ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCSegment.cpp
Revision: 253
Committed: Tue Jul 13 19:40:46 2010 UTC (14 years, 10 months ago) by francois
File size: 38083 byte(s)
Log Message:
changement de hiearchie et utilisation de ccmake + mise a jour

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     #include "CAD4FE_geometric_tools.h"
23     #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     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 )
573     {
574     int insertedNodeCount = 0;
575     MCNode * n[2] = { __n1, __n2};
576     for (int i=0; i<2; i++)
577     {
578     MG_SOMMET * v = 0;
579     if (n[i]->get_lien_topologie_reference()->get_dimension() == 0)
580     v = (MG_SOMMET * ) n[i]->get_lien_topologie_reference();
581     if (v)
582     if (__mcEdge->GetPolyCurve()->Contains( v ) == false )
583     return 0;
584     if (n[i]->IsInEdge(__refEdge) == false)
585     return 0;
586     // nodes have merged ref vertices
587     if (n[(i+1)%2]->IsInVertex(v))
588     return 0;
589     }
590     __n1->incrementer();__n2->incrementer();
591     double t1 = __n1->T(__refEdge);
592     double t2 = __n2->T(__refEdge);
593     if (fabs(t2-t1) < 1E-6*(__refEdge->get_tmax()-__refEdge->get_tmin()))
594     return 0;
595    
596     double period = __refEdge->get_courbe()->get_periode();
597     if (period != 0.0 && fabs(t2 - t1) > .5*period)
598     if (t2<t1)
599     t2 += period;
600     else t1 += period;
601     double t3 = t1 + (t2-t1)*.5;
602     double s3;
603     double xyz[3]; __refEdge->evaluer(t3,xyz);
604     MCNode edgeNode (__mcEdge, __refEdge, t3, xyz);
605     for (int i=0; i<__refEdge->get_nb_mg_coarete(); i++)
606     {
607     MG_FACE * face = __refEdge->get_mg_coarete(i)->get_boucle()->get_mg_face();
608    
609     MCNodePolyline faceLine(liaison_topologique);
610     faceLine.Add(__n1,face);
611     faceLine.Add(__n2,face);
612     double L = faceLine.GetLength();
613     MCNode faceNode = faceLine.Evaluate(L*.5);
614     double distanceToEdge = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(faceNode.get_coord(),edgeNode.get_coord());
615     double ratioConvergence = distanceToEdge / __lastDistanceToEdge;
616     double distN1N2 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__n2->get_coord(),__n1->get_coord());
617     bool testConvergence = ( fabs(ratioConvergence - 1) < .001 || distN1N2 < __epsilon );
618     if ( (distanceToEdge > __epsilon )
619     && testConvergence == false )
620     {
621     insertedNodeCount++;
622     __mcEdge->GetPolyCurve()->Parameter_RefEdgeTToS ( t3, __refEdge, &s3, false);
623     if (__mcEdge->GetPolyCurve()->est_periodique()
624     && __mcEdge->get_tmin() > s3+1E-5*(__mcEdge->GetPolyCurve()->get_periode())
625     )
626     s3 += __mcEdge->GetPolyCurve()->get_periode();
627     MCNode * newMCNode = new MCNode ( edgeNode );
628     __mapMCEdgeNodesBySParameter.insert(std::make_pair(s3,newMCNode));
629     __mapMCEdgeRefEdgesBySParameter.insert(std::make_pair(s3, __refEdge));
630     newMCNode->incrementer();
631     insertedNodeCount += RefineInRefEdge(__mcEdge, __refEdge, __n1, newMCNode, __epsilon, distanceToEdge, __mapMCEdgeNodesBySParameter,__mapMCEdgeRefEdgesBySParameter);
632     insertedNodeCount += RefineInRefEdge(__mcEdge, __refEdge, newMCNode, __n2, __epsilon, distanceToEdge, __mapMCEdgeNodesBySParameter,__mapMCEdgeRefEdgesBySParameter);
633     newMCNode->decrementer();
634     break;
635     }
636     }
637     __n1->decrementer();__n2->decrementer();
638     return insertedNodeCount;
639     }
640    
641     int MCSegment::Construct_MCEdge(MCEdge * __mcEdge)
642     {
643     double s[2];
644     double t,dt;
645     int i,j;
646     unsigned iEdge;
647     MG_ARETE * edge;
648     PolyCurve * polycurve = __mcEdge->GetPolyCurve();
649     double period = polycurve->get_periode();
650     double smin = __mcEdge->get_tmin();
651     double smax = __mcEdge->get_tmax();
652    
653     VPts CurveNodes;
654     std::vector < MG_ELEMENT_TOPOLOGIQUE * > CurveTopo;
655    
656     MCNode * n[2];
657     n[0]=(MCNode *)get_noeud1();
658     n[1]=(MCNode *)get_noeud2();
659    
660     std::map < double , MCNode * > nodes;
661     std::map < double , MG_ARETE * > edges;
662    
663     // get the parameter of extremities n1 n2 of the segment
664     for (i=0; i<2; i++)
665     {
666     if (n[i]->GetRefVertexMapping().size() >= 1) // MC node is on a ref vertex
667     {
668     MG_SOMMET * refVertex = (MG_SOMMET*)n[i]->get_lien_topologie_reference();
669     if (polycurve->ContainsRefVertex(refVertex) == false)
670     {
671     for (std::set<MG_SOMMET*>::iterator itV = n[i]->GetRefVertexMapping().begin();
672     itV != n[i]->GetRefVertexMapping().end();
673     itV++)
674     {
675     MG_SOMMET * v = *itV;
676     if (polycurve->ContainsRefVertex(v))
677     {
678     s[i] = polycurve->RefVertex_GetS(v);
679     if (n[i]->get_lien_topologie_reference() != v)
680     {
681     double xyzV[3]; v->get_point()->evaluer(xyzV);
682     n[i] = new MCNode (__mcEdge,v,xyzV[0],xyzV[1],xyzV[2]);
683     //n[i]->incrementer();
684     }
685     break;
686     }
687     }
688     }
689     else
690     {
691     s[i] = polycurve->RefVertex_GetS(refVertex);
692     }
693     }
694     else if (n[i]->GetRefEdgeMapping().size() == 1) // MC node is in a ref edge
695     {
696     polycurve->inverser(s[i], n[i]->get_coord(), 1E-6);
697     }
698     }
699    
700     if (period != 0.0)
701     {
702     for (i=0;i<2;i++){
703     if (s[i] > smax + fabs(smax-smin)*1E-6)
704     s[i] -= period;
705     if (s[i] < smin - fabs(smax-smin)*1E-6)
706     s[i] += period; }
707     }
708    
709     if (period != 0.0 && fabs(s[1] - s[0]) > .5*period)
710     if (s[1]<s[0])
711     s[1] += period;
712     else s[1] += period;
713    
714     for (i=0; i<2; i++)
715     {
716     nodes[s[i]] = n[i];
717     }
718    
719     {
720     MG_ARETE * edge; double t,dt;
721     double si = std::min(s[0],s[1]);
722     polycurve->Parameter_SToRefEdgeT ( si+1E-6*fabs(s[1]-s[0]), &edge,&t,&dt,false);
723     edges [ si ] = edge;
724     }
725    
726    
727     for (int i=0; i<2; i++)
728     {
729     OT_VECTEUR_3D v, v_node(n[i]->get_coord());
730     polycurve->evaluer(s[i], v);
731     double dist = (v_node-v).get_longueur();
732     if (dist > .001*__mcEdge->GetPolyCurve()->get_longueur())
733     {
734     printf("Distance between projection and node = %f\n", dist);
735     polycurve->inverser(s[i], n[i]->get_coord(), 1E-6);
736     polycurve->evaluer(s[i], v);
737     }
738     }
739    
740     // Create nodes in vertices between n1 and n2
741     double si=0;
742     for (i=0;si<std::max(s[1],s[0]);i++)
743     {
744     int iEdge = i%polycurve->GetRefEdgeCount();
745     int iVertex = (period != 0.0)? i%(polycurve->GetRefVertexCount()-1): i%polycurve->GetRefVertexCount();
746     if ((si-s[0])*(s[1]-si) > 0)
747     {
748     MG_SOMMET * vertex = polycurve->GetRefVertex(iVertex);
749     double xyz[3];vertex->get_point()->evaluer(xyz);
750     MCNode * ni = new MCNode ( __mcEdge, vertex, xyz[0], xyz[1], xyz[2] );
751     nodes [ si ] = ni;
752     edges [ si ] = polycurve->GetRefEdge(iEdge);
753     //ni->incrementer();
754     }
755     si += polycurve->GetLength(iEdge);
756     }
757    
758     std::map < double , MCNode * > refinedNodes = nodes;
759     std::map < double , MG_ARETE * > refinedEdges = edges;
760    
761     for (std::map<double, MCNode * >::iterator itN = nodes.begin();
762     itN != nodes.end();
763     itN++)
764     {
765     std::map<double, MCNode * >::iterator itNii = itN;
766     itNii++;
767     if (itNii == nodes.end())
768     break;
769     MCNode * ni = itN->second;
770     MCNode * nii = itNii->second;
771     double si = itN->first;
772     double sii = itNii->first;
773     double smid = .5*(si+sii);
774    
775     if (ni->get_lien_topologie_reference()->get_dimension() == 0)
776     {
777     MG_SOMMET * vi = (MG_SOMMET*)ni->get_lien_topologie_reference();
778     if (nii->IsInVertex(vi))
779     continue;
780     }
781    
782     if (nii->get_lien_topologie_reference()->get_dimension() == 0)
783     {
784     MG_SOMMET * vii = (MG_SOMMET*)nii->get_lien_topologie_reference();
785     if (ni->IsInVertex(vii))
786     continue;
787     }
788    
789     MG_ARETE * refEdge=0; double tMid; double dtMid;
790     polycurve->Parameter_SToRefEdgeT(smid,&refEdge,&tMid,&dtMid,false);
791     // and if the edge is periodic and tii-ti > period/2 then insert a node in the middle
792     {
793     if (refEdge->get_courbe()->est_periodique() != 0 )
794     {
795     MG_ARETE * refEdgei=0, * refEdgeii=0;
796     double tii, dtii, ti, dti;
797     polycurve->Parameter_SToRefEdgeT(si,&refEdgei,&ti,&dti,false);
798     polycurve->Parameter_SToRefEdgeT(sii,&refEdgeii,&tii,&dtii,false);
799    
800     if (fabs(tii-ti) > .5*refEdge->get_courbe()->get_periode())
801     {
802     double xyz[3];
803     refEdge->evaluer(tMid,xyz);
804     MCNode * newMCNode = new MCNode(__mcEdge, refEdge, tMid, xyz);
805     //newMCNode->incrementer();
806     refinedNodes[smid] = newMCNode;
807     refinedEdges[smid] = refEdge;
808     }
809     }
810     }
811     }
812     nodes = refinedNodes;
813     edges = refinedEdges;
814    
815     for (std::map<double, MCNode * >::iterator itN = nodes.begin();
816     itN != nodes.end();
817     itN++)
818     {
819     std::map<double, MCNode * >::iterator itNii = itN;
820     itNii++;
821     if (itNii == nodes.end())
822     break;
823     MCNode * ni = itN->second;
824     MCNode * nii = itNii->second;
825     double si = itN->first;
826    
827     MG_ARETE * refEdge=edges[si];
828    
829     // Refine the mc segment discretization with discretization error in faces < segment length / 1000
830     double deltaMax = get_longueur()*1E-2;
831     RefineInRefEdge(__mcEdge, refEdge, ni, nii, deltaMax, 1E300, refinedNodes, refinedEdges );
832     }
833     nodes=refinedNodes;
834     edges=refinedEdges;
835    
836    
837     // detect edges which contain nodes, and make segments of this edge on these nodes
838     for (std::map<double, MCNode * >::iterator itN = nodes.begin();
839     itN != nodes.end();
840     itN++)
841     {
842     std::map<double, MCNode * >::iterator itNii = itN;
843     itNii++;
844     if (itNii == nodes.end())
845     break;
846    
847     MCNode * ni = itN->second;
848     MCNode * nii = itNii->second;
849     double si = itN->first;
850     std::map<double, MG_ARETE*>::iterator itRefEdge = edges.find(si);
851     if (itRefEdge != edges.end())
852     edge = itRefEdge->second;
853     else
854     edge = 0;
855     if (ni->IsInEdge(edge) == false ||
856     nii->IsInEdge(edge) == false )
857     {
858     for (MCNode::EMapIterator itNiRefEdge = ni->GetRefEdgeMapping().begin();
859     itNiRefEdge != ni->GetRefEdgeMapping().end();
860     itNiRefEdge++)
861     {
862     edge = itNiRefEdge->first;
863     if ( nii->IsInEdge(edge) )
864     {
865     break;
866     }
867     }
868     }
869    
870     double params[2];
871     params[0]=itN->first;
872     params[1]=itNii->first;
873    
874     for (int i=0;i<2;i++)
875     if ((s[1]-params[i])*(s[0]-params[i])>0)
876     printf("pb\n");
877    
878     std::vector < MCNode * > segEdge;
879     segEdge.push_back (ni);
880     segEdge.push_back (nii);
881    
882     E.insert(std::make_pair(edge, segEdge));
883     // copy the curve in adjacent faces
884     for (int itF = 0; itF < edge->get_nb_mg_coarete(); itF++)
885     {
886     MG_FACE * face = edge->get_mg_coarete(itF)->get_boucle()->get_mg_face();
887     F.insert(std::make_pair(face, segEdge));
888     }
889    
890     if (CurveNodes.size () == 0 || CurveNodes[CurveNodes.size()-1] != ni)
891     CurveNodes.push_back(ni);
892     CurveNodes.push_back(nii);
893     CurveTopo.push_back(edge);
894     }
895    
896     if (_polylineEvaluator == NULL) _polylineEvaluator = new MCNodePolyline(liaison_topologique,CurveNodes,CurveTopo);
897     else
898     for (unsigned i=0;i<CurveNodes.size();i++)
899     _polylineEvaluator->Add(CurveNodes[i],CurveTopo[i]);
900    
901     return 1;
902     }
903    
904     MCFace * MCSegment::Find_MCFace(MCEdge * __mcEdge, MG_SOMMET * __refVertex1, MG_SOMMET * __refVertex2)
905     {
906     for (int itF = 0; itF != __mcEdge->get_nb_mg_coarete(); itF++)
907     {
908     MCFace * F = (MCFace*)__mcEdge->get_mg_coarete(itF)->get_boucle()->get_mg_face();
909     bool v1Found = false, v2Found = false;
910     for (int itFLoop = 0; itFLoop != F->get_nb_mg_boucle(); itFLoop ++)
911     {
912     MG_BOUCLE * loop = F->get_mg_boucle(itFLoop);
913     for (int itFLoopEdge = 0; itFLoopEdge != loop->get_nb_mg_coarete(); itFLoopEdge++)
914     {
915     MCEdge * mcEdge = (MCEdge *)loop->get_mg_coarete( itFLoopEdge )->get_arete();
916     if ( mcEdge->GetPolyCurve()->ContainsRefVertex(__refVertex1) )
917     v1Found = true;
918     if ( mcEdge->GetPolyCurve()->ContainsRefVertex(__refVertex2) )
919     v2Found = true;
920     if (v1Found && v2Found)
921     return F;
922     }
923     }
924     }
925     return NULL;
926     }
927    
928     int MCSegment::Construct_MergedVertices(MCNode * __mcNode)
929     {
930     if (get_lien_topologie()->get_dimension() != 1)
931     {
932     printf("Warning: MCSegment topology is not a MCEdge ! then it's not possible to construct a mapping on a merged vertex\n");
933     return 0;
934     }
935     MCEdge * mcEdge = (MCEdge*)get_lien_topologie();
936     MG_SOMMET * polycurveRefVertex = NULL;
937     MG_SOMMET * mcVertexRefVertex = (MG_SOMMET*)__mcNode->get_lien_topologie();
938     MCFace * mcFace;
939     for (std::set<MG_SOMMET*>::iterator itV = __mcNode->GetRefVertexMapping().begin();
940     itV != __mcNode->GetRefVertexMapping().end();
941     itV++ )
942     {
943     MG_SOMMET * v = *itV;
944     if (v != mcVertexRefVertex)
945     {
946     polycurveRefVertex = v;
947     mcFace = Find_MCFace(mcEdge, polycurveRefVertex, mcVertexRefVertex);
948     if (mcFace)
949     {
950     MCNode * polycurve_mcNode = NULL;
951     double v_xyz[3];
952     v->get_point()->evaluer(v_xyz);
953    
954     polycurve_mcNode = new MCNode (get_lien_topologie(), v, v_xyz[0],v_xyz[1],v_xyz[2]);
955    
956     polycurve_mcNode->incrementer();
957     if (polycurve_mcNode)
958     Construct_MCFaceByShortestPath(mcFace, __mcNode, polycurve_mcNode);
959    
960     break;
961     }
962     }
963     }
964    
965     return 1;
966     }
967    
968     BOITE_3D MCSegment::get_boite_3D(void)
969     {
970     return BOITE_3D(_bbox[0],_bbox[1],_bbox[2],_bbox[3],_bbox[4],_bbox[5]);
971     }
972    
973     void MCSegment::SetSaveFormat(char __format)
974     {
975     _saveFormat=__format;
976     if (__format == 2)
977     {
978     MG_ELEMENT_TOPOLOGIQUE * refTopo = 0;
979     switch (liaison_topologique->get_dimension())
980     {
981     case 1:
982     {
983     refTopo = ((MCEdge*)liaison_topologique)->GetPolyCurve()->GetRefEdge(0);
984     break;
985     }
986     case 2:
987     {
988     refTopo = ((MCFace*)liaison_topologique)->GetPolySurface()->GetRefFace(0);
989     break;
990     }
991     }
992     change_lien_topologie(refTopo);
993     }
994     }
995    
996     void MCSegment::enregistrer(std::ostream& o)
997     {
998     if (_saveFormat == 0) // Save as CAD4FE_MC_SEGMENT in magic file
999     {
1000     if(liaison_topologique->get_dimension()==1) o << "%" << get_id() << "=CAD4FE_MCSEGMENT($"<< get_lien_topologie()->get_id() << ",$" << noeud1->get_id() << ",$" << noeud2->get_id() << ");" << std::endl;
1001     }
1002     else if (_saveFormat == 1) // Save as MG_SEGMENT in magic file
1003     {
1004     MG_SEGMENT::enregistrer(o);
1005     }
1006     else if (_saveFormat == 2)
1007     {
1008     MG_SEGMENT::enregistrer(o);
1009     }
1010     }
1011     int MCSegment::get_type_entite()
1012     {
1013     return IDMCSEGMENT;
1014     }
1015    
1016