ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/geometrie/src/CAD4FE_PolyCurve.cpp
Revision: 1075
Committed: Tue Aug 10 17:02:54 2021 UTC (4 years ago) by francois
File size: 30708 byte(s)
Log Message:
suppression de warning avec le dernier compilateur

File Contents

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