ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCAA.cpp
Revision: 64
Committed: Fri Feb 1 18:27:30 2008 UTC (17 years, 3 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_MCAA.cpp
File size: 107018 byte(s)
Log Message:
mise a jour final these Gilles Foucault

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