ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCAA.cpp
Revision: 176
Committed: Tue May 19 20:56:11 2009 UTC (15 years, 11 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_MCAA.cpp
File size: 107033 byte(s)
Log Message:
Mise à jour :
* CAD4FE
* outil : HypergraphLib qui est maintenant compilable sous Linux (essais mois aout 2008)
* outil : ot_mathematique.cpp suppression d'une méthode de classe inutile nécessaire pour compiler avec CodeGear Builder 2006 OT_VECTEUR_3D::OT_VECTEUR_3D(OT_VECTEUR_3D& mdd)

File Contents

# User Rev Content
1 foucault 27 //---------------------------------------------------------------------------
2    
3     #include <sstream>
4     #include <fstream>
5     #pragma hdrstop
6    
7     //---------------------------------------------------------------------------
8     // include MAGIC Headers
9     #include "gestionversion.h"
10     #include <MG_GEOMETRIE.h>
11     #include <MG_MAILLAGE.h>
12     #include <MG_MAILLAGE_OUTILS.h>
13     #include <MG_GESTIONNAIRE.h>
14     #include <mailleur0d.h>
15     #include <mailleur1d.h>
16     #include <mailleur2d.h>
17     #include <fct_generateur_3d.h>
18     #include <fct_generateur_fichier.h>
19     #include <fct_generateur_constante.h>
20     #include <fct_taille.h>
21     #include <ot_algorithme_geometrique.h>
22    
23     #include "CAD4FE_MCBody.h"
24     #include "CAD4FE_geometric_tools.h"
25     #include "CAD4FE_PolyCurve.h"
26     #include "CAD4FE_PolySurface.h"
27     #include "CAD4FE_MCFace.h"
28     #include "CAD4FE_MCEdge.h"
29     #include "CAD4FE_MCVertex.h"
30     #include "CAD4FE_GlobalEdgeCriteria.h"
31     #include "CAD4FE_LoopCriteria.h"
32     #include "CAD4FE_LocalEdgeCriteria.h"
33     #include "CAD4FE_EdgeCollapseCriteria.h"
34     #include "CAD4FE_VertexCriteria.h"
35     #include "CAD4FE_mg_utils.h"
36     #include "CAD4FE_InventorText_MCAA.h"
37     #include "CAD4FE_InventorText_MG_MAILLAGE.h"
38     #include "CAD4FE_Intersection_Plane_MG_MAILLAGE.h"
39     #include "CAD4FE_Intersection_Plane_MG_SEGMENT.h"
40     #include "CAD4FE_Colormap.h"
41 foucault 64 #include "CAD4FE_Criteria.h"
42     #include "CAD4FE_ShortestPathByClosestPointOnEdge.h"
43     #include "CAD4FE_MCNode.h"
44 foucault 27
45     #include "CAD4FE_MCAA.h"
46     //---------------------------------------------------------------------------
47     #pragma package(smart_init)
48    
49    
50     using namespace CAD4FE;
51    
52     MCAA::MCAA(MG_VOLUME * __refBody, MG_MAILLAGE * __tessellation, MG_GESTIONNAIRE * __gest, MG_GEOMETRIE * __geom)
53     : _refBody(__refBody), _refTess(__tessellation), _refGest(__gest), _geom(__geom), _sizeMap(NULL), _mcTessSegGrid(NULL), _feMesh(NULL)
54     {
55    
56     _mcBody = new MCBody(_geom, __refBody);
57    
58     std::ofstream file;
59     char filename [5000]="";
60     strcat (filename, getenv("TEMP"));
61     strcat (filename, "RefTessellation.iv");
62     file.open(filename);
63     file<<InventorText_MG_MAILLAGE(__tessellation).GetText();
64     file<<"}";
65     file.close();
66    
67     _InitializeMCBodyTessellation();
68    
69     // Setting default meshing parameters :
70     _maxOverdensity = 2;
71     _limitAngle = Criteria::PlanarCurve_BetaEpsilon(.22);
72 foucault 64 SetMinMCEdgeCount(0);
73     SetMinMCVertexCount(1);
74 foucault 27
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 foucault 64 _mcBody->G2ToNeatoFile(_mcBody->G10(), "c:\\gilles\\g10.neato", "c:\\gilles\\g10.neato");
86    
87 foucault 27 /*
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 foucault 64 //---------------------------------------------------------------------------
147     int MCAA::GetMinMCEdgeCount()
148     {
149     return _minMCEdgeCount;
150     }
151     //---------------------------------------------------------------------------
152     void MCAA::SetMinMCEdgeCount(int __minMCEdgeCount)
153     {
154     _minMCEdgeCount = __minMCEdgeCount;
155     }
156     //---------------------------------------------------------------------------
157     int MCAA::GetMinMCVertexCount()
158     {
159     return _minMCVertexCount;
160     }
161     //---------------------------------------------------------------------------
162     void MCAA::SetMinMCVertexCount(int __minMCVertexCount)
163     {
164     _minMCVertexCount=__minMCVertexCount;
165     }
166 foucault 27 // 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 \"%d\" 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 %d 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 %d 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 %d 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 %d : element id %d 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 %d : element id %d 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 %d 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 %d : element id %d NOT ok\n", vertex->get_id(), element->get_id());
413     }
414     }
415     }
416     }
417    
418     //---------------------------------------------------------------------------
419     void MCAA::MergeVertices(MCVertex * __deleteVertex, MCVertex * __targetVertex)
420     {
421     MCVertex * V1 = __deleteVertex;
422     MCVertex * V2 = __targetVertex;
423     std::set<MCEdge*>edges;
424     _mcBody->MergeVertices(V1,V2,edges);
425    
426     std::set<MCEdge*>::iterator itEdge;
427     for (itEdge = edges.begin(); itEdge != edges.end(); itEdge++)
428     {
429     EC_Delete(*itEdge);
430     DeleteFEMesh(*itEdge);
431     }
432     TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = V1->get_lien_maillage();
433     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
434     MG_ELEMENT_MAILLAGE* element2;
435     for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
436     element2->change_lien_topologie(NULL);
437    
438     int N=V1->get_nb_mg_cosommet();
439     for (int i=0; i<N; i++)
440     _geom->supprimer_mg_cosommet(V1->get_mg_cosommet(0));
441     _mcBody->DeleteMCVertex(V1);
442     VC_Delete(V1);
443    
444     for (itEdge = edges.begin(); itEdge != edges.end(); itEdge++)
445     InitializeFEMesh(*itEdge);
446    
447     for (itEdge = edges.begin(); itEdge != edges.end(); itEdge++)
448     EC_Init(*itEdge);
449     }
450     //---------------------------------------------------------------------------
451     void
452     MCAA::_InitializeMCBodyTessellation()
453     {
454     // Duplicate the reference geometry's mesh !
455     _mcTess = _refTess->dupliquer ( _refGest );
456    
457     long id_ref_to_mc = _mcTess->get_id() - _refTess->get_id();
458    
459     // update the link of tessellation entities of the MC Body Tessellation
460     {
461     MCBODY_FOR_EACH_MCFACE(_mcBody, mcFace)
462     {
463     const std::set<MG_FACE *> & lst_ref_faces = mcFace->GetPolySurface()->GetRefFaces();
464     for (std::set<MG_FACE *>::const_iterator it_ref_face = lst_ref_faces.begin();
465     it_ref_face != lst_ref_faces.end();
466     it_ref_face ++ )
467     {
468     MG_FACE * refFace = *it_ref_face;
469    
470     TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = refFace->get_lien_maillage();
471     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
472     MG_ELEMENT_MAILLAGE* element2;
473     for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
474     {
475     if (_refTess->contient(element2))
476     {
477     MG_TRIANGLE * ref_triang = (MG_TRIANGLE *) element2;
478     MG_TRIANGLE * mc_triang = _mcTess->get_mg_triangleid ( ref_triang->get_id() + id_ref_to_mc );
479    
480     mc_triang->change_lien_topologie ( mcFace );
481    
482     MG_SEGMENT * segs[3];
483     MG_NOEUD * nos[3];
484     MG_TRIANGLE_GET_SEGMENTS(mc_triang,segs);
485     MG_TRIANGLE_GET_NOEUDS(mc_triang,nos);
486     for (int i=0;i<3;i++)
487     {
488     if (!segs[i]->get_lien_topologie() || segs[i]->get_lien_topologie()->get_dimension() == 2)
489     segs[i]->change_lien_topologie2(mcFace);//change_lien_topologie_mct(segs[i],mapRefToMCFace,mapRefToMCEdge,mapRefToMCVertex);
490     if (! nos[i]->get_lien_topologie() || nos[i]->get_lien_topologie()->get_dimension() == 2)
491     nos[i]->change_lien_topologie2(mcFace);//change_lien_topologie_mct(nos[i],mapRefToMCFace,mapRefToMCEdge,mapRefToMCVertex);
492     }
493     }
494    
495     }
496     }
497     }}
498    
499     {
500     MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
501     {
502     const std::vector<MG_ARETE *> & lst_ref_edges = edge->GetPolyCurve()->GetRefEdges();
503     for (std::vector<MG_ARETE *>::const_iterator it_ref_edge = lst_ref_edges.begin();
504     it_ref_edge != lst_ref_edges.end();
505     it_ref_edge ++ )
506     {
507     MG_ARETE * ref_edge = *it_ref_edge;
508    
509     TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = ref_edge->get_lien_maillage();
510     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
511     MG_ELEMENT_MAILLAGE* element2;
512     int counter = 0;
513     for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
514     {
515     if (_refTess->contient(element2))
516     {
517     MG_SEGMENT * ref_seg = (MG_SEGMENT *) element2;
518    
519     if ( ! ref_seg ) continue;
520    
521     MG_SEGMENT * mc_seg = _mcTess->get_mg_segmentid ( ref_seg->get_id() + id_ref_to_mc );
522     mc_seg->change_lien_topologie( edge );
523    
524     MG_NOEUD * nos[2];
525     nos[0] = mc_seg->get_noeud1();
526     nos[1] = mc_seg->get_noeud2();
527     for (int i=0;i<2;i++)
528     if (! nos[i]->get_lien_topologie() || nos[i]->get_lien_topologie()->get_dimension() > 0)
529     nos[i]->change_lien_topologie2(edge);
530    
531     counter++;
532     }
533     }
534     if (counter == 0)
535     printf("warning : no segments are connected to ref edge id=(%d,%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 foucault 176 nb_steps[i] = std::min(floor((_bbox[i+3]-_bbox[i])/cellSize),40.0);
579 foucault 27 else
580     nb_steps[i] = 40;
581    
582     if (nb_steps[i] == 0)
583     nb_steps[i] ++;
584     }
585 foucault 176 MG_UTILS utils;
586     utils.TPL_GRILLE_Construct<MG_SEGMENT*>(_bbox, nb_steps, *_mcTessSegGrid);
587 foucault 27
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 %d\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 %d\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,__mcEdge,_sizeMap);
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 %d FE mesh elements on the MC Edge %d\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 %d 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 %d 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 francois 35 n = new MG_NOEUD(__mcVertex,coo[0],coo[1],coo[2],MAILLEUR_AUTO);
800 foucault 27 _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 %d\n", vertex->get_id() );
831     double coo[3];
832     vertex->get_point()->evaluer(coo);
833 francois 35 MG_NOEUD* n = new MG_NOEUD(vertex,coo[0],coo[1],coo[2],MAILLEUR_AUTO);
834 foucault 27 _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 %d\n",edge->get_id());
846     MAILLEUR1D m1d(_feMesh,_geom,edge,_sizeMap);
847     m1d.maille();
848     }
849     }
850    
851    
852     printf("MAILLAGE 2D\n");
853     {
854     MAILLEUR2D::priorite_metrique=.65;
855     for (unsigned it_face = 0; it_face != _geom->get_nb_mg_face(); it_face++)
856     {
857     MG_FACE * face = _geom->get_mg_face(it_face);
858     printf(" MC face %d\n",face->get_id());
859     MAILLEUR2D m2d(_feMesh,_geom,face,_sizeMap);
860     m2d.maille();
861     }
862     }
863    
864     }
865     //---------------------------------------------------------------------------
866     MG_MAILLAGE *
867     MCAA::GetFEMesh () const
868     {
869     return _feMesh;
870     }
871     //---------------------------------------------------------------------------
872     void
873     MCAA::UseDefaultMeshSize()
874     {
875     // Setting the default Size Map
876     double s = CalculateDefaultMeshSize();
877     printf (" Mesh size set to default value = %f\n", s);
878     SetConstantMeshSize ( s );
879     Update();
880     }
881     //---------------------------------------------------------------------------
882     void MCAA::ReadSizeMapFile(const char * __filename)
883     {
884     FCT_GENERATEUR_3D<4> * sizeMap = new FCT_GENERATEUR_3D<4>;
885     sizeMap->lire((char*)__filename);
886     if (_sizeMap)
887     delete _sizeMap;
888     _sizeMap = sizeMap;
889    
890     Update();
891     }
892     //---------------------------------------------------------------------------
893     void MCAA::SetSizeMap(FCT_TAILLE * __sizeMap)
894     {
895     if (_sizeMap)
896     delete _sizeMap;
897     _sizeMap = __sizeMap;
898     Update();
899     }
900     //---------------------------------------------------------------------------
901     void MCAA::ReadSizeMapRefinementFile(const char * __filename)
902     {
903     // Setting the default Size Map
904     double s = CalculateDefaultMeshSize();
905     FCT_GENERATEUR_FICHIER * sizeMap = new FCT_GENERATEUR_FICHIER((char*)__filename, s);
906     _sizeMap = sizeMap;
907     sizeMap->construit();
908     char outfilename[10000]="";
909     sprintf(outfilename,"%s.ctt",__filename);
910     sizeMap->enregistrer(outfilename);
911     sprintf(outfilename,"%s.ctt","c:\\gilles\\mcbody.magic");
912     sizeMap->enregistrer(outfilename);
913    
914     Update();
915     }
916     //---------------------------------------------------------------------------
917     void
918     MCAA::SetConstantMeshSize(double __meshSize)
919     {
920     if (_sizeMap)
921     delete _sizeMap;
922    
923     char outputfilename[]="c:\\gilles\\mcbody.magic.ctt";
924     _sizeMap = new FCT_GENERATEUR_CONSTANTE ( *_refGest, __meshSize );
925     ((FCT_GENERATEUR_CONSTANTE*)_sizeMap)->construit(_bbox[0],_bbox[1],_bbox[2],_bbox[0+3],_bbox[1+3],_bbox[2+3]);
926     ((FCT_GENERATEUR_CONSTANTE*)_sizeMap)->enregistrer(outputfilename);
927     }
928    
929     //---------------------------------------------------------------------------
930     double
931     MCAA::CalculateDefaultMeshSize ()
932     {
933     // Default Size = .3 * Volume / Surface
934     double V, S;
935     V = MG_UTILS::MG_MAILLAGE_GetVolume(_mcTess);
936     S = MG_UTILS::MG_MAILLAGE_GetSurface(_mcTess);
937     printf("Volume = %f\n", V );
938     printf("Surface = %f\n", S );
939     return .3 * V / S;
940     }
941    
942     //---------------------------------------------------------------------------
943     void MCAA::GetBoundingBox(double __bbox[6]) const
944     {
945     for (unsigned i = 0; i<6; i++)
946     __bbox[i] = _bbox[i];
947     }
948    
949     //---------------------------------------------------------------------------
950     double
951     MCAA::GetSize(double __xyz[3])
952     {
953     if (_sizeMap == NULL)
954     return 0;
955    
956     double density_tensor[9];
957     _sizeMap->evaluer(__xyz, density_tensor);
958     return pow(density_tensor[0], -0.5);
959     }
960     //---------------------------------------------------------------------------
961     double
962     MCAA::GetMinSize(double __xyz[3])
963     {
964     return GetSize(__xyz) / GetMaxOverdensity();
965     }
966     //---------------------------------------------------------------------------
967     MG_SEGMENT * MCAA::_FindClosestSeg(TPL_MAP_ENTITE<MG_SEGMENT *> & __lstSegs, MCEdge * __mcEdge, double __P[3], double __N[3])
968     {
969     // minimum distance found between the tess edge and P
970     double min_distanceFrom_P = 9E99;
971     // vertices of the edge which are closest to edgePnt
972     MG_SEGMENT * closest_seg = NULL;
973    
974     TPL_MAP_ENTITE<MG_SEGMENT *>::ITERATEUR itSeg;
975     for (MG_SEGMENT * seg = __lstSegs.get_premier(itSeg);
976     seg;
977     seg = __lstSegs.get_suivant(itSeg))
978     {
979     Intersection_Plane_MG_SEGMENT intersection ( __P, __N, seg, 1E-12);
980    
981     if (intersection.Test () )
982     {
983     intersection.Find();
984    
985     if (__mcEdge != seg->get_lien_topologie() || intersection.GetSegmentT() < 0 || intersection.GetSegmentT() > 1)
986     continue;
987    
988     double intersectionPt [3];
989     intersection.GetPoint( intersectionPt );
990     double distance = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3 ( intersectionPt, __P );
991    
992     if (distance < min_distanceFrom_P)
993     {
994     min_distanceFrom_P = distance;
995     closest_seg = seg;
996     }
997     }
998     }
999    
1000     return closest_seg;
1001     }
1002    
1003     //---------------------------------------------------------------------------
1004     MG_SEGMENT * MCAA::FindClosestSeg(MCEdge * __mcEdge, double __P[3], double __N[3])
1005     {
1006     TPL_MAP_ENTITE<MG_SEGMENT *> lstSegs;
1007     _mcTessSegGrid->rechercher( __P[0], __P[1], __P[2], GetSize(__P), lstSegs);
1008     return _FindClosestSeg(lstSegs, __mcEdge, __P, __N);
1009     }
1010     //---------------------------------------------------------------------------
1011     void MCAA::EC_Init(MCEdge * __mcEdge)
1012     {
1013     // arguments : _mcBody, __mcEdge, _feMesh, __mcTess, _mcTessSegGrid,
1014     GlobalEdgeCriteria * gec = new GlobalEdgeCriteria(__mcEdge, this);
1015     gec->Init();
1016     _ecMap.insert( std::make_pair(__mcEdge,gec) );
1017     }
1018     //---------------------------------------------------------------------------
1019     void MCAA::EC_ChangeTopo(MCEdge * __old, MCEdge * __new)
1020     {
1021     GlobalEdgeCriteria * old_gec, * new_gec;
1022     ECMapIterator it_ec = _ecMap.find(__old);
1023    
1024     if ( it_ec != _ecMap.end() )
1025     {
1026     old_gec = it_ec->second;
1027     }
1028     else
1029     return;
1030    
1031     it_ec = _ecMap.find(__new);
1032     if ( it_ec != _ecMap.end() )
1033     {
1034     new_gec = it_ec->second;
1035     }
1036     else
1037     {
1038     new_gec = new GlobalEdgeCriteria (__new, this);
1039     _ecMap.insert( std::make_pair(__new,new_gec) );
1040     }
1041    
1042     new_gec->ChangeTopo(old_gec);
1043     }
1044     //---------------------------------------------------------------------------
1045     void MCAA::EC_Delete(MCEdge * __mcEdge)
1046     {
1047     ECMapIterator it_ec = _ecMap.find(__mcEdge);
1048    
1049     if ( it_ec != _ecMap.end() )
1050     {
1051     GlobalEdgeCriteria * gec = it_ec->second;
1052     delete gec;
1053     _ecMap.erase (it_ec);
1054     }
1055     else
1056     {
1057     for (it_ec = _ecMap.begin();
1058     it_ec != _ecMap.end();
1059     it_ec ++)
1060     {
1061     GlobalEdgeCriteria * gec = it_ec->second;
1062     if (gec->GetEdge() == __mcEdge)
1063     {
1064     delete gec;
1065     _ecMap.erase (it_ec);
1066     it_ec = _ecMap.begin();
1067     }
1068     }
1069    
1070     }
1071     /*
1072     ECMapIterator it_ec;
1073    
1074     for (it_ec = _ecMap.find(__mcEdge);
1075     it_ec != _ecMap.end();
1076     it_ec = _ecMap.find(__mcEdge))
1077     {
1078     //for (; it_ec->first == __mcEdge ; it_ec++ )
1079     {
1080     EdgeCriteria * ec = it_ec->second;
1081     if (ec) delete ec;
1082     _ecMap.erase (it_ec);
1083     }
1084     }
1085    
1086     SupprEdgeScoreMapIterator it_ESMap = _map_supprEdgeScore.find(__mcEdge);
1087     if (it_ESMap != _map_supprEdgeScore.end())
1088     _map_supprEdgeScore.erase(it_ESMap); */
1089     }
1090    
1091     //---------------------------------------------------------------------------
1092     void MCAA::EC_Update(MCEdge * __mcEdge)
1093     {
1094     ECMapIterator it_ec = _ecMap.find(__mcEdge);
1095     if (it_ec != _ecMap.end())
1096     {
1097     GlobalEdgeCriteria * ec = it_ec->second;
1098     // update local edge criteria
1099     // while keeping the normal offset polyline
1100     ec->Update(true);
1101     _ecMap.erase(it_ec);
1102     _ecMap.insert( std::make_pair(ec->GetEdge(),ec) );
1103     }
1104     else
1105     printf("_ecMap.end() !\n");
1106     }
1107     //---------------------------------------------------------------------------
1108     void MCAA::EC_Init()
1109     {
1110     printf("Initializing edge local properties \n");
1111     {
1112     MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
1113     {
1114     printf(" Edge local properties of MC edge %d\n",edge->get_id());
1115     EC_Delete(edge);
1116     EC_Init(edge);
1117     }
1118     }
1119     }
1120    
1121     //---------------------------------------------------------------------------
1122     std::vector <LocalEdgeCriteria *>
1123     MCAA::EC_Get(MCEdge * __mcEdge)
1124     {
1125     std::vector <LocalEdgeCriteria *> res;
1126     ECMapIterator it_ec = _ecMap.find(__mcEdge);
1127     if (it_ec != _ecMap.end())
1128     {
1129     GlobalEdgeCriteria * ec = it_ec->second;
1130     res = ec->GetLocalEdgeCriteria();
1131     }
1132     else
1133     printf("_ecMap.end() !\n");
1134    
1135     return res;
1136     }
1137     //---------------------------------------------------------------------------
1138     GlobalEdgeCriteria * MCAA::GetGlobalEdgeCriteria(MCEdge * __mcEdge)
1139     {
1140     ECMapIterator it_ec = _ecMap.find(__mcEdge);
1141     if (it_ec != _ecMap.end())
1142     {
1143     return it_ec->second;
1144     }
1145     else
1146     {
1147     return NULL;
1148     }
1149     }
1150     //---------------------------------------------------------------------------
1151     GlobalEdgeCriteria * MCAA::GetHighestEdgeDeletionScore()
1152     {
1153     GlobalEdgeCriteria * BestDeletionEC = NULL;
1154     double bestscore = 0;
1155    
1156     ECMapIterator it_ec;
1157     for (it_ec = _ecMap.begin();
1158     it_ec != _ecMap.end();
1159     it_ec++)
1160     {
1161 foucault 64 MCEdge * mcEdge = it_ec->first;
1162 foucault 27 GlobalEdgeCriteria * ec = it_ec->second;
1163     double score = ec->DeletionScore();
1164    
1165 foucault 64 if (mcEdge != ec->GetEdge())
1166     continue;
1167    
1168 foucault 27 if ( !BestDeletionEC ||
1169     score>bestscore )
1170     {
1171     BestDeletionEC = ec;
1172     bestscore = score;
1173     }
1174     }
1175    
1176     if ( bestscore < 1E-3 )
1177     {
1178     bestscore = 0;
1179     BestDeletionEC = NULL;
1180     }
1181    
1182     return BestDeletionEC;
1183     }
1184    
1185     //---------------------------------------------------------------------------
1186     VertexCriteria * MCAA::GetHighestVCScore()
1187     {
1188     VertexCriteria * vc = NULL;
1189     double highestScore = -1E308;
1190    
1191     for (VCMapCIterator itVC = _vcMap.begin();
1192     itVC != _vcMap.end();
1193     itVC++)
1194     {
1195     if (vc == NULL)
1196     {
1197     vc = itVC->second;
1198     }
1199     else if (itVC->second->GetScore() > highestScore)
1200     {
1201     MCVertex * mcVertex = itVC->second->GetVertex();
1202    
1203     if (_mapSuppressRefVertexCount.find(mcVertex->GetRefVertex()) == _mapSuppressRefVertexCount.end() ||
1204     _mapSuppressRefVertexCount[mcVertex->GetRefVertex()] < 4 )
1205     {
1206     vc = itVC->second;
1207     highestScore = vc->GetScore();
1208     }
1209     }
1210     }
1211    
1212     return vc;
1213     }
1214    
1215     //---------------------------------------------------------------------------
1216     void
1217     MCAA::VC_Init()
1218     {
1219     {
1220     MCBODY_FOR_EACH_MCVERTEX(_mcBody, vertex)
1221     {
1222     printf(" Vertex local properties of MC vertex %d\n",vertex->get_id());
1223     VC_Delete(vertex);
1224     VC_Init(vertex);
1225     }
1226     }
1227     }
1228    
1229     //---------------------------------------------------------------------------
1230     void MCAA::VC_Init(MCVertex * __mcVertex)
1231     {
1232     double xyz[3];
1233     __mcVertex->get_point()->evaluer(xyz);
1234     VertexCriteria * vc = new VertexCriteria(__mcVertex, this);
1235     _vcMap [ __mcVertex ] = vc;
1236     }
1237    
1238     //---------------------------------------------------------------------------
1239     void MCAA::VC_Delete(MCVertex * __mcVertex)
1240     {
1241     VCMapIterator itV = _vcMap.find(__mcVertex);
1242     if ( itV != _vcMap.end())
1243     {
1244     delete itV->second;
1245     _vcMap.erase(itV);
1246     }
1247     }
1248     //---------------------------------------------------------------------------
1249    
1250     VertexCriteria * MCAA::VC_Get(MCVertex * __mcVertex)
1251     {
1252     VCMapCIterator it = _vcMap.find(__mcVertex);
1253     if (it != _vcMap.end() )
1254     {
1255     return it->second;
1256     }
1257     else
1258     {
1259     printf("Warning : did not find the vertex properties of vertex %x id = %d\n", __mcVertex, __mcVertex->get_id());
1260     return NULL;
1261     }
1262     }
1263    
1264     //---------------------------------------------------------------------------
1265     /*void
1266     MCAA::Simplify( MCTChanges * __mctChanges )
1267     {
1268     std::set<MG_SEGMENT*> setSegmentBadTopology;
1269     std::set<MG_NOEUD*> setNodeBadTopology;
1270     bool result= true;
1271    
1272     //CheckMCMesh( this->GetMCTess(), setSegmentBadTopology, setNodeBadTopology );
1273     //CheckMCMesh( this->GetFEMesh(), setSegmentBadTopology, setNodeBadTopology );
1274    
1275     while ( result )
1276     {
1277     MCTChanges mctChanges;
1278    
1279     result = Next(&mctChanges);
1280    
1281     // CheckMCMesh( this->GetMCTess(), setSegmentBadTopology, setNodeBadTopology );
1282     // CheckMCMesh( this->GetFEMesh(), setSegmentBadTopology, setNodeBadTopology );
1283    
1284    
1285     }
1286     } */
1287    
1288     //---------------------------------------------------------------------------
1289     /*bool MCAA::Next( MCTChanges * __mctChanges )
1290     {
1291     bool bSimplifDone = false;
1292     if (!bSimplifDone) bSimplifDone = SplitEdgesAtIncompatibleLocalCriteria(__mctChanges);
1293     if (!bSimplifDone) bSimplifDone = SuppressNextVertex(__mctChanges);
1294     if (!bSimplifDone) bSimplifDone = SuppressNextEdge(__mctChanges);
1295    
1296     return bSimplifDone;
1297     } */
1298    
1299     //---------------------------------------------------------------------------
1300     /*bool MCAA::SuppressNextEdge(MCTChanges * __mctChanges)
1301     {
1302     GlobalEdgeCriteria * ec = GetHighestEdgeDeletionScore();
1303    
1304     if (ec == NULL)
1305     return false;
1306    
1307     bool bSimplifDone = (ec->DeletionScore() > 1E-3);
1308    
1309     if (bSimplifDone)
1310     {
1311     SuppressMCEdge(ec->GetEdge(), __mctChanges);
1312     }
1313    
1314     return bSimplifDone;
1315     }*/
1316    
1317     //---------------------------------------------------------------------------
1318     bool MCAA::SuppressNextVertex(MCTChanges * __mctChanges)
1319     {
1320     VertexCriteria * vc = GetHighestVCScore();
1321    
1322     if (vc == NULL)
1323     return false;
1324    
1325     bool bSimplifDone = (vc->GetScore() > 1E-3);
1326     if (bSimplifDone)
1327     {
1328     SuppressMCVertex(vc->GetVertex(), __mctChanges);
1329     vc = GetHighestVCScore();
1330     }
1331    
1332     return bSimplifDone;
1333     }
1334     //---------------------------------------------------------------------------
1335     bool MCAA::Node_Segment_Same_Face(MG_NOEUD * __n, MG_SEGMENT * __seg, std::set <MCFace *> & __commonFaces)
1336     {
1337     Graph::Arc * segEdge_G21Arc = _mcBody->G21()->GetArc(__seg->get_lien_topologie()->get_id());
1338    
1339     for (int i=0; i<__n->get_lien_segment()->get_nb(); i++)
1340     {
1341     MG_SEGMENT * seg = __n->get_lien_segment()->get(i);
1342     MG_ARETE * edge = (MG_ARETE *) seg->get_lien_topologie();
1343    
1344     Graph::Arc *G21Arc = _mcBody->G21()->GetArc(edge->get_id());
1345     for (Graph::Arc::MultimapNodesById::const_iterator itNode = G21Arc->Nodes().begin(); itNode != G21Arc->Nodes().end(); itNode++)
1346     if ( segEdge_G21Arc->Nodes().find(itNode->first) != segEdge_G21Arc->Nodes().end() )
1347     __commonFaces.insert( _mcBody->GetMCFace(itNode->second) );
1348     }
1349    
1350     return (__commonFaces.size() != 0);
1351     }
1352    
1353     /*MG_MAILLAGE * MCAA::FaceBoundaryMesh(MG_MAILLAGE * __mesh, MCFace * __face)
1354     {
1355     Graph::Node * F_G21Node = _mcBody->G21()->GetNode(__face->get_id());
1356     Graph::Node::MultimapArcsById & F_G21NodeArcs = F_G21Node->IncidentArcs();
1357    
1358     std::set <MG_NOEUD * > nodes;
1359     std::set <MG_SEGMENT *> segs;
1360    
1361     LISTE_MG_SEGMENT::iterator it_seg;
1362     for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1363     seg; seg =__mesh->get_suivant_segment(it_seg))
1364     {
1365     int seg_Topo_Id = seg->get_lien_topologie()->get_id();
1366     if (F_G21NodeArcs.find(seg_Topo_Id) != F_G21NodeArcs.end())
1367     {
1368     nodes.insert(seg->get_noeud1());
1369     nodes.insert(seg->get_noeud2());
1370     segs.insert(seg);
1371     }
1372     }
1373    
1374     std::map <MG_NOEUD * , MG_NOEUD *> mapNodes;
1375    
1376    
1377     MG_MAILLAGE * newMesh = new MG_MAILLAGE(_geom);
1378     _refGest->ajouter_mg_maillage(newMesh);
1379    
1380     for (std::set<MG_NOEUD*>::iterator itNode = nodes.begin();
1381     itNode != nodes.end();
1382     itNode ++)
1383     {
1384     MG_NOEUD * n = *itNode;
1385     MG_NOEUD * newNode = newMesh->ajouter_mg_noeud(NULL, n->get_x(), n->get_y(), n->get_z());
1386     newNode->change_lien_topologie2(n->get_lien_topologie());
1387     mapNodes [ n ] = newNode;
1388     }
1389    
1390     for (std::set<MG_SEGMENT*>::iterator itSeg = segs.begin();
1391     itSeg != segs.end();
1392     itSeg ++)
1393     {
1394     MG_SEGMENT * seg = *itSeg;
1395     MG_SEGMENT * newSeg = newMesh->ajouter_mg_segment(NULL, mapNodes[seg->get_noeud1()], mapNodes[seg->get_noeud2()]);
1396     newSeg->change_lien_topologie2(seg->get_lien_topologie());
1397     }
1398    
1399     return newMesh;
1400     } */
1401    
1402     Graph::Graph * MCAA::FaceBoundaryMesh(MG_MAILLAGE * __mesh, MCFace * __face, std::set <MG_NOEUD * > & nodes, std::set <MG_SEGMENT *> & segs)
1403     {
1404     Graph::Graph * faceBoundaryMeshGraph = new Graph::Graph();
1405     nodes.clear();
1406     segs.clear();
1407    
1408     Graph::Node * F_G21Node = _mcBody->G21()->GetNode(__face->get_id());
1409     Graph::Node::MultimapArcsById & F_G21NodeArcs = F_G21Node->IncidentArcs();
1410    
1411     LISTE_MG_SEGMENT::iterator it_seg;
1412     for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1413     seg; seg =__mesh->get_suivant_segment(it_seg))
1414     {
1415     int seg_Topo_Id = seg->get_lien_topologie()->get_id();
1416     if (F_G21NodeArcs.find(seg_Topo_Id) != F_G21NodeArcs.end())
1417     {
1418     nodes.insert(seg->get_noeud1());
1419     nodes.insert(seg->get_noeud2());
1420     segs.insert(seg);
1421     }
1422     }
1423    
1424     for ( std::set<MG_SEGMENT*>::iterator itSeg = segs.begin();
1425     itSeg != segs.end();
1426     itSeg ++)
1427     {
1428     MG_SEGMENT * seg = *itSeg;
1429     Graph::Node * graphNode = faceBoundaryMeshGraph->AddNode(seg->get_id());
1430     graphNode->SetUserData(seg);
1431     graphNode->SetUserData(2,__mesh);
1432     }
1433    
1434     for (std::set<MG_NOEUD*>::iterator itNode = nodes.begin();
1435     itNode != nodes.end();
1436     itNode ++)
1437     {
1438     MG_NOEUD * n = *itNode;
1439     std::multimap< int, Graph::Node * > arcNodes;
1440    
1441     TPL_LISTE_ENTITE< class MG_SEGMENT * > * adjSegList = n->get_lien_segment();
1442     int nbAdjSeg = adjSegList->get_nb();
1443     for (int i=0; i<nbAdjSeg; i++)
1444     {
1445     MG_SEGMENT * seg = adjSegList->get(i);
1446     Graph::Node * graphNode = faceBoundaryMeshGraph->GetNode(seg->get_id());
1447     if (graphNode)
1448     arcNodes.insert(std::make_pair(graphNode->Id(), graphNode));
1449     }
1450     Graph::Arc * graphArc = faceBoundaryMeshGraph->AddArc(n->get_id(), arcNodes);
1451     graphArc->SetUserData(n);
1452     graphArc->SetUserData(2,__mesh);
1453     }
1454    
1455     return faceBoundaryMeshGraph;
1456     }
1457    
1458     //---------------------------------------------------------------------------
1459     int MCAA::SimplifyConstrictedSections()
1460     {
1461     int result = 0;
1462     {MCBODY_FOR_EACH_MCFACE(_mcBody, face)
1463     {
1464     bool stop = false;
1465     while (stop == false)
1466     {
1467     bool done = ProcessNextConstrictedSectionInFace(face);
1468     if (done)
1469     {
1470     result++;
1471     }
1472     else
1473     {
1474     stop = true;
1475     }
1476     }
1477     }
1478     }
1479     return result;
1480     }
1481    
1482     bool MCAA::ProcessNextConstrictedSectionInFace(MCFace * __mcFace)
1483     {
1484     // std::map<MCFace *, Graph::Graph *> faceBoundaryMesh;
1485     std::set <MG_NOEUD * > nodes;
1486     std::set <MG_SEGMENT *> segs;
1487    
1488     MCFace * face = __mcFace;
1489     Graph::Graph * G = FaceBoundaryMesh(_feMesh, face, nodes, segs);
1490    
1491     ConstrictedSection cs,cs2,cs3;
1492     MG_NOEUD *no2,*no3;
1493     for (std::set <MG_NOEUD * >::iterator itNo = nodes.begin();
1494     itNo != nodes.end();
1495     itNo++)
1496     {
1497     MG_NOEUD * no = *itNo;
1498    
1499     if (NodeConstrictedSection(face, no, cs, G))
1500     {
1501     MCVertex *V1, *V2;
1502    
1503     {
1504     MCEdge * edge = 0;
1505     if (no->get_lien_topologie()->get_dimension() > 0)
1506     {
1507     edge = (MCEdge*)no->get_lien_topologie();
1508     if (((MCVertex*)edge->get_cosommet1()->get_sommet())->GetMergedRefVertices().size() > 0)
1509     continue;
1510     if (((MCVertex*)edge->get_cosommet2()->get_sommet())->GetMergedRefVertices().size() > 0)
1511     continue;
1512     }
1513     if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() > 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() > 0)
1514     {
1515     edge = (MCEdge*)cs.Seg1->get_lien_topologie();
1516     if (((MCVertex*)edge->get_cosommet1()->get_sommet())->GetMergedRefVertices().size() > 0)
1517     continue;
1518    
1519     if (((MCVertex*)edge->get_cosommet2()->get_sommet())->GetMergedRefVertices().size() > 0)
1520     continue;
1521     }
1522     }
1523    
1524     // if node is not on a vertex, then insert a vertex on node
1525     if (no->get_lien_topologie()->get_dimension() > 0)
1526     {
1527     MCEdge * edge = (MCEdge*)no->get_lien_topologie();
1528    
1529     MCTChanges mctChanges;
1530     RTChanges rtChanges;
1531     SplitEdge(edge, no->get_coord(), &mctChanges, &rtChanges);
1532     V1 = (mctChanges.V.begin())->second;
1533     }
1534     else // V1 = this vertex
1535     {
1536     V1 = (MCVertex *)no->get_lien_topologie();
1537     }
1538     // if the extremities of the segment are not on a vertex, then insert a vertex
1539     // on the closest point
1540     if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() > 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() > 0)
1541     {
1542     MCEdge * edge = (MCEdge*)cs.Seg1->get_lien_topologie();
1543     MCTChanges mctChanges;
1544     RTChanges rtChanges;
1545     SplitEdge(edge, cs.Seg1P, &mctChanges, &rtChanges);
1546     V2 = (mctChanges.V.begin())->second;
1547     }
1548     else // V2 = this vertex
1549     {
1550     if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() == 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() == 0 )
1551     {
1552     double dist1 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(cs.Seg1->get_noeud1()->get_coord(), cs.Seg1P);
1553     double dist2 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(cs.Seg1->get_noeud2()->get_coord(), cs.Seg1P);
1554     if(dist1<dist2)
1555     V2 = (MCVertex *) cs.Seg1->get_noeud1()->get_lien_topologie();
1556     else
1557     V2 = (MCVertex *) cs.Seg1->get_noeud2()->get_lien_topologie();
1558     }
1559     else if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() == 0)
1560     V2 = (MCVertex *) cs.Seg1->get_noeud1()->get_lien_topologie();
1561     else if (cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() == 0)
1562     V2 = (MCVertex *) cs.Seg1->get_noeud2()->get_lien_topologie();
1563     }
1564     // Merge vertices V1 with V2
1565     std::set<MCEdge*> edges;
1566     std::set<MCEdge*>::iterator itEdge;
1567     MergeVertices(V1,V2);
1568    
1569     delete G;
1570     return true;
1571     }
1572     }
1573     delete G;
1574     return false;
1575     }
1576    
1577     //---------------------------------------------------------------------------
1578     /*bool MCAA::ProcessConstrictedSection()
1579     {
1580     std::map<MCFace *, MG_MAILLAGE *> faceBoundaryMesh;
1581     {MCBODY_FOR_EACH_MCFACE(_mcBody, face)
1582     {
1583     MG_MAILLAGE * mesh = FaceBoundaryMesh(_feMesh, face);
1584    
1585     ConstrictedSection cs,cs2,cs3;
1586     MG_NOEUD *no2,*no3;
1587     LISTE_MG_NOEUD::iterator it_no;
1588     for (MG_NOEUD* no = mesh->get_premier_noeud(it_no);
1589     no; no = mesh->get_suivant_noeud(it_no))
1590     {
1591     double LMin=GetSize(no->get_coord())/GetMaxOverdensity();
1592    
1593     TPL_MAP_ENTITE<MG_SEGMENT *> lstSegs;
1594     LISTE_MG_SEGMENT::iterator it_seg;
1595     for (MG_SEGMENT * seg = mesh->get_premier_segment(it_seg);
1596     seg;
1597     seg = mesh->get_suivant_segment(it_seg))
1598     {
1599     MG_NOEUD * n1 = seg->get_noeud1();
1600     MG_NOEUD * n2 = seg->get_noeud2();
1601     if (n1 == no || n2 == no)
1602     continue;
1603     double * S1P0 = n1->get_coord();
1604     double * S1P1 = n2->get_coord();
1605     double * P = no->get_coord();
1606    
1607     double P2[3];
1608     OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_3d(S1P0,S1P1,P,P2);
1609     if(OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(P2,P) <= LMin)
1610     lstSegs.ajouter(seg);
1611     }
1612    
1613    
1614     if (NodeConstrictedSection(face, no, cs, lstSegs, mesh))
1615     {
1616     MCVertex *V1, *V2;
1617     // if node is not on a vertex, then insert a vertex on node
1618     if (no->get_lien_topologie()->get_dimension() > 0)
1619     {
1620     MCEdge * edge = (MCEdge*)no->get_lien_topologie();
1621    
1622     if (((MCVertex*)edge->get_cosommet1()->get_sommet())->GetMergedRefVertices().size() > 0)
1623     continue;
1624    
1625     if (((MCVertex*)edge->get_cosommet2()->get_sommet())->GetMergedRefVertices().size() > 0)
1626     continue;
1627    
1628    
1629     MCTChanges mctChanges;
1630     RTChanges rtChanges;
1631     SplitEdge(edge, no->get_coord(), &mctChanges, &rtChanges);
1632     V1 = (mctChanges.V.begin())->second;
1633     }
1634     else // V1 = this vertex
1635     {
1636     V1 = (MCVertex *)no->get_lien_topologie();
1637     }
1638     // if the extremities of the segment are not on a vertex, then insert a vertex
1639     // on the closest point
1640     if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() > 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() > 0)
1641     {
1642     MCEdge * edge = (MCEdge*)cs.Seg1->get_lien_topologie();
1643    
1644     if (((MCVertex*)edge->get_cosommet1()->get_sommet())->GetMergedRefVertices().size() > 0)
1645     continue;
1646    
1647     if (((MCVertex*)edge->get_cosommet2()->get_sommet())->GetMergedRefVertices().size() > 0)
1648     continue;
1649    
1650    
1651     MCTChanges mctChanges;
1652     RTChanges rtChanges;
1653     SplitEdge(edge, cs.Seg1P, &mctChanges, &rtChanges);
1654     V2 = (mctChanges.V.begin())->second;
1655     }
1656     else // V2 = this vertex
1657     {
1658     if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() == 0 && cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() == 0 )
1659     {
1660     double dist1 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(cs.Seg1->get_noeud1()->get_coord(), cs.Seg1P);
1661     double dist2 = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(cs.Seg1->get_noeud2()->get_coord(), cs.Seg1P);
1662     if(dist1<dist2)
1663     V2 = (MCVertex *) cs.Seg1->get_noeud1()->get_lien_topologie();
1664     else
1665     V2 = (MCVertex *) cs.Seg1->get_noeud2()->get_lien_topologie();
1666     }
1667     else if (cs.Seg1->get_noeud1()->get_lien_topologie()->get_dimension() == 0)
1668     V2 = (MCVertex *) cs.Seg1->get_noeud1()->get_lien_topologie();
1669     else if (cs.Seg1->get_noeud2()->get_lien_topologie()->get_dimension() == 0)
1670     V2 = (MCVertex *) cs.Seg1->get_noeud2()->get_lien_topologie();
1671     }
1672     // Merge vertices V1 with V2
1673     std::set<MCEdge*> edges;
1674     std::set<MCEdge*>::iterator itEdge;
1675     MergeVertices(V1,V2);
1676    
1677     LISTE_MG_NOEUD::iterator it_no2;
1678     for (MG_NOEUD* no2 = mesh->get_premier_noeud(it_no2);
1679     no2; no2 = mesh->get_suivant_noeud(it_no2))
1680     no2->change_lien_topologie2(NULL);
1681    
1682     LISTE_MG_SEGMENT::iterator it_seg2;
1683     for (MG_SEGMENT* seg2 = mesh->get_premier_segment(it_seg2);
1684     seg2; seg2 = mesh->get_suivant_segment(it_seg2))
1685     seg2->change_lien_topologie2(NULL);
1686    
1687     //_refGest->supprimer_mg_maillageid(mesh->get_id());
1688     return true;
1689     }
1690     }
1691     LISTE_MG_NOEUD::iterator it_no2;
1692     for (MG_NOEUD* no2 = mesh->get_premier_noeud(it_no2);
1693     no2; no2 = mesh->get_suivant_noeud(it_no2))
1694     no2->change_lien_topologie2(NULL);
1695    
1696     LISTE_MG_SEGMENT::iterator it_seg2;
1697     for (MG_SEGMENT* seg2 = mesh->get_premier_segment(it_seg2);
1698     seg2; seg2 = mesh->get_suivant_segment(it_seg2))
1699     seg2->change_lien_topologie2(NULL);
1700    
1701     _refGest->supprimer_mg_maillageid(mesh->get_id());
1702     }
1703     }
1704    
1705     return false;
1706     }*/
1707    
1708     //---------------------------------------------------------------------------
1709     bool MCAA::NodeConstrictedSection(MCFace * __mcFace, MG_NOEUD * __n, ConstrictedSection & __cs, Graph::Graph * __faceBoundaryMeshGraph)
1710     {
1711     int i,j,k;
1712     double LMin;
1713    
1714 foucault 64 if (__n->get_lien_topologie()->get_nb_ccf() != 0)
1715     return false;
1716    
1717 foucault 27 double meshSize = GetSize(__n->get_coord());
1718     LMin = .5*meshSize/GetMaxOverdensity();
1719    
1720     std::map<double,ConstrictedSection> mapCSByDistance;
1721    
1722     const Graph::Graph::MapNodesById & graphNodes = __faceBoundaryMeshGraph->GetNodes();
1723     for (Graph::Graph::MapNodesById::const_iterator itGN = graphNodes.begin();
1724     itGN != graphNodes.end();
1725     itGN++)
1726     {
1727     Graph::Node * graphNode = itGN->second;
1728     MG_SEGMENT * seg = (MG_SEGMENT *)graphNode->GetUserData();
1729    
1730    
1731    
1732     std::set<MCFace*>commonF;
1733     double dist;
1734     double *SP0 = seg->get_noeud1()->get_coord();
1735     double *SP1 = seg->get_noeud2()->get_coord();
1736     double *P = __n->get_coord();
1737     double P2[3];
1738     OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_3d(SP0,SP1,P,P2);
1739     dist=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(P,P2);
1740     if (dist < LMin)
1741     {
1742     if (__n==seg->get_noeud1() || __n==seg->get_noeud2())
1743     continue;
1744     std::set <Graph::Node*> adjacentGNSegs, adjacentGNSegs2;
1745     graphNode->AdjacentNodes (adjacentGNSegs);
1746     for (std::set <Graph::Node*>::iterator itN1 = adjacentGNSegs.begin(); itN1 != adjacentGNSegs.end(); itN1++)
1747     {
1748     Graph::Node * gn1 = *itN1;
1749     MG_SEGMENT * seg1 = (MG_SEGMENT *)gn1->GetUserData();
1750     if (__n==seg1->get_noeud1() || __n==seg1->get_noeud2())
1751     continue;
1752     // gn1->AdjacentNodes (adjacentGNSegs2);
1753     }
1754     /*
1755     for (std::set <Graph::Node*>::iterator itN2 = adjacentGNSegs.begin(); itN2 != adjacentGNSegs.end(); itN2++)
1756     {
1757     Graph::Node * gn2 = *itN2;
1758     MG_SEGMENT * seg2 = (MG_SEGMENT *)gn2->GetUserData();
1759     if (__n==seg2->get_noeud1() || __n==seg2->get_noeud2())
1760     continue;
1761     } */
1762    
1763     ConstrictedSection cs;
1764     std::set<MCFace*>::iterator itF=commonF.begin();
1765     cs.F = *itF;
1766     cs.Node = __n;
1767     cs.Seg1 = seg;
1768     OT_ALGORITHME_GEOMETRIQUE::VEC3_ASSIGN_VEC3(P2,cs.Seg1P);
1769     mapCSByDistance[dist] = cs;
1770     }
1771     }
1772    
1773     for (std::map<double, ConstrictedSection>::iterator itCS=mapCSByDistance.begin();
1774     itCS != mapCSByDistance.end();
1775     itCS++)
1776     {
1777 foucault 64 double distance = itCS->first;
1778 foucault 27 MG_SEGMENT *sa = itCS->second.Seg1;
1779     OT_VECTEUR_3D point_a = itCS->second.Seg1P;
1780    
1781     for (int i=0; i<__n->get_lien_segment()->get_nb(); i++)
1782     {
1783     MG_SEGMENT * sb = __n->get_lien_segment()->get(i);
1784     OT_VECTEUR_3D point_b(__n->get_coord());
1785    
1786     std::vector <Graph::Node *> pathNodes;
1787     std::vector <Graph::Arc *> pathArcs;
1788     Graph::Node * nStart = __faceBoundaryMeshGraph->GetNode(sa->get_id());
1789     Graph::Node * nEnd = __faceBoundaryMeshGraph->GetNode(sb->get_id());
1790     if (nEnd == 0 || nStart == 0) // segment adjacent to node is not in the face
1791     continue;
1792    
1793     double distance = Graph::Dijkstra(__faceBoundaryMeshGraph,nStart,nEnd,GraphDistanceBetweenSegs,pathNodes,pathArcs);
1794    
1795     bool testShortestPath = (distance > 3*meshSize);
1796    
1797     if (testShortestPath == false)
1798     break;
1799    
1800     bool testInteriorDir;
1801     {
1802     OT_VECTEUR_3D direction_b_a;
1803     for (int i=0; i<3; i++)
1804     direction_b_a[i] = point_a[i]-point_b[i];
1805    
1806     if ( direction_b_a.get_longueur2() > 1E-32 )
1807     {
1808 foucault 64 double * xyz_topo[2]={point_b,point_a};
1809     MCNode * mcNode[2]={0,0};
1810     MG_ELEMENT_TOPOLOGIQUE * mcTopo[2], * refTopo[2];
1811     mcTopo[0] = __n->get_lien_topologie();
1812     mcTopo[1] = sa->get_lien_topologie();
1813    
1814     for (int k=0;k<2;k++)
1815     {
1816     switch(mcTopo[k]->get_dimension())
1817     {
1818     case 0:
1819     {
1820     MCVertex * mcVertex = (MCVertex *)mcTopo[k];
1821     mcNode[k] = new MCNode(mcVertex,mcVertex->GetRefVertex(),xyz_topo[k][0],xyz_topo[k][1],xyz_topo[k][2]);
1822     break;
1823     }
1824     case 1:
1825     {
1826     MCEdge * mcEdge = (MCEdge*) mcTopo[k];
1827     PolyCurve * polyCurve = mcEdge->GetPolyCurve();
1828     MG_ARETE * refEdge = 0;
1829     double s_polycurve,t_refEdge,dt_refEdge;
1830     polyCurve->inverser(s_polycurve,xyz_topo[k],1E-6);
1831     polyCurve->Parameter_SToRefEdgeT (s_polycurve, &refEdge, &t_refEdge, &dt_refEdge,false);
1832     mcNode[k] = new MCNode(mcEdge, refEdge, t_refEdge, xyz_topo[k]);
1833     break;
1834     }
1835     default:
1836     {
1837     refTopo[k] = 0;
1838     }
1839     }
1840     }
1841    
1842     ShortestPathByClosestPointOnEdge operateur_distGeo(__mcFace,mcNode[0],mcNode[1],.25*meshSize);
1843     double distanceGeo = operateur_distGeo.Find();
1844     if (distanceGeo > .5*meshSize)
1845     testInteriorDir = false;
1846     else
1847     testInteriorDir = true;
1848    
1849     //testInteriorDir = GeometricTools::MCFace_MCTopoDir_IsInterior(__mcFace, mcVertexB, __n->get_coord(), direction_b_a);
1850 foucault 27 }
1851     }
1852 foucault 64
1853 foucault 27 if (testInteriorDir == false)
1854     break;
1855    
1856     if (testInteriorDir && testShortestPath)
1857     {
1858     __cs = itCS->second;
1859     return true;
1860     }
1861     }
1862     }
1863    
1864     return false;
1865     }
1866     double MCAA::GraphDistanceBetweenSegs(Graph::Node * __a, Graph::Node * __b, Graph::Arc * __arc )
1867     {
1868     MG_SEGMENT * seg1 = (MG_SEGMENT *)__a->GetUserData();
1869     MG_SEGMENT * seg2 = (MG_SEGMENT *)__b->GetUserData();
1870     return .5*(seg1->get_longueur()+seg2->get_longueur());
1871     }
1872     //---------------------------------------------------------------------------
1873     struct DJSeg {
1874     int nbVisit;
1875     double d;
1876     MG_SEGMENT * seg;
1877     MG_SEGMENT * previous;
1878     };
1879     //---------------------------------------------------------------------------
1880     // Calcule le chemin le plus court entre les milieux des segments sa et sb
1881     double
1882     MCAA::ShortestPath(MG_MAILLAGE * __mesh, MG_SEGMENT * sa, MG_SEGMENT * sb)
1883     {
1884     int i,j,k;
1885    
1886     if ( ! __mesh->contient(sa) || ! __mesh->contient(sb))
1887     {
1888     printf("ShortestPath : error : the mesh does not contain the querried segment!\n");
1889     return -1;
1890     }
1891    
1892     /*fonction Dijkstra (noeuds, fils, distance, debut, fin)*/
1893     double distance;
1894     std::map<MG_SEGMENT*, struct DJSeg> nodes;
1895     std::multimap<double, struct DJSeg*> nodesByD;
1896    
1897     /*
1898     Pour n parcourant noeuds
1899     n.parcouru = infini // Peut être implémenté avec -1
1900     n.precedent = 0
1901     Fin pour*/
1902     MG_SEGMENT *seg;
1903     LISTE_MG_SEGMENT::iterator it_seg;
1904     for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1905     seg; seg =__mesh->get_suivant_segment(it_seg))
1906     {
1907    
1908     struct DJSeg djseg;
1909    
1910     djseg.previous = NULL;
1911     djseg.seg = seg;
1912     djseg.nbVisit = 0;
1913     djseg.d = 1E300;
1914    
1915     nodes[seg] = djseg;
1916     }
1917    
1918     if (nodes.find(sa) == nodes.end() || nodes.find(sb) == nodes.end())
1919     return 1E300;
1920    
1921     /*
1922     debut.parcouru = 0
1923     DejaVu = liste vide
1924     PasEncoreVu = noeuds
1925     */
1926     nodes[sa].d = 0;
1927    
1928    
1929     std::set <MG_SEGMENT*> visited, unvisited;
1930    
1931     nodesByD.insert( std::make_pair( 0, &(nodes[sa])) );
1932    
1933     for (MG_SEGMENT* seg = __mesh->get_premier_segment(it_seg);
1934     seg; seg =__mesh->get_suivant_segment(it_seg))
1935     {
1936     unvisited.insert(seg);
1937    
1938     }
1939     //
1940    
1941     // Tant que PasEncoreVu != liste vide
1942     while (unvisited.size() != 0)
1943     {
1944     // n1 = minimum(PasEncoreVu) // Le noeud dans PasEncoreVu avec parcouru le plus petit
1945     struct DJSeg closestSeg;
1946     /*if (visited.size() == 0)
1947     closestSeg = nodes[sa];
1948     else
1949     closestSeg = nodes[*(unvisited.begin())];
1950    
1951     for (std::map<MG_SEGMENT*, struct DJSeg>::iterator itDJSeg = nodes.begin();
1952     itDJSeg != nodes.end();
1953     itDJSeg++)
1954     {
1955     if (
1956     itDJSeg->second.d < closestSeg.d
1957     && unvisited.find(itDJSeg->second.seg) != unvisited.end()
1958     )
1959     {
1960     closestSeg = itDJSeg->second;
1961     }
1962     } */
1963    
1964     std::multimap<double, struct DJSeg *>::iterator itDJSegByDist;
1965     for (itDJSegByDist = nodesByD.begin();
1966     itDJSegByDist != nodesByD.end(); itDJSegByDist++)
1967     {
1968     if ( unvisited.find(itDJSegByDist->second->seg) != unvisited.end() )
1969     {
1970     closestSeg = *(itDJSegByDist->second);
1971     break;
1972     }
1973     }
1974     if (itDJSegByDist == nodesByD.end())
1975     closestSeg = nodes[*(unvisited.begin())];
1976    
1977     MG_SEGMENT * seg = closestSeg.seg;
1978    
1979     // DejaVu.ajouter(n1)
1980     //
1981     visited.insert(seg);
1982     nodes[seg].nbVisit ++;
1983    
1984    
1985     // PasEncoreVu.enlever(n1)
1986     unvisited.erase(seg);
1987    
1988    
1989     /*
1990     Pour n2 parcourant fils(n1) // Les noeuds reliés à n1 par un arc
1991     Si n2.parcouru > n1.parcouru + distance(n1, n2) // distance correspond au poids de l'arc reliant n1 et n2
1992     n2.parcouru = n1.parcouru + distance(n1, n2)
1993     n2.precedent = n1 // Dis que pour aller à n2, il faut passer par n1
1994     Fin si
1995     Fin pour
1996     Fin tant que
1997     */
1998     std::set <MG_SEGMENT*>children;
1999     TPL_LISTE_ENTITE<MG_SEGMENT*> *lien_segment1 = seg->get_noeud1()->get_lien_segment();
2000     for (i=0; i<lien_segment1->get_nb(); i++)
2001     {
2002     MG_SEGMENT * child = lien_segment1->get(i);
2003     if (child != seg )
2004     children.insert(child);
2005     }
2006     TPL_LISTE_ENTITE<MG_SEGMENT*> *lien_segment2 = seg->get_noeud2()->get_lien_segment();
2007     for (i=0; i<lien_segment2->get_nb(); i++)
2008     {
2009     MG_SEGMENT * child = lien_segment2->get(i);
2010     if (child != seg )
2011     children.insert(child);
2012     }
2013    
2014     for ( std::set <MG_SEGMENT*>::iterator itChild = children.begin();
2015     itChild != children.end();
2016     itChild++)
2017     {
2018     MG_SEGMENT * child = *itChild;
2019     struct DJSeg * sDJSegChild = &(nodes[child]);
2020     double dist_child = .5*seg->get_longueur() + .5*child->get_longueur();
2021    
2022     if ( sDJSegChild->d > closestSeg.d + dist_child)
2023     {
2024     sDJSegChild->d = closestSeg.d + dist_child;
2025     sDJSegChild->previous = seg;
2026    
2027     if ( unvisited.find(sDJSegChild->seg) != unvisited.end() )
2028     nodesByD.insert(std::make_pair(sDJSegChild->d, sDJSegChild));
2029     }
2030     }
2031    
2032     }
2033    
2034     /*
2035     chemin = liste vide
2036     n = fin
2037     Tant que n != debut
2038     chemin.ajouterAvant(n)
2039     n = n.precedent
2040     Fin tant que
2041     Retourner chemin
2042     Fin fonction Dijkstra.
2043     */
2044    
2045     std::vector<MG_SEGMENT*> path;
2046     struct DJSeg n = nodes[sb];
2047     distance = n.d;
2048    
2049     int nb_seg = __mesh->get_nb_mg_segment();
2050    
2051     for (i=0; i<nb_seg && n.seg != sa; i++)
2052     {
2053     path.insert(path.begin(), n.seg);
2054     n = nodes[n.previous];
2055     }
2056     if (i == nb_seg)
2057     distance = 1E300;
2058    
2059     return distance;
2060     }
2061     //---------------------------------------------------------------------------
2062     /*bool MCAA::TestEdgeSupprBoundary(MCVertex * __mcVertex)
2063     {
2064     int i;
2065    
2066     if (_mcBody->G10()->GetArc(__mcVertex->get_id())->Rank() != 2)
2067     return false;
2068    
2069     // Get the 2 edges adjacent to this vertex
2070     std::vector < MCEdge * > edges;
2071     _mcBody->Vertex_GetAdjacentEdges(__mcVertex, edges);
2072    
2073     // Get node of this vertex in the FE mesh
2074     TPL_SET<MG_ELEMENT_MAILLAGE *> * lien_maillage = __mcVertex->get_lien_maillage();
2075     TPL_SET<MG_ELEMENT_MAILLAGE *>::ITERATEUR it;
2076     MG_ELEMENT_MAILLAGE * elem;
2077     MG_NOEUD * node = NULL;
2078     for (elem = lien_maillage->get_premier(it); elem ; elem = lien_maillage->get_suivant(it))
2079     {
2080     if (_feMesh->contient(elem))
2081     {
2082     node = (MG_NOEUD*)elem;
2083     break;
2084     }
2085     }
2086     if (!node)
2087     {
2088     printf("Warning : no node was found for MCVertex %d in the FE mesh !\n", __mcVertex->get_id());
2089     return false;
2090     }
2091    
2092     // Get the two segments adjacent to this node
2093     MG_SEGMENT * segs[2];
2094     segs[0] = node->get_lien_segment()->get(0);
2095     segs[1] = node->get_lien_segment()->get(1);
2096    
2097     // Get the two local edge criteria of these segments
2098     LocalEdgeCriteria * edgeCrit[2];
2099     for (i=0;i<2;i++)
2100     {
2101     MCEdge * edge = (MCEdge*)segs[i]->get_lien_topologie();
2102    
2103     ECMapIterator it_ec = _ecMap.find(edge);
2104    
2105     if (it_ec != _ecMap.end())
2106     {
2107     GlobalEdgeCriteria * gec = it_ec->second;
2108     edgeCrit[i] = gec->GetLocalEdgeCriteria(segs[i]);
2109     if (!edgeCrit[i])
2110     {
2111     printf("Warning : no criteria were found for segment %d of edge %d\n", segs[i]->get_id(), edge->get_id());
2112     return false;
2113     }
2114     }
2115     else
2116     {
2117     printf("TestEdgeSupprBoundary : Error : vertex %d is not found\n");
2118     return false;
2119     }
2120     }
2121    
2122     return ( edgeCrit[0]->DeletionScore() * edgeCrit[1]->DeletionScore() < 0);
2123     } */
2124     //---------------------------------------------------------------------------
2125     void
2126     MCAA::SuppressMCEdge(MCEdge * __mcEdge, MCTChanges * __mctChanges)
2127     {
2128     MCFace * F[3];
2129    
2130     // update the simplification time
2131     time++;
2132    
2133     // Get the list of vertex that are adjacent to the
2134     // mc edge
2135     std::vector<MCVertex*> edge_vertices;
2136     _mcBody->Edge_GetVertices(__mcEdge, edge_vertices);
2137    
2138     // remove the FE mesh of this edge
2139     DeleteFEMesh(__mcEdge);
2140     // Delete the criteria of the MC Edge
2141     EC_Delete(__mcEdge);
2142    
2143     // Suppress the mc edge of the mc body
2144     _mcBody->SuppressMCEdge(__mcEdge, F);
2145    
2146     // the current MCFace containing to the deleted edge
2147     MCFace * newFace = F[2];
2148    
2149     // move the link of the edge to the current MCFace containing to the deleted edge
2150     MG_MAILLAGE_OUTILS::change_lien_maillage( __mcEdge, newFace );
2151     for (int i=0; i<2; i++)
2152     {
2153     if (F[i] != NULL)
2154     {
2155     // a face that was deleted from MCT
2156     MCFace * oldFace = F[i];
2157     // update mesh link of old face to new face
2158     MG_MAILLAGE_OUTILS::change_lien_maillage( oldFace, newFace );
2159     // delete old face
2160     _mcBody->DeleteMCFace(oldFace);
2161     }
2162     }
2163    
2164     std::set<MCEdge*> adjedge = _mcBody->Face_GetAdjacentEdges(newFace);
2165     for ( std::set<MCEdge*>::iterator itAdjEdge = adjedge.begin();
2166     itAdjEdge != adjedge.end(); itAdjEdge++)
2167     {
2168     MCEdge * edge = *itAdjEdge;
2169     GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(edge);
2170     gec->Update(__mcEdge, false);
2171     }
2172    
2173     // Dereference the MCEdge from the geometry manager, and free the memory
2174     _mcBody->DeleteMCEdge(__mcEdge);
2175    
2176     // update the vertex properties on the adjacent vertices
2177     for (std::vector<MCVertex*>::iterator itVertex = edge_vertices.begin();
2178     itVertex != edge_vertices.end();
2179     itVertex++ )
2180     {
2181     MCVertex * v = *itVertex;
2182     VC_Get(v)->Update();
2183     }
2184    
2185     // update the modification time of the MC Edge
2186     newFace->time = time;
2187     __mctChanges->E.insert(std::make_pair(__mcEdge, (MCEdge*)NULL));
2188     if (F[0]) __mctChanges->F.insert(std::make_pair(F[0], F[2]));
2189     if (F[1]) __mctChanges->F.insert(std::make_pair(F[1], F[2]));
2190     }
2191     //---------------------------------------------------------------------------
2192     void
2193     MCAA::SuppressMCVertex(MCVertex * __mcVertex, MCTChanges * __mctChanges)
2194     {
2195     std::multimap<MCEdge*,MCEdge*>::iterator itE;
2196    
2197     // update the simplification time
2198     time++;
2199    
2200     if (_mapSuppressRefVertexCount.find(__mcVertex->GetRefVertex()) == _mapSuppressRefVertexCount.end())
2201     _mapSuppressRefVertexCount[ __mcVertex->GetRefVertex() ] = 1;
2202     else
2203     {
2204     _mapSuppressRefVertexCount[ __mcVertex->GetRefVertex() ]++;
2205     }
2206    
2207     // Get the edges adjacent to this vertex
2208     std::set< MCEdge * > vertex_edges;
2209     _mcBody->Vertex_GetAdjacentEdges(__mcVertex, vertex_edges);
2210    
2211     if ( vertex_edges.size() != 0 && vertex_edges.size() != 2)
2212     {
2213     printf("P B vertex %d has %d edges\n", __mcVertex->get_id(), vertex_edges.size());
2214     }
2215    
2216     std::set< MCFace * > vertex_faces;
2217     _mcBody->Vertex_GetAdjacentFaces(__mcVertex, vertex_faces);
2218     if (vertex_edges.size() == 0) // case of a vertex isolated in the face
2219     {
2220     if (vertex_faces.size() == 1)
2221     {
2222     std::set< MCFace * >::iterator vertex_faces_it = vertex_faces.begin();
2223     // delete the node of the FE mesh
2224     DeleteFEMesh(__mcVertex);
2225     // update the link of the deleted vertex in the MC Tessellation
2226     MG_MAILLAGE_OUTILS::change_lien_maillage(__mcVertex, *vertex_faces_it);
2227     }
2228     else
2229     {
2230     printf("Problem : vertex has 0 edge and 0 face !!!\n");
2231     }
2232     }
2233    
2234     // Suppress this vertex in the MCBody
2235     MCEdge * newEdge = NULL;
2236    
2237     _mcBody->SuppressMCVertex(__mcVertex, __mctChanges);
2238    
2239     if ( __mctChanges->E.size() != 0)
2240     {
2241     itE = __mctChanges->E.begin();
2242     newEdge = itE->second;
2243    
2244     for (itE = __mctChanges->E.begin(); itE != __mctChanges->E.end(); itE++)
2245     {
2246     MCEdge * edge0 = itE->first;
2247     MCEdge * edge1 = itE->second;
2248    
2249     printf("Created edge %d containing %d %x", newEdge->get_id(), edge0->get_id(), edge1->get_id());
2250    
2251     // If edge0 was deleted
2252     if ( edge0 != 0 )
2253     {
2254     // move the link of the egde to the current MCFace containing to the deleted edge
2255     MG_MAILLAGE_OUTILS::change_lien_maillage( edge0, edge1, _mcTess);
2256     MG_MAILLAGE_OUTILS::change_lien_maillage(__mcVertex, edge1, _mcTess);
2257    
2258     // update the modification time of the MC Edge
2259     newEdge->time = time;
2260     }
2261     }
2262     printf("\n");
2263    
2264     std::set <MCEdge*> faces_edges;
2265     for (std::set<MCFace*>::iterator itFace = vertex_faces.begin();
2266     itFace != vertex_faces.end();
2267     itFace++)
2268     {
2269     MCFace * mcFace = *itFace;
2270    
2271     // Get the G21 arcs to G21 node
2272     // they compose the MC edges adjacent to the MC face
2273     Graph::Node * G21Node = _mcBody->G21()->GetNode(mcFace->get_id());
2274    
2275     Graph::Node::MultimapArcsById & arcsOfG21Node = G21Node->IncidentArcs();
2276    
2277     for (Graph::Node::MultimapArcsById::const_iterator it = arcsOfG21Node.begin();
2278     it != arcsOfG21Node.end();
2279     it++)
2280     faces_edges.insert( _mcBody->GetMCEdge(it->second) );
2281     }
2282    
2283     for (std::set<MCEdge*>::iterator itFaceEdge = faces_edges.begin();
2284     itFaceEdge != faces_edges.end();
2285     itFaceEdge++)
2286     {
2287     MCEdge * faceEdge = *itFaceEdge;
2288     if ( vertex_edges.find(faceEdge) != vertex_edges.end() )
2289     continue;
2290     GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(faceEdge);
2291     if (gec == NULL ) continue;
2292    
2293     for (std::set<MCEdge*>::iterator itDeletedVertexEdge = vertex_edges.begin();
2294     itDeletedVertexEdge != vertex_edges.end();
2295     itDeletedVertexEdge++)
2296     {
2297     MCEdge * deletedEdge = *itDeletedVertexEdge;
2298     gec->Update(deletedEdge, false);
2299     }
2300     }
2301    
2302     // delete edge criteria of each original mc Edge
2303     // initialize the edge criteria on the new merged MCEdge
2304     bool bRemeshMergedEdges = true;
2305     if ( bRemeshMergedEdges )
2306     {
2307     DeleteFEMesh(newEdge);
2308     DeleteFEMesh(__mcVertex);
2309     InitializeFEMesh(newEdge);
2310     EC_Init(newEdge);
2311    
2312     for (itE = __mctChanges->E.begin(); itE != __mctChanges->E.end(); itE++)
2313     {
2314     MCEdge * oldEdge2 = itE->first;
2315    
2316     // delete the edge criteria of the original mc edge
2317     EC_Delete(oldEdge2);
2318     }
2319     }
2320     else
2321     {
2322     for (itE = __mctChanges->E.begin(); itE != __mctChanges->E.end(); itE++)
2323     {
2324     MCEdge * oldEdge2 = itE->first;
2325     MCEdge * newEdge2 = itE->second;
2326     if (oldEdge2)
2327     {
2328    
2329    
2330     // move local edge criterie to new merged mc edge
2331     EC_ChangeTopo(oldEdge2, newEdge2);
2332     GetGlobalEdgeCriteria(newEdge2)->Update(false);
2333    
2334     // delete the edge criteria of the original mc edge
2335     EC_Delete(oldEdge2);
2336     }
2337     }
2338     }
2339     }
2340    
2341     // the vertex properties of the deleted mc vertex are deleted
2342     VC_Delete(__mcVertex);
2343    
2344     // Delete Old vertex
2345     _mcBody->DeleteMCVertex(__mcVertex);
2346    
2347     // Delete old MC Edges
2348     for (std::set<MCEdge*>::iterator itE = vertex_edges.begin();
2349     itE != vertex_edges.end();
2350     itE++ )
2351     {
2352     MCEdge * mcEdge = *itE;
2353     _mcBody->DeleteMCEdge(mcEdge);
2354     }
2355     }
2356    
2357     //---------------------------------------------------------------------------
2358     bool MCAA::SplitEdgesAtIncompatibleLocalCriteria(MCTChanges * __mctChanges)
2359     {
2360     int i;
2361     double bestSplitScore = 0, bestSplitPoint[3];
2362     MCEdge * bestSplitEdge = NULL;
2363     RTChanges rtChanges;
2364    
2365     for (ECMapIterator it_ec = _ecMap.begin();
2366     it_ec != _ecMap.end();
2367     it_ec++)
2368     {
2369     MCEdge * mcEdge = it_ec->first;
2370     GlobalEdgeCriteria * gec = it_ec->second;
2371     double splitScore = 0, splitPoint[3];
2372     splitScore = gec->SplitScore(splitPoint);
2373     if (splitScore > bestSplitScore)
2374     {
2375     bestSplitScore = splitScore;
2376     bestSplitEdge = mcEdge;
2377     for (i=0;i<3;i++)
2378     bestSplitPoint[i] = splitPoint[i];
2379    
2380     break;
2381     }
2382     }
2383    
2384     if (bestSplitEdge)
2385     {
2386     SplitEdge(bestSplitEdge, bestSplitPoint, __mctChanges, &rtChanges);
2387     return true;
2388     }
2389     else
2390     return false;
2391     }
2392     //---------------------------------------------------------------------------
2393     void MCAA::SplitEdge(MCEdge * __mcEdge, double xyz[3], MCTChanges * __mctChanges, RTChanges * __rtChanges, bool __splitTessellation)
2394     {
2395     int i;
2396    
2397     // Get the list of faces that are adjacent to the
2398     // mc edge
2399     std::set < MCFace * > edge_faces = _mcBody->Edge_GetAdjacentFaces(__mcEdge);
2400    
2401    
2402     // Split the MC Edge
2403     MG_ARETE *__origRefEdge, *__splitRefEdges[2];
2404     MG_SOMMET *__splitRefVertex;
2405     MCVertex * __splitVertex;
2406     MCEdge * __splitEdges[2];
2407    
2408     __origRefEdge = __mcEdge->GetPolyCurve()->GetRefEdge(0);
2409    
2410     _mcBody->SplitEdge(__mcEdge, xyz, __mctChanges, __rtChanges);
2411    
2412     if (__mctChanges->E.size() == 0)
2413     return;
2414    
2415     std::multimap<MCEdge*, MCEdge*>::iterator itMCE;
2416     std::multimap<MCVertex*, MCVertex*>::iterator itMCV;
2417    
2418     itMCE = __mctChanges->E.begin();
2419     for (i=0; i<2; i++, itMCE++)
2420     __splitEdges[i] = itMCE->second;
2421    
2422     itMCV = __mctChanges->V.begin();
2423     __splitVertex = itMCV->second;
2424    
2425     std::multimap<MG_ARETE*, MG_ARETE*>::iterator itRE;
2426     std::multimap<MG_SOMMET*, MG_SOMMET*>::iterator itRV;
2427    
2428     itRE = __rtChanges->E.begin();
2429     for (i=0; i<2; i++, itRE++)
2430     {
2431     __origRefEdge = itRE->first;
2432     __splitRefEdges[i] = itRE->second;
2433     }
2434    
2435     itRV = __rtChanges->V.begin();
2436     __splitRefVertex = itRV->second;
2437    
2438     printf("Edge %d has been substituted by edges %d and %d\n", __mcEdge->get_id(), __splitEdges[0]->get_id(), __splitEdges[1]->get_id());
2439    
2440     MG_SEGMENT * mcTessOriginalSegment, *refTessOriginalSegment;
2441     // split the tessellation
2442     if (__splitTessellation)
2443     {
2444     MG_NOEUD * mcTessSplitNode;
2445     MG_SEGMENT * mcTessSplitSegments[2];
2446     MG_MAILLAGE_OUTILS::SplitEdgeInMesh(_mcTess, __mcEdge, __splitVertex, __splitEdges[0], __splitEdges[1], &mcTessOriginalSegment, &mcTessSplitNode, mcTessSplitSegments);
2447    
2448     MG_NOEUD * refTessSplitNode;
2449     MG_SEGMENT * refTessSplitSegments[2];
2450     if (__origRefEdge) MG_MAILLAGE_OUTILS::SplitEdgeInMesh(_refTess, __origRefEdge, __splitRefVertex, __splitRefEdges[0], __splitRefEdges[1], &refTessOriginalSegment, &refTessSplitNode, refTessSplitSegments);
2451    
2452     // update MC Tessellation Grid
2453     _UpdateMCTessSegGrid(__mcEdge, mcTessOriginalSegment,mcTessSplitSegments);
2454     }
2455     if (__origRefEdge) _geom->supprimer_mg_areteid(__origRefEdge->get_id());
2456    
2457     // remesh the split edges
2458     DeleteFEMesh(__mcEdge);
2459     DeleteFEMesh(__splitVertex);
2460     MG_NOEUD * feNode;
2461     InitializeFEMesh(__splitVertex, &feNode);
2462     for (i=0; i<2; i++)
2463     {
2464     InitializeFEMesh(__splitEdges[i]);
2465     }
2466    
2467     // update vertex criteria
2468     VC_Init(__splitVertex);
2469    
2470     // update edge criteria
2471     EC_Delete(__mcEdge);
2472     for (i=0; i<2; i++)
2473     EC_Init(__splitEdges[i]);
2474     _mcBody->DeleteMCEdge(__mcEdge);
2475    
2476     if (mcTessOriginalSegment)
2477     { MCBODY_FOR_EACH_MCEDGE ( _mcBody, mcEdge )
2478     {
2479     GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(mcEdge);
2480     gec->ReInit(mcTessOriginalSegment);
2481     gec->Update(__mcEdge, false);
2482     }
2483     }
2484    
2485     /*for ( std::set < MCFace * >::iterator itF = edge_faces.begin();
2486     itF != edge_faces.end();
2487     itF ++ )
2488     {
2489     MCFace * mcFace = *itF;
2490    
2491     Graph::Node *G21Node = _mcBody->G21()->GetNode(mcFace->get_id());
2492    
2493     Graph::Node::MultimapArcsById & arcsOfG21Node = G21Node->IncidentArcs();
2494    
2495     for (Graph::Node::MultimapArcsById::const_iterator it = arcsOfG21Node.begin();
2496     it != arcsOfG21Node.end();
2497     it++)
2498     {
2499     MCEdge * mcEdge = _mcBody->GetMCEdge(it->second);
2500     GlobalEdgeCriteria * gec = GetGlobalEdgeCriteria(mcEdge);
2501     bool gecUpdate = false;
2502    
2503     GlobalEdgeCriteria::LEC_Iterator it_lec;
2504     LocalEdgeCriteria * lec;
2505     for (lec = gec->GetFirstLocalEdgeCriteria(it_lec);
2506     lec;
2507     lec = gec->GetNextLocalEdgeCriteria(it_lec))
2508     {
2509     if (lec->IsTouchingSegment(mcTessOriginalSegment))
2510     {
2511     lec->Update(true);
2512     gecUpdate = true;
2513     }
2514     }
2515    
2516     if (gecUpdate)
2517     {
2518    
2519     }
2520     }
2521     } */
2522    
2523     // delete the original segments in MC and Ref tessellations
2524     if (mcTessOriginalSegment)
2525     _mcTess->supprimer_mg_segmentid(mcTessOriginalSegment->get_id());
2526     if (refTessOriginalSegment)
2527     _refTess->supprimer_mg_segmentid(refTessOriginalSegment->get_id());
2528    
2529     // update the simplification time
2530     time++;
2531     __splitVertex->time = time;
2532     for (i=0; i<2; i++)
2533     __splitEdges[i]->time = time;
2534    
2535     Graph::Arc * G21Arc = _mcBody->G21()->GetArc( __splitEdges[0]->get_id() );
2536     for (Graph::Arc::MultimapNodesById::const_iterator itN = G21Arc->Nodes().begin();
2537     itN != G21Arc->Nodes().end();
2538     itN++)
2539     {
2540     MCFace * adjacentFace = _mcBody->GetMCFace(itN->second);
2541     adjacentFace->time = time;
2542     }
2543     }
2544    
2545     //---------------------------------------------------------------------------
2546     void MCAA::Simplify()
2547     {
2548     MCTChanges mctChanges;
2549     Simplify2(&mctChanges);
2550     }
2551     //---------------------------------------------------------------------------
2552     void
2553     MCAA::Simplify2( MCTChanges * __mctChanges )
2554     {
2555     int nbFace0, nbFace1;
2556     int nbEdge0, nbEdge1;
2557     int nbVertex0, nbVertex1;
2558    
2559     nbFace0 = _mcBody->G21()->GetNodes().size();
2560     nbEdge0 = _mcBody->G21()->GetArcs().size();
2561     nbVertex0=_mcBody->G20()->GetArcs().size();
2562    
2563     std::set<MG_SEGMENT*> setSegmentBadTopology;
2564     std::set<MG_NOEUD*> setNodeBadTopology;
2565 foucault 64
2566     char animFilename[] = "";//"c:/gilles/anim.iv";
2567     std::ofstream animFile;
2568     double animTime = 15; double animTimeStep = 15.0f/nbEdge0;
2569     InventorText_MCAA * ivText = NULL;
2570     if ( strlen(animFilename) )
2571     {
2572     animFile.open(animFilename);
2573     ivText = new InventorText_MCAA(this);
2574     ivText->ShowFEMesh = false;
2575     ivText->ShowRefModel = false;
2576     ivText->ShowEdgeIds = false;
2577     ivText->ShowCriteria = false;
2578     ivText->ColorMCEdge = InventorText_MCAA::GlobalSuppressionCriterion;
2579     animFile << ivText->GetText_BeginAnimation(0,animTime);
2580     }
2581    
2582 foucault 27 bool result= true;
2583     while ( result )
2584     {
2585     MCTChanges mctChanges;
2586    
2587     result = Next2(&mctChanges);
2588     __mctChanges->Merge(mctChanges);
2589 foucault 64 if (ivText)
2590     {
2591     animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2592     animTime+=animTimeStep;
2593     }
2594 foucault 27 // Stop simplification if there remains only 1 MC Edge in the MCBody !
2595 foucault 64 if (_mcBody->G21()->GetArcs().size() == _minMCEdgeCount)
2596     break;
2597 foucault 27 }
2598 foucault 64 _nbE += SimplifyFaceLoop();
2599     if (ivText)
2600     {
2601     animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2602     animTime+=animTimeStep;
2603     }
2604 foucault 27 result= true;
2605     while ( result )
2606     {
2607     MCTChanges mctChanges;
2608    
2609 foucault 64 result = Next2(&mctChanges);
2610     if (ivText)
2611     {
2612     animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2613     animTime+=animTimeStep;
2614     }
2615 foucault 27 __mctChanges->Merge(mctChanges);
2616     }
2617     _nbC += SimplifyEdgeCollapse();
2618 foucault 64
2619     if (ivText)
2620     {
2621     animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2622     animTime+=animTimeStep;
2623     }
2624 foucault 27 _nbD += SimplifyConstrictedSections();
2625 foucault 64 if (ivText)
2626     {
2627     animTimeStep = 1E9;
2628     animFile << ivText->GetText_StepAnimation(animTime,animTime+animTimeStep);
2629     animTime+=animTimeStep;
2630     animFile << ivText->GetText_EndAnimation();
2631     }
2632 foucault 27
2633     nbFace1 = _mcBody->G21()->GetNodes().size();
2634     nbEdge1 = _mcBody->G21()->GetArcs().size();
2635     nbVertex1=_mcBody->G20()->GetArcs().size();
2636    
2637     printf("The initial CAD model contained :\n%d faces\n%d edges\n%d vertices\n", nbFace0,nbEdge0,nbVertex0);
2638     printf("%d edge deleted\n", _nbA);
2639     printf("%d vertex deleted\n", _nbB);
2640     printf("%d edge collapsed\n", _nbC);
2641     printf("%d constricted sections collapsed\n", _nbD);
2642     printf("%d loops deleted\n", _nbE);
2643     printf("The final CAD model contains :\n%d faces\n%d edges\n%d vertices\n", nbFace1,nbEdge1,nbVertex1);
2644     }
2645    
2646     int MCAA::SimplifyFaceLoop()
2647     {
2648     int nbLoopDeleted = 0;
2649     int i;
2650     do
2651     {
2652     i = NextSimplifyFaceLoop();
2653     nbLoopDeleted += i;
2654     }
2655     while (i);
2656     return nbLoopDeleted;
2657     }
2658    
2659     int MCAA::NextSimplifyFaceLoop()
2660     {
2661     int loopCount = 0;
2662     std::multimap < double , LoopCriteria * > mapLoopCriteria;
2663     {MCBODY_FOR_EACH_MCFACE(_mcBody,face)
2664     {
2665     std::vector < std::vector < MCEdge * > > loops = _mcBody->Face_GetCycles(face);
2666     std::vector < LoopCriteria * > vecLoopCriteria;
2667     for (unsigned itLoop = 0; itLoop < loops.size(); itLoop++)
2668     {
2669     LoopCriteria * crit = new LoopCriteria(this, face, loops[itLoop], 5);
2670     double score = crit->DeletionScore();
2671     mapLoopCriteria.insert ( std::make_pair( score, crit ) );
2672     }
2673     }}
2674    
2675    
2676     std::multimap < double , LoopCriteria * >::reverse_iterator itHighestScore = mapLoopCriteria.rbegin();
2677     if (itHighestScore != mapLoopCriteria.rend() && itHighestScore->first > 0)
2678     {
2679     LoopCriteria * highestLoopCriteria = itHighestScore->second;
2680    
2681     if (_mcBody->Contains(highestLoopCriteria->GetFace()) &&
2682     highestLoopCriteria->DeletionScore() > 0)
2683     {
2684     std::set < MCVertex * > loopVertices;
2685     std::vector < MCEdge* > loop = highestLoopCriteria->GetLoop();
2686     loopCount++;
2687    
2688     #define SUPPRESS_ONE_EDGE_OF_SMALL_LOOP
2689     #ifdef SUPPRESS_ONE_EDGE_OF_SMALL_LOOP
2690     MCEdge * mcEdgeMax; double maxL = -1;
2691     MCEdge * mcEdgeMin; double minL = 1E300;
2692     for (unsigned itEdge = 0; itEdge < loop.size(); itEdge ++ )
2693     {
2694     std::vector<MCVertex *> extremities;
2695     MCEdge * mcEdge = loop[itEdge];
2696     _mcBody->Edge_GetVertices(mcEdge, extremities);
2697     for (unsigned i=0; i<extremities.size(); i++)
2698     loopVertices.insert ( extremities [i] );
2699    
2700     double L = _ecMap[mcEdge]->GetLength();
2701     if (L > maxL)
2702     {
2703     maxL = L;
2704     mcEdgeMax = loop[itEdge];
2705     }
2706     if (L < minL)
2707     {
2708     minL = L;
2709     mcEdgeMin = loop[itEdge];
2710     }
2711     }
2712    
2713     MCTChanges mctChanges3,mctChanges1;
2714     SuppressMCEdge(mcEdgeMin, &mctChanges3);
2715     mctChanges1.Merge(mctChanges3);
2716     #endif
2717    
2718     #ifdef SUPPRESS_ALL_EDGES_OF_SMALL_LOOP
2719     for (unsigned itEdge = 0; itEdge < loop.size(); itEdge ++ )
2720     {
2721     MCEdge * mcEdge = loop[itEdge];
2722     std::vector<MCVertex *> extremities;
2723     _mcBody->Edge_GetVertices(mcEdge, extremities);
2724     for (unsigned i=0; i<extremities.size(); i++)
2725     loopVertices.insert ( extremities [i] );
2726    
2727     double splitScore, splitPoint[3];
2728     splitScore = highestLoopCriteria->EdgeSplitScore(mcEdge, splitPoint);
2729    
2730     MCTChanges mctChanges1;
2731    
2732     MCTChanges mctChanges3;
2733     SuppressMCEdge(mcEdge, &mctChanges3);
2734     mctChanges1.Merge(mctChanges3);
2735     }
2736     /* if (splitScore > 0)
2737     {
2738     MCTChanges mctChanges2;
2739     RTChanges rtChanges2;
2740     SplitEdge(mcEdge, splitPoint, &mctChanges2, &rtChanges2);
2741     if (mctChanges2.E.size() != 0) // Successful split !!!
2742     {
2743     for (std::multimap<MCEdge*,MCEdge*>::iterator itEdge = mctChanges2.E.begin();
2744     itEdge != mctChanges2.E.end();
2745     itEdge++)
2746     {
2747     if (itEdge->second != NULL) // edge created by SplitEdge()
2748     {
2749     MCEdge * mcEdgeSplit = itEdge->second;
2750     MCTChanges mctChanges3;
2751     RTChanges rtChanges3;
2752     SuppressMCEdge(mcEdgeSplit, &mctChanges3);
2753     mctChanges1.Merge(mctChanges3);
2754     break;
2755     }
2756     }
2757     }
2758     else // failure : there is 0 edge after split
2759     {
2760     MCTChanges mctChanges3;
2761     SuppressMCEdge(mcEdge, &mctChanges3);
2762     mctChanges1.Merge(mctChanges3);
2763     }
2764     }
2765     else
2766     {
2767     MCTChanges mctChanges3;
2768     SuppressMCEdge(mcEdge, &mctChanges3);
2769     mctChanges1.Merge(mctChanges3);
2770     }
2771     */
2772     #endif //#ifdef SUPPRESS_ALL_EDGES_OF_SMALL_LOOP
2773     for (std::set<MCVertex*>::iterator itVertex = loopVertices.begin();
2774     itVertex != loopVertices.end();
2775     itVertex++)
2776     {
2777     MCVertex * mcVertex = *itVertex;
2778     VertexCriteria * vCrit = _vcMap[mcVertex];
2779     if ( vCrit->GetScore() > 0)
2780     {
2781     MCTChanges mctChanges1;
2782     SuppressMCVertex(mcVertex, &mctChanges1);
2783     _nbB++;
2784     }
2785     }
2786     }
2787     }
2788    
2789     for ( std::multimap < double , LoopCriteria * >::iterator itLoopCriteria = mapLoopCriteria.begin();
2790     itLoopCriteria != mapLoopCriteria.end();
2791     itLoopCriteria++)
2792     {
2793     LoopCriteria * crit = itLoopCriteria->second;
2794     delete crit;
2795     }
2796    
2797     return loopCount;
2798     }
2799    
2800     int MCAA::SimplifyEdgeCollapse()
2801     {
2802     bool result;
2803     int counter;
2804    
2805     counter=0;
2806     do
2807     {
2808 foucault 64 counter++;
2809 foucault 27 MCEdge * collapseEdge = NULL;
2810     MCVertex * deleteVertex = NULL;
2811     double bestScore = 0;
2812    
2813     if (_mcBody->G21()->GetArcs().size() <= 1)
2814     break;
2815    
2816     {MCBODY_FOR_EACH_MCEDGE(_mcBody, edge)
2817     {
2818     if (_mcBody->G21()->GetArcs().size() <= 1)
2819     break;
2820    
2821     MCVertex * vertex[2];
2822     vertex[0] = (MCVertex * ) edge->get_cosommet1()->get_sommet();
2823     vertex[1] = (MCVertex * ) edge->get_cosommet2()->get_sommet();
2824    
2825     for (int i=0; i<2; i++)
2826     {
2827     double score = EdgeCollapseCriteria(edge, vertex[i], this).GetScore();
2828     if (score > bestScore)
2829     {
2830     bestScore = score;
2831     collapseEdge = edge;
2832     deleteVertex = vertex[i];
2833     }
2834     }
2835     }
2836     }
2837    
2838     if (collapseEdge&&deleteVertex)
2839     result = CollapseMCEdgeToMCVertex(collapseEdge, deleteVertex);
2840     else
2841     result = false;
2842    
2843    
2844    
2845     } while (result);
2846    
2847     return counter;
2848     }
2849    
2850     bool MCAA::CollapseMCEdgeToMCVertex(MCEdge * collapseEdge, MCVertex * deleteVertex)
2851     {
2852     bool result = true;
2853    
2854     result = true;
2855     MCVertex * vertex[2];
2856     vertex[0] = (MCVertex * ) collapseEdge->get_cosommet1()->get_sommet();
2857     vertex[1] = (MCVertex * ) collapseEdge->get_cosommet2()->get_sommet();
2858     MCVertex * targetVertex = (vertex[0]!=deleteVertex)?vertex[0]:vertex[1];
2859     std::set <MCEdge*> setNewEdges, setOldEdges;
2860     std::set <MCEdge*>::iterator itEdge, itEdge2;
2861     _mcBody->ContractEdgeToVertex(collapseEdge, targetVertex, setNewEdges, setOldEdges);
2862    
2863     for (itEdge = setOldEdges.begin(); itEdge != setOldEdges.end(); itEdge++)
2864     {
2865     MCEdge * mcEdge = *itEdge;
2866     EC_Delete(mcEdge);
2867    
2868     std::vector <MG_SEGMENT*> vecSegs;
2869     TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = mcEdge->get_lien_maillage();
2870     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
2871     MG_ELEMENT_MAILLAGE* element2;
2872     for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
2873     {
2874     if (_feMesh->contient(element2))
2875     vecSegs.push_back((MG_SEGMENT*)element2);
2876     }
2877    
2878     for (std::vector<MG_SEGMENT *>::iterator it = vecSegs.begin();
2879     it != vecSegs.end();
2880     it++)
2881     {
2882     MG_SEGMENT * seg = *it;
2883    
2884     _feMesh->supprimer_mg_segmentid(seg->get_id());
2885    
2886     for (itEdge2 = setNewEdges.begin(); itEdge2 != setNewEdges.end(); itEdge2++)
2887     {
2888     MCEdge * mcEdge2 = *itEdge2;
2889     mcEdge2->get_lien_maillage()->supprimer(seg);
2890     }
2891     }
2892     }
2893    
2894     for (itEdge = setNewEdges.begin(); itEdge != setNewEdges.end(); itEdge++)
2895     DeleteFEMesh(*itEdge);
2896    
2897     DeleteFEMesh(deleteVertex);
2898     VC_Delete(deleteVertex);
2899    
2900     TPL_SET<MG_ELEMENT_MAILLAGE*> * lien_maillage2 = deleteVertex->get_lien_maillage();
2901     TPL_SET<MG_ELEMENT_MAILLAGE*>::ITERATEUR it2;
2902     MG_ELEMENT_MAILLAGE* element2;
2903     for (element2 = lien_maillage2->get_premier(it2); element2; element2 = lien_maillage2->get_suivant(it2) )
2904     {
2905     MCEdge * mcEdgeOfDeletedVertex=*(setNewEdges.rbegin());
2906     element2->change_lien_topologie2(mcEdgeOfDeletedVertex);
2907     }
2908    
2909     _mcBody->DeleteMCVertex(deleteVertex);
2910     for (itEdge = setOldEdges.begin(); itEdge != setOldEdges.end(); itEdge++)
2911     {
2912     MCEdge * mcEdge = *itEdge;
2913     _mcBody->DeleteMCEdge(mcEdge);
2914     }
2915    
2916     for (itEdge = setNewEdges.begin(); itEdge != setNewEdges.end(); itEdge++)
2917     InitializeFEMesh(*itEdge);
2918    
2919     for (itEdge = setNewEdges.begin(); itEdge != setNewEdges.end(); itEdge++)
2920     EC_Init(*itEdge);
2921    
2922    
2923    
2924    
2925     /* std::set<MG_SEGMENT*> setSegmentBadTopology;
2926     std::set<MG_NOEUD*> setNodeBadTopology;
2927     CheckMCMesh( this->GetMCTess(), setSegmentBadTopology, setNodeBadTopology );
2928     CheckMCMesh( this->GetFEMesh(), setSegmentBadTopology, setNodeBadTopology );*/
2929    
2930     return result;
2931     }
2932    
2933     //---------------------------------------------------------------------------
2934     bool MCAA::Next2( MCTChanges * __mctChanges )
2935     {
2936     bool bSimplifDone = false;
2937 foucault 64 if (!bSimplifDone && _minMCVertexCount < _mcBody->G10()->GetArcs().size() ) bSimplifDone = SuppressNextVertex(__mctChanges);
2938 foucault 27 if (bSimplifDone) _nbB++;
2939 foucault 64 if (!bSimplifDone && _minMCEdgeCount < _mcBody->G10()->GetNodes().size()) { bSimplifDone = SuppressNextEdge2(__mctChanges); if (bSimplifDone) _nbA++; }
2940 foucault 27
2941     return bSimplifDone;
2942     }
2943     //---------------------------------------------------------------------------
2944     bool MCAA::SuppressNextEdge2(MCTChanges * __mctChanges)
2945     {
2946     GlobalEdgeCriteria * ec = GetHighestEdgeDeletionScore();
2947    
2948     if (ec == NULL)
2949     return false;
2950    
2951     bool bSimplifDone = (ec->DeletionScore() > 1E-3);
2952    
2953     if (bSimplifDone)
2954     {
2955     RTChanges rtChanges;
2956     DeleteEdge2(ec->GetEdge(), __mctChanges, &rtChanges);
2957     }
2958    
2959     return bSimplifDone;
2960     }
2961     //---------------------------------------------------------------------------
2962     void
2963     MCAA::DeleteEdge2(MCEdge * __mcEdge, MCTChanges * __mctChanges, RTChanges * __rtChanges)
2964     {
2965     int i;
2966     double splitScore = 0, splitPoint[3];
2967     RTChanges rtChanges;
2968     double deletionScore;
2969    
2970     GlobalEdgeCriteria * gec=_ecMap[__mcEdge];
2971     splitScore = gec->SplitScore(splitPoint);
2972     if (splitScore > 0)
2973     {
2974     MCTChanges mctChanges;
2975     RTChanges rtChanges;
2976     SplitEdge(__mcEdge, splitPoint, &mctChanges, &rtChanges);
2977     if (mctChanges.E.size() != 0) // Successful split !!!
2978     {
2979     for (std::multimap<MCEdge*,MCEdge*>::iterator itEdge = mctChanges.E.begin();
2980     itEdge != mctChanges.E.end();
2981     itEdge++)
2982     {
2983     if (itEdge->second != NULL) // edge created by SplitEdge()
2984     {
2985     DeleteEdge2(itEdge->second, __mctChanges, __rtChanges);
2986     __mctChanges->Merge(mctChanges);
2987     }
2988     }
2989     }
2990     else // failure : there is 0 edge after split
2991     {
2992     deletionScore=gec->DeletionScore();
2993     if (deletionScore>0)
2994     SuppressMCEdge(__mcEdge, &mctChanges);
2995     __mctChanges->Merge(mctChanges);
2996     }
2997     }
2998     else
2999     {
3000     MCTChanges mctChanges;
3001     deletionScore=gec->DeletionScore();
3002     if (deletionScore>0)
3003     SuppressMCEdge(__mcEdge, &mctChanges);
3004     __mctChanges->Merge(mctChanges);
3005     }
3006     }