Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rounding-vertex.cc
Go to the documentation of this file.
1 /*
2  * lib-rounding : Opérations de chamfreinage.
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-rounding
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 "rounding-vertex.hh"
26 #include "g-map-vertex.hh"
27 #include "geometry.hh"
28 #include <cstdlib>
29 #include <cassert>
30 using namespace GMap3d;
31 //******************************************************************************
33  CRoundingGeneric(AMap),
34  FMap(AMap)
35 {
36  assert(FMap != NULL);
37 
38  FCoefs[0] = FMap->getNewDirectInfo();
39  FCoefs[1] = FMap->getNewDirectInfo();
40 }
41 //------------------------------------------------------------------------------
43 {
44  FMap->freeDirectInfo(FCoefs[0]);
45  FMap->freeDirectInfo(FCoefs[1]);
46 }
47 //******************************************************************************
48 #define GET_KV(DART) ((FMap->isMarked((DART), AMarkNumber)) \
49  ? getDartRoundingCoef((DART), 0) \
50  : 0.0 )
51 //------------------------------------------------------------------------------
52 int CRoundingVertex::roundMarkedVertices(int AMarkNumber, bool ADig)
53 {
54  int nbRounded = 0;
55 
56  int directIndex = FMap->getNewDirectInfo();
57 
58  int treated = FMap->getNewMark();
59  int original = FMap->getNewMark();
60  int newdarts = FMap->getNewMark(); FMap->negateMaskMark(newdarts);
61 
62  CDynamicCoverageAll it(FMap);
63 
64  // On marque tous les brins de la G-carte par original :
65  FMap->negateMaskMark(original);
66 
67  /* Pour chaque brin de la carte, pointage du champ directInfo[directIndex]
68  * sur le plongement du sommet topologique auquel il appartient :
69  */
70  FMap->pointDirectInfoToAttributeVertex(directIndex);
71 
72  // Chanfreinage :
73  for (; it.cont(); ++it)
74  if (!FMap->isMarked(*it, treated))
75  {
76  if (FMap->isMarked(*it, AMarkNumber))
77  {
78  FMap->markOrbit(*it, ORBIT_VERTEX, treated);
79 
80  /* Initialement, tous les brins du sommet ont le même plongement,
81  * on ne détache donc que *it de son plongement.
82  */
83  CAttributeVertex* oldVertex = FMap->removeVertex(*it);
84 
85  CStaticCoverageVertex cov(FMap, *it);
86 
87  // Topologie -------------------------------------------------------
88 
89  /* On récupère la "dimension" d'une cellule pour savoir si on doit
90  * fermer ou non :
91  */
92  int roundingDim = getVertexRoundingDimension(*it, 0);
93  int closureLevel = getEdgeRoundingDimension(*it, 0);
94 
95  // On chanfreine l'arête :
96  if (!ADig)
97  chamferVertex(*it, closureLevel);
98  else if (roundingDim==3)
99  chamferVertex(*it, 2);
100  else
101  chamferVertex(*it, roundingDim);
102 
103  /* Fermeture : uniquement en 3D (et pas en 2D) car cela ne veut rien
104  * dire en 2D de fermer un objet par rapport à une arête :
105  */
106  if (!ADig && closureLevel==3)
107  {
108  bool stop = false;
109 
110  for (CDynamicCoverageVolume cov(FMap, FMap->alpha123(*it));
111  !stop && cov.cont(); ++cov)
112  if (FMap->isFree2(*cov))
113  {
114  FMap->stopUp(*cov, 2);
115  stop = true;
116  }
117  }
118 
119  // Géométrie -------------------------------------------------------
120  for ( ; cov.cont(); ++cov)
121  // Pour le cas des faces vides ou des arêtes pendantes ??
122  if (!FMap->isMarked(FMap->alpha1(*cov), treated))
123  {
124  CDart* d0 = FMap->alpha0(*cov);
125 
126  CAttributeVertex* vertex0;
127 
128  if (FMap->isMarked(d0, original))
129  vertex0 =
130  FMap->getDirectInfoAsAttributeVertex(d0, directIndex);
131  else
132  // Comment pourrait-il ne pas être original ???
133  vertex0 = FMap->findVertex(d0);
134 
135  // Plongement du nouveau sommet:
136  TCoordinate u = GET_KV(*cov);
137  FMap->setVertex(*cov, (1-u) * *oldVertex + u * *vertex0);
138 
139  // Marquage des derniers brins créés :
140  FMap->markOrbit(*cov, ORBIT_VERTEX, treated);
141  }
142 
143  // Démarquage pour la destruction finale:
144  // FMap->unsetMark(*it, treated);
145 
146  ++nbRounded;
147  }
148  else
149  FMap->setMark(*it, treated);
150  }
151 
152  // Destruction des anciens plongements:
153  for (it.reinit(); it.cont(); ++it)
154  if (!FMap->isMarked(*it, treated))
155  {
156  delete FMap->getDirectInfoAsAttributeVertex(*it, directIndex);
157  FMap->setMark(*it, treated);
158  }
159 
160  // Libération des marques et des champs directInfo:
161  FMap->negateMaskMark(treated);
162  FMap->freeMark(treated);
163 
164  FMap->unmarkAll(original);
165  FMap->freeMark(original);
166 
167  FMap->freeDirectInfo(directIndex);
168 
169  FMap->negateMaskMark(newdarts);
170  FMap->markIncidentCells(ORBIT_EDGE , newdarts);
171  FMap->markIncidentCells(ORBIT_VERTEX, newdarts);
172 
173  FMap->deleteMarkedNullLengthEdges(newdarts);
174  FMap->deleteMarkedFlatFaces (newdarts);
175  FMap->deleteMarkedFlatVolumes (newdarts);
176 
177  FMap->unmarkAll(newdarts);
178  FMap->freeMark(newdarts);
179 
180  return nbRounded;
181 }
182 //------------------------------------------------------------------------------
183 #undef GET_KV
184 //******************************************************************************
186  bool A3D, bool ADig, bool ASetback)
187 {
188  assert(!ADig || A3D);
189 
190  int nbRounded = 0;
191 
192  int selected = FMap->getNewMark();
193  int treated = FMap->getNewMark();
194  int initial = FMap->getNewMark();
195  int newdarts = FMap->getNewMark(); FMap->negateMaskMark(newdarts);
196 
197  int vertexToDestroy = FMap->getNewMark(); // sommets à détruire
198 
199  int directOldVertex = FMap->getNewDirectInfo(); // anciens sommets
200  int directNewVertex = FMap->getNewDirectInfo(); // nouveaux sommets
201 
202  CDynamicCoverageAll it(FMap);
203 
204  /* Pointage du champ directInfo[directOldVertex] sur le plongement sommet,
205  * ceci pour tous les brins de la carte :
206  */
207  FMap->pointDirectInfoToAttributeVertex(directOldVertex);
208 
209  /* Extension de la liste et suppression des anciens sommets des listes
210  * d'attributs :
211  */
212  doListExtension(AMarkNumber, initial, selected, treated,
213  vertexToDestroy, &it);
214 
215  /* Calcul des Min-Max :
216  * Le calcul des min-Max est différent en 2D et en 3D
217  * RQ : Le setback n'intervient pas ici car on ne fait que chercher
218  * le brin porteur du max pour les profondeurs d'arête. D'ailleurs
219  * les brins comparés ici possèdent le même coeff de setback par
220  * initialisation.
221  */
222  int max = FMap->getNewMark();
223 
224  doMinMaxCalcul(FCoefs[1], selected, treated, initial, max, A3D, &it);
225  /*
226  for (it.reinit(); it.cont(); ++it)
227  if (is_marked(*it, max))
228  set_mark(*it,1);
229  else
230  set_mark(*it,2);
231  */
232 
233  // Calcul des nouveaux sommets !!!!
234  doNewVerticesCalcul(selected, treated, initial, max, directOldVertex,
235  directNewVertex, ASetback, A3D, &it);
236 
237  nbRounded = doEdgeChamferingInRounding(treated, initial, ADig, A3D, &it);
238 
239  doVerticesChamferingInRounding(treated, initial, ADig, A3D, &it);
240 
241  // Retrait des arêtes de liaison inutiles (et des faces plates) :
242  for (it.reinit(); it.cont(); ++it)
243  if (!FMap->isMarked(*it, treated))
244  {
245  if (FMap->isMarked(*it, selected))
246  {
247  CDart* d101 = FMap->alpha101(*it); // d101 est forcément sélectionné
248 
249  FMap->setMark(FMap->alpha3(*it ), treated);
250  FMap->setMark( d101 , treated);
251  FMap->setMark(FMap->alpha3(d101), treated);
252 
253  if ((*it!=d101) && FMap->isMarked(*it, max) &&
254  FMap->isMarked(d101, max) &&
255  !FMap->isMarked(FMap->alpha1(*it), selected))
256  {
257  removeEdge(FMap->alpha1(*it));
258  // À faire: traitement des volumes vides.
259  }
260  }
261 
262  FMap->setMark(*it, treated);
263  }
264 
265  FMap->negateMaskMark(treated);
266 
267  // Position des nouveaux sommets :
268  for (it.reinit(); it.cont(); ++it)
269  if (!FMap->isMarked(*it, treated))
270  {
271  if (FMap->isMarked(*it, selected))
272  {
273  assert(FMap->findVertex(*it) == NULL);
274 
275  // Position du nouveau :
276  CAttributeVertex* vertex =
277  FMap->getDirectInfoAsAttributeVertex(*it, directNewVertex);
278  FMap->setVertex(*it, vertex);
279 
280  FMap->unsetMark(*it, selected);
281 
282  /* Destruction des autres, créés inutilement à cause des
283  * suppressions de cellules plates qui ont été effectuées :
284  */
285  for (CDynamicCoverageVertex cov(FMap, *it); cov.cont(); ++cov)
286  if (FMap->isMarked(*cov, selected))
287  {
288  FMap->unsetMark(*it, selected);
289  delete FMap->getDirectInfoAsAttributeVertex(*cov,
290  directNewVertex);
291  }
292 
293  FMap->markOrbit(*it, ORBIT_VERTEX, treated);
294  }
295  else
296  FMap->setMark(*it, treated);
297  }
298 
299  FMap->negateMaskMark(treated);
300 
301  // Destruction des anciens plongements :
302  for (it.reinit(); it.cont(); ++it)
303  if (FMap->isMarked(*it, vertexToDestroy))
304  {
305  delete FMap->getDirectInfoAsAttributeVertex(*it, directOldVertex);
306  FMap->unsetMark(*it, vertexToDestroy);
307  }
308 
309  // Libération des marques et des champs direct_info utilisés :
310  FMap->unmarkAll(max);
311  FMap->freeMark(max);
312 
313  FMap->unmarkAll(initial);
314  FMap->freeMark(initial);
315 
316  FMap->unmarkAll(selected);
317  FMap->freeMark(selected);
318 
319  FMap->freeMark(treated);
320 
321  FMap->freeMark(vertexToDestroy);
322  FMap->freeDirectInfo(directOldVertex);
323  FMap->freeDirectInfo(directNewVertex);
324 
325  FMap->negateMaskMark(newdarts);
326  FMap->markIncidentCells(ORBIT_EDGE , newdarts);
327  FMap->markIncidentCells(ORBIT_VERTEX, newdarts);
328 
329  FMap->deleteMarkedNullLengthEdges(newdarts);
330  FMap->deleteMarkedFlatFaces (newdarts);
331  FMap->deleteMarkedFlatVolumes (newdarts);
332 
333  FMap->unmarkAll(newdarts);
334  FMap->freeMark(newdarts);
335 
336  return nbRounded;
337 }
338 //------------------------------------------------------------------------------
339 void CRoundingVertex::doListExtension(int AMarkNumber, int AMarkInitial,
340  int AMarkSelected, int AMarkTreated,
341  int AMarkVertexToDestroy, CCoverage* ACov)
342 {
343  FMap->markIncidentCells(ORBIT_EDGE, AMarkNumber, AMarkInitial );
344  FMap->markIncidentCells(ORBIT_EDGE, AMarkNumber, AMarkSelected);
345 
346  for ( ; ACov->cont(); ++(*ACov))
347  if (!FMap->isMarked(**ACov, AMarkTreated))
348  {
349  if (FMap->isMarked(**ACov, AMarkSelected))
350  {
351  for (CDynamicCoverageVertex cov(FMap, **ACov); cov.cont(); ++cov)
352  {
353  if (FMap->getVertex(*cov) != NULL)
354  {
355  FMap->removeVertex(*cov);
356  FMap->setMark(*cov, AMarkVertexToDestroy);
357  }
358 
359  FMap->setMark(*cov, AMarkSelected);
360  FMap->setMark(*cov, AMarkTreated );
361  }
362  }
363  else
364  FMap->setMark(**ACov, AMarkTreated);
365  }
366 
367  FMap->negateMaskMark(AMarkTreated);
368 }
369 //------------------------------------------------------------------------------
370 #define GET_KE(DART) ((FMap->isMarked((DART), AMarkInitial)) \
371  ? (getDartRoundingCoef((DART), 1)) \
372  : 0.0 )
373 //..............................................................................
374 void CRoundingVertex::doMinMaxCalcul(int /*ADirectCoef1*/,
375  int AMarkSelected, int AMarkTreated,
376  int AMarkInitial, int AMarkMax,
377  bool A3D, CCoverage* ACov)
378 {
379  if (!A3D)
380  {
381  for (ACov->reinit(); ACov->cont(); ++(*ACov))
382  if (!FMap->isMarked(**ACov, AMarkTreated))
383  {
384  if (FMap->isMarked(**ACov, AMarkSelected))
385  {
386  CDartVertex* d = (CDartVertex*) **ACov ;
387  CDartVertex* d121 = (CDartVertex*) FMap->alpha121(**ACov);
388 
389  /* Voir ce qui se passe si d121 n'est pas le brin qu'on pense
390  * Rayons d'arrondi associés au brin courant et à son image par
391  * FMap->alpha2 :
392  */
393  TCoordinate val = GET_KE(d );
394  TCoordinate val121 = GET_KE(d121);
395 
396  if (isPositive(val-val121)) FMap->setMark(d , AMarkMax);
397  if (isPositive(val121-val)) FMap->setMark(d121, AMarkMax);
398 
399  FMap->setMark(d121, AMarkTreated);
400  }
401 
402  FMap->setMark(**ACov, AMarkTreated);
403  }
404  }
405  else
406  {
407  TCoordinate maxVal;
408 
409  for (ACov->reinit(); ACov->cont(); ++(*ACov))
410  if (!FMap->isMarked(**ACov, AMarkTreated))
411  {
412  if (FMap->isMarked(**ACov, AMarkSelected))
413  {
414  maxVal = 0;
415 
416  // Récupération du rayon d'arrondi maximum :
417  for (CDynamicCoverage23 cov1(FMap, FMap->alpha1(**ACov));
418  cov1.cont(); ++cov1)
419  {
420  TCoordinate cVal = GET_KE(FMap->alpha1(*cov1));
421 
422  if (isPositive(cVal-maxVal))
423  maxVal = cVal;
424  }
425 
426  // Marquage des brins par min ou Max :
427  for (CDynamicCoverage23 cov2(FMap, FMap->alpha1(**ACov));
428  cov2.cont(); ++cov2)
429  {
430  if (isPositive(GET_KE(FMap->alpha1(*cov2)) - maxVal))
431  FMap->setMark(FMap->alpha1(*cov2), AMarkMax);
432 
433  FMap->setMark(FMap->alpha1(*cov2), AMarkTreated);
434  }
435  }
436 
437  FMap->setMark(**ACov, AMarkTreated);
438  }
439  }
440 
441  FMap->negateMaskMark(AMarkTreated);
442 }
443 //..............................................................................
444 #undef GET_KE
445 //------------------------------------------------------------------------------
446 #define GET_KV(DART) (getDartRoundingCoef((DART), 0))
447 #define GET_KE(DART) ((FMap->isMarked(DART, AMarkInitial)) \
448  ? (getDartRoundingCoef((DART), 1)) \
449  : 0.0)
450 //..............................................................................
452 doNewVerticesCalcul(int AMarkSelected, int AMarkTreated,
453  int AMarkInitial, int AMarkMax,
454  int ADirectIndexOld, int ADirectIndexNew,
455  bool ASetback, bool A3D, CCoverage* ACov)
456 {
457  for (ACov->reinit(); ACov->cont(); ++(*ACov))
458  if (!FMap->isMarked(**ACov,AMarkTreated))
459  {
460  if (FMap->isMarked(**ACov, AMarkSelected))
461  {
462  CDartVertex* d = (CDartVertex*) **ACov ;
463  CDartVertex* d0 = (CDartVertex*) FMap->alpha0 (d );
464  CDartVertex* d1 = (CDartVertex*) FMap->alpha1 (d );
465  CDartVertex* d10 = (CDartVertex*) FMap->alpha10(d );
466  CDartVertex* d010 = (CDartVertex*) FMap->alpha10(d0 );
467  CDartVertex* d1010 = (CDartVertex*) FMap->alpha10(d10);
468 
469 #define GET_V(DART) (* FMap-> \
470  getDirectInfoAsAttributeVertex((DART), ADirectIndexOld))
471  CAttributeVertex& V1 = GET_V(d );
472  CAttributeVertex& V2 = GET_V(d10 );
473  CAttributeVertex& V3 = GET_V(d0 );
474  CAttributeVertex& V4 = GET_V(d1010);
475  CAttributeVertex& V5 = GET_V(d010 );
476 #undef GET_V
477 
478  // Rayons associés aux brins courants:
479  TCoordinate u = GET_KE(d );
480  TCoordinate u0 = GET_KE(d0 );
481  TCoordinate u10 = GET_KE(d10);
482  TCoordinate u1 = GET_KE(d1 );
483 
484  // Setback associé à d :
485  TCoordinate usb = GET_KV(d);
486 
487  CVertex V6 = (1-u )*V1 + u *V2;
488  CVertex V7 = (1-u0)*V3 + u0*V5;
489 
490  CVertex V8,V9;
491 
492  if (FMap->isMarked(d1, AMarkMax)) // d1 max
493  {
494  if (ASetback && isPositive(usb-u1) && !areEqual(usb,u1))
495  {
496  /* On a un setback dont on doit tenir compte.
497  * On marque d1 min car l'arête de liaison doit maintenant
498  * être conservée.
499  */
500  FMap->unsetMark(d1, AMarkMax);
501 
502  V8 = (1-usb )*V1 + usb*V3;
503  V9 = (1-(u10+usb-u1))*V2 + (u10+usb-u1)*V4;
504  }
505  else
506  {
507  V8 = (1-u1 )*V1 + u1 *V3;
508  V9 = (1-u10)*V2 + u10*V4;
509  }
510  }
511  else // d1 min
512  {
513  TCoordinate u2;
514 
515  if (A3D)
516  {
517  CDynamicCoverage23 cov2(FMap, d);
518 
519  while (cov2.cont() &&
520  ! FMap->isMarked(FMap->alpha1(*cov2), AMarkMax))
521  ++cov2;
522 
523  u2 = GET_KE(FMap->alpha1(*cov2));
524  }
525  else
526  {
527  u2 = GET_KE(FMap->alpha21(d));
528  }
529 
530  TCoordinate ui = u10 + u2 - u1;
531 
532  if (ASetback && isPositive(usb-u2) && !areEqual(usb,u2))
533  {
534  // On a un setback dont on doit tenir compte :
535  V8 = (1-usb)*V1 + usb*V3;
536  V9 = (1-(u10+usb-u2))*V2 + (u10+usb-u2)*V4;
537  }
538  else
539  {
540  V8 = (1-u2)*V1 + u2*V3;
541  V9 = (1-ui)*V2 + ui*V4;
542  }
543  }
544 
545  CVertex newVertex = CGeometry::getLinesIntersection(V6,V7, V8,V9);
546 
547  FMap->setDirectInfo(d, ADirectIndexNew,
548  new CAttributeVertex(newVertex));
549 
550  if (FMap->isMarked(d1, AMarkMax) && FMap->isMarked(d,AMarkMax))
551  {
552  FMap->setDirectInfo(d1, ADirectIndexNew,
553  new CAttributeVertex(newVertex));
554  // FMap->setMark(d1,AMarkTreated);
555  }
556  }
557 
558  FMap->setMark(**ACov,AMarkTreated);
559  }
560 
561  FMap->negateMaskMark(AMarkTreated);
562 }
563 //..............................................................................
564 #undef GET_V
565 #undef GET_K
566 #undef GET_KV
567 //------------------------------------------------------------------------------
569 doEdgeChamferingInRounding(int AMarkTreated, int AMarkInitial,
570  bool ADig, bool A3D, CCoverage* ACov)
571 {
572  int nbRounded = 0;
573  int closureLevel;
574 
575  // Chanfreinage des arêtes :
576  for (ACov->reinit(); ACov->cont(); ++(*ACov))
577  if (! FMap->isMarked(**ACov, AMarkTreated))
578  {
579  if (FMap->isMarked(**ACov, AMarkInitial))
580  {
581  CDartVertex* d = (CDartVertex*) **ACov;
582 
583  // On marque tous les brins de l'arête contenant d :
584  FMap->markOrbit(**ACov, ORBIT_EDGE, AMarkTreated);
585 
586  FMap->negateMaskMark(AMarkTreated);
587 
588  /* On récupère la "dimension" d'une cellule pour savoir si on doit
589  * fermer ou non :
590  */
591  closureLevel = getEdgeRoundingDimension(d,1);
592 
593  // On chanfreine l'arête :
594  if (!ADig)
595  chamferEdge(d, closureLevel);
596  else
597  {
598  if (getVertexRoundingDimension(d, 1) == 3)
599  chamferEdge(d, 2);
600  else
602  }
603 
604  /* Fermeture : uniquement en 3D et pas en 2D car cela ne veut rien
605  * dire en 2D de fermer un objet par rapport à une arête.
606  */
607  if (A3D && !ADig && closureLevel==3)
608  {
609  bool stop = false;
610 
611  for (CDynamicCoverageVolume cov(FMap, FMap->alpha23(d));
612  !stop && cov.cont(); ++cov)
613  if (FMap->isFree2(*cov))
614  {
615  FMap->stopUp(*cov, 2);
616  stop = true;
617  }
618  }
619 
620  FMap->negateMaskMark(AMarkTreated);
621  ++nbRounded;
622  }
623 
624  FMap->setMark(**ACov, AMarkTreated);
625  }
626 
627  FMap->negateMaskMark(AMarkTreated);
628 
629  return nbRounded;
630 }
631 //------------------------------------------------------------------------------
633  int AMarkInitial,
634  bool ADig, bool A3D,
635  CCoverage* ACov)
636 {
637  int closureLevel;
638 
639  // Chanfreinage des sommets :
640  for (ACov->reinit(); ACov->cont(); ++(*ACov))
641  if (!FMap->isMarked(**ACov, AMarkTreated))
642  {
643  if (FMap->isMarked(**ACov, AMarkInitial))
644  {
645  // On marque tous les brins de l'orbite sommet incidente à *it :
646  FMap->markOrbit(**ACov, ORBIT_VERTEX, AMarkTreated);
647 
648  closureLevel = getEdgeRoundingDimension(**ACov,0);
649 
650  // On chanfreine le sommet:
651  FMap->negateMaskMark(AMarkTreated);
652 
653  if (!ADig)
654  chamferVertex(**ACov, closureLevel);
655  else if (getVertexRoundingDimension(**ACov, 0)==3)
656  chamferVertex(**ACov, 2);
657  else
658  chamferVertex(**ACov, getVertexRoundingDimension(**ACov, 0));
659 
660  // Fermeture :
661  if (A3D && !ADig && closureLevel==3)
662  {
663  bool stop = false;
664 
665  for (CDynamicCoverageVolume cov(FMap, FMap->alpha123(**ACov));
666  !stop && cov.cont(); ++cov)
667  if (FMap->isFree2(*cov))
668  {
669  FMap->stopUp(*cov, 2);
670  stop = true;
671  }
672  }
673  // 2D et 3D même combat :
674  else if (!ADig && closureLevel==2)
675  {
676  bool stop = false;
677 
678  for (CDynamicCoverageVolume cov(FMap, FMap->alpha123(**ACov));
679  !stop && cov.cont(); ++cov)
680  if (FMap->isFree1(*cov))
681  {
682  FMap->stopUp(*cov, 1);
683  stop = true;
684  }
685  }
686 
687  FMap->negateMaskMark(AMarkTreated);
688  }
689 
690  FMap->setMark(**ACov, AMarkTreated);
691  }
692 
693  FMap->negateMaskMark(AMarkTreated);
694 }
695 //******************************************************************************
696 TCoordinate CRoundingVertex::getDartRoundingCoef(CDart* ADart,
697  int ADimension) const
698 {
699  assert(ADimension == 0 || ADimension == 1);
700  return ((long int) (ADart->getDirectInfo(FCoefs[ADimension]))) / 1000.0;
701 }
702 //------------------------------------------------------------------------------
703 void CRoundingVertex::setDartRoundingCoef(CDart* ADart, int ADimension,
704  TCoordinate AValue) const
705 {
706  assert(ADimension == 0 || ADimension == 1);
707  ADart->setDirectInfo(FCoefs[ADimension], (void*) (long int) (1000 * AValue));
708 }
709 //******************************************************************************