Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
corefine-2d-tools.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 
24 #include "corefine-2d-tools.hh"
25 #include "bounding-box.hh"
26 
27 // #define WARNING_MESSAGES
28 // #define DEBUG_MESSAGES
29 #include "message-macros.hh"
30 
31 using namespace std;
32 using namespace GMap3d;
33 
34 //******************************************************************************
35 
36 #define PROD(V1, V2) ((V1).getX() * (V2).getY() - (V1).getY() * (V2).getX())
37 
38 #define a0 FMap->alpha0
39 #define a1 FMap->alpha1
40 #define a2 FMap->alpha2
41 #define a3 FMap->alpha3
42 
43 #define VTX(d) (AVertexDI < 0 ? FMap->findVertex(d) : \
44  (CAttributeVertex*)FMap->getDirectInfo(d, AVertexDI))
45 
46 //******************************************************************************
47 
48 CCorefine2dTools::CCorefine2dTools(CGMapVertex * AMap, TCoordinate AEpsilon)
49  : CGeneralTools(AMap,AEpsilon)
50 {
51 }
52 
53 //******************************************************************************
54 
55 bool CCorefine2dTools::isVectorInSector(const CVertex & AVector,
56  const CVertex & ASectorVector1,
57  const CVertex & ASectorVector2)
58 {
59  if (PROD(ASectorVector1, ASectorVector2) < 0.0)
60  return (PROD(ASectorVector1, AVector) >= 0 ||
61  PROD(ASectorVector2, AVector) <= 0);
62 
63  return (PROD(ASectorVector1, AVector) >= 0 &&
64  PROD(ASectorVector2, AVector) <= 0);
65 }
66 
67 //******************************************************************************
68 
69 bool CCorefine2dTools::isVectorInSector(const CVertex & AVector,
70  CDart * ASector, int AVertexDI)
71 {
72  CVertex center = *VTX(ASector);
73 
74  CVertex v1 = *VTX(FMap->alpha0(ASector)) - center;
75  CVertex v2 = *VTX(FMap->alpha0(FMap->alpha1(ASector))) - center;
76 
77  return isVectorInSector(AVector, v1, v2);
78 }
79 
80 //******************************************************************************
81 
82 bool CCorefine2dTools::areVectorsColinear(const CVertex & AVector1,
83  const CVertex & AVector2)
84 {
85 // if (PROD(AVector1, AVector2) != 0.0)
86 // return false;
87 // else
88 // return AVector1.dot(AVector2) > 0.0;
89 
90  CVertex v1 = normalizeVector(AVector1);
91  CVertex v2 = normalizeVector(AVector2);
92 
93  assert(v1 != ORIGIN);
94  assert(v2 != ORIGIN);
95 
96  return arePointsEqual(v1, v2);
97 }
98 
99 //******************************************************************************
100 
101 TCoordinate CCorefine2dTools::pointParameterOnLine(const CVertex & APoint,
102  const CVertex & ALineVertex1,
103  const CVertex & ALineVertex2)
104 {
105  TCoordinate res;
106  CVertex v = ALineVertex2 - ALineVertex1;
107 
108 #ifdef WARNING_MESSAGES
109  if (isVectorNull(v))
110  WARN_BB("<CGeneralTools::pointParameterOnLine> "
111  << "Le vecteur est de longueur nulle : " << v);
112 #endif
113 
114  if (fabs(v.getX()) > fabs(v.getY()))
115  res = (APoint.getX() - ALineVertex1.getX()) / v.getX();
116  else
117  res = (APoint.getY() - ALineVertex1.getY()) / v.getY();
118 
119  return res;
120 }
121 
122 //******************************************************************************
123 
124 CDart * CCorefine2dTools::findSectorOfVector(const CVertex & AVector,
125  CDart * AVertex, int AVertexDI)
126 {
127  CDart *d = AVertex;
128 
129  if (a1(d) != a2(d))
130  while (!isVectorInSector(AVector, d, AVertexDI))
131  d = a2(a1(d));
132 
133  return d;
134 }
135 
136 //******************************************************************************
137 
138 // list<CDart*> * CCorefine2dTools::sortVerticesEdges(CDart * AVertex1,
139 // CDart * AVertex2)
140 // {
141 // AVertex2 = findSectorOfVector(getEdgeVector(AVertex1), AVertex2);
142 
143 // CDart *d1 = a2(a1(AVertex1));
144 // CDart *d2 = AVertex2;
145 // CVertex v1 = getEdgeVector(a2(a1(AVertex1)));
146 
147 // list<CDart*> * l = new list<CDart*>;
148 
149 // l->push_back(AVertex2);
150 // l->push_back(AVertex1);
151 
152 // while (d1 != AVertex1) {
153 // if (isVectorInSector(v1, d2)) {
154 // l->push_back(d1);
155 
156 // d1 = a2(a1(d1));
157 // v1 = getEdgeVector(d1);
158 // }
159 // else {
160 // d2 = a2(a1(d2));
161 
162 // l->push_back(d2);
163 // }
164 // }
165 
166 // d2 = a2(a1(d2));
167 
168 // while (d2 != AVertex2) {
169 // l->push_back(d2);
170 
171 // d2 = a2(a1(d2));
172 // }
173 
174 // return l;
175 // }
176 
177 //******************************************************************************
178 
179 list<CDart*> * CCorefine2dTools::sortVerticesEdges(CDart * AVertex1,
180  CDart * AVertex2,
181  int AVertexDI)
182 {
183  DEBUG_FUNCTION;
184 
185  CDart *d;
186  list<CDart*> * l = new list<CDart*>;
187  list<CDart*>::iterator it;
188 
189  // Cas ou le premier sommet est une extrémité d'un segment seul
190  if (a1(AVertex1) == a2(AVertex1)) {
191  l->push_back(AVertex1);
192  AVertex2 = a2(a1(findSectorOfVector(edgeVector(AVertex1, AVertexDI),
193  AVertex2, AVertexDI)));
194 
195  d = AVertex2;
196  do {
197  l->push_back(d);
198  d = a2(a1(d));
199  }
200  while (d != AVertex2);
201  }
202  // Cas ou le second sommet est une extrémité d'un segment seul
203  else if (a1(AVertex2) == a2(AVertex2)) {
204  l->push_back(AVertex2);
205  AVertex1 = a2(a1(findSectorOfVector(edgeVector(AVertex2, AVertexDI),
206  AVertex1, AVertexDI)));
207 
208  d = AVertex1;
209  do {
210  l->push_back(d);
211  d = a2(a1(d));
212  }
213  while (d != AVertex1);
214  }
215  // Cas restants
216  else {
217  int mark = FMap->getNewMark();
218  CVertex center = *VTX(AVertex1);
219 
220  d = AVertex1;
221  CVertex v = *VTX(a0(d)) - center;
222 
223  AVertex2 = findSectorOfVector(v, AVertex2, AVertexDI);
224 
225  CDart *d1 = a2(a1(AVertex1));
226  CDart *d2 = a2(a1(AVertex2));
227 
228  CVertex v1 = *VTX(a0(d1)) - center;
229  CVertex v2 = *VTX(a0(d2)) - center;
230 
231 #define INSERT(dart) (l->push_back(dart), FMap->setMark(dart, mark))
232 
233  do {
234  INSERT(d);
235 
236  bool test1 = isVectorInSector(v1, v, v2);
237  bool test2 = isVectorInSector(v2, v, v1);
238 
239  MSG("v = " << center << " --> " << center + v);
240  MSG("v1 = " << center << " --> " << center + v1);
241  MSG("v2 = " << center << " --> " << center + v2);
242 
243  MSG("tests :");
244  MSG("v1 entre v et v2 : " << test1);
245  MSG("v2 entre v et v1 : " << test2);
246 
247  if (areVectorsColinear(v, v2)) {
248  MSG("v et v2 sont colinéaires");
249  d = d2;
250  v = v2;
251  d2 = a2(a1(d2));
252  v2 = *VTX(a0(d2)) - center;
253  }
254  else if (areVectorsColinear(v1, v2)) {
255 // else if (test1 == test2 && v1.dot(v2) > 0.0) {
256  MSG("v1 et v2 sont colinéaires");
257 
258  d = d1;
259  v = v1;
260 
261  if (!FMap->isMarked(d2, mark)) {
262  INSERT(d2);
263  }
264 
265  d2 = a2(a1(d2));
266  d1 = a2(a1(d1));
267 
268  v1 = *VTX(a0(d1)) - center;
269  v2 = *VTX(a0(d2)) - center;
270  }
271  else if (test1 && !test2) {
272  MSG("v1 est entre v et v2");
273 
274  d = d1;
275  v = v1;
276  d1 = a2(a1(d1));
277  v1 = *VTX(a0(d1)) - center;
278  }
279  else if (!test1 && test2) {
280  MSG("v2 est entre v et v1");
281 
282  d = d2;
283  v = v2;
284  d2 = a2(a1(d2));
285  v2 = *VTX(a0(d2)) - center;
286  }
287  else {
288  assert(test1 != test2);
289  }
290  }
291  while (!FMap->isMarked(d, mark));
292 
293 #undef INSERT
294 
295  bool problem = false;
296 
297  // Démarquage des brins du deuxième sommet
298  d2 = AVertex2;
299  do {
300  if (FMap->isMarked(d2, mark))
301  FMap->unsetMark(d2, mark);
302  else {
303  WARN_BR("<CCorefine2dTools::sortVerticesEdges> "
304  << "Brin du deuxième sommet non marqué !");
305  problem = true;
306  }
307 
308  d2 = a2(a1(d2));
309  }
310  while (d2 != AVertex2);
311 
312  // Démarquage des brins du premier sommet
313  d1 = AVertex1;
314  do {
315  if (FMap->isMarked(d1, mark))
316  FMap->unsetMark(d1, mark);
317  else {
318  WARN_BR("<CCorefine2dTools::sortVerticesEdges> "
319  << "Brin du premier sommet non marqué !");
320  problem = true;
321  }
322 
323  d1 = a2(a1(d1));
324  }
325  while (d1 != AVertex1);
326 
327  FMap->freeMark(mark);
328 
329  if (problem) {
330  cout << "\033[0;33m"
331  << "Tri angulaire autour du sommet " << center << endl;
332  for (it = l->begin() ; it != l->end() ; it++) {
333  cout << *VTX(a0(*it)) << endl;
334  }
335  cout << "\033[0m";
336 
337  delete l;
338  l = NULL;
339  }
340  }
341 
342  return l;
343 }
344 
345 //******************************************************************************
346 
347 list<CDart*> *
349  const list<CDart*> & AVertices,
350  int AVertexDI)
351 {
352  int mark = FMap->getNewMark();
353  list<CDart*> * l = new list<CDart*>;
354  list<CDart*>::const_iterator it;
355  int size = AVertices.size();
356  CDart **darts = new CDart*[size];
357  CDart **tmp_darts = new CDart*[size];
358  CVertex *vectors = new CVertex[size];
359  int i = 0, j;
360 
361  CVertex center = *VTX(AVertex1);
362 
363  CDart *d = AVertex1;
364  CVertex v = *VTX(a0(d)) - center;
365 
366  CDart *d1 = a2(a1(AVertex1));
367  CVertex v1 = *VTX(a0(d1)) - center;
368 
369  for (it = AVertices.begin() ; it != AVertices.end() ; it++) {
370  darts[i] = findSectorOfVector(v, *it, AVertexDI);
371  tmp_darts[i] = a2(a1(darts[i]));
372  vectors[i] = *VTX(a0(tmp_darts[i])) - center;
373  i++;
374  }
375 
376 #define INSERT(dart) (l->push_back(dart), FMap->setMark(dart, mark))
377 
378  do {
379  INSERT(d);
380 
381  j = 0;
382 
383  // Recherche du vecteur le plus proche
384  for (i = 1 ; i < size ; i++)
385  if (isVectorInSector(vectors[i], v, vectors[j]))
386  j = i;
387 
388  if (areVectorsColinear(v1, vectors[j])) {
389  d = d1;
390  v = v1;
391 
392  for (i = 0 ; i < size ; i++)
393  if (areVectorsColinear(vectors[i], v1)) {
394  if(!FMap->isMarked(tmp_darts[i], mark)) {
395  INSERT(tmp_darts[i]);
396  }
397 
398  tmp_darts[i] = a2(a1(tmp_darts[i]));
399  vectors[i] = *VTX(a0(tmp_darts[i])) - center;
400  }
401 
402  d1 = a2(a1(d1));
403  v1 = *VTX(a0(d1)) - center;
404  }
405  else if (isVectorInSector(vectors[j], v, v1)) {
406  d = tmp_darts[j];
407  v = vectors[j];
408 
409  for (i = 0 ; i < size ; i++)
410  if (i != j && areVectorsColinear(vectors[i], v)) {
411  if(!FMap->isMarked(tmp_darts[i], mark)) {
412  INSERT(tmp_darts[i]);
413  }
414 
415  tmp_darts[i] = a2(a1(tmp_darts[i]));
416  vectors[i] = *VTX(a0(tmp_darts[i])) - center;
417  }
418 
419  tmp_darts[j] = a2(a1(tmp_darts[j]));
420  vectors[j] = *VTX(a0(tmp_darts[j])) - center;
421  }
422  else {
423  d = d1;
424  v = v1;
425  d1 = a2(a1(d1));
426  v1 = *VTX(a0(d1)) - center;
427  }
428  }
429  while ( /*d != AVertex1*/ !FMap->isMarked(d, mark));
430 
431 #undef INSERT
432 
433  bool problem = false;
434 
435  // Démarquage des brins des sommets
436  for (i = 0 ; i < size ; i++) {
437  tmp_darts[i] = darts[i];
438 
439  do {
440  if (FMap->isMarked(tmp_darts[i], mark))
441  FMap->unsetMark(tmp_darts[i], mark);
442  else {
443  WARN_BR("<CCorefine2dTools::sortMultipleVerticesEdges> "
444  << "Brin du sommet n°" << i << " non marqué !");
445  problem = true;
446  }
447 
448  tmp_darts[i] = a2(a1(tmp_darts[i]));
449  }
450  while (tmp_darts[i] != darts[i]);
451  }
452 
453  // Démarquage des brins du premier sommet
454  d1 = AVertex1;
455  do {
456  if (FMap->isMarked(d1, mark))
457  FMap->unsetMark(d1, mark);
458  else {
459  WARN_BR("<CCorefine2dTools::sortMultipleVerticesEdges> "
460  << "Brin du premier sommet non marqué !");
461  problem = true;
462  }
463 
464  d1 = a2(a1(d1));
465  }
466  while (d1 != AVertex1);
467 
468  FMap->freeMark(mark);
469 
470  delete [] darts;
471  delete [] tmp_darts;
472  delete [] vectors;
473 
474  if (problem) {
475 #ifdef WARNING_MESSAGES
476  cout << "\033[1;34m" << "Tri angulaire autour du sommet " << center << endl;
477  for (it = l->begin() ; it != l->end() ; it++)
478  cout << *VTX(a0(*it)) << endl;
479  cout << "\033[0m";
480 #endif
481 
482  delete l;
483 
484  return NULL;
485  }
486 
487  return l;
488 }
489 
490 //******************************************************************************
491 
492 CDart * CCorefine2dTools::findWellOrientedDart(CDart * AVertex, int AVertexDI)
493 {
494  CVertex v1, v2;
495 
496  v1 = faceNormalVector(AVertex, AVertexDI);
497  v2 = faceNormalVector(a2(AVertex), AVertexDI);
498 
499  if ((v1.getZ() < 0.0 && v2.getZ() < 0.0) ||
500  (v1.getZ() > 0.0 && v2.getZ() > 0.0)) {
501  /* Nous sommes ici dans le cas où une des deux faces est une face
502  * extérieure et nous devons donc comparer la taille des deux faces.
503  */
504  CBoundingBox bb1, bb2;
505 
506  bb1 = orbitBoundingBox(AVertex, ORBIT_FACE, AVertexDI);
507  bb2 = orbitBoundingBox(a2(AVertex), ORBIT_FACE, AVertexDI);
508 
509  if (bb1.getSurface() <= bb2.getSurface()) {
510  // AVertex n'est pas la face extérieure, sa normale doit donc être > 0
511  if (v1.getZ() < 0.0) {
512  AVertex = a1(AVertex);
513  }
514  }
515  else {
516  // AVertex est la face extérieure, sa normale doit donc être < 0
517  if (v1.getZ() > 0.0) {
518  AVertex = a1(AVertex);
519  }
520  }
521  }
522  else if (v1.getZ() < 0.0) {
523  AVertex = a1(AVertex);
524  }
525 
526  return AVertex;
527 }
528 
529 //******************************************************************************
530 
533  const CVertex & AVertex1,
534  const CVertex & AVertex2,
535  TCoordinate * AParam)
536 {
537  assert(AParam != NULL);
538 
539  if (arePointsEqual(APoint, AVertex2)) {
540  *AParam = 1.0;
541  return EP_OnSecondVertex;
542  }
543 
544  if (arePointsEqual(APoint, AVertex1)) {
545  *AParam = 0.0;
546  return EP_OnFirstVertex;
547  }
548 
549  if (isPointOnLine(APoint, AVertex1, AVertex2)) {
550  *AParam = pointParameterOnLine(APoint, AVertex1, AVertex2);
551 
552  if (*AParam >= 0.0 && *AParam <= 1.0)
553  return EP_OnEdge;
554  }
555 
556  return EP_OutOfEdge;
557 }
558 
559 //******************************************************************************
560 
563  const CVertex & ALinePoint2,
564  const CVertex & AEdgePoint1,
565  const CVertex & AEdgePoint2,
566  TCoordinate * ALineParam,
567  TCoordinate * AEdgeParam)
568 {
569  assert(AEdgeParam != NULL && ALineParam != NULL);
570 
571  if (localizePointOnEdge(AEdgePoint2, ALinePoint1,
572  ALinePoint2, ALineParam) != EP_OutOfEdge) {
573 
574  *AEdgeParam = 1.0;
575  return EP_OnSecondVertex;
576  }
577 
578  if (localizePointOnEdge(AEdgePoint1, ALinePoint1,
579  ALinePoint2, ALineParam) != EP_OutOfEdge) {
580  *AEdgeParam = 0.0;
581  return EP_OnFirstVertex;
582  }
583 
584  CVertex v[2] = {ALinePoint2 - ALinePoint1, AEdgePoint2 - AEdgePoint1};
585  TCoordinate d = v[0].getY() * v[1].getX() - v[0].getX() * v[1].getY();
586 
587 #ifdef WARNING_MESSAGES
588  if (isVectorNull(v[0]) || isVectorNull(v[1]))
589  WARN_BB("<localizeEdgesIntersection>"
590  << "Une des arêtes est de longueur nulle !");
591 #endif
592 
593  if (d == 0.0)
594  return EP_OutOfEdge;
595 
596  *ALineParam = (v[1].getY() * (ALinePoint1.getX() - AEdgePoint1.getX()) -
597  v[1].getX() * (ALinePoint1.getY() - AEdgePoint1.getY())) / d;
598 
599  if (fabs(v[1].getX()) > fabs(v[1].getY()))
600  *AEdgeParam = (ALinePoint1.getX() + *ALineParam * v[0].getX() -
601  AEdgePoint1.getX()) / v[1].getX();
602  else
603  *AEdgeParam = (ALinePoint1.getY() + *ALineParam * v[0].getY() -
604  AEdgePoint1.getY()) / v[1].getY();
605 
606 // CVertex pt = AEdgePoint1 + *AEdgeParam * v[1];
607 
608 // if (arePointsEqual(pt, AEdgePoint2))
609 // return EP_OnSecondVertex;
610 
611 // if (arePointsEqual(pt, AEdgePoint1))
612 // return EP_OnFirstVertex;
613 
614  if (*AEdgeParam >= 0.0 && *AEdgeParam <= 1.0)
615  return EP_OnEdge;
616 
617  return EP_OutOfEdge;
618 }
619 
620 //******************************************************************************
621 
624  const CVertex & AVertex2,
625  CDart * AFace,
626  bool AFaceIsVertex1,
627  int AVertexDI)
628 {
629  CDart *d = AFace;
630  CEdgeIntersection inter;
631  int edge_mark = FMap->getNewMark();
632  TPositionOnEdge pos;
633  TCoordinate t1 = 0.0, t2 = 0.0, best_t2 = 1.0;
634  CVertex *pt1, *pt2;
635 
636  //if (arePointsEqual(AVertex1, AVertex2))
637  if (AVertex1 == AVertex2) {
638  FMap->freeMark(edge_mark);
639  return inter;
640  }
641 
642  // Parcours des sommets de la face
643  do {
644  pos = localizePointOnEdge(*VTX(d), AVertex1, AVertex2, &t2);
645 
646  if ((pos == EP_OnEdge && t2 < best_t2) ||
647  (pos == EP_OnSecondVertex && t2 <= best_t2) ||
648  (pos == EP_OnFirstVertex && AFaceIsVertex1 && d != AFace) ||
649  (pos == EP_OnFirstVertex && !AFaceIsVertex1)) {
650  inter.setCell(d);
651  inter.setCellDimension(0);
652  inter.setPosition(pos);
653 
654  best_t2 = t2;
655 
656  FMap->setMark(d, edge_mark);
657  FMap->setMark(a0(d), edge_mark);
658  FMap->setMark(a1(d), edge_mark);
659  FMap->setMark(a0(a1(d)), edge_mark);
660  }
661 
662  d = a1(a0(d));
663  }
664  while (d != AFace);
665 
666  // Parcours des arêtes de la face
667  do {
668  pt1 = VTX(d);
669  pt2 = VTX(a0(d));
670 
671  if (FMap->isMarked(d, edge_mark)) {
672  FMap->unsetMark(d, edge_mark);
673  FMap->unsetMark(a0(d), edge_mark);
674  }
675  else if (fabs((*pt2 - *pt1).norm()) > FEps / 2.0) {
676  pos = localizeEdgesIntersection(*pt1, *pt2, AVertex1, AVertex2, &t1, &t2);
677 
678  if ((t1 >= 0.0 && t1 <= 1.0) &&
679  ((pos == EP_OnEdge && t2 < best_t2) ||
680  (pos == EP_OnSecondVertex && t2 <= best_t2) ||
681  (pos == EP_OnFirstVertex && AFaceIsVertex1 &&
682  d != AFace && d != a0(a1(AFace))) ||
683  (pos == EP_OnFirstVertex && !AFaceIsVertex1))) {
684  inter.setCell(d);
685  inter.setCellDimension(1);
686  inter.setPosition(pos);
687 
688  best_t2 = t2;
689  }
690  }
691 
692  d = a1(a0(d));
693  }
694  while (d != AFace);
695 
696  FMap->freeMark(edge_mark);
697 
698  if (inter.getCell() != NULL)
699  inter.setPoint(AVertex1 + best_t2 * (AVertex2 - AVertex1));
700 
701  return inter;
702 }
703 
704 //******************************************************************************
705 
706 CDart * CCorefine2dTools::localizePointInMesh(const CVertex & APoint,
707  CDart * AMesh, int AVertexDI)
708 {
709  CDart *face = NULL;
710  CEdgeIntersection inter;
711  CVertex pt;
712 
713  inter.setCell(AMesh);
714  inter.setCellDimension(0);
715 
716  do {
717  switch (inter.getCellDimension()) {
718  case 0:
719  pt = *VTX(inter.getCell());
720  face = findSectorOfVector(APoint - pt, inter.getCell(), AVertexDI);
721  break;
722 
723  case 1:
724  pt = inter.getPoint();
725  face = a2(a0(inter.getCell()));
726  /* boucle infinie dans certains cas !!! :( */
727  break;
728 
729  default:
730  break;
731  }
732 
733 // cout << "Dim = " << inter.getCellDimension() << endl;
734 
735  inter = findNearestIntersection(pt, APoint, face, true, AVertexDI);
736  }
737  while (inter.getCell() != NULL);
738 
739  return face;
740 }
741 
742 //******************************************************************************
743 
744 void CCorefine2dTools::removeDoubleEdges(CDart *& AMesh1, CDart *& AMesh2, bitset<NB_MARKS> ACopyMarks, int AVertexDI)
745 {
746  CDart *d, *to_link[4], *edge[4], *to_remove[4];
747  int remove_mark = FMap->getNewMark();
748  CVertex pt1, pt2;
749 
750  for (CStaticCoverageCC scc(FMap, AMesh1) ; scc.cont() ; scc++) {
751  d = *scc;
752 
753  if (!FMap->isMarked(a1(d), remove_mark)) {
754  if (a1(a0(d)) == a0(a1(d)) || a0(a2(a1(d))) == a1(a2(a0(d)))) {
755  edge[0] = d;
756  edge[1] = a0(edge[0]);
757  edge[2] = a2(edge[1]);
758  edge[3] = a0(edge[2]);
759 
760  to_remove[0] = a2(a1(d));
761  to_remove[1] = a0(to_remove[0]);
762  to_remove[2] = a2(to_remove[1]);
763  to_remove[3] = a0(to_remove[2]);
764 
765  if (a1(a0(d)) == a0(a1(d))) {
766  to_link[0] = d;
767  to_link[1] = a0(d);
768  to_link[2] = a1(to_remove[0]);
769  to_link[3] = a1(to_remove[1]);
770  }
771  else { // a0(a2(a1(d))) == a1(a2(a0(d)))
772  to_link[0] = d;
773  to_link[1] = a0(a2(d));
774  to_link[2] = a1(to_remove[0]);
775  to_link[3] = a1(to_remove[2]);
776  }
777 
778  for (int i=0 ; i<4 ; i++) {
779  if (!FMap->isFree1(to_link[i]))
780  FMap->dartUnsew1(to_link[i]);
781 
782  FMap->setMark(to_remove[i], remove_mark);
783 
784  if (AMesh1 == to_remove[i])
785  AMesh1 = edge[i];
786  if (AMesh2 == to_remove[i])
787  AMesh2 = edge[i];
788 
789  for (int j = 0; j < NB_MARKS; j++)
790  if (ACopyMarks[j] && FMap->isMarked(to_remove[i], j))
791  FMap->setMark(edge[i], j);
792  }
793 
794  FMap->dartSew1(to_link[0], to_link[2]);
795  FMap->dartSew1(to_link[1], to_link[3]);
796 
797  if (AVertexDI >= 0) {
798  FMap->pointDirectInfoToAttributeVertex(AVertexDI, to_link[0]);
799  FMap->pointDirectInfoToAttributeVertex(AVertexDI, to_link[1]);
800  }
801  }
802  }
803  }
804 
805  FMap->deleteMarkedDarts(remove_mark);
806 
807  FMap->freeMark(remove_mark);
808 }
809 
810 //******************************************************************************