ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCBody.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_MCBody.cpp
File size: 67401 byte(s)
Error occurred while calculating annotation data.
Log Message:
mise a jour final these Gilles Foucault

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