16 V.
lc = (1 - t) * v[1]->lc + t * v[2]->lc;
17 V.
w = (1 - t) * v[1]->w + t * v[2]->w;
18 const double t2 = t * t;
19 const double t3 = t * t * t;
20 const double s[4] = {-.5 * t3 + t2 - .5 * t, 1.5 * t3 - 2.5 * t2 + 1,
21 -1.5 * t3 + 2 * t2 + .5 * t, 0.5 * t3 - 0.5 * t2};
31 int derivee,
double t1,
double t2)
38 V.
lc = (1 - t) * v[1]->lc + t * v[2]->lc;
39 V.
w = (1 - t) * v[1]->w + t * v[2]->w;
47 else if(derivee == 2) {
60 for(i = 0; i < 4; i++) { vec[i] = 0.0; }
63 for(i = 0; i < 4; i++) {
64 for(j = 0; j < 4; j++) { vec[i] += mat[i][j] * v[j]->
Pos.
X; }
67 for(j = 0; j < 4; j++) {
68 V.
Pos.
X += T[j] * vec[j];
73 for(i = 0; i < 4; i++) {
74 for(j = 0; j < 4; j++) { vec[i] += mat[i][j] * v[j]->
Pos.
Y; }
77 for(j = 0; j < 4; j++) {
78 V.
Pos.
Y += T[j] * vec[j];
83 for(i = 0; i < 4; i++) {
84 for(j = 0; j < 4; j++) { vec[i] += mat[i][j] * v[j]->
Pos.
Z; }
86 for(j = 0; j < 4; j++) {
87 V.
Pos.
Z += T[j] * vec[j];
92 V.
Pos.
X /= ((t2 - t1));
93 V.
Pos.
Y /= ((t2 - t1));
94 V.
Pos.
Z /= ((t2 - t1));
96 else if(derivee == 2) {
97 V.
Pos.
X /= ((t2 - t1) * (t2 - t1));
98 V.
Pos.
Y /= ((t2 - t1) * (t2 - t1));
99 V.
Pos.
Z /= ((t2 - t1) * (t2 - t1));
112 double T[4] = {0., 0., 0., 0.};
120 else if(derivee == 1) {
126 else if(derivee == 2) {
135 for(i = 0; i < 4; i++) {
136 for(j = 0; j < 4; j++) { coord[i] += v[j]->
pntOnGeometry * mat[i][j]; }
139 for(j = 0; j < 4; j++) { p += coord[j] * T[j]; }
146 if(NbControls - derivee <= 0)
return Vertex(0, 0, 0);
151 for(
int i = 0; i < NbControls; ++i) {
159 for(
int i = 0; i < NbControls; ++i) {
170 for(
int i = 0; i < NbControls; ++i) {
183 while(NbControls > 1) {
185 for(
int i = 0; i < NbControls; ++i) {
190 c2.
X = (1 - u) *
c1.X + u * c2.
X;
191 c2.
Y = (1 - u) *
c1.Y + u * c2.
Y;
192 c2.
Z = (1 - u) *
c1.Z + u * c2.
Z;
222 #if 1 // bypass regression in Gmsh 4 for bsplines on geometry (see #685)
226 int NbCurves = NbControlPoints + (periodic ? -1 : 1);
227 int iCurve = (int)floor(u * (
double)NbCurves);
228 if(iCurve == NbCurves) iCurve -= 1;
229 double t1 = (double)(iCurve) / (double)(NbCurves);
230 double t2 = (double)(iCurve + 1) / (double)(NbCurves);
231 double t = (u - t1) / (t2 - t1);
233 for(
int i = 0; i < 4; i++) {
236 k = (iCurve - 1 + i) % (NbControlPoints - 1);
237 if(k < 0) k += NbControlPoints - 1;
240 k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints - 1));
256 static double mat2[4][4] = {
257 {0, 0, 0, 0}, {0, 0, 0, 0}, {-1, 1, 0, 0}, {1, 0, 0, 0}};
259 static double mat3[4][4] = {
260 {0, 0, 0, 0}, {1, -2, 1, 0}, {-2, 2, 0, 0}, {1, 0, 0, 0}};
262 static double mat4[4][4] = {{-1, 3, -3, 1},
268 static double mat5[4][4] = {
269 {-1, 7. / 4, -1, 1. / 4}, {3, -4.5, 1.5, 0}, {-3, 3, 0, 0}, {1, 0, 0, 0}};
272 static double mat6_1[4][4] = {{-1, 7. / 4, -11. / 12, 2. / 12},
276 static double mat6_2[4][4] = {{-1. / 4, 7. / 12, -7. / 12, 1. / 4},
277 {3. / 4, -5. / 4, 1. / 2, 0},
278 {-3. / 4, 1. / 4, 1. / 2, 0},
279 {1. / 4, 7. / 12, 1. / 6, 0}};
281 static double matext_1[4][4] = {{-1, 7. / 4, -11. / 12, 1. / 6},
285 static double mat7_2[4][4] = {{-1. / 4, 7. / 12, -1. / 2, 1. / 6},
286 {3. / 4, -5. / 4, 1. / 2, 0},
287 {-3. / 4, 1. / 4, 1. / 2, 0},
288 {1. / 4, 7. / 12, 1. / 6, 0}};
289 static double matext_2[4][4] = {{-1. / 4, 7. / 12, -.5, 1. / 6},
290 {3. / 4, -5. / 4, .5, 0},
291 {-3. / 4, 1. / 4, .5, 0},
292 {1. / 4, 7. / 12, 1. / 6, 0}};
297 int NbCurves = NbControlPoints + (periodic ? -1 : -3);
299 NbCurves = std::max(NbCurves, 1);
301 int iCurve =
static_cast<int>(std::floor(u *
static_cast<double>(NbCurves)));
302 if(iCurve == NbCurves) iCurve -= 1;
304 double t1 =
static_cast<double>(iCurve) /
static_cast<double>(NbCurves);
305 double t2 =
static_cast<double>(iCurve + 1) /
static_cast<double>(NbCurves);
306 double t = (u - t1) / (t2 - t1);
309 for(
int i = 0; i < 4; i++) {
312 k = (iCurve - 1 + i) % (NbControlPoints - 1);
313 if(k < 0) k += NbControlPoints - 1;
316 k = std::min(iCurve + i, NbControlPoints - 1);
319 if(k >= 0 && k < NbControlPoints) {
329 double(*matrix)[4][4] = &
Curve->
mat;
332 if((NbControlPoints > 6 && iCurve >= NbCurves - 2) ||
333 (NbControlPoints > 4 && iCurve == NbCurves - 1)) {
344 iCurve = NbCurves - 1 - iCurve;
347 switch(NbControlPoints) {
348 case 2: matrix = &mat2;
break;
349 case 3: matrix = &mat3;
break;
350 case 4: matrix = &mat4;
break;
351 case 5: matrix = &mat5;
break;
352 case 6: matrix = &mat6_1;
break;
353 default: matrix = &matext_1;
break;
356 else if(iCurve == 1) {
357 switch(NbControlPoints) {
358 case 6: matrix = &mat6_2;
break;
359 case 7: matrix = &mat7_2;
break;
360 default: matrix = &matext_2;
break;
365 #if 0 // bypass regression in Gmsh 4 for bsplines on geometry (see #685)
383 if(u >= U[n])
return n - 1;
384 if(u <= U[0])
return deg;
388 int mid = (low + high) / 2;
390 while(u < U[mid] || u >= U[mid + 1]) {
395 mid = (low + high) / 2;
400 static void basisFuns(
double u,
int i,
int deg,
float *U,
double *N)
403 double *right = &left[deg + 1];
408 for(
int j = 1; j <= deg; j++) {
409 left[j] = u - U[i + 1 - j];
410 right[j] = U[i + j] - u;
412 for(
int r = 0; r < j; r++) {
413 temp = N[r] / (right[r + 1] + left[j - r]);
414 N[r] = saved + right[r + 1] * temp;
415 saved = left[j - r] * temp;
436 p.
lc += Nb[i] * v->
lc;
447 return Vertex(0., 0., 0.);
470 const double eps1 = (u < eps) ? 0.0 : eps;
471 const double eps2 = (u > 1 - eps) ? 0.0 : eps;
475 V.
Pos.
X = (
D[1].Pos.X -
D[0].Pos.X) / (eps1 + eps2);
476 V.
Pos.
Y = (
D[1].Pos.Y -
D[0].Pos.Y) / (eps1 + eps2);
477 V.
Pos.
Z = (
D[1].Pos.Z -
D[0].Pos.Z) / (eps1 + eps2);
497 double const eps1 = (u < eps) ? 0.0 : eps;
498 double const eps2 = (u > 1 - eps) ? 0.0 : eps;
502 V.
Pos.
X = (
D[1].Pos.X -
D[0].Pos.X) / (eps1 + eps2);
503 V.
Pos.
Y = (
D[1].Pos.Y -
D[0].Pos.Y) / (eps1 + eps2);
504 V.
Pos.
Z = (
D[1].Pos.Z -
D[0].Pos.Z) / (eps1 + eps2);
512 double theta, t1, t2, t;
520 Msg::Error(
"Line with less than 2 control points");
524 int i =
static_cast<int>(
static_cast<double>(N - 1) * u);
526 if(i >= N - 1) i = N - 2;
529 t1 =
static_cast<double>(i) /
static_cast<double>(N - 1);
530 t2 =
static_cast<double>(i + 1) /
static_cast<double>(N - 1);
531 t = (u - t1) / (t2 - t1);
540 V.
w = (1. - t) * v[1]->w + t * v[2]->w;
541 V.
lc = (1. - t) * v[1]->lc + t * v[2]->lc;
561 Msg::Error(
"Circle or ellipse with less than 2 control points");
569 theta =
c->Circle.t1 - (
c->Circle.t1 -
c->Circle.t2) * u;
570 theta -=
c->Circle.incl;
572 V.
Pos.
X =
c->Circle.f1 * std::cos(theta) * std::cos(
c->Circle.incl) -
573 c->Circle.f2 * std::sin(theta) * std::sin(
c->Circle.incl);
574 V.
Pos.
Y =
c->Circle.f1 * std::cos(theta) * std::sin(
c->Circle.incl) +
575 c->Circle.f2 * std::sin(theta) * std::cos(
c->Circle.incl);
585 V.
w = (1. - u) *
c->beg->w + u *
c->end->w;
586 V.
lc = (1. - u) *
c->beg->lc + u *
c->end->lc;
600 Msg::Error(
"Spline with less than 2 control points");
604 int i =
static_cast<double>(N - 1) * u;
608 if(i >= N - 1) i = N - 2;
610 t1 =
static_cast<double>(i) /
static_cast<double>(N - 1);
611 t2 =
static_cast<double>(i + 1) /
static_cast<double>(N - 1);
612 t = (u - t1) / (t2 - t1);
617 if(
c->beg ==
c->end) {
List_Read(
c->Control_Points, N - 2, &v[0]); }
630 if(
c->beg ==
c->end) {
List_Read(
c->Control_Points, 1, &v[3]); }
645 SPoint3 pt =
c->geometry->point(pp);
659 Msg::Debug(
"Cannot interpolate boundary layer curve");
663 Msg::Debug(
"Cannot interpolate discrete curve");
666 default:
Msg::Error(
"Unknown curve type %d in interpolation",
c->Typ);
break;
677 T
TRAN_QUA(T
const c1, T
const c2, T
const c3, T
const c4, T
const s1,
678 T
const s2, T
const s3, T
const s4, T
const u, T
const v)
680 return (1.0 - u) * c4 + u * c2 + (1.0 - v) *
c1 + v * c3 -
681 ((1.0 - u) * (1.0 - v) * s1 + u * (1.0 - v) * s2 + u * v * s3 +
726 T
TRAN_TRI(T
const c1, T
const c2, T
const c3, T
const s1, T
const s2,
727 T
const s3, T
const u, T
const v)
729 return u * c2 + (1.0 - v) *
c1 + v * c3 - (u * (1.0 - v) * s2 + u * v * s3);
762 T
TRAN_TRIB(T
const c1, T
const c1b, T
const c2, T
const c2b, T
const c3,
763 T
const c3b, T
const s1, T
const s2, T
const s3, T
const u,
766 return (1.0 - u) * (
c1 + c3b - s1) + (u - v) * (c2 + c1b - s2) +
772 Vertex s3,
double u,
double v)
778 TRAN_TRIB(
c1.w, c1b.
w, c2.
w, c2b.
w, c3.
w, c3b.
w, s1.
w, s2.
w, s3.
w, u, v);
790 double r = std::sqrt(std::pow(
S.Pos.X - center.
Pos.
X, 2) +
791 std::pow(
S.Pos.Y - center.
Pos.
Y, 2) +
792 std::pow(
S.Pos.Z - center.
Pos.
Z, 2));
793 double s = std::sqrt(std::pow(T->
Pos.
X - center.
Pos.
X, 2) +
794 std::pow(T->
Pos.
Y - center.
Pos.
Y, 2) +
795 std::pow(T->
Pos.
Z - center.
Pos.
Z, 2));
797 double const dirx = (T->
Pos.
X - center.
Pos.
X) / s;
798 double const diry = (T->
Pos.
Y - center.
Pos.
Y) / s;
799 double const dirz = (T->
Pos.
Z - center.
Pos.
Z) / s;
808 Curve *C[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
811 Msg::Error(
"No curves on boundary of ruled surface");
812 return Vertex(0., 0., 0.);
819 "Cannot interpolate ruled surface with discrete bounding curves");
820 return Vertex(0., 0., 0.);
822 if(!C[i]->beg || !C[i]->end) {
823 Msg::Error(
"Cannot interpolate ruled surface if bounding curves don't "
825 return Vertex(0., 0., 0.);
830 bool isSphere =
true;
845 if(!i) {
List_Read(C[i]->Control_Points, 1, &
O); }
848 List_Read(C[i]->Control_Points, 1, &tmp);
858 isPlane &= (n[0] == C[i]->Circle.invmat[0][2] &&
861 if(isPlane) isSphere =
false;
876 C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
878 C[3], C[3]->ubeg + (C[3]->uend - C[3]->ubeg) * (1. - v), 0);
893 C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
898 C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * (u - v), 0);
902 C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
906 C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1 - u + v), 0);
908 C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0);
934 Msg::Error(
"Unknown curve in extruded surface");
984 (
D[1].Pos.Z -
D[0].Pos.Z) /
fd_eps);
986 else if(derivee == 2) {
1019 (
D[1].Pos.Y -
D[0].Pos.Y) /
fd_eps,
1020 (
D[1].Pos.Z -
D[0].Pos.Z) /
fd_eps);
1041 Msg::Error(
"Should not interpolate plane surface here");
1042 return Vertex(0., 0., 0.);
1044 Msg::Debug(
"Cannot interpolate boundary layer surface");
1045 return Vertex(0., 0., 0.);
1047 Msg::Debug(
"Cannot interpolate discrete surface");
1048 return Vertex(0., 0., 0.);
1050 Msg::Error(
"Unknown surface type in interpolation");
1051 return Vertex(0., 0., 0.);