ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/geometrie/src/CAD4FE_PolyCurve.cpp
Revision: 27
Committed: Thu Jul 5 15:26:40 2007 UTC (17 years, 10 months ago) by foucault
Original Path: magic/lib/geometrie/geometrie/src/CAD4FE_PolyCurve.cpp
File size: 30494 byte(s)
Log Message:

File Contents

# User Rev Content
1 foucault 27 //---------------------------------------------------------------------------
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     void
221     PolyCurve::VerifyS(double & __s)
222     {
223     if ( est_periodique() )
224     {
225     while (__s > get_tmax() )
226     __s -= get_periode();
227     }
228     else
229     {
230     if (__s > get_tmax() )
231     __s = get_tmax();
232     }
233     }
234    
235     double
236     PolyCurve::RefVertex_GetS(MG_SOMMET * __refVertex)
237     {
238     int N = RefVertex_GetIndex(__refVertex);
239     double s;
240     s=0;
241     for (int i=0;i<N;i++)
242     s += GetLength(i);
243    
244     return s;
245     }
246    
247     void
248     PolyCurve::RefEdge_GetT(unsigned __iEdge,
249     double __s,
250     double *__t, double *__dt, bool __curvilinearLength
251     )
252     {
253     double t1,t2;
254     MG_SOMMET * vertex = lst_vertices[ __iEdge ];
255     MG_ARETE * edge = lst_ref_edges[ __iEdge ];
256    
257     if (vertex == edge->get_cosommet1()->get_sommet())
258     {
259     t1=edge->get_tmin();
260     t2=edge->get_tmax();
261     }
262     else
263     {
264     t1=edge->get_tmax();
265     t2=edge->get_tmin();
266     }
267    
268     if ( __curvilinearLength == false )
269     {
270     *__dt = (t2 - t1) / GetLength( __iEdge );
271     *__t = t1 + __s * (*__dt);
272     }
273     else
274     {
275     TPL_FONCTION1<double,MG_ARETE,double> longueur_bsp(*edge, equation_longueur);
276     double s = __s;
277     double increment = s/t_max*(t2-t1)/40;
278     if (increment < 1E-4 * (t2-t1))
279     {
280     *__dt = (t2 - t1) / GetLength( __iEdge );
281     *__t = t1 + __s * (*__dt);
282    
283     return;
284     }
285     longueur_bsp.integrer_jusqua_gauss_2(t1, increment, s, __t);
286     *__dt = (*__t - t1) / s;
287     }
288     }
289    
290     void
291     PolyCurve::RefEdge_GetS(unsigned __iEdge,
292     double __t,
293     double *__s, bool __curvilinearLength
294     )
295     {
296     double t1,t2;
297     MG_SOMMET * vertex = lst_vertices[ __iEdge ];
298     MG_ARETE * edge = lst_ref_edges[ __iEdge ];
299     double period=edge->get_courbe()->get_periode();
300    
301     t1=edge->get_tmin();
302     t2=edge->get_tmax();
303    
304     if (edge->get_courbe()->est_periodique())
305     {
306     if (__t < t1 - period*1E-6)
307     __t += period;
308     }
309    
310     if ( __curvilinearLength == false)
311     {
312     if (vertex == edge->get_cosommet1()->get_sommet())
313     *__s = lst_length[__iEdge] * (__t-t1)/(t2-t1);
314     else
315     *__s = lst_length[__iEdge] * (__t-t2)/(t1-t2);
316     }
317     else
318     {
319     if (vertex == edge->get_cosommet1()->get_sommet())
320     *__s = edge->get_longueur(t1,__t);
321     else
322     *__s = edge->get_longueur(__t,t2);
323     }
324     }
325    
326     void
327     PolyCurve::InsertCurve(MG_ARETE *__edge)
328     {
329     if (lst_ref_edges.size() == 0)
330     {
331     lst_ref_edges.push_back ( __edge );
332     lst_length.push_back ( GetLength(__edge) );
333     lst_vertices.push_back ( __edge->get_cosommet1()->get_sommet());
334     lst_vertices.push_back ( __edge->get_cosommet2()->get_sommet());
335     t_min = 0;
336     t_max = lst_length[0];
337     return;
338     }
339    
340     // Get the two vertices of this edge
341     MG_SOMMET * V[2];
342     int iV[2], // index of V[i] in lst_vertices[] ie. V [ i ] == lst_vertices[ iV[ i ] ]
343     iiVc=-1, // index < 2 of the common vertex in V[0,1] ie. if (iVc != -1) V [ iiVc ] == lst_vertices[ iV[ iiVc ] ]
344     iiVo=-1; // index < 2 of the other vertex in V[0,1] ie. if (iVo != -1) V [ iiVo ] == lst_vertices[ iV[ iiVo ] ]
345     V[0] = __edge->get_cosommet1()->get_sommet();
346     V[1] = __edge->get_cosommet2()->get_sommet();
347    
348     // Verify wether the vertices are already referenced in
349     // the polycurve
350     std::vector<MG_SOMMET*>::iterator itV[2];
351     for (int i=0; i<2; i++)
352     {
353     itV[i] = std::find (lst_vertices.begin(), lst_vertices.end(), V[i]);
354     if (itV[i] != lst_vertices.end())
355     { // V[i] is already in a curve of the polycurve
356     iV[i] = std::distance(lst_vertices.begin(), itV[i]);
357     if (iiVc == -1)
358     iiVc = i;
359     else
360     {
361     if (iV[iiVc] == 0)
362     { // case of a periodic polycurve : two vertices are common, the
363     // common vertex should be the last vertex of this polycurve (iV[iiVc]=N-1),
364     // and the other vertex the first vertex of this polycurve (iV[iiVo]=0)
365     iiVo = iiVc;
366     iiVc = i;
367     }
368     else
369     {
370     iiVo = i;
371     }
372     }
373    
374     if ( iV[i] != 0 && iV[i]+1 != (int)lst_vertices.size() )
375     {
376     printf (" Error in PolyCurve::InsertCurve : can't insert a MG_ARETE (extremities = %d, %d) not adjacent to the extremities of this PolyCurve (extremities = %d, %d)\n", __edge->get_cosommet1()->get_sommet()->get_id(), __edge->get_cosommet2()->get_sommet()->get_id(), get_sommet1()->get_id(), get_sommet2()->get_id());
377     return;
378     }
379     }
380     else // vertex V[i] not found
381     {
382     iV[i] = -1;
383     iiVo = i;
384     }
385     }
386    
387    
388     if (iiVc == -1)
389     {
390     printf (" Error in PolyCurve::InsertCurve : the curve requested to append is not connected to the existing polycurve\n");
391     return;
392     }
393    
394     if ( iV [iiVc] == 0 ) // the inserted curve is adjacent to the first vertex of the polycurve
395     {
396     std::reverse(lst_ref_edges.begin(), lst_ref_edges.end());
397     std::reverse(lst_vertices.begin(), lst_vertices.end());
398     std::reverse(lst_length.begin(), lst_length.end());
399     InsertCurve(__edge);
400     }
401     else if ( iV [iiVc]+1 == lst_vertices.size() ) // the inserted curve is adjacent to the last vertex of the polycurve
402     {
403     lst_vertices.push_back ( V [ iiVo ] );
404     lst_ref_edges.push_back ( __edge );
405     lst_length.push_back ( GetLength(__edge) );
406     }
407     else
408     {
409     printf("PolyCurve::InsertCurve Error : the edge %d is neither adjacent to end vertex nor to start vertex of polycurve %d\n", __edge->get_id(), get_id());
410     printf("Polycurve Start vertex = %d, End vertex = %d\n", get_sommet1()->get_id(),get_sommet2()->get_id());
411     printf("Edge Start vertex = %d, End vertex = %d\n", V[0]->get_id(), V[1]->get_id());
412     return;
413     }
414    
415     // update t_max
416     t_max = 0;
417     for (std::vector<double>::const_iterator it_length = lst_length.begin();
418     it_length != lst_length.end();
419     it_length++)
420     t_max += (*it_length);
421    
422     }
423    
424     void
425     PolyCurve::Parameter_SToRefEdgeT (double __s, unsigned * __iEdge, double *__t, double *__dt, bool __curvilinearLength)
426     {
427     double s;
428     unsigned i;
429    
430     VerifyS(__s);
431    
432     i=0;
433     s=0;
434     while (s + GetLength(i) < __s && i+1 < lst_ref_edges.size() )
435     {
436     s += GetLength(i);
437     i++;
438     }
439    
440     RefEdge_GetT(i, __s - s, __t, __dt, __curvilinearLength);
441     *__iEdge = i;
442     }
443    
444     void
445     PolyCurve::Parameter_SToRefEdgeT (double __s, MG_ARETE ** __edge, double *__t, double *__dt, bool __curvilinearLength)
446     {
447     unsigned iEdge;
448     Parameter_SToRefEdgeT(__s, &iEdge, __t, __dt, __curvilinearLength);
449     *__edge = GetRefEdge(iEdge);
450     }
451    
452     unsigned
453     PolyCurve::RefEdge_GetIndex(MG_ARETE * __edge)
454     {
455     unsigned i = std::distance ( lst_ref_edges.begin(), std::find ( lst_ref_edges.begin(), lst_ref_edges.end(), __edge) );
456     return i;
457     }
458    
459     unsigned
460     PolyCurve::RefVertex_GetIndex(MG_SOMMET * __vertex)
461     {
462     unsigned i = std::distance ( lst_vertices.begin(), std::find ( lst_vertices.begin(), lst_vertices.end(), __vertex) );
463     return i;
464     }
465    
466     void
467     PolyCurve::Parameter_RefEdgeTToS (double __t, MG_ARETE * __edge, double *__s, bool __curvilinearLength)
468     {
469     double s, ds;
470     unsigned i;
471    
472     i = RefEdge_GetIndex(__edge);
473    
474     s=0;
475     for ( unsigned k = 0; k < i; k++)
476     {
477     s += GetLength(k);
478     }
479     RefEdge_GetS(i, __t, &ds, __curvilinearLength);
480     s += ds;
481    
482     *__s = s;
483     }
484    
485     void
486     PolyCurve::evaluer (double __s, double __X[3])
487     {
488     bool curvilinearLength = false;
489     evaluer(__s, __X, curvilinearLength);
490     }
491    
492     void
493     PolyCurve::evaluer (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
494     {
495     if (IsPoint())
496     {
497     lst_vertices[0]->get_point()->evaluer(__X);
498     return;
499     }
500    
501     VerifyS (__s);
502     unsigned iEdge;
503     MG_ARETE * edge;
504     double t, dt;
505     Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
506     edge = lst_ref_edges [ iEdge ];
507     PolyCurve::VerifyRefEdgeT(edge, t);
508     edge->evaluer ( t, __X );
509     }
510    
511     void
512     PolyCurve::deriver (double __s, double __X[3]) // curvilinear abcissa
513     {
514     bool curvilinearLength = false;
515     deriver(__s, __X, curvilinearLength);
516     }
517    
518     void
519     PolyCurve::deriver (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
520     {
521     if (IsPoint())
522     {
523     for (int i=0;i<3;i++) __X[i] = 1;
524     return;
525     }
526    
527     VerifyS (__s);
528     unsigned iEdge;
529     MG_ARETE * edge;
530     double t, dt;
531     Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
532     edge = lst_ref_edges [ iEdge ];
533     PolyCurve::VerifyRefEdgeT(edge, t);
534     edge->deriver ( t, __X );
535    
536     // dC/ds = dC/dt * dt/ds
537     for (int i = 0; i<3; i++)
538     __X[i] *= dt;
539     }
540    
541    
542     void
543     PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz) // curvilinear abcissa
544     {
545     bool curvilinearLength = false;
546     deriver_seconde(__s, __ddxyz, __dxyz, __xyz, curvilinearLength);
547    
548     }
549     void
550     PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz, bool __curvilinearLength) // curvilinear abcissa
551     {
552     unsigned iEdge;
553     MG_ARETE * edge;
554     double t, dt;
555    
556     if (IsPoint())
557     {
558     if (__ddxyz) for (int i=0;i<3;i++) __ddxyz[i]=1;
559     if (__dxyz) for (int i=0;i<3;i++) __dxyz[i]=1;
560     evaluer(0,__xyz);
561     return;
562     }
563    
564     VerifyS (__s);
565    
566     Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
567     edge = lst_ref_edges [ iEdge ];
568    
569     for (int i=0; i<3; i++)
570     __ddxyz[i] = 0;
571    
572     if (__dxyz)
573     edge->deriver(t, __dxyz);
574     // dC/ds = dC/dt * dt/ds
575     for (int i = 0; i<3; i++)
576     __dxyz[i] *= dt;
577    
578     if (__xyz)
579     edge->evaluer(t, __xyz);
580     }
581    
582    
583    
584     void
585     PolyCurve::Merge( PolyCurve & __polycurve)
586     {
587     if (lst_vertices.size() == 0)
588     {
589     for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
590     it != __polycurve.lst_ref_edges.end();
591     it++ )
592     InsertCurve ( *it );
593     }
594     else if (get_sommet2() == __polycurve.get_sommet2() || get_sommet1() == __polycurve.get_sommet2() )
595     {;
596     for (std::vector < MG_ARETE * >::reverse_iterator it = __polycurve.lst_ref_edges.rbegin();
597     it != __polycurve.lst_ref_edges.rend();
598     it++)
599     InsertCurve ( *it );
600     }
601     else if ( get_sommet1() == __polycurve.get_sommet1() || get_sommet2() == __polycurve.get_sommet1() )
602     {
603     for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
604     it != __polycurve.lst_ref_edges.end();
605     it++ )
606     InsertCurve ( *it );
607     }
608     else
609     {
610     printf("PolyCurve::Merge Error : the polycurve %d is neither adjacent to end vertex nor to start vertex of polycurve %d\n", __polycurve.get_id(), get_id());
611     printf("Polycurve Start vertex = %d, End vertex = %d\n", get_sommet1()->get_id(),get_sommet2()->get_id());
612     printf("Other __polycurve Start vertex = %d, End vertex = %d\n", __polycurve.get_sommet1()->get_id(), __polycurve.get_sommet2()->get_id());
613     return;
614    
615     }
616     }
617    
618     void
619     PolyCurve::SetPeriodicPoleRefVertex(MG_SOMMET * __v)
620     {
621     if ( est_periodique() == false)
622     return;
623    
624     std::vector<MG_ARETE*> e;
625     std::vector<MG_SOMMET*> v;
626     std::vector<double> l;
627     unsigned k=RefVertex_GetIndex(__v);
628     unsigned N=lst_vertices.size();
629     for (unsigned i=0; i<N; i++)
630     {
631     unsigned m = (i+k)%N;
632     unsigned n = (i+k+1)%N;
633     MG_SOMMET * tempv = lst_vertices[ m ];
634     MG_SOMMET * lastV = (v.size()) ? v[v.size()-1] : 0;
635     if ( lastV && lastV == tempv )
636     tempv = lst_vertices[n];
637     v.push_back(tempv);
638     }
639     for (unsigned i=0; i+1<N; i++)
640     e.push_back(lst_ref_edges[ (i+k)%(N-1) ]);
641     for (unsigned i=0; i+1<N; i++)
642     l.push_back(lst_length[ (i+k)%(N-1) ]);
643     lst_vertices = v;
644     lst_ref_edges = e;
645     lst_length = l;
646     }
647    
648     double
649     PolyCurve::get_longueur (double __s_min, double __s_max, double precision)
650     {
651     double result;
652     if ( __s_min >= 0 && __s_max >= 0 )
653     return fabs (__s_min - __s_max);
654     else
655     {
656     return t_max;
657     }
658     }
659    
660     double PolyCurve::get_tmin()
661     {
662     return t_min;
663     }
664    
665     double PolyCurve::get_tmax()
666     {
667     return t_max;
668     }
669    
670     MG_SOMMET *
671     PolyCurve::get_sommet1()
672     {
673     return lst_vertices[0];
674     }
675    
676    
677     MG_SOMMET *
678     PolyCurve::get_sommet2()
679     {
680     return lst_vertices[lst_vertices.size()-1];
681     }
682    
683     double
684     PolyCurve::get_sommet1_s()
685     {
686     return get_tmin();
687     }
688    
689    
690     double
691     PolyCurve::get_sommet2_s()
692     {
693     return get_tmax();
694     }
695    
696     void
697     PolyCurve::inverser(double & __t, double __point[3], double precision)
698     {
699     bool curvilinearLength = false;
700    
701     inverser(__t, __point, precision, curvilinearLength);
702     }
703    
704     int PolyCurve::est_periodique(void)
705     {
706     if ( get_sommet1 () == get_sommet2 () )
707     return 1;
708     else
709     return 0;
710     }
711    
712     double PolyCurve::get_periode(void)
713     {
714     if ( est_periodique() )
715     return get_longueur();
716     else
717     return 0;
718     }
719    
720    
721     int PolyCurve::get_type_geometrique(TPL_LISTE_ENTITE<double> &param)
722     {
723     return 4343; // TYPE = Poly curve
724     }
725    
726     void PolyCurve::enregistrer(std::ostream& o)
727     {
728     unsigned int i;
729    
730     if (IsPoint() == false)
731     {
732     o << "%" << get_id()
733     << "=CAD4FE_POLYCURVE(" << GetRefEdgeCount() << ",(";
734    
735     for (i=0; i < GetRefEdgeCount(); i++)
736     {
737     if ( i ) o <<",";
738     o << "$" << GetRefEdge(i)->get_id();
739     }
740    
741     o << "));" << std::endl;
742     }
743     else // The polycurve is a point !
744     {
745     o << "%" << get_id() << "=CAD4FE_POLYCURVE(0,("<<GetRefVertex(0)->get_id()<<"));"<< std::endl;
746     }
747     }
748    
749     std::vector<MG_ARETE*> &
750     PolyCurve::GetRefEdges()
751     {
752     return lst_ref_edges;
753     }
754    
755     void
756     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)
757     {
758     int i,j;
759     double tSplit;
760     MG_ARETE * splitEdge = __refEdge;
761     splitEdge->inverser(tSplit, __xyz);
762    
763     // Create the split vertex at position xyz
764     MG_POINT * point = new LC_POINT(__xyz);
765     __geom->ajouter_mg_point(point);
766     std::ostringstream idoriginal;
767     idoriginal << "Vertex of "<< splitEdge->get_idoriginal() <<" split at t="<<tSplit;
768     MG_SOMMET * splitVertex = new MG_SOMMET(idoriginal.str(), point);
769     *__splitVertex = splitVertex;
770     __geom->ajouter_mg_sommet(splitVertex);
771    
772     // split the edge in two edges
773     MG_COURBE * curves[2];
774     MG_SOMMET * vertices[2][2];
775     MG_COSOMMET * cov[2][2];
776    
777     vertices[0][0] = splitEdge->get_cosommet1()->get_sommet();
778     vertices[0][1] = splitVertex;
779     vertices[1][0] = splitVertex;
780     vertices[1][1] = splitEdge->get_cosommet2()->get_sommet();
781    
782     curves[0] = curves[1] = splitEdge->get_courbe();
783    
784     double verticesT[2][2];
785     verticesT[0][0] = splitEdge->get_tmin();
786     verticesT[1][1] = splitEdge->get_tmax();
787     verticesT[0][1] = verticesT[1][0] = tSplit;
788    
789     // create two edges
790     for (i=0; i<2; i++)
791     {
792     // orientation
793     int orientation = splitEdge->get_orientation();
794     // Create an edge using the start vertex and the split vertex
795     std::ostringstream idoriginal;
796     idoriginal << __refEdge->get_idoriginal();
797     idoriginal << " split with t0 " << verticesT[i][0] << " t1 " << verticesT[i][1];
798     edges[i] = new MG_ARETE (idoriginal.str(), 0, curves[i], orientation);
799     __geom->ajouter_mg_arete (edges[i]);
800     // create covertices
801     for (j=0;j<2;j++)
802     {
803     cov[i][j] = __geom->ajouter_mg_cosommet (edges[i], vertices[i][j]);
804     }
805    
806     edges[i]->changer_cosommet1(cov[i][0]);
807     edges[i]->changer_cosommet2(cov[i][1]);
808     }
809    
810     MG_BOUCLE * split_edge_loops[10];
811     int nb_split_edge_loops = 0;
812     MG_COARETE * split_edge_coedges[10], * coedges[20];
813     int nb_split_edge_coedges = 0, nb_coedges = 0;
814     // create four coedges (in manifold body case)
815     // replace each coedges belong to initial edge in both loops of the ref faces
816     //
817     // for each shell of the ref body
818     unsigned nb_shells = __refBody->get_nb_mg_coquille ();
819     for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
820     {
821     MG_COQUILLE * shell = __refBody->get_mg_coquille(it_shells);
822     // for each coface->face F of the shell
823     unsigned nb_coface = shell->get_nb_mg_coface();
824     for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
825     {
826     MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
827    
828     // for each loop L of this face
829     unsigned nb_loop = face->get_nb_mg_boucle();
830     for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
831     {
832     MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
833     // for each coedge coe of L
834     unsigned nb_edge = loop->get_nb_mg_coarete();
835     for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
836     {
837     MG_COARETE * coedge = loop->get_mg_coarete(it_edge);
838     MG_ARETE * edge = coedge->get_arete();
839    
840     // if coe contains split_edge
841     if (edge == splitEdge)
842     {
843     split_edge_loops[ nb_split_edge_loops++ ] = loop;
844     split_edge_coedges[ nb_split_edge_coedges++ ] = coedge;
845     // create coe[0] ( edges[0], F, coe->sense )
846     // create coe[1] ( edges[1], F, coe->sense )
847     // delete coe in L
848     // add coe[0] in L
849     // add coe[1] in L
850     for (i=0; i<2; i++)
851     {
852     coedges[nb_coedges++] = __geom->ajouter_mg_coarete (edges[i], loop, coedge->get_orientation());
853     loop->ajouter_mg_coarete(coedges[nb_coedges-1]);
854     }
855    
856     loop->supprimer_mg_coarete(coedge);
857     __geom->supprimer_mg_coarete(coedge);
858     }
859     // fi
860     }
861     }
862     }
863     }
864    
865     }
866    
867     void
868     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])
869     {
870     int i,j;
871     *__splitRefVertex = NULL;
872     __splitRefEdges[0]=__splitRefEdges[1]=NULL;
873    
874     // get the parameter of __splitVertex
875     double sSplitVertex;
876     __polyCurve->inverser(sSplitVertex,__xyz,1E-6);
877    
878     unsigned index; // index of the reference edge split
879     double tEdge, dtEdge; // real parameter of the reference edge split
880     __polyCurve->Parameter_SToRefEdgeT(sSplitVertex,&index,&tEdge,&dtEdge, false);
881     *__origRefEdge = __polyCurve->GetRefEdge(index);
882     MG_SOMMET * v[2];
883     v[0] = __polyCurve->GetRefVertex(index);
884     v[1] = __polyCurve->GetRefVertex(index+1);
885    
886     // Test wether __xyz is located on one extremity of the ref edge
887     for (i=0; i<2; i++)
888     {
889     double v_xyz[3];
890    
891     v[i]->get_point()->evaluer(v_xyz);
892    
893     if (OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__xyz, v_xyz) / __polyCurve->GetLength(index) < 1E-6)
894     {
895     if (index+i == 0 || index+i+1 == __polyCurve->GetRefVertexCount())
896     {
897     printf("Can't split a polycurve on vertex ID %d because its extremities are vertices : %d and %d\n", v[i]->get_id(), __polyCurve->GetRefVertex(0)->get_id(), __polyCurve->GetRefVertex(__polyCurve->GetRefVertexCount()-1)->get_id());
898     return;
899     }
900    
901     *__origRefEdge = NULL;
902     *__splitRefVertex = v[i];
903     __splitRefEdges[0] = __polyCurve->GetRefEdge(index-1+i);
904     __splitRefEdges[1] = __polyCurve->GetRefEdge(index+i);
905    
906     // create the two polyCurves
907     for (int k=0; k<2; k++)
908     {
909     // create polycurve
910     __result[k] = new PolyCurve ( __splitRefEdges[k] );
911     __geom->ajouter_mg_courbe(__result[k]);
912     for (j = (k==0)?index-2+i:index+i+1; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*k)
913     __result[k]->InsertCurve(__polyCurve->GetRefEdge(j));
914     }
915    
916     break;
917     }
918     }
919     if (*__splitRefVertex == NULL)
920     {
921     CAD4FE::SplitRefEdge(*__origRefEdge, v[0], v[1], __xyz, __refBody, __geom, __splitRefEdges, __splitRefVertex);
922    
923     if ( __splitRefEdges[0]->get_cosommet1()->get_sommet() != v[0] && __splitRefEdges[0]->get_cosommet2()->get_sommet() != v[0] )
924     std::swap(__splitRefEdges[0], __splitRefEdges[1] );
925    
926     // create the two polyCurves
927     for (i=0; i<2; i++)
928     {
929     // create polycurve
930     __result[i] = new PolyCurve ( __splitRefEdges[i] );
931     __geom->ajouter_mg_courbe(__result[i]);
932     for (j = index-1+2*i; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*i)
933     __result[i]->InsertCurve(__polyCurve->GetRefEdge(j));
934     }
935     }
936    
937     if (__result[0]->get_sommet1() !=__result[1]->get_sommet1() &&__result[0]->get_sommet1() !=__result[1]->get_sommet2() &&
938     __result[0]->get_sommet2() !=__result[1]->get_sommet1() &&__result[0]->get_sommet2() !=__result[1]->get_sommet2())
939     printf("Error");
940    
941     }
942    
943     bool PolyCurve::IsPoint() const
944     {
945     return lst_vertices.size() == 1 && lst_ref_edges.size() == 0;
946     }
947    
948     void
949     PolyCurve::get_param_NURBS(int& indx_premier_ptctr,TPL_LISTE_ENTITE<double> &param)
950     {
951     return;
952     }
953    
954    
955