ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCAA.cpp
Revision: 569
Committed: Thu Oct 16 14:36:31 2014 UTC (10 years, 6 months ago) by foucault
File size: 97734 byte(s)
Log Message:
Mise à jour pour CAD4FE (Gilles) : operation 1 (tentative)

File Contents

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