Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmg-contract-and-remove.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"
26 #include <deque>
27 using namespace std;
28 using namespace GMap3d;
29 //******************************************************************************
30 // Contractions et suppressions simultanées de cellules de dimension quelconque.
31 // Pour chaque cellule concernée, un marquage sur un brin incident à celle-ci
32 // indique l'opération à affectuer.
33 //
34 // dim == 3: contraction de volume
35 // (précondition : volume de degré inférieur local égal à 2)
36 // dim == 2: contraction ou suppression de face
37 // (pas de précondition pour la suppression)
38 // (précondition contraction : face de degré inférieur local égal à 2)
39 // dim == 1: contraction ou suppression d'arête
40 // (pas de précondition pour la contraction)
41 // (précondition suppression: arête de degré inférieur local égal à 2)
42 // dim == 0: suppression de sommet
43 // (précondition : sommet de degré inférieur local égal à 2)
44 //******************************************************************************
46  int AMarkNumberC2,
47  int AMarkNumberC3,
48  int AMarkNumberS0,
49  int AMarkNumberS1,
50  int AMarkNumberS2,
51  bool ADeleteDarts )
52 {
53 
54  int marks[6]; // contiendra les 6 marques passées en paramètre
55  // - La dimension de la cellule concernée par l'opération
56  // de marque rangée dans la case i du tableau est (i+1)%4.
57 
58  int nbCellMarked = 0; // Indique le nombre cellules supprimées et contractées
59 
60  marks[0] = AMarkNumberC1;
61  marks[1] = AMarkNumberC2;
62  marks[2] = AMarkNumberC3;
63  marks[3] = AMarkNumberS0;
64  marks[4] = AMarkNumberS1;
65  marks[5] = AMarkNumberS2;
66 
67  // On marque les brins de chaque cellule concernée par l'une des opérations
68  for(int i=0 ; i<=5; i++)
69  {
70  if (marks[i]!=-1)
71  {
72  nbCellMarked += markIncidentCells(ORBIT_CELL[(i+1)%4], marks[i]);
73  }
74  }
75 
76  // On démarque les cellules qui ne respectent pas les préconditions de la suppression
77  // ou de la contraction
78  CDynamicCoverageAll cov(this);
79  for ( ; cov.cont(); ++cov )
80  {
81  for(int i=0; i<=2; i++)
82  {
83  if (marks[i]!=-1)
84  {
85  if ( isMarked(*cov, marks[i]) )
86  {
87  int cell = i+1;
88  if ( !canContract(*cov, cell) )
89  {
90  unmarkOrbit( *cov, ORBIT_CELL[cell], marks[i]);
91  nbCellMarked--;
92  }
93  }
94  }
95  }
96  for(int i=3; i<=5; i++)
97  {
98  if (marks[i]!= -1)
99  {
100  if ( isMarked(*cov, marks[i]) )
101  {
102  int cell = (i+1)%4;
103  if ( !canRemove(*cov, cell) )
104  {
105  unmarkOrbit( *cov, ORBIT_CELL[cell], marks[i]);
106  nbCellMarked--;
107  }
108  }
109  }
110  }
111  }
112 
113  int firstMark; // La première marque rencontrée.
114  int nbMark;
115  int cell;
116 
117  // On démarque les cellules non disjointes
118  for ( cov.reinit(); cov.cont(); ++cov )
119  {
120  firstMark = -1;
121  nbMark = 0;
122 
123  for(int i=0; i<=5; i++)
124  {
125  if( marks[i] != -1 )
126  if ( isMarked(*cov, marks[i]) )
127  {
128  ++nbMark;
129 
130  if ( firstMark==-1 ) firstMark = i;
131  else
132  {
133  cell = (i+1)%4;
134  unmarkOrbit( *cov, ORBIT_CELL[cell], marks[i]);
135  nbCellMarked--;
136  }
137  }
138  }
139 
140  if ( nbMark>1 )
141  {
142  cell = (firstMark+1)%4;
143  unmarkOrbit( *cov, ORBIT_CELL[cell], marks[firstMark]);
144  }
145  }
146 
147  // et on contracte ou supprime ce qui reste marqué
148  CDart* current = NULL;
149  CDart* t2 = NULL;
150 
151  for ( cov.reinit(); cov.cont(); ++cov )
152  {
153  for(int i=0; i<=1; i++)
154  {
155  int cell = (i+1)%4;
156  if (marks[i] != -1)
157  {
158  if ( !(isMarked( *cov, marks[i]) ||
159  isMarked( *cov, marks[i+4]) ) &&
160  (isMarked( alpha(*cov, cell), marks[i]) ||
161  isMarked( alpha(*cov, cell), marks[i+4])) )
162  {
163  current = *cov;
164  t2 = alpha(current, cell);
165 
166  while (isMarked(t2, marks[i]) || isMarked(t2, marks[i+4]) )
167  {
168  if (isMarked(t2, marks[i]))
169  t2 = alpha(alpha(t2, cell-1), cell);
170  else
171  t2 = alpha(alpha(t2, cell+1), cell);
172  }
173 
174  if ( t2 != alpha(current, cell) )
175  {
176  unsew(current, cell);
177  if ( !isFree(t2, cell) ) unsew(t2, cell);
178  if ( t2!=current ) sew(current, t2, cell);
179  }
180  }
181  }
182  }
183  if (AMarkNumberC3 != -1)
184  {
185  if ( !isMarked( *cov, AMarkNumberC3) &&
186  isMarked( alpha(*cov, 3), AMarkNumberC3) )
187  {
188  current = *cov;
189  t2 = alpha(current, 3);
190 
191  while (isMarked(t2, AMarkNumberC3))
192  {
193  t2 = alpha(alpha(t2, 2), 3);
194  }
195 
196  if ( t2 != alpha(current, 3) )
197  {
198  unsew(current, 3);
199  if ( !isFree(t2, 3) ) unsew(t2, 3);
200  if ( t2!=current ) sew(current, t2, 3);
201  }
202  }
203  }
204  if (AMarkNumberS0 != -1)
205  {
206  if ( !isMarked( *cov, AMarkNumberS0) &&
207  isMarked( alpha(*cov, 0), AMarkNumberS0) )
208  {
209  current = *cov;
210  t2 = alpha(current, 0);
211 
212  while (isMarked(t2, AMarkNumberS0))
213  {
214  t2 = alpha(alpha(t2, 1), 0);
215  }
216 
217  if ( t2 != alpha(current, 0) )
218  {
219  unsew(current, 0);
220  if ( !isFree(t2, 0) ) unsew(t2, 0);
221  if ( t2!=current ) sew(current, t2, 0);
222  }
223  }
224  }
225  }
226 
227  // on netoie si demandé
228  if (ADeleteDarts)
229  {
230  for (cov.reinit(); cov.cont(); )
231  {
232  for (int i=0; i<=5; i++)
233  {
234  if(marks[i] != -1)
235  {
236  if ( isMarked(*cov, marks[i]) )
237  {
238  delMapDart(*cov);
239  i=5;
240  }
241  }
242  if (i==5) ++cov;
243  }
244  }
245  }
246  return nbCellMarked;
247 }