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

File Contents

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