ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/geometrie/src/CAD4FE_PolyCurve.cpp
Revision: 763
Committed: Wed Dec 2 19:55:53 2015 UTC (9 years, 5 months ago) by francois
File size: 30529 byte(s)
Log Message:
Le fichier MAGiC est maintenant versionné. LA version actuelle est 2.0. L'ancienne version est 1.0.
Tout est transparent pour l'utilisateur. Les vieilles versions sont lisibles mais les nouveaux enregistrements sont dans la version la plus récente.
Changement des conditions aux limites : ajout d'un parametre pour dire si la condition numerique est une valeur ou une formule ou un lien vers une autre entité magic.
Les parametres pour saisir sont maintenant -ccf -ccfi -ccff -ccft -ccfit -ccfft

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 foucault 569 #include "CAD4FE_MG_ARETE_ClosestPointOn.h"
15 foucault 27
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 foucault 569 #include "CAD4FE_PolyCurve.h"
31 foucault 27
32     //---------------------------------------------------------------------------
33    
34     #pragma package(smart_init)
35    
36     #include <math.h>
37    
38     #ifdef __BORLANDC__
39 foucault 569 #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 foucault 569 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 foucault 569 }
64 foucault 27
65     double
66     PolyCurve::GetLength(MG_ARETE * __edge)
67     {
68 foucault 569 return __edge->get_longueur(__edge->get_tmin(), __edge->get_tmax());
69 foucault 27 }
70    
71     double
72     PolyCurve::GetLength(unsigned __index)
73     {
74 foucault 569 return lst_length[__index];
75 foucault 27 }
76 foucault 569
77 foucault 27 double equation_longueur(MG_ARETE & __edge,double t)
78     {
79 foucault 569 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 foucault 569 unsigned PolyCurve::GetRefEdgeCount()
97 foucault 27 {
98     return lst_ref_edges.size();
99     }
100    
101 foucault 569 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 foucault 569 return ContainsRefVertex((MG_SOMMET *)__topo);
121 foucault 27 if (__topo->get_dimension() == 1)
122 foucault 569 return ContainsRefEdge((MG_ARETE *)__topo);
123 foucault 27 return false;
124 foucault 569 }
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 foucault 569 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 foucault 569 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 foucault 569 int j;
154     double s;
155 foucault 27
156 foucault 569 double edge_length = t_max;
157 foucault 27
158 foucault 569 // 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 foucault 569 for (j = 0; j < 3; j++)
168     if (fabs(vertex_point[j] - __point[j]) > edge_length*precision)
169     break;
170 foucault 27
171 foucault 569 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 foucault 569 __t = s;
179 foucault 27
180 foucault 569 return;
181     }
182 foucault 27 }
183    
184 foucault 569 // 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 foucault 27 {
194 foucault 569 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 foucault 27 }
212    
213 foucault 569 Parameter_RefEdgeTToS ( tClosestEdge, lst_ref_edges[iClosestEdge], &s, __curvilinearLength);
214 foucault 27
215 foucault 569 __t = s;
216 foucault 27
217 foucault 569 return;
218 foucault 27 }
219    
220     void
221     PolyCurve::VerifyS(double & __s)
222     {
223 foucault 569 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 foucault 569 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 foucault 569 double __s,
250     double *__t, double *__dt, bool __curvilinearLength
251     )
252 foucault 27 {
253 foucault 569 double t1,t2;
254     MG_SOMMET * vertex = lst_vertices[ __iEdge ];
255     MG_ARETE * edge = lst_ref_edges[ __iEdge ];
256 foucault 27
257 foucault 569 if (vertex == edge->get_cosommet1()->get_sommet())
258 foucault 27 {
259 foucault 569 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 foucault 27
283 foucault 569 return;
284     }
285     longueur_bsp.integrer_jusqua_gauss_2(t1, increment, s, __t);
286     *__dt = (*__t - t1) / s;
287 foucault 27 }
288     }
289    
290     void
291     PolyCurve::RefEdge_GetS(unsigned __iEdge,
292 foucault 569 double __t,
293     double *__s, bool __curvilinearLength
294     )
295 foucault 27 {
296 foucault 569 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 foucault 569 t1=edge->get_tmin();
302     t2=edge->get_tmax();
303 foucault 27
304 foucault 569 if (edge->get_courbe()->est_periodique())
305     {
306     if (__t < t1 - period*1E-6)
307     __t += period;
308     }
309 foucault 27
310 foucault 569 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 foucault 27 else
318 foucault 569 {
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 foucault 569 {
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 foucault 27
348 foucault 569 // 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 foucault 27
374 foucault 569 if ( iV[i] != 0 && iV[i]+1 != (int)lst_vertices.size() )
375     {
376 francois 660 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());
377 foucault 569 return;
378     }
379 foucault 27 }
380 foucault 569 else // vertex V[i] not found
381 foucault 27 {
382 foucault 569 iV[i] = -1;
383     iiVo = i;
384 foucault 27 }
385 foucault 569 }
386 foucault 27
387 foucault 569
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 foucault 27 return;
392     }
393 foucault 569
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 foucault 27 {
403 foucault 569 lst_vertices.push_back ( V [ iiVo ] );
404     lst_ref_edges.push_back ( __edge );
405     lst_length.push_back ( GetLength(__edge) );
406 foucault 27 }
407 foucault 569 else
408     {
409 francois 660 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());
410     printf("Polycurve Start vertex = %lu, End vertex = %lu\n", get_sommet1()->get_id(),get_sommet2()->get_id());
411     printf("Edge Start vertex = %lu, End vertex = %lu\n", V[0]->get_id(), V[1]->get_id());
412 foucault 569 return;
413     }
414 foucault 27
415 foucault 569 // 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 foucault 27
422     }
423    
424     void
425     PolyCurve::Parameter_SToRefEdgeT (double __s, unsigned * __iEdge, double *__t, double *__dt, bool __curvilinearLength)
426     {
427 foucault 569 double s;
428     unsigned i;
429 foucault 27
430 foucault 569 VerifyS(__s);
431 foucault 27
432 foucault 569 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 foucault 569 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 foucault 569 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 foucault 569 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 foucault 569 {
469     double s, ds;
470     unsigned i;
471 foucault 27
472 foucault 569 i = RefEdge_GetIndex(__edge);
473 foucault 27
474 foucault 569 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 foucault 569 *__s = s;
483 foucault 27 }
484 foucault 569
485 foucault 27 void
486     PolyCurve::evaluer (double __s, double __X[3])
487     {
488 foucault 569 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 foucault 569 if (IsPoint())
496     {
497     lst_vertices[0]->get_point()->evaluer(__X);
498     return;
499     }
500 foucault 27
501 foucault 569 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 foucault 569
511 foucault 27 void
512     PolyCurve::deriver (double __s, double __X[3]) // curvilinear abcissa
513     {
514 foucault 569 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 foucault 569 {
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 foucault 569
542 foucault 27 void
543     PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz) // curvilinear abcissa
544     {
545 foucault 569 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 foucault 569 {
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 foucault 27
564 foucault 569 VerifyS (__s);
565 foucault 27
566 foucault 569 Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
567     edge = lst_ref_edges [ iEdge ];
568 foucault 27
569 foucault 569 for (int i=0; i<3; i++)
570     __ddxyz[i] = 0;
571 foucault 27
572 foucault 569 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 foucault 27
578 foucault 569 if (__xyz)
579     edge->evaluer(t, __xyz);
580 foucault 27 }
581    
582    
583    
584     void
585     PolyCurve::Merge( PolyCurve & __polycurve)
586     {
587 foucault 569 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 francois 660 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());
611     printf("Polycurve Start vertex = %lu, End vertex = %lu\n", get_sommet1()->get_id(),get_sommet2()->get_id());
612     printf("Other __polycurve Start vertex = %lu, End vertex = %lu\n", __polycurve.get_sommet1()->get_id(), __polycurve.get_sommet2()->get_id());
613 foucault 569 return;
614 foucault 27
615 foucault 569 }
616 foucault 27 }
617    
618     void
619     PolyCurve::SetPeriodicPoleRefVertex(MG_SOMMET * __v)
620     {
621     if ( est_periodique() == false)
622     return;
623 foucault 569
624 foucault 27 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 foucault 569 unsigned m = (i+k)%N;
632     unsigned n = (i+k+1)%N;
633 foucault 27 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 foucault 569 PolyCurve::get_longueur (double __s_min, double __s_max, double precision)
650 foucault 27 {
651 foucault 569 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 foucault 27 }
659    
660     double PolyCurve::get_tmin()
661     {
662 foucault 569 return t_min;
663 foucault 27 }
664    
665     double PolyCurve::get_tmax()
666     {
667 foucault 569 return t_max;
668 foucault 27 }
669    
670     MG_SOMMET *
671 foucault 569 PolyCurve::get_sommet1()
672 foucault 27 {
673 foucault 569 return lst_vertices[0];
674 foucault 27 }
675    
676    
677     MG_SOMMET *
678 foucault 569 PolyCurve::get_sommet2()
679 foucault 27 {
680 foucault 569 return lst_vertices[lst_vertices.size()-1];
681 foucault 27 }
682    
683     double
684     PolyCurve::get_sommet1_s()
685     {
686 foucault 569 return get_tmin();
687 foucault 27 }
688    
689    
690     double
691 foucault 569 PolyCurve::get_sommet2_s()
692 foucault 27 {
693 foucault 569 return get_tmax();
694 foucault 27 }
695    
696     void
697     PolyCurve::inverser(double & __t, double __point[3], double precision)
698     {
699 foucault 569 bool curvilinearLength = false;
700 foucault 27
701 foucault 569 inverser(__t, __point, precision, curvilinearLength);
702 foucault 27 }
703    
704     int PolyCurve::est_periodique(void)
705     {
706 foucault 569 if ( get_sommet1 () == get_sommet2 () )
707     return 1;
708     else
709     return 0;
710 foucault 27 }
711    
712     double PolyCurve::get_periode(void)
713     {
714     if ( est_periodique() )
715     return get_longueur();
716     else
717 foucault 569 return 0;
718 foucault 27 }
719    
720    
721     int PolyCurve::get_type_geometrique(TPL_LISTE_ENTITE<double> &param)
722     {
723 foucault 569 return 4343; // TYPE = Poly curve
724 foucault 27 }
725    
726 francois 763 void PolyCurve::enregistrer(std::ostream& o,double version)
727 foucault 27 {
728     unsigned int i;
729    
730     if (IsPoint() == false)
731 foucault 569 {
732     o << "%" << get_id()
733     << "=CAD4FE_POLYCURVE(" << GetRefEdgeCount() << ",(";
734    
735     for (i=0; i < GetRefEdgeCount(); i++)
736 foucault 27 {
737 foucault 569 if ( i ) o <<",";
738     o << "$" << GetRefEdge(i)->get_id();
739     }
740 foucault 27
741 foucault 569 o << "));" << std::endl;
742     }
743 foucault 27 else // The polycurve is a point !
744 foucault 569 {
745     o << "%" << get_id() << "=CAD4FE_POLYCURVE(0,($"<<GetRefVertex(0)->get_id()<<"));"<< std::endl;
746     }
747 foucault 27 }
748    
749 foucault 569 std::vector<MG_ARETE*> &
750     PolyCurve::GetRefEdges()
751 foucault 27 {
752 foucault 569 return lst_ref_edges;
753 foucault 27 }
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 foucault 569 double tSplit;
760 foucault 27 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 foucault 569
777 foucault 27 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 foucault 569
782 foucault 27 curves[0] = curves[1] = splitEdge->get_courbe();
783    
784     double verticesT[2][2];
785 foucault 569 verticesT[0][0] = splitEdge->get_tmin();
786 foucault 27 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 foucault 569 int orientation = splitEdge->get_orientation();
794 foucault 27 // 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 foucault 569 // 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 francois 283 // for each coface->face F of the shell
823 foucault 569 unsigned nb_coface = shell->get_nb_mg_coface();
824     for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
825 foucault 27 {
826 foucault 569 MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
827 foucault 27
828 foucault 569 // 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 foucault 27 {
832 foucault 569 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 francois 283 }
862 foucault 27 }
863 foucault 569 }
864 foucault 27
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 francois 660 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());
898 foucault 27 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 foucault 569
906 foucault 27 // 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 foucault 569
916 foucault 27 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 foucault 569 std::swap(__splitRefEdges[0], __splitRefEdges[1] );
925 foucault 27
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 foucault 569 __result[0]->get_sommet2() !=__result[1]->get_sommet1() &&__result[0]->get_sommet2() !=__result[1]->get_sommet2())
939 foucault 27 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 foucault 569 return;
952 foucault 27 }
953    
954    
955