gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GeoInterpolation.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include "GmshMessage.h"
7 #include "Geo.h"
8 #include "GeoInterpolation.h"
9 #include "Numeric.h"
10 #include "Context.h"
11 
12 static double const fd_eps = 1.0e-8;
13 
14 static void InterpolateCatmullRom(Vertex *v[4], double t, Vertex &V)
15 {
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};
22  V.Pos.X = s[0] * v[0]->Pos.X + s[1] * v[1]->Pos.X + s[2] * v[2]->Pos.X +
23  s[3] * v[3]->Pos.X;
24  V.Pos.Y = s[0] * v[0]->Pos.Y + s[1] * v[1]->Pos.Y + s[2] * v[2]->Pos.Y +
25  s[3] * v[3]->Pos.Y;
26  V.Pos.Z = s[0] * v[0]->Pos.Z + s[1] * v[1]->Pos.Z + s[2] * v[2]->Pos.Z +
27  s[3] * v[3]->Pos.Z;
28 }
29 
30 static Vertex InterpolateCubicSpline(Vertex *v[4], double t, double mat[4][4],
31  int derivee, double t1, double t2)
32 {
33  Vertex V;
34  int i, j;
35  double vec[4], T[4];
36 
37  V.Pos.X = V.Pos.Y = V.Pos.Z = 0.0;
38  V.lc = (1 - t) * v[1]->lc + t * v[2]->lc;
39  V.w = (1 - t) * v[1]->w + t * v[2]->w;
40 
41  if(derivee == 1) {
42  T[3] = 0.;
43  T[2] = 1.;
44  T[1] = 2. * t;
45  T[0] = 3. * t * t;
46  }
47  else if(derivee == 2) {
48  T[3] = 0.;
49  T[2] = 0.;
50  T[1] = 2.;
51  T[0] = 6. * t;
52  }
53  else {
54  T[3] = 1.;
55  T[2] = t;
56  T[1] = t * t;
57  T[0] = t * t * t;
58  }
59 
60  for(i = 0; i < 4; i++) { vec[i] = 0.0; }
61 
62  // X
63  for(i = 0; i < 4; i++) {
64  for(j = 0; j < 4; j++) { vec[i] += mat[i][j] * v[j]->Pos.X; }
65  }
66 
67  for(j = 0; j < 4; j++) {
68  V.Pos.X += T[j] * vec[j];
69  vec[j] = 0.0;
70  }
71 
72  // Y
73  for(i = 0; i < 4; i++) {
74  for(j = 0; j < 4; j++) { vec[i] += mat[i][j] * v[j]->Pos.Y; }
75  }
76 
77  for(j = 0; j < 4; j++) {
78  V.Pos.Y += T[j] * vec[j];
79  vec[j] = 0.0;
80  }
81 
82  // Z
83  for(i = 0; i < 4; i++) {
84  for(j = 0; j < 4; j++) { vec[i] += mat[i][j] * v[j]->Pos.Z; }
85  }
86  for(j = 0; j < 4; j++) {
87  V.Pos.Z += T[j] * vec[j];
88  vec[j] = 0.0;
89  }
90 
91  if(derivee == 1) {
92  V.Pos.X /= ((t2 - t1));
93  V.Pos.Y /= ((t2 - t1));
94  V.Pos.Z /= ((t2 - t1));
95  }
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));
100  }
101 
102  return V;
103 }
104 
105 // interpolation in the parametric space
106 SPoint2 InterpolateCubicSpline(Vertex *v[4], double t, double mat[4][4],
107  double t1, double t2, gmshSurface *s,
108  int derivee)
109 {
110  Vertex V;
111  int i, j;
112  double T[4] = {0., 0., 0., 0.};
113 
114  if(derivee == 0) {
115  T[3] = 1.;
116  T[2] = t;
117  T[1] = t * t;
118  T[0] = t * t * t;
119  }
120  else if(derivee == 1) {
121  T[3] = 0.;
122  T[2] = 1;
123  T[1] = 2 * t;
124  T[0] = 3 * t * t;
125  }
126  else if(derivee == 2) {
127  T[3] = 0.;
128  T[2] = 0;
129  T[1] = 2;
130  T[0] = 6 * t;
131  }
132 
133  SPoint2 coord[4], p;
134 
135  for(i = 0; i < 4; i++) {
136  for(j = 0; j < 4; j++) { coord[i] += v[j]->pntOnGeometry * mat[i][j]; }
137  }
138 
139  for(j = 0; j < 4; j++) { p += coord[j] * T[j]; }
140  return p;
141 }
142 
143 static Vertex InterpolateBezier(Curve *Curve, double u, int derivee)
144 {
145  int NbControls = List_Nbr(Curve->Control_Points);
146  if(NbControls - derivee <= 0) return Vertex(0, 0, 0);
147 
148  List_T *controls = List_Create(NbControls, 1, sizeof(Coord));
149 
150  if(Curve->geometry) {
151  for(int i = 0; i < NbControls; ++i) {
152  Vertex *v;
153  List_Read(Curve->Control_Points, i, &v);
154  Coord c = {v->pntOnGeometry.x(), v->pntOnGeometry.y(), 0};
155  List_Add(controls, &c);
156  }
157  }
158  else {
159  for(int i = 0; i < NbControls; ++i) {
160  Vertex *v;
161  List_Read(Curve->Control_Points, i, &v);
162  List_Add(controls, &v->Pos);
163  }
164  }
165 
166  // Compute derivative:
167  while(derivee > 0) {
168  NbControls--;
169  derivee--;
170  for(int i = 0; i < NbControls; ++i) {
171  Coord c1;
172  Coord c2;
173  List_Read(controls, i, &c1);
174  List_Read(controls, i + 1, &c2);
175  c2.X -= c1.X;
176  c2.Y -= c1.Y;
177  c2.Z -= c1.Z;
178  List_Write(controls, i, &c2);
179  }
180  }
181 
182  // De Casteljau's algorithm:
183  while(NbControls > 1) {
184  NbControls--;
185  for(int i = 0; i < NbControls; ++i) {
186  Coord c1;
187  Coord c2;
188  List_Read(controls, i, &c1);
189  List_Read(controls, i + 1, &c2);
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;
193  List_Write(controls, i, &c2);
194  }
195  }
196 
197  Coord c;
198  List_Read(controls, 0, &c);
199  List_Delete(controls);
200 
201  if(Curve->geometry) {
202  SPoint2 pp(c.X, c.Y);
203  SPoint3 pt = Curve->geometry->point(pp);
204  Vertex V;
205  V.Pos.X = pt.x();
206  V.Pos.Y = pt.y();
207  V.Pos.Z = pt.z();
208  return V;
209  }
210  else {
211  Vertex V;
212  V.Pos.X = c.X;
213  V.Pos.Y = c.Y;
214  V.Pos.Z = c.Z;
215  return V;
216  }
217 }
218 
219 // Uniform BSplines
220 static Vertex InterpolateUBS(Curve *Curve, double u, int derivee)
221 {
222 #if 1 // bypass regression in Gmsh 4 for bsplines on geometry (see #685)
223  if(Curve->geometry) {
224  bool periodic = (Curve->end == Curve->beg);
225  int NbControlPoints = List_Nbr(Curve->Control_Points);
226  int NbCurves = NbControlPoints + (periodic ? -1 : 1);
227  int iCurve = (int)floor(u * (double)NbCurves);
228  if(iCurve == NbCurves) iCurve -= 1; // u = 1
229  double t1 = (double)(iCurve) / (double)(NbCurves);
230  double t2 = (double)(iCurve + 1) / (double)(NbCurves);
231  double t = (u - t1) / (t2 - t1);
232  Vertex *v[4];
233  for(int i = 0; i < 4; i++) {
234  int k;
235  if(periodic) {
236  k = (iCurve - 1 + i) % (NbControlPoints - 1);
237  if(k < 0) k += NbControlPoints - 1;
238  }
239  else {
240  k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints - 1));
241  }
242  List_Read(Curve->Control_Points, k, &v[i]);
243  }
244  SPoint2 pp = InterpolateCubicSpline(v, t, Curve->mat, t1, t2,
245  Curve->geometry, derivee);
246  SPoint3 pt = Curve->geometry->point(pp);
247  Vertex V;
248  V.Pos.X = pt.x();
249  V.Pos.Y = pt.y();
250  V.Pos.Z = pt.z();
251  return V;
252  }
253 #endif
254 
255  // Mat for 2 control points (=> linear)
256  static double mat2[4][4] = {
257  {0, 0, 0, 0}, {0, 0, 0, 0}, {-1, 1, 0, 0}, {1, 0, 0, 0}};
258  // Mat for 3 control points (=> quadratic, Bézier)
259  static double mat3[4][4] = {
260  {0, 0, 0, 0}, {1, -2, 1, 0}, {-2, 2, 0, 0}, {1, 0, 0, 0}};
261  // Mat for 4 control points (=> cubic, Bézier)
262  static double mat4[4][4] = {{-1, 3, -3, 1}, // t^3
263  {3, -6, 3, 0}, // t^2
264  {-3, 3, 0, 0}, // t^1
265  {1, 0, 0, 0}}; // t^0
266  // n0 n1 n2 n3
267  // Mat for 5 control points (left extremity, other obtained by symmetry)
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}};
270  // Mat for 6 control points (left extremity + middle, right obtained by
271  // symmetry)
272  static double mat6_1[4][4] = {{-1, 7. / 4, -11. / 12, 2. / 12},
273  {3, -4.5, 1.5, 0},
274  {-3, 3, 0, 0},
275  {1, 0, 0, 0}};
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}};
280  // Mat for 7+ control points
281  static double matext_1[4][4] = {{-1, 7. / 4, -11. / 12, 1. / 6},
282  {3, -4.5, 1.5, 0},
283  {-3, 3, 0, 0},
284  {1, 0, 0, 0}};
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}};
293 
294  bool periodic = (Curve->end == Curve->beg);
295 
296  int NbControlPoints = List_Nbr(Curve->Control_Points);
297  int NbCurves = NbControlPoints + (periodic ? -1 : -3);
298 
299  NbCurves = std::max(NbCurves, 1);
300 
301  int iCurve = static_cast<int>(std::floor(u * static_cast<double>(NbCurves)));
302  if(iCurve == NbCurves) iCurve -= 1; // u = 1
303 
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);
307 
308  Vertex *v[4];
309  for(int i = 0; i < 4; i++) {
310  int k;
311  if(periodic) {
312  k = (iCurve - 1 + i) % (NbControlPoints - 1);
313  if(k < 0) k += NbControlPoints - 1;
314  }
315  else {
316  k = std::min(iCurve + i, NbControlPoints - 1);
317  }
318 
319  if(k >= 0 && k < NbControlPoints) {
320  List_Read(Curve->Control_Points, k, &v[i]);
321  }
322  else {
323  Msg::Warning("Wrong control point index in bspline");
324  Vertex V;
325  return V;
326  }
327  }
328 
329  double(*matrix)[4][4] = &Curve->mat;
330  if(!periodic) {
331  // Inverse if right extremity
332  if((NbControlPoints > 6 && iCurve >= NbCurves - 2) ||
333  (NbControlPoints > 4 && iCurve == NbCurves - 1)) {
334  Vertex *v_tmp = v[0];
335  v[0] = v[3];
336  v[3] = v_tmp;
337  v_tmp = v[1];
338  v[1] = v[2];
339  v[2] = v_tmp;
340  t = 1 - t;
341  double t_tmp = t1;
342  t1 = t2;
343  t2 = t_tmp;
344  iCurve = NbCurves - 1 - iCurve;
345  }
346  if(iCurve == 0) {
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;
354  }
355  }
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;
361  }
362  }
363  }
364 
365 #if 0 // bypass regression in Gmsh 4 for bsplines on geometry (see #685)
366  if(Curve->geometry) {
367  SPoint2 pp =
368  InterpolateCubicSpline(v, t, *matrix, t1, t2, Curve->geometry, derivee);
369  SPoint3 pt = Curve->geometry->point(pp);
370  Vertex V;
371  V.Pos.X = pt.x();
372  V.Pos.Y = pt.y();
373  V.Pos.Z = pt.z();
374  return V;
375  }
376 #endif
377  return InterpolateCubicSpline(v, t, *matrix, derivee, t1, t2);
378 }
379 
380 // Non Uniform BSplines
381 int findSpan(double u, int deg, int n, float *U)
382 {
383  if(u >= U[n]) return n - 1;
384  if(u <= U[0]) return deg;
385 
386  int low = deg;
387  int high = n + 1;
388  int mid = (low + high) / 2;
389 
390  while(u < U[mid] || u >= U[mid + 1]) {
391  if(u < U[mid])
392  high = mid;
393  else
394  low = mid;
395  mid = (low + high) / 2;
396  }
397  return mid;
398 }
399 
400 static void basisFuns(double u, int i, int deg, float *U, double *N)
401 {
402  double left[1000];
403  double *right = &left[deg + 1];
404 
405  double temp, saved;
406 
407  N[0] = 1.0;
408  for(int j = 1; j <= deg; j++) {
409  left[j] = u - U[i + 1 - j];
410  right[j] = U[i + j] - u;
411  saved = 0.0;
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;
416  }
417  N[j] = saved;
418  }
419 }
420 
421 static Vertex InterpolateNurbs(Curve *Curve, double u, int derivee)
422 {
423  double Nb[1000];
424  int span =
426  basisFuns(u, span, Curve->degre, Curve->k, Nb);
427  Vertex p;
428  p.Pos.X = p.Pos.Y = p.Pos.Z = p.w = p.lc = 0.0;
429  for(int i = Curve->degre; i >= 0; --i) {
430  Vertex *v;
431  List_Read(Curve->Control_Points, span - Curve->degre + i, &v);
432  p.Pos.X += Nb[i] * v->Pos.X;
433  p.Pos.Y += Nb[i] * v->Pos.Y;
434  p.Pos.Z += Nb[i] * v->Pos.Z;
435  p.w += Nb[i] * v->w;
436  p.lc += Nb[i] * v->lc;
437  }
438  return p;
439 }
440 
441 Vertex InterpolateCurve(Curve *c, double u, int const derivee)
442 {
443  if(c->Num < 0) {
444  Curve *C0 = FindCurve(-c->Num);
445  if(!C0) {
446  Msg::Error("Unknown curve %d", -c->Num);
447  return Vertex(0., 0., 0.);
448  }
449  return InterpolateCurve(C0, C0->ubeg + (C0->uend - C0->ubeg) * (1.0 - u),
450  derivee);
451  }
452 
453  const double eps = (c->Typ == MSH_SEGM_LINE) ? 1e-5 : fd_eps;
454 
455  Vertex V;
456 
457  if(derivee == 1) {
458  switch(c->Typ) {
459  /*
460  case MSH_SEGM_BSPLN:
461  V = InterpolateUBS(c, u, 1);
462  V.u = u;
463  break;
464  */
465  case MSH_SEGM_BEZIER:
466  V = InterpolateBezier(c, u, 1);
467  V.u = u;
468  break;
469  default:
470  const double eps1 = (u < eps) ? 0.0 : eps;
471  const double eps2 = (u > 1 - eps) ? 0.0 : eps;
472  Vertex D[2];
473  D[0] = InterpolateCurve(c, u - eps1, 0);
474  D[1] = InterpolateCurve(c, u + eps2, 0);
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);
478  V.u = u;
479  break;
480  }
481  return V;
482  }
483 
484  if(derivee == 2) {
485  switch(c->Typ) {
486  /*
487  case MSH_SEGM_BSPLN:
488  V = InterpolateUBS(c, u, 2);
489  V.u = u;
490  break;
491  */
492  case MSH_SEGM_BEZIER:
493  V = InterpolateBezier(c, u, 2);
494  V.u = u;
495  break;
496  default:
497  double const eps1 = (u < eps) ? 0.0 : eps;
498  double const eps2 = (u > 1 - eps) ? 0.0 : eps;
499  Vertex D[2];
500  D[0] = InterpolateCurve(c, u - eps1, 1);
501  D[1] = InterpolateCurve(c, u + eps2, 1);
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);
505  V.u = u;
506  break;
507  }
508  return V;
509  }
510 
511  Vertex *v[5];
512  double theta, t1, t2, t;
513  Vertex temp1, temp2;
514 
515  switch(c->Typ) {
516  case MSH_SEGM_LINE: {
517  int N = List_Nbr(c->Control_Points);
518 
519  if(N < 2) {
520  Msg::Error("Line with less than 2 control points");
521  V.Pos.X = V.Pos.Y = V.Pos.Z = 0;
522  }
523  else {
524  int i = static_cast<int>(static_cast<double>(N - 1) * u);
525  // clamp
526  if(i >= N - 1) i = N - 2;
527  if(i < 0) i = 0;
528 
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);
532 
533  List_Read(c->Control_Points, i, &v[1]);
534  List_Read(c->Control_Points, i + 1, &v[2]);
535 
536  if(!c->geometry) {
537  V.Pos.X = v[1]->Pos.X + t * (v[2]->Pos.X - v[1]->Pos.X);
538  V.Pos.Y = v[1]->Pos.Y + t * (v[2]->Pos.Y - v[1]->Pos.Y);
539  V.Pos.Z = v[1]->Pos.Z + t * (v[2]->Pos.Z - v[1]->Pos.Z);
540  V.w = (1. - t) * v[1]->w + t * v[2]->w;
541  V.lc = (1. - t) * v[1]->lc + t * v[2]->lc;
542  }
543  else {
544  SPoint2 p =
545  v[1]->pntOnGeometry + (v[2]->pntOnGeometry - v[1]->pntOnGeometry) * t;
546  SPoint3 pp = c->geometry->point(p);
547  V.Pos.X = pp.x();
548  V.Pos.Y = pp.y();
549  V.Pos.Z = pp.z();
550  }
551  }
552  break;
553  }
554 
555  case MSH_SEGM_CIRC:
556  case MSH_SEGM_CIRC_INV:
557  case MSH_SEGM_ELLI:
558  case MSH_SEGM_ELLI_INV: {
559  int N = List_Nbr(c->Control_Points);
560  if(N < 2) {
561  Msg::Error("Circle or ellipse with less than 2 control points");
562  V.Pos.X = V.Pos.Y = V.Pos.Z = 0;
563  }
564  else {
565  if(c->Typ == MSH_SEGM_CIRC_INV || c->Typ == MSH_SEGM_ELLI_INV) {
566  V.u = 1. - u;
567  u = V.u;
568  }
569  theta = c->Circle.t1 - (c->Circle.t1 - c->Circle.t2) * u;
570  theta -= c->Circle.incl; // for ellipses
571 
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);
576  V.Pos.Z = 0.0;
577 
578  Projette(&V, c->Circle.invmat);
579  List_Read(c->Control_Points, 1, &v[0]);
580 
581  V.Pos.X += v[0]->Pos.X;
582  V.Pos.Y += v[0]->Pos.Y;
583  V.Pos.Z += v[0]->Pos.Z;
584 
585  V.w = (1. - u) * c->beg->w + u * c->end->w;
586  V.lc = (1. - u) * c->beg->lc + u * c->end->lc;
587  }
588  break;
589  }
590 
591  case MSH_SEGM_BSPLN: V = InterpolateUBS(c, u, 0); break;
592 
593  case MSH_SEGM_BEZIER: V = InterpolateBezier(c, u, 0); break;
594 
595  case MSH_SEGM_NURBS: V = InterpolateNurbs(c, u, 0); break;
596 
597  case MSH_SEGM_SPLN: {
598  int N = List_Nbr(c->Control_Points);
599  if(N < 2) {
600  Msg::Error("Spline with less than 2 control points");
601  V.Pos.X = V.Pos.Y = V.Pos.Z = 0;
602  }
603  else {
604  int i = static_cast<double>(N - 1) * u;
605 
606  // clamp
607  if(i < 0) i = 0;
608  if(i >= N - 1) i = N - 2;
609 
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);
613 
614  List_Read(c->Control_Points, i, &v[1]);
615  List_Read(c->Control_Points, i + 1, &v[2]);
616  if(!i) {
617  if(c->beg == c->end) { List_Read(c->Control_Points, N - 2, &v[0]); }
618  else {
619  v[0] = &temp1;
620  v[0]->Pos.X = 2. * v[1]->Pos.X - v[2]->Pos.X;
621  v[0]->Pos.Y = 2. * v[1]->Pos.Y - v[2]->Pos.Y;
622  v[0]->Pos.Z = 2. * v[1]->Pos.Z - v[2]->Pos.Z;
623  v[0]->pntOnGeometry = v[1]->pntOnGeometry * 2. - v[2]->pntOnGeometry;
624  }
625  }
626  else {
627  List_Read(c->Control_Points, i - 1, &v[0]);
628  }
629  if(i == N - 2) {
630  if(c->beg == c->end) { List_Read(c->Control_Points, 1, &v[3]); }
631  else {
632  v[3] = &temp2;
633  v[3]->Pos.X = 2. * v[2]->Pos.X - v[1]->Pos.X;
634  v[3]->Pos.Y = 2. * v[2]->Pos.Y - v[1]->Pos.Y;
635  v[3]->Pos.Z = 2. * v[2]->Pos.Z - v[1]->Pos.Z;
636  v[3]->pntOnGeometry = v[2]->pntOnGeometry * 2. - v[1]->pntOnGeometry;
637  }
638  }
639  else {
640  List_Read(c->Control_Points, i + 2, &v[3]);
641  }
642  if(c->geometry) {
643  SPoint2 pp =
644  InterpolateCubicSpline(v, t, c->mat, t1, t2, c->geometry, 0);
645  SPoint3 pt = c->geometry->point(pp);
646  V.Pos.X = pt.x();
647  V.Pos.Y = pt.y();
648  V.Pos.Z = pt.z();
649  }
650  else {
651  InterpolateCatmullRom(v, t, V);
652  // V = InterpolateCubicSpline(v, t, c->mat, 0, t1, t2);
653  }
654  }
655  break;
656  }
657 
658  case MSH_SEGM_BND_LAYER:
659  Msg::Debug("Cannot interpolate boundary layer curve");
660  break;
661 
662  case MSH_SEGM_DISCRETE:
663  Msg::Debug("Cannot interpolate discrete curve");
664  break;
665 
666  default: Msg::Error("Unknown curve type %d in interpolation", c->Typ); break;
667  }
668  V.u = u;
669  return V;
670 }
671 
672 // Transfinite interpolation on a quadrangle :
673 // f(u,v) = (1-u)c4(v) + u c2(v) + (1-v)c1(u) + v c3(u)
674 // - [ (1-u)(1-v)s1 + u(1-v)s2 + uv s3 + (1-u)v s4 ]
675 
676 template <class T>
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)
679 {
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 +
682  (1.0 - u) * v * s4);
683 }
684 
686  Vertex s1, Vertex s2, Vertex s3, Vertex s4,
687  double u, double v)
688 {
689  Vertex V;
690 
691  V.lc = TRAN_QUA(c1.lc, c2.lc, c3.lc, c4.lc, s1.lc, s2.lc, s3.lc, s4.lc, u, v);
692  V.w = TRAN_QUA(c1.w, c2.w, c3.w, c4.w, s1.w, s2.w, s3.w, s4.w, u, v);
693  V.Pos.X = TRAN_QUA(c1.Pos.X, c2.Pos.X, c3.Pos.X, c4.Pos.X, s1.Pos.X, s2.Pos.X,
694  s3.Pos.X, s4.Pos.X, u, v);
695  V.Pos.Y = TRAN_QUA(c1.Pos.Y, c2.Pos.Y, c3.Pos.Y, c4.Pos.Y, s1.Pos.Y, s2.Pos.Y,
696  s3.Pos.Y, s4.Pos.Y, u, v);
697  V.Pos.Z = TRAN_QUA(c1.Pos.Z, c2.Pos.Z, c3.Pos.Z, c4.Pos.Z, s1.Pos.Z, s2.Pos.Z,
698  s3.Pos.Z, s4.Pos.Z, u, v);
699  return V;
700 }
701 
702 // Transfinite interpolation on a triangle :
703 //
704 // s3(1,1)
705 // +
706 // / |
707 // c3 / |
708 // / | c2
709 // / |
710 // / c1 |
711 // +----------+
712 // s1(0,0) s2(1,0)
713 
714 // Old-style: TRAN_QUA with s1=s4=c4
715 //
716 // f(u,v) = u c2 (v) + (1-v) c1(u) + v c3(u) - u(1-v) s2 - uv s3
717 //
718 // u = v = 0 -----> x = c1(0) = s1 --> OK
719 // u = 1 ; v = 0 -----> x = c2(0) + c1(1) - s2 = s2 --> OK
720 // u = 1 ; v = 1 -----> x = c2(1) + c3(1) - s3 = s3 --> OK
721 // v = 0 --> u s2 + c1(u) - u s2 --> x = c1(u) --> OK
722 // u = 1 --> c2(v) + (1-v) s2 + v s3 -(1-v) s2 - v s3 --> x = c2(v) --> OK
723 // u = 0 --> (1-v) s1 + v s1 = s1 !!! not terrible (singular)
724 
725 template <class T>
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)
728 {
729  return u * c2 + (1.0 - v) * c1 + v * c3 - (u * (1.0 - v) * s2 + u * v * s3);
730 }
731 
732 static Vertex TransfiniteTri(Vertex c1, Vertex c2, Vertex c3, const Vertex &s1,
733  Vertex s2, Vertex s3, double u, double v)
734 {
735  Vertex V;
736  V.lc = TRAN_TRI(c1.lc, c2.lc, c3.lc, s1.lc, s2.lc, s3.lc, u, v);
737  V.w = TRAN_TRI(c1.w, c2.w, c3.w, s1.w, s2.w, s3.w, u, v);
738  V.Pos.X =
739  TRAN_TRI(c1.Pos.X, c2.Pos.X, c3.Pos.X, s1.Pos.X, s2.Pos.X, s3.Pos.X, u, v);
740  V.Pos.Y =
741  TRAN_TRI(c1.Pos.Y, c2.Pos.Y, c3.Pos.Y, s1.Pos.Y, s2.Pos.Y, s3.Pos.Y, u, v);
742  V.Pos.Z =
743  TRAN_TRI(c1.Pos.Z, c2.Pos.Z, c3.Pos.Z, s1.Pos.Z, s2.Pos.Z, s3.Pos.Z, u, v);
744  return V;
745 }
746 
747 // New-style:
748 //
749 // f(u,v) = (1-u) (c1(u-v) + c3(1-v) - s1) +
750 // (u-v) (c2(v) + c1(u) - s2) +
751 // v (c3(1-u) + c2(1-u+v) - s3)
752 //
753 // u = v = 0 --> f(0,0) = s1 + s1 - s1 = s1
754 // u = v = 1 --> f(1,1) = s3 + s3 - s3 = s3
755 // u = 1 ; v = 0 --> f(1,1) = s2 + s2 - s2 = s2
756 // v = 0 --> (1-u)c1(u) + u c1(u) = c1(u) --> COOL
757 
758 // FIXME: but what happens when v > u ? You interpolate the curves outside
759 // ubeg/uend... Argh.
760 
761 template <class T>
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,
764  T const v)
765 {
766  return (1.0 - u) * (c1 + c3b - s1) + (u - v) * (c2 + c1b - s2) +
767  v * (c3 + c2b - s3);
768 }
769 
771  Vertex c3, Vertex c3b, Vertex s1, Vertex s2,
772  Vertex s3, double u, double v)
773 {
774  Vertex V;
775  V.lc = TRAN_TRIB(c1.lc, c1b.lc, c2.lc, c2b.lc, c3.lc, c3b.lc, s1.lc, s2.lc,
776  s3.lc, u, v);
777  V.w =
778  TRAN_TRIB(c1.w, c1b.w, c2.w, c2b.w, c3.w, c3b.w, s1.w, s2.w, s3.w, u, v);
779  V.Pos.X = TRAN_TRIB(c1.Pos.X, c1b.Pos.X, c2.Pos.X, c2b.Pos.X, c3.Pos.X,
780  c3b.Pos.X, s1.Pos.X, s2.Pos.X, s3.Pos.X, u, v);
781  V.Pos.Y = TRAN_TRIB(c1.Pos.Y, c1b.Pos.Y, c2.Pos.Y, c2b.Pos.Y, c3.Pos.Y,
782  c3b.Pos.Y, s1.Pos.Y, s2.Pos.Y, s3.Pos.Y, u, v);
783  V.Pos.Z = TRAN_TRIB(c1.Pos.Z, c1b.Pos.Z, c2.Pos.Z, c2b.Pos.Z, c3.Pos.Z,
784  c3b.Pos.Z, s1.Pos.Z, s2.Pos.Z, s3.Pos.Z, u, v);
785  return V;
786 }
787 
788 static void TransfiniteSph(Vertex S, Vertex center, Vertex *T)
789 {
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));
796 
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;
800 
801  T->Pos.X = center.Pos.X + r * dirx;
802  T->Pos.Y = center.Pos.Y + r * diry;
803  T->Pos.Z = center.Pos.Z + r * dirz;
804 }
805 
806 static Vertex InterpolateRuledSurface(Surface *s, double u, double v)
807 {
808  Curve *C[4] = {nullptr, nullptr, nullptr, nullptr};
809 
810  if(!List_Nbr(s->Generatrices)) {
811  Msg::Error("No curves on boundary of ruled surface");
812  return Vertex(0., 0., 0.);
813  }
814 
815  for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) {
816  List_Read(s->Generatrices, i, &C[i]);
817  if(C[i]->Typ == MSH_SEGM_BND_LAYER || C[i]->Typ == MSH_SEGM_DISCRETE) {
818  Msg::Error(
819  "Cannot interpolate ruled surface with discrete bounding curves");
820  return Vertex(0., 0., 0.);
821  }
822  if(!C[i]->beg || !C[i]->end) {
823  Msg::Error("Cannot interpolate ruled surface if bounding curves don't "
824  "have end points");
825  return Vertex(0., 0., 0.);
826  }
827  }
828 
829  Vertex *O = nullptr;
830  bool isSphere = true;
831 
832  // Ugly hack: "fix" transfinite interpolation if we have a sphere
833  // patch
834  if(s->InSphereCenter) {
835  // it's on a sphere: get the center
836  O = s->InSphereCenter;
837  }
838  else {
839  // try to be intelligent (hum)
840  for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) {
841  if(C[i]->Typ != MSH_SEGM_CIRC && C[i]->Typ != MSH_SEGM_CIRC_INV) {
842  isSphere = false;
843  }
844  else if(isSphere) {
845  if(!i) { List_Read(C[i]->Control_Points, 1, &O); }
846  else {
847  Vertex *tmp;
848  List_Read(C[i]->Control_Points, 1, &tmp);
849  if(CompareVertex(&O, &tmp)) isSphere = false;
850  }
851  }
852  }
853  if(isSphere) {
854  double n[3] = {C[0]->Circle.invmat[0][2], C[0]->Circle.invmat[1][2],
855  C[0]->Circle.invmat[2][2]};
856  bool isPlane = true;
857  for(int i = 1; i < std::min(List_Nbr(s->Generatrices), 4); i++)
858  isPlane &= (n[0] == C[i]->Circle.invmat[0][2] &&
859  n[1] == C[i]->Circle.invmat[1][2] &&
860  n[2] == C[i]->Circle.invmat[2][2]);
861  if(isPlane) isSphere = false;
862  }
863  }
864 
865  Vertex *S[4], V[4], VB[3], T;
866  if(s->Typ == MSH_SURF_REGL && List_Nbr(s->Generatrices) >= 4) {
867  S[0] = C[0]->beg;
868  S[1] = C[1]->beg;
869  S[2] = C[2]->beg;
870  S[3] = C[3]->beg;
871  V[0] =
872  InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
873  V[1] =
874  InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
875  V[2] = InterpolateCurve(
876  C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
877  V[3] = InterpolateCurve(
878  C[3], C[3]->ubeg + (C[3]->uend - C[3]->ubeg) * (1. - v), 0);
879  T =
880  TransfiniteQua(V[0], V[1], V[2], V[3], *S[0], *S[1], *S[2], *S[3], u, v);
881  if(isSphere) TransfiniteSph(*S[0], *O, &T);
882  }
883  else if(List_Nbr(s->Generatrices) >= 3) {
884  S[0] = C[0]->beg;
885  S[1] = C[1]->beg;
886  S[2] = C[2]->beg;
887  if(CTX::instance()->geom.oldRuledSurface) {
888  V[0] =
889  InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
890  V[1] =
891  InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
892  V[2] = InterpolateCurve(
893  C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
894  T = TransfiniteTri(V[0], V[1], V[2], *S[0], *S[1], *S[2], u, v);
895  }
896  else {
897  V[0] = InterpolateCurve(
898  C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * (u - v), 0);
899  V[1] =
900  InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
901  V[2] = InterpolateCurve(
902  C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
903  VB[0] =
904  InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
905  VB[1] = InterpolateCurve(
906  C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1 - u + v), 0);
907  VB[2] = InterpolateCurve(
908  C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0);
909  T = TransfiniteTriB(V[0], VB[0], V[1], VB[1], V[2], VB[2], *S[0], *S[1],
910  *S[2], u, v);
911  }
912  if(isSphere) { TransfiniteSph(*S[0], *O, &T); }
913  }
914 
915  return T;
916 }
917 
918 static Vertex InterpolateExtrudedSurface(Surface *s, double u, double v)
919 {
920  Curve *c = FindCurve(s->Extrude->geo.Source);
921 
922  // find position of c in the list of generatrices
923  int num = -1;
924  for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
925  if(c == *(Curve **)List_Pointer(s->Generatrices, i)) {
926  num = i;
927  break;
928  }
929  }
930 
931  Vertex T;
932 
933  if(num < 0) {
934  Msg::Error("Unknown curve in extruded surface");
935  return T;
936  }
937 
938  switch(num) {
939  case 0:
940  T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * u, 0);
941  s->Extrude->Extrude(v, T.Pos.X, T.Pos.Y, T.Pos.Z);
942  return T;
943  case 1:
944  T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * v, 0);
945  s->Extrude->Extrude(1. - u, T.Pos.X, T.Pos.Y, T.Pos.Z);
946  return T;
947  case 2:
948  T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * (1. - u), 0);
949  s->Extrude->Extrude(1. - v, T.Pos.X, T.Pos.Y, T.Pos.Z);
950  return T;
951  default:
952  T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * (1. - v), 0);
953  s->Extrude->Extrude(u, T.Pos.X, T.Pos.Y, T.Pos.Z);
954  return T;
955  }
956 }
957 
958 Vertex InterpolateSurface(Surface *s, double u, double v, int derivee, int u_v)
959 {
960  if(derivee == 1) {
961  Vertex D[4];
962  if(u_v == 1) {
963  if(u - fd_eps < 0.0) {
964  D[0] = InterpolateSurface(s, u, v, 0, 0);
965  D[1] = InterpolateSurface(s, u + fd_eps, v, 0, 0);
966  }
967  else {
968  D[0] = InterpolateSurface(s, u - fd_eps, v, 0, 0);
969  D[1] = InterpolateSurface(s, u, v, 0, 0);
970  }
971  }
972  else {
973  if(v - fd_eps < 0.0) {
974  D[0] = InterpolateSurface(s, u, v, 0, 0);
975  D[1] = InterpolateSurface(s, u, v + fd_eps, 0, 0);
976  }
977  else {
978  D[0] = InterpolateSurface(s, u, v - fd_eps, 0, 0);
979  D[1] = InterpolateSurface(s, u, v, 0, 0);
980  }
981  }
982  return Vertex((D[1].Pos.X - D[0].Pos.X) / fd_eps,
983  (D[1].Pos.Y - D[0].Pos.Y) / fd_eps,
984  (D[1].Pos.Z - D[0].Pos.Z) / fd_eps);
985  }
986  else if(derivee == 2) {
987  Vertex D[2];
988  if(u_v == 1) { // dudu
989  if(u - fd_eps < 0.0) {
990  D[0] = InterpolateSurface(s, u, v, 1, 1);
991  D[1] = InterpolateSurface(s, u + fd_eps, v, 1, 1);
992  }
993  else {
994  D[0] = InterpolateSurface(s, u - fd_eps, v, 1, 1);
995  D[1] = InterpolateSurface(s, u, v, 1, 1);
996  }
997  }
998  else if(u_v == 2) { // dvdv
999  if(v - fd_eps < 0.0) {
1000  D[0] = InterpolateSurface(s, u, v, 1, 2);
1001  D[1] = InterpolateSurface(s, u, v + fd_eps, 1, 2);
1002  }
1003  else {
1004  D[0] = InterpolateSurface(s, u, v - fd_eps, 1, 2);
1005  D[1] = InterpolateSurface(s, u, v, 1, 2);
1006  }
1007  }
1008  else { // dudv
1009  if(v - fd_eps < 0.0) {
1010  D[0] = InterpolateSurface(s, u, v, 1, 1);
1011  D[1] = InterpolateSurface(s, u, v + fd_eps, 1, 1);
1012  }
1013  else {
1014  D[0] = InterpolateSurface(s, u, v - fd_eps, 1, 1);
1015  D[1] = InterpolateSurface(s, u, v, 1, 1);
1016  }
1017  }
1018  return Vertex((D[1].Pos.X - D[0].Pos.X) / fd_eps,
1019  (D[1].Pos.Y - D[0].Pos.Y) / fd_eps,
1020  (D[1].Pos.Z - D[0].Pos.Z) / fd_eps);
1021  }
1022 
1023  if(s->geometry) {
1024  SPoint3 p = s->geometry->point(u, v);
1025  return Vertex(p.x(), p.y(), p.z());
1026  }
1027 
1028  // Warning: we use the exact extrusion formula so we can create exact surfaces
1029  // of revolution. This WILL fail if the surface is transformed after the
1030  // extrusion: in that case set the exactExtrusion option to 0 to use the
1031  // normal code path
1032  if(CTX::instance()->geom.exactExtrusion && s->Extrude &&
1034  && s->Typ != MSH_SURF_BND_LAYER)
1035  return InterpolateExtrudedSurface(s, u, v);
1036 
1037  switch(s->Typ) {
1038  case MSH_SURF_REGL:
1039  case MSH_SURF_TRIC: return InterpolateRuledSurface(s, u, v);
1040  case MSH_SURF_PLAN:
1041  Msg::Error("Should not interpolate plane surface here");
1042  return Vertex(0., 0., 0.);
1043  case MSH_SURF_BND_LAYER:
1044  Msg::Debug("Cannot interpolate boundary layer surface");
1045  return Vertex(0., 0., 0.);
1046  case MSH_SURF_DISCRETE:
1047  Msg::Debug("Cannot interpolate discrete surface");
1048  return Vertex(0., 0., 0.);
1049  default:
1050  Msg::Error("Unknown surface type in interpolation");
1051  return Vertex(0., 0., 0.);
1052  }
1053 }
MSH_SEGM_DISCRETE
#define MSH_SEGM_DISCRETE
Definition: GeoDefines.h:31
D
#define D
Definition: DefaultOptions.h:24
List_Pointer
void * List_Pointer(List_T *liste, int index)
Definition: ListUtils.cpp:152
Geo.h
GeoInterpolation.h
MSH_SEGM_BEZIER
#define MSH_SEGM_BEZIER
Definition: GeoDefines.h:29
Vertex::pntOnGeometry
SPoint2 pntOnGeometry
Definition: Geo.h:40
InterpolateExtrudedSurface
static Vertex InterpolateExtrudedSurface(Surface *s, double u, double v)
Definition: GeoInterpolation.cpp:918
Curve
Definition: Geo.h:74
List_Write
void List_Write(List_T *liste, int index, void *data)
Definition: ListUtils.cpp:120
Surface::Typ
int Typ
Definition: Geo.h:114
MSH_SURF_BND_LAYER
#define MSH_SURF_BND_LAYER
Definition: GeoDefines.h:36
SPoint2
Definition: SPoint2.h:12
MSH_SURF_PLAN
#define MSH_SURF_PLAN
Definition: GeoDefines.h:33
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
Vertex::u
double u
Definition: Geo.h:33
Curve::end
Vertex * end
Definition: Geo.h:85
List_T
Definition: ListUtils.h:9
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
InterpolateCubicSpline
static Vertex InterpolateCubicSpline(Vertex *v[4], double t, double mat[4][4], int derivee, double t1, double t2)
Definition: GeoInterpolation.cpp:30
TRAN_TRI
T TRAN_TRI(T const c1, T const c2, T const c3, T const s1, T const s2, T const s3, T const u, T const v)
Definition: GeoInterpolation.cpp:726
CircParam::invmat
double invmat[3][3]
Definition: Geo.h:70
SPoint3
Definition: SPoint3.h:14
gmshSurface::point
virtual SPoint3 point(double par1, double par2) const =0
List_Nbr
int List_Nbr(List_T *liste)
Definition: ListUtils.cpp:106
Vertex
Definition: Geo.h:29
TransfiniteQua
static Vertex TransfiniteQua(Vertex c1, Vertex c2, Vertex c3, Vertex c4, Vertex s1, Vertex s2, Vertex s3, Vertex s4, double u, double v)
Definition: GeoInterpolation.cpp:685
InterpolateRuledSurface
static Vertex InterpolateRuledSurface(Surface *s, double u, double v)
Definition: GeoInterpolation.cpp:806
CompareVertex
int CompareVertex(const void *a, const void *b)
Definition: Geo.cpp:30
Coord
Definition: Geo.h:25
List_Create
List_T * List_Create(int n, int incr, int size)
Definition: ListUtils.cpp:46
InterpolateBezier
static Vertex InterpolateBezier(Curve *Curve, double u, int derivee)
Definition: GeoInterpolation.cpp:143
GmshMessage.h
TransfiniteTriB
static Vertex TransfiniteTriB(Vertex c1, Vertex c1b, Vertex c2, Vertex c2b, Vertex c3, Vertex c3b, Vertex s1, Vertex s2, Vertex s3, double u, double v)
Definition: GeoInterpolation.cpp:770
ExtrudeParams::geo
struct ExtrudeParams::@15 geo
MSH_SEGM_SPLN
#define MSH_SEGM_SPLN
Definition: GeoDefines.h:21
InterpolateCurve
Vertex InterpolateCurve(Curve *c, double u, int const derivee)
Definition: GeoInterpolation.cpp:441
List_Add
void List_Add(List_T *liste, void *data)
Definition: ListUtils.cpp:90
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
Curve::Control_Points
List_T * Control_Points
Definition: Geo.h:88
Curve::uend
double uend
Definition: Geo.h:87
gmshSurface
Definition: gmshSurface.h:22
Curve::ubeg
double ubeg
Definition: Geo.h:87
Surface::Extrude
ExtrudeParams * Extrude
Definition: Geo.h:124
FindCurve
static Curve * FindCurve(int inum, Tree_T *t)
Definition: Geo.cpp:694
fd_eps
static double const fd_eps
Definition: GeoInterpolation.cpp:12
EXTRUDED_ENTITY
#define EXTRUDED_ENTITY
Definition: ExtrudeParams.h:17
TRAN_QUA
T TRAN_QUA(T const c1, T const c2, T const c3, T const c4, T const s1, T const s2, T const s3, T const s4, T const u, T const v)
Definition: GeoInterpolation.cpp:677
MSH_SEGM_CIRC_INV
#define MSH_SEGM_CIRC_INV
Definition: GeoDefines.h:23
MSH_SEGM_BND_LAYER
#define MSH_SEGM_BND_LAYER
Definition: GeoDefines.h:30
Curve::k
float * k
Definition: Geo.h:90
Numeric.h
Curve::beg
Vertex * beg
Definition: Geo.h:85
MSH_SEGM_NURBS
#define MSH_SEGM_NURBS
Definition: GeoDefines.h:28
Projette
void Projette(Vertex *v, double mat[3][3])
Definition: Geo.h:177
InterpolateSurface
Vertex InterpolateSurface(Surface *s, double u, double v, int derivee, int u_v)
Definition: GeoInterpolation.cpp:958
basisFuns
static void basisFuns(double u, int i, int deg, float *U, double *N)
Definition: GeoInterpolation.cpp:400
TransfiniteSph
static void TransfiniteSph(Vertex S, Vertex center, Vertex *T)
Definition: GeoInterpolation.cpp:788
Surface
Definition: Geo.h:111
MSH_SURF_DISCRETE
#define MSH_SURF_DISCRETE
Definition: GeoDefines.h:38
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
InterpolateUBS
static Vertex InterpolateUBS(Curve *Curve, double u, int derivee)
Definition: GeoInterpolation.cpp:220
List_Delete
void List_Delete(List_T *liste)
Definition: ListUtils.cpp:66
ExtrudeParams::Mode
int Mode
Definition: ExtrudeParams.h:49
Vertex::lc
double lc
Definition: Geo.h:33
MSH_SURF_REGL
#define MSH_SURF_REGL
Definition: GeoDefines.h:34
Curve::mat
double mat[4][4]
Definition: Geo.h:84
MSH_SEGM_ELLI_INV
#define MSH_SEGM_ELLI_INV
Definition: GeoDefines.h:25
ExtrudeParams::Extrude
void Extrude(int iLayer, int iElemLayer, double &dx, double &dy, double &dz)
Definition: ExtrudeParams.cpp:51
S
#define S
Definition: DefaultOptions.h:21
Curve::geometry
gmshSurface * geometry
Definition: Geo.h:93
ExtrudeParams::Source
int Source
Definition: ExtrudeParams.h:51
MSH_SEGM_CIRC
#define MSH_SEGM_CIRC
Definition: GeoDefines.h:22
MSH_SURF_TRIC
#define MSH_SURF_TRIC
Definition: GeoDefines.h:35
TransfiniteTri
static Vertex TransfiniteTri(Vertex c1, Vertex c2, Vertex c3, const Vertex &s1, Vertex s2, Vertex s3, double u, double v)
Definition: GeoInterpolation.cpp:732
SPoint2::x
double x(void) const
Definition: SPoint2.h:86
Coord::X
double X
Definition: Geo.h:26
Context.h
O
#define O
Definition: DefaultOptions.h:22
findSpan
int findSpan(double u, int deg, int n, float *U)
Definition: GeoInterpolation.cpp:381
Coord::Z
double Z
Definition: Geo.h:26
MSH_SEGM_BSPLN
#define MSH_SEGM_BSPLN
Definition: GeoDefines.h:27
InterpolateNurbs
static Vertex InterpolateNurbs(Curve *Curve, double u, int derivee)
Definition: GeoInterpolation.cpp:421
Coord::Y
double Y
Definition: Geo.h:26
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
Vertex::Pos
Coord Pos
Definition: Geo.h:34
TRAN_TRIB
T TRAN_TRIB(T const c1, T const c1b, T const c2, T const c2b, T const c3, T const c3b, T const s1, T const s2, T const s3, T const u, T const v)
Definition: GeoInterpolation.cpp:762
Surface::Generatrices
List_T * Generatrices
Definition: Geo.h:120
Surface::geometry
gmshSurface * geometry
Definition: Geo.h:129
MSH_SEGM_ELLI
#define MSH_SEGM_ELLI
Definition: GeoDefines.h:24
Curve::degre
int degre
Definition: Geo.h:91
Surface::InSphereCenter
Vertex * InSphereCenter
Definition: Geo.h:123
c1
const double c1
Definition: GaussQuadratureHex.cpp:16
InterpolateCatmullRom
static void InterpolateCatmullRom(Vertex *v[4], double t, Vertex &V)
Definition: GeoInterpolation.cpp:14
Vertex::w
double w
Definition: Geo.h:33
List_Read
void List_Read(List_T *liste, int index, void *data)
Definition: ListUtils.cpp:111
MSH_SEGM_LINE
#define MSH_SEGM_LINE
Definition: GeoDefines.h:20
SPoint2::y
double y(void) const
Definition: SPoint2.h:88
Curve::Circle
CircParam Circle
Definition: Geo.h:92