ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCAA.cpp
Revision: 27
Committed: Thu Jul 5 15:26:40 2007 UTC (17 years, 10 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_MCAA.cpp
File size: 102284 byte(s)
Log Message:

File Contents

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