ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCSegment.cpp
Revision: 763
Committed: Wed Dec 2 19:55:53 2015 UTC (9 years, 5 months ago) by francois
File size: 38557 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     #include <fstream>
4    
5     #pragma hdrstop
6    
7     #include "gestionversion.h"
8     #include "CAD4FE_MCSegment.h"
9     #include "CAD4FE_MCFace.h"
10     #include "CAD4FE_MCEdge.h"
11    
12     #include "ot_algorithme_geometrique.h"
13     #include "ot_decalage_parametre.h"
14     #include "CAD4FE_MCNode.h"
15     #include "CAD4FE_PolySurface.h"
16     #include "CAD4FE_PolyCurve.h"
17     #include "CAD4FE_MCVertex.h"
18     #include "CAD4FE_MCEdge.h"
19     #include "CAD4FE_Intersection_Plane_PolySurface.h"
20     #include "CAD4FE_ShortestPathByClosestPointOnEdge.h"
21     #include "CAD4FE_MCNodePolyline.h"
22 foucault 569 #include "CAD4FE_Geometric_Tools.h"
23 foucault 27 #include "CAD4FE_InventorText_MG_MAILLAGE.h"
24     #include "ot_root_find.h"
25     #include "CAD4FE_mailleur2d.h"
26    
27     //---------------------------------------------------------------------------
28    
29     #pragma package(smart_init)
30    
31     using namespace CAD4FE;
32    
33     //---------------------------------------------------------------------------
34     MCSegment::MCSegment (unsigned long num, MG_ELEMENT_TOPOLOGIQUE *topo, MCNode *mgnoeud1, MCNode *mgnoeud2, double longue)
35     : MG_SEGMENT(num,topo,mgnoeud1,mgnoeud2,longue),_polylineEvaluator(0),_sense(1), _saveFormat(0)
36     {
37     _cstrMCFaceScheme = CstrMCFaceByPlaneIntr;
38     ConstructGeometry();
39     }
40     //---------------------------------------------------------------------------
41     MCSegment::MCSegment (MG_ELEMENT_TOPOLOGIQUE *topo, MCNode *mgnoeud1, MCNode *mgnoeud2, double longue, long __cstrMCFaceScheme)
42     : MG_SEGMENT(topo,mgnoeud1,mgnoeud2,longue),_polylineEvaluator(0),_sense(1),_cstrMCFaceScheme(__cstrMCFaceScheme), _saveFormat(0)
43     {
44     ConstructGeometry();
45     }
46     //---------------------------------------------------------------------------
47     MCSegment::MCSegment( MCSegment & __s)
48     : MG_SEGMENT(0,__s.liaison_topologique,__s.get_noeud1(),__s.get_noeud2(),__s.get_longueur()), _saveFormat(0)
49     {
50     unsigned i;
51     for (FMapCIterator itF = __s.F.begin(); itF != __s.F.end(); itF++)
52     {
53     MG_FACE * face = itF->first;
54     F.insert(std::make_pair(face,itF->second));
55     }
56     for (EMapCIterator itE = __s.E.begin(); itE != __s.E.end(); itE++)
57     {
58     MG_ARETE * edge = itE->first;
59     E.insert(std::make_pair(edge,itE->second));
60     }
61     //V = __s.V;
62     _polylineEvaluator=new MCNodePolyline(*__s._polylineEvaluator);
63     _sense = __s._sense;
64     }
65     //---------------------------------------------------------------------------
66     MCSegment::FMap & MCSegment::GetRefFaceMapping()
67     {
68     return F;
69     }
70     //---------------------------------------------------------------------------
71     MCSegment::EMap & MCSegment::GetRefEdgeMapping()
72     {
73     return E;
74     }
75     //---------------------------------------------------------------------------
76     MCSegment::~MCSegment()
77     {
78     unsigned i,j;
79     if (_polylineEvaluator) delete _polylineEvaluator;
80     }
81     //---------------------------------------------------------------------------
82     std::vector <MCNode*> MCSegment::GetPolylineNodes()
83     {
84     return _polylineEvaluator->GetPolylineNodes();
85     }
86     //---------------------------------------------------------------------------
87     MCNode* MCSegment::GetPolylineNode(unsigned __index)
88     {
89     return _polylineEvaluator->GetPolylineNode(__index);
90     }
91     //---------------------------------------------------------------------------
92     std::vector <MG_ELEMENT_TOPOLOGIQUE*> MCSegment::GetPolylineTopos()
93     {
94     return _polylineEvaluator->GetPolylineTopos();
95     }
96     //---------------------------------------------------------------------------
97     MG_ELEMENT_TOPOLOGIQUE* MCSegment::GetPolylineTopo(unsigned __index)
98     {
99     return _polylineEvaluator->GetPolylineTopo(__index);
100     }
101     //---------------------------------------------------------------------------
102     unsigned MCSegment::GetPolylineNodeCount()
103     {
104     return _polylineEvaluator->GetPolylineNodes().size();
105     }
106     //---------------------------------------------------------------------------
107     double MCSegment::get_longueur_geo()
108     {
109     double length = _polylineEvaluator->GetLength();
110     return length;
111     }
112     //---------------------------------------------------------------------------
113     void MCSegment::evaluer_geo(double __t, MCNode * __result, double * tangent, double * curvature)
114     {
115     double t,L;
116     if (_sense == -1)
117     t = (1-__t);
118     else
119     t = __t;
120    
121     L=get_longueur_geo();
122     * __result = _polylineEvaluator->Evaluate( t * L, tangent, curvature );
123     if (tangent)
124     for (int i=0; i<3; i++) tangent[i] *= L;
125     if (_sense == -1)
126     {
127     if (tangent)
128     for (int i=0; i<3; i++) tangent[i]*=-1;
129     }
130     }
131     //---------------------------------------------------------------------------
132     void MCSegment::inverser_geo(double & __t, MCNode * __node)
133     {
134     _polylineEvaluator->Inverse(__t, __node);
135     double length = _polylineEvaluator->GetLength();
136     __t = __t/length;
137    
138     if (_sense == -1)
139     __t = (1-__t);
140     }
141     //---------------------------------------------------------------------------
142     int MCSegment::get_orientation()
143     {
144     return _sense;
145     }
146     //---------------------------------------------------------------------------
147     void MCSegment::change_orientation(int __sense)
148     {
149     _sense = __sense;
150     }
151     //---------------------------------------------------------------------------
152     void MCSegment::UpdateGeometry ()
153     {
154     calcule_longueur();
155     F.clear();
156     E.clear();
157     //V.clear();
158     delete _polylineEvaluator;
159     _polylineEvaluator = 0;
160     ConstructGeometry ();
161     }
162     //---------------------------------------------------------------------------
163     void MCSegment::ConstructGeometry ()
164     {
165     MCNode * mcNode1 = (MCNode*)get_noeud1();
166     MCNode * mcNode2 = (MCNode*)get_noeud2();
167     CAD4FE::MCFace * mcFace = NULL;
168     CAD4FE::MCEdge * mcEdge = NULL;
169     if (get_lien_topologie()->get_dimension() == 2)
170     {
171     mcFace = (MCFace*)get_lien_topologie();
172     }
173     if (get_lien_topologie()->get_dimension() == 1)
174     {
175     mcEdge = ((CAD4FE::MCEdge*)get_lien_topologie());
176     }
177     if (mcEdge)
178     {
179     Construct_MCEdge(mcEdge);
180     Construct_MergedVertices(mcNode1);
181     Construct_MergedVertices(mcNode2);
182     }
183     else if (mcFace)
184     {
185     int res;
186     if (_cstrMCFaceScheme == CstrMCFaceByPlaneIntr )
187     {
188     res = Construct_MCFace(mcFace,mcNode1,mcNode2);
189     if (res != 1 )
190     {
191     res = Construct_MCFaceByShortestPath(mcFace,mcNode1,mcNode2);
192     if (res == 1) _cstrMCFaceScheme = CstrMCFaceByShortestPath;
193     }
194     }
195     else if (_cstrMCFaceScheme == CstrMCFaceByPlaneIntrNormalByShortestPath)
196     {
197     res = Construct_MCFace(mcFace,mcNode1,mcNode2);
198     if (res != 1)
199     {
200     res = Construct_MCFaceByShortestPath(mcFace,mcNode1,mcNode2);
201     if (res == 1)
202     _cstrMCFaceScheme = CstrMCFaceByShortestPath;
203     }
204     }
205     else if (_cstrMCFaceScheme == CstrMCFaceByShortestPath )
206     {
207     res = Construct_MCFaceByShortestPath(mcFace,mcNode1,mcNode2);
208     if (res != 1)
209     {
210     res = Construct_MCFace(mcFace,mcNode1,mcNode2);
211     if (res == 1)
212     _cstrMCFaceScheme = CstrMCFaceByPlaneIntr;
213     }
214     }
215     else if (_cstrMCFaceScheme == CstrNoRefTopologyMapping)
216     {
217     res = Construct_NoTopology(mcNode1,mcNode2);
218     }
219     }
220    
221     _sense = 1;
222     ConstructBoundaryBox();
223     }
224    
225     void MCSegment::ConstructBoundaryBox()
226     {
227     for (unsigned j=0; j<_polylineEvaluator->GetPolylineNodes().size();j++)
228     {
229     MCNode * n = _polylineEvaluator->GetPolylineNode(j);
230     double * x = n->get_coord();
231     if (j == 0)
232     {
233     for (int i=0;i<3;i++)
234     _bbox[i] = _bbox[i+3] = x[i];
235     }
236     else
237     {
238     for (int i=0;i<3;i++)
239     {
240     if (_bbox[i]>x[i])
241     _bbox[i] = x[i];
242     else if (_bbox[i+3]<x[i])
243     _bbox[i+3] = x[i];
244     }
245     }
246     }
247     for (double t=.25; t<=.75; t+=.25)
248     {
249     MCNode n = _polylineEvaluator->Evaluate(t);
250     double * x = n.get_coord();
251    
252     for (int i=0;i<3;i++)
253     {
254     if (_bbox[i]>x[i])
255     _bbox[i] = x[i];
256     else if (_bbox[i+3]<x[i])
257     _bbox[i+3] = x[i];
258     }
259     }
260     }
261    
262     extern MG_MAILLAGE * debugMesh;
263    
264     int MCSegment::Construct_MCFaceByShortestPath(MCFace * __mcFace, MCNode* __n1, MCNode* __n2)
265     {
266     unsigned i,j;
267     double dN1N2=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__n1->get_coord(),__n2->get_coord());
268     int shortestPathOptions = 0;
269     ShortestPathByClosestPointOnEdge shortestPath(__mcFace,__n1,__n2,dN1N2, shortestPathOptions);
270     ShortestPathByClosestPointOnEdge *shortestPathDoubleDist = NULL;
271     std::vector<MCNode*> vecPts;
272     std::vector<MG_ELEMENT_TOPOLOGIQUE*> vecTopo;
273     double distance = shortestPath.Find(&vecPts,&vecTopo);
274    
275     if (distance > 100) // failure, second try with 2*dist(n1,n2)
276     {
277     unsigned maxNbTries = 4;
278     unsigned maxDistFactor = 1;
279     for (i=0; i<maxNbTries; i++)
280     {
281     maxDistFactor *= 2;
282     vecPts.clear();vecTopo.clear();
283     shortestPathDoubleDist = new ShortestPathByClosestPointOnEdge (__mcFace,__n1,__n2,maxDistFactor*dN1N2, shortestPathOptions);
284     distance = shortestPathDoubleDist->Find(&vecPts,&vecTopo);
285     if (distance > 100)
286     {
287     delete shortestPathDoubleDist;
288     vecPts.clear();vecTopo.clear();
289     shortestPathOptions=ShortestPathByClosestPointOnEdge::NoCheckFaceIntr;
290     shortestPathDoubleDist = new ShortestPathByClosestPointOnEdge (__mcFace,__n1,__n2,maxDistFactor*dN1N2, shortestPathOptions);
291     distance = shortestPathDoubleDist->Find(&vecPts,&vecTopo);
292     if (distance > 100)
293     {
294     delete shortestPathDoubleDist;
295     shortestPathDoubleDist = NULL;
296     }
297     }
298     else
299     {
300     break;
301     }
302     }
303     }
304    
305     if (distance > 100)
306     {
307     printf("Warning : Construct_MCFaceByShortestPath failed !\n");
308     distance = shortestPath.Find(&vecPts,&vecTopo);
309     Construct_MCFace(__mcFace,__n1,__n2);
310     return 0;
311     }
312     if (distance < .8*dN1N2)
313     {
314     printf("Warning : %d < .8*%f in Construct_MCFaceByShortestPath !\n", distance, dN1N2);
315     }
316    
317     if (_polylineEvaluator == NULL) _polylineEvaluator = new MCNodePolyline(liaison_topologique);
318    
319     for (i=0;i+1<vecPts.size();i++)
320     {
321     MCNode * xi=vecPts[i], *xii=vecPts[i+1];
322     MG_ELEMENT_TOPOLOGIQUE * topo = vecTopo[i];
323    
324     if (topo->get_dimension() == 2)
325     {
326     MG_FACE * face = (MG_FACE *) topo;
327     std::vector<MCNode*> Ci;
328     OT_VECTEUR_3D normalXi,normalXii,normalAvg,dir,v,xi_xyz(xi->get_coord()),xii_xyz(xii->get_coord());
329     xi->NormalMCFace(__mcFace, normalXi);
330     xii->NormalMCFace(__mcFace, normalXii);
331     normalAvg = .5*normalXi+.5*normalXii;
332     dir=xii_xyz-xi_xyz;
333     v=normalAvg&dir;
334     double L=dir.get_longueur();
335     Intersection_Plane_MG_FACE * intr = NULL;
336     if (L > 1E-6 && ((shortestPathOptions&ShortestPathByClosestPointOnEdge::NoCheckFaceIntr)==0))
337     {
338     intr = new Intersection_Plane_MG_FACE(xi,v,face,__mcFace);
339     intr->MakeSegment(xi,xii,L/50,L/3000,3,dir);
340     Ci = intr->Get()[0];
341     if (Ci.size()<2||Ci[Ci.size()-1]!=xii||Ci[0]!=xi)
342     {
343     delete intr;
344     intr = 0;
345     Ci.clear();
346     Ci.push_back(xi);
347     Ci.push_back(xii);
348     }
349     }
350     else
351     {
352     Ci.push_back(xi);
353     Ci.push_back(xii);
354     }
355     F.insert( std::make_pair(face, Ci) );
356    
357     for (j=0; j<Ci.size(); j++)
358     {
359     _polylineEvaluator->Add(Ci[j],face);
360     }
361     if (intr != NULL)
362     delete intr;
363     }
364     if (topo->get_dimension() == 1)
365     {
366     MG_ARETE * edge = (MG_ARETE *) topo;
367    
368     //double dist = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(xi->get_coord(), xii->get_coord());
369     //double epsilon = dist*1E-2;
370     //int insertedNodeCount = RefineInRefEdge(__mcFace, edge, xi, xii, epsilon, 1E300, refinedNodes, refinedEdges );
371    
372     VPts Ci;
373     Ci.push_back(xi);
374     Ci.push_back(xii);
375    
376     E.insert (std::make_pair(edge, Ci));
377     for (int itF = 0; itF < edge->get_nb_mg_coarete(); itF++)
378     {
379     MG_FACE * face = edge->get_mg_coarete(itF)->get_boucle()->get_mg_face();
380     F.insert(std::make_pair(face, Ci));
381     }
382    
383     for (j=0; j<Ci.size(); j++)
384     {
385     _polylineEvaluator->Add(Ci[j],edge);
386     }
387     }
388     if (topo->get_dimension() == 0)
389     {
390    
391     }
392     }
393    
394     if (shortestPathDoubleDist != NULL)
395     delete shortestPathDoubleDist;
396    
397     return 1;
398     }
399    
400     int MCSegment::Construct_NoTopology(MCNode * __n1, MCNode * __n2)
401     {
402     _polylineEvaluator = new MCNodePolyline(liaison_topologique);
403     _polylineEvaluator->Add(__n1,NULL);
404     _polylineEvaluator->Add(__n2,NULL);
405     return 1;
406     }
407    
408     int MCSegment::Construct_MCFace(MCFace * __mcFace, MCNode* __n1, MCNode* __n2)
409     {
410     unsigned i,j;
411     PolySurface * polysurface = __mcFace->GetPolySurface();
412    
413     OT_VECTEUR_3D normal1, normal2, xyz1, xyz2, v1, v2;
414     if ( _cstrMCFaceScheme != CstrMCFaceByPlaneIntrNormalByShortestPath )
415     {
416     int nbRefFaces;
417     polysurface->calcul_normale_unitaire(__n1->GetRefFaceMapping(),normal1,&nbRefFaces);
418     polysurface->calcul_normale_unitaire(__n2->GetRefFaceMapping(),normal2,&nbRefFaces);
419     v2 = .5*(normal1+normal2);
420     if (v2.get_longueur2() < 1E-100)
421     {
422     printf("Warning: surface's normal at node 1 is opposite to surface's normal at node 2\n");
423     printf("\t trying to evaluate surface's normal with the shortest path algorithm\n");
424     _cstrMCFaceScheme = CstrMCFaceByPlaneIntrNormalByShortestPath;
425     }
426     }
427     if (_cstrMCFaceScheme==CstrMCFaceByPlaneIntrNormalByShortestPath)
428     {
429     double maxDistBetween3DSegmentAndShortestPath=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__n1->get_coord(),__n2->get_coord());
430     ShortestPathByClosestPointOnEdge * shortestPath = new ShortestPathByClosestPointOnEdge(__mcFace,__n1,__n2,maxDistBetween3DSegmentAndShortestPath);
431     std::vector<MCNode*> vecPts;
432     std::vector<MG_ELEMENT_TOPOLOGIQUE*> vecTopo;
433     double distance=shortestPath->Find(&vecPts, &vecTopo);
434     if (distance > 100)
435     {
436     // delete shortestPath;
437     // vecPts.clear(); vecTopo.clear();
438     // shortestPath = new ShortestPathByClosestPointOnEdge(__mcFace,__n1,__n2,100);
439     double *x1=__n1->get_coord(),*x2=__n2->get_coord();
440     printf("%f %f %f %f %f %f ",x1[0],x1[1],x1[2],x2[0],x2[1],x2[2]);
441     // double distance = shortestPath->Find(&vecPts, &vecTopo);
442     if (distance > 100)
443     printf("Error in average normal\n");
444    
445     }
446     if (distance == 0.0)
447     {
448     delete shortestPath;
449     return 0;
450     }
451     // estimation of the face normal by the average of the normals
452     // in the polyline
453     OT_VECTEUR_3D avgNormal(0,0,0);
454     MCNodePolyline polyline(liaison_topologique,vecPts,vecTopo);
455     unsigned nb_points=10, real_nb_points=0;
456     double s_max=polyline.GetLength();
457     for (double s=0; real_nb_points < 1 || s < s_max; s+=.9999*(s_max/nb_points))
458     {
459     real_nb_points++;
460     MCNode mcNode=polyline.Evaluate(s);
461     OT_VECTEUR_3D tmpNormal;
462     int nbRefFaces;
463     polysurface->calcul_normale_unitaire(mcNode.GetRefFaceMapping(),tmpNormal,&nbRefFaces);
464     avgNormal += tmpNormal;
465     }
466     avgNormal /= real_nb_points;
467     v2=avgNormal;
468     delete shortestPath;
469     }
470    
471     xyz1=OT_VECTEUR_3D(__n1->get_coord());
472     xyz2=OT_VECTEUR_3D(__n2->get_coord());
473     v1=xyz2-xyz1;
474    
475     // Make a special treatment to manage nodes of merged vertices
476     MCNode * polysurfaceNodes[2]={__n1,__n2};
477     MCNode * n[2]={__n1,__n2};
478     VPts MergedVertexCurveNodes[2];
479     std::vector < MG_ELEMENT_TOPOLOGIQUE * > MergedVertexCurveTopo[2];
480     for (int i=0;i<2;i++)
481     if (n[i]->GetRefVertexMapping().size() > 1) // if node is in a merged vertex
482     {
483     MCVertex * mcVertex = (MCVertex*) n[i]->get_lien_topologie();
484     MG_SOMMET * refVertex = (MG_SOMMET*) n[i]->get_lien_topologie_reference();
485     MG_SOMMET * mergedVertex = NULL;
486     if (GeometricTools::PolySurface_Contains_RefVertex(polysurface,refVertex) == false)
487     {
488     for (MCNode::VMapIterator itV = n[i]->GetRefVertexMapping().begin();
489     itV != n[i]->GetRefVertexMapping().end();
490     itV++)
491     if ( GeometricTools::PolySurface_Contains_RefVertex(polysurface,*itV) )
492     {
493     mergedVertex = *itV;
494     break;
495     }
496    
497     double xyz[3];mergedVertex->get_point()->evaluer(xyz);
498     double d=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(xyz,n[i]->get_coord());
499     MCNode * mergedVertexNode = new MCNode(mcVertex,mergedVertex,xyz[0],xyz[1],xyz[2]);
500     polysurfaceNodes[i] = mergedVertexNode;
501    
502     MCFace * mcFacePath = NULL;
503     std::set<MG_FACE*> mergedVertexMCFaces;
504     GeometricTools::MG_SOMMET_GetAdjacent_MG_FACE(mcVertex,mergedVertexMCFaces);
505     for (std::set<MG_FACE*>::iterator itF=mergedVertexMCFaces.begin();
506     itF != mergedVertexMCFaces.end(); itF++)
507     {
508     MCFace* adjacentMCFace = (MCFace*)(*itF);
509     if (GeometricTools::PolySurface_Contains_RefVertex(adjacentMCFace->GetPolySurface(),mergedVertex)
510     && GeometricTools::PolySurface_Contains_RefVertex(adjacentMCFace->GetPolySurface(),refVertex)
511     )
512     {
513     mcFacePath = adjacentMCFace;
514     break;
515     }
516     }
517     ShortestPathByClosestPointOnEdge shortestPath(mcFacePath,n[i],mergedVertexNode,d);
518     double distance = shortestPath.Find(&(MergedVertexCurveNodes[i]),&(MergedVertexCurveTopo[i]));
519    
520     if (distance < 100)
521     for (unsigned j=0; j<MergedVertexCurveNodes[i].size();j++)
522     MergedVertexCurveNodes[i][j]->incrementer();
523     }
524     }
525    
526     Intersection_Plane_PolySurface intrPolySurface (polysurfaceNodes[0], v2&v1, __mcFace, polysurfaceNodes[1]);
527     MCNodePolyline * intersectionPlaneMCFace = intrPolySurface.MakeSegment(polysurfaceNodes[0], polysurfaceNodes[1], v1);
528    
529     if (intersectionPlaneMCFace != NULL)
530     {
531     _polylineEvaluator = intersectionPlaneMCFace;
532     _polylineEvaluator->incrementer();
533    
534     Intersection_Plane_PolySurface::FMapIterator it;
535     Intersection_Plane_MG_FACE * intr = NULL;
536     for (intr = intrPolySurface.GetFirstCurve(it); intr; intr = intrPolySurface.GetNextCurve(it) )
537     {
538     MG_FACE * face = intr->GetFace();
539     VPts nodes = intr->Get()[0];
540     F.insert(std::make_pair(face, nodes));
541     }
542    
543     for ( unsigned i=0;1+i<GetPolylineNodeCount();i++)
544     {
545     MG_ELEMENT_TOPOLOGIQUE * topo = GetPolylineTopo(i);
546     if ( topo != NULL && topo->get_dimension()==1)
547     {
548     MCNode * xi = GetPolylineNode(i);
549     MCNode * xii = GetPolylineNode(i+1);
550     MG_ARETE * edge = (MG_ARETE *) topo;
551     VPts Ci;
552     Ci.push_back(xi);
553     Ci.push_back(xii);
554    
555     E.insert (std::make_pair(edge, Ci));
556     for (int itF = 0; itF < edge->get_nb_mg_coarete(); itF++)
557     {
558     MG_FACE * face = edge->get_mg_coarete(itF)->get_boucle()->get_mg_face();
559     F.insert(std::make_pair(face, Ci));
560     }
561     }
562     }
563    
564     return 1;
565     }
566     else
567     {
568     return 0;
569     }
570     }
571    
572 foucault 569 int MCSegment::RefineInRefEdge(MCEdge * __mcEdge, MG_ARETE * __refEdge, MCNode * __n1, MCNode * __n2, double __epsilon, double __lastDistanceToEdge, std::map < double , MCNode * > & __mapMCEdgeNodesBySParameter, std::map < double , MG_ARETE * > & __mapMCEdgeRefEdgesBySParameter, int __iRecursiveCalls)
573 foucault 27 {
574 foucault 569 static const int RefineInRefEdge_MAX_RECURSIVE_CALL_COUNT = 100;
575     if (__iRecursiveCalls > RefineInRefEdge_MAX_RECURSIVE_CALL_COUNT)
576     {
577     printf("Warning : RefineInRefEdge : The number of recursive calls has been reached (%d)\n",RefineInRefEdge_MAX_RECURSIVE_CALL_COUNT);
578     return 0;
579     }
580    
581 foucault 27 int insertedNodeCount = 0;
582     MCNode * n[2] = { __n1, __n2};
583     for (int i=0; i<2; i++)
584     {
585     MG_SOMMET * v = 0;
586     if (n[i]->get_lien_topologie_reference()->get_dimension() == 0)
587     v = (MG_SOMMET * ) n[i]->get_lien_topologie_reference();
588     if (v)
589     if (__mcEdge->GetPolyCurve()->Contains( v ) == false )
590     return 0;
591     if (n[i]->IsInEdge(__refEdge) == false)
592     return 0;
593     // nodes have merged ref vertices
594     if (n[(i+1)%2]->IsInVertex(v))
595     return 0;
596     }
597     __n1->incrementer();__n2->incrementer();
598     double t1 = __n1->T(__refEdge);
599     double t2 = __n2->T(__refEdge);
600     if (fabs(t2-t1) < 1E-6*(__refEdge->get_tmax()-__refEdge->get_tmin()))
601     return 0;
602    
603     double period = __refEdge->get_courbe()->get_periode();
604     if (period != 0.0 && fabs(t2 - t1) > .5*period)
605     if (t2<t1)
606     t2 += period;
607     else t1 += period;
608     double t3 = t1 + (t2-t1)*.5;
609     double s3;
610     double xyz[3]; __refEdge->evaluer(t3,xyz);
611     MCNode edgeNode (__mcEdge, __refEdge, t3, xyz);
612     for (int i=0; i<__refEdge->get_nb_mg_coarete(); i++)
613     {
614     MG_FACE * face = __refEdge->get_mg_coarete(i)->get_boucle()->get_mg_face();
615    
616     MCNodePolyline faceLine(liaison_topologique);
617     faceLine.Add(__n1,face);
618     faceLine.Add(__n2,face);
619     double L = faceLine.GetLength();
620     MCNode faceNode = faceLine.Evaluate(L*.5);
621     double distanceToEdge = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(faceNode.get_coord(),edgeNode.get_coord());
622     double ratioConvergence = distanceToEdge / __lastDistanceToEdge;
623     double distN1N2 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__n2->get_coord(),__n1->get_coord());
624     bool testConvergence = ( fabs(ratioConvergence - 1) < .001 || distN1N2 < __epsilon );
625     if ( (distanceToEdge > __epsilon )
626     && testConvergence == false )
627     {
628     insertedNodeCount++;
629     __mcEdge->GetPolyCurve()->Parameter_RefEdgeTToS ( t3, __refEdge, &s3, false);
630     if (__mcEdge->GetPolyCurve()->est_periodique()
631     && __mcEdge->get_tmin() > s3+1E-5*(__mcEdge->GetPolyCurve()->get_periode())
632     )
633     s3 += __mcEdge->GetPolyCurve()->get_periode();
634     MCNode * newMCNode = new MCNode ( edgeNode );
635     __mapMCEdgeNodesBySParameter.insert(std::make_pair(s3,newMCNode));
636     __mapMCEdgeRefEdgesBySParameter.insert(std::make_pair(s3, __refEdge));
637     newMCNode->incrementer();
638 foucault 569 insertedNodeCount += RefineInRefEdge(__mcEdge, __refEdge, __n1, newMCNode, __epsilon, distanceToEdge, __mapMCEdgeNodesBySParameter,__mapMCEdgeRefEdgesBySParameter, __iRecursiveCalls+1);
639     insertedNodeCount += RefineInRefEdge(__mcEdge, __refEdge, newMCNode, __n2, __epsilon, distanceToEdge, __mapMCEdgeNodesBySParameter,__mapMCEdgeRefEdgesBySParameter, __iRecursiveCalls+1);
640 foucault 27 newMCNode->decrementer();
641     break;
642     }
643     }
644     __n1->decrementer();__n2->decrementer();
645     return insertedNodeCount;
646     }
647    
648     int MCSegment::Construct_MCEdge(MCEdge * __mcEdge)
649     {
650     double s[2];
651     double t,dt;
652     int i,j;
653     unsigned iEdge;
654     MG_ARETE * edge;
655     PolyCurve * polycurve = __mcEdge->GetPolyCurve();
656     double period = polycurve->get_periode();
657     double smin = __mcEdge->get_tmin();
658     double smax = __mcEdge->get_tmax();
659    
660     VPts CurveNodes;
661     std::vector < MG_ELEMENT_TOPOLOGIQUE * > CurveTopo;
662    
663     MCNode * n[2];
664     n[0]=(MCNode *)get_noeud1();
665     n[1]=(MCNode *)get_noeud2();
666    
667     std::map < double , MCNode * > nodes;
668     std::map < double , MG_ARETE * > edges;
669    
670     // get the parameter of extremities n1 n2 of the segment
671     for (i=0; i<2; i++)
672     {
673     if (n[i]->GetRefVertexMapping().size() >= 1) // MC node is on a ref vertex
674     {
675     MG_SOMMET * refVertex = (MG_SOMMET*)n[i]->get_lien_topologie_reference();
676     if (polycurve->ContainsRefVertex(refVertex) == false)
677     {
678     for (std::set<MG_SOMMET*>::iterator itV = n[i]->GetRefVertexMapping().begin();
679     itV != n[i]->GetRefVertexMapping().end();
680     itV++)
681     {
682     MG_SOMMET * v = *itV;
683     if (polycurve->ContainsRefVertex(v))
684     {
685     s[i] = polycurve->RefVertex_GetS(v);
686     if (n[i]->get_lien_topologie_reference() != v)
687     {
688     double xyzV[3]; v->get_point()->evaluer(xyzV);
689     n[i] = new MCNode (__mcEdge,v,xyzV[0],xyzV[1],xyzV[2]);
690     //n[i]->incrementer();
691     }
692     break;
693     }
694     }
695     }
696     else
697     {
698     s[i] = polycurve->RefVertex_GetS(refVertex);
699     }
700     }
701     else if (n[i]->GetRefEdgeMapping().size() == 1) // MC node is in a ref edge
702     {
703     polycurve->inverser(s[i], n[i]->get_coord(), 1E-6);
704     }
705     }
706    
707     if (period != 0.0)
708     {
709     for (i=0;i<2;i++){
710     if (s[i] > smax + fabs(smax-smin)*1E-6)
711     s[i] -= period;
712     if (s[i] < smin - fabs(smax-smin)*1E-6)
713     s[i] += period; }
714     }
715    
716     if (period != 0.0 && fabs(s[1] - s[0]) > .5*period)
717     if (s[1]<s[0])
718     s[1] += period;
719     else s[1] += period;
720    
721     for (i=0; i<2; i++)
722     {
723     nodes[s[i]] = n[i];
724     }
725    
726     {
727     MG_ARETE * edge; double t,dt;
728     double si = std::min(s[0],s[1]);
729     polycurve->Parameter_SToRefEdgeT ( si+1E-6*fabs(s[1]-s[0]), &edge,&t,&dt,false);
730     edges [ si ] = edge;
731     }
732    
733    
734     for (int i=0; i<2; i++)
735     {
736     OT_VECTEUR_3D v, v_node(n[i]->get_coord());
737     polycurve->evaluer(s[i], v);
738     double dist = (v_node-v).get_longueur();
739     if (dist > .001*__mcEdge->GetPolyCurve()->get_longueur())
740     {
741     printf("Distance between projection and node = %f\n", dist);
742     polycurve->inverser(s[i], n[i]->get_coord(), 1E-6);
743     polycurve->evaluer(s[i], v);
744     }
745     }
746    
747     // Create nodes in vertices between n1 and n2
748     double si=0;
749     for (i=0;si<std::max(s[1],s[0]);i++)
750     {
751     int iEdge = i%polycurve->GetRefEdgeCount();
752     int iVertex = (period != 0.0)? i%(polycurve->GetRefVertexCount()-1): i%polycurve->GetRefVertexCount();
753     if ((si-s[0])*(s[1]-si) > 0)
754     {
755     MG_SOMMET * vertex = polycurve->GetRefVertex(iVertex);
756     double xyz[3];vertex->get_point()->evaluer(xyz);
757     MCNode * ni = new MCNode ( __mcEdge, vertex, xyz[0], xyz[1], xyz[2] );
758     nodes [ si ] = ni;
759     edges [ si ] = polycurve->GetRefEdge(iEdge);
760     //ni->incrementer();
761     }
762     si += polycurve->GetLength(iEdge);
763     }
764    
765     std::map < double , MCNode * > refinedNodes = nodes;
766     std::map < double , MG_ARETE * > refinedEdges = edges;
767    
768     for (std::map<double, MCNode * >::iterator itN = nodes.begin();
769     itN != nodes.end();
770     itN++)
771     {
772     std::map<double, MCNode * >::iterator itNii = itN;
773     itNii++;
774     if (itNii == nodes.end())
775     break;
776     MCNode * ni = itN->second;
777     MCNode * nii = itNii->second;
778     double si = itN->first;
779     double sii = itNii->first;
780     double smid = .5*(si+sii);
781    
782     if (ni->get_lien_topologie_reference()->get_dimension() == 0)
783     {
784     MG_SOMMET * vi = (MG_SOMMET*)ni->get_lien_topologie_reference();
785     if (nii->IsInVertex(vi))
786     continue;
787     }
788    
789     if (nii->get_lien_topologie_reference()->get_dimension() == 0)
790     {
791     MG_SOMMET * vii = (MG_SOMMET*)nii->get_lien_topologie_reference();
792     if (ni->IsInVertex(vii))
793     continue;
794     }
795    
796     MG_ARETE * refEdge=0; double tMid; double dtMid;
797     polycurve->Parameter_SToRefEdgeT(smid,&refEdge,&tMid,&dtMid,false);
798     // and if the edge is periodic and tii-ti > period/2 then insert a node in the middle
799     {
800     if (refEdge->get_courbe()->est_periodique() != 0 )
801     {
802     MG_ARETE * refEdgei=0, * refEdgeii=0;
803     double tii, dtii, ti, dti;
804     polycurve->Parameter_SToRefEdgeT(si,&refEdgei,&ti,&dti,false);
805     polycurve->Parameter_SToRefEdgeT(sii,&refEdgeii,&tii,&dtii,false);
806    
807     if (fabs(tii-ti) > .5*refEdge->get_courbe()->get_periode())
808     {
809     double xyz[3];
810     refEdge->evaluer(tMid,xyz);
811     MCNode * newMCNode = new MCNode(__mcEdge, refEdge, tMid, xyz);
812     //newMCNode->incrementer();
813     refinedNodes[smid] = newMCNode;
814     refinedEdges[smid] = refEdge;
815     }
816     }
817     }
818     }
819     nodes = refinedNodes;
820     edges = refinedEdges;
821    
822     for (std::map<double, MCNode * >::iterator itN = nodes.begin();
823     itN != nodes.end();
824     itN++)
825     {
826     std::map<double, MCNode * >::iterator itNii = itN;
827     itNii++;
828     if (itNii == nodes.end())
829     break;
830     MCNode * ni = itN->second;
831     MCNode * nii = itNii->second;
832     double si = itN->first;
833    
834     MG_ARETE * refEdge=edges[si];
835    
836     // Refine the mc segment discretization with discretization error in faces < segment length / 1000
837     double deltaMax = get_longueur()*1E-2;
838 foucault 569 if (deltaMax < 1E-7)
839     deltaMax = 1E-7;
840 foucault 27 RefineInRefEdge(__mcEdge, refEdge, ni, nii, deltaMax, 1E300, refinedNodes, refinedEdges );
841     }
842     nodes=refinedNodes;
843     edges=refinedEdges;
844    
845    
846     // detect edges which contain nodes, and make segments of this edge on these nodes
847     for (std::map<double, MCNode * >::iterator itN = nodes.begin();
848     itN != nodes.end();
849     itN++)
850     {
851     std::map<double, MCNode * >::iterator itNii = itN;
852     itNii++;
853     if (itNii == nodes.end())
854     break;
855    
856     MCNode * ni = itN->second;
857     MCNode * nii = itNii->second;
858     double si = itN->first;
859     std::map<double, MG_ARETE*>::iterator itRefEdge = edges.find(si);
860     if (itRefEdge != edges.end())
861     edge = itRefEdge->second;
862     else
863     edge = 0;
864     if (ni->IsInEdge(edge) == false ||
865     nii->IsInEdge(edge) == false )
866     {
867     for (MCNode::EMapIterator itNiRefEdge = ni->GetRefEdgeMapping().begin();
868     itNiRefEdge != ni->GetRefEdgeMapping().end();
869     itNiRefEdge++)
870     {
871     edge = itNiRefEdge->first;
872     if ( nii->IsInEdge(edge) )
873     {
874     break;
875     }
876     }
877     }
878    
879     double params[2];
880     params[0]=itN->first;
881     params[1]=itNii->first;
882    
883     for (int i=0;i<2;i++)
884     if ((s[1]-params[i])*(s[0]-params[i])>0)
885     printf("pb\n");
886    
887     std::vector < MCNode * > segEdge;
888     segEdge.push_back (ni);
889     segEdge.push_back (nii);
890    
891     E.insert(std::make_pair(edge, segEdge));
892     // copy the curve in adjacent faces
893     for (int itF = 0; itF < edge->get_nb_mg_coarete(); itF++)
894     {
895     MG_FACE * face = edge->get_mg_coarete(itF)->get_boucle()->get_mg_face();
896     F.insert(std::make_pair(face, segEdge));
897     }
898    
899     if (CurveNodes.size () == 0 || CurveNodes[CurveNodes.size()-1] != ni)
900     CurveNodes.push_back(ni);
901     CurveNodes.push_back(nii);
902     CurveTopo.push_back(edge);
903     }
904    
905     if (_polylineEvaluator == NULL) _polylineEvaluator = new MCNodePolyline(liaison_topologique,CurveNodes,CurveTopo);
906     else
907     for (unsigned i=0;i<CurveNodes.size();i++)
908     _polylineEvaluator->Add(CurveNodes[i],CurveTopo[i]);
909    
910     return 1;
911     }
912    
913     MCFace * MCSegment::Find_MCFace(MCEdge * __mcEdge, MG_SOMMET * __refVertex1, MG_SOMMET * __refVertex2)
914     {
915     for (int itF = 0; itF != __mcEdge->get_nb_mg_coarete(); itF++)
916     {
917     MCFace * F = (MCFace*)__mcEdge->get_mg_coarete(itF)->get_boucle()->get_mg_face();
918     bool v1Found = false, v2Found = false;
919     for (int itFLoop = 0; itFLoop != F->get_nb_mg_boucle(); itFLoop ++)
920     {
921     MG_BOUCLE * loop = F->get_mg_boucle(itFLoop);
922     for (int itFLoopEdge = 0; itFLoopEdge != loop->get_nb_mg_coarete(); itFLoopEdge++)
923     {
924     MCEdge * mcEdge = (MCEdge *)loop->get_mg_coarete( itFLoopEdge )->get_arete();
925     if ( mcEdge->GetPolyCurve()->ContainsRefVertex(__refVertex1) )
926     v1Found = true;
927     if ( mcEdge->GetPolyCurve()->ContainsRefVertex(__refVertex2) )
928     v2Found = true;
929     if (v1Found && v2Found)
930     return F;
931     }
932     }
933     }
934     return NULL;
935     }
936    
937     int MCSegment::Construct_MergedVertices(MCNode * __mcNode)
938     {
939     if (get_lien_topologie()->get_dimension() != 1)
940     {
941     printf("Warning: MCSegment topology is not a MCEdge ! then it's not possible to construct a mapping on a merged vertex\n");
942     return 0;
943     }
944     MCEdge * mcEdge = (MCEdge*)get_lien_topologie();
945     MG_SOMMET * polycurveRefVertex = NULL;
946     MG_SOMMET * mcVertexRefVertex = (MG_SOMMET*)__mcNode->get_lien_topologie();
947     MCFace * mcFace;
948     for (std::set<MG_SOMMET*>::iterator itV = __mcNode->GetRefVertexMapping().begin();
949     itV != __mcNode->GetRefVertexMapping().end();
950     itV++ )
951     {
952     MG_SOMMET * v = *itV;
953     if (v != mcVertexRefVertex)
954     {
955     polycurveRefVertex = v;
956     mcFace = Find_MCFace(mcEdge, polycurveRefVertex, mcVertexRefVertex);
957     if (mcFace)
958     {
959     MCNode * polycurve_mcNode = NULL;
960     double v_xyz[3];
961     v->get_point()->evaluer(v_xyz);
962    
963     polycurve_mcNode = new MCNode (get_lien_topologie(), v, v_xyz[0],v_xyz[1],v_xyz[2]);
964    
965     polycurve_mcNode->incrementer();
966     if (polycurve_mcNode)
967     Construct_MCFaceByShortestPath(mcFace, __mcNode, polycurve_mcNode);
968    
969     break;
970     }
971     }
972     }
973    
974     return 1;
975     }
976    
977     BOITE_3D MCSegment::get_boite_3D(void)
978     {
979     return BOITE_3D(_bbox[0],_bbox[1],_bbox[2],_bbox[3],_bbox[4],_bbox[5]);
980     }
981    
982     void MCSegment::SetSaveFormat(char __format)
983     {
984     _saveFormat=__format;
985     if (__format == 2)
986     {
987     MG_ELEMENT_TOPOLOGIQUE * refTopo = 0;
988     switch (liaison_topologique->get_dimension())
989     {
990     case 1:
991     {
992     refTopo = ((MCEdge*)liaison_topologique)->GetPolyCurve()->GetRefEdge(0);
993     break;
994     }
995     case 2:
996     {
997     refTopo = ((MCFace*)liaison_topologique)->GetPolySurface()->GetRefFace(0);
998     break;
999     }
1000     }
1001     change_lien_topologie(refTopo);
1002     }
1003     }
1004    
1005 francois 763 void MCSegment::enregistrer(std::ostream& o,double version)
1006 foucault 27 {
1007     if (_saveFormat == 0) // Save as CAD4FE_MC_SEGMENT in magic file
1008     {
1009     if(liaison_topologique->get_dimension()==1) o << "%" << get_id() << "=CAD4FE_MCSEGMENT($"<< get_lien_topologie()->get_id() << ",$" << noeud1->get_id() << ",$" << noeud2->get_id() << ");" << std::endl;
1010     }
1011     else if (_saveFormat == 1) // Save as MG_SEGMENT in magic file
1012     {
1013 francois 763 MG_SEGMENT::enregistrer(o,version);
1014 foucault 27 }
1015     else if (_saveFormat == 2)
1016     {
1017 francois 763 MG_SEGMENT::enregistrer(o,version);
1018 foucault 27 }
1019     }
1020     int MCSegment::get_type_entite()
1021     {
1022     return IDMCSEGMENT;
1023     }
1024    
1025