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

File Contents

# Content
1 //---------------------------------------------------------------------------
2
3 #include <sstream>
4 #include <fstream>
5 #pragma hdrstop
6
7 //---------------------------------------------------------------------------
8 // include MAGIC Headers
9 #include "gestionversion.h"
10 #include <mg_geometrie.h>
11 #include <mg_maillage.h>
12 #include <mg_maillage_outils.h>
13 #include <mg_gestionnaire.h>
14 #include <mailleur0d.h>
15 #include <mailleur1d.h>
16 #include <mailleur2d.h>
17 #include <fct_generateur_3d.h>
18 #include <fct_generateur_fichier.h>
19 #include <fct_generateur_constante.h>
20 #include <fct_taille.h>
21 #include <ot_algorithme_geometrique.h>
22
23 #include "CAD4FE_MCBody.h"
24 #include "CAD4FE_Geometric_Tools.h"
25 #include "CAD4FE_PolyCurve.h"
26 #include "CAD4FE_PolySurface.h"
27 #include "CAD4FE_MCFace.h"
28 #include "CAD4FE_MCEdge.h"
29 #include "CAD4FE_MCVertex.h"
30 #include "CAD4FE_GlobalEdgeCriteria.h"
31 #include "CAD4FE_LoopCriteria.h"
32 #include "CAD4FE_LocalEdgeCriteria.h"
33 #include "CAD4FE_EdgeCollapseCriteria.h"
34 #include "CAD4FE_VertexCriteria.h"
35 #include "CAD4FE_mg_utils.h"
36 #include "CAD4FE_InventorText_MCAA.h"
37 #include "CAD4FE_InventorText_MG_MAILLAGE.h"
38 #include "CAD4FE_Intersection_Plane_MG_MAILLAGE.h"
39 #include "CAD4FE_Intersection_Plane_MG_SEGMENT.h"
40 #include "CAD4FE_ColorMap.h"
41 #include "CAD4FE_Criteria.h"
42 #include "CAD4FE_ShortestPathByClosestPointOnEdge.h"
43 #include "CAD4FE_MCNode.h"
44
45 #include "CAD4FE_MCAA.h"
46 //---------------------------------------------------------------------------
47 #pragma package(smart_init)
48
49
50 using namespace CAD4FE;
51
52 MCAA::MCAA(MG_VOLUME * __refBody, MG_MAILLAGE * __tessellation, MG_GESTIONNAIRE * __gest, MG_GEOMETRIE * __geom)
53 : _refBody(__refBody), _refTess(__tessellation), _refGest(__gest), _geom(__geom), _sizeMap(NULL), _mcTessSegGrid(NULL), _feMesh(NULL)
54 {
55
56 _mcBody = new MCBody(_geom, __refBody);
57
58 std::ofstream file;
59 char filename [5000]="";
60 strcat (filename, getenv("TEMP"));
61 strcat (filename, "\\RefTessellation.iv");
62 file.open(filename);
63 file<<InventorText_MG_MAILLAGE(__tessellation).GetText();
64 file<<"}";
65 file.close();
66
67 _InitializeMCBodyTessellation();
68
69 // Setting default meshing parameters :
70 _maxOverdensity = 2;
71 _limitAngle = Criteria::PlanarCurve_BetaEpsilon(.22);
72 SetMinMCEdgeCount(0);
73 SetMinMCVertexCount(1);
74
75 // set the time variable, representing the
76 // simplification step number to zero
77 time = 0;
78
79 _nbA=0; // edge deletion
80 _nbB=0; // vertex deletion
81 _nbC=0; // edge collapse
82 _nbD=0; // constricted section
83 _nbE=0; // loops
84
85 //_mcBody->G2ToNeatoFile(_mcBody->G10(), "c:\\gilles\\g10.neato", "c:\\gilles\\g10.neato");
86
87 /*
88 // Try to do a 2D mesh
89 //_DebugTraditionnalMesh();
90 if (__sizeMap != 0)
91 _sizeMap = __sizeMap;
92 else
93 UseDefaultMeshSize();
94 */
95 }
96 //---------------------------------------------------------------------------
97 void
98 MCAA::Update()
99 {
100 // Initialize the mesh size
101 InitializeFEMesh();
102
103 // Initialize the MC Tessellation Segments Grid
104 _InitializeMCTessSegGrid();
105
106 // Initialize Edge local properties
107 EC_Init();
108
109 // Initialize Vertex properties
110 VC_Init();
111 }
112 //---------------------------------------------------------------------------
113
114 MCAA::~MCAA()
115 {
116 delete _mcTessSegGrid;
117 for (ECMapIterator it_ec = _ecMap.begin();
118 it_ec != _ecMap.end();
119 it_ec++)
120 {
121 GlobalEdgeCriteria * gec = it_ec->second;
122 delete gec;
123 }
124 for (VCMapIterator it_vc = _vcMap.begin();
125 it_vc != _vcMap.end();
126 it_vc++)
127 {
128 VertexCriteria * vc = it_vc->second;
129 delete vc;
130 }
131 delete _mcBody;
132 }
133
134 //---------------------------------------------------------------------------
135 // Input Meshing criteria
136 // Limit deviation angle
137 double MCAA::GetLimitAngle()
138 {
139 return _limitAngle;
140 }
141 //---------------------------------------------------------------------------
142 void MCAA::SetLimitAngle(double __limitAngle)
143 {
144 _limitAngle = __limitAngle;
145 }
146 //---------------------------------------------------------------------------
147 int MCAA::GetMinMCEdgeCount()
148 {
149 return _minMCEdgeCount;
150 }
151 //---------------------------------------------------------------------------
152 void MCAA::SetMinMCEdgeCount(int __minMCEdgeCount)
153 {
154 _minMCEdgeCount = __minMCEdgeCount;
155 }
156 //---------------------------------------------------------------------------
157 int MCAA::GetMinMCVertexCount()
158 {
159 return _minMCVertexCount;
160 }
161 //---------------------------------------------------------------------------
162 void MCAA::SetMinMCVertexCount(int __minMCVertexCount)
163 {
164 _minMCVertexCount=__minMCVertexCount;
165 }
166 // Input Meshing criteria
167 // Relative Sag
168 void MCAA::SetRelativeSag(double __relativeSag )
169 {
170 _relativeSag = __relativeSag;
171
172 // Browse the edge criterions
173 // Set the relative sag on each edge suppression criterion
174 ECMapCIterator it_ec;
175 for (it_ec = _ecMap.begin();
176 it_ec != _ecMap.end() ;
177 it_ec++ )
178 {
179 // update local edge criteria
180 // while keeping the normal offset polyline
181 it_ec->second->Update(false);
182 }
183
184
185 // Set the relative sag on each vertex suppression criterion
186 VCMapIterator itV;
187 for (itV = _vcMap.begin(); itV != _vcMap.end(); itV++)
188 {
189 // update local edge criteria
190 // while keeping the normal offset polyline
191 it_ec->second->Update(false);
192 }
193 }
194 //---------------------------------------------------------------------------
195 double MCAA::GetRelativeSag()
196 {
197 return _relativeSag;
198 }
199 //---------------------------------------------------------------------------
200 // Overdensity factor
201 void MCAA::SetMaxOverdensity(double __maxOverdensity)
202 {
203 _maxOverdensity = __maxOverdensity;
204 ECMapCIterator it_ec;
205 for (it_ec = _ecMap.begin();
206 it_ec != _ecMap.end() ;
207 it_ec++ )
208 {
209 // update local edge criteria
210 // while keeping the normal offset polyline
211 it_ec->second->Update(false);
212 }
213
214 VCMapIterator itV;
215 for (itV = _vcMap.begin(); itV != _vcMap.end(); itV++)
216 {
217 // update local edge criteria
218 // while keeping the normal offset polyline
219 it_ec->second->Update(false);
220 }
221 }
222 double MCAA::GetMaxOverdensity()
223 {
224 return _maxOverdensity;
225 }
226 //---------------------------------------------------------------------------
227 bool MCAA::CheckIfMeshIsReferencedInTopo(MG_ELEMENT_MAILLAGE * __elem)
228 {
229 if ( __elem->get_dimension() == 1 && __elem->get_lien_topologie()->get_dimension() == 2 )
230 {
231 MG_FACE * face = (MG_FACE*)__elem->get_lien_topologie();
232 MG_SEGMENT* seg = (MG_SEGMENT*) __elem;
233 return CheckIfMeshIsReferencedInTopo(seg, face);
234 }
235
236 if ( ! __elem->get_lien_topologie()->get_lien_maillage()->contient(__elem) )
237 {
238 printf("Mesh element ID \"%ld\" is not referenced in the topology ! ", __elem->get_id());
239 return false;
240 }
241 else
242 return true;
243 }
244 //---------------------------------------------------------------------------
245 bool MCAA::CheckIfMeshIsReferencedInTopo(MG_SEGMENT * __seg, MG_FACE * __face)
246 {
247 int i;
248 for (i=0; i<__seg->get_lien_triangle()->get_nb(); i++)
249 {
250 MG_TRIANGLE * triang = __seg->get_lien_triangle()->get(i);
251
252 if ( ! CheckIfMeshIsReferencedInTopo(triang) )
253 return false;
254
255 }
256
257 return true;
258 }
259 //---------------------------------------------------------------------------
260 bool MCAA::CheckIfTopoExists(MG_ELEMENT_TOPOLOGIQUE * topo)
261 {
262 if (topo)
263 {
264 switch (topo->get_dimension())
265 {
266 case 0:
267 {
268 MCVertex * mctopo = _mcBody->GetMCVertex(topo->get_id());
269
270
271 if (mctopo != topo)
272 {
273 printf("MC Vertex %ld does not exist !\n", topo->get_id());
274 return false;
275 }
276 else
277 return true;
278
279
280
281 }
282 case 1:
283 {
284 MCEdge * mctopo = _mcBody->GetMCEdge(topo->get_id());
285 MCEdge * topo2 = (MCEdge*) _geom->get_mg_areteid(topo->get_id());
286
287 if (mctopo != topo || topo2 != topo)
288 {
289 printf("MC Edge %ld does not exist !\n", topo->get_id());
290 return false;
291 }
292 else
293 return true;
294 }
295 case 2:
296 {
297 MCFace * mctopo = _mcBody->GetMCFace(topo->get_id());
298
299 if (mctopo != topo)
300 {
301 printf("MC Face %ld does not exist !\n", topo->get_id());
302 return false;
303 }
304 else
305 return true;
306 }
307 default:
308 printf("The topological link claims a dimension \"%d\" > 2 or < 0 !\n", topo->get_dimension());
309 }
310 }
311 else
312 {
313 printf("Topo = NULL\n");
314 return false;
315 }
316 return false;
317 }
318 //---------------------------------------------------------------------------
319
320 void MCAA::CheckMCMesh(MG_MAILLAGE * __mesh, std::set<MG_SEGMENT*> & __setSegmentBadTopology, std::set<MG_NOEUD*> & __setNodeBadTopology )
321 {
322 LISTE_MG_TRIANGLE::iterator it_triang;
323 for (MG_TRIANGLE* triang = __mesh->get_premier_triangle(it_triang);
324 triang; triang =__mesh->get_suivant_triangle(it_triang))
325 {
326 MG_ELEMENT_TOPOLOGIQUE * topo = triang->get_lien_topologie();
327 CheckIfTopoExists(topo);
328 CheckIfMeshIsReferencedInTopo(triang);
329 }
330
331 LISTE_MG_SEGMENT::iterator it_seg;
332 for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
333 seg; seg =__mesh->get_suivant_segment(it_seg))
334 {
335 MG_ELEMENT_TOPOLOGIQUE * topo = seg->get_lien_topologie();
336 if (!CheckIfTopoExists(topo) || !CheckIfMeshIsReferencedInTopo(seg))
337 __setSegmentBadTopology.insert(seg);
338 }
339
340 LISTE_MG_NOEUD::iterator it_no;
341 for (MG_NOEUD* no = __mesh->get_premier_noeud(it_no);
342 no; no =__mesh->get_suivant_noeud(it_no))
343 {
344 MG_ELEMENT_TOPOLOGIQUE * topo = no->get_lien_topologie();
345 if (!CheckIfTopoExists(topo))
346 __setNodeBadTopology.insert(no);
347 }
348
349 {MCBODY_FOR_EACH_MCFACE(_mcBody,face)
350 {
351 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage = face->get_lien_maillage();
352
353 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
354 MG_ELEMENT_MAILLAGE* element;
355 int nb = lien_maillage->get_nb();
356 int i=0;
357 for (element = lien_maillage->get_premier(it); i++ < nb && element ; element = lien_maillage->get_suivant(it) )
358 {
359 if (face != element->get_lien_topologie())
360 printf("face %ld : element id %ld NOT ok\n", face->get_id(), element->get_id());
361 }
362 }
363 }
364 {MCBODY_FOR_EACH_MCEDGE(_mcBody,edge)
365 {
366 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage = edge->get_lien_maillage();
367
368 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
369 MG_ELEMENT_MAILLAGE* element;
370 int nb = lien_maillage->get_nb();
371 int i=0;
372 for (element = lien_maillage->get_premier(it); i++ < nb && element ; element = lien_maillage->get_suivant(it) )
373 {
374 if (edge != element->get_lien_topologie())
375 {
376 printf("edge %ld : element id %ld NOT ok\n", edge->get_id(), element->get_id());
377 }
378 }
379
380
381 int nbOfNodesDim0 = 0;
382 i=0;
383 for (element = lien_maillage->get_premier(it); i++ < nb && element ; element = lien_maillage->get_suivant(it) )
384 {
385 if ( ! __mesh->contient(element) ) continue;
386 MG_SEGMENT * seg = (MG_SEGMENT *) element;
387 MG_NOEUD * V[2];
388 V[0] = seg->get_noeud1();
389 V[1] = seg->get_noeud2();
390 for (int i=0; i<2; i++)
391 {
392 if ( V[i]->get_lien_topologie() && V[i]->get_lien_topologie()->get_dimension() == 0)
393 nbOfNodesDim0++;
394 }
395 }
396 if (nbOfNodesDim0 != 2)
397 printf("Edge %ld Problem : there has %d nodes having a vertex attached!\n", edge->get_id(), nbOfNodesDim0);
398
399 }
400 }
401 {MCBODY_FOR_EACH_MCVERTEX(_mcBody,vertex)
402 {
403 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage = vertex->get_lien_maillage();
404
405 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it;
406 MG_ELEMENT_MAILLAGE* element;
407 int nb = lien_maillage->get_nb();
408 int i=0;
409 for (element = lien_maillage->get_premier(it); i++ < nb && element ; element = lien_maillage->get_suivant(it) )
410 {
411 if (vertex != element->get_lien_topologie())
412 printf("vertex %ld : element id %ld NOT ok\n", vertex->get_id(), element->get_id());
413 }
414 }
415 }
416 }
417
418 //---------------------------------------------------------------------------
419 void MCAA::MergeVertices(MCVertex * __deleteVertex, MCVertex * __targetVertex)
420 {
421 MCVertex * V1 = __deleteVertex;
422 MCVertex * V2 = __targetVertex;
423 std::set<MCEdge*>edges;
424 _mcBody->MergeVertices(V1,V2,edges);
425
426 std::set<MCEdge*>::iterator itEdge;
427 for (itEdge = edges.begin(); itEdge != edges.end(); itEdge++)
428 {
429 EC_Delete(*itEdge);
430 DeleteFEMesh(*itEdge);
431 }
432 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = V1->get_lien_maillage();
433 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
434 MG_ELEMENT_MAILLAGE* element2;
435 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
436 element2->change_lien_topologie(NULL);
437
438 int N=V1->get_nb_mg_cosommet();
439 for (int i=0; i<N; i++)
440 _geom->supprimer_mg_cosommet(V1->get_mg_cosommet(0));
441 _mcBody->DeleteMCVertex(V1);
442 VC_Delete(V1);
443
444 for (itEdge = edges.begin(); itEdge != edges.end(); itEdge++)
445 InitializeFEMesh(*itEdge);
446
447 for (itEdge = edges.begin(); itEdge != edges.end(); itEdge++)
448 EC_Init(*itEdge);
449 }
450 //---------------------------------------------------------------------------
451 void
452 MCAA::_InitializeMCBodyTessellation()
453 {
454 // Duplicate the reference geometry's mesh !
455 _mcTess = _refTess->dupliquer ( _refGest );
456
457 long id_ref_to_mc = _mcTess->get_id() - _refTess->get_id();
458
459 // update the link of tessellation entities of the MC Body Tessellation
460 {
461 MCBODY_FOR_EACH_MCFACE(_mcBody, mcFace)
462 {
463 const std::set<MG_FACE *> & lst_ref_faces = mcFace->GetPolySurface()->GetRefFaces();
464 for (std::set<MG_FACE *>::const_iterator it_ref_face = lst_ref_faces.begin();
465 it_ref_face != lst_ref_faces.end();
466 it_ref_face ++ )
467 {
468 MG_FACE * refFace = *it_ref_face;
469
470 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = refFace->get_lien_maillage();
471 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
472 MG_ELEMENT_MAILLAGE* element2;
473 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
474 {
475 if (_refTess->contient(element2))
476 {
477 MG_TRIANGLE * ref_triang = (MG_TRIANGLE *) element2;
478 MG_TRIANGLE * mc_triang = _mcTess->get_mg_triangleid ( ref_triang->get_id() + id_ref_to_mc );
479
480 mc_triang->change_lien_topologie ( mcFace );
481
482 MG_SEGMENT * segs[3];
483 MG_NOEUD * nos[3];
484 MG_TRIANGLE_GET_SEGMENTS(mc_triang,segs);
485 MG_TRIANGLE_GET_NOEUDS(mc_triang,nos);
486 for (int i=0;i<3;i++)
487 {
488 if (!segs[i]->get_lien_topologie() || segs[i]->get_lien_topologie()->get_dimension() == 2)
489 segs[i]->change_lien_topologie2(mcFace);//change_lien_topologie_mct(segs[i],mapRefToMCFace,mapRefToMCEdge,mapRefToMCVertex);
490 if (! nos[i]->get_lien_topologie() || nos[i]->get_lien_topologie()->get_dimension() == 2)
491 nos[i]->change_lien_topologie2(mcFace);//change_lien_topologie_mct(nos[i],mapRefToMCFace,mapRefToMCEdge,mapRefToMCVertex);
492 }
493 }
494
495 }
496 }
497 }}
498
499 {
500 MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
501 {
502 const std::vector<MG_ARETE *> & lst_ref_edges = edge->GetPolyCurve()->GetRefEdges();
503 for (std::vector<MG_ARETE *>::const_iterator it_ref_edge = lst_ref_edges.begin();
504 it_ref_edge != lst_ref_edges.end();
505 it_ref_edge ++ )
506 {
507 MG_ARETE * ref_edge = *it_ref_edge;
508
509 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = ref_edge->get_lien_maillage();
510 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
511 MG_ELEMENT_MAILLAGE* element2;
512 int counter = 0;
513 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
514 {
515 if (_refTess->contient(element2))
516 {
517 MG_SEGMENT * ref_seg = (MG_SEGMENT *) element2;
518
519 if ( ! ref_seg ) continue;
520
521 MG_SEGMENT * mc_seg = _mcTess->get_mg_segmentid ( ref_seg->get_id() + id_ref_to_mc );
522 mc_seg->change_lien_topologie( edge );
523
524 MG_NOEUD * nos[2];
525 nos[0] = mc_seg->get_noeud1();
526 nos[1] = mc_seg->get_noeud2();
527 for (int i=0;i<2;i++)
528 if (! nos[i]->get_lien_topologie() || nos[i]->get_lien_topologie()->get_dimension() > 0)
529 nos[i]->change_lien_topologie2(edge);
530
531 counter++;
532 }
533 }
534 if (counter == 0)
535 printf("warning : no segments are connected to ref edge id=(%ld,%s) !\n",edge->get_id(),edge->get_idoriginal().c_str());
536 }
537 }
538 }
539
540 {MCBODY_FOR_EACH_MCVERTEX(_mcBody, mc_vertex)
541 {
542 MG_SOMMET * ref_vertex = mc_vertex->GetRefVertex();
543
544 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = ref_vertex->get_lien_maillage();
545 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
546 MG_ELEMENT_MAILLAGE* element2;
547 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
548 {
549 if (_refTess->contient(element2))
550 {
551 MG_NOEUD * ref_node = (MG_NOEUD*) element2;
552 MG_NOEUD * mc_node = _mcTess->get_mg_noeudid ( ref_node->get_id() + id_ref_to_mc );
553
554 mc_node->change_lien_topologie(mc_vertex);
555 break;
556 }
557 }
558 }}
559
560 MG_UTILS::MG_MAILLAGE_GetBoundingBox(_mcTess, _bbox);
561 }
562
563 //---------------------------------------------------------------------------
564 void
565 MCAA::_InitializeMCTessSegGrid()
566 {
567 if (_mcTessSegGrid)
568 delete _mcTessSegGrid;
569
570 _mcTessSegGrid = new TPL_GRILLE < MG_SEGMENT * >;
571
572 int nb_steps[3];
573 for (unsigned i = 0; i < 3; i++)
574 {
575 double cellSize = GetSize(_bbox);
576
577 if ( cellSize != 0 )
578 nb_steps[i] = std::min(floor((_bbox[i+3]-_bbox[i])/cellSize),40.0);
579 else
580 nb_steps[i] = 40;
581
582 if (nb_steps[i] == 0)
583 nb_steps[i] ++;
584 }
585 MG_UTILS utils;
586 utils.TPL_GRILLE_Construct<MG_SEGMENT*>(_bbox, nb_steps, *_mcTessSegGrid);
587
588 {
589 MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
590 {
591
592 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = edge->get_lien_maillage();
593 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
594 MG_ELEMENT_MAILLAGE* element2;
595 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
596 {
597 MG_SEGMENT * mc_seg = (MG_SEGMENT *)element2;
598
599 if (_mcTess->contient(mc_seg) )
600 _mcTessSegGrid->inserer(mc_seg);
601 }
602 }
603 }
604 }
605 //---------------------------------------------------------------------------
606 void
607 MCAA::_UpdateMCTessSegGrid(MCEdge * __mcEdge, MG_SEGMENT * __originalSegment, MG_SEGMENT * __splitSegments[2])
608 {
609 int i;
610
611 if (__originalSegment)
612 _mcTessSegGrid->supprimer( __originalSegment );
613
614 for (i=0; i<2; i++)
615 if ( __splitSegments[i] )
616 _mcTessSegGrid->inserer( __splitSegments[i] );
617
618 }
619 TPL_GRILLE <MG_SEGMENT *> * MCAA::GetMCTessSegGrid()
620 {
621 return _mcTessSegGrid;
622 }
623 //---------------------------------------------------------------------------
624 MG_VOLUME * MCAA::GetRefBody () const
625 {
626 return this->_refBody;
627 }
628
629 //---------------------------------------------------------------------------
630 MCBody * MCAA::GetMCBody () const
631 {
632 return this->_mcBody;
633 }
634
635
636 //---------------------------------------------------------------------------
637 MG_MAILLAGE * MCAA::GetRefTess () const
638 {
639 return this->_refTess;
640 }
641
642
643 //---------------------------------------------------------------------------
644 MG_MAILLAGE * MCAA::GetMCTess () const
645 {
646 return this->_mcTess;
647 }
648
649
650 //---------------------------------------------------------------------------
651 MG_GESTIONNAIRE * MCAA::GetGest () const
652 {
653 return this->_refGest;
654 }
655
656 //---------------------------------------------------------------------------
657 void MCAA::InitializeFEMesh ()
658 {
659 if ( ! _sizeMap )
660 {
661 printf("InitializeFEMesh() : Can't mesh this MC Body : the size map is NULL \n");
662 return;
663 }
664
665 if (_feMesh)
666 _refGest->supprimer_mg_maillageid(_feMesh->get_id() );
667 _feMesh = new MG_MAILLAGE(_geom);
668 _refGest->ajouter_mg_maillage(_feMesh);
669
670 printf("MAILLAGE 0D\n");
671 {
672 MCBODY_FOR_EACH_MCVERTEX(_mcBody, vertex)
673 {
674 printf(" MC vertex %ld\n", vertex->get_id() );
675 InitializeFEMesh(vertex);
676 }
677 }
678
679
680 printf("MAILLAGE 1D\n");
681 {
682 MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
683 {
684 printf(" MC edge %ld\n",edge->get_id());
685 InitializeFEMesh(edge);
686 }
687 }
688 }
689
690 //---------------------------------------------------------------------------
691 #undef debug_InitializeFEMesh_Edge
692 void MCAA::InitializeFEMesh(MCEdge * __mcEdge)
693 {
694 MAILLEUR1D m1d(_feMesh,_geom,_sizeMap,__mcEdge);
695 m1d.maille();
696
697 #ifdef debug_InitializeFEMesh_Edge
698 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = __mcEdge->get_lien_maillage();
699 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
700 MG_ELEMENT_MAILLAGE* element2;
701 int nb=0;
702 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
703 {
704 if (_feMesh->contient(element2))
705 nb++;
706 }
707 printf("There are %ld FE mesh elements on the MC Edge %ld\n", nb, __mcEdge->get_id());
708 #endif
709 }
710 //---------------------------------------------------------------------------
711 #undef debug_DeleteFEMesh_
712 void MCAA::DeleteFEMesh(MCEdge * __mcEdge)
713 {
714 std::vector <MG_SEGMENT *> vecSegs;
715 /*LISTE_MG_SEGMENT::iterator it_seg;
716 for (MG_SEGMENT* seg = _feMesh->get_premier_segment(it_seg);
717 seg; seg =_feMesh->get_suivant_segment(it_seg))
718 {
719 MG_ELEMENT_TOPOLOGIQUE * topo = seg->get_lien_topologie();
720 if (__mcEdge == topo)
721 {
722 vecSegs.push_back(seg);
723 }
724 } */
725
726 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = __mcEdge->get_lien_maillage();
727 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
728 MG_ELEMENT_MAILLAGE* element2;
729 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
730 {
731 if (_feMesh->contient(element2))
732 vecSegs.push_back((MG_SEGMENT*)element2);
733 }
734
735 for (std::vector<MG_SEGMENT *>::iterator it = vecSegs.begin();
736 it != vecSegs.end();
737 it++)
738 {
739 MG_SEGMENT * seg = *it;
740
741 _feMesh->supprimer_mg_segmentid(seg->get_id());
742 }
743
744 #ifdef debug_DeleteFEMesh_
745 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = __mcEdge->get_lien_maillage();
746 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
747 MG_ELEMENT_MAILLAGE* element2;
748 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
749 {
750 if (_feMesh->contient(element2))
751 _feMesh->supprimer_mg_segmentid(element2->get_id());
752 else if ( ! _mcTess->contient(element2))
753 printf("A segment of edge %ld is neither attached to MC Tess nor FE Mesh !\n",element2->get_id(), __mcEdge->get_id());
754 }
755 #endif
756 }
757 //---------------------------------------------------------------------------
758 int MCAA::GetFEMeshSegmentCount(MCEdge * __mcEdge)
759 {
760 int result = 0;
761
762 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = __mcEdge->get_lien_maillage();
763 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
764 MG_ELEMENT_MAILLAGE* element2;
765 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
766 {
767 if (_feMesh->contient(element2))
768 result ++;
769 }
770
771 return result;
772 }
773 //---------------------------------------------------------------------------
774 void MCAA::DeleteMesh(MCEdge * __mcEdge)
775 {
776 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = __mcEdge->get_lien_maillage();
777 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
778 MG_ELEMENT_MAILLAGE* element2;
779 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
780 {
781 if (_feMesh->contient(element2))
782 _feMesh->supprimer_mg_segmentid(element2->get_id());
783 else if (_mcTess->contient(element2))
784 _mcTess->supprimer_mg_segmentid(element2->get_id());
785 else
786 {
787 delete element2;
788 //printf((char*)"A segment of edge %lu is neither attached to MC Tess nor FE Mesh !\n",element2->get_id(), __mcEdge->get_id());
789 }
790 }
791 }
792 //---------------------------------------------------------------------------
793 void MCAA::InitializeFEMesh(MCVertex * __mcVertex, MG_NOEUD ** __n)
794 {
795 MG_NOEUD* n = NULL;
796
797 double coo[3];
798 __mcVertex->get_point()->evaluer(coo);
799 n = new MG_NOEUD(__mcVertex,coo[0],coo[1],coo[2],MAGIC::ORIGINE::MAILLEUR_AUTO);
800 _feMesh->ajouter_mg_noeud(n);
801
802 if (__n) *__n = n;
803 }
804
805 //---------------------------------------------------------------------------
806 void MCAA::DeleteFEMesh(MCVertex * __mcVertex)
807 {
808 TPL_SET<MG_ELEMENT_MAILLAGE*> lien_maillage2 = *__mcVertex->get_lien_maillage();
809 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
810 MG_ELEMENT_MAILLAGE* element2;
811 for (element2 = lien_maillage2.get_premier(it2); element2; element2 = lien_maillage2.get_suivant(it2) )
812 {
813 if (_feMesh->contient(element2))
814 _feMesh->supprimer_mg_noeudid(element2->get_id());
815 }
816 }
817 //---------------------------------------------------------------------------
818 void
819 MCAA::_DebugTraditionnalMesh()
820 {
821
822 _feMesh = new MG_MAILLAGE(_geom);
823 _refGest->ajouter_mg_maillage(_feMesh);
824
825 printf("MAILLAGE 0D\n");
826 {
827 for (unsigned it_vertex = 0; it_vertex != _geom->get_nb_mg_sommet(); it_vertex++)
828 {
829 MG_SOMMET * vertex = _geom->get_mg_sommet(it_vertex);
830 printf(" MC vertex %ld\n", vertex->get_id() );
831 double coo[3];
832 vertex->get_point()->evaluer(coo);
833 MG_NOEUD* n = new MG_NOEUD(vertex,coo[0],coo[1],coo[2],MAGIC::ORIGINE::MAILLEUR_AUTO);
834 _feMesh->ajouter_mg_noeud(n);
835 vertex->get_lien_maillage()->ajouter(n);
836 }
837 }
838
839
840 printf("MAILLAGE 1D\n");
841 {
842 for (unsigned it_edge = 0; it_edge != _geom->get_nb_mg_arete(); it_edge++)
843 {
844 MG_ARETE * edge = _geom->get_mg_arete(it_edge);
845 printf(" MC edge %ld\n",edge->get_id());
846 MAILLEUR1D m1d(_feMesh,_geom,_sizeMap,edge);
847 m1d.maille();
848 }
849 }
850
851
852 printf("MAILLAGE 2D\n");
853 {
854 for (unsigned it_face = 0; it_face != _geom->get_nb_mg_face(); it_face++)
855 {
856 MG_FACE * face = _geom->get_mg_face(it_face);
857 printf(" MC face %ld\n",face->get_id());
858 MAILLEUR2D m2d(_feMesh,_geom,_sizeMap,face);
859 m2d.change_priorite_metrique(.65);
860 m2d.maille();
861 }
862 }
863
864 }
865 //---------------------------------------------------------------------------
866 MG_MAILLAGE *
867 MCAA::GetFEMesh () const
868 {
869 return _feMesh;
870 }
871 //---------------------------------------------------------------------------
872 void
873 MCAA::UseDefaultMeshSize()
874 {
875 // Setting the default Size Map
876 double s = CalculateDefaultMeshSize();
877 printf (" Mesh size set to default value = %f\n", s);
878 SetConstantMeshSize ( s );
879 Update();
880 }
881 //---------------------------------------------------------------------------
882 void MCAA::ReadSizeMapFile(const char * __filename)
883 {
884 FCT_GENERATEUR_3D<4> * sizeMap = new FCT_GENERATEUR_3D<4>;
885 sizeMap->lire((char*)__filename);
886 if (_sizeMap)
887 delete _sizeMap;
888 _sizeMap = sizeMap;
889
890 Update();
891 }
892 //---------------------------------------------------------------------------
893 void MCAA::SetSizeMap(FCT_TAILLE * __sizeMap)
894 {
895 if (_sizeMap)
896 delete _sizeMap;
897 _sizeMap = __sizeMap;
898 Update();
899 }
900 //---------------------------------------------------------------------------
901 void MCAA::ReadSizeMapRefinementFile(const char * __filename)
902 {
903 // Setting the default Size Map
904 double s = CalculateDefaultMeshSize();
905 FCT_GENERATEUR_FICHIER * sizeMap = new FCT_GENERATEUR_FICHIER((char*)__filename, s);
906 _sizeMap = sizeMap;
907 sizeMap->construit();
908 char outfilename[10000]="";
909 sprintf(outfilename,"%s.ctt",__filename);
910 sizeMap->enregistrer(outfilename);
911 sprintf(outfilename,"%s.ctt","c:\\gilles\\mcbody.magic");
912 sizeMap->enregistrer(outfilename);
913
914 Update();
915 }
916 //---------------------------------------------------------------------------
917 void
918 MCAA::SetConstantMeshSize(double __meshSize)
919 {
920 if (_sizeMap)
921 delete _sizeMap;
922
923 char outputfilename[]="c:\\gilles\\mcbody.magic.ctt";
924 _sizeMap = new FCT_GENERATEUR_CONSTANTE ( *_refGest, __meshSize );
925 ((FCT_GENERATEUR_CONSTANTE*)_sizeMap)->construit(_bbox[0],_bbox[1],_bbox[2],_bbox[0+3],_bbox[1+3],_bbox[2+3]);
926 ((FCT_GENERATEUR_CONSTANTE*)_sizeMap)->enregistrer(outputfilename);
927 }
928
929 //---------------------------------------------------------------------------
930 double
931 MCAA::CalculateDefaultMeshSize ()
932 {
933 // Default Size = .3 * Volume / Surface
934 double V, S;
935 V = MG_UTILS::MG_MAILLAGE_GetVolume(_mcTess);
936 S = MG_UTILS::MG_MAILLAGE_GetSurface(_mcTess);
937 printf("Volume = %f\n", V );
938 printf("Surface = %f\n", S );
939 return .3 * V / S;
940 }
941
942 //---------------------------------------------------------------------------
943 void MCAA::GetBoundingBox(double __bbox[6]) const
944 {
945 for (unsigned i = 0; i<6; i++)
946 __bbox[i] = _bbox[i];
947 }
948
949 //---------------------------------------------------------------------------
950 double
951 MCAA::GetSize(double __xyz[3])
952 {
953 if (_sizeMap == NULL)
954 return 0;
955
956 double density_tensor[9];
957 _sizeMap->evaluer(__xyz, density_tensor);
958 return pow(density_tensor[0], -0.5);
959 }
960 //---------------------------------------------------------------------------
961 double
962 MCAA::GetMinSize(double __xyz[3])
963 {
964 return GetSize(__xyz) / GetMaxOverdensity();
965 }
966 //---------------------------------------------------------------------------
967 MG_SEGMENT * MCAA::_FindClosestSeg(TPL_MAP_ENTITE<MG_SEGMENT *> & __lstSegs, MCEdge * __mcEdge, double __P[3], double __N[3])
968 {
969 // minimum distance found between the tess edge and P
970 double min_distanceFrom_P = 9E99;
971 // vertices of the edge which are closest to edgePnt
972 MG_SEGMENT * closest_seg = NULL;
973
974 TPL_MAP_ENTITE<MG_SEGMENT *>::ITERATEUR itSeg;
975 for (MG_SEGMENT * seg = __lstSegs.get_premier(itSeg);
976 seg;
977 seg = __lstSegs.get_suivant(itSeg))
978 {
979 Intersection_Plane_MG_SEGMENT intersection ( __P, __N, seg, 1E-12);
980
981 if (intersection.Test () )
982 {
983 intersection.Find();
984
985 if (__mcEdge != seg->get_lien_topologie() || intersection.GetSegmentT() < 0 || intersection.GetSegmentT() > 1)
986 continue;
987
988 double intersectionPt [3];
989 intersection.GetPoint( intersectionPt );
990 double distance = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3 ( intersectionPt, __P );
991
992 if (distance < min_distanceFrom_P)
993 {
994 min_distanceFrom_P = distance;
995 closest_seg = seg;
996 }
997 }
998 }
999
1000 return closest_seg;
1001 }
1002
1003 //---------------------------------------------------------------------------
1004 MG_SEGMENT * MCAA::FindClosestSeg(MCEdge * __mcEdge, double __P[3], double __N[3])
1005 {
1006 TPL_MAP_ENTITE<MG_SEGMENT *> lstSegs;
1007 _mcTessSegGrid->rechercher( __P[0], __P[1], __P[2], GetSize(__P), lstSegs);
1008 return _FindClosestSeg(lstSegs, __mcEdge, __P, __N);
1009 }
1010 //---------------------------------------------------------------------------
1011 void MCAA::EC_Init(MCEdge * __mcEdge)
1012 {
1013 // arguments : _mcBody, __mcEdge, _feMesh, __mcTess, _mcTessSegGrid,
1014 GlobalEdgeCriteria * gec = new GlobalEdgeCriteria(__mcEdge, this);
1015 gec->Init();
1016 _ecMap.insert( std::make_pair(__mcEdge,gec) );
1017 }
1018 //---------------------------------------------------------------------------
1019 void MCAA::EC_ChangeTopo(MCEdge * __old, MCEdge * __new)
1020 {
1021 GlobalEdgeCriteria * old_gec, * new_gec;
1022 ECMapIterator it_ec = _ecMap.find(__old);
1023
1024 if ( it_ec != _ecMap.end() )
1025 {
1026 old_gec = it_ec->second;
1027 }
1028 else
1029 return;
1030
1031 it_ec = _ecMap.find(__new);
1032 if ( it_ec != _ecMap.end() )
1033 {
1034 new_gec = it_ec->second;
1035 }
1036 else
1037 {
1038 new_gec = new GlobalEdgeCriteria (__new, this);
1039 _ecMap.insert( std::make_pair(__new,new_gec) );
1040 }
1041
1042 new_gec->ChangeTopo(old_gec);
1043 }
1044 //---------------------------------------------------------------------------
1045 void MCAA::EC_Delete(MCEdge * __mcEdge)
1046 {
1047 ECMapIterator it_ec = _ecMap.find(__mcEdge);
1048
1049 if ( it_ec != _ecMap.end() )
1050 {
1051 GlobalEdgeCriteria * gec = it_ec->second;
1052 delete gec;
1053 _ecMap.erase (it_ec);
1054 }
1055 else
1056 {
1057 for (it_ec = _ecMap.begin();
1058 it_ec != _ecMap.end();
1059 it_ec ++)
1060 {
1061 GlobalEdgeCriteria * gec = it_ec->second;
1062 if (gec->GetEdge() == __mcEdge)
1063 {
1064 delete gec;
1065 _ecMap.erase (it_ec);
1066 it_ec = _ecMap.begin();
1067 }
1068 }
1069
1070 }
1071 }
1072
1073 //---------------------------------------------------------------------------
1074 void MCAA::EC_Update(MCEdge * __mcEdge)
1075 {
1076 ECMapIterator it_ec = _ecMap.find(__mcEdge);
1077 if (it_ec != _ecMap.end())
1078 {
1079 GlobalEdgeCriteria * ec = it_ec->second;
1080 // update local edge criteria
1081 // while keeping the normal offset polyline
1082 ec->Update(true);
1083 _ecMap.erase(it_ec);
1084 _ecMap.insert( std::make_pair(ec->GetEdge(),ec) );
1085 }
1086 else
1087 printf("_ecMap.end() !\n");
1088 }
1089 //---------------------------------------------------------------------------
1090 void MCAA::EC_Init()
1091 {
1092 printf("Initializing edge local properties \n");
1093 {
1094 MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
1095 {
1096 printf(" Edge local properties of MC edge %ld\n",edge->get_id());
1097 EC_Delete(edge);
1098 EC_Init(edge);
1099 }
1100 }
1101 }
1102
1103 //---------------------------------------------------------------------------
1104 std::vector <LocalEdgeCriteria *>
1105 MCAA::EC_Get(MCEdge * __mcEdge)
1106 {
1107 std::vector <LocalEdgeCriteria *> res;
1108 ECMapIterator it_ec = _ecMap.find(__mcEdge);
1109 if (it_ec != _ecMap.end())
1110 {
1111 GlobalEdgeCriteria * ec = it_ec->second;
1112 res = ec->GetLocalEdgeCriteria();
1113 }
1114 else
1115 printf("_ecMap.end() !\n");
1116
1117 return res;
1118 }
1119 //---------------------------------------------------------------------------
1120 GlobalEdgeCriteria * MCAA::GetGlobalEdgeCriteria(MCEdge * __mcEdge)
1121 {
1122 ECMapIterator it_ec = _ecMap.find(__mcEdge);
1123 if (it_ec != _ecMap.end())
1124 {
1125 return it_ec->second;
1126 }
1127 else
1128 {
1129 return NULL;
1130 }
1131 }
1132 //---------------------------------------------------------------------------
1133 GlobalEdgeCriteria * MCAA::GetHighestEdgeDeletionScore()
1134 {
1135 GlobalEdgeCriteria * BestDeletionEC = NULL;
1136 double bestscore = 0;
1137
1138 ECMapIterator it_ec;
1139 for (it_ec = _ecMap.begin();
1140 it_ec != _ecMap.end();
1141 it_ec++)
1142 {
1143 MCEdge * mcEdge = it_ec->first;
1144 GlobalEdgeCriteria * ec = it_ec->second;
1145 double score = ec->DeletionScore();
1146
1147 if (mcEdge != ec->GetEdge())
1148 continue;
1149
1150 if ( !BestDeletionEC ||
1151 score>bestscore )
1152 {
1153 BestDeletionEC = ec;
1154 bestscore = score;
1155 }
1156 }
1157
1158 if ( bestscore < 1E-3 )
1159 {
1160 bestscore = 0;
1161 BestDeletionEC = NULL;
1162 }
1163
1164 return BestDeletionEC;
1165 }
1166
1167 //---------------------------------------------------------------------------
1168 VertexCriteria * MCAA::GetHighestVCScore()
1169 {
1170 VertexCriteria * vc = NULL;
1171 double highestScore = -1E308;
1172
1173 for (VCMapCIterator itVC = _vcMap.begin();
1174 itVC != _vcMap.end();
1175 itVC++)
1176 {
1177 if (vc == NULL)
1178 {
1179 vc = itVC->second;
1180 }
1181 else if (itVC->second->GetScore() > highestScore)
1182 {
1183 MCVertex * mcVertex = itVC->second->GetVertex();
1184
1185 if (_mapSuppressRefVertexCount.find(mcVertex->GetRefVertex()) == _mapSuppressRefVertexCount.end() ||
1186 _mapSuppressRefVertexCount[mcVertex->GetRefVertex()] < 4 )
1187 {
1188 vc = itVC->second;
1189 highestScore = vc->GetScore();
1190 }
1191 }
1192 }
1193
1194 return vc;
1195 }
1196
1197 //---------------------------------------------------------------------------
1198 void
1199 MCAA::VC_Init()
1200 {
1201 {
1202 MCBODY_FOR_EACH_MCVERTEX(_mcBody, vertex)
1203 {
1204 printf(" Vertex local properties of MC vertex %ld\n",vertex->get_id());
1205 VC_Delete(vertex);
1206 VC_Init(vertex);
1207 }
1208 }
1209 }
1210
1211 //---------------------------------------------------------------------------
1212 void MCAA::VC_Init(MCVertex * __mcVertex)
1213 {
1214 double xyz[3];
1215 __mcVertex->get_point()->evaluer(xyz);
1216 VertexCriteria * vc = new VertexCriteria(__mcVertex, this);
1217 _vcMap [ __mcVertex ] = vc;
1218 }
1219
1220 //---------------------------------------------------------------------------
1221 void MCAA::VC_Delete(MCVertex * __mcVertex)
1222 {
1223 VCMapIterator itV = _vcMap.find(__mcVertex);
1224 if ( itV != _vcMap.end())
1225 {
1226 delete itV->second;
1227 _vcMap.erase(itV);
1228 }
1229 }
1230 //---------------------------------------------------------------------------
1231
1232 VertexCriteria * MCAA::VC_Get(MCVertex * __mcVertex)
1233 {
1234 VCMapCIterator it = _vcMap.find(__mcVertex);
1235 if (it != _vcMap.end() )
1236 {
1237 return it->second;
1238 }
1239 else
1240 {
1241 printf("Warning : did not find the vertex properties of vertex %p id = %ld\n", __mcVertex, __mcVertex->get_id());
1242 return NULL;
1243 }
1244 }
1245
1246 //---------------------------------------------------------------------------
1247 bool MCAA::SuppressNextVertex(MCTChanges * __mctChanges)
1248 {
1249 VertexCriteria * vc = GetHighestVCScore();
1250
1251 if (vc == NULL)
1252 return false;
1253
1254 bool bSimplifDone = (vc->GetScore() > 1E-3);
1255 if (bSimplifDone)
1256 {
1257 SuppressMCVertex(vc->GetVertex(), __mctChanges);
1258 vc = GetHighestVCScore();
1259 }
1260
1261 return bSimplifDone;
1262 }
1263 //---------------------------------------------------------------------------
1264 bool MCAA::Node_Segment_Same_Face(MG_NOEUD * __n, MG_SEGMENT * __seg, std::set <MCFace *> & __commonFaces)
1265 {
1266 Graph::Arc * segEdge_G21Arc = _mcBody->G21()->GetArc(__seg->get_lien_topologie()->get_id());
1267
1268 for (int i=0; i<__n->get_lien_segment()->get_nb(); i++)
1269 {
1270 MG_SEGMENT * seg = __n->get_lien_segment()->get(i);
1271 MG_ARETE * edge = (MG_ARETE *) seg->get_lien_topologie();
1272
1273 Graph::Arc *G21Arc = _mcBody->G21()->GetArc(edge->get_id());
1274 for (Graph::Arc::MultimapNodesById::const_iterator itNode = G21Arc->Nodes().begin(); itNode != G21Arc->Nodes().end(); itNode++)
1275 if ( segEdge_G21Arc->Nodes().find(itNode->first) != segEdge_G21Arc->Nodes().end() )
1276 __commonFaces.insert( _mcBody->GetMCFace(itNode->second) );
1277 }
1278
1279 return (__commonFaces.size() != 0);
1280 }
1281
1282 Graph::Graph * MCAA::FaceBoundaryMesh(MG_MAILLAGE * __mesh, MCFace * __face, std::set <MG_NOEUD * > & nodes, std::set <MG_SEGMENT *> & segs)
1283 {
1284 Graph::Graph * faceBoundaryMeshGraph = new Graph::Graph();
1285 nodes.clear();
1286 segs.clear();
1287
1288 Graph::Node * F_G21Node = _mcBody->G21()->GetNode(__face->get_id());
1289 Graph::Node::MultimapArcsById & F_G21NodeArcs = F_G21Node->IncidentArcs();
1290
1291 LISTE_MG_SEGMENT::iterator it_seg;
1292 for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1293 seg; seg =__mesh->get_suivant_segment(it_seg))
1294 {
1295 int seg_Topo_Id = seg->get_lien_topologie()->get_id();
1296 if (F_G21NodeArcs.find(seg_Topo_Id) != F_G21NodeArcs.end())
1297 {
1298 nodes.insert(seg->get_noeud1());
1299 nodes.insert(seg->get_noeud2());
1300 segs.insert(seg);
1301 }
1302 }
1303
1304 for ( std::set<MG_SEGMENT*>::iterator itSeg = segs.begin();
1305 itSeg != segs.end();
1306 itSeg ++)
1307 {
1308 MG_SEGMENT * seg = *itSeg;
1309 Graph::Node * graphNode = faceBoundaryMeshGraph->AddNode(seg->get_id());
1310 graphNode->SetUserData(seg);
1311 graphNode->SetUserData(2,__mesh);
1312 }
1313
1314 for (std::set<MG_NOEUD*>::iterator itNode = nodes.begin();
1315 itNode != nodes.end();
1316 itNode ++)
1317 {
1318 MG_NOEUD * n = *itNode;
1319 std::multimap< int, Graph::Node * > arcNodes;
1320
1321 TPL_LISTE_ENTITE< class MG_SEGMENT * > * adjSegList = n->get_lien_segment();
1322 int nbAdjSeg = adjSegList->get_nb();
1323 for (int i=0; i<nbAdjSeg; i++)
1324 {
1325 MG_SEGMENT * seg = adjSegList->get(i);
1326 Graph::Node * graphNode = faceBoundaryMeshGraph->GetNode(seg->get_id());
1327 if (graphNode)
1328 arcNodes.insert(std::make_pair(graphNode->Id(), graphNode));
1329 }
1330 Graph::Arc * graphArc = faceBoundaryMeshGraph->AddArc(n->get_id(), arcNodes);
1331 graphArc->SetUserData(n);
1332 graphArc->SetUserData(2,__mesh);
1333 }
1334
1335 return faceBoundaryMeshGraph;
1336 }
1337
1338 //---------------------------------------------------------------------------
1339 int MCAA::SimplifyConstrictedSections()
1340 {
1341 int result = 0;
1342 {MCBODY_FOR_EACH_MCFACE(_mcBody, face)
1343 {
1344 bool stop = false;
1345 while (stop == false)
1346 {
1347 bool done = ProcessNextConstrictedSectionInFace(face);
1348 if (done)
1349 {
1350 result++;
1351 }
1352 else
1353 {
1354 stop = true;
1355 }
1356 }
1357 }
1358 }
1359 return result;
1360 }
1361
1362 bool MCAA::ProcessNextConstrictedSectionInFace(MCFace * __mcFace)
1363 {
1364 std::set <MG_NOEUD * > nodes;
1365 std::set <MG_SEGMENT *> segs;
1366
1367 MCFace * face = __mcFace;
1368 Graph::Graph * G = FaceBoundaryMesh(_feMesh, face, nodes, segs);
1369
1370 ConstrictedSection cs,cs2,cs3;
1371 MG_NOEUD *no2,*no3;
1372 for (std::set <MG_NOEUD * >::iterator itNo = nodes.begin();
1373 itNo != nodes.end();
1374 itNo++)
1375 {
1376 MG_NOEUD * no = *itNo;
1377
1378 if (NodeConstrictedSection(face, no, cs, G))
1379 {
1380 MCVertex *V1, *V2;
1381
1382 {
1383 MCEdge * edge = 0;
1384 if (no->get_lien_topologie()->get_dimension() > 0)
1385 {
1386 edge = (MCEdge*)no->get_lien_topologie();
1387 if (((MCVertex*)edge->get_cosommet1()->get_sommet())->GetMergedRefVertices().size() > 0)
1388 continue;
1389 if (((MCVertex*)edge->get_cosommet2()->get_sommet())->GetMergedRefVertices().size() > 0)
1390 continue;
1391 }
1392 if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() > 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() > 0)
1393 {
1394 edge = (MCEdge*)cs.Seg1->get_lien_topologie();
1395 if (((MCVertex*)edge->get_cosommet1()->get_sommet())->GetMergedRefVertices().size() > 0)
1396 continue;
1397
1398 if (((MCVertex*)edge->get_cosommet2()->get_sommet())->GetMergedRefVertices().size() > 0)
1399 continue;
1400 }
1401 }
1402
1403 // if node is not on a vertex, then insert a vertex on node
1404 if (no->get_lien_topologie()->get_dimension() > 0)
1405 {
1406 MCEdge * edge = (MCEdge*)no->get_lien_topologie();
1407
1408 MCTChanges mctChanges;
1409 RTChanges rtChanges;
1410 SplitEdge(edge, no->get_coord(), &mctChanges, &rtChanges);
1411 V1 = (mctChanges.V.begin())->second;
1412 }
1413 else // V1 = this vertex
1414 {
1415 V1 = (MCVertex *)no->get_lien_topologie();
1416 }
1417 // if the extremities of the segment are not on a vertex, then insert a vertex
1418 // on the closest point
1419 if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() > 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() > 0)
1420 {
1421 MCEdge * edge = (MCEdge*)cs.Seg1->get_lien_topologie();
1422 MCTChanges mctChanges;
1423 RTChanges rtChanges;
1424 SplitEdge(edge, cs.Seg1P, &mctChanges, &rtChanges);
1425 V2 = (mctChanges.V.begin())->second;
1426 }
1427 else // V2 = this vertex
1428 {
1429 if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() == 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() == 0 )
1430 {
1431 double dist1 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(cs.Seg1->get_noeud1()->get_coord(), cs.Seg1P);
1432 double dist2 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(cs.Seg1->get_noeud2()->get_coord(), cs.Seg1P);
1433 if(dist1<dist2)
1434 V2 = (MCVertex *) cs.Seg1->get_noeud1()->get_lien_topologie();
1435 else
1436 V2 = (MCVertex *) cs.Seg1->get_noeud2()->get_lien_topologie();
1437 }
1438 else if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() == 0)
1439 V2 = (MCVertex *) cs.Seg1->get_noeud1()->get_lien_topologie();
1440 else if (cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() == 0)
1441 V2 = (MCVertex *) cs.Seg1->get_noeud2()->get_lien_topologie();
1442 }
1443 // Merge vertices V1 with V2
1444 std::set<MCEdge*> edges;
1445 std::set<MCEdge*>::iterator itEdge;
1446 MergeVertices(V1,V2);
1447
1448 delete G;
1449 return true;
1450 }
1451 }
1452 delete G;
1453 return false;
1454 }
1455
1456 //---------------------------------------------------------------------------
1457 bool MCAA::NodeConstrictedSection(MCFace * __mcFace, MG_NOEUD * __n, ConstrictedSection & __cs, Graph::Graph * __faceBoundaryMeshGraph)
1458 {
1459 int i,j,k;
1460 double LMin;
1461
1462 if (__n->get_lien_topologie()->get_nb_ccf() != 0)
1463 return false;
1464
1465 double meshSize = GetSize(__n->get_coord());
1466 LMin = .5*meshSize/GetMaxOverdensity();
1467
1468 std::map<double,ConstrictedSection> mapCSByDistance;
1469
1470 const Graph::Graph::MapNodesById & graphNodes = __faceBoundaryMeshGraph->GetNodes();
1471 for (Graph::Graph::MapNodesById::const_iterator itGN = graphNodes.begin();
1472 itGN != graphNodes.end();
1473 itGN++)
1474 {
1475 Graph::Node * graphNode = itGN->second;
1476 MG_SEGMENT * seg = (MG_SEGMENT *)graphNode->GetUserData();
1477
1478
1479
1480 std::set<MCFace*>commonF;
1481 double dist;
1482 double *SP0 = seg->get_noeud1()->get_coord();
1483 double *SP1 = seg->get_noeud2()->get_coord();
1484 double *P = __n->get_coord();
1485 double P2[3];
1486 OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_3d(SP0,SP1,P,P2);
1487 dist=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(P,P2);
1488 if (dist < LMin)
1489 {
1490 if (__n==seg->get_noeud1() || __n==seg->get_noeud2())
1491 continue;
1492 std::set <Graph::Node*> adjacentGNSegs, adjacentGNSegs2;
1493 graphNode->AdjacentNodes (adjacentGNSegs);
1494 for (std::set <Graph::Node*>::iterator itN1 = adjacentGNSegs.begin(); itN1 != adjacentGNSegs.end(); itN1++)
1495 {
1496 Graph::Node * gn1 = *itN1;
1497 MG_SEGMENT * seg1 = (MG_SEGMENT *)gn1->GetUserData();
1498 if (__n==seg1->get_noeud1() || __n==seg1->get_noeud2())
1499 continue;
1500 }
1501
1502 ConstrictedSection cs;
1503 std::set<MCFace*>::iterator itF=commonF.begin();
1504 cs.F = *itF;
1505 cs.Node = __n;
1506 cs.Seg1 = seg;
1507 OT_ALGORITHME_GEOMETRIQUE::VEC3_ASSIGN_VEC3(P2,cs.Seg1P);
1508 mapCSByDistance[dist] = cs;
1509 }
1510 }
1511
1512 for (std::map<double, ConstrictedSection>::iterator itCS=mapCSByDistance.begin();
1513 itCS != mapCSByDistance.end();
1514 itCS++)
1515 {
1516 double distance = itCS->first;
1517 MG_SEGMENT *sa = itCS->second.Seg1;
1518 OT_VECTEUR_3D point_a = itCS->second.Seg1P;
1519
1520 for (int i=0; i<__n->get_lien_segment()->get_nb(); i++)
1521 {
1522 MG_SEGMENT * sb = __n->get_lien_segment()->get(i);
1523 OT_VECTEUR_3D point_b(__n->get_coord());
1524
1525 std::vector <Graph::Node *> pathNodes;
1526 std::vector <Graph::Arc *> pathArcs;
1527 Graph::Node * nStart = __faceBoundaryMeshGraph->GetNode(sa->get_id());
1528 Graph::Node * nEnd = __faceBoundaryMeshGraph->GetNode(sb->get_id());
1529 if (nEnd == 0 || nStart == 0) // segment adjacent to node is not in the face
1530 continue;
1531
1532 double distance = Graph::Dijkstra(__faceBoundaryMeshGraph,nStart,nEnd,GraphDistanceBetweenSegs,pathNodes,pathArcs);
1533
1534 bool testShortestPath = (distance > 3*meshSize);
1535
1536 if (testShortestPath == false)
1537 break;
1538
1539 bool testInteriorDir;
1540 {
1541 OT_VECTEUR_3D direction_b_a;
1542 for (int i=0; i<3; i++)
1543 direction_b_a[i] = point_a[i]-point_b[i];
1544
1545 if ( direction_b_a.get_longueur2() > 1E-32 )
1546 {
1547 double * xyz_topo[2]={point_b,point_a};
1548 MCNode * mcNode[2]={0,0};
1549 MG_ELEMENT_TOPOLOGIQUE * mcTopo[2], * refTopo[2];
1550 mcTopo[0] = __n->get_lien_topologie();
1551 mcTopo[1] = sa->get_lien_topologie();
1552
1553 for (int k=0;k<2;k++)
1554 {
1555 switch(mcTopo[k]->get_dimension())
1556 {
1557 case 0:
1558 {
1559 MCVertex * mcVertex = (MCVertex *)mcTopo[k];
1560 mcNode[k] = new MCNode(mcVertex,mcVertex->GetRefVertex(),xyz_topo[k][0],xyz_topo[k][1],xyz_topo[k][2]);
1561 break;
1562 }
1563 case 1:
1564 {
1565 MCEdge * mcEdge = (MCEdge*) mcTopo[k];
1566 PolyCurve * polyCurve = mcEdge->GetPolyCurve();
1567 MG_ARETE * refEdge = 0;
1568 double s_polycurve,t_refEdge,dt_refEdge;
1569 polyCurve->inverser(s_polycurve,xyz_topo[k],1E-6);
1570 polyCurve->Parameter_SToRefEdgeT (s_polycurve, &refEdge, &t_refEdge, &dt_refEdge,false);
1571 mcNode[k] = new MCNode(mcEdge, refEdge, t_refEdge, xyz_topo[k]);
1572 break;
1573 }
1574 default:
1575 {
1576 refTopo[k] = 0;
1577 }
1578 }
1579 }
1580
1581 ShortestPathByClosestPointOnEdge operateur_distGeo(__mcFace,mcNode[0],mcNode[1],.25*meshSize);
1582 double distanceGeo = operateur_distGeo.Find();
1583 if (distanceGeo > .5*meshSize)
1584 testInteriorDir = false;
1585 else
1586 testInteriorDir = true;
1587
1588 }
1589 }
1590
1591 if (testInteriorDir == false)
1592 break;
1593
1594 if (testInteriorDir && testShortestPath)
1595 {
1596 __cs = itCS->second;
1597 return true;
1598 }
1599 }
1600 }
1601
1602 return false;
1603 }
1604 double MCAA::GraphDistanceBetweenSegs(Graph::Node * __a, Graph::Node * __b, Graph::Arc * __arc )
1605 {
1606 MG_SEGMENT * seg1 = (MG_SEGMENT *)__a->GetUserData();
1607 MG_SEGMENT * seg2 = (MG_SEGMENT *)__b->GetUserData();
1608 return .5*(seg1->get_longueur()+seg2->get_longueur());
1609 }
1610 //---------------------------------------------------------------------------
1611 struct DJSeg {
1612 int nbVisit;
1613 double d;
1614 MG_SEGMENT * seg;
1615 MG_SEGMENT * previous;
1616 };
1617 //---------------------------------------------------------------------------
1618 // Calcule le chemin le plus court entre les milieux des segments sa et sb
1619 double
1620 MCAA::ShortestPath(MG_MAILLAGE * __mesh, MG_SEGMENT * sa, MG_SEGMENT * sb)
1621 {
1622 int i,j,k;
1623
1624 if ( ! __mesh->contient(sa) || ! __mesh->contient(sb))
1625 {
1626 printf("ShortestPath : error : the mesh does not contain the querried segment!\n");
1627 return -1;
1628 }
1629
1630 /*fonction Dijkstra (noeuds, fils, distance, debut, fin)*/
1631 double distance;
1632 std::map<MG_SEGMENT*, struct DJSeg> nodes;
1633 std::multimap<double, struct DJSeg*> nodesByD;
1634
1635 /*
1636 Pour n parcourant noeuds
1637 n.parcouru = infini // Peut �tre impl�ment� avec -1
1638 n.precedent = 0
1639 Fin pour*/
1640 MG_SEGMENT *seg;
1641 LISTE_MG_SEGMENT::iterator it_seg;
1642 for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1643 seg; seg =__mesh->get_suivant_segment(it_seg))
1644 {
1645
1646 struct DJSeg djseg;
1647
1648 djseg.previous = NULL;
1649 djseg.seg = seg;
1650 djseg.nbVisit = 0;
1651 djseg.d = 1E300;
1652
1653 nodes[seg] = djseg;
1654 }
1655
1656 if (nodes.find(sa) == nodes.end() || nodes.find(sb) == nodes.end())
1657 return 1E300;
1658
1659 /*
1660 debut.parcouru = 0
1661 DejaVu = liste vide
1662 PasEncoreVu = noeuds
1663 */
1664 nodes[sa].d = 0;
1665
1666
1667 std::set <MG_SEGMENT*> visited, unvisited;
1668
1669 nodesByD.insert( std::make_pair( 0, &(nodes[sa])) );
1670
1671 for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1672 seg; seg =__mesh->get_suivant_segment(it_seg))
1673 {
1674 unvisited.insert(seg);
1675
1676 }
1677 //
1678
1679 // Tant que PasEncoreVu != liste vide
1680 while (unvisited.size() != 0)
1681 {
1682 // n1 = minimum(PasEncoreVu) // Le noeud dans PasEncoreVu avec parcouru le plus petit
1683 struct DJSeg closestSeg;
1684
1685 std::multimap<double, struct DJSeg *>::iterator itDJSegByDist;
1686 for (itDJSegByDist = nodesByD.begin();
1687 itDJSegByDist != nodesByD.end(); itDJSegByDist++)
1688 {
1689 if ( unvisited.find(itDJSegByDist->second->seg) != unvisited.end() )
1690 {
1691 closestSeg = *(itDJSegByDist->second);
1692 break;
1693 }
1694 }
1695 if (itDJSegByDist == nodesByD.end())
1696 closestSeg = nodes[*(unvisited.begin())];
1697
1698 MG_SEGMENT * seg = closestSeg.seg;
1699
1700 // DejaVu.ajouter(n1)
1701 //
1702 visited.insert(seg);
1703 nodes[seg].nbVisit ++;
1704
1705
1706 // PasEncoreVu.enlever(n1)
1707 unvisited.erase(seg);
1708
1709
1710 /*
1711 Pour n2 parcourant fils(n1) // Les noeuds reli�s � n1 par un arc
1712 Si n2.parcouru > n1.parcouru + distance(n1, n2) // distance correspond au poids de l'arc reliant n1 et n2
1713 n2.parcouru = n1.parcouru + distance(n1, n2)
1714 n2.precedent = n1 // Dis que pour aller � n2, il faut passer par n1
1715 Fin si
1716 Fin pour
1717 Fin tant que
1718 */
1719 std::set <MG_SEGMENT*>children;
1720 TPL_LISTE_ENTITE<MG_SEGMENT*> *lien_segment1 = seg->get_noeud1()->get_lien_segment();
1721 for (i=0; i<lien_segment1->get_nb(); i++)
1722 {
1723 MG_SEGMENT * child = lien_segment1->get(i);
1724 if (child != seg )
1725 children.insert(child);
1726 }
1727 TPL_LISTE_ENTITE<MG_SEGMENT*> *lien_segment2 = seg->get_noeud2()->get_lien_segment();
1728 for (i=0; i<lien_segment2->get_nb(); i++)
1729 {
1730 MG_SEGMENT * child = lien_segment2->get(i);
1731 if (child != seg )
1732 children.insert(child);
1733 }
1734
1735 for ( std::set <MG_SEGMENT*>::iterator itChild = children.begin();
1736 itChild != children.end();
1737 itChild++)
1738 {
1739 MG_SEGMENT * child = *itChild;
1740 struct DJSeg * sDJSegChild = &(nodes[child]);
1741 double dist_child = .5*seg->get_longueur() + .5*child->get_longueur();
1742
1743 if ( sDJSegChild->d > closestSeg.d + dist_child)
1744 {
1745 sDJSegChild->d = closestSeg.d + dist_child;
1746 sDJSegChild->previous = seg;
1747
1748 if ( unvisited.find(sDJSegChild->seg) != unvisited.end() )
1749 nodesByD.insert(std::make_pair(sDJSegChild->d, sDJSegChild));
1750 }
1751 }
1752
1753 }
1754
1755 /*
1756 chemin = liste vide
1757 n = fin
1758 Tant que n != debut
1759 chemin.ajouterAvant(n)
1760 n = n.precedent
1761 Fin tant que
1762 Retourner chemin
1763 Fin fonction Dijkstra.
1764 */
1765
1766 std::vector<MG_SEGMENT*> path;
1767 struct DJSeg n = nodes[sb];
1768 distance = n.d;
1769
1770 int nb_seg = __mesh->get_nb_mg_segment();
1771
1772 for (i=0; i<nb_seg && n.seg != sa; i++)
1773 {
1774 path.insert(path.begin(), n.seg);
1775 n = nodes[n.previous];
1776 }
1777 if (i == nb_seg)
1778 distance = 1E300;
1779
1780 return distance;
1781 }
1782 //---------------------------------------------------------------------------
1783 /*bool MCAA::TestEdgeSupprBoundary(MCVertex * __mcVertex)
1784 {
1785 int i;
1786
1787 if (_mcBody->G10()->GetArc(__mcVertex->get_id())->Rank() != 2)
1788 return false;
1789
1790 // Get the 2 edges adjacent to this vertex
1791 std::vector < MCEdge * > edges;
1792 _mcBody->Vertex_GetAdjacentEdges(__mcVertex, edges);
1793
1794 // Get node of this vertex in the FE mesh
1795 TPL_SET<MG_ELEMENT_MAILLAGE *> * lien_maillage = __mcVertex->get_lien_maillage();
1796 TPL_SET<MG_ELEMENT_MAILLAGE *>::ITERATEUR it;
1797 MG_ELEMENT_MAILLAGE * elem;
1798 MG_NOEUD * node = NULL;
1799 for (elem = lien_maillage->get_premier(it); elem ; elem = lien_maillage->get_suivant(it))
1800 {
1801 if (_feMesh->contient(elem))
1802 {
1803 node = (MG_NOEUD*)elem;
1804 break;
1805 }
1806 }
1807 if (!node)
1808 {
1809 printf("Warning : no node was found for MCVertex %ld in the FE mesh !\n", __mcVertex->get_id());
1810 return false;
1811 }
1812
1813 // Get the two segments adjacent to this node
1814 MG_SEGMENT * segs[2];
1815 segs[0] = node->get_lien_segment()->get(0);
1816 segs[1] = node->get_lien_segment()->get(1);
1817
1818 // Get the two local edge criteria of these segments
1819 LocalEdgeCriteria * edgeCrit[2];
1820 for (i=0;i<2;i++)
1821 {
1822 MCEdge * edge = (MCEdge*)segs[i]->get_lien_topologie();
1823
1824 ECMapIterator it_ec = _ecMap.find(edge);
1825
1826 if (it_ec != _ecMap.end())
1827 {
1828 GlobalEdgeCriteria * gec = it_ec->second;
1829 edgeCrit[i] = gec->GetLocalEdgeCriteria(segs[i]);
1830 if (!edgeCrit[i])
1831 {
1832 printf("Warning : no criteria were found for segment %ld of edge %ld\n", segs[i]->get_id(), edge->get_id());
1833 return false;
1834 }
1835 }
1836 else
1837 {
1838 printf("TestEdgeSupprBoundary : Error : vertex %ld is not found\n");
1839 return false;
1840 }
1841 }
1842
1843 return ( edgeCrit[0]->DeletionScore() * edgeCrit[1]->DeletionScore() < 0);
1844 } */
1845
1846 void V(MCAA * mcaa)
1847 {
1848 MCBody * _mcBody = mcaa->GetMCBody();
1849 {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge22){
1850 if (_mcBody->G21()->GetArcs().size() <= 1)
1851 break;
1852 if (mcaa->CheckIfTopoExists(edge22) == false)
1853 printf("MC Edge ID=%lu not OK\n", edge22->get_id());
1854 }
1855 }
1856
1857 }
1858 //---------------------------------------------------------------------------
1859 void
1860 MCAA::SuppressMCEdge(MCEdge * __mcEdge, MCTChanges * __mctChanges)
1861 {
1862 MCFace * F[3];
1863
1864 // update the simplification time
1865 time++;
1866
1867 // Get the list of vertex that are adjacent to the
1868 // mc edge
1869 std::vector<MCVertex*> edge_vertices;
1870 _mcBody->Edge_GetVertices(__mcEdge, edge_vertices);
1871
1872 // remove the FE mesh of this edge
1873 DeleteFEMesh(__mcEdge);
1874 // Delete the criteria of the MC Edge
1875 EC_Delete(__mcEdge);
1876
1877 // Suppress the mc edge of the mc body
1878 _mcBody->SuppressMCEdge(__mcEdge, F);
1879 // V(this);
1880
1881 // the current MCFace containing to the deleted edge
1882 MCFace * newFace = F[2];
1883
1884 // move the link of the edge to the current MCFace containing to the deleted edge
1885 MG_MAILLAGE_OUTILS::change_lien_maillage( __mcEdge, newFace );
1886 for (int i=0; i<2; i++)
1887 {
1888 if (F[i] != NULL)
1889 {
1890 // a face that was deleted from MCT
1891 MCFace * oldFace = F[i];
1892 // update mesh link of old face to new face
1893 MG_MAILLAGE_OUTILS::change_lien_maillage( oldFace, newFace );
1894 // delete old face
1895 _mcBody->DeleteMCFace(oldFace);
1896 //V(this);
1897 }
1898 }
1899
1900 std::set<MCEdge*> adjedge = _mcBody->Face_GetAdjacentEdges(newFace);
1901 for ( std::set<MCEdge*>::iterator itAdjEdge = adjedge.begin();
1902 itAdjEdge != adjedge.end(); itAdjEdge++)
1903 {
1904 MCEdge * edge = *itAdjEdge;
1905 GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(edge);
1906 gec->Update(__mcEdge, false);
1907 //V(this);
1908 }
1909
1910 // Dereference the MCEdge from the geometry manager, and free the memory
1911 _mcBody->DeleteMCEdge(__mcEdge);
1912 //V(this);
1913
1914 // update the vertex properties on the adjacent vertices
1915 for (std::vector<MCVertex*>::iterator itVertex = edge_vertices.begin();
1916 itVertex != edge_vertices.end();
1917 itVertex++ )
1918 {
1919 MCVertex * v = *itVertex;
1920 VC_Get(v)->Update();
1921 //V(this);
1922 }
1923
1924 // update the modification time of the MC Edge
1925 newFace->time = time;
1926 __mctChanges->E.insert(std::make_pair(__mcEdge, (MCEdge*)NULL));
1927 if (F[0]) __mctChanges->F.insert(std::make_pair(F[0], F[2]));
1928 if (F[1]) __mctChanges->F.insert(std::make_pair(F[1], F[2]));
1929
1930 //V(this);
1931 }
1932 //---------------------------------------------------------------------------
1933 void
1934 MCAA::SuppressMCVertex(MCVertex * __mcVertex, MCTChanges * __mctChanges)
1935 {
1936 std::multimap<MCEdge*,MCEdge*>::iterator itE;
1937
1938 // update the simplification time
1939 time++;
1940
1941 if (_mapSuppressRefVertexCount.find(__mcVertex->GetRefVertex()) == _mapSuppressRefVertexCount.end())
1942 _mapSuppressRefVertexCount[ __mcVertex->GetRefVertex() ] = 1;
1943 else
1944 {
1945 _mapSuppressRefVertexCount[ __mcVertex->GetRefVertex() ]++;
1946 }
1947
1948 // Get the edges adjacent to this vertex
1949 std::set< MCEdge * > vertex_edges;
1950 _mcBody->Vertex_GetAdjacentEdges(__mcVertex, vertex_edges);
1951
1952 if ( vertex_edges.size() != 0 && vertex_edges.size() != 2)
1953 {
1954 printf("P B vertex %ld has %lx edges\n", __mcVertex->get_id(), (long unsigned int)vertex_edges.size());
1955 }
1956
1957 std::set< MCFace * > vertex_faces;
1958 _mcBody->Vertex_GetAdjacentFaces(__mcVertex, vertex_faces);
1959 if (vertex_edges.size() == 0) // case of a vertex isolated in the face
1960 {
1961 if (vertex_faces.size() == 1)
1962 {
1963 std::set< MCFace * >::iterator vertex_faces_it = vertex_faces.begin();
1964 // delete the node of the FE mesh
1965 DeleteFEMesh(__mcVertex);
1966 // update the link of the deleted vertex in the MC Tessellation
1967 MG_MAILLAGE_OUTILS::change_lien_maillage(__mcVertex, *vertex_faces_it);
1968 }
1969 else
1970 {
1971 printf("Problem : vertex has 0 edge and 0 face !!!\n");
1972 }
1973 }
1974
1975 // Suppress this vertex in the MCBody
1976 MCEdge * newEdge = NULL;
1977
1978 _mcBody->SuppressMCVertex(__mcVertex, __mctChanges);
1979
1980 if ( __mctChanges->E.size() != 0)
1981 {
1982 itE = __mctChanges->E.begin();
1983 newEdge = itE->second;
1984
1985 for (itE = __mctChanges->E.begin(); itE != __mctChanges->E.end(); itE++)
1986 {
1987 MCEdge * edge0 = itE->first;
1988 MCEdge * edge1 = itE->second;
1989
1990 printf("Created edge %ld containing %ld %ld", newEdge->get_id(), edge0->get_id(), edge1->get_id());
1991
1992 // If edge0 was deleted
1993 if ( edge0 != 0 )
1994 {
1995 // move the link of the egde to the current MCFace containing to the deleted edge
1996 MG_MAILLAGE_OUTILS::change_lien_maillage( edge0, edge1, _mcTess);
1997 MG_MAILLAGE_OUTILS::change_lien_maillage(__mcVertex, edge1, _mcTess);
1998
1999 // update the modification time of the MC Edge
2000 newEdge->time = time;
2001 }
2002 }
2003 printf("\n");
2004
2005 std::set <MCEdge*> faces_edges;
2006 for (std::set<MCFace*>::iterator itFace = vertex_faces.begin();
2007 itFace != vertex_faces.end();
2008 itFace++)
2009 {
2010 MCFace * mcFace = *itFace;
2011
2012 // Get the G21 arcs to G21 node
2013 // they compose the MC edges adjacent to the MC face
2014 Graph::Node * G21Node = _mcBody->G21()->GetNode(mcFace->get_id());
2015
2016 Graph::Node::MultimapArcsById & arcsOfG21Node = G21Node->IncidentArcs();
2017
2018 for (Graph::Node::MultimapArcsById::const_iterator it = arcsOfG21Node.begin();
2019 it != arcsOfG21Node.end();
2020 it++)
2021 faces_edges.insert( _mcBody->GetMCEdge(it->second) );
2022 }
2023
2024 for (std::set<MCEdge*>::iterator itFaceEdge = faces_edges.begin();
2025 itFaceEdge != faces_edges.end();
2026 itFaceEdge++)
2027 {
2028 MCEdge * faceEdge = *itFaceEdge;
2029 if ( vertex_edges.find(faceEdge) != vertex_edges.end() )
2030 continue;
2031 GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(faceEdge);
2032 if (gec == NULL ) continue;
2033
2034 for (std::set<MCEdge*>::iterator itDeletedVertexEdge = vertex_edges.begin();
2035 itDeletedVertexEdge != vertex_edges.end();
2036 itDeletedVertexEdge++)
2037 {
2038 MCEdge * deletedEdge = *itDeletedVertexEdge;
2039 gec->Update(deletedEdge, false);
2040 }
2041 }
2042
2043 // delete edge criteria of each original mc Edge
2044 // initialize the edge criteria on the new merged MCEdge
2045 bool bRemeshMergedEdges = true;
2046 if ( bRemeshMergedEdges )
2047 {
2048 DeleteFEMesh(newEdge);
2049 DeleteFEMesh(__mcVertex);
2050 InitializeFEMesh(newEdge);
2051 EC_Init(newEdge);
2052
2053 for (itE = __mctChanges->E.begin(); itE != __mctChanges->E.end(); itE++)
2054 {
2055 MCEdge * oldEdge2 = itE->first;
2056
2057 // delete the edge criteria of the original mc edge
2058 EC_Delete(oldEdge2);
2059 }
2060 }
2061 else
2062 {
2063 for (itE = __mctChanges->E.begin(); itE != __mctChanges->E.end(); itE++)
2064 {
2065 MCEdge * oldEdge2 = itE->first;
2066 MCEdge * newEdge2 = itE->second;
2067 if (oldEdge2)
2068 {
2069
2070
2071 // move local edge criterie to new merged mc edge
2072 EC_ChangeTopo(oldEdge2, newEdge2);
2073 GetGlobalEdgeCriteria(newEdge2)->Update(false);
2074
2075 // delete the edge criteria of the original mc edge
2076 EC_Delete(oldEdge2);
2077 }
2078 }
2079 }
2080 }
2081
2082 // the vertex properties of the deleted mc vertex are deleted
2083 VC_Delete(__mcVertex);
2084
2085 // Delete Old vertex
2086 _mcBody->DeleteMCVertex(__mcVertex);
2087
2088 // Delete old MC Edges
2089 for (std::set<MCEdge*>::iterator itE = vertex_edges.begin();
2090 itE != vertex_edges.end();
2091 itE++ )
2092 {
2093 MCEdge * mcEdge = *itE;
2094 _mcBody->DeleteMCEdge(mcEdge);
2095 }
2096 }
2097
2098 //---------------------------------------------------------------------------
2099 bool MCAA::SplitEdgesAtIncompatibleLocalCriteria(MCTChanges * __mctChanges)
2100 {
2101 int i;
2102 double bestSplitScore = 0, bestSplitPoint[3];
2103 MCEdge * bestSplitEdge = NULL;
2104 RTChanges rtChanges;
2105
2106 for (ECMapIterator it_ec = _ecMap.begin();
2107 it_ec != _ecMap.end();
2108 it_ec++)
2109 {
2110 MCEdge * mcEdge = it_ec->first;
2111 GlobalEdgeCriteria * gec = it_ec->second;
2112 double splitScore = 0, splitPoint[3];
2113 splitScore = gec->SplitScore(splitPoint);
2114 if (splitScore > bestSplitScore)
2115 {
2116 bestSplitScore = splitScore;
2117 bestSplitEdge = mcEdge;
2118 for (i=0;i<3;i++)
2119 bestSplitPoint[i] = splitPoint[i];
2120
2121 break;
2122 }
2123 }
2124
2125 if (bestSplitEdge)
2126 {
2127 SplitEdge(bestSplitEdge, bestSplitPoint, __mctChanges, &rtChanges);
2128 return true;
2129 }
2130 else
2131 return false;
2132 }
2133 //---------------------------------------------------------------------------
2134 void MCAA::SplitEdge(MCEdge * __mcEdge, double xyz[3], MCTChanges * __mctChanges, RTChanges * __rtChanges, bool __splitTessellation)
2135 {
2136 int i;
2137
2138 // Get the list of faces that are adjacent to the
2139 // mc edge
2140 std::set < MCFace * > edge_faces = _mcBody->Edge_GetAdjacentFaces(__mcEdge);
2141
2142
2143 // Split the MC Edge
2144 MG_ARETE *__origRefEdge, *__splitRefEdges[2];
2145 MG_SOMMET *__splitRefVertex;
2146 MCVertex * __splitVertex;
2147 MCEdge * __splitEdges[2];
2148
2149 __origRefEdge = __mcEdge->GetPolyCurve()->GetRefEdge(0);
2150
2151 _mcBody->SplitEdge(__mcEdge, xyz, __mctChanges, __rtChanges);
2152
2153 if (__mctChanges->E.size() == 0)
2154 return;
2155
2156 std::multimap<MCEdge*, MCEdge*>::iterator itMCE;
2157 std::multimap<MCVertex*, MCVertex*>::iterator itMCV;
2158
2159 itMCE = __mctChanges->E.begin();
2160 for (i=0; i<2; i++, itMCE++)
2161 __splitEdges[i] = itMCE->second;
2162
2163 itMCV = __mctChanges->V.begin();
2164 __splitVertex = itMCV->second;
2165
2166 std::multimap<MG_ARETE*, MG_ARETE*>::iterator itRE;
2167 std::multimap<MG_SOMMET*, MG_SOMMET*>::iterator itRV;
2168
2169 itRE = __rtChanges->E.begin();
2170 for (i=0; i<2; i++, itRE++)
2171 {
2172 __origRefEdge = itRE->first;
2173 __splitRefEdges[i] = itRE->second;
2174 }
2175
2176 itRV = __rtChanges->V.begin();
2177 __splitRefVertex = itRV->second;
2178
2179 printf("Edge %ld has been substituted by edges %ld and %ld\n", __mcEdge->get_id(), __splitEdges[0]->get_id(), __splitEdges[1]->get_id());
2180
2181 MG_SEGMENT * mcTessOriginalSegment, *refTessOriginalSegment;
2182 // split the tessellation
2183 if (__splitTessellation)
2184 {
2185 MG_NOEUD * mcTessSplitNode;
2186 MG_SEGMENT * mcTessSplitSegments[2];
2187 MG_MAILLAGE_OUTILS::SplitEdgeInMesh(_mcTess, __mcEdge, __splitVertex, __splitEdges[0], __splitEdges[1], &mcTessOriginalSegment, &mcTessSplitNode, mcTessSplitSegments);
2188
2189 MG_NOEUD * refTessSplitNode;
2190 MG_SEGMENT * refTessSplitSegments[2];
2191 if (__origRefEdge) MG_MAILLAGE_OUTILS::SplitEdgeInMesh(_refTess, __origRefEdge, __splitRefVertex, __splitRefEdges[0], __splitRefEdges[1], &refTessOriginalSegment, &refTessSplitNode, refTessSplitSegments);
2192
2193 // update MC Tessellation Grid
2194 _UpdateMCTessSegGrid(__mcEdge, mcTessOriginalSegment,mcTessSplitSegments);
2195 }
2196 if (__origRefEdge) _geom->supprimer_mg_areteid(__origRefEdge->get_id());
2197
2198 // remesh the split edges
2199 DeleteFEMesh(__mcEdge);
2200 DeleteFEMesh(__splitVertex);
2201 MG_NOEUD * feNode;
2202 InitializeFEMesh(__splitVertex, &feNode);
2203 for (i=0; i<2; i++)
2204 {
2205 InitializeFEMesh(__splitEdges[i]);
2206 }
2207
2208 // update vertex criteria
2209 VC_Init(__splitVertex);
2210
2211 // update edge criteria
2212 EC_Delete(__mcEdge);
2213 for (i=0; i<2; i++)
2214 EC_Init(__splitEdges[i]);
2215 _mcBody->DeleteMCEdge(__mcEdge);
2216
2217 if (mcTessOriginalSegment)
2218 { MCBODY_FOR_EACH_MCEDGE ( _mcBody, mcEdge )
2219 {
2220 GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(mcEdge);
2221 gec->ReInit(mcTessOriginalSegment);
2222 gec->Update(__mcEdge, false);
2223 }
2224 }
2225
2226
2227 // delete the original segments in MC and Ref tessellations
2228 if (mcTessOriginalSegment)
2229 _mcTess->supprimer_mg_segmentid(mcTessOriginalSegment->get_id());
2230 if (refTessOriginalSegment)
2231 _refTess->supprimer_mg_segmentid(refTessOriginalSegment->get_id());
2232
2233 // update the simplification time
2234 time++;
2235 __splitVertex->time = time;
2236 for (i=0; i<2; i++)
2237 __splitEdges[i]->time = time;
2238
2239 Graph::Arc * G21Arc = _mcBody->G21()->GetArc( __splitEdges[0]->get_id() );
2240 for (Graph::Arc::MultimapNodesById::const_iterator itN = G21Arc->Nodes().begin();
2241 itN != G21Arc->Nodes().end();
2242 itN++)
2243 {
2244 MCFace * adjacentFace = _mcBody->GetMCFace(itN->second);
2245 adjacentFace->time = time;
2246 }
2247 }
2248
2249 //---------------------------------------------------------------------------
2250 void MCAA::Simplify()
2251 {
2252 MCTChanges mctChanges;
2253 Simplify2(&mctChanges);
2254 }
2255 //---------------------------------------------------------------------------
2256 void
2257 MCAA::Simplify2( MCTChanges * __mctChanges )
2258 {
2259 int nbFace0, nbFace1;
2260 int nbEdge0, nbEdge1;
2261 int nbVertex0, nbVertex1;
2262
2263 nbFace0 = _mcBody->G21()->GetNodes().size();
2264 nbEdge0 = _mcBody->G21()->GetArcs().size();
2265 nbVertex0=_mcBody->G20()->GetArcs().size();
2266
2267 std::set<MG_SEGMENT*> setSegmentBadTopology;
2268 std::set<MG_NOEUD*> setNodeBadTopology;
2269
2270 char animFilename[] = "";//"c:/gilles/anim.iv";
2271 std::ofstream animFile;
2272 double animTime = 15; double animTimeStep = 15.0f/nbEdge0;
2273 InventorText_MCAA * ivText = NULL;
2274 if ( strlen(animFilename) )
2275 {
2276 animFile.open(animFilename);
2277 ivText = new InventorText_MCAA(this);
2278 ivText->ShowFEMesh = false;
2279 ivText->ShowRefModel = false;
2280 ivText->ShowEdgeIds = false;
2281 ivText->ShowCriteria = false;
2282 ivText->ColorMCEdge = InventorText_MCAA::GlobalSuppressionCriterion;
2283 animFile << ivText->GetText_BeginAnimation(0,animTime);
2284 }
2285
2286 bool result= true;
2287 while ( result )
2288 {
2289 MCTChanges mctChanges;
2290
2291 result = Next2(&mctChanges);
2292 __mctChanges->Merge(mctChanges);
2293 if (ivText)
2294 {
2295 animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2296 animTime+=animTimeStep;
2297 }
2298 // Stop simplification if there remains only 1 MC Edge in the MCBody !
2299 if (_mcBody->G21()->GetArcs().size() == _minMCEdgeCount)
2300 break;
2301
2302
2303 }
2304 _nbE += SimplifyFaceLoop();
2305 if (ivText)
2306 {
2307 animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2308 animTime+=animTimeStep;
2309 }
2310 {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge22){
2311 if (_mcBody->G21()->GetArcs().size() <= 1)
2312 break;
2313 if (CheckIfTopoExists(edge22) == false)
2314 printf("MC Edge ID=%lu not OK\n", edge22->get_id());
2315 }
2316 }
2317 result= true;
2318 while ( result )
2319 {
2320 MCTChanges mctChanges;
2321
2322 result = Next2(&mctChanges);
2323 if (ivText)
2324 {
2325 animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2326 animTime+=animTimeStep;
2327 }
2328 __mctChanges->Merge(mctChanges);
2329 }
2330 _nbC += SimplifyEdgeCollapse();
2331
2332 if (ivText)
2333 {
2334 animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2335 animTime+=animTimeStep;
2336 }
2337 _nbD += SimplifyConstrictedSections();
2338
2339
2340 if (ivText)
2341 {
2342 animTimeStep = 1E9;
2343 animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2344 animTime+=animTimeStep;
2345 animFile << ivText->GetText_EndAnimation();
2346 }
2347
2348
2349
2350 nbFace1 = _mcBody->G21()->GetNodes().size();
2351 nbEdge1 = _mcBody->G21()->GetArcs().size();
2352 nbVertex1=_mcBody->G20()->GetArcs().size();
2353
2354 printf("The initial CAD model contained :\n%d faces\n%d edges\n%d vertices\n", nbFace0,nbEdge0,nbVertex0);
2355 printf("%d edge deleted\n", _nbA);
2356 printf("%d vertex deleted\n", _nbB);
2357 printf("%d edge collapsed\n", _nbC);
2358 printf("%d constricted sections collapsed\n", _nbD);
2359 printf("%d loops deleted\n", _nbE);
2360 printf("The final CAD model contains :\n%d faces\n%d edges\n%d vertices\n", nbFace1,nbEdge1,nbVertex1);
2361 }
2362
2363 int MCAA::SimplifyFaceLoop()
2364 {
2365 int nbLoopDeleted = 0;
2366 int i;
2367 do
2368 {
2369 i = NextSimplifyFaceLoop();
2370 nbLoopDeleted += i;
2371 }
2372 while (i);
2373 return nbLoopDeleted;
2374 }
2375
2376 int MCAA::NextSimplifyFaceLoop()
2377 {
2378 int loopCount = 0;
2379 std::multimap < double , LoopCriteria * > mapLoopCriteria;
2380 {MCBODY_FOR_EACH_MCFACE(_mcBody,face)
2381 {
2382 std::vector < std::vector < MCEdge * > > loops = _mcBody->Face_GetCycles(face);
2383 std::vector < LoopCriteria * > vecLoopCriteria;
2384 for (unsigned itLoop = 0; itLoop < loops.size(); itLoop++)
2385 {
2386 LoopCriteria * crit = new LoopCriteria(this, face, loops[itLoop], 5);
2387 double score = crit->DeletionScore();
2388 mapLoopCriteria.insert ( std::make_pair( score, crit ) );
2389 }
2390 }}
2391
2392
2393 std::multimap < double , LoopCriteria * >::reverse_iterator itHighestScore = mapLoopCriteria.rbegin();
2394 if (itHighestScore != mapLoopCriteria.rend() && itHighestScore->first > 0)
2395 {
2396 LoopCriteria * highestLoopCriteria = itHighestScore->second;
2397
2398 if (_mcBody->Contains(highestLoopCriteria->GetFace()) &&
2399 highestLoopCriteria->DeletionScore() > 0)
2400 {
2401 std::set < MCVertex * > loopVertices;
2402 std::vector < MCEdge* > loop = highestLoopCriteria->GetLoop();
2403 loopCount++;
2404
2405 #define SUPPRESS_ONE_EDGE_OF_SMALL_LOOP
2406 #ifdef SUPPRESS_ONE_EDGE_OF_SMALL_LOOP
2407 MCEdge * mcEdgeMax; double maxL = -1;
2408 MCEdge * mcEdgeMin; double minL = 1E300;
2409 for (unsigned itEdge = 0; itEdge < loop.size(); itEdge ++ )
2410 {
2411 std::vector<MCVertex *> extremities;
2412 MCEdge * mcEdge = loop[itEdge];
2413 _mcBody->Edge_GetVertices(mcEdge, extremities);
2414 for (unsigned i=0; i<extremities.size(); i++)
2415 loopVertices.insert ( extremities [i] );
2416
2417 double L = _ecMap[mcEdge]->GetLength();
2418 if (L > maxL)
2419 {
2420 maxL = L;
2421 mcEdgeMax = loop[itEdge];
2422 }
2423 if (L < minL)
2424 {
2425 minL = L;
2426 mcEdgeMin = loop[itEdge];
2427 }
2428 }
2429
2430 MCTChanges mctChanges3,mctChanges1;
2431 SuppressMCEdge(mcEdgeMin, &mctChanges3);
2432 mctChanges1.Merge(mctChanges3);
2433 #endif
2434
2435 #ifdef SUPPRESS_ALL_EDGES_OF_SMALL_LOOP
2436 for (unsigned itEdge = 0; itEdge < loop.size(); itEdge ++ )
2437 {
2438 MCEdge * mcEdge = loop[itEdge];
2439 std::vector<MCVertex *> extremities;
2440 _mcBody->Edge_GetVertices(mcEdge, extremities);
2441 for (unsigned i=0; i<extremities.size(); i++)
2442 loopVertices.insert ( extremities [i] );
2443
2444 double splitScore, splitPoint[3];
2445 splitScore = highestLoopCriteria->EdgeSplitScore(mcEdge, splitPoint);
2446
2447 MCTChanges mctChanges1;
2448
2449 MCTChanges mctChanges3;
2450 SuppressMCEdge(mcEdge, &mctChanges3);
2451 mctChanges1.Merge(mctChanges3);
2452 }
2453
2454 #endif //#ifdef SUPPRESS_ALL_EDGES_OF_SMALL_LOOP
2455 for (std::set<MCVertex*>::iterator itVertex = loopVertices.begin();
2456 itVertex != loopVertices.end();
2457 itVertex++)
2458 {
2459 MCVertex * mcVertex = *itVertex;
2460 VertexCriteria * vCrit = _vcMap[mcVertex];
2461 if ( vCrit->GetScore() > 0)
2462 {
2463 MCTChanges mctChanges1;
2464 SuppressMCVertex(mcVertex, &mctChanges1);
2465 _nbB++;
2466 }
2467 }
2468 }
2469 }
2470
2471 for ( std::multimap < double , LoopCriteria * >::iterator itLoopCriteria = mapLoopCriteria.begin();
2472 itLoopCriteria != mapLoopCriteria.end();
2473 itLoopCriteria++)
2474 {
2475 LoopCriteria * crit = itLoopCriteria->second;
2476 delete crit;
2477 }
2478
2479 return loopCount;
2480 }
2481
2482 int MCAA::SimplifyEdgeCollapse()
2483 {
2484 bool result;
2485 int counter;
2486
2487 {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge22){
2488 if (_mcBody->G21()->GetArcs().size() <= 1)
2489 break;
2490 if (CheckIfTopoExists(edge22) == false)
2491 printf("MC Edge ID=%lu not OK\n", edge22->get_id());
2492 }
2493 }
2494
2495 counter=0;
2496 do
2497 {
2498 counter++;
2499 MCEdge * collapseEdge = NULL;
2500 MCVertex * deleteVertex = NULL;
2501 double bestScore = 0;
2502
2503 if (_mcBody->G21()->GetArcs().size() <= 1)
2504 break;
2505
2506 {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
2507 {
2508 if (_mcBody->G21()->GetArcs().size() <= 1)
2509 break;
2510
2511 MCVertex * vertex[2];
2512 vertex[0] = (MCVertex * ) edge->get_cosommet1()->get_sommet();
2513 vertex[1] = (MCVertex * ) edge->get_cosommet2()->get_sommet();
2514
2515 for (int i=0; i<2; i++)
2516 {
2517 double score = EdgeCollapseCriteria(edge, vertex[i], this).GetScore();
2518 if (score > bestScore)
2519 {
2520 bestScore = score;
2521 collapseEdge = edge;
2522 deleteVertex = vertex[i];
2523 }
2524 }
2525
2526
2527 }
2528 }
2529
2530 if (collapseEdge&&deleteVertex)
2531 result = CollapseMCEdgeToMCVertex(collapseEdge, deleteVertex);
2532 else
2533 result = false;
2534
2535 } while (result);
2536
2537 {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge22){
2538 if (_mcBody->G21()->GetArcs().size() <= 1)
2539 break;
2540 if (CheckIfTopoExists(edge22) == false)
2541 printf("MC Edge ID=%lu not OK\n", edge22->get_id());
2542 }
2543 }
2544
2545 return counter;
2546 }
2547
2548 bool MCAA::CollapseMCEdgeToMCVertex(MCEdge * collapseEdge, MCVertex * deleteVertex)
2549 {
2550 bool result = true;
2551
2552 result = true;
2553 MCVertex * vertex[2];
2554 vertex[0] = (MCVertex * ) collapseEdge->get_cosommet1()->get_sommet();
2555 vertex[1] = (MCVertex * ) collapseEdge->get_cosommet2()->get_sommet();
2556 MCVertex * targetVertex = (vertex[0]!=deleteVertex)?vertex[0]:vertex[1];
2557 std::set <MCEdge*> setNewEdges, setOldEdges;
2558 std::set <MCEdge*>::iterator itEdge, itEdge2;
2559 _mcBody->ContractEdgeToVertex(collapseEdge, targetVertex, setNewEdges, setOldEdges);
2560
2561 for (itEdge = setOldEdges.begin(); itEdge != setOldEdges.end(); itEdge++)
2562 {
2563 MCEdge * mcEdge = *itEdge;
2564 EC_Delete(mcEdge);
2565
2566 std::vector <MG_SEGMENT*> vecSegs;
2567 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = mcEdge->get_lien_maillage();
2568 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
2569 MG_ELEMENT_MAILLAGE* element2;
2570 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
2571 {
2572 if (_feMesh->contient(element2))
2573 vecSegs.push_back((MG_SEGMENT*)element2);
2574 }
2575
2576 for (std::vector<MG_SEGMENT *>::iterator it = vecSegs.begin();
2577 it != vecSegs.end();
2578 it++)
2579 {
2580 MG_SEGMENT * seg = *it;
2581
2582 _feMesh->supprimer_mg_segmentid(seg->get_id());
2583
2584 for (itEdge2 = setNewEdges.begin(); itEdge2 != setNewEdges.end(); itEdge2++)
2585 {
2586 MCEdge * mcEdge2 = *itEdge2;
2587 mcEdge2->get_lien_maillage()->supprimer(seg);
2588 }
2589 }
2590 }
2591
2592 for (itEdge = setNewEdges.begin(); itEdge != setNewEdges.end(); itEdge++)
2593 DeleteFEMesh(*itEdge);
2594
2595 DeleteFEMesh(deleteVertex);
2596 VC_Delete(deleteVertex);
2597
2598 TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = deleteVertex->get_lien_maillage();
2599 TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
2600 MG_ELEMENT_MAILLAGE* element2;
2601 for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
2602 {
2603 MCEdge * mcEdgeOfDeletedVertex=*(setNewEdges.rbegin());
2604 element2->change_lien_topologie2(mcEdgeOfDeletedVertex);
2605 }
2606
2607 _mcBody->DeleteMCVertex(deleteVertex);
2608 for (itEdge = setOldEdges.begin(); itEdge != setOldEdges.end(); itEdge++)
2609 {
2610 MCEdge * mcEdge = *itEdge;
2611 _mcBody->DeleteMCEdge(mcEdge);
2612 }
2613
2614 for (itEdge = setNewEdges.begin(); itEdge != setNewEdges.end(); itEdge++)
2615 InitializeFEMesh(*itEdge);
2616
2617 for (itEdge = setNewEdges.begin(); itEdge != setNewEdges.end(); itEdge++)
2618 EC_Init(*itEdge);
2619
2620 {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge22){
2621 if (_mcBody->G21()->GetArcs().size() <= 1)
2622 break;
2623 if (CheckIfTopoExists(edge22) == false)
2624 printf("MC Edge ID=%lu not OK\n", edge22->get_id());
2625 }
2626 }
2627
2628
2629 /* std::set<MG_SEGMENT*> setSegmentBadTopology;
2630 std::set<MG_NOEUD*> setNodeBadTopology;
2631 CheckMCMesh( this->GetMCTess(), setSegmentBadTopology, setNodeBadTopology );
2632 CheckMCMesh( this->GetFEMesh(), setSegmentBadTopology, setNodeBadTopology );*/
2633
2634 return result;
2635 }
2636
2637 //---------------------------------------------------------------------------
2638 bool MCAA::Next2( MCTChanges * __mctChanges )
2639 {
2640 bool bSimplifDone = false;
2641 if (!bSimplifDone && _minMCVertexCount < _mcBody->G10()->GetArcs().size() ) bSimplifDone = SuppressNextVertex(__mctChanges);
2642 if (bSimplifDone) _nbB++;
2643 if (!bSimplifDone && _minMCEdgeCount < _mcBody->G10()->GetNodes().size()) { bSimplifDone = SuppressNextEdge2(__mctChanges); if (bSimplifDone) _nbA++; }
2644
2645 return bSimplifDone;
2646 }
2647 //---------------------------------------------------------------------------
2648 bool MCAA::SuppressNextEdge2(MCTChanges * __mctChanges)
2649 {
2650 GlobalEdgeCriteria * ec = GetHighestEdgeDeletionScore();
2651
2652 if (ec == NULL)
2653 return false;
2654
2655 bool bSimplifDone = (ec->DeletionScore() > 1E-3);
2656
2657 if (bSimplifDone)
2658 {
2659 RTChanges rtChanges;
2660 DeleteEdge2(ec->GetEdge(), __mctChanges, &rtChanges);
2661 }
2662
2663 return bSimplifDone;
2664 }
2665 //---------------------------------------------------------------------------
2666 void
2667 MCAA::DeleteEdge2(MCEdge * __mcEdge, MCTChanges * __mctChanges, RTChanges * __rtChanges)
2668 {
2669 int i;
2670 double splitScore = 0, splitPoint[3];
2671 RTChanges rtChanges;
2672 double deletionScore;
2673
2674 GlobalEdgeCriteria * gec=_ecMap[__mcEdge];
2675 splitScore = gec->SplitScore(splitPoint);
2676 if (splitScore > 0)
2677 {
2678 MCTChanges mctChanges;
2679 RTChanges rtChanges;
2680 SplitEdge(__mcEdge, splitPoint, &mctChanges, &rtChanges);
2681 if (mctChanges.E.size() != 0) // Successful split !!!
2682 {
2683 for (std::multimap<MCEdge*,MCEdge*>::iterator itEdge = mctChanges.E.begin();
2684 itEdge != mctChanges.E.end();
2685 itEdge++)
2686 {
2687 if (itEdge->second != NULL) // edge created by SplitEdge()
2688 {
2689 DeleteEdge2(itEdge->second, __mctChanges, __rtChanges);
2690 __mctChanges->Merge(mctChanges);
2691 }
2692 }
2693 }
2694 else // failure : there is 0 edge after split
2695 {
2696 deletionScore=gec->DeletionScore();
2697 if (deletionScore>0)
2698 SuppressMCEdge(__mcEdge, &mctChanges);
2699 __mctChanges->Merge(mctChanges);
2700 }
2701 }
2702 else
2703 {
2704 MCTChanges mctChanges;
2705 deletionScore=gec->DeletionScore();
2706 if (deletionScore>0)
2707 SuppressMCEdge(__mcEdge, &mctChanges);
2708 __mctChanges->Merge(mctChanges);
2709 }
2710 }