Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rounding-generic.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-generic.hh"
26 #include "g-map-generic.hh"
27 #include <cstdlib>
28 #include <cassert>
29 using namespace GMap3d;
30 //******************************************************************************
32  FMap(AMap)
33 {
34  assert(FMap != NULL);
35 }
36 //------------------------------------------------------------------------------
38 {
39 }
40 //******************************************************************************
41 void CRoundingGeneric::chamferCell(CDart* ADart, int ACellDim, int AMaxDim)
42 {
43  assert(ADart != NULL);
44  assert(0 <= ACellDim && ACellDim <= 2);
45 
46  int treated = FMap->getNewMark();
47 
48  CCoverage* cov = FMap->getStaticCoverage(ADart, ORBIT_CELL[ACellDim]);
49 
50  for (; cov->cont(); ++(*cov))
51  {
52  CDart* current = **cov;
53 
54  CDart* d0 = FMap->alpha0(current);
55  CDart* d1 = FMap->alpha1(current);
56  CDart* d2 = FMap->alpha2(current);
57  CDart* d3 = FMap->alpha3(current);
58 
59  addDartChain(current, 0, AMaxDim);
60 
61  if (FMap->isMarked(d0, treated))
62  chamfreinLink(current, d1, 0, ACellDim, AMaxDim);
63 
64  if (FMap->isMarked(d1, treated))
65  chamfreinLink(current, d1, 1, ACellDim, AMaxDim);
66 
67  if (FMap->isMarked(d2, treated))
68  chamfreinLink(current, d2, 2, ACellDim, AMaxDim);
69 
70  if (FMap->isMarked(d3, treated))
71  chamfreinLink(current, d3, 3, ACellDim, AMaxDim);
72 
73  FMap->setMark(current, treated);
74  }
75 
76  for (cov->reinit(); cov->cont(); ++(*cov))
77  FMap->unsetMark(**cov, treated);
78 
79  FMap->freeMark(treated);
80 
81  delete cov;
82 }
83 //******************************************************************************
84 void CRoundingGeneric::chamferVertex(CDart* ADart, int AMaxDim)
85 {
86  assert(ADart != NULL);
87 
88  CStaticCoverageVertex cov(FMap, ADart);
89 
90  int treated = FMap->getNewMark();
91 
92  for (; cov.cont(); ++cov)
93  {
94  CDart* current = *cov;
95 
96  CDart* d1 = FMap->alpha1(current);
97  CDart* d2 = FMap->alpha2(current);
98  CDart* d3 = FMap->alpha3(current);
99 
100  addDartChain(current, 0, AMaxDim);
101 
102  if (FMap->isMarked(d1, treated)) chamfreinLink(current, d1, 1,0, AMaxDim);
103  if (FMap->isMarked(d2, treated)) chamfreinLink(current, d2, 2,0, AMaxDim);
104  if (FMap->isMarked(d3, treated)) chamfreinLink(current, d3, 3,0, AMaxDim);
105 
106  FMap->setMark(current, treated);
107  }
108 
109  for (cov.reinit(); cov.cont(); ++cov)
110  FMap->unsetMark(*cov, treated);
111 
112  FMap->freeMark(treated);
113 }
114 //------------------------------------------------------------------------------
115 void CRoundingGeneric::chamferEdge(CDart * ADart, int AMaxDim)
116 {
117  assert(ADart!=NULL);
118 
119  CStaticCoverageEdge cov(FMap, ADart);
120 
121  int treated = FMap->getNewMark();
122 
123  for (; cov.cont(); ++cov)
124  {
125  CDart* current = *cov;
126 
127  CDart* d0 = FMap->alpha0(current);
128  CDart* d2 = FMap->alpha2(current);
129  CDart* d3 = FMap->alpha3(current);
130 
131  addDartChain(current, 1, AMaxDim);
132 
133  if (FMap->isMarked(d0, treated)) chamfreinLink(current, d0, 0,1, AMaxDim);
134  if (FMap->isMarked(d2, treated)) chamfreinLink(current, d2, 2,1, AMaxDim);
135  if (FMap->isMarked(d3, treated)) chamfreinLink(current, d3, 3,1, AMaxDim);
136 
137  FMap->setMark(current, treated);
138  }
139 
140  for (cov.reinit(); cov.cont(); ++cov)
141  FMap->unsetMark(*cov, treated);
142 
143  FMap->freeMark(treated);
144 }
145 //******************************************************************************
146 void CRoundingGeneric::addDartChain(CDart* ADart, int ADimMin, int ADimMax)
147 {
148  assert(ADart != NULL);
149  assert(0 <= ADimMin);
150  assert(ADimMin < ADimMax);
151  assert(ADimMax <= 3);
152 
153  CDart* d1 = ADart;
154 
155  for (int dim = ADimMin+1; dim <= ADimMax; ++dim)
156  {
157  CDart* d2 = FMap->addMapDart();
158  FMap->linkAlpha(d1, d2, dim);
159  d1 = d2;
160  }
161 }
162 //******************************************************************************
163 void CRoundingGeneric::chamfreinLink(CDart* ADart1, CDart* ADart2,
164  int ADim, int ADimMin, int ADimMax)
165 {
166  assert(ADart1 != NULL);
167  assert(ADart2 != NULL);
168 
169  assert(ADim != ADimMin);
170  assert(ADimMin < ADimMax);
171 
172  for (int dim = ADimMin+1; dim <= ADimMax; ++dim)
173  {
174  ADart1 = FMap->alpha(ADart1, dim);
175  ADart2 = FMap->alpha(ADart2, dim);
176 
177  if (dim < ADim)
178  {
179  if (dim < ADim-1)
180  FMap->linkAlpha(ADart1, ADart2, ADim);
181  }
182  else
183  if (ADim != ADimMin)
184  FMap->linkAlpha(ADart1, ADart2, ADim<ADimMin ? ADim : ADim-1);
185  }
186 }
187 //******************************************************************************
188 int CRoundingGeneric::getVertexRoundingDimension(CDart* ADart, int ACellDim)
189 {
190  assert(ADart != NULL);
191  assert(0<=ACellDim && ACellDim<=3);
192 
193  int i = 0;
194  bool cont = true;
195 
196  while (cont && i<4)
197  {
198  if (i != ACellDim)
199  cont = FMap->isIClosedOrbit(ADart, i, ORBIT_CELL[ACellDim]);
200 
201  if (cont)
202  ++i;
203  }
204 
205  return i-1;
206 }
207 //------------------------------------------------------------------------------
208 int CRoundingGeneric::getEdgeRoundingDimension(CDart* ADart, int ACellDim)
209 {
210  assert(ADart != NULL);
211  assert(0<=ACellDim && ACellDim<=3);
212 
213  int i = getVertexRoundingDimension(ADart, ACellDim);
214 
215  if (i<3 && ! FMap->isIFreeOrbit(ADart, i, ORBIT_CELL[ACellDim]))
216  return i+1;
217 
218  return i;
219 }
220 //- AUTRE VERSION: -------------------------------------------------------------
221 // int CRoundingGeneric::getEdgeRoundingDimension(CDart* ADart, int ACellDim)
222 // {
223 // assert(ADart != NULL);
224 // assert(0<=ACellDim && ACellDim<=3);
225 //
226 // int i, j;
227 // bool cont = true;
228 //
229 // for (i=0; cont && i<4; ++i)
230 // if (i != j)
231 // cont = FMap->isIClosedOrbit(ADart, i, ORBIT_CELL[ACellDim]);
232 //
233 // // À ce stade, on sait que la cellule est fermée
234 // // jusqu'à la dimension i-1 incluse.
235 //
236 // if (i==4)
237 // {
238 // if (FMap->isIClosedOrbit(ADart, 3, ORBIT_CELL[ACellDim]))
239 // return 3;
240 //
241 // if (FMap->isIFreeOrbit(ADart, 3, ORBIT_CELL[ACellDim]))
242 // return 2;
243 //
244 // return 3;
245 // }
246 //
247 // return FMap->isIFreeOrbit(ADart, i, ORBIT_CELL[ACellDim]) ? i-1 : i;
248 // }
249 //******************************************************************************
251 {
252  assert(ADart != NULL);
253 
254  for (CDynamicCoverage23 cov(FMap, ADart); cov.cont(); )
255  {
256  CDart* current = cov++;
257 
258  if (! FMap->isFree1(current) &&
259  ! FMap->isFree1(FMap->alpha0(current)))
260  FMap->linkAlpha1(FMap->alpha1(current), FMap->alpha01(current));
261  else
262  {
263  FMap->unlinkAlpha1( current );
264  FMap->unlinkAlpha1(FMap->alpha0(current));
265  }
266 
267  if (! FMap->isFree0(current))
268  FMap->delMapDart(FMap->alpha0(current));
269 
270  FMap->delMapDart(current);
271  }
272 }
273 //******************************************************************************