ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCSegment.cpp
Revision: 1075
Committed: Tue Aug 10 17:02:54 2021 UTC (4 years ago) by francois
File size: 38557 byte(s)
Log Message:
suppression de warning avec le dernier compilateur

File Contents

# Content
1 //---------------------------------------------------------------------------
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 : %f < .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, int __iRecursiveCalls)
573 {
574 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 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 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 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 if (deltaMax < 1E-7)
839 deltaMax = 1E-7;
840 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 void MCSegment::enregistrer(std::ostream& o,double version)
1006 {
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 MG_SEGMENT::enregistrer(o,version);
1014 }
1015 else if (_saveFormat == 2)
1016 {
1017 MG_SEGMENT::enregistrer(o,version);
1018 }
1019 }
1020 int MCSegment::get_type_entite()
1021 {
1022 return IDMCSEGMENT;
1023 }
1024
1025