Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmg-fictive-face.cc
Go to the documentation of this file.
1 /*
2  * lib-gmapkernel : Un noyau de 3-G-cartes et des opérations.
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-gmapkernel
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 "g-map-generic.hh"
27 using namespace GMap3d;
28 //******************************************************************************
30  int AFictiveFaceMark,
31  int ADeleteMark)
32 {
33  assert( ADart!=NULL );
34  assert( !isFree1(ADart) );
35  assert( !isFree2(ADart) );
36  assert( isFree3(ADart) );
37  assert( !isFree3(alpha2(ADart)) );
38  assert( isMarked(alpha2(ADart), AFictiveFaceMark) );
39 
40  CDart* last = NULL;
41  CDart* d1 = NULL;
42  CDart* d2 = NULL;
43 
44  CDynamicCoverage23 it(this,ADart);
45  while ( it.cont() )
46  {
47  if ( isMarked(*it, AFictiveFaceMark) && !isMarked(*it, ADeleteMark) )
48  {
49  d1 = alpha1(*it);
50  d2 = alpha01(*it);
51 
52  if ( !isFree1(*it) )
53  {
54  unsew1(*it);
55  assert( !isFree1(alpha0(*it)) );
56  unsew1(alpha0(*it));
57  sew1( d1, d2 );
58  }
59 
60  setMark( *it, ADeleteMark );
61  setMark( alpha0(*it), ADeleteMark );
62  }
63  last = it++;
64  }
65 
66  assert( isFree3(last) && last!=ADart );
67  unsew2( last );
68  unsew2( ADart );
69 
70  sew2( last, ADart );
71 }
72 //******************************************************************************
73 void CGMapGeneric::shiftOneFictiveFace(CDart* ADart, int AFictiveFaceMark,
74  int ADeleteMark)
75 {
76  assert( ADart!=NULL );
77  assert( !isFree1(ADart) );
78  assert( !isFree2(ADart) );
79  assert( isFree3(ADart) );
80  assert( !isFree3(alpha2(ADart)) );
81  assert( isMarked(alpha2(ADart), AFictiveFaceMark) );
82 
83  unsigned int directInfo = getNewDirectInfo();
84  unsigned int nextAlpha = 0;
85 
86  CDart * d1 = alpha1(ADart);
87  CDart * d2 = alpha232(ADart);
88  CDart * n1 = NULL;
89  CDart * n2 = NULL;
90  CDart * toDelete = alpha2(ADart);
91  CDart * prev = ADart;
92 
93  // Initialisations et décourures / re-coutures
94  setDirectInfo( ADart, directInfo, alpha3(alpha21(ADart)) );
95  setDirectInfo( alpha0(ADart), directInfo, alpha3(alpha201(ADart)) );
96 
97  unsew1( toDelete );
98  unsew1( alpha0(toDelete) );
99 
100  unsew2( ADart );
101  unsew2( d2 );
102 
103  sew2( ADart, d2 );
104 
105  // Boucle sur tout les brins à traiter.
106  while ( d1!=alpha0(ADart) )
107  {
108  d2 = alpha2( d1 );
109 
110  n1 = addMapDart(); n2 = addMapDart();
111  setMark(n1, AFictiveFaceMark); setMark(n2, AFictiveFaceMark);
112 
113  linkAlpha3( n1, n2 );
114 
115  linkAlpha2( d1, n1 ); linkAlpha2( d2, n2 );
116 
117  setDirectInfo( d1, directInfo, n1 );
118 
119  if ( nextAlpha==0 )
120  {
121  linkAlpha1( n1, (CDart*)getDirectInfo(prev, directInfo) );
122  linkAlpha1( n2, alpha3((CDart*)getDirectInfo(prev, directInfo)) );
123  }
124  else
125  {
126  assert ( nextAlpha==1 );
127  linkAlpha0( n1, (CDart*)getDirectInfo(prev, directInfo) );
128  linkAlpha0( n2, alpha3((CDart*)getDirectInfo(prev, directInfo)) );
129  }
130 
131  // Passage au prochain brin
132  prev = d1;
133  d1 = alpha(d1, nextAlpha);
134  /* En sautant les arêtes fictives et les arêtes pendantes ???
135  if ( d1!=alpha0(ADart) && nextAlpha==1 )
136  while ( d1!=alpha0(ADart) &&
137  (isMarked(d1, AFictiveEdgeMark) || alpha01(d1)==alpha20(d1)) )
138  d1 = alpha21(d1);
139  */
140  nextAlpha = ( nextAlpha==0 ? 1 : 0 );
141  }
142 
143  assert ( nextAlpha==0 );
144  linkAlpha1( n1, (CDart*)getDirectInfo(d1, directInfo) );
145  linkAlpha1( n2, alpha3((CDart*)getDirectInfo(d1, directInfo)) );
146 
147  // Suppression des brins inutiles.
148  setMark(alpha03(toDelete), ADeleteMark);
149  setMark(alpha3(toDelete), ADeleteMark);
150  setMark(alpha0(toDelete), ADeleteMark);
151  setMark(toDelete, ADeleteMark);
152  // delMapDart(alpha03(toDelete)); delMapDart(alpha3(toDelete));
153  // delMapDart(alpha0(toDelete)); delMapDart(toDelete);
154 
155  freeDirectInfo(directInfo);
156 }
157 //******************************************************************************
158 bool CGMapGeneric::canShiftOneFictiveFace(CDart* ADart, int AFictiveFaceMark)
159 {
160  assert( ADart!=NULL );
161  assert( !isFree1(ADart) );
162  assert( !isFree2(ADart) );
163  assert( !isFree3(ADart) );
164  assert( !isFree2(alpha3(ADart)) );
165  assert( isMarked(ADart, AFictiveFaceMark) );
166 
167  int currentFace = getNewMark();
168  bool res = true;
169  CDart * d1 = alpha1(ADart);
170  bool edgeMarked, vertexMarked;
171 
172  // On marque la face courante
173  markOrbit( ADart, ORBIT_FACE, currentFace);
174 
175  while ( res && d1!=alpha0(ADart) )
176  {
177  edgeMarked = false;
178  vertexMarked = false;
179 
180  for (CDynamicCoverageEdge it(this, d1); !edgeMarked && it.cont(); ++it)
181  edgeMarked = isMarked(*it, currentFace);
182 
183  for (CDynamicCoverageEdge it(this, alpha1(d1));
184  !edgeMarked && it.cont(); ++it)
185  edgeMarked = isMarked(*it, currentFace);
186 
187  if ( !edgeMarked )
188  {
189  for (CDynamicCoverageVertex it(this, d1); !vertexMarked && it.cont();
190  ++it)
191  vertexMarked = isMarked(*it, currentFace);
192 
193  if ( vertexMarked ) res = false;
194  }
195 
196  d1 = alpha01(d1);
197  }
198 
199  // On démarque la face courante et on libère les marques
200  unmarkOrbit( ADart, ORBIT_FACE, currentFace);
201  freeMark(currentFace);
202 
203  return res;
204 }
205 //******************************************************************************
206 void CGMapGeneric::shiftAllFictiveFaces(CDart* ADart, int AFictiveFaceMark,
207  int ADeleteMark)
208 {
209  assert( !isMarked(ADart, AFictiveFaceMark) );
210  assert( !isFree2(ADart) && isFree3(ADart) );
211 
212  while ( isMarked(alpha2(ADart), AFictiveFaceMark) )
213  {
214  shiftOneFictiveFace(ADart, AFictiveFaceMark, ADeleteMark);
215  }
216 }
217 //******************************************************************************
218 bool CGMapGeneric::canShiftAllFictiveFaces(CDart* ADart, int AFictiveFaceMark)
219 {
220  assert( !isMarked(ADart, AFictiveFaceMark) );
221  assert( !isFree2(ADart) && isFree3(ADart) );
222 
223  bool res = true;
224  CDart* current = alpha2(ADart);
225 
226  while ( res && isMarked(current, AFictiveFaceMark) )
227  {
228  res = canShiftOneFictiveFace(current, AFictiveFaceMark);
229  current = alpha32(current);
230  }
231  return res;
232 }
233 //******************************************************************************
234 int CGMapGeneric::findEdgeType( CDart* ADart, CDart** AFirstDart,
235  int AFictiveFaceMark )
236 {
237  assert( ADart!=NULL );
238 
239  int markEdge = getNewMark();
240  int markFace = getNewMark();
241  int res = 0;
242  int nbReel = 0; // Pour compter le nombre d'arête réelle non boucle
243  bool reelDangling = false;
244 
245  CDynamicCoverageEdge it(this, ADart);
246  for ( ; it.cont(); ++it )
247  setMark(*it, markEdge);
248 
249  // On parcours l'arête. On s'arrête si on a trouvé et une face réelle
250  // et une face non boucle, ou plus de 2 faces réelles.
251  for ( it.reinit(); it.cont() && nbReel<=2 && (!reelDangling || nbReel==1);
252  ++it )
253  {
254  if ( !isMarked(*it, markFace) )
255  {
256  // Si on n'est pas sur une face fictive
257  if ( !isMarked(*it, AFictiveFaceMark) )
258  {
259  if ( isMarked(alpha1(*it), markEdge) ||
260  isMarked(alpha01(*it), markEdge) )
261  {
262  *AFirstDart = *it;
263  reelDangling = true; // Ici la face de degré 1 est incidente
264  // à une arête pendante.
265  }
266  else
267  {
268  if ( nbReel==0 )
269  *AFirstDart = *it; // Cette face est réelle et non boucle
270  }
271  ++nbReel; // On compte le nombre de faces réelles
272  markOrbit(*it, ORBIT_FACE, markFace);
273  }
274  }
275  }
276 
277  if ( reelDangling ) // On a trouvé une boucle réelle
278  {
279  if ( nbReel==1 ) res = 1; // C'est la seule face réelle
280  else res = 3; // Il y a d'autres faces réelle incidentes à l'arête
281  }
282  else
283  {
284  if ( nbReel==2 )
285  res = 2; // On a exactement 2 faces réelles sans arête pendante
286  else if ( nbReel!=0 ) res = 3; // cas ==1 ou >2
287  }
288 
289  // On refait le parcours du sommet pour enlever les marques
290  for ( it.reinit(); it.cont(); ++it )
291  {
292  if ( isMarked(*it, markFace) )
293  unmarkOrbit(*it, ORBIT_FACE, markFace);
294 
295  unsetMark(*it, markEdge);
296  }
297 
298  // assert(isWholeMapUnmarked(markEdge));
299  // assert(isWholeMapUnmarked(markFace));
300 
301  freeMark(markEdge);
302  freeMark(markFace);
303 
304  return res;
305 }
306 //******************************************************************************