ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/geometrie/src/CAD4FE_PolyCurve.cpp
Revision: 283
Committed: Tue Sep 13 21:11:20 2011 UTC (13 years, 8 months ago) by francois
File size: 27438 byte(s)
Log Message:
structure de l'écriture

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 francois 283 #pragma warn -8012
40 foucault 27 #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 francois 283 t_min = (0);
53     t_max = (-1);
54     InsertCurve( __edge );
55 foucault 27 }
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 francois 283 }
64 foucault 27
65     double
66     PolyCurve::GetLength(MG_ARETE * __edge)
67     {
68 francois 283 return __edge->get_longueur(__edge->get_tmin(), __edge->get_tmax());
69 foucault 27 }
70    
71     double
72     PolyCurve::GetLength(unsigned __index)
73     {
74 francois 283 return lst_length[__index];
75 foucault 27 }
76 francois 283
77 foucault 27 double equation_longueur(MG_ARETE & __edge,double t)
78     {
79 francois 283 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 foucault 27 }
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 francois 283 unsigned PolyCurve::GetRefEdgeCount()
97 foucault 27 {
98     return lst_ref_edges.size();
99     }
100    
101 francois 283 unsigned PolyCurve::GetRefVertexCount()
102 foucault 27 {
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 francois 283 return ContainsRefVertex((MG_SOMMET *)__topo);
121 foucault 27 if (__topo->get_dimension() == 1)
122 francois 283 return ContainsRefEdge((MG_ARETE *)__topo);
123 foucault 27 return false;
124 francois 283 }
125 foucault 27
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 francois 283 if (__t > t2 )
135     __t -= __edge->get_courbe()->get_periode();
136     if (__t < t1 )
137     __t += __edge->get_courbe()->get_periode();
138 foucault 27 }
139     else
140     {
141     double tStart=(t1<t2)?t1:t2;
142     double tEnd=(t1>t2)?t1:t2;
143 francois 283 if (__t > tEnd )
144     __t = tEnd;
145     if (__t < tStart )
146     __t = tStart;
147 foucault 27 }
148     }
149    
150     void
151     PolyCurve::inverser(double & __t, double __point[3], double precision, bool __curvilinearLength)
152     {
153 francois 283 int j;
154     double s;
155 foucault 27
156 francois 283 double edge_length = t_max;
157 foucault 27
158 francois 283 // 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 foucault 27
167 francois 283 for (j = 0; j < 3; j++)
168     if (fabs(vertex_point[j] - __point[j]) > edge_length*precision)
169     break;
170 foucault 27
171 francois 283 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 foucault 27
178 francois 283 __t = s;
179 foucault 27
180 francois 283 return;
181 foucault 27 }
182 francois 283 }
183 foucault 27
184 francois 283 // 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 foucault 27 {
207 francois 283 min_distance = distance;
208     iClosestEdge = std::distance (lst_ref_edges.begin(), it_edge );
209     tClosestEdge = t_edge;
210 foucault 27 }
211 francois 283 }
212 foucault 27
213 francois 283 Parameter_RefEdgeTToS ( tClosestEdge, lst_ref_edges[iClosestEdge], &s, __curvilinearLength);
214 foucault 27
215 francois 283 __t = s;
216 foucault 27
217 francois 283 return;
218 foucault 27 }
219    
220     void
221     PolyCurve::VerifyS(double & __s)
222     {
223 francois 283 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 foucault 27 }
234    
235 francois 283 double
236 foucault 27 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 francois 283 double __s,
250     double *__t, double *__dt, bool __curvilinearLength
251     )
252 foucault 27 {
253 francois 283 double t1,t2;
254     MG_SOMMET * vertex = lst_vertices[ __iEdge ];
255     MG_ARETE * edge = lst_ref_edges[ __iEdge ];
256 foucault 27
257 francois 283 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 foucault 27 {
280 francois 283 *__dt = (t2 - t1) / GetLength( __iEdge );
281     *__t = t1 + __s * (*__dt);
282 foucault 27
283 francois 283 return;
284 foucault 27 }
285 francois 283 longueur_bsp.integrer_jusqua_gauss_2(t1, increment, s, __t);
286     *__dt = (*__t - t1) / s;
287     }
288 foucault 27 }
289    
290     void
291     PolyCurve::RefEdge_GetS(unsigned __iEdge,
292 francois 283 double __t,
293     double *__s, bool __curvilinearLength
294     )
295 foucault 27 {
296 francois 283 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 foucault 27
301 francois 283 t1=edge->get_tmin();
302     t2=edge->get_tmax();
303 foucault 27
304 francois 283 if (edge->get_courbe()->est_periodique())
305     {
306     if (__t < t1 - period*1E-6)
307     __t += period;
308     }
309 foucault 27
310 francois 283 if ( __curvilinearLength == false)
311     {
312     if (vertex == edge->get_cosommet1()->get_sommet())
313     *__s = lst_length[__iEdge] * (__t-t1)/(t2-t1);
314 foucault 27 else
315 francois 283 *__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 foucault 27 }
325    
326     void
327     PolyCurve::InsertCurve(MG_ARETE *__edge)
328 francois 283 {
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 foucault 27
340 francois 283 // 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 foucault 27
348 francois 283 // 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 foucault 27 }
368 francois 283 else
369 foucault 27 {
370 francois 283 iiVo = i;
371 foucault 27 }
372 francois 283 }
373 foucault 27
374 francois 283 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 = %ld, %ld) not adjacent to the extremities of this PolyCurve (extremities = %ld, %ld)\n", __edge->get_cosommet1()->get_sommet()->get_id(), __edge->get_cosommet2()->get_sommet()->get_id(), get_sommet1()->get_id(), get_sommet2()->get_id());
377 foucault 27 return;
378 francois 283 }
379 foucault 27 }
380 francois 283 else // vertex V[i] not found
381 foucault 27 {
382 francois 283 iV[i] = -1;
383     iiVo = i;
384 foucault 27 }
385 francois 283 }
386 foucault 27
387    
388 francois 283 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 %ld is neither adjacent to end vertex nor to start vertex of polycurve %ld\n", __edge->get_id(), get_id());
410     printf("Polycurve Start vertex = %ld, End vertex = %ld\n", get_sommet1()->get_id(),get_sommet2()->get_id());
411     printf("Edge Start vertex = %ld, End vertex = %ld\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 foucault 27 }
423    
424     void
425     PolyCurve::Parameter_SToRefEdgeT (double __s, unsigned * __iEdge, double *__t, double *__dt, bool __curvilinearLength)
426     {
427 francois 283 double s;
428     unsigned i;
429 foucault 27
430 francois 283 VerifyS(__s);
431 foucault 27
432 francois 283 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 foucault 27
440 francois 283 RefEdge_GetT(i, __s - s, __t, __dt, __curvilinearLength);
441     *__iEdge = i;
442 foucault 27 }
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 francois 283 unsigned
453 foucault 27 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 francois 283 unsigned
460 foucault 27 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 francois 283 {
469     double s, ds;
470     unsigned i;
471 foucault 27
472 francois 283 i = RefEdge_GetIndex(__edge);
473 foucault 27
474 francois 283 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 foucault 27
482 francois 283 *__s = s;
483 foucault 27 }
484 francois 283
485 foucault 27 void
486     PolyCurve::evaluer (double __s, double __X[3])
487     {
488 francois 283 bool curvilinearLength = false;
489     evaluer(__s, __X, curvilinearLength);
490 foucault 27 }
491    
492     void
493     PolyCurve::evaluer (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
494     {
495 francois 283 if (IsPoint())
496     {
497     lst_vertices[0]->get_point()->evaluer(__X);
498     return;
499     }
500 foucault 27
501 francois 283 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 foucault 27 }
510 francois 283
511 foucault 27 void
512     PolyCurve::deriver (double __s, double __X[3]) // curvilinear abcissa
513     {
514 francois 283 bool curvilinearLength = false;
515     deriver(__s, __X, curvilinearLength);
516 foucault 27 }
517    
518     void
519     PolyCurve::deriver (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
520 francois 283 {
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 foucault 27 }
540    
541 francois 283
542 foucault 27 void
543     PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz) // curvilinear abcissa
544     {
545 francois 283 bool curvilinearLength = false;
546     deriver_seconde(__s, __ddxyz, __dxyz, __xyz, curvilinearLength);
547 foucault 27
548     }
549     void
550     PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz, bool __curvilinearLength) // curvilinear abcissa
551 francois 283 {
552     unsigned iEdge;
553     MG_ARETE * edge;
554     double t, dt;
555 foucault 27
556 francois 283 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 foucault 27
564 francois 283 VerifyS (__s);
565 foucault 27
566 francois 283 Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
567     edge = lst_ref_edges [ iEdge ];
568 foucault 27
569 francois 283 for (int i=0; i<3; i++)
570     __ddxyz[i] = 0;
571 foucault 27
572 francois 283 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 foucault 27 }
581    
582    
583    
584     void
585     PolyCurve::Merge( PolyCurve & __polycurve)
586     {
587 francois 283 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     ;
597     for (std::vector < MG_ARETE * >::reverse_iterator it = __polycurve.lst_ref_edges.rbegin();
598     it != __polycurve.lst_ref_edges.rend();
599     it++)
600     InsertCurve ( *it );
601     }
602     else if ( get_sommet1() == __polycurve.get_sommet1() || get_sommet2() == __polycurve.get_sommet1() )
603     {
604     for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
605     it != __polycurve.lst_ref_edges.end();
606     it++ )
607     InsertCurve ( *it );
608     }
609     else
610     {
611     printf("PolyCurve::Merge Error : the polycurve %ld is neither adjacent to end vertex nor to start vertex of polycurve %ld\n", __polycurve.get_id(), get_id());
612     printf("Polycurve Start vertex = %ld, End vertex = %ld\n", get_sommet1()->get_id(),get_sommet2()->get_id());
613     printf("Other __polycurve Start vertex = %ld, End vertex = %ld\n", __polycurve.get_sommet1()->get_id(), __polycurve.get_sommet2()->get_id());
614     return;
615 foucault 27
616 francois 283 }
617 foucault 27 }
618    
619     void
620     PolyCurve::SetPeriodicPoleRefVertex(MG_SOMMET * __v)
621     {
622     if ( est_periodique() == false)
623     return;
624 francois 283
625 foucault 27 std::vector<MG_ARETE*> e;
626     std::vector<MG_SOMMET*> v;
627     std::vector<double> l;
628     unsigned k=RefVertex_GetIndex(__v);
629     unsigned N=lst_vertices.size();
630     for (unsigned i=0; i<N; i++)
631     {
632 francois 283 unsigned m = (i+k)%N;
633     unsigned n = (i+k+1)%N;
634 foucault 27 MG_SOMMET * tempv = lst_vertices[ m ];
635     MG_SOMMET * lastV = (v.size()) ? v[v.size()-1] : 0;
636     if ( lastV && lastV == tempv )
637     tempv = lst_vertices[n];
638     v.push_back(tempv);
639     }
640     for (unsigned i=0; i+1<N; i++)
641     e.push_back(lst_ref_edges[ (i+k)%(N-1) ]);
642     for (unsigned i=0; i+1<N; i++)
643     l.push_back(lst_length[ (i+k)%(N-1) ]);
644     lst_vertices = v;
645     lst_ref_edges = e;
646     lst_length = l;
647     }
648    
649     double
650 francois 283 PolyCurve::get_longueur (double __s_min, double __s_max, double precision)
651 foucault 27 {
652 francois 283 double result;
653     if ( __s_min >= 0 && __s_max >= 0 )
654     return fabs (__s_min - __s_max);
655     else
656     {
657     return t_max;
658     }
659 foucault 27 }
660    
661     double PolyCurve::get_tmin()
662     {
663 francois 283 return t_min;
664 foucault 27 }
665    
666     double PolyCurve::get_tmax()
667     {
668 francois 283 return t_max;
669 foucault 27 }
670    
671     MG_SOMMET *
672 francois 283 PolyCurve::get_sommet1()
673 foucault 27 {
674 francois 283 return lst_vertices[0];
675 foucault 27 }
676    
677    
678     MG_SOMMET *
679 francois 283 PolyCurve::get_sommet2()
680 foucault 27 {
681 francois 283 return lst_vertices[lst_vertices.size()-1];
682 foucault 27 }
683    
684     double
685     PolyCurve::get_sommet1_s()
686     {
687 francois 283 return get_tmin();
688 foucault 27 }
689    
690    
691     double
692 francois 283 PolyCurve::get_sommet2_s()
693 foucault 27 {
694 francois 283 return get_tmax();
695 foucault 27 }
696    
697     void
698     PolyCurve::inverser(double & __t, double __point[3], double precision)
699     {
700 francois 283 bool curvilinearLength = false;
701 foucault 27
702 francois 283 inverser(__t, __point, precision, curvilinearLength);
703 foucault 27 }
704    
705     int PolyCurve::est_periodique(void)
706     {
707 francois 283 if ( get_sommet1 () == get_sommet2 () )
708     return 1;
709     else
710     return 0;
711 foucault 27 }
712    
713     double PolyCurve::get_periode(void)
714     {
715     if ( est_periodique() )
716     return get_longueur();
717     else
718 francois 283 return 0;
719 foucault 27 }
720    
721    
722     int PolyCurve::get_type_geometrique(TPL_LISTE_ENTITE<double> &param)
723     {
724 francois 283 return 4343; // TYPE = Poly curve
725 foucault 27 }
726    
727     void PolyCurve::enregistrer(std::ostream& o)
728     {
729     unsigned int i;
730    
731     if (IsPoint() == false)
732     {
733 francois 283 o << "%" << get_id()
734     << "=CAD4FE_POLYCURVE(" << GetRefEdgeCount() << ",(";
735 foucault 27
736 francois 283 for (i=0; i < GetRefEdgeCount(); i++)
737     {
738     if ( i ) o <<",";
739     o << "$" << GetRefEdge(i)->get_id();
740     }
741    
742     o << "));" << std::endl;
743     }
744 foucault 27 else // The polycurve is a point !
745 francois 283 {
746     o << "%" << get_id() << "=CAD4FE_POLYCURVE(0,($"<<GetRefVertex(0)->get_id()<<"));"<< std::endl;
747     }
748 foucault 27 }
749    
750 francois 283 std::vector<MG_ARETE*> &
751     PolyCurve::GetRefEdges()
752 foucault 27 {
753 francois 283 return lst_ref_edges;
754 foucault 27 }
755    
756     void
757     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)
758     {
759     int i,j;
760 francois 283 double tSplit;
761 foucault 27 MG_ARETE * splitEdge = __refEdge;
762     splitEdge->inverser(tSplit, __xyz);
763    
764     // Create the split vertex at position xyz
765     MG_POINT * point = new LC_POINT(__xyz);
766     __geom->ajouter_mg_point(point);
767     std::ostringstream idoriginal;
768     idoriginal << "Vertex of "<< splitEdge->get_idoriginal() <<" split at t="<<tSplit;
769     MG_SOMMET * splitVertex = new MG_SOMMET(idoriginal.str(), point);
770     *__splitVertex = splitVertex;
771     __geom->ajouter_mg_sommet(splitVertex);
772    
773     // split the edge in two edges
774     MG_COURBE * curves[2];
775     MG_SOMMET * vertices[2][2];
776     MG_COSOMMET * cov[2][2];
777 francois 283
778 foucault 27 vertices[0][0] = splitEdge->get_cosommet1()->get_sommet();
779     vertices[0][1] = splitVertex;
780     vertices[1][0] = splitVertex;
781     vertices[1][1] = splitEdge->get_cosommet2()->get_sommet();
782 francois 283
783 foucault 27 curves[0] = curves[1] = splitEdge->get_courbe();
784    
785     double verticesT[2][2];
786 francois 283 verticesT[0][0] = splitEdge->get_tmin();
787 foucault 27 verticesT[1][1] = splitEdge->get_tmax();
788     verticesT[0][1] = verticesT[1][0] = tSplit;
789    
790     // create two edges
791     for (i=0; i<2; i++)
792     {
793     // orientation
794 francois 283 int orientation = splitEdge->get_orientation();
795 foucault 27 // Create an edge using the start vertex and the split vertex
796     std::ostringstream idoriginal;
797     idoriginal << __refEdge->get_idoriginal();
798     idoriginal << " split with t0 " << verticesT[i][0] << " t1 " << verticesT[i][1];
799     edges[i] = new MG_ARETE (idoriginal.str(), 0, curves[i], orientation);
800     __geom->ajouter_mg_arete (edges[i]);
801     // create covertices
802     for (j=0;j<2;j++)
803     {
804     cov[i][j] = __geom->ajouter_mg_cosommet (edges[i], vertices[i][j]);
805     }
806    
807     edges[i]->changer_cosommet1(cov[i][0]);
808     edges[i]->changer_cosommet2(cov[i][1]);
809     }
810    
811     MG_BOUCLE * split_edge_loops[10];
812     int nb_split_edge_loops = 0;
813     MG_COARETE * split_edge_coedges[10], * coedges[20];
814     int nb_split_edge_coedges = 0, nb_coedges = 0;
815     // create four coedges (in manifold body case)
816     // replace each coedges belong to initial edge in both loops of the ref faces
817     //
818 francois 283 // for each shell of the ref body
819     unsigned nb_shells = __refBody->get_nb_mg_coquille ();
820     for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
821     {
822     MG_COQUILLE * shell = __refBody->get_mg_coquille(it_shells);
823     // for each coface->face F of the shell
824     unsigned nb_coface = shell->get_nb_mg_coface();
825     for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
826 foucault 27 {
827 francois 283 MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
828    
829     // for each loop L of this face
830     unsigned nb_loop = face->get_nb_mg_boucle();
831     for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
832     {
833     MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
834     // for each coedge coe of L
835     unsigned nb_edge = loop->get_nb_mg_coarete();
836     for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
837 foucault 27 {
838 francois 283 MG_COARETE * coedge = loop->get_mg_coarete(it_edge);
839     MG_ARETE * edge = coedge->get_arete();
840 foucault 27
841 francois 283 // if coe contains split_edge
842     if (edge == splitEdge)
843     {
844     split_edge_loops[ nb_split_edge_loops++ ] = loop;
845     split_edge_coedges[ nb_split_edge_coedges++ ] = coedge;
846     // create coe[0] ( edges[0], F, coe->sense )
847     // create coe[1] ( edges[1], F, coe->sense )
848     // delete coe in L
849     // add coe[0] in L
850     // add coe[1] in L
851     for (i=0; i<2; i++)
852 foucault 27 {
853 francois 283 coedges[nb_coedges++] = __geom->ajouter_mg_coarete (edges[i], loop, coedge->get_orientation());
854     loop->ajouter_mg_coarete(coedges[nb_coedges-1]);
855     }
856 foucault 27
857 francois 283 loop->supprimer_mg_coarete(coedge);
858     __geom->supprimer_mg_coarete(coedge);
859     }
860     // fi
861 foucault 27 }
862 francois 283 }
863     }
864     }
865 foucault 27
866     }
867    
868     void
869     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])
870     {
871     int i,j;
872     *__splitRefVertex = NULL;
873     __splitRefEdges[0]=__splitRefEdges[1]=NULL;
874    
875     // get the parameter of __splitVertex
876     double sSplitVertex;
877     __polyCurve->inverser(sSplitVertex,__xyz,1E-6);
878    
879     unsigned index; // index of the reference edge split
880     double tEdge, dtEdge; // real parameter of the reference edge split
881     __polyCurve->Parameter_SToRefEdgeT(sSplitVertex,&index,&tEdge,&dtEdge, false);
882     *__origRefEdge = __polyCurve->GetRefEdge(index);
883     MG_SOMMET * v[2];
884     v[0] = __polyCurve->GetRefVertex(index);
885     v[1] = __polyCurve->GetRefVertex(index+1);
886    
887     // Test wether __xyz is located on one extremity of the ref edge
888     for (i=0; i<2; i++)
889     {
890     double v_xyz[3];
891    
892     v[i]->get_point()->evaluer(v_xyz);
893    
894     if (OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__xyz, v_xyz) / __polyCurve->GetLength(index) < 1E-6)
895     {
896     if (index+i == 0 || index+i+1 == __polyCurve->GetRefVertexCount())
897     {
898 francois 272 printf("Can't split a polycurve on vertex ID %ld because its extremities are vertices : %ld and %ld\n", v[i]->get_id(), __polyCurve->GetRefVertex(0)->get_id(), __polyCurve->GetRefVertex(__polyCurve->GetRefVertexCount()-1)->get_id());
899 foucault 27 return;
900     }
901    
902     *__origRefEdge = NULL;
903     *__splitRefVertex = v[i];
904     __splitRefEdges[0] = __polyCurve->GetRefEdge(index-1+i);
905     __splitRefEdges[1] = __polyCurve->GetRefEdge(index+i);
906 francois 283
907 foucault 27 // create the two polyCurves
908     for (int k=0; k<2; k++)
909     {
910     // create polycurve
911     __result[k] = new PolyCurve ( __splitRefEdges[k] );
912     __geom->ajouter_mg_courbe(__result[k]);
913     for (j = (k==0)?index-2+i:index+i+1; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*k)
914     __result[k]->InsertCurve(__polyCurve->GetRefEdge(j));
915     }
916 francois 283
917 foucault 27 break;
918     }
919     }
920     if (*__splitRefVertex == NULL)
921     {
922     CAD4FE::SplitRefEdge(*__origRefEdge, v[0], v[1], __xyz, __refBody, __geom, __splitRefEdges, __splitRefVertex);
923    
924     if ( __splitRefEdges[0]->get_cosommet1()->get_sommet() != v[0] && __splitRefEdges[0]->get_cosommet2()->get_sommet() != v[0] )
925 francois 283 std::swap(__splitRefEdges[0], __splitRefEdges[1] );
926 foucault 27
927     // create the two polyCurves
928     for (i=0; i<2; i++)
929     {
930     // create polycurve
931     __result[i] = new PolyCurve ( __splitRefEdges[i] );
932     __geom->ajouter_mg_courbe(__result[i]);
933     for (j = index-1+2*i; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*i)
934     __result[i]->InsertCurve(__polyCurve->GetRefEdge(j));
935     }
936     }
937    
938     if (__result[0]->get_sommet1() !=__result[1]->get_sommet1() &&__result[0]->get_sommet1() !=__result[1]->get_sommet2() &&
939 francois 283 __result[0]->get_sommet2() !=__result[1]->get_sommet1() &&__result[0]->get_sommet2() !=__result[1]->get_sommet2())
940 foucault 27 printf("Error");
941    
942     }
943    
944     bool PolyCurve::IsPoint() const
945     {
946     return lst_vertices.size() == 1 && lst_ref_edges.size() == 0;
947     }
948    
949     void
950     PolyCurve::get_param_NURBS(int& indx_premier_ptctr,TPL_LISTE_ENTITE<double> &param)
951     {
952 francois 283 return;
953 foucault 27 }
954    
955    
956