Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
corefine-2d-sweeping.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 //********************************************************************************
25 #include "corefine-2d-sweeping.hh"
26 #include "g-map-vertex.hh"
27 #include "geometry.hh"
28 #include <cassert>
29 using namespace GMap3d;
30 using namespace std;
31 //******************************************************************************
33  FMap(AMap)
34 {
35  assert(FMap != NULL);
36 }
37 //------------------------------------------------------------------------------
39 {
40 }
41 //******************************************************************************
42 #define GET_V(DART) FMap->getDirectInfoAsAttributeVertex((DART), directVertex)
43 
44 #define IT_PRED(IT,SET) (((IT)==(SET).begin()) \
45  ? NULL \
46  : * (--(IT), (IT)++))
47 
48 #define IT_SUCC(IT,SET) (++(IT), \
49  ((IT)==(SET).end()) \
50  ? (--(IT), (CDartVertex *) NULL) \
51  : (*((IT)--)))
52 //------------------------------------------------------------------------------
53 void CCorefineSegmentsSweeping::corefine(CDart* ADart1, CDart* ADart2,
54  const CVertex& ANormalVector)
55 {
56  assert(ADart1 != NULL);
57  assert(ADart2 != NULL);
58  assert(FMap->isIFreeOrbit(ADart1, 3, ORBIT_CC));
59  assert(FMap->isIFreeOrbit(ADart2, 3, ORBIT_CC));
60  assert(!ANormalVector.isNull());
61 
62  if (FMap->isSameOrbit(ADart1, ADart2, ORBIT_CC))
63  return;
64 
65  // 0) Réservation des ressources:
66  int treated = FMap->getNewMark();
67 
68  int directVertex = FMap->getNewDirectInfo();
69  int mesh1 = FMap->getNewMark();
70  int extremity1 = FMap->getNewMark();
71 
72  CDart* dart;
73 
74  // 0) Fermeture des 2-bords:
75  for (dart = ADart1; dart!=NULL; dart = dart==ADart1 ? ADart2 : NULL)
76  {
77  for (CDynamicCoverageCC cov(FMap, dart); cov.cont(); ++cov)
78  if (FMap->isFree2(*cov))
79  FMap->stopUp(*cov, 2);
80  }
81 
82  // 1) Initialisations:
83  FMap->pointDirectInfoToAttributeVertex(directVertex);
84  FMap->markOrbit(ADart1, ORBIT_CC, mesh1);
85 
86  // 2) Tri des extrémités selon l'ordre lexicographique:
87  CDartLexicoCompare lexComparator(FMap, directVertex,
88  extremity1, ANormalVector,
89  true /*comparaison exacte*/);
90 
91  LEX_SET eventSet(lexComparator);
92 
93  for (dart = ADart1; dart!=NULL; dart = dart==ADart1 ? ADart2 : NULL)
94  {
95  for (CDynamicCoverageCC cov(FMap, dart); cov.cont(); ++cov)
96  if (! FMap->isMarked(*cov, treated))
97  {
98  FMap->markOrbit(*cov, ORBIT_02, treated);
99 
100  if (! FMap->isFree0(*cov))
101  {
102  if (lexComparator((CDartVertex*) *cov,
103  (CDartVertex*) FMap->alpha0(*cov)))
104  FMap->setMark( *cov , extremity1);
105  else
106  FMap->setMark(FMap->alpha0(*cov), extremity1);
107 
108  eventSet.insert((CDartVertex*) *cov );
109  eventSet.insert((CDartVertex*) FMap->alpha0(*cov));
110  }
111  }
112 
113  FMap->unmarkOrbit(dart, ORBIT_CC, treated);
114  }
115 
116  // 3) Balayage et insertion des nouveaux sommets:
117  LEX_SET eventTreatedSet(lexComparator);
118 
120  vertComparator(FMap, directVertex, extremity1, ANormalVector);
121 
122  VERT_SET sweepingSet(vertComparator);
123 
124  while (eventSet.begin()!=eventSet.end())
125  {
126  CDartVertex* current = * eventSet.begin();
127 
128  vertComparator.setCurrentPoint(* GET_V(current));
129 
130  if (FMap->isMarked(current, extremity1))
131  {
132  // EXTREMITÉ ENTRANTE D'UN SEGMENT:
133  // Insertion dans l'ensemble de balayage:
134  VERT_IT currentPos = sweepingSet.insert((CDartVertex *) current);
135  assert(sweepingSet.find((CDartVertex *) current) != sweepingSet.end());
136 
137  // Récupération des voisins dans l'ensemble de balayage:
138  CDart * neighbors[2];
139 
140  neighbors[0] = IT_PRED(currentPos, sweepingSet);
141  neighbors[1] = IT_SUCC(currentPos, sweepingSet);
142 
143  // Tests d'intersection:
144  for (int i=0; i<2; ++i)
145  manageEdgesIntersection(current, neighbors[i], eventSet,
146  lexComparator, sweepingSet, extremity1,
147  mesh1, directVertex, ANormalVector);
148  }
149  else
150  {
151  // EXTRÉMITÉ SORTANTE D'UN SEGMENT:
152  assert(lexComparator((CDartVertex*) FMap->alpha0(current),
153  (CDartVertex*) current));
154 
155  VERT_IT it =
156  findElementInSweepingSet(sweepingSet, FMap->alpha0(current));
157 
158  // Récupération des voisins dans l'ensemble de balayage:
159  CDart* neighbors[2];
160 
161  neighbors[0] = IT_PRED(it, sweepingSet);
162  neighbors[1] = IT_SUCC(it, sweepingSet);
163 
164  // Tests d'intersection:
165  manageEdgesIntersection(neighbors[0], neighbors[1], eventSet,
166  lexComparator, sweepingSet, extremity1,
167  mesh1, directVertex, ANormalVector);
168 
169  // Suppression de l'extrémité entrante correspondante de l'ensemble
170  // de balayage:
171  sweepingSet.erase(it);
172  }
173 
174  // Passage à l'élément suivant:
175  eventTreatedSet.insert(current);
176  eventSet.erase(current);
177  }
178 
179  eventTreatedSet.swap(eventSet);
180 
181  // 4) Orientation:
182  int exterior = FMap->getNewMark();
183 
184  CDart* darts[2] = { ADart1, ADart2 };
185 
186  for (int i=0; i<2; ++i)
187  {
188  if (CGeometry::getAngle(FMap->cellDimensionNormalVector(darts[i], 3),
189  ANormalVector) > 90)
190  {
191  FMap->markOrbit (darts[i], ORBIT_CC, exterior);
192  FMap->halfUnmarkOrbit(darts[i], ORBIT_CC, exterior);
193  }
194  else
195  FMap->halfMarkOrbit(darts[i], ORBIT_CC, exterior);
196  }
197 
198  // 5) Tri lexicographique des extrémités en tenant compte des erreurs
199  // d'arrondi:
201  lexComparator2(FMap, directVertex,
202  extremity1, ANormalVector,
203  false /*comparaison à epsilon près*/);
204 
205  LEX_SET eventSet2(lexComparator2);
206  LEX_IT it;
207 
208  for (it = eventSet.begin(); it!=eventSet.end(); ++it)
209  eventSet2.insert(*it);
210 
211  // 6) Assemblage des 2 maillages:
213  angComparator(FMap, directVertex, ANormalVector);
214 
215  for (it = eventSet2.begin(); it!=eventSet2.end(); )
216  {
217  const CAttributeVertex & currentVertex = * GET_V(*it);
218  bool uniqueTopoVertex = true;
219 
220  LEX_IT first = it++;
221 
222  while (it!=eventSet2.end() && * GET_V(*it) == currentVertex)
223  {
224  if (GET_V(*it) != &currentVertex)
225  uniqueTopoVertex = false;
226 
227  ++it;
228  }
229 
230  if (!uniqueTopoVertex)
231  {
232  ANG_SET angSet(angComparator);
233 
234  // Tri angulaire:
235  for (LEX_IT local = first; local!=it; ++local)
236  {
237  CDart * current = *local;
238 
239  assert(! FMap->isFree2(current));
240 
241  if (! FMap->isMarked(current, exterior))
242  current = FMap->alpha2(current);
243 
244  assert(FMap->isMarked(current, exterior));
245  assert(FMap->findVertex(current) == GET_V(current));
246 
247  angSet.insert((CDartVertex*) current);
248  }
249 
250  // Coutures:
251  ANG_IT round = angSet.end();
252  CDart* pred = *(--round);
253 
254  for (round = angSet.begin(); round!=angSet.end(); ++round)
255  {
256  if (! FMap->isFree1(FMap->alpha2(pred)))
257  FMap->unsew1(FMap->alpha2(pred));
258 
259  if (! FMap->isFree1(*round))
260  FMap->unsew1(*round);
261 
262  assert(FMap->isMarked(FMap->alpha2(pred), exterior) !=
263  FMap->isMarked(*round, exterior));
264 
265  FMap->sew1(FMap->alpha2(pred), *round);
266  pred = *round;
267  }
268 
269  // Mise-à-jour des champs direct-info:
270  FMap->pointDirectInfoToAttributeVertex(directVertex, pred);
271  }
272  }
273 
274  // 7) Suppression des arêtes doubles:
275  int toDelete = FMap->getNewMark();
276 
277  CDynamicCoverageAll itAll(FMap);
278 
279  for (; itAll.cont(); ++itAll)
280  if (! FMap->isMarked(*itAll, toDelete) &&
281  ! FMap->isFree0(*itAll) && ! FMap->isFree1(*itAll) &&
282  (GET_V(FMap->alpha0(*itAll)) == GET_V(FMap->alpha10(*itAll))))
283  {
284  if (FMap->alpha01(*itAll) != FMap->alpha10(*itAll))
285  {
286  // "Décroisement" des arêtes:
287  CDart* d0 = FMap->alpha0 (*itAll); FMap->unsew0(d0 );
288  CDart* d10 = FMap->alpha10(*itAll); FMap->unsew0(d10);
289 
290  FMap->sew0( *itAll , FMap->alpha2(d10));
291  FMap->sew0(FMap->alpha1(*itAll), FMap->alpha2(d0 ));
292  }
293 
294  assert(FMap->alpha01(*itAll) == FMap->alpha10(*itAll));
295 
296  // Isolement et marquage de la face plate:
297  CDart* d2 = FMap->alpha2 (*itAll); FMap->unsew2(d2 );
298  CDart* d12 = FMap->alpha12(*itAll); FMap->unsew2(d12);
299 
300  FMap->sew2(d2, d12);
301 
302  FMap->markOrbit(*itAll, ORBIT_FACE, toDelete);
303  }
304 
305  // Suppression des brins marqués:
306  for (itAll.reinit(); itAll.cont(); )
307  {
308  CDart * current = itAll++;
309 
310  if (FMap->isMarked(current, toDelete))
311  FMap->delMapDart(current);
312  }
313 
314  FMap->freeMark(toDelete);
315 
316  // 8) Libération des ressources:
317  FMap->freeMark(treated);
318  FMap->freeDirectInfo(directVertex);
319 
320  FMap->unmarkAll(mesh1);
321  FMap->freeMark(mesh1);
322 
323  FMap->unmarkAll(exterior);
324  FMap->freeMark(exterior);
325 
326  FMap->unmarkAll(extremity1);
327  FMap->freeMark(extremity1);
328 }
329 //------------------------------------------------------------------------------
330 #undef GET_V
331 #undef IT_PRED
332 #undef IT_SUCC
333 //******************************************************************************
335 findElementInSweepingSet(VERT_SET & ASweepingSet, CDart * AElement)
336 {
337  assert(AElement != NULL);
338 
339  VERT_IT it = ASweepingSet.find((CDartVertex *) AElement);
340 
341  if (it == ASweepingSet.end())
342  {
343  cout << "Élément introuvable: " << AElement << "!" << endl;
344  it = ASweepingSet.begin();
345  while (it != ASweepingSet.end() && *it != AElement)
346  ++it;
347 
348  if (it==ASweepingSet.end())
349  {
350  cout << * (CVertex*) FMap->findVertex( AElement ) << endl;
351  cout << * (CVertex*) FMap->findVertex(FMap->alpha0(AElement)) << endl;
352  }
353 
354  assert(it != ASweepingSet.end());
355  }
356 
357  return it;
358 }
359 //******************************************************************************
360 #define GET_V(DART) FMap->getDirectInfoAsAttributeVertex((DART), ADirectVertex)
361 //------------------------------------------------------------------------------
363 manageEdgesIntersection(CDart * ADart1, CDart * ADart2,
364  LEX_SET & AEventSet,
365  const CDartLexicoCompare& ALexComparator,
366  VERT_SET & /*ASweepingSet*/,
367  int AExtremity1, int AMesh1, int ADirectVertex,
368  const CVertex & ANormalVector)
369 {
370  if (ADart1==NULL || ADart2==NULL)
371  return;
372 
373  if (FMap->isMarked(ADart1, AMesh1) == FMap->isMarked(ADart2, AMesh1))
374  return;
375 
376  // Plongements de la première arête:
377  CAttributeVertex* A = GET_V( ADart1 );
378  CAttributeVertex* B = GET_V(FMap->alpha0(ADart1));
379 
380  // Plongements de la deuxième arête:
381  CAttributeVertex* C = GET_V( ADart2 );
382  CAttributeVertex* D = GET_V(FMap->alpha0(ADart2));
383 
384  // Intersection éventuelle:
385  int cut[2];
386  CDart* cutDart[2] = { ADart1, ADart2 };
387  static CVertex intersections[2];
388 
389  CGeometry::getSegmentsIntersection(*A,*B,*C,*D, ANormalVector,
390  cut[0], intersections[0],
391  cut[1], intersections[1]);
392 
393  for (int i=1; i>=0; --i)
394  if (cut[i]!=0)
395  {
396  CDart* toCut = cutDart[cut[i]-1];
397 
398  assert(ALexComparator((CDartVertex*) toCut,
399  (CDartVertex*) FMap->alpha0(toCut)));
400 
401  FMap->CGMapGeneric::insertVertex(toCut);
402  FMap->setVertex(FMap->alpha0(toCut), intersections[i]);
403 
404  FMap->pointDirectInfoToAttributeVertex(ADirectVertex,
405  FMap->alpha0(toCut));
406 
407  FMap->setMark(FMap->alpha01(toCut), AExtremity1);
408 
409  if (FMap->isMarked(toCut, AMesh1))
410  FMap->markOrbit(FMap->alpha0(toCut), ORBIT_VERTEX, AMesh1);
411 
412  AEventSet.insert((CDartVertex*) FMap->alpha0 (toCut));
413  AEventSet.insert((CDartVertex*) FMap->alpha01(toCut));
414 
415  assert(ALexComparator((CDartVertex*) toCut,
416  (CDartVertex*) FMap->alpha0 (toCut)));
417  assert(ALexComparator((CDartVertex*) FMap->alpha01 (toCut),
418  (CDartVertex*) FMap->alpha010(toCut)));
419  }
420 }
421 //------------------------------------------------------------------------------
422 #undef GET_V
423 //******************************************************************************