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

File Contents

# Content
1 #include <vector>
2 #include <string>
3 #include <sstream>
4 #include <fstream>
5 #include <algorithm>
6 #include <math.h>
7 #pragma hdrstop
8
9 // Headers of Magic
10
11 #include <gestionversion.h>
12 #include <lc_point.h>
13 #include <step_point.h>
14
15 #include <CAD4FE_MCFace.h>
16 #include <CAD4FE_MCEdge.h>
17 #include <CAD4FE_PolyCurve.h>
18 #include <CAD4FE_PolySurface.h>
19 #include <CAD4FE_MCVertex.h>
20 #include <mg_maillage.h>
21 #include <mg_gestionnaire.h>
22 #include <ot_mathematique.h>
23
24 // Headers of CAD4FE
25 #include <CAD4FE_geometric_tools.h>
26 #include "CAD4FE_MakeLoops.h"
27 #include "CAD4FE_MCBody.h"
28 #include "CAD4FE_ColorMap.h"
29 #include "CAD4FE_Criteria.h"
30 #include "HypergraphLib_Components.h"
31 #include "HypergraphLib_Neato.h"
32 #include "HypergraphLib_FindCycles.h"
33
34 using namespace CAD4FE;
35
36
37 void MCTChanges::Merge(MCTChanges& __mctChanges)
38 {
39 int i;
40
41 std::multimap<MCEdge*,MCEdge*>::iterator itEdge1, itEdge2;
42 for ( itEdge1 = E.begin();
43 itEdge1 != E.end();
44 itEdge1++)
45 {
46 i=0;
47 for ( itEdge2 = __mctChanges.E.find(itEdge1->second);
48 itEdge2->first == itEdge1->second && itEdge2 != __mctChanges.E.end();
49 itEdge2++)
50 {
51 if (itEdge2->second == itEdge2->first)
52 continue;
53 E.insert(std::make_pair(itEdge1->first, itEdge2->second));
54 i++;
55 }
56 if (i>0)
57 E.erase(itEdge1);
58 }
59
60 for ( itEdge2 = __mctChanges.E.begin();
61 itEdge2 != __mctChanges.E.end();
62 itEdge2++)
63 {
64 itEdge1 = E.find(itEdge2->first);
65 if (itEdge1 == E.end())
66 {
67 E.insert(std::make_pair(itEdge1->first,itEdge1->second));
68 }
69 }
70 }
71
72 //---------------------------------------------------------------------------
73 MCBody::MCBody(MG_GEOMETRIE* __refGeom, MG_VOLUME * __refBody)
74 {
75 time = 0;
76 _refBody = __refBody;
77 _refGeom = __refGeom;
78 InitHyperGraphs();
79 }
80
81 //---------------------------------------------------------------------------
82 MCBody::~MCBody()
83 {
84 delete _G10;
85 delete _G20;
86 delete _G21;
87 }
88
89 //---------------------------------------------------------------------------
90 void MCBody::Graph_SetUserData(MG_ELEMENT_TOPOLOGIQUE * __topo)
91 {
92 Graph_SetUserData(_G10, __topo);
93 Graph_SetUserData(_G20, __topo);
94 Graph_SetUserData(_G21, __topo);
95 }
96
97 //---------------------------------------------------------------------------
98 void MCBody::Graph_SetUserData(Graph::Graph * __G, MG_ELEMENT_TOPOLOGIQUE * __topo)
99 {
100 int id = __topo->get_id();
101
102 switch (__topo->get_dimension())
103 {
104 case 0:// MCVertex
105 {
106 // reference vertex in arc of g10 and g20
107 if (__G == _G10 || __G == _G20 )
108 __G->GetArc(id)->SetUserData(__topo);
109
110 break;
111 }
112 case 1:// MCEdge
113 {
114 // reference edge in node of g10 and arc of g21
115 if (__G == _G10 )
116 __G->GetNode(id)->SetUserData(__topo);
117 else if (__G == _G21 )
118 __G->GetArc(id)->SetUserData(__topo);
119
120 break;
121 }
122 case 2:// MCFace
123 {
124 // reference face in node of g20 and g21
125 if (__G == _G20 || __G == _G21 )
126 __G->GetNode(id)->SetUserData(__topo);
127
128 break;
129 }
130 }
131 }
132
133 //---------------------------------------------------------------------------
134 MCFace * MCBody::AddMCFace(MG_FACE * __refFace)
135 {
136 MCFace *newMCFace = new MCFace(__refFace);
137 // Set the face ID
138 _refGeom->ajouter_mg_surface(newMCFace->GetPolySurface());
139 _refGeom->ajouter_mg_face(newMCFace);
140
141 return newMCFace;
142 }
143
144 //---------------------------------------------------------------------------
145 MCFace * MCBody::AddMCFace( MCFace *__a, MCFace *__b)
146 {
147 std::ostringstream idOriginal;
148 MCFace & mcFace1 = *__a;
149 MCFace & mcFace2 = *__b;
150 MCFace *newMCFace = new MCFace(mcFace1, mcFace2);
151 _refGeom->ajouter_mg_surface(newMCFace->GetPolySurface());
152 _refGeom->ajouter_mg_face(newMCFace);
153 return newMCFace;
154 }
155
156 //---------------------------------------------------------------------------
157 MCFace* MCBody::GetMCFace(const int __id) const
158 {
159 Graph::Node * node = _G21->GetNode(__id);
160 if (node)
161 return GetMCFace(node);
162 else
163 printf("Error in GetMCFace ID = %d\n", __id);
164
165 return NULL;
166 }
167
168 //---------------------------------------------------------------------------
169 bool MCBody::Contains(MCFace * __mcFace) const
170 {
171 return (GetMCFace(__mcFace->get_id()) != NULL);
172 }
173
174 //---------------------------------------------------------------------------
175 MCFace* MCBody::GetMCFace(Graph::GraphObject * __graphObject)
176 {
177 return (MCFace*) __graphObject->GetUserData();
178 }
179 //---------------------------------------------------------------------------
180 //
181 void MCBody::AddMCEdgeCovertices(MCEdge * __mcEdge, std::vector<MCVertex *> __mcVertex)
182 {
183 int i;
184
185 // Set the covertex ID and add it in the geometry manager
186 MG_COSOMMET * covertex[2];
187 for (i=0;i<2;i++)
188 covertex[i] = _refGeom->ajouter_mg_cosommet(__mcEdge, __mcVertex[i]);
189
190 if ( covertex[0]->get_t() > covertex[1]->get_t() && ! __mcEdge->GetPolyCurve()->est_periodique() )
191 std::swap (covertex[0], covertex[1]);
192
193
194 __mcEdge->changer_cosommet1(covertex[0]);
195 __mcEdge->changer_cosommet2(covertex[1]);
196 }
197 //---------------------------------------------------------------------------
198 void MCBody::DeleteMCEdgeCovertices(MCEdge * __mcEdge)
199 {
200 _refGeom->supprimer_mg_cosommet(__mcEdge->get_cosommet1());
201 _refGeom->supprimer_mg_cosommet(__mcEdge->get_cosommet2());
202 }
203 //---------------------------------------------------------------------------
204 void MCBody::DeleteMCEdge(MCEdge * __mcEdge)
205 {
206 printf("Deleting MC Edge\t : ID \"%d\" at adress %x\n",__mcEdge->get_id(), __mcEdge);
207 _refGeom->supprimer_mg_courbeid(__mcEdge->GetPolyCurve()->get_id());
208 _refGeom->supprimer_mg_areteid(__mcEdge->get_id());
209 }
210 //---------------------------------------------------------------------------
211 void MCBody::DeleteMCFace(MCFace * __mcFace)
212 {
213 printf("Deleting MC Face\t : ID \"%d\" at adress %x\n",__mcFace->get_id(), __mcFace);
214 _refGeom->supprimer_mg_surfaceid(__mcFace->GetPolySurface()->get_id());
215 _refGeom->supprimer_mg_faceid(__mcFace->get_id());
216 }
217 //---------------------------------------------------------------------------
218 void MCBody::DeleteMCVertex(MCVertex * __mcVertex)
219 {
220 printf("Deleting MC Vertex\t : ID \"%d\" at adress %x\n",__mcVertex->get_id(), __mcVertex);
221
222 _refGeom->supprimer_mg_sommetid(__mcVertex->get_id());
223 }
224 //---------------------------------------------------------------------------
225 MCEdge * MCBody::AddMCEdge(MG_ARETE * __refEdge)
226 {
227 // Construct a mc edge
228 MCEdge * newMCEdge = new MCEdge(__refEdge);
229
230 // Set the newEdge ID
231 _refGeom->ajouter_mg_courbe(newMCEdge->GetPolyCurve());
232
233 if (_refGeom->get_mg_courbeid( newMCEdge->GetPolyCurve()->get_id()) == NULL)
234 printf("PB!\n");
235
236 _refGeom->ajouter_mg_arete(newMCEdge);
237 if (_refGeom->get_mg_areteid( newMCEdge->get_id()) == NULL)
238 printf("PB!\n");
239
240 return newMCEdge;
241 }
242 //---------------------------------------------------------------------------
243 MCEdge * MCBody::AddMCEdge(MCEdge *__A, MCEdge *__B)
244 {
245 std::ostringstream idOriginal;
246 idOriginal<< __A->get_idoriginal();
247 idOriginal<<"+";
248 idOriginal<< __B->get_idoriginal();
249
250 // Create a polycurve
251 MCEdge * newMCEdge = new MCEdge( idOriginal.str(), *__A, *__B);
252
253 // Set the newEdge ID
254 _refGeom->ajouter_mg_courbe(newMCEdge->GetPolyCurve());
255
256 if (_refGeom->get_mg_courbeid( newMCEdge->GetPolyCurve()->get_id()) == NULL)
257 printf("PB!\n");
258
259 _refGeom->ajouter_mg_arete(newMCEdge);
260 if (_refGeom->get_mg_areteid( newMCEdge->get_id()) == NULL)
261 printf("PB!\n");
262
263 return newMCEdge;
264 }
265 //---------------------------------------------------------------------------
266 MCEdge * MCBody::AddMCEdge(PolyCurve *__curve)
267 {
268 std::ostringstream idOriginal;
269 idOriginal<< "MCEdge" ;
270 for (unsigned i=0; i<__curve->GetRefEdgeCount(); i++)
271 idOriginal<<"-"<<__curve->GetRefEdge(i)->get_id();
272 MCEdge * newMCEdge = new MCEdge(idOriginal.str(), __curve);
273
274 // Set the newEdge ID
275 _refGeom->ajouter_mg_courbe(newMCEdge->GetPolyCurve());
276
277 if (_refGeom->get_mg_courbeid( newMCEdge->GetPolyCurve()->get_id()) == NULL)
278 printf("PB!\n");
279
280 _refGeom->ajouter_mg_arete(newMCEdge);
281 if (_refGeom->get_mg_areteid( newMCEdge->get_id()) == NULL)
282 printf("PB!\n");
283
284 return newMCEdge;
285 }
286
287 //---------------------------------------------------------------------------
288 Graph::Graph * MCBody::G10() const
289 {
290 return _G10;
291 }
292
293 //---------------------------------------------------------------------------
294 Graph::Graph * MCBody::G21() const
295 {
296 return _G21;
297 }
298
299 //---------------------------------------------------------------------------
300 Graph::Graph * MCBody::G20() const
301 {
302 return _G20;
303 }
304
305 //---------------------------------------------------------------------------
306 MCEdge* MCBody::GetMCEdge(int __id) const
307 {
308 Graph::Node * node = _G10->GetNode(__id);
309
310 if (node)
311 return GetMCEdge(node);
312 else
313 cout << "GetMCEdge : Error: Did not find the MCEdge corresponding to the ID \""<<__id<<"\"\n";
314
315 return NULL;
316 }
317
318 //---------------------------------------------------------------------------
319 MCEdge* MCBody::GetMCEdge(Graph::GraphObject * __graphObject)
320 {
321 return (MCEdge *) __graphObject->GetUserData();
322 }
323
324 //---------------------------------------------------------------------------
325 bool MCBody::Contains(MCEdge * __mcEdge) const
326 {
327 Graph::Node * n = _G10->GetNode(__mcEdge->get_id());
328
329 if (!n)
330 return false;
331
332 return ( n->GetUserData() == __mcEdge );
333 }
334
335 //---------------------------------------------------------------------------
336 MCVertex * MCBody::AddMCVertex(MG_SOMMET * __refVertex)
337 {
338 double pos[3]; __refVertex->get_point()->evaluer(pos);
339 MCVertex *mcVertex = new MCVertex(__refVertex);
340
341 // Add the vertex to the geometry manager in order to
342 // set its ID
343 _refGeom->ajouter_mg_sommet(mcVertex);
344
345 return mcVertex;
346 }
347
348 //---------------------------------------------------------------------------
349 MCVertex* MCBody::GetMCVertex(int __id)const
350 {
351 Graph::Arc * arc;
352 arc = _G10->GetArc(__id);
353 if (arc)
354 return GetMCVertex(arc);
355 else
356 {
357 printf("Error in GetMCVertex (int id) method : can't find the arc ID %d in G10 Graph !\n", __id);
358 }
359 return NULL;
360 }
361
362 //---------------------------------------------------------------------------
363 bool MCBody::Contains(MCVertex * __mcVertex) const
364 {
365 Graph::Arc * a = _G10->GetArc(__mcVertex->get_id());
366
367 if (!a)
368 return false;
369
370 return (a->GetUserData() == __mcVertex );
371 }
372
373 //---------------------------------------------------------------------------
374 MCVertex * MCBody::GetMCVertex(Graph::GraphObject * __graphObject)
375 {
376 return (MCVertex*) __graphObject->GetUserData();
377 }
378
379 //---------------------------------------------------------------------------
380 void MCBody::InitHyperGraphs()
381 {
382 int j, k;
383 _G21 = new Graph::Graph;
384 _G10 = new Graph::Graph;
385 _G20 = new Graph::Graph;
386
387 std::set < MG_FACE * > lst_ref_faces;
388 std::set < MG_ARETE * > lst_ref_edges;
389 std::set < MG_SOMMET * > lst_ref_vertices;
390
391 // initialize face, edge, and vertices lists
392 unsigned nb_shells = _refBody->get_nb_mg_coquille ();
393 for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
394 {
395 MG_COQUILLE * shell = _refBody->get_mg_coquille(it_shells);
396 unsigned nb_coface = shell->get_nb_mg_coface();
397 for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
398 {
399 MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
400 lst_ref_faces.insert(face);
401
402 unsigned nb_loop = face->get_nb_mg_boucle();
403 for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
404 {
405 MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
406 unsigned nb_edge = loop->get_nb_mg_coarete();
407
408 for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
409 {
410 MG_ARETE * edge = loop->get_mg_coarete(it_edge)->get_arete();
411 lst_ref_edges.insert(edge);
412
413 lst_ref_vertices.insert (edge->get_cosommet1()->get_sommet());
414 lst_ref_vertices.insert (edge->get_cosommet2()->get_sommet());
415 }
416 }
417 }
418 }
419
420
421 // Correspondance map between Reference Entities and MC entities
422 std::map <MG_FACE *, MCFace *> mapRefToMCFace;
423 std::map <MG_ARETE *, MCEdge *> mapRefToMCEdge;
424 std::map <MG_SOMMET *, MCVertex *> mapRefToMCVertex;
425
426 // Create the MC Vertices
427 for (std::set<MG_SOMMET*>::iterator it_vert = lst_ref_vertices.begin();
428 it_vert != lst_ref_vertices.end(); it_vert++)
429 {
430 MG_SOMMET * refVertex = *it_vert;
431 // Create the MC Vertex
432 // and initialize the Indentifier using the Geometry manager
433 MCVertex * mcVertex = AddMCVertex(refVertex);
434 // Map the MC Vertex to its reference vertex in the correspondance map
435 mapRefToMCVertex [ refVertex ] = mcVertex;
436 }
437
438 // Create the MC Edges
439 for (std::set <MG_ARETE *>::iterator it_edge = lst_ref_edges.begin();
440 it_edge != lst_ref_edges.end();
441 it_edge ++)
442 {
443 MG_ARETE * refEdge = *it_edge;
444 // Create the MC Edge
445 // and initialize the Indentifier using the Geometry manager
446 MCEdge * mcEdge = AddMCEdge(refEdge);
447 // Map the MC Edge to its reference edge in the correspondance map
448 mapRefToMCEdge [ refEdge ] = mcEdge;
449 }
450
451 // Create the MC Faces
452 for (std::set<MG_FACE*>::iterator it_face = lst_ref_faces.begin();
453 it_face != lst_ref_faces.end();
454 it_face++)
455 {
456 MG_FACE * refFace = *it_face;
457 // Create the MC Face
458 // and initialize the Indentifier using the Geometry manager
459 MCFace * mcFace = AddMCFace(refFace);
460 // Map the MC Face to its reference Face in the correspondance map
461 mapRefToMCFace [ refFace ] = mcFace;
462 }
463
464 // for each face of the reference topology
465 for (std::set<MG_FACE*>::iterator it_face = lst_ref_faces.begin();
466 it_face != lst_ref_faces.end();
467 it_face++)
468 {
469 MG_FACE * refFace = *it_face;
470
471 // Get the MCFace corresponding to the reference face
472 MCFace * mcFace = mapRefToMCFace [ refFace ];
473
474 printf("Initializing\tMC Face\tID \"%d\" \t(Ref Face ID \"%d\")\n",mcFace->get_id(), refFace->get_id());
475
476 // Add a node in _G21 and _G20
477 _G21->AddNode (mcFace->get_id());
478 _G20->AddNode (mcFace->get_id());
479
480 // initialize graph G21 and G20 nodes to face
481 Graph_SetUserData(mcFace);
482 }
483
484 // For each edge of refBody :
485 // create an arc in G21 and connect-it to each nodes of adjacent faces
486 // create a node in G1
487 for (std::set <MG_ARETE *>::iterator it_edge = lst_ref_edges.begin();
488 it_edge != lst_ref_edges.end();
489 it_edge ++)
490 {
491 MG_ARETE * refEdge = *it_edge;
492
493 // Get the MCEdge corresponding to the reference Edge
494 MCEdge * mcEdge = mapRefToMCEdge [ refEdge ];
495
496 // printing the step number
497 printf("Initializing\t MC Edge\t%d of %d : ID = \"%d\" \t(Reference Edge ID \"%d\")\n", std::distance(lst_ref_edges.begin(), it_edge)+1, lst_ref_edges.size(), mcEdge->get_id(), refEdge->get_id());
498
499 // create a node in G1
500
501 // add a node in _G10
502 _G10->AddNode (mcEdge->get_id());
503
504 // create an arc in G21 and connect-it to each nodes of adjacent faces
505 std::vector <int> nodes;
506 for (int j=0; j < refEdge->get_nb_mg_coarete(); j++)
507 {
508 MG_FACE * refFace = refEdge->get_mg_coarete(j)->get_boucle()->get_mg_face();
509 // mcFace = adjacent face
510 MCFace * mcFace = mapRefToMCFace [ refFace ];
511
512 // connect arc to adjacent faces
513 nodes.push_back(mcFace->get_id());
514 }
515 _G21->AddArc(nodes, mcEdge->get_id());
516
517 // initialize graph G21 arcs and G10 nodes to MC Edge
518 Graph_SetUserData(mcEdge);
519 }
520
521
522 // For each ref vertex of reference Body :
523 for (std::set<MG_SOMMET*>::iterator it_vertex = lst_ref_vertices.begin();
524 it_vertex != lst_ref_vertices.end();
525 it_vertex++)
526 {
527 MG_SOMMET * refVertex = *it_vertex;
528
529 // Get the MCVertex corresponding to the reference Vertex
530 MCVertex * mcVertex = mapRefToMCVertex [ refVertex ];
531
532 // -------------- G20 Arc --------------------------------------------
533 // create an arc in G20 and connect-it to each nodes of adjacent faces
534 {
535 std::vector <int> nodes;
536 for (unsigned j = 0; j < refVertex->get_nb_mg_cosommet(); j++)
537 {
538 MG_ARETE * refEdge = refVertex->get_mg_cosommet(j)->get_arete();
539
540 for (int k=0; k < refEdge->get_nb_mg_coarete(); k++)
541 {
542 MG_FACE * refFace = refEdge->get_mg_coarete(k)->get_boucle()->get_mg_face();
543 MCFace * mcFace = mapRefToMCFace [ refFace ];
544
545 if (std::find (nodes.begin(), nodes.end(), mcFace->get_id()) == nodes.end())
546 nodes.push_back(mcFace->get_id());
547 }
548 }
549 // create a graph-arc in G20
550 _G20->AddArc(nodes, mcVertex->get_id());
551 }
552
553
554 // -------------- G10 Arc --------------------------------------------
555 // create an arc in G10 and connect-it to each nodes of adjacent edges
556 {
557 std::vector <int> nodes;
558 for (unsigned j = 0; j < refVertex->get_nb_mg_cosommet(); j++)
559 {
560 MG_ARETE * refEdge = refVertex->get_mg_cosommet(j)->get_arete();
561 MCEdge * mcEdge = mapRefToMCEdge [ refEdge ];
562
563 nodes.push_back(mcEdge->get_id());
564 }
565 // create a graph-arc in G10
566 _G10->AddArc(nodes, mcVertex->get_id());
567 }
568
569 // initialize graph G10 arc and G20 arc to MC Vertex
570 Graph_SetUserData(mcVertex);
571 }
572
573 // Add covertices for each edge
574 {
575 MCBODY_FOR_EACH_MCEDGE(this, mcEdge)
576 {
577 std::vector <MCVertex*> extremities;
578 Edge_GetVertices(mcEdge, extremities);
579 AddMCEdgeCovertices(mcEdge, extremities);
580 }
581 }
582 }
583
584 //---------------------------------------------------------------------------
585 int
586 MCBody::G2ToNeatoFile (Graph::Graph * __G2,
587 char * __filename,
588 char *__graphname)
589 {
590 using std::cout;
591 std::ofstream neatoFile;
592 neatoFile.open( __filename );
593 neatoFile << NeatoGraph(*__G2);
594
595 neatoFile.close(); //explicit
596
597 return 0;
598 }
599 //---------------------------------------------------------------------------
600 // Create a MCVertex with a defined label
601 MCVertex * MCBody::CreateMCVertex (MG_SOMMET * __refVertex)
602 {
603 // Create the MC Vertex in G20 and G10
604
605 MCVertex * mcVertex = new MCVertex (__refVertex);
606
607 _refGeom->ajouter_mg_sommet(mcVertex);
608
609 int id = mcVertex->get_id();
610 Graph::Arc * G20Arc = _G20->AddArc(id, 0 /*rank=0*/);
611 Graph::Arc * G10Arc = _G10->AddArc(id, 0 /*rank=0*/);
612
613 Graph_SetUserData(mcVertex);
614
615 return mcVertex;
616 }
617
618 //---------------------------------------------------------------------------
619 // Split an MC edge by inserting one MC vertex in its domain
620 void MCBody::SplitEdge(MCEdge * __mcEdge, double __xyz[3], MCTChanges * __mctChanges, RTChanges * __rtChanges)
621 {
622 MG_ARETE *__origRefEdge;
623 MG_SOMMET * __splitRefVertex;
624 MG_ARETE *__splitRefEdges[2];
625 MCVertex * __mcVertex;
626 MCEdge *__result[2];
627 int i;
628
629 // store the extremities of the original edge in a vector
630 std::vector <MCVertex * > origEdgeExtremities;
631 Edge_GetVertices ( __mcEdge, origEdgeExtremities );
632
633 // split curves
634 PolyCurve * edgePolyCurve = __mcEdge->GetPolyCurve();
635 PolyCurve * curves[2];
636 SplitPolyCurve(edgePolyCurve, __xyz, _refBody, _refGeom, curves, &__origRefEdge, &__splitRefVertex, __splitRefEdges);
637 if ( __splitRefVertex == NULL )
638 {
639 printf("Can't split MC Edge in MC body\n");
640 return;
641 }
642 _refGeom->ajouter_mg_sommet(__splitRefVertex);
643
644 __mcVertex = CreateMCVertex(__splitRefVertex);
645
646 printf("Inserting MC Vertex\t : ID \"%d\" \n", __mcVertex->get_id());
647
648 // Create the two MC Edges
649 for ( i=0; i<2; i++)
650 {
651 __result[i] = AddMCEdge(curves[i]);
652 __result[i]->copie_ccf(*__mcEdge);
653 }
654
655 // duplicate G21A to get 2 parallel arcs
656 Graph::Arc * G21A[3];
657 G21A[2] = _G21->GetArc(__mcEdge->get_id());
658 int faceId[2];
659
660 // save the G21 nodes adjacent to the mc Edges's arc
661 Graph::Node * G21N[2];
662 i=0;
663 for (Graph::Arc::MultimapNodesById::iterator itG21Node = G21A[2]->Nodes().begin();
664 itG21Node != G21A[2]->Nodes().end();
665 itG21Node++ )
666 {
667 faceId[i] = itG21Node->first;
668 G21N[i++] = itG21Node->second;
669 }
670
671
672 // Set edges id
673 int edgeId[3];
674 edgeId[2] = __mcEdge->get_id();
675 for (i = 0; i < 2; i++)
676 edgeId[i] = __result[i]->get_id();
677
678 // Duplicate the G21 arc of the split edge
679 for (i = 0; i < 2; i++)
680 G21A[i] = _G21->DuplicateArc(G21A[2], edgeId[i]);
681 // Remove the G21 Arc of the split edge
682 _G21->RemoveArc(G21A[2]);
683
684 // split the G10 node of the split edge
685 Graph::Arc * G10A[3];
686 Graph::Node * G10N[3];
687 G10A[2] = _G10->GetArc( __mcVertex->get_id() ); // the arc representing the split vertex
688 G10N[2] = _G10->GetNode( __mcEdge->get_id() );
689 // delete the G10 node of the old edge
690 _G10->RemoveNode(G10N[2]);
691 // Add two new nodes
692 for ( i=0; i<2; i++)
693 G10N[i] = _G10->AddNode(edgeId[i]);
694 // Add an arc linking the 2 nodes. This arc represents the split vertex
695 // Link the G10 arc of the MC vertex to the 2 nodes representing the edges
696 for (i=0; i<2; i++)
697 {
698 G10A[2]->Add(G10N[i]);
699 G10N[i]->Add(G10A[2]);
700 }
701
702 for (i=0; i<2; i++)
703 {
704 MG_SOMMET * refVertex = NULL;
705 if (curves[i]->get_sommet1()->get_id() != __mcVertex->GetRefVertex()->get_id())
706 refVertex = curves[i]->get_sommet1();
707 else
708 refVertex = curves[i]->get_sommet2();
709 MCVertex * V;
710
711 for (int j=0; j<2; j++)
712 if (origEdgeExtremities[j]->Contains( refVertex ))
713 V = origEdgeExtremities[j];
714
715 G10A[i] = _G10->GetArc(V->get_id());
716 }
717
718
719 // add new node[i] in arc[i]
720 for ( i=0; i<2; i++)
721 {
722 G10A[i]->Add(G10N[i]);
723 G10N[i]->Add(G10A[i]);
724 }
725
726 // Add an arc in G20
727 Graph::Arc * G20Arc = _G20->GetArc(__mcVertex->get_id());
728 Graph::Node * G20Node[2];
729 for ( i=0; i<2; i++)
730 {
731 G20Node[i] = _G20->GetNode(faceId[i]);
732 G20Arc->Add(G20Node[i]);
733 G20Node[i]->Add(G20Arc);
734 }
735
736 printf("G10A[2]->Rank = %d\n", G10A[2]->Rank());
737 printf("G20A[2]->Rank = %d\n", _G20->GetArc(__mcVertex->get_id())->Rank());
738
739 /// Operations using the resulting Graph of this MC Edge
740 /// split :
741 /// Get the vertex extremities of both new MC Edge
742 /// and Add 2 Covertices
743 for (i=0; i<2; i++)
744 {
745 MCEdge * newMCEdge = __result[i];
746
747 std::vector<MCVertex*> mcVertexExtremities;
748 Edge_GetVertices(newMCEdge, mcVertexExtremities);
749 AddMCEdgeCovertices(newMCEdge, mcVertexExtremities);
750
751 /// Set graph user Data of new MCEdge G21 Arc and G10 Node
752 Graph_SetUserData(newMCEdge);
753 }
754
755 // Deleted and Created MC Topology
756 if (__mctChanges)
757 {
758 // a new vertex has been created
759 __mctChanges->V.insert( std::make_pair ((MCVertex*)NULL, __mcVertex));
760 // __mcEdge has been replaces by 2 new edges
761 __mctChanges->E.insert( std::make_pair (__mcEdge, (MCEdge*) NULL) );
762 __mctChanges->E.insert( std::make_pair ((MCEdge*) NULL, __result[0]) );
763 __mctChanges->E.insert( std::make_pair ((MCEdge*) NULL, __result[1]) );
764 }
765
766 // Deleted and created Reference Topology
767 if (__rtChanges)
768 {
769 // a new vertex __splitRefVertex has been created
770 __rtChanges->V.insert( std::make_pair ((MCVertex*)NULL , __splitRefVertex) );
771 // __origRefEdge has been replaces by 2 new edges __splitRefEdges
772 __rtChanges->E.insert( std::make_pair (__origRefEdge , __splitRefEdges[0]) );
773 __rtChanges->E.insert( std::make_pair (__origRefEdge , __splitRefEdges[1]) );
774 }
775 }
776
777 //---------------------------------------------------------------------------
778 int
779 MCBody::G1ToNeatoFile (Graph::Graph * __G1,
780 char * __filename,
781 char *__graphname)
782 {
783 using std::cout;
784 std::ofstream neatoFile;
785 neatoFile.open( __filename );
786 neatoFile << "graph \""<< __graphname <<"\" {" << std::endl;
787 neatoFile << "node [ shape=box , color = blue ]\n";
788
789 //////// G1 graph
790 GRAPH_FOR_EACH_ARC_CONST(__G1,itarcs)
791 {
792 neatoFile << "\""<<itarcs->first<<"\" [ shape=point, style=filled, fillcolor=red ]\n";
793
794 ARC_FOR_EACH_NODE_CONST( itarcs->second, itnodes)
795 {
796 neatoFile << "\""<< itnodes->first << "\"";
797 neatoFile << " -- ";
798 neatoFile << "\""<< itarcs->first << "\"";
799 neatoFile << " [ len=1 ] ";
800 neatoFile << std::endl;
801 }
802 }
803 neatoFile << "}" << std::endl;
804 neatoFile << std::endl;
805
806 neatoFile.close(); //explicit
807
808 return 0;
809 }
810
811 //---------------------------------------------------------------------------
812 void
813 MCBody::SuppressMCEdge(MCEdge * __mcEdge, MCFace * __F[3])
814 {
815 int i;
816 int __id = __mcEdge->get_id();
817
818 // Find the arc __id in G2V (G2 Virtual)
819 Graph::Arc * arcG21 = _G21->GetArc(__id);
820
821 ///// Process G2 Graph
822 printf("Deleting MC Edge\t : ID \"%d\" at adress %x \n", __id, __mcEdge);
823
824 if ( ! arcG21->IsLoop() ) // The arc represents an boundary edge
825 {
826 // Get the two mc faces adjacent to the suppressed mc edge
827 MCFace * face[3];
828 int faceId[3];
829 Graph::Node * faceNode[3];
830
831 i = 0;
832 Graph::Arc::MultimapNodesById::iterator itNode = arcG21->Nodes().begin();
833 for (i=0; i<2; i++)
834 {
835 faceId[i] = itNode->first;
836 faceNode[i] = itNode->second;
837 face[i] = GetMCFace(faceId[i]);
838
839 itNode++;
840 }
841
842 // Merge the nodes of these 2 mc face in G21
843 // (contract the arc in G21)
844 MCFace* newMCFace = AddMCFace(face[0], face[1]);
845 faceId[2] = newMCFace->get_id();
846 faceNode[2] = _G21->MergeNodes(faceNode[0], faceNode[1], faceId[2]);
847 _G21->RemoveArc(__id);
848
849 // Merge the nodes of these 2 mc faces in G20
850 Graph::Node * mergedG20Node = _G20->MergeNodes( faceId[0], faceId[1], faceId[2]);
851
852 // Remove the node in G10
853 _G10->RemoveNode(__mcEdge->get_id());
854
855 // Attach the MC Face to Graph nodes of G21 and G10
856 Graph_SetUserData(newMCFace);
857
858 printf ("Adding new merged face %d = { %d + %d }\n", faceId[2], faceId[0], faceId[1]);
859
860 __F[0] = face[0];
861 __F[1] = face[1];
862 __F[2] = newMCFace;
863 }
864 else // The arc represents an interior edge
865 {
866 Graph::Node *n = _G21->GetArc(__id)->First();
867
868 // if the arc is a loop then delete it
869 // in G2V : delete the g2v arc from the node and from the graph
870 _G21->RemoveArc(__id);
871 // in G1V : delete the g1v node from the graph
872 _G10->RemoveNode(__id);
873
874 __F[0] = 0;
875 __F[1] = 0;
876 __F[2] = GetMCFace(n);
877 }
878 }
879
880 //---------------------------------------------------------------------------
881 void
882 MCBody::SuppressMCVertex(MCVertex * __mcVertex, MCTChanges * __mctChanges)
883 {
884 printf("Deleting MC Vertex\t : ID \"%d\" at adress %x\n",__mcVertex->get_id(), __mcVertex);
885
886 // Find the arc __name in G1V (G1 Virtual)
887 Graph::Arc *g1vArc = _G10->GetArc( __mcVertex->get_id() );
888 MCVertex * mcVertex = __mcVertex;
889
890 // Case of a B-Rep vertex separating only 2 edges
891 if ( g1vArc->Rank() == 2 )
892 {
893 // Get the 2 MC Edges separated by the MC Vertex
894 std::vector <MCEdge *> edge;
895 Vertex_GetAdjacentEdges( mcVertex, edge );
896
897 // Get the MC Faces Separated by the 2 MC Edges
898 std::set <MCFace *> listMCFaces = Edge_GetAdjacentFaces(edge[0]);
899 MCFace * mcFace[2];
900 std::set<MCFace*>::iterator itr=listMCFaces.begin();
901 for (unsigned i=0;i<2;i++)
902 {
903 mcFace[i] = *itr;
904 itr++;
905 }
906
907 // Unify parallel G21 arcs
908
909 // Create a unique arc in G2 Which connect n1 and n2
910 Graph::Arc::MultimapNodesById newG21ArcNodes = _G21->GetArc( edge[0]->get_id() )->Nodes();
911 _G21->RemoveArc( edge[0]->get_id() );
912 _G21->RemoveArc( edge[1]->get_id() );
913
914 printf("the deleted vertex was adjacent to %d / %d faces\n", _G20->GetArc( __mcVertex->get_id() )->Rank(), listMCFaces.size());
915 printf("the deleted vertex was adjacent to %d edges\n", _G10->GetArc( __mcVertex->get_id() )->Rank());
916 // attach to the new node a edge attribute
917 // constructed by the merge of the 2 edge attributes
918 MCEdge * newMCEdge = AddMCEdge(edge[0], edge[1]);
919
920 _G21->AddArc(newMCEdge->get_id(), newG21ArcNodes);
921
922 // Merge nodes G10
923 Graph::Node* n = _G10->MergeNodes(_G10->GetNode(edge[0]->get_id()), _G10->GetNode(edge[1]->get_id()), newMCEdge->get_id());
924 // Remove G10 loop-arc to newNode
925 _G10->RemoveArc( _G10->GetArc(__mcVertex->get_id()) );
926 // Remove G20 arc
927 _G20->RemoveArc( _G20->GetArc(__mcVertex->get_id()));
928
929 /// Operations using the resulting Graph of this MC Vertex
930 /// Suppression :
931 /// Get the vertex extremities of this new MC Edge
932 /// and Add 2 Covertices
933 std::vector<MCVertex*> mcVertexExtremities;
934 Edge_GetVertices(newMCEdge, mcVertexExtremities);
935 PolyCurve * newPolyCurve = newMCEdge->GetPolyCurve();
936
937 if (newPolyCurve->est_periodique())
938 if (newPolyCurve->get_sommet1() != mcVertexExtremities[0]->GetRefVertex())
939 newPolyCurve->SetPeriodicPoleRefVertex(mcVertexExtremities[0]->GetRefVertex());
940
941 AddMCEdgeCovertices(newMCEdge, mcVertexExtremities);
942 /// Set graph user Data of new MCEdge G21 Arc and G10 Node
943 Graph_SetUserData(newMCEdge);
944
945 if (__mctChanges)
946 {
947 // The mc vertex has been deleted
948 __mctChanges->V.insert( std::make_pair (__mcVertex, (MCVertex*) NULL) );
949 // The 2 adjacent edges have been merged together
950 __mctChanges->E.insert( std::make_pair (edge[0], newMCEdge) );
951 __mctChanges->E.insert( std::make_pair (edge[1], newMCEdge) );
952 }
953 }
954 else if (g1vArc->Rank() == 0)
955 { // case of a vertex isolated in the domain of a face
956 _G10->RemoveArc(_G10->GetArc(__mcVertex->get_id()));
957 _G20->RemoveArc(_G20->GetArc(__mcVertex->get_id()));
958
959 if (__mctChanges)
960 {
961 // The mc vertex has been deleted
962 __mctChanges->V.insert( std::make_pair (__mcVertex, (MCVertex*) NULL) );
963 }
964 }
965 else
966 {
967 printf("Warning : MCBody can't delete vertex %d because its rank equals %d\n", g1vArc->Rank());
968 }
969 }
970
971 //---------------------------------------------------------------------------
972 void MCBody::MergeVertices(MCVertex * __deleteVertex, MCVertex * __targetVertex, std::set<MCEdge*> & edges)
973 {
974 int V1_id, V2_id;
975 MCVertex * V1, * V2;
976 Graph::Arc * V1_G10Arc, *V2_G10Arc, *V1_G20Arc, *V2_G20Arc;
977 V1=__deleteVertex; V1_id=V1->get_id();
978 V2=__targetVertex; V2_id=V2->get_id();
979 V1_G10Arc=_G10->GetArc(V1_id);
980 V1_G20Arc=_G20->GetArc(V1_id);
981 V2_G10Arc=_G10->GetArc(V2_id);
982 V2_G20Arc=_G20->GetArc(V2_id);
983 Graph::Arc::MultimapNodesById V1_G10Arc_MapNodes = V1_G10Arc->Nodes();
984 Graph::Arc::MultimapNodesById V1_G20Arc_MapNodes = V1_G20Arc->Nodes();
985 Graph::Arc::MultimapNodesById::iterator itNode;
986
987 // Initialize edge list
988 for (itNode = V1_G10Arc_MapNodes.begin(); itNode != V1_G10Arc_MapNodes.end(); itNode++)
989 {
990 Graph::Node * n = itNode->second;
991 MCEdge * e = GetMCEdge(n);
992 edges.insert(e);
993 }
994 // Replace V1 by V2 in G20 and G10
995 for (itNode = V1_G10Arc_MapNodes.begin(); itNode != V1_G10Arc_MapNodes.end(); itNode++)
996 {
997 Graph::Node * n = itNode->second;
998 V2_G10Arc->Add(n);
999 n->Add(V2_G10Arc);
1000 }
1001 _G10->RemoveArc(V1_G10Arc);
1002 for (itNode = V1_G20Arc_MapNodes.begin(); itNode != V1_G20Arc_MapNodes.end(); itNode++)
1003 {
1004 Graph::Node * n = itNode->second;
1005 V2_G20Arc->Add(n);
1006 n->Add(V2_G20Arc);
1007 }
1008 _G20->RemoveArc(V1_G20Arc);
1009
1010 // replace each covertices to V1 by covertex to V2
1011 int i,N;
1012 N=V1->get_nb_mg_cosommet();
1013 for (i=0; i<N; i++)
1014 {
1015 MG_COSOMMET * cov = V1->get_mg_cosommet(i);
1016 MCEdge * e = (MCEdge*) cov->get_arete();
1017
1018 cov = _refGeom->ajouter_mg_cosommet(e,V2);
1019
1020 if (e->get_cosommet1()->get_sommet()==V1)
1021 e->changer_cosommet1(cov);
1022 else if (e->get_cosommet2()->get_sommet()==V1)
1023 e->changer_cosommet2(cov);
1024 }
1025
1026 V2->Merge(V1);
1027 }
1028 //---------------------------------------------------------------------------
1029 /**
1030 * Edge collapse operator
1031 * arguments : name of the edge to be contracted, name of the vertex to contract the edge on
1032 *
1033 */
1034 void MCBody::ContractEdgeToVertex(MCEdge * __mcEdge, MCVertex * __targetVertex, std::set <MCEdge*> & newEdges, std::set<MCEdge*> & oldEdges)
1035 {
1036 // E3 = mcedge V3 = target vertex V4 = delete vertex
1037 printf("Contracting\tMC Edge \"%d\" to MC Vertex \"%d\"\n", __mcEdge->get_id(), __targetVertex->get_id());
1038
1039 MCVertex * V3 = __targetVertex, * V4;
1040 MCEdge * E3 = __mcEdge;
1041 int V4_id, V3_id, E3_id;
1042 Graph::Arc * V4_G10Arc, *V3_G10Arc, * V4_G20Arc, *V3_G20Arc, * E3_G21Arc;
1043 Graph::Node * E3_G10Node;
1044
1045 V3_id = V3->get_id();
1046 V3_G10Arc = _G10->GetArc(V3_id);
1047 V3_G20Arc = _G20->GetArc(V3_id);
1048
1049 E3_id = E3->get_id();
1050 E3_G10Node = _G10->GetNode(E3_id);
1051 E3_G21Arc = _G21->GetArc(E3_id);
1052
1053 // Get G1 arc V4 the second incident arc to E3 different to V3
1054 for (Graph::Node::MultimapArcsById::const_iterator incidentArcIter = E3_G10Node->IncidentArcs().begin();
1055 incidentArcIter != E3_G10Node->IncidentArcs().end();
1056 incidentArcIter++)
1057 if (incidentArcIter->first != V3_id)
1058 V4_G10Arc = incidentArcIter->second;
1059 V4 = GetMCVertex(V4_G10Arc);
1060 V4_id = V4->get_id();
1061 V4_G20Arc = _G20->GetArc(V4_id);
1062
1063 // Merge E3 with edges that are adjacent to V4
1064 // get the nodes of the arc
1065 Graph::Arc::MultimapNodesById initialV4Nodes = V4_G10Arc->Nodes();
1066 for (Graph::Arc::MultimapNodesById::const_iterator itNode = initialV4Nodes.begin();
1067 itNode != initialV4Nodes.end();
1068 itNode++)
1069 {
1070 int id = itNode->first;
1071
1072 if (V4_G10Arc->IsLoopOfNode(id) || V3_G10Arc->IsLoopOfNode(E3_id)|| V4_G10Arc->IsLoopOfNode(E3_id) )
1073 {
1074 printf("Warning while Contracting\tMC Edge \"%d\" to MC Vertex \"%d\" \nArc %d is a loop of node %d\n",
1075 V4_id, E3_id, V3_id, id);
1076
1077 return;
1078 }
1079 }
1080
1081
1082 for (Graph::Arc::MultimapNodesById::const_iterator itNode = initialV4Nodes.begin();
1083 itNode != initialV4Nodes.end();
1084 itNode++)
1085 {
1086 oldEdges.insert(GetMCEdge(itNode->second));
1087 }
1088
1089 for (Graph::Arc::MultimapNodesById::const_iterator itNode = initialV4Nodes.begin();
1090 itNode != initialV4Nodes.end();
1091 itNode++)
1092 {
1093 int id = itNode->first;
1094 Graph::Node * node = itNode->second;
1095
1096 if (id != E3_id)
1097 {
1098
1099 // attach to the new node a MC edge attribute
1100 // constructed by the merge of the 2 edge attributes
1101 MCEdge * newEdge = AddMCEdge(GetMCEdge(id), E3);
1102 int newId = newEdge->get_id();
1103
1104 Graph::Node * newG10Node = _G10->MergeNodes(node, E3_G10Node, newId, true);
1105 printf("Edge Contraction : merging edges %d and %d in new edge %d\n", node->Id(), E3_id, newId);
1106
1107 // Create an edge in G2 named newVEdgeName and
1108 // conecting nodes n1_g2nodes
1109 Graph::Arc* newG21Arc = _G21->AddArc(newId, _G21->GetArc(id)->Nodes());
1110
1111 newEdges.insert(newEdge);
1112 }
1113 }
1114 for (Graph::Arc::MultimapNodesById::const_iterator itNode = V4_G20Arc->Nodes().begin();
1115 itNode != V4_G20Arc->Nodes().end();
1116 itNode++)
1117 {
1118 Graph::Node * n = itNode->second;
1119 int idN = itNode->first;
1120 if (E3_G21Arc->Nodes().find(idN) == E3_G21Arc->Nodes().end())
1121 {
1122 V3_G20Arc->Add(n);
1123 n->Add(V3_G20Arc);
1124 }
1125 }
1126 for (Graph::Arc::MultimapNodesById::const_iterator itNode = initialV4Nodes.begin();
1127 itNode != initialV4Nodes.end();
1128 itNode++)
1129 {
1130 // in G1 : remove the old edges adjacent to v4
1131 _G10->RemoveNode(itNode->first);
1132
1133 // In G2 :
1134 // remove the old edges adjacent to v4
1135 _G21->RemoveArc(itNode->first);
1136 }
1137
1138 _G20->RemoveArc(V4_id);
1139 _G10->RemoveArc(V4_id);
1140
1141 for (std::set<MCEdge*>::iterator itEdge=newEdges.begin();itEdge!=newEdges.end();itEdge++)
1142 {
1143 MCEdge * newEdge = *itEdge;
1144 Graph_SetUserData(newEdge);
1145 std::vector<MCVertex*> mcVertexExtremities;
1146 Edge_GetVertices(newEdge, mcVertexExtremities);
1147 AddMCEdgeCovertices(newEdge, mcVertexExtremities);
1148 }
1149
1150 V3->Merge(V4);
1151 }
1152
1153 //---------------------------------------------------------------------------
1154 void MCBody::Edge_GetVertices (MCEdge * __mcEdge, std::vector<MCVertex*> & __mcVertices)
1155 {
1156 // Get the incident G10 arcs to G10 node
1157 // they compose the loops of the MC face
1158
1159 Graph::Node::MultimapArcsById & arcsOfG10Node = _G10->GetNode( __mcEdge->get_id() )->IncidentArcs();
1160
1161 // Get each MC edge from incident arcs
1162 for ( Graph::Node::MultimapArcsById::const_iterator it = arcsOfG10Node.begin();
1163 it != arcsOfG10Node.end(); it++)
1164 {
1165 __mcVertices.push_back(GetMCVertex (it->second));
1166 }
1167 }
1168
1169 //---------------------------------------------------------------------------
1170 std::set < MCFace * >
1171 MCBody::Edge_GetAdjacentFaces(MCEdge * __mcEdge)
1172 {
1173 std::set < MCFace * > result;
1174
1175 // Get the G21 nodes to G21 arc
1176 // they compose the MC faces adjacent to the MC edge
1177 Graph::Arc *G21Arc = _G21->GetArc(__mcEdge->get_id());
1178
1179 Graph::Arc::MultimapNodesById & nodesOfG21Arc = G21Arc->Nodes();
1180
1181
1182 for (Graph::Arc::MultimapNodesById::const_iterator it = nodesOfG21Arc.begin();
1183 it != nodesOfG21Arc.end();
1184 it++)
1185 {
1186
1187 MCFace *mcFace = GetMCFace(it->second);
1188 result.insert( mcFace );
1189
1190 }
1191
1192 return result;
1193 }
1194
1195
1196 //---------------------------------------------------------------------------
1197 std::set < MCEdge * >
1198 MCBody::Face_GetAdjacentEdges(MCFace * __mcFace)
1199 {
1200 std::set < MCEdge * > result;
1201
1202 // Get the G21 arcs to G21 node
1203 // they compose the MC edges adjacent to the MC face
1204 Graph::Node *G21Node = _G21->GetNode(__mcFace->get_id());
1205
1206 Graph::Node::MultimapArcsById & arcsOfG21Node = G21Node->IncidentArcs();
1207
1208
1209 for (Graph::Node::MultimapArcsById::const_iterator it = arcsOfG21Node.begin();
1210 it != arcsOfG21Node.end();
1211 it++)
1212 {
1213
1214 result.insert( GetMCEdge(it->second) );
1215
1216 }
1217
1218 return result;
1219 }
1220
1221 std::vector < std::vector < MCEdge * > >
1222 MCBody::Face_GetUnsortedLoops(MCFace * __mcFace)
1223 {
1224 std::set < std::set < Graph::Node * > > loops;
1225 std::vector < std::vector < MCEdge * > > result;
1226
1227 // Extract G 10 subgraph of this face
1228 Graph::Graph * G10 = Face_G10SubGraph(__mcFace);
1229
1230 // Extract Strongly Connected Components
1231 // The SCC represent the BRep loop edges !
1232 std::set < std::set < Graph::Node * > > scc;
1233 Graph::FindSCC(G10,scc);
1234
1235 for (std::set < std::set < Graph::Node * > >::iterator it1 = scc.begin();
1236 it1 != scc.end();
1237 it1++
1238 )
1239 {
1240 std::vector <MCEdge * > loop;
1241 std::set < Graph::Node * > & loopNodes = *it1;
1242 for ( std::set < Graph::Node * >::iterator it2 = loopNodes.begin();
1243 it2 != loopNodes.end();
1244 it2++)
1245 {
1246 Graph::Node * node = *it2;
1247 MCEdge * mcEdge = GetMCEdge( node );
1248 loop.push_back(mcEdge);
1249 }
1250 result.push_back(loop);
1251 }
1252
1253 delete G10;
1254 return result;
1255 }
1256
1257 std::vector < std::vector < MCEdge * > >
1258 MCBody::Face_GetCycles(MCFace * __mcFace)
1259 {
1260 std::set < std::set < Graph::Node * > > loops;
1261 std::vector < std::vector < MCEdge * > > result;
1262
1263 // Extract G 10 subgraph of this face
1264 Graph::Graph * G10 = Face_G10SubGraph(__mcFace);
1265
1266 // Extract Graph cycles
1267 // The graph cycles represent loops which toopology is a circle !
1268 std::vector < std::vector < Graph::Node * > > cycles;
1269 Graph::FindCycles(G10,cycles);
1270
1271 for (std::vector < std::vector < Graph::Node * > >::iterator it1 = cycles.begin();
1272 it1 != cycles.end();
1273 it1++
1274 )
1275 {
1276 std::vector <MCEdge * > mcEdgeLoop;
1277 std::vector < Graph::Node * > & cycleNodes = *it1;
1278 for ( std::vector < Graph::Node * >::iterator it2 = cycleNodes.begin();
1279 it2 != cycleNodes.end();
1280 it2++)
1281 {
1282 Graph::Node * node = *it2;
1283 MCEdge * mcEdge = GetMCEdge( node );
1284 mcEdgeLoop.push_back(mcEdge);
1285 }
1286 result.push_back(mcEdgeLoop);
1287 }
1288
1289 for (Graph::Graph::MapNodesById::const_iterator itNode = G10->GetNodes().begin();
1290 itNode != G10->GetNodes().end();
1291 itNode++)
1292 {
1293 Graph::Node * node = itNode->second;
1294 for (Graph::Node::MultimapArcsById::const_iterator itArc = node->IncidentArcs().begin();
1295 itArc != node->IncidentArcs().end();
1296 itArc ++)
1297 {
1298 Graph::Arc * arc = itArc->second;
1299 if ( arc->IsLoopOfNode(node->Id()) )
1300 {
1301 std::vector < MCEdge * > loop;
1302 MCEdge * mcEdge = GetMCEdge(node);
1303 loop.push_back(mcEdge);
1304 result.push_back(loop);
1305 }
1306 }
1307 }
1308
1309 delete G10;
1310 return result;
1311 }
1312 //---------------------------------------------------------------------------
1313 void MCBody::Face_GetMCVertices (MCFace * __mcFace, std::vector<MCVertex*> & __mcVertices)
1314 {
1315 // Get the incident G20 arcs to G20 node
1316 const Graph::Node::MultimapArcsById & arcsOfG20Node = _G20->GetNode(__mcFace->get_id())->IncidentArcs();
1317
1318 // Get each MC edge from incident arcs
1319 for ( Graph::Node::MultimapArcsById::const_iterator it = arcsOfG20Node.begin();
1320 it != arcsOfG20Node.end(); it++)
1321 {
1322 __mcVertices.push_back(GetMCVertex (it->second));
1323 }
1324 }
1325
1326 //---------------------------------------------------------------------------
1327 void MCBody::Vertex_GetAdjacentEdges(MCVertex * __mcVertex, std::vector<MCEdge *> & __list)
1328 {
1329 __list.clear();
1330
1331 Graph::Arc * a = _G10->GetArc(__mcVertex->get_id());
1332 for (Graph::Arc::MultimapNodesById::const_iterator it = a->Nodes().begin();
1333 it != a->Nodes().end();
1334 it++)
1335 __list.push_back(GetMCEdge(it->second));
1336 }
1337
1338 //---------------------------------------------------------------------------
1339 void MCBody::Vertex_GetAdjacentEdges(MCVertex * __mcVertex, std::set<MCEdge *> & __list)
1340 {
1341 __list.clear();
1342
1343 Graph::Arc * a = _G10->GetArc( __mcVertex->get_id() );
1344 for (Graph::Arc::MultimapNodesById::const_iterator it = a->Nodes().begin();
1345 it != a->Nodes().end();
1346 it++)
1347 __list.insert(GetMCEdge(it->second));
1348 }
1349
1350
1351 //---------------------------------------------------------------------------
1352 void MCBody::Vertex_GetAdjacentFaces(MCVertex * __mcVertex, std::set<MCFace *> & __list)
1353 {
1354 __list.clear();
1355
1356 Graph::Arc * a = _G20->GetArc(__mcVertex->get_id());
1357 for (Graph::Arc::MultimapNodesById::const_iterator it = a->Nodes().begin();
1358 it != a->Nodes().end();
1359 it++)
1360 __list.insert(GetMCFace(it->second));
1361 }
1362 //---------------------------------------------------------------------------
1363 Graph::Graph * MCBody::Face_G10SubGraph(MCFace * __mcFace)
1364 {
1365 std::set < Graph::Node * > nodes;
1366 Graph::Graph * result;
1367
1368 // Get the G21 arcs to G21 node
1369 // they compose the MC edges adjacent to the MC face
1370 Graph::Node *G21Node = _G21->GetNode( __mcFace->get_id() );
1371
1372 Graph::Node::MultimapArcsById & arcsOfG21Node = G21Node->IncidentArcs();
1373
1374
1375 for (Graph::Node::MultimapArcsById::const_iterator it = arcsOfG21Node.begin();
1376 it != arcsOfG21Node.end();
1377 it++)
1378 {
1379 MCEdge * edge = GetMCEdge(it->second);
1380 Graph::Node * g10Node = _G10->GetNode(edge->get_id());
1381 nodes.insert(g10Node);
1382 }
1383
1384 result = new Graph::Graph(*_G10,nodes);
1385
1386 return result;
1387 }
1388
1389 //---------------------------------------------------------------------------
1390 MG_COARETE * MCBody::CreateCoEdge(MCFace * mcFace, MG_BOUCLE * mcLoop, MCEdge * mcEdge, int sense)
1391 {
1392 MG_COARETE * mcCoEdge = _refGeom->ajouter_mg_coarete (mcEdge, mcLoop, sense);
1393 mcLoop->ajouter_mg_coarete(mcCoEdge);
1394 return mcCoEdge;
1395 }
1396 //---------------------------------------------------------------------------
1397 int MCBody::ExportBRep_MCEdgeSense(MCFace * mcFace, MCEdge * mcEdge)
1398 {
1399
1400 // for each shell of the ref body
1401 unsigned nb_shells = _refBody->get_nb_mg_coquille ();
1402 for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
1403 {
1404 MG_COQUILLE * shell = _refBody->get_mg_coquille(it_shells);
1405 // for each coface->face F of the shell
1406 unsigned nb_coface = shell->get_nb_mg_coface();
1407 for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
1408 {
1409 MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
1410
1411 if ( ! mcFace->GetPolySurface()->Contains(face) )
1412 continue;
1413
1414 // for each loop L of this face
1415 unsigned nb_loop = face->get_nb_mg_boucle();
1416 for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
1417 {
1418 MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
1419 // for each coedge coe of L
1420 unsigned nb_edge = loop->get_nb_mg_coarete();
1421 for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
1422 {
1423 MG_COARETE * coedge = loop->get_mg_coarete(it_edge);
1424 MG_ARETE * edge = coedge->get_arete();
1425
1426 int iRefEdge = -1;
1427 for (int itRefEdge = 0; itRefEdge != mcEdge->GetPolyCurve()->GetRefEdgeCount(); itRefEdge++)
1428 {
1429
1430 if (mcEdge->GetPolyCurve()->GetRefEdge(itRefEdge) == edge)
1431 {
1432 // Do not take reference edge if it is interior to the MC Face
1433 // (e.g. boundary edge contracted along an interior edge)
1434 int nbInteriorFaces = 0;
1435 for (int it_face2 = 0; it_face2 < edge->get_nb_mg_coarete(); it_face2++)
1436 {
1437 MG_FACE * face2 = edge->get_mg_coarete(it_face2)->get_boucle()->get_mg_face();
1438 if (mcFace->GetPolySurface()->Contains(face2))
1439 nbInteriorFaces ++;
1440 }
1441 if (nbInteriorFaces == 1)
1442 iRefEdge = itRefEdge;
1443 }
1444 }
1445
1446 if ( iRefEdge != -1 )
1447 {
1448 MG_SOMMET * polycurveStartRefVertex = mcEdge->GetPolyCurve()->GetRefVertex(iRefEdge);
1449 MG_ARETE * polycurveStartRefEdge = mcEdge->GetPolyCurve()->GetRefEdge(iRefEdge);
1450
1451 // Get the start vertex of this coedge
1452 // coedgeStartVertex = start ref vertex of coe1
1453 MG_SOMMET * coedgeStartVertex;
1454 if ( coedge->get_orientation() == 1)
1455 coedgeStartVertex = edge->get_cosommet1()->get_sommet();
1456 else
1457 coedgeStartVertex = edge->get_cosommet2()->get_sommet();
1458
1459 //
1460 // sense = ( coedgeStartVertex != v1 ) ? -1 : 1 ;
1461 int sense;
1462 if ( polycurveStartRefVertex != edge->get_cosommet1()->get_sommet() )
1463 sense = -coedge->get_orientation();
1464 else
1465 sense = coedge->get_orientation();
1466
1467 /*OT_VECTEUR_3D tangentPc, tangentRefEdge;
1468 PolyCurve * pc = mcEdge->GetPolyCurve();
1469 MG_SOMMET * polycurveStartRefVertex = pc->GetRefVertex(iRefEdge);
1470 MG_SOMMET * polycurveEndRefVertex = pc->GetRefVertex(iRefEdge+1);
1471 double sMid = .5*(pc->RefVertex_GetS(polycurveStartRefVertex)+pc->RefVertex_GetS(polycurveEndRefVertex));
1472 pc->deriver(sMid, tangentPc);
1473 double tMidRefEdge, dtMidRefEdge; MG_ARETE * tmpRefEdge;
1474 pc->Parameter_SToRefEdgeT(sMid, &tmpRefEdge, &tMidRefEdge, &dtMidRefEdge, false);
1475 tmpRefEdge->deriver(tMidRefEdge, tangentRefEdge);
1476
1477 double fSense = tangentRefEdge * tangentPc;
1478 int sense;
1479 if ( fSense < 0 )
1480 sense = -coedge->get_orientation();
1481 else
1482 sense = coedge->get_orientation(); */
1483
1484 return sense;
1485 }
1486 } // end for coedge
1487 } // end for face->loop
1488 } // end for coface
1489 } // end shell
1490
1491 return NULL;
1492 }
1493 MG_VOLUME * MCBody::ExportBRep()
1494 {
1495 int i,j,k;
1496
1497 std::ostringstream idBRepVolume;
1498 idBRepVolume << "MCBody of reference BRep "<< _refBody->get_idoriginal();
1499 _brep = new MG_VOLUME (idBRepVolume.str());
1500 _refGeom->ajouter_mg_volume(_brep);
1501
1502 MG_COQUILLE * mcShell = new MG_COQUILLE(_brep);
1503 _refGeom->ajouter_mg_coquille(mcShell, _brep);
1504
1505 {MCBODY_FOR_EACH_MCFACE(this, mcFace)
1506 {
1507 _refGeom->ajouter_mg_face(mcFace);
1508
1509 MG_COFACE * mcCoFace = _refGeom->ajouter_mg_coface(mcFace, mcShell, 1);
1510 mcShell->ajouter_mg_coface(mcCoFace);
1511 MG_SURFACE * surface = mcFace->get_surface();
1512 _refGeom->ajouter_mg_surface(surface);
1513
1514 std::set <MCEdge*> mcEdgeArray = Face_GetAdjacentEdges(mcFace);
1515 std::vector <MG_FACE*> faces;std::vector <MG_ARETE*> edges;std::vector <int> edgesense;
1516 for (std::set <MCEdge*>::iterator itEdge = mcEdgeArray.begin();
1517 itEdge != mcEdgeArray.end(); itEdge++)
1518 {
1519 MCEdge * mcEdge = *itEdge;
1520
1521 bool boundaryEdge = (!_G21->GetArc(mcEdge->get_id())->IsLoop());
1522
1523 // If the MC Edge is a boundary, then create an oriented coedge
1524 if (boundaryEdge)
1525 {
1526 faces.push_back(mcFace);
1527 edges.push_back(mcEdge);
1528 int sense = ExportBRep_MCEdgeSense(mcFace,mcEdge);
1529 edgesense.push_back(sense);
1530 }
1531 // If the MC Edge is interior, then create two coedges
1532 // with same sense and inverse sense
1533 else
1534 {
1535 faces.push_back(mcFace); faces.push_back(mcFace);
1536 edges.push_back(mcEdge);edges.push_back(mcEdge);
1537 edgesense.push_back(+1);edgesense.push_back(-1);
1538 }
1539 }
1540 std::vector < std::vector<CAD4FE::MakeLoops::CoEdge*> > loops;
1541 CAD4FE::MakeLoops makeLoops(faces,edges,edgesense);
1542 makeLoops.GetFaceLoops(mcFace,loops);
1543 for (unsigned k=0;k<loops.size();k++)
1544 {
1545 MG_BOUCLE * mcLoop = new MG_BOUCLE(mcFace);
1546 _refGeom->ajouter_mg_boucle(mcLoop, mcFace);
1547 for (unsigned l=0;l<loops[k].size();l++)
1548 {
1549 CAD4FE::MakeLoops::CoEdge* c = loops[k][l];
1550 CreateCoEdge(mcFace,mcLoop,(MCEdge*)c->Edge(),c->Sense());
1551 }
1552 }
1553 }}
1554
1555 return _brep;
1556 }
1557
1558
1559 int MCBody::DeleteBRep(MG_GESTIONNAIRE * gest, MG_GEOMETRIE * mggeo)
1560 {
1561 /// Lists of MCT entities
1562 std::set < CAD4FE::MCFace * > lst_mc_faces;
1563 std::set < CAD4FE::MCEdge * > lst_mc_edges;
1564 std::set < CAD4FE::MCVertex * > lst_mc_vertices;
1565 std::set < MG_COQUILLE * > lst_mc_shell;
1566 std::set < MG_BOUCLE * > lst_mc_loop;
1567
1568 // initialize MC face, MC edge, MC loop, MC shell, and MC vertices lists
1569 unsigned nb_shells = _brep->get_nb_mg_coquille ();
1570 for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
1571 {
1572 MG_COQUILLE * shell = _brep->get_mg_coquille(it_shells);
1573 lst_mc_shell.insert(shell);
1574 unsigned nb_coface = shell->get_nb_mg_coface();
1575 for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
1576 {
1577 CAD4FE::MCFace * face = (CAD4FE::MCFace *)shell->get_mg_coface(it_coface)->get_face();
1578 lst_mc_faces.insert(face);
1579
1580 unsigned nb_loop = face->get_nb_mg_boucle();
1581 for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
1582 {
1583 MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
1584 lst_mc_loop.insert(loop);
1585 unsigned nb_edge = loop->get_nb_mg_coarete();
1586
1587 for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
1588 {
1589 CAD4FE::MCEdge * edge = (CAD4FE::MCEdge*)loop->get_mg_coarete(it_edge)->get_arete();
1590 lst_mc_edges.insert(edge);
1591
1592 lst_mc_vertices.insert ((CAD4FE::MCVertex*)edge->get_cosommet1()->get_sommet());
1593 lst_mc_vertices.insert ((CAD4FE::MCVertex*)edge->get_cosommet2()->get_sommet());
1594 }
1595 }
1596 }
1597 }
1598
1599 for (unsigned i=0;i<gest->get_nb_mg_maillage();)
1600 {
1601 MG_MAILLAGE * tmpMesh = gest->get_mg_maillage(i);
1602 LISTE_MG_TRIANGLE::iterator itTri;
1603 for (MG_TRIANGLE * tri = tmpMesh->get_premier_triangle(itTri);
1604 tri; tri = tmpMesh->get_suivant_triangle(itTri))
1605 if (lst_mc_faces.end() != lst_mc_faces.find((CAD4FE::MCFace*)tri->get_lien_topologie()))
1606 tmpMesh->supprimer_mg_triangleid(tri->get_id());
1607 LISTE_MG_SEGMENT::iterator itSeg;
1608 for (MG_SEGMENT * seg = tmpMesh->get_premier_segment(itSeg);
1609 seg; seg=tmpMesh->get_suivant_segment(itSeg) )
1610 if (lst_mc_edges.end() != lst_mc_edges.find((CAD4FE::MCEdge*)seg->get_lien_topologie())
1611 || lst_mc_faces.end() != lst_mc_faces.find((CAD4FE::MCFace*)seg->get_lien_topologie())
1612 )
1613 tmpMesh->supprimer_mg_segmentid(seg->get_id());
1614 LISTE_MG_NOEUD::iterator itNo;
1615 for (MG_NOEUD * no = tmpMesh->get_premier_noeud(itNo);
1616 no; no=tmpMesh->get_suivant_noeud(itNo))
1617 if (
1618 lst_mc_vertices.end() != lst_mc_vertices.find((CAD4FE::MCVertex*)no->get_lien_topologie())
1619 || lst_mc_edges.end() != lst_mc_edges.find((CAD4FE::MCEdge*)no->get_lien_topologie())
1620 || lst_mc_faces.end() != lst_mc_faces.find((CAD4FE::MCFace*)no->get_lien_topologie())
1621 )
1622 tmpMesh->supprimer_mg_noeudid(no->get_id());
1623
1624 if (tmpMesh->get_nb_mg_noeud() == 0)
1625 gest->supprimer_mg_maillage(i);
1626 else
1627 i++;
1628 }
1629 for (std::set < MG_COQUILLE * >::iterator itShell = lst_mc_shell.begin();
1630 itShell != lst_mc_shell.end();
1631 itShell++)
1632 mggeo->supprimer_mg_coquilleid((*itShell)->get_id());
1633 for (std::set<CAD4FE::MCFace *>::iterator itFace = lst_mc_faces.begin(); itFace != lst_mc_faces.end(); itFace++)
1634 {
1635 CAD4FE::MCFace* mcFace=*itFace;
1636 CAD4FE::PolySurface * ps = mcFace->GetPolySurface();
1637 mggeo->supprimer_mg_faceid(mcFace->get_id());
1638 mggeo->supprimer_mg_surfaceid(ps->get_id());
1639 }
1640 for (std::set < MG_BOUCLE * >::iterator itLoop = lst_mc_loop.begin();
1641 itLoop != lst_mc_loop.end();
1642 itLoop++)
1643 mggeo->supprimer_mg_boucleid((*itLoop)->get_id());
1644
1645 for (std::set<CAD4FE::MCEdge *>::iterator itEdge = lst_mc_edges.begin(); itEdge != lst_mc_edges.end(); itEdge++)
1646 {
1647 CAD4FE::MCEdge* mcEdge=*itEdge;
1648 CAD4FE::PolyCurve * pc=mcEdge->GetPolyCurve();
1649 mggeo->supprimer_mg_areteid(mcEdge->get_id());
1650 mggeo->supprimer_mg_courbeid(pc->get_id());
1651 }
1652 for (std::set<CAD4FE::MCVertex *>::iterator itVertex = lst_mc_vertices.begin(); itVertex != lst_mc_vertices.end(); itVertex++)
1653 {
1654 CAD4FE::MCVertex * mcVertex = *itVertex;
1655 mggeo->supprimer_mg_sommetid(mcVertex->get_id());
1656 }
1657 mggeo->supprimer_mg_volumeid(_brep->get_id());
1658 return 1;
1659 }