ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/mtu/src/CAD4FE_PolyCurve.cpp
Revision: 1158
Committed: Thu Jun 13 22:18:49 2024 UTC (11 months, 1 week ago) by francois
File size: 31273 byte(s)
Log Message:
compatibilité Ubuntu 22.04
Suppression des refeences à Windows
Ajout d'une banière

File Contents

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