Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
corefine-2d-propagation.cc
Go to the documentation of this file.
1 /*
2  * lib-corefinement : Opérations de corafinement.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-corefinement
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
25 #include "time.hh"
26 
27 // #define DEBUG_MESSAGES
28 #include "message-macros.hh"
29 
30 #include INCLUDE_NON_INLINE("corefine-2d-propagation.icc")
31 
32 using namespace std;
33 using namespace GMap3d;
34 
35 //******************************************************************************
36 
37 #define INFO_MESSAGES
38 
39 #ifdef INFO_MESSAGES
40 #define INFO(s) (cout << s << endl)
41 #else // INFO_MESSAGES
42 #define INFO(s)
43 #endif // INFO_MESSAGES
44 
45 //******************************************************************************
46 
47 #define a0 FMap->alpha0
48 #define a1 FMap->alpha1
49 #define a2 FMap->alpha2
50 #define a3 FMap->alpha3
51 
52 #define b1(d) ((CDart*)FMap->getDirectInfo(d, FAlpha1DI))
53 
54 //******************************************************************************
55 
56 CCorefine2dPropagation::CCorefine2dPropagation(CGMapVertex * AMap,
57  const CPlane & APlane,
58  bool ACalculateOrientation,
59  TCoordinate AEpsilon,
60  int AVertexDI)
61  : CCorefine(AMap, AEpsilon), FPlane(APlane), FTools(AMap, AEpsilon),
62  FCalculateOrientation(ACalculateOrientation), FNumberOfIntersections(0)
63 {
64  ENTER;
65 
66  FBestProj = FPlane.getBestProjection();
67 
68  if (AVertexDI < 0) {
69  FVertexDI = FMap->getNewDirectInfo();
70  MSG("FVertexDI = FMap->getNewDirectInfo() = " << FVertexDI);
72  }
73  else {
74  FVertexDI = AVertexDI;
75  FLocalVertexDirectInfo = false;
76  }
77 
78  FAlpha1DI = FMap->getNewDirectInfo();
79  MSG("FAlpha1DI = FMap->getNewDirectInfo() = " << FAlpha1DI);
80 
81  EXIT;
82 }
83 
84 //******************************************************************************
85 
87 {
88  ENTER;
89 
91  MSG("FMap->freeDirectInfo(FVertexDI = " << FVertexDI << ")");
92  FMap->freeDirectInfo(FVertexDI);
93  }
94 
95  MSG("FMap->freeDirectInfo(FAlpha1DI = " << FAlpha1DI << ")");
96  FMap->freeDirectInfo(FAlpha1DI);
97 
98  EXIT;
99 }
100 
101 //******************************************************************************
102 
103 int CCorefine2dPropagation::corefine(CDart *& AMesh1, CDart *& AMesh2,
104  bitset<NB_MARKS> ACopyMarks)
105 {
106  TCoordinate t;
107  list<CDart*> vertex_list;
108  CEdgeIntersection inter;
109  CDart *vertex, *edge, *face, *tmp_edge, *tmp_face;
110  int edge_mark = FMap->getNewMark();
111  int vertex_mark = FMap->getNewMark();
112  CVertex *pt1, *pt2, tmp_pt;
113  CTime start, end;
114 
115  FCopyMarks = ACopyMarks;
116 
117  ENTER;
118 
119  INFO("Initialisation des maillages");
120  start.updateTime();
121 
122  initMesh(AMesh1);
123  initMesh(AMesh2);
124 
125  end.updateTime();
126  FInitialisationTime = end - start;
127  INFO("Durée de l'initialisation : " << FInitialisationTime);
128 
129  INFO("Orientation des maillages");
130  start.updateTime();
131 
132  if (FCalculateOrientation) {
133  AMesh1 = FTools.findWellOrientedDart(AMesh1, FVertexDI);
134  AMesh2 = FTools.findWellOrientedDart(AMesh2, FVertexDI);
135  }
136 
137  vertex = AMesh1;
138  face = AMesh2;
139 
140  end.updateTime();
141  FOrientationTime = end - start;
142  INFO("Durée de l'orientation : " << FOrientationTime);
143 
144 // cout << FTools.faceNormalVector(vertex, FVertexDI) << endl;
145 // FTools.displayFaceVertices(vertex, FVertexDI);
146 // cout << FTools.faceNormalVector(face, FVertexDI) << endl;
147 // FTools.displayFaceVertices(face, FVertexDI);
148 
149  INFO("Localisation de la première face");
150  start.updateTime();
151 
152  // Recherche de la face du deuxième maillage contenant le brin de départ du
153  // premier maillage
154  face = FTools.localizePointInMesh(*getVertex(vertex), face, FVertexDI);
155 
156 // cout << "\033[0;37m"
157 // << "Point de départ sur le premier maillage : "
158 // << *getVertex(vertex) << endl
159 // << "Sommets de la face du second maillage contenant ce point : "
160 // << endl;
161 // FTools.displayFaceVertices(face, FVertexDI);
162 // cout << "\033[0m";
163 
164  end.updateTime();
165  FLocalizationTime = end - start;
166  INFO("Durée de la localisation : " << FLocalizationTime);
167 
168  pt1 = getVertex(face);
169  pt2 = getVertex(a0(face));
170  tmp_pt = *getVertex(vertex);
171 
172  // Si le brin d1 se trouve sur l'arête incidente à d2, on éclate cette arête
173  switch(FTools.localizePointOnEdge(tmp_pt, *pt1, *pt2, &t)) {
174  case EP_OnEdge:
175  face = splitEdge(face, tmp_pt);
176  weldVertices(vertex, face);
177  FMap->markOrbit(vertex, ORBIT_VERTEX, vertex_mark);
178  break;
179 
180  case EP_OnSecondVertex:
181  face = a2(a0(face));
182  case EP_OnFirstVertex:
183  modifyVertex(face, tmp_pt);
184  weldVertices(vertex, face);
185  FMap->markOrbit(vertex, ORBIT_VERTEX, vertex_mark);
186  break;
187 
188  default:
189  break;
190  }
191 
192  INFO("Parcours des maillages et création des intersections");
193  start.updateTime();
194 
195  // Ajoute le sommet et la face courants dans la liste
196  vertex_list.push_back(vertex);
197  vertex_list.push_back(face);
198 
199  // Tant qu'il y a des éléments dans la liste, on continue le parcours
200  while(!vertex_list.empty()) {
201 
202  // Récupération des prochains sommets et faces à traiter
203  vertex = vertex_list.front(), vertex_list.pop_front();
204  face = vertex_list.front(), vertex_list.pop_front();
205 
206  edge = vertex;
207 
208  MSG("Parcours du sommet : " << *getVertex(vertex));
209 
210  // Parcours des arêtes incidentes au sommet
211  do {
212  if (!FMap->isMarked(edge, edge_mark)) {
213 
214  pt1 = getVertex(edge);
215  pt2 = getVertex(a0(edge));
216 
217 #ifdef DEBUG_MESSAGES
218  cout << "Parcours de l'arête : ";
219  FTools.displayEdgeVertices(edge, FVertexDI);
220 #endif // DEBUG_MESSAGES
221 
222  /* Si le sommet d'origine de l'arête est marqué, c'est qu'il possède une
223  * intersection avec une arête ou un sommet de l'autre maillage. Il
224  * faut donc rechercher la face contenant l'arête qu'on longe.
225  */
226  if (FMap->isMarked(edge, vertex_mark)) {
227 // tmp_face = FTools.findSectorOfVector(*pt2 - *pt1, face, FVertexDI);
228 
229  /* On peut éviter de chercher le bon secteur à chaque fois si
230  * l'interclassement fonctionne correctement...
231  */
232  tmp_face = a2(edge);
233  while (b1(tmp_face) == NULL)
234  tmp_face = a2(a1(tmp_face));
235  tmp_face = b1(tmp_face);
236 
237  inter = FTools.findNearestIntersection(*pt1, *pt2, tmp_face, true,
238  FVertexDI);
239  }
240  else {
241  tmp_face = face;
242 
243  inter = FTools.findNearestIntersection(*pt1, *pt2, tmp_face, false,
244  FVertexDI);
245  }
246 
247 #ifdef DEBUG_MESSAGES
248  cout << "Recherche d'une intersection dans la face :" << endl;
249  FTools.displayFaceVertices(tmp_face, FVertexDI);
250 #endif
251 
252  if (inter.getCell() != NULL &&
253  (inter.getPosition() != EP_OnSecondVertex ||
254  !FMap->isMarked(a2(a0(edge)), vertex_mark))) {
255 #ifdef DEBUG_MESSAGES
256  cout << "Une intersection trouvée dans la face avec l'arête :\n";
257  FTools.displayEdgeVertices(inter.getCell(), FVertexDI);
258  cout << "Première arête : ";
259 #endif
260 
261  if (inter.getPosition() == EP_OnEdge) {
262  MSG("Intersection franche");
263  tmp_edge = splitEdge(edge, inter.getPoint());
264  tmp_pt = inter.getPoint();
265  }
266  else if (inter.getPosition() == EP_OnFirstVertex) {
267  cout << "\033[0;31m"
268  << "Intersection avec le sommet d'origine de l'arête "
269  << *pt1 << " et ";
270  if (inter.getCellDimension() == 0)
271  cout << "le sommet " << *getVertex(inter.getCell());
272  else
273  cout << "l'arête [" << *getVertex(inter.getCell())
274  << "," << *getVertex(a0(inter.getCell())) << "]";
275  cout << "\033[0m\n";
276 
277  tmp_edge = edge;
278  tmp_pt = *pt1;
279  }
280  else {
281  MSG("Intersection avec le sommet extrémité de l'arête");
282  tmp_edge = a2(a0(edge));
283  tmp_pt = *pt2;
284  }
285 
286  MSG("Deuxième arête : ");
287 
288  if (inter.getCellDimension() == 1) {
289  MSG("Intersection franche");
290  tmp_face = splitEdge(inter.getCell(), tmp_pt);
291  }
292  else {
293  MSG("Intersection avec un sommet");
294  tmp_face = inter.getCell();
295  modifyVertex(inter.getCell(), tmp_pt);
296  }
297 
298  if (inter.getPosition() != EP_OnFirstVertex ||
299  !FMap->isMarked(edge, vertex_mark)) {
300  weldVertices(tmp_edge, tmp_face);
301  }
302  else {
303  cout << "\033[1;31m"
304  << "Interclassement de plus de deux sommets " << *pt1
305  << "\033[0m\n";
306 
307  /* Cas très délicat à gérer !!!
308  * Ici, comme le point d'intersection est proche du sommet
309  * d'origine A de l'arête, il faut faire un interclassement entre
310  * le nouveau sommet et tous les sommets déjà interclassés en A.
311  */
312  //weldMultipleVertices(tmp_edge, tmp_face);
313  }
314 
315  FMap->markOrbit(tmp_edge, ORBIT_VERTEX, vertex_mark);
316  }
317  else {
318  tmp_edge = a2(a0(edge));
319  }
320 
321  vertex_list.push_back(tmp_edge);
322  vertex_list.push_back(tmp_face);
323 
324  FMap->markOrbit(edge, ORBIT_EDGE, edge_mark);
325  }
326 
327  // Passage à l'arête suivante sur le sommet
328  edge = a2(a1(edge));
329  }
330  while (edge != vertex);
331  }
332 
333  FMap->unmarkOrbit(AMesh1, ORBIT_CC, edge_mark);
334  FMap->unmarkOrbit(AMesh1, ORBIT_CC, vertex_mark);
335 
336  FMap->freeMark(edge_mark);
337  FMap->freeMark(vertex_mark);
338 
339  end.updateTime();
340  FPropagationTime = end - start;
341  INFO("Durée de la recherche des intersections : " << FPropagationTime);
342 
343  if (FNumberOfIntersections != 0) {
344  INFO("Assemblage final des maillages");
345  start.updateTime();
346  applyModifications(AMesh1);
347  end.updateTime();
348  FAssemblyTime = end - start;
349  }
350  else {
351  INFO("Aucune intersection entre les maillages "
352  << "==> insertion d'une arête fictive");
353  start.updateTime();
354  tmp_face = FTools.localizePointInMesh(*getVertex(face), AMesh1, FVertexDI);
355  FMap->insertEdge(tmp_face, a1(face));
356  end.updateTime();
357  FAssemblyTime = end - start;
358  }
359  INFO("Durée de l'assemblage : " << FAssemblyTime);
360 
361  INFO("Nettoyage des maillages");
362  start.updateTime();
363 
364  cleanMesh(AMesh1);
365 
366  if (FNumberOfIntersections == 0)
367  cleanMesh(AMesh2);
368 
369  end.updateTime();
370  FCleaningTime = end - start;
371  INFO("Durée du nettoyage : " << FCleaningTime);
372 
373  if (FNumberOfIntersections != 0) {
374  INFO("Suppression des arêtes doubles");
375  start.updateTime();
376 
377  FTools.removeDoubleEdges(AMesh1, AMesh2, FCopyMarks);
378 
379  end.updateTime();
380  FDoubleEdgesCleaningTime = end - start;
381  INFO("Durée de la suppression : " << FDoubleEdgesCleaningTime);
382 
383  INFO("Nombre d'intersections réalisées : "
385  }
386  else FDoubleEdgesCleaningTime.setTime(0, 0);
387 
388  EXIT;
389 
390  return FNumberOfIntersections;
391 }
392 
393 //******************************************************************************
394 
396 {
397  return FInitialisationTime;
398 }
399 
400 //------------------------------------------------------------------------------
401 
403 {
404  return FOrientationTime;
405 }
406 
407 //------------------------------------------------------------------------------
408 
410 {
411  return FLocalizationTime;
412 }
413 
414 //------------------------------------------------------------------------------
415 
417 {
418  return FPropagationTime;
419 }
420 
421 //------------------------------------------------------------------------------
422 
424 {
425  return FAssemblyTime;
426 }
427 
428 //------------------------------------------------------------------------------
429 
431 {
432  return FCleaningTime;
433 }
434 
435 //------------------------------------------------------------------------------
436 
438 {
440 }
441 
442 //******************************************************************************
443 
445 {
446  ENTER;
447 
448  int vert_mark = FMap->getNewMark();
449  CAttributeVertex *vert;
450 
451  for (CStaticCoverageCC scc2(FMap, AMesh); scc2.cont(); ++scc2)
452  if (FMap->isFree2(*scc2))
453  FMap->stopUp(*scc2, 2);
454 
455  for (CStaticCoverageCC scc1(FMap, AMesh); scc1.cont(); ++scc1)
456  if (FMap->isFree1(*scc1))
457  FMap->linkAlpha1(*scc1, a2(*scc1));
458 
459  for (CDynamicCoverageCC dcc(FMap, AMesh); dcc.cont(); ++dcc) {
460  FMap->setDirectInfo(*dcc, FAlpha1DI, NULL);
461 
462  if (!FMap->isMarked(*dcc, vert_mark)) {
463  vert = FMap->findVertex(*dcc);
464 
465  *(CVertex*)vert = FPlane.projectPoint(*vert, FBestProj);
466 
467 // if (FLocalVertexDirectInfo) {
468  for (CDynamicCoverageVertex dcv(FMap, *dcc) ; dcv.cont() ; dcv++) {
469  FMap->setMark(*dcv, vert_mark);
470  FMap->setDirectInfo(*dcv, FVertexDI, vert);
471  }
472 // }
473 // else {
474 // FMap->markOrbit(*dcc, ORBIT_VERTEX, vert_mark);
475 // }
476  }
477  }
478 
479  FMap->unmarkOrbit(AMesh, ORBIT_CC, vert_mark);
480  FMap->freeMark(vert_mark);
481 
482  EXIT;
483 }
484 
485 //******************************************************************************
486 
488 {
489  ENTER;
490 
491  int vert_mark = FMap->getNewMark();
492  CAttributeVertex *vert;
493 
494  for (CDynamicCoverageCC dcc(FMap, AMesh) ; dcc.cont() ; dcc++) {
495  FMap->setDirectInfo(*dcc, FAlpha1DI, NULL);
496 
497  if (!FMap->isMarked(*dcc, vert_mark)) {
498  FMap->markOrbit(*dcc, ORBIT_VERTEX, vert_mark);
499  vert = FMap->findVertex(*dcc);
500 
501  *(CVertex*)vert = FPlane.unprojectPoint(*vert, FBestProj);
502  }
503  }
504 
505  FMap->unmarkOrbit(AMesh, ORBIT_CC, vert_mark);
506  FMap->freeMark(vert_mark);
507 
508  EXIT;
509 }
510 
511 //******************************************************************************
512 
513 CDart * CCorefine2dPropagation::splitEdge(CDart * AEdge,
514  const CVertex & AVertex)
515 {
516  ENTER;
517 
518  CDart *d = a1(FMap->CGMapGeneric::insertVertex(AEdge));
519 
520  CAttributeVertex *att = new CAttributeVertex(AVertex);
521 
522  FMap->setVertex(d, att);
523 
524  for (CDynamicCoverageVertex dcv(FMap, d) ; dcv.cont() ; dcv++) {
525  FMap->setDirectInfo(*dcv, FVertexDI, att);
526  FMap->setDirectInfo(*dcv, FAlpha1DI, NULL);
527 
528  for (int i = 0; i < NB_MARKS; i++)
529  if (FCopyMarks[i] && FMap->isMarked(a0(*dcv), i))
530  FMap->setMark(*dcv, i);
531  }
532 
533  EXIT;
534 
535  return d;
536 }
537 
538 //******************************************************************************
539 
540 // void CCorefine2dPropagation::weldVertices(CDart * AVertex1, CDart * AVertex2)
541 // {
542 // list<CDart*> * l = FTools.sortVerticesEdges(AVertex1, AVertex2, FVertexDI);
543 // list<CDart*>::iterator it;
544 // CDart *d1, *d2;
545 
546 // if (l == NULL) {
547 // cout << "\033[1;33m"
548 // << "Erreur lors du tri angulaire => fusion des sommets impossible !"
549 // << "\033[0m\n";
550 
551 // return;
552 // }
553 
554 // ENTER;
555 
556 // it = l->begin();
557 // d2 = *it;
558 
559 // do {
560 // d1 = d2;
561 // it++;
562 
563 // if (it != l->end())
564 // d2 = *it;
565 // else
566 // d2 = *l->begin();
567 
568 // if (a1(d1) != a2(d2)) {
569 // FMap->setDirectInfo(d1, FAlpha1DI, a2(d2));
570 // FMap->setDirectInfo(a2(d2), FAlpha1DI, d1);
571 // }
572 // else {
573 // FMap->setDirectInfo(d1, FAlpha1DI, NULL);
574 // FMap->setDirectInfo(a2(d2), FAlpha1DI, NULL);
575 // }
576 // }
577 // while (it != l->end());
578 
579 // delete l;
580 
581 // FNumberOfIntersections++;
582 
583 // EXIT;
584 // }
585 
586 //******************************************************************************
587 
589 {
590  public:
591  CAngularEdgeComparator(CGMapVertex * AMap, const CVertex & ACenter,
592  int AVertexDI)
593  : FMap(AMap), FCenter(ACenter), FVertexDI(AVertexDI) {}
594 
595  bool operator () (CDart * AEdge1, CDart * AEdge2)
596  {
597  CVertex v1 = *getVertex(a0(AEdge1)) - FCenter;
598  CVertex v2 = *getVertex(a0(AEdge2)) - FCenter;
599  return (v1 * v2).getZ() > 0.0;
600  }
601 
602  private:
603 
604  CAttributeVertex * getVertex(CDart * ADart) const
605  { return (CAttributeVertex*)FMap->getDirectInfo(ADart, FVertexDI); }
606 
607  private:
608  CGMapVertex *FMap;
609  CVertex FCenter;
610  int FVertexDI;
611 };
612 
613 void CCorefine2dPropagation::weldVertices(CDart * AVertex1, CDart * AVertex2)
614 {
615  CAngularEdgeComparator comp(FMap, *getVertex(AVertex1), FVertexDI);
616  multiset<CDart*, CAngularEdgeComparator> edges(comp);
617  multiset<CDart*, CAngularEdgeComparator>::iterator it, tmp_it;
618  CDart *d1, *d2;
619 
620  // Ajout des premières arêtes
621  d1 = AVertex1;
622  do {
623  edges.insert(d1);
624  d1 = a2(FTools.alpha1(d1));
625  }
626  while (d1 != AVertex1);
627 
628  // Ajout des secondes arêtes
629  d2 = AVertex2;
630  do {
631  edges.insert(d2);
632  d2 = a2(FTools.alpha1(d2));
633  }
634  while (d2 != AVertex2);
635 
636  for (it = edges.begin(); it != edges.end(); ) {
637  tmp_it = it++;
638 
639  d1 = *tmp_it;
640  d2 = (it != edges.end()) ? *it : *edges.begin();
641 
642  if (a1(d1) != a2(d2)) {
643  FMap->setDirectInfo(d1, FAlpha1DI, a2(d2));
644  FMap->setDirectInfo(a2(d2), FAlpha1DI, d1);
645  }
646  }
647 
649 }
650 
651 //******************************************************************************
652 
654  CDart * AVertex2)
655 {
656  list<CDart*> vertices;
657  list<CDart*>::iterator it;
658  CDart *d1, *d2;
659  int mark = FMap->getNewMark();
660 
661  FMap->markOrbit(AVertex1, ORBIT_VERTEX, mark);
662 
663  // Ajout des sommets déjà reliés au premier sommet
664  d1 = AVertex1;
665  do {
666  d2 = b1(d1);
667 
668  if (d2 != NULL && !FMap->isMarked(d2, mark)) {
669  vertices.push_back(d2);
670  FMap->markOrbit(d2, ORBIT_VERTEX, mark);
671  }
672 
673  d1 = a2(a1(d1));
674  }
675  while (d1 != AVertex1);
676 
677  // Ajout du second sommet
678  if (!FMap->isMarked(AVertex2, mark)) {
679  vertices.push_back(AVertex2);
680  FMap->markOrbit(AVertex2, ORBIT_VERTEX, mark);
681  }
682 
683  // Ajout des sommets déjà reliés au second sommet
684  d1 = AVertex2;
685  do {
686  d2 = b1(d1);
687 
688  if (d2 != NULL && !FMap->isMarked(d2, mark)) {
689  vertices.push_back(d2);
690  FMap->markOrbit(d2, ORBIT_VERTEX, mark);
691  }
692 
693  d1 = a2(a1(d1));
694  }
695  while (d1 != AVertex2);
696 
697  // Démarquage des sommets
698  for (it = vertices.begin() ; it != vertices.end() ; it++)
699  FMap->unmarkOrbit(*it, ORBIT_VERTEX, mark);
700  FMap->freeMark(mark);
701 
702  list<CDart*> * l = FTools.sortMultipleVerticesEdges(AVertex1, vertices,
703  FVertexDI);
704 
705  if (l == NULL) {
706  cout << "\033[1;33m"
707  << "Erreur lors du tri angulaire => fusion des sommets impossible !"
708  << "\033[0m\n";
709 
710  return;
711  }
712 
713  it = l->begin();
714  d2 = *it;
715 
716  do {
717  d1 = d2;
718  it++;
719 
720  if (it != l->end())
721  d2 = *it;
722  else
723  d2 = *l->begin();
724 
725  if (a1(d1) != a2(d2)) {
726  FMap->setDirectInfo(d1, FAlpha1DI, a2(d2));
727  FMap->setDirectInfo(a2(d2), FAlpha1DI, d1);
728  }
729  else {
730  FMap->setDirectInfo(d1, FAlpha1DI, NULL);
731  FMap->setDirectInfo(a2(d2), FAlpha1DI, NULL);
732  }
733  }
734  while (it != l->end());
735 
736  delete l;
737 
739 }
740 
741 //******************************************************************************
742 
743 // void CCorefine2dPropagation::applyModifications(CDart * AMesh)
744 // {
745 // CDart *d1, *d2;
746 // int vertex_mark = FMap->getNewMark();
747 // CAttributeVertex *att;
748 // CVertex pt;
749 
750 // StaticCoverageCC scc(FMap, AMesh);
751 
752 // for (scc.reinit() ; scc.cont() ; scc++) {
753 // if (!FMap->isMarked(*scc, vertex_mark)) {
754 // att = FMap->removeVertex(*scc);
755 // pt = *((CVertex*)att);
756 // delete att;
757 
758 // for (StaticCoverageVertex scv(FMap, *scc) ; scv.cont() ; scv++) {
759 // d1 = *scv;
760 // d2 = b1(d1);
761 
762 // if (d2 != NULL) {
763 // FMap->uu1(d1);
764 // FMap->uu1(d2);
765 // FMap->ll1(d1, d2);
766 // }
767 
768 // FMap->setMark(d1, vertex_mark);
769 // }
770 
771 // modifyVertex(*scc, pt);
772 // }
773 // }
774 
775 // for (scc.reinit() ; scc.cont() ; scc++)
776 // FMap->unsetMark(*scc, vertex_mark);
777 
778 // FMap->freeMark(vertex_mark);
779 // }
780 
781 //******************************************************************************
782 
784 {
785  ENTER;
786 
787  CDart *d1, *d2;
788 
789  for (CStaticCoverageCC scc(FMap, AMesh) ; scc.cont() ; scc++) {
790  d1 = *scc;
791  d2 = b1(d1);
792 
793  if (d2 != NULL) {
794  if (!FMap->isFree1(d1))
795  FMap->dartUnsew1(d1);
796 
797  if (!FMap->isFree1(d2))
798  FMap->dartUnsew1(d2);
799 
800  FMap->dartSew1(d1, d2);
801  }
802  }
803 
804  EXIT;
805 }
806 
807 //******************************************************************************
808 
809 #undef a0
810 #undef a1
811 #undef a2
812 #undef b1
813 
814 //******************************************************************************