ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/geometrie/src/CAD4FE_PolyCurve.cpp
Revision: 906
Committed: Mon Nov 13 22:30:18 2017 UTC (7 years, 6 months ago) by couturad
File size: 30691 byte(s)
Log Message:
Nouveau opencascade commit 1

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