MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
CAD4FE_PolyCurve.cpp
Aller à la documentation de ce fichier.
1 //####//------------------------------------------------------------
2 //####//------------------------------------------------------------
3 //####// MAGiC
4 //####// Jean Christophe Cuilliere et Vincent FRANCOIS
5 //####// Departement de Genie Mecanique - UQTR
6 //####//------------------------------------------------------------
7 //####// MAGIC est un projet de recherche de l equipe ERICCA
8 //####// du departement de genie mecanique de l Universite du Quebec a Trois Rivieres
9 //####// http://www.uqtr.ca/ericca
10 //####// http://www.uqtr.ca/
11 //####//------------------------------------------------------------
12 //####//------------------------------------------------------------
13 //####//
14 //####// CAD4FE_PolyCurve.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:58:54 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 
23 
24 #include "gestionversion.h"
25 #include "mg_geometrie.h"
26 #include "mg_gestionnaire.h"
27 #include "mg_arete.h"
28 #include "lc_point.h"
29 #include "tpl_fonction.h"
31 #include "ot_decalage_parametre.h"
33 
34 
35 #include <map>
36 #include <ostream>
37 #include <string>
38 #include <vector>
39 #include <sstream>
40 
41 
42 #pragma hdrstop
43 
44 #include "CAD4FE_PolyCurve.h"
45 
46 
47 #pragma package(smart_init)
48 
49 #include <math.h>
50 
51 #ifdef __BORLANDC__
52 #pragma warn -8012
53 #pragma warn -8037
54 #endif
55 
56 using namespace CAD4FE;
57 
59 {
60 
61 }
62 
64 {
65  t_min = (0);
66  t_max = (-1);
67  InsertCurve( __edge );
68 }
69 
71 {
72  t_min = (0);
73  t_max = (0);
74  lst_vertices.push_back(__vertex);
75  lst_length.push_back(0);
76 }
77 
78 double
80 {
81  return __edge->get_longueur(__edge->get_tmin(), __edge->get_tmax());
82 }
83 
84 double
85 PolyCurve::GetLength(unsigned __index)
86 {
87  return lst_length[__index];
88 }
89 
90 double equation_longueur(MG_ARETE & __edge,double t)
91 {
92  PolyCurve::VerifyRefEdgeT(&__edge, t);
93  double dxyz[3];
94  __edge.deriver(t,dxyz);
95  return sqrt(dxyz[0]*dxyz[0]+dxyz[1]*dxyz[1]+dxyz[2]*dxyz[2]);
96 }
97 
98 
99 MG_ARETE * PolyCurve::GetRefEdge(unsigned int __index)
100 {
101  return lst_ref_edges[__index];
102 }
103 
104 MG_SOMMET * PolyCurve::GetRefVertex(unsigned int __index)
105 {
106  return lst_vertices[__index];
107 }
108 
110 {
111  return lst_ref_edges.size();
112 }
113 
115 {
116  return lst_vertices.size();
117 }
118 
119 
121 {
122  return ( std::find(lst_ref_edges.begin(),lst_ref_edges.end(),__refEdge) != lst_ref_edges.end());
123 }
124 
126 {
127  return ( std::find(lst_vertices.begin(),lst_vertices.end(),__v) != lst_vertices.end());
128 }
129 
131 {
132  if (__topo->get_dimension() == 0)
133  return ContainsRefVertex((MG_SOMMET *)__topo);
134  if (__topo->get_dimension() == 1)
135  return ContainsRefEdge((MG_ARETE *)__topo);
136  return false;
137 }
138 
139 void
140 PolyCurve::VerifyRefEdgeT(MG_ARETE * __edge, double & __t)
141 {
142  double t1 = __edge->get_tmin();
143  double t2 = __edge->get_tmax();
144 
145  if ( __edge->get_courbe()->est_periodique() )
146  {
147  if (__t > t2 )
148  __t -= __edge->get_courbe()->get_periode();
149  if (__t < t1 )
150  __t += __edge->get_courbe()->get_periode();
151  }
152  else
153  {
154  double tStart=(t1<t2)?t1:t2;
155  double tEnd=(t1>t2)?t1:t2;
156  if (__t > tEnd )
157  __t = tEnd;
158  if (__t < tStart )
159  __t = tStart;
160  }
161 }
162 
163 void
164 PolyCurve::inverser(double & __t, double __point[3], double precision, bool __curvilinearLength)
165 {
166  int j;
167  double s;
168 
169  double edge_length = t_max;
170 
171  // Test wether the requested point is coincident with a vertex of the polyline
172  for (std::vector<MG_SOMMET *>::iterator it_vertex = lst_vertices.begin();
173  it_vertex != lst_vertices.end();
174  it_vertex++)
175  {
176  double vertex_point [3];
177  MG_SOMMET * vertex = *it_vertex;
178  vertex->get_point()->evaluer(vertex_point);
179 
180  for (j = 0; j < 3; j++)
181  if (fabs(vertex_point[j] - __point[j]) > edge_length*precision)
182  break;
183 
184  if ( j == 3 )
185  {
186  unsigned iVertex = std::distance ( lst_vertices.begin(), it_vertex );
187  s = 0;
188  for (unsigned k = 0; k < iVertex; k++)
189  s += lst_length[k];
190 
191  __t = s;
192 
193  return;
194  }
195  }
196 
197  // If the requested point is not on a vertex
198  // then test the reference edges
199  unsigned iClosestEdge;
200  double tClosestEdge = 0;
201  double min_distance = 1E99;
202  MG_ARETE * edge;
203  for (std::vector <MG_ARETE *>::iterator it_edge = lst_ref_edges.begin();
204  it_edge != lst_ref_edges.end();
205  it_edge++)
206  {
207  edge = *it_edge;
208  double t_edge;
209  //edge->inverser ( t_edge, __point );
210  MG_ARETE_ClosestPointOn func(__point, edge);
211  t_edge = func.Find();
212  double xEdge = (t_edge-edge->get_tmin())/(edge->get_tmax()-edge->get_tmin());
213  if (xEdge>1) t_edge = edge->get_tmax();
214  if (xEdge<0) t_edge = edge->get_tmin();
215  double point[3];
216  edge->evaluer (t_edge, point );
217  double distance = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(point, __point);
218  if (distance < min_distance)
219  {
220  min_distance = distance;
221  iClosestEdge = std::distance (lst_ref_edges.begin(), it_edge );
222  tClosestEdge = t_edge;
223  }
224  }
225 
226  Parameter_RefEdgeTToS ( tClosestEdge, lst_ref_edges[iClosestEdge], &s, __curvilinearLength);
227 
228  __t = s;
229 
230  return;
231 }
232 
233 bool PolyCurve::est_sur_courbe(double* xyz, double precision)
234 {
235  std::cout <<" *** PolyCurve::est_sur_courbe : FONCTION NON IMPLEMENTE ***" << std::endl;
236  return false;
237 }
238 
239 
240 void
241 PolyCurve::VerifyS(double & __s)
242 {
243  if ( est_periodique() )
244  {
245  while (__s > get_tmax() )
246  __s -= get_periode();
247  }
248  else
249  {
250  if (__s > get_tmax() )
251  __s = get_tmax();
252  }
253 }
254 
255 double
257 {
258  int N = RefVertex_GetIndex(__refVertex);
259  double s;
260  s=0;
261  for (int i=0;i<N;i++)
262  s += GetLength(i);
263 
264  return s;
265 }
266 
267 void
268 PolyCurve::RefEdge_GetT(unsigned __iEdge,
269  double __s,
270  double *__t, double *__dt, bool __curvilinearLength
271  )
272 {
273  double t1,t2;
274  MG_SOMMET * vertex = lst_vertices[ __iEdge ];
275  MG_ARETE * edge = lst_ref_edges[ __iEdge ];
276 
277  if (vertex == edge->get_cosommet1()->get_sommet())
278  {
279  t1=edge->get_tmin();
280  t2=edge->get_tmax();
281  }
282  else
283  {
284  t1=edge->get_tmax();
285  t2=edge->get_tmin();
286  }
287 
288  if ( __curvilinearLength == false )
289  {
290  *__dt = (t2 - t1) / GetLength( __iEdge );
291  *__t = t1 + __s * (*__dt);
292  }
293  else
294  {
296  double s = __s;
297  double increment = s/t_max*(t2-t1)/40;
298  if (increment < 1E-4 * (t2-t1))
299  {
300  *__dt = (t2 - t1) / GetLength( __iEdge );
301  *__t = t1 + __s * (*__dt);
302 
303  return;
304  }
305  longueur_bsp.integrer_jusqua_gauss_2(t1, increment, s, __t);
306  *__dt = (*__t - t1) / s;
307  }
308 }
309 
310 void
311 PolyCurve::RefEdge_GetS(unsigned __iEdge,
312  double __t,
313  double *__s, bool __curvilinearLength
314  )
315 {
316  double t1,t2;
317  MG_SOMMET * vertex = lst_vertices[ __iEdge ];
318  MG_ARETE * edge = lst_ref_edges[ __iEdge ];
319  double period=edge->get_courbe()->get_periode();
320 
321  t1=edge->get_tmin();
322  t2=edge->get_tmax();
323 
324  if (edge->get_courbe()->est_periodique())
325  {
326  if (__t < t1 - period*1E-6)
327  __t += period;
328  }
329 
330  if ( __curvilinearLength == false)
331  {
332  if (vertex == edge->get_cosommet1()->get_sommet())
333  *__s = lst_length[__iEdge] * (__t-t1)/(t2-t1);
334  else
335  *__s = lst_length[__iEdge] * (__t-t2)/(t1-t2);
336  }
337  else
338  {
339  if (vertex == edge->get_cosommet1()->get_sommet())
340  *__s = edge->get_longueur(t1,__t);
341  else
342  *__s = edge->get_longueur(__t,t2);
343  }
344 }
345 
346 void
348 {
349  if (lst_ref_edges.size() == 0)
350  {
351  lst_ref_edges.push_back ( __edge );
352  lst_length.push_back ( GetLength(__edge) );
353  lst_vertices.push_back ( __edge->get_cosommet1()->get_sommet());
354  lst_vertices.push_back ( __edge->get_cosommet2()->get_sommet());
355  t_min = 0;
356  t_max = lst_length[0];
357  return;
358  }
359 
360  // Get the two vertices of this edge
361  MG_SOMMET * V[2];
362  int iV[2], // index of V[i] in lst_vertices[] ie. V [ i ] == lst_vertices[ iV[ i ] ]
363  iiVc=-1, // index < 2 of the common vertex in V[0,1] ie. if (iVc != -1) V [ iiVc ] == lst_vertices[ iV[ iiVc ] ]
364  iiVo=-1; // index < 2 of the other vertex in V[0,1] ie. if (iVo != -1) V [ iiVo ] == lst_vertices[ iV[ iiVo ] ]
365  V[0] = __edge->get_cosommet1()->get_sommet();
366  V[1] = __edge->get_cosommet2()->get_sommet();
367 
368  // Verify wether the vertices are already referenced in
369  // the polycurve
370  std::vector<MG_SOMMET*>::iterator itV[2];
371  for (int i=0; i<2; i++)
372  {
373  itV[i] = std::find (lst_vertices.begin(), lst_vertices.end(), V[i]);
374  if (itV[i] != lst_vertices.end())
375  { // V[i] is already in a curve of the polycurve
376  iV[i] = std::distance(lst_vertices.begin(), itV[i]);
377  if (iiVc == -1)
378  iiVc = i;
379  else
380  {
381  if (iV[iiVc] == 0)
382  { // case of a periodic polycurve : two vertices are common, the
383  // common vertex should be the last vertex of this polycurve (iV[iiVc]=N-1),
384  // and the other vertex the first vertex of this polycurve (iV[iiVo]=0)
385  iiVo = iiVc;
386  iiVc = i;
387  }
388  else
389  {
390  iiVo = i;
391  }
392  }
393 
394  if ( iV[i] != 0 && iV[i]+1 != (int)lst_vertices.size() )
395  {
396  printf (" Error in PolyCurve::InsertCurve : can't insert a MG_ARETE (extremities = %lu, %lu) not adjacent to the extremities of this PolyCurve (extremities = %lu, %lu)\n", __edge->get_cosommet1()->get_sommet()->get_id(), __edge->get_cosommet2()->get_sommet()->get_id(), get_sommet1()->get_id(), get_sommet2()->get_id());
397  return;
398  }
399  }
400  else // vertex V[i] not found
401  {
402  iV[i] = -1;
403  iiVo = i;
404  }
405  }
406 
407 
408  if (iiVc == -1)
409  {
410  printf (" Error in PolyCurve::InsertCurve : the curve requested to append is not connected to the existing polycurve\n");
411  return;
412  }
413 
414  if ( iV [iiVc] == 0 ) // the inserted curve is adjacent to the first vertex of the polycurve
415  {
416  std::reverse(lst_ref_edges.begin(), lst_ref_edges.end());
417  std::reverse(lst_vertices.begin(), lst_vertices.end());
418  std::reverse(lst_length.begin(), lst_length.end());
419  InsertCurve(__edge);
420  }
421  else if ( iV [iiVc]+1 == lst_vertices.size() ) // the inserted curve is adjacent to the last vertex of the polycurve
422  {
423  lst_vertices.push_back ( V [ iiVo ] );
424  lst_ref_edges.push_back ( __edge );
425  lst_length.push_back ( GetLength(__edge) );
426  }
427  else
428  {
429  printf("PolyCurve::InsertCurve Error : the edge %lu is neither adjacent to end vertex nor to start vertex of polycurve %lu\n", __edge->get_id(), get_id());
430  printf("Polycurve Start vertex = %lu, End vertex = %lu\n", get_sommet1()->get_id(),get_sommet2()->get_id());
431  printf("Edge Start vertex = %lu, End vertex = %lu\n", V[0]->get_id(), V[1]->get_id());
432  return;
433  }
434 
435  // update t_max
436  t_max = 0;
437  for (std::vector<double>::const_iterator it_length = lst_length.begin();
438  it_length != lst_length.end();
439  it_length++)
440  t_max += (*it_length);
441 
442 }
443 
444 void
445 PolyCurve::Parameter_SToRefEdgeT (double __s, unsigned * __iEdge, double *__t, double *__dt, bool __curvilinearLength)
446 {
447  double s;
448  unsigned i;
449 
450  VerifyS(__s);
451 
452  i=0;
453  s=0;
454  while (s + GetLength(i) < __s && i+1 < lst_ref_edges.size() )
455  {
456  s += GetLength(i);
457  i++;
458  }
459 
460  RefEdge_GetT(i, __s - s, __t, __dt, __curvilinearLength);
461  *__iEdge = i;
462 }
463 
464 void
465 PolyCurve::Parameter_SToRefEdgeT (double __s, MG_ARETE ** __edge, double *__t, double *__dt, bool __curvilinearLength)
466 {
467  unsigned iEdge;
468  Parameter_SToRefEdgeT(__s, &iEdge, __t, __dt, __curvilinearLength);
469  *__edge = GetRefEdge(iEdge);
470 }
471 
472 unsigned
474 {
475  unsigned i = std::distance ( lst_ref_edges.begin(), std::find ( lst_ref_edges.begin(), lst_ref_edges.end(), __edge) );
476  return i;
477 }
478 
479 unsigned
481 {
482  unsigned i = std::distance ( lst_vertices.begin(), std::find ( lst_vertices.begin(), lst_vertices.end(), __vertex) );
483  return i;
484 }
485 
486 void
487 PolyCurve::Parameter_RefEdgeTToS (double __t, MG_ARETE * __edge, double *__s, bool __curvilinearLength)
488 {
489  double s, ds;
490  unsigned i;
491 
492  i = RefEdge_GetIndex(__edge);
493 
494  s=0;
495  for ( unsigned k = 0; k < i; k++)
496  {
497  s += GetLength(k);
498  }
499  RefEdge_GetS(i, __t, &ds, __curvilinearLength);
500  s += ds;
501 
502  *__s = s;
503 }
504 
505 void
506 PolyCurve::evaluer (double __s, double __X[3])
507 {
508  bool curvilinearLength = false;
509  evaluer(__s, __X, curvilinearLength);
510 }
511 
512 void
513 PolyCurve::evaluer (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
514 {
515  if (IsPoint())
516  {
517  lst_vertices[0]->get_point()->evaluer(__X);
518  return;
519  }
520 
521  VerifyS (__s);
522  unsigned iEdge;
523  MG_ARETE * edge;
524  double t, dt;
525  Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
526  edge = lst_ref_edges [ iEdge ];
527  PolyCurve::VerifyRefEdgeT(edge, t);
528  edge->evaluer ( t, __X );
529 }
530 
531 void
532 PolyCurve::deriver (double __s, double __X[3]) // curvilinear abcissa
533 {
534  bool curvilinearLength = false;
535  deriver(__s, __X, curvilinearLength);
536 }
537 
538 void
539 PolyCurve::deriver (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
540 {
541  if (IsPoint())
542  {
543  for (int i=0;i<3;i++) __X[i] = 1;
544  return;
545  }
546 
547  VerifyS (__s);
548  unsigned iEdge;
549  MG_ARETE * edge;
550  double t, dt;
551  Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
552  edge = lst_ref_edges [ iEdge ];
553  PolyCurve::VerifyRefEdgeT(edge, t);
554  edge->deriver ( t, __X );
555 
556  // dC/ds = dC/dt * dt/ds
557  for (int i = 0; i<3; i++)
558  __X[i] *= dt;
559 }
560 
561 
562 void
563 PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz) // curvilinear abcissa
564 {
565  bool curvilinearLength = false;
566  deriver_seconde(__s, __ddxyz, __dxyz, __xyz, curvilinearLength);
567 
568 }
569 void
570 PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz, bool __curvilinearLength) // curvilinear abcissa
571 {
572  unsigned iEdge;
573  MG_ARETE * edge;
574  double t, dt;
575 
576  if (IsPoint())
577  {
578  if (__ddxyz) for (int i=0;i<3;i++) __ddxyz[i]=1;
579  if (__dxyz) for (int i=0;i<3;i++) __dxyz[i]=1;
580  evaluer(0,__xyz);
581  return;
582  }
583 
584  VerifyS (__s);
585 
586  Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
587  edge = lst_ref_edges [ iEdge ];
588 
589  for (int i=0; i<3; i++)
590  __ddxyz[i] = 0;
591 
592  if (__dxyz)
593  edge->deriver(t, __dxyz);
594  // dC/ds = dC/dt * dt/ds
595  for (int i = 0; i<3; i++)
596  __dxyz[i] *= dt;
597 
598  if (__xyz)
599  edge->evaluer(t, __xyz);
600 }
601 
602 
603 
604 void
606 {
607  if (lst_vertices.size() == 0)
608  {
609  for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
610  it != __polycurve.lst_ref_edges.end();
611  it++ )
612  InsertCurve ( *it );
613  }
614  else if (get_sommet2() == __polycurve.get_sommet2() || get_sommet1() == __polycurve.get_sommet2() )
615  {;
616  for (std::vector < MG_ARETE * >::reverse_iterator it = __polycurve.lst_ref_edges.rbegin();
617  it != __polycurve.lst_ref_edges.rend();
618  it++)
619  InsertCurve ( *it );
620  }
621  else if ( get_sommet1() == __polycurve.get_sommet1() || get_sommet2() == __polycurve.get_sommet1() )
622  {
623  for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
624  it != __polycurve.lst_ref_edges.end();
625  it++ )
626  InsertCurve ( *it );
627  }
628  else
629  {
630  printf("PolyCurve::Merge Error : the polycurve %lu is neither adjacent to end vertex nor to start vertex of polycurve %lu\n", __polycurve.get_id(), get_id());
631  printf("Polycurve Start vertex = %lu, End vertex = %lu\n", get_sommet1()->get_id(),get_sommet2()->get_id());
632  printf("Other __polycurve Start vertex = %lu, End vertex = %lu\n", __polycurve.get_sommet1()->get_id(), __polycurve.get_sommet2()->get_id());
633  return;
634 
635  }
636 }
637 
638 void
640 {
641  if ( est_periodique() == false)
642  return;
643 
644  std::vector<MG_ARETE*> e;
645  std::vector<MG_SOMMET*> v;
646  std::vector<double> l;
647  unsigned k=RefVertex_GetIndex(__v);
648  unsigned N=lst_vertices.size();
649  for (unsigned i=0; i<N; i++)
650  {
651  unsigned m = (i+k)%N;
652  unsigned n = (i+k+1)%N;
653  MG_SOMMET * tempv = lst_vertices[ m ];
654  MG_SOMMET * lastV = (v.size()) ? v[v.size()-1] : 0;
655  if ( lastV && lastV == tempv )
656  tempv = lst_vertices[n];
657  v.push_back(tempv);
658  }
659  for (unsigned i=0; i+1<N; i++)
660  e.push_back(lst_ref_edges[ (i+k)%(N-1) ]);
661  for (unsigned i=0; i+1<N; i++)
662  l.push_back(lst_length[ (i+k)%(N-1) ]);
663  lst_vertices = v;
664  lst_ref_edges = e;
665  lst_length = l;
666 }
667 
668 double
669 PolyCurve::get_longueur (double __s_min, double __s_max, double precision)
670 {
671  double result;
672  if ( __s_min >= 0 && __s_max >= 0 )
673  return fabs (__s_min - __s_max);
674  else
675  {
676  return t_max;
677  }
678 }
679 
681 {
682  return t_min;
683 }
684 
686 {
687  return t_max;
688 }
689 
690 MG_SOMMET *
692 {
693  return lst_vertices[0];
694 }
695 
696 
697 MG_SOMMET *
699 {
700  return lst_vertices[lst_vertices.size()-1];
701 }
702 
703 double
705 {
706  return get_tmin();
707 }
708 
709 
710 double
712 {
713  return get_tmax();
714 }
715 
716 void
717 PolyCurve::inverser(double & __t, double __point[3], double precision)
718 {
719  bool curvilinearLength = false;
720 
721  inverser(__t, __point, precision, curvilinearLength);
722 }
723 
725 {
726  if ( get_sommet1 () == get_sommet2 () )
727  return 1;
728  else
729  return 0;
730 }
731 
733 {
734  if ( est_periodique() )
735  return get_longueur();
736  else
737  return 0;
738 }
739 
740 
742 {
743  return 4343; // TYPE = Poly curve
744 }
745 
746 void PolyCurve::enregistrer(std::ostream& o,double version)
747 {
748  unsigned int i;
749 
750  if (IsPoint() == false)
751  {
752  o << "%" << get_id()
753  << "=CAD4FE_POLYCURVE(" << GetRefEdgeCount() << ",(";
754 
755  for (i=0; i < GetRefEdgeCount(); i++)
756  {
757  if ( i ) o <<",";
758  o << "$" << GetRefEdge(i)->get_id();
759  }
760 
761  o << "));" << std::endl;
762  }
763  else // The polycurve is a point !
764  {
765  o << "%" << get_id() << "=CAD4FE_POLYCURVE(0,($"<<GetRefVertex(0)->get_id()<<"));"<< std::endl;
766  }
767 }
768 
769  std::vector<MG_ARETE*> &
771 {
772  return lst_ref_edges;
773 }
774 
775 void
776 CAD4FE::SplitRefEdge(MG_ARETE * __refEdge, MG_SOMMET * __refVertex1, MG_SOMMET * __refVertex2, double __xyz[3], MG_VOLUME * __refBody, MG_GEOMETRIE * __geom, MG_ARETE * edges[2], MG_SOMMET ** __splitVertex)
777 {
778  int i,j;
779  double tSplit;
780  MG_ARETE * splitEdge = __refEdge;
781  splitEdge->inverser(tSplit, __xyz);
782 
783  // Create the split vertex at position xyz
784  MG_POINT * point = new LC_POINT(__xyz);
785  __geom->ajouter_mg_point(point);
786  std::ostringstream idoriginal;
787  idoriginal << "Vertex of "<< splitEdge->get_idoriginal() <<" split at t="<<tSplit;
788  MG_SOMMET * splitVertex = new MG_SOMMET(idoriginal.str(), point);
789  *__splitVertex = splitVertex;
790  __geom->ajouter_mg_sommet(splitVertex);
791 
792  // split the edge in two edges
793  MG_COURBE * curves[2];
794  MG_SOMMET * vertices[2][2];
795  MG_COSOMMET * cov[2][2];
796 
797  vertices[0][0] = splitEdge->get_cosommet1()->get_sommet();
798  vertices[0][1] = splitVertex;
799  vertices[1][0] = splitVertex;
800  vertices[1][1] = splitEdge->get_cosommet2()->get_sommet();
801 
802  curves[0] = curves[1] = splitEdge->get_courbe();
803 
804  double verticesT[2][2];
805  verticesT[0][0] = splitEdge->get_tmin();
806  verticesT[1][1] = splitEdge->get_tmax();
807  verticesT[0][1] = verticesT[1][0] = tSplit;
808 
809  // create two edges
810  for (i=0; i<2; i++)
811  {
812  // orientation
813  int orientation = splitEdge->get_orientation();
814  // Create an edge using the start vertex and the split vertex
815  std::ostringstream idoriginal;
816  idoriginal << __refEdge->get_idoriginal();
817  idoriginal << " split with t0 " << verticesT[i][0] << " t1 " << verticesT[i][1];
818  edges[i] = new MG_ARETE (idoriginal.str(), 0, curves[i], orientation);
819  __geom->ajouter_mg_arete (edges[i]);
820  // create covertices
821  for (j=0;j<2;j++)
822  {
823  cov[i][j] = __geom->ajouter_mg_cosommet (edges[i], vertices[i][j]);
824  }
825 
826  edges[i]->changer_cosommet1(cov[i][0]);
827  edges[i]->changer_cosommet2(cov[i][1]);
828  }
829 
830  MG_BOUCLE * split_edge_loops[10];
831  int nb_split_edge_loops = 0;
832  MG_COARETE * split_edge_coedges[10], * coedges[20];
833  int nb_split_edge_coedges = 0, nb_coedges = 0;
834  // create four coedges (in manifold body case)
835  // replace each coedges belong to initial edge in both loops of the ref faces
836  //
837  // for each shell of the ref body
838  unsigned nb_shells = __refBody->get_nb_mg_coquille ();
839  for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
840  {
841  MG_COQUILLE * shell = __refBody->get_mg_coquille(it_shells);
842  // for each coface->face F of the shell
843  unsigned nb_coface = shell->get_nb_mg_coface();
844  for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
845  {
846  MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
847 
848  // for each loop L of this face
849  unsigned nb_loop = face->get_nb_mg_boucle();
850  for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
851  {
852  MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
853  // for each coedge coe of L
854  unsigned nb_edge = loop->get_nb_mg_coarete();
855  for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
856  {
857  MG_COARETE * coedge = loop->get_mg_coarete(it_edge);
858  MG_ARETE * edge = coedge->get_arete();
859 
860  // if coe contains split_edge
861  if (edge == splitEdge)
862  {
863  split_edge_loops[ nb_split_edge_loops++ ] = loop;
864  split_edge_coedges[ nb_split_edge_coedges++ ] = coedge;
865  // create coe[0] ( edges[0], F, coe->sense )
866  // create coe[1] ( edges[1], F, coe->sense )
867  // delete coe in L
868  // add coe[0] in L
869  // add coe[1] in L
870  for (i=0; i<2; i++)
871  {
872  coedges[nb_coedges++] = __geom->ajouter_mg_coarete (edges[i], loop, coedge->get_orientation());
873  loop->ajouter_mg_coarete(coedges[nb_coedges-1]);
874  }
875 
876  loop->supprimer_mg_coarete(coedge);
877  __geom->supprimer_mg_coarete(coedge);
878  }
879  // fi
880  }
881  }
882  }
883  }
884 
885 }
886 
887 void
888 CAD4FE::SplitPolyCurve(PolyCurve * __polyCurve, double __xyz[3], MG_VOLUME * __refBody, MG_GEOMETRIE * __geom, PolyCurve * __result[2], MG_ARETE **__origRefEdge, MG_SOMMET ** __splitRefVertex, MG_ARETE * __splitRefEdges[2])
889 {
890  int i,j;
891  *__splitRefVertex = NULL;
892  __splitRefEdges[0]=__splitRefEdges[1]=NULL;
893 
894  // get the parameter of __splitVertex
895  double sSplitVertex;
896  __polyCurve->inverser(sSplitVertex,__xyz,1E-6);
897 
898  unsigned index; // index of the reference edge split
899  double tEdge, dtEdge; // real parameter of the reference edge split
900  __polyCurve->Parameter_SToRefEdgeT(sSplitVertex,&index,&tEdge,&dtEdge, false);
901  *__origRefEdge = __polyCurve->GetRefEdge(index);
902  MG_SOMMET * v[2];
903  v[0] = __polyCurve->GetRefVertex(index);
904  v[1] = __polyCurve->GetRefVertex(index+1);
905 
906  // Test wether __xyz is located on one extremity of the ref edge
907  for (i=0; i<2; i++)
908  {
909  double v_xyz[3];
910 
911  v[i]->get_point()->evaluer(v_xyz);
912 
913  if (OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__xyz, v_xyz) / __polyCurve->GetLength(index) < 1E-6)
914  {
915  if (index+i == 0 || index+i+1 == __polyCurve->GetRefVertexCount())
916  {
917  printf("Can't split a polycurve on vertex ID %lu because its extremities are vertices : %lu and %lu\n", v[i]->get_id(), __polyCurve->GetRefVertex(0)->get_id(), __polyCurve->GetRefVertex(__polyCurve->GetRefVertexCount()-1)->get_id());
918  return;
919  }
920 
921  *__origRefEdge = NULL;
922  *__splitRefVertex = v[i];
923  __splitRefEdges[0] = __polyCurve->GetRefEdge(index-1+i);
924  __splitRefEdges[1] = __polyCurve->GetRefEdge(index+i);
925 
926  // create the two polyCurves
927  for (int k=0; k<2; k++)
928  {
929  // create polycurve
930  __result[k] = new PolyCurve ( __splitRefEdges[k] );
931  __geom->ajouter_mg_courbe(__result[k]);
932  for (j = (k==0)?index-2+i:index+i+1; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*k)
933  __result[k]->InsertCurve(__polyCurve->GetRefEdge(j));
934  }
935 
936  break;
937  }
938  }
939  if (*__splitRefVertex == NULL)
940  {
941  CAD4FE::SplitRefEdge(*__origRefEdge, v[0], v[1], __xyz, __refBody, __geom, __splitRefEdges, __splitRefVertex);
942 
943  if ( __splitRefEdges[0]->get_cosommet1()->get_sommet() != v[0] && __splitRefEdges[0]->get_cosommet2()->get_sommet() != v[0] )
944  std::swap(__splitRefEdges[0], __splitRefEdges[1] );
945 
946  // create the two polyCurves
947  for (i=0; i<2; i++)
948  {
949  // create polycurve
950  __result[i] = new PolyCurve ( __splitRefEdges[i] );
951  __geom->ajouter_mg_courbe(__result[i]);
952  for (j = index-1+2*i; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*i)
953  __result[i]->InsertCurve(__polyCurve->GetRefEdge(j));
954  }
955  }
956 
957  if (__result[0]->get_sommet1() !=__result[1]->get_sommet1() &&__result[0]->get_sommet1() !=__result[1]->get_sommet2() &&
958  __result[0]->get_sommet2() !=__result[1]->get_sommet1() &&__result[0]->get_sommet2() !=__result[1]->get_sommet2())
959  printf("Error");
960 
961 }
962 
963 bool PolyCurve::IsPoint() const
964 {
965  return lst_vertices.size() == 1 && lst_ref_edges.size() == 0;
966 }
967 
968 void
970 {
971 return;
972 }
973 
974 
975 
CAD4FE::PolyCurve::inverser
void inverser(double &__t, double __point[3], double precision)
Definition: CAD4FE_PolyCurve.cpp:717
MG_ARETE::changer_cosommet2
virtual void changer_cosommet2(class MG_COSOMMET *cosom)
Definition: mg_arete.cpp:77
MG_ARETE::get_cosommet2
virtual class MG_COSOMMET * get_cosommet2(void)
Definition: mg_arete.cpp:85
CAD4FE::PolyCurve::get_longueur
double get_longueur(double __s_min=-1, double __s_max=-1, double precision=1E-6)
Definition: CAD4FE_PolyCurve.cpp:669
MG_COURBE::est_periodique
virtual int est_periodique(void)=0
mg_geometrie.h
CAD4FE::PolyCurve::VerifyS
void VerifyS(double &__s)
Definition: CAD4FE_PolyCurve.cpp:241
MG_VOLUME::get_nb_mg_coquille
virtual int get_nb_mg_coquille(void)
Definition: mg_volume.cpp:65
CAD4FE::PolyCurve::SetPeriodicPoleRefVertex
void SetPeriodicPoleRefVertex(MG_SOMMET *__v)
Definition: CAD4FE_PolyCurve.cpp:639
MG_BOUCLE
Definition: mg_boucle.h:35
gestionversion.h
MG_BOUCLE::get_nb_mg_coarete
virtual int get_nb_mg_coarete(void)
Definition: mg_boucle.cpp:78
CAD4FE::PolyCurve::PolyCurve
PolyCurve()
Definition: CAD4FE_PolyCurve.cpp:58
CAD4FE::PolyCurve::ContainsRefVertex
bool ContainsRefVertex(MG_SOMMET *__v)
Definition: CAD4FE_PolyCurve.cpp:125
CAD4FE::PolyCurve::RefEdge_GetT
void RefEdge_GetT(unsigned __index, double length, double *__t, double *__dt, bool __curvilinearLength)
Definition: CAD4FE_PolyCurve.cpp:268
MG_ARETE::evaluer
virtual void evaluer(double t, double *xyz)
Definition: mg_arete.cpp:143
CAD4FE::PolyCurve::get_tmax
double get_tmax()
Definition: CAD4FE_PolyCurve.cpp:685
mg_gestionnaire.h
MG_IDENTIFICATEUR::get_id
unsigned long get_id()
Definition: mg_identificateur.cpp:53
CAD4FE::PolyCurve::VerifyRefEdgeT
static void VerifyRefEdgeT(MG_ARETE *__edge, double &__t)
Definition: CAD4FE_PolyCurve.cpp:140
CAD4FE::PolyCurve
Definition: CAD4FE_PolyCurve.h:38
MG_COSOMMET
Definition: mg_cosommet.h:31
equation_longueur
double equation_longueur(MG_ARETE &__edge, double t)
Definition: CAD4FE_PolyCurve.cpp:90
CAD4FE::PolyCurve::GetLength
double GetLength(MG_ARETE *__edge)
Definition: CAD4FE_PolyCurve.cpp:79
CAD4FE::PolyCurve::enregistrer
void enregistrer(std::ostream &o, double version)
Definition: CAD4FE_PolyCurve.cpp:746
CAD4FE::PolyCurve::GetRefEdges
std::vector< MG_ARETE * > & GetRefEdges()
Definition: CAD4FE_PolyCurve.cpp:770
MG_COARETE
Definition: mg_coarete.h:31
CAD4FE::PolyCurve::get_tmin
double get_tmin()
Definition: CAD4FE_PolyCurve.cpp:680
MG_ARETE::get_orientation
virtual int get_orientation(void)
Definition: mg_arete.cpp:93
CAD4FE::PolyCurve::RefEdge_GetS
void RefEdge_GetS(unsigned __iEdge, double __t, double *__s, bool __curvilinearLength)
Definition: CAD4FE_PolyCurve.cpp:311
MG_COFACE::get_face
virtual MG_FACE * get_face(void)
Definition: mg_coface.cpp:58
TPL_FONCTION1::integrer_jusqua_gauss_2
void integrer_jusqua_gauss_2(C x1, C dx, C valeur_integrale_cible, C *x2)
Definition: tpl_fonction.h:57
MG_ELEMENT_TOPOLOGIQUE::get_dimension
virtual int get_dimension(void)=0
MG_BOUCLE::ajouter_mg_coarete
virtual void ajouter_mg_coarete(class MG_COARETE *mgcoarete)
Definition: mg_boucle.cpp:73
MG_VOLUME
Definition: mg_volume.h:33
MG_COQUILLE
Definition: mg_coquille.h:34
MG_FACE::get_nb_mg_boucle
virtual int get_nb_mg_boucle(void)
Definition: mg_face.cpp:67
swap
void swap(double2 &a, double2 &b)
Definition: ot_fonctions.cpp:106
CAD4FE::PolyCurve::get_sommet2_s
double get_sommet2_s()
Definition: CAD4FE_PolyCurve.cpp:711
MG_GEOMETRIE::ajouter_mg_sommet
virtual int ajouter_mg_sommet(MG_SOMMET *mgsom)
Definition: mg_geometrie.cpp:497
MG_COURBE
Definition: mg_courbe.h:30
CAD4FE::PolyCurve::lst_length
std::vector< double > lst_length
Definition: CAD4FE_PolyCurve.h:107
CAD4FE::PolyCurve::GetRefEdgeCount
unsigned GetRefEdgeCount()
Definition: CAD4FE_PolyCurve.cpp:109
MG_ARETE::get_tmin
virtual double get_tmin(void)
Definition: mg_arete.cpp:179
CAD4FE::PolyCurve::Parameter_RefEdgeTToS
void Parameter_RefEdgeTToS(double __t, MG_ARETE *__edge, double *__s, bool __curvilinearLength)
Definition: CAD4FE_PolyCurve.cpp:487
ot_decalage_parametre.h
MG_VOLUME::get_mg_coquille
virtual MG_COQUILLE * get_mg_coquille(int num)
Definition: mg_volume.cpp:70
MG_COURBE::t_min
double t_min
Definition: mg_courbe.h:61
CAD4FE::PolyCurve::get_param_NURBS
virtual void get_param_NURBS(int &indx_premier_ptctr, TPL_LISTE_ENTITE< double > &param)
Definition: CAD4FE_PolyCurve.cpp:969
MG_ELEMENT_TOPOLOGIQUE
Definition: mg_element_topologique.h:51
CAD4FE::PolyCurve::lst_ref_edges
std::vector< MG_ARETE * > lst_ref_edges
Definition: CAD4FE_PolyCurve.h:105
MG_ARETE::inverser
virtual void inverser(double &t, double *xyz, double precision=1e-6)
Definition: mg_arete.cpp:173
MG_COURBE::t_max
double t_max
Definition: mg_courbe.h:62
CAD4FE::PolyCurve::get_sommet1_s
double get_sommet1_s()
Definition: CAD4FE_PolyCurve.cpp:704
MG_GEOMETRIE::ajouter_mg_cosommet
virtual int ajouter_mg_cosommet(MG_COSOMMET *mgcosom)
Definition: mg_geometrie.cpp:643
CAD4FE::PolyCurve::ContainsRefEdge
bool ContainsRefEdge(MG_ARETE *__refEdge)
Definition: CAD4FE_PolyCurve.cpp:120
CAD4FE::PolyCurve::lst_vertices
std::vector< MG_SOMMET * > lst_vertices
Definition: CAD4FE_PolyCurve.h:106
lc_point.h
CAD4FE::SplitRefEdge
void SplitRefEdge(MG_ARETE *__refEdge, MG_SOMMET *__refVertex1, MG_SOMMET *__refVertex2, double __xyz[3], MG_VOLUME *__refBody, MG_GEOMETRIE *__geom, MG_ARETE *edges[2], MG_SOMMET **__splitVertex)
Definition: CAD4FE_PolyCurve.cpp:776
CAD4FE::PolyCurve::GetRefEdge
MG_ARETE * GetRefEdge(unsigned int)
Definition: CAD4FE_PolyCurve.cpp:99
CAD4FE::MG_ARETE_ClosestPointOn::Find
double Find()
Definition: CAD4FE_MG_ARETE_ClosestPointOn.cpp:157
TPL_FONCTION1
Definition: tpl_fonction.h:28
CAD4FE::PolyCurve::get_sommet2
MG_SOMMET * get_sommet2()
Definition: CAD4FE_PolyCurve.cpp:698
CAD4FE::MG_ARETE_ClosestPointOn
Definition: CAD4FE_MG_ARETE_ClosestPointOn.h:31
V
void V(MCAA *mcaa)
Definition: CAD4FE_MCAA.cpp:1794
CAD4FE::PolyCurve::evaluer
void evaluer(double __s, double __X[3])
Definition: CAD4FE_PolyCurve.cpp:506
MG_COARETE::get_orientation
virtual int get_orientation(void)
Definition: mg_coarete.cpp:71
CAD4FE::PolyCurve::Merge
void Merge(PolyCurve &)
Definition: CAD4FE_PolyCurve.cpp:605
MG_SOMMET::get_point
virtual MG_POINT * get_point(void)
Definition: mg_sommet.cpp:52
CAD4FE::PolyCurve::Contains
bool Contains(MG_ELEMENT_TOPOLOGIQUE *__topo)
Definition: CAD4FE_PolyCurve.cpp:130
mg_arete.h
MG_POINT
Definition: mg_point.h:33
CAD4FE::PolyCurve::get_type_geometrique
int get_type_geometrique(TPL_LISTE_ENTITE< double > &param)
Definition: CAD4FE_PolyCurve.cpp:741
MG_COSOMMET::get_sommet
virtual MG_SOMMET * get_sommet(void)
Definition: mg_cosommet.cpp:83
MG_GEOMETRIE::supprimer_mg_coarete
virtual int supprimer_mg_coarete(MG_COARETE *mgcoarete)
Definition: mg_geometrie.cpp:976
MG_GEOMETRIE::ajouter_mg_courbe
virtual int ajouter_mg_courbe(MG_COURBE *mgcrb)
Definition: mg_geometrie.cpp:251
MG_GEOMETRIE::ajouter_mg_coarete
virtual int ajouter_mg_coarete(MG_COARETE *mgcoarete)
Definition: mg_geometrie.cpp:925
CAD4FE_MG_ARETE_ClosestPointOn.h
CAD4FE::PolyCurve::est_periodique
int est_periodique(void)
Definition: CAD4FE_PolyCurve.cpp:724
MG_BOUCLE::get_mg_coarete
virtual MG_COARETE * get_mg_coarete(int num)
Definition: mg_boucle.cpp:84
MG_GEOMETRIE::ajouter_mg_arete
virtual int ajouter_mg_arete(MG_ARETE *mgarete)
Definition: mg_geometrie.cpp:759
sqrt
double2 sqrt(double2 &val)
Definition: ot_doubleprecision.cpp:345
MG_GEOMETRIE::ajouter_mg_point
virtual int ajouter_mg_point(MG_POINT *mgpt)
Definition: mg_geometrie.cpp:137
CAD4FE_PolyCurve.h
LC_POINT
Definition: lc_point.h:30
MG_ARETE::get_courbe
virtual class MG_COURBE * get_courbe(void)
Definition: mg_arete.cpp:89
CAD4FE::PolyCurve::RefVertex_GetIndex
unsigned int RefVertex_GetIndex(MG_SOMMET *__refVertex)
Definition: CAD4FE_PolyCurve.cpp:480
CAD4FE::PolyCurve::Parameter_SToRefEdgeT
void Parameter_SToRefEdgeT(double __s, unsigned *__iEdge, double *__t, double *__dt, bool __curvilinearLength)
Definition: CAD4FE_PolyCurve.cpp:445
ot_algorithme_geometrique.h
MG_ARETE::changer_cosommet1
virtual void changer_cosommet1(class MG_COSOMMET *cosom)
Definition: mg_arete.cpp:73
CAD4FE::PolyCurve::GetRefVertex
MG_SOMMET * GetRefVertex(unsigned int)
Definition: CAD4FE_PolyCurve.cpp:104
MG_GEOMETRIE
Definition: mg_geometrie.h:84
CAD4FE
Definition: CAD4FE_ClosestPoint_Segment_MG_ARETE.h:34
MG_SOMMET::get_dimension
virtual int get_dimension(void)
Definition: mg_sommet.cpp:93
MG_COURBE::get_periode
virtual double get_periode(void)=0
TPL_LISTE_ENTITE< double >
CAD4FE::PolyCurve::get_sommet1
MG_SOMMET * get_sommet1()
Definition: CAD4FE_PolyCurve.cpp:691
CAD4FE::PolyCurve::get_periode
double get_periode(void)
Definition: CAD4FE_PolyCurve.cpp:732
MG_COQUILLE::get_nb_mg_coface
virtual int get_nb_mg_coface(void)
Definition: mg_coquille.cpp:76
MG_BOUCLE::supprimer_mg_coarete
virtual void supprimer_mg_coarete(class MG_COARETE *mgcoarete)
Definition: mg_boucle.cpp:89
MG_COQUILLE::get_mg_coface
virtual MG_COFACE * get_mg_coface(int num)
Definition: mg_coquille.cpp:90
CAD4FE::PolyCurve::deriver
void deriver(double __s, double __X[3])
Definition: CAD4FE_PolyCurve.cpp:532
MG_ARETE::deriver
virtual void deriver(double t, double *xyz)
Definition: mg_arete.cpp:149
MG_ARETE
Definition: mg_arete.h:36
MG_FACE
Definition: mg_face.h:34
MG_FACE::get_mg_boucle
virtual MG_BOUCLE * get_mg_boucle(int num)
Definition: mg_face.cpp:72
MG_ELEMENT_TOPOLOGIQUE::get_idoriginal
virtual std::string get_idoriginal(void)
Definition: mg_element_topologique.cpp:299
CAD4FE::PolyCurve::IsPoint
bool IsPoint() const
Definition: CAD4FE_PolyCurve.cpp:963
MG_ARETE::get_cosommet1
virtual class MG_COSOMMET * get_cosommet1(void)
Definition: mg_arete.cpp:81
MG_SOMMET
Definition: mg_sommet.h:35
MG_ARETE::get_longueur
virtual double get_longueur(double t1, double t2, double precis=1e-6)
Definition: mg_arete.cpp:193
CAD4FE::PolyCurve::deriver_seconde
void deriver_seconde(double __s, double __ddxyz[3], double *__dxyz=NULL, double *__xyz=NULL)
Definition: CAD4FE_PolyCurve.cpp:563
MG_COARETE::get_arete
virtual MG_ARETE * get_arete(void)
Definition: mg_coarete.cpp:58
CAD4FE::PolyCurve::GetRefVertexCount
unsigned GetRefVertexCount()
Definition: CAD4FE_PolyCurve.cpp:114
MG_ARETE::get_tmax
virtual double get_tmax(void)
Definition: mg_arete.cpp:184
OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3
static double VEC3_DISTANCE_VEC3(double a[3], double b[3])
Definition: ot_algorithme_geometrique.h:127
MG_POINT::evaluer
virtual void evaluer(double *xyz)=0
CAD4FE::PolyCurve::est_sur_courbe
bool est_sur_courbe(double *xyz, double precision=1e-6)
Definition: CAD4FE_PolyCurve.cpp:233
CAD4FE::PolyCurve::InsertCurve
void InsertCurve(MG_ARETE *)
Definition: CAD4FE_PolyCurve.cpp:347
CAD4FE::SplitPolyCurve
void SplitPolyCurve(PolyCurve *__polyCurve, double __xyz[3], MG_VOLUME *__refBody, MG_GEOMETRIE *__geom, PolyCurve *__result[2], MG_ARETE **__origRefEdge, MG_SOMMET **__splitRefVertex, MG_ARETE *__splitRefEdges[2])
Definition: CAD4FE_PolyCurve.cpp:888
tpl_fonction.h
CAD4FE::PolyCurve::RefEdge_GetIndex
unsigned int RefEdge_GetIndex(MG_ARETE *__refEdge)
Definition: CAD4FE_PolyCurve.cpp:473
CAD4FE::PolyCurve::RefVertex_GetS
double RefVertex_GetS(MG_SOMMET *__refVertex)
Definition: CAD4FE_PolyCurve.cpp:256
m
#define m(i, j)