Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
mg-cell-identification.cc
Go to the documentation of this file.
1 /*
2  * lib-mesh : Opérations de maillage et lissage.
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-mesh
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 "mesh-generic.hh"
26 #include "g-map-generic.hh"
27 using namespace GMap3d;
28 //******************************************************************************
29 #define SIDE(DART) ((((CGMapGeneric*) FMap)->*side)(DART))
30 #define TURN(DART) ((((CGMapGeneric*) FMap)->*turn)(DART))
31 #define SUCC(DART) ((((CGMapGeneric*) FMap)->*succ)(DART))
32 //******************************************************************************
33 bool CMeshGeneric::isTopoEdge(CDart* ADart, CDart* AModel)
34 {
35  assert(ADart!=NULL);
36  return isTopoEdge1Meshed(ADart, 1, AModel);
37 }
38 //******************************************************************************
39 bool CMeshGeneric::isTopoEdge1Meshed(CDart* ADart, int ASx, CDart* AModel)
40 {
41  assert(ADart!=NULL);
42 
43  int n = 0;
44 
45  for (CDynamicCoverage01 cov(FMap, ADart); n<ASx && cov.cont(); ++cov)
46  {
47  if (FMap->isFree0(*cov))
48  return false;
49 
50  if (AModel!=NULL)
51  {
52  CDynamicCoverage23 covDart (FMap, *cov );
53  CDynamicCoverage23 covModel(FMap, AModel);
54 
55  while (covDart.cont() && covModel.cont() &&
56  covDart.prevOperationType()==covModel.prevOperationType())
57  {
58  ++covDart;
59  ++covModel;
60  }
61 
62  if (covDart.cont() || covModel.cont())
63  return false;
64  }
65 
66  ++cov;
67  ++n;
68 
69  if (n<ASx && FMap->isFree1(*cov))
70  return false;
71  }
72 
73  return true;
74 }
75 //******************************************************************************
76 bool CMeshGeneric::isTopoEdgeIMeshed(int ADim, CDart* ADart, int AS,
77  CDart* AModel)
78 {
79  assert(ADim>=0 && ADim<=1);
80  assert(ADart!=NULL);
81  assert(AS>0);
82 
83  if (ADim==1)
84  return isTopoEdge1Meshed(ADart, AS, AModel);
85 
86  return isTopoEdge(ADart, AModel);
87 }
88 //******************************************************************************
89 bool CMeshGeneric::isTopoSquare(CDart* ADart, bool ACheck3Sews, bool A3Sewed)
90 {
91  assert(ADart!=NULL);
92  return isTopoSquare1Meshed(ADart, 1,1, ACheck3Sews, A3Sewed);
93 }
94 //******************************************************************************
95 bool CMeshGeneric::isTopoSquare1Meshed(CDart* ADart, int ASx, int ASy,
96  bool ACheck3Sews, bool A3Sewed)
97 {
98  assert(ADart!=NULL);
99  assert(ASx>0);
100  assert(ASy>0);
101 
102  if (ACheck3Sews && A3Sewed==FMap->isFree3(ADart))
103  return false;
104 
105  int nbDarts = 0;
106  int nbToObtain = 4*(ASx+ASy);
107 
108  for (CDynamicCoverage01 cov(FMap, ADart); cov.cont(); ++cov)
109  {
110  if (FMap->isFree0(*cov) || FMap->isFree1(*cov))
111  return false;
112 
113  if (++nbDarts > nbToObtain)
114  return false;
115  }
116 
117  return nbDarts == nbToObtain;
118 }
119 //******************************************************************************
120 bool CMeshGeneric::isTopoSquare2Meshed(CDart* ADart, int ASx, int ASy,
121  bool ACheck3Sews, bool A3Sewed)
122 {
123  assert(ADart!=NULL);
124  assert(ASx>0);
125  assert(ASy>0);
126 
127  return isTopoSquareIMeshed(2, ADart, ASx,ASy, ACheck3Sews, A3Sewed);
128 }
129 //******************************************************************************
130 bool CMeshGeneric::isTopoSquare3Meshed(CDart* ADart, int ASx, int ASy,
131  bool ACheck3Sews, bool A3Sewed)
132 {
133  assert(ADart!=NULL);
134  assert(ASx>0);
135  assert(ASy>0);
136 
137  return isTopoSquareIMeshed(3, ADart, ASx,ASy, ACheck3Sews, A3Sewed);
138 }
139 //******************************************************************************
140 bool CMeshGeneric::isTopoSquareIMeshed(int ADim, CDart* ADart, int ASx, int ASy,
141  bool ACheck3Sews, bool A3Sewed)
142 {
143  assert(ADim>=0 && ADim<=3);
144  assert(ADart!=NULL);
145  assert(ASx>0);
146  assert(ASy>0);
147 
148  if (ADim==0)
149  return isTopoSquare(ADart, ACheck3Sews, A3Sewed);
150 
151  if (ADim==1)
152  return isTopoSquare1Meshed(ADart, ASx, ASy, ACheck3Sews, A3Sewed);
153 
154  // Cas où ADim==2 ou 3:
155 
156  CDart* (CGMapGeneric::* succ) (CDart*) const
157  = ADim==2 ? & CGMapGeneric::alpha0121 : & CGMapGeneric::alpha012321;
158 
159  CDart* (CGMapGeneric::* side) (CDart*) const
160  = ADim==2 ? & CGMapGeneric::alpha01 : & CGMapGeneric::alpha012;
161 
162  CDart* (CGMapGeneric::* turn) (CDart*) const
163  = ADim==2 ? & CGMapGeneric::alpha12 : & CGMapGeneric::alpha1232;
164 
165  CDart* currentX = ADart;
166 
167  for (int i=0; i<ASx; ++i)
168  {
169  CDart* currentY = FMap->alpha1(currentX);
170 
171  for (int j=0; j<ASy; ++j)
172  {
173  if (!isTopoSquare(currentY, ACheck3Sews, A3Sewed))
174  return false;
175 
176  if (i<ASx-1)
177  if (FMap->isFree(SIDE(FMap->alpha1(currentY)), ADim))
178  return false;
179 
180  if (j<ASy-1)
181  if (FMap->isFree(SIDE( currentY ), ADim))
182  return false;
183 
184  if (i>0 && j>0)
185  {
186  CDart* tmp = currentY;
187 
188  for (int k=0; k<4; ++k)
189  {
190  tmp = TURN(tmp);
191 
192  if ((k!=3 && tmp==currentY) || (k==3 && tmp!=currentY))
193  return false;
194  }
195  }
196 
197  if (j<ASy-1)
198  currentY = SUCC(currentY);
199  }
200 
201  if (i<ASx-1)
202  currentX = SUCC(currentX);
203  }
204 
205  return true;
206 }
207 //******************************************************************************
208 bool CMeshGeneric::isFreeTopoSquareIMeshed(int ADim, CDart* ADart,
209  int ASx, int ASy,
210  int AMarkNumberNotX1,
211  int AMarkNumberNotX2,
212  int AMarkNumberNotY1,
213  int AMarkNumberNotY2,
214  int AReturnedDart,
215  CDart** AOppositeDart)
216 {
217  assert(ADim>=0 && ADim<=2);
218  assert(ADart!=NULL);
219  assert(ASx>0);
220  assert(ASy>0);
221  assert(isTopoSquareIMeshed(ADim, ADart, ASx,ASy));
222  assert(AMarkNumberNotX1>0);
223  assert(AMarkNumberNotY1>0);
224  assert(AReturnedDart>=1 && AReturnedDart<=3);
225 
226  if (ADim==0)
227  ASx = ASy = 1;
228 
229  CDart* (CGMapGeneric::* succ) (CDart*) const
230  = ADim<2 ? & CGMapGeneric::alpha01 : & CGMapGeneric::alpha0121;
231 
232  CDart* current = ADart;
233 
234  for (int round=0; round<2; ++round)
235  {
236  for (int i=0; i<ASx; ++i)
237  {
238  if (FMap->isMarked(current, AMarkNumberNotX1) ||
239  (AMarkNumberNotX2>=0 &&
240  FMap->isMarked(current, AMarkNumberNotX2)))
241  return false;
242 
243  if (FMap->isMarked(FMap->alpha0(current), AMarkNumberNotX1) ||
244  (AMarkNumberNotX2>=0 &&
245  FMap->isMarked(FMap->alpha0(current), AMarkNumberNotX2)))
246  return false;
247 
248  if (i<ASx-1)
249  current = SUCC(current);
250  }
251 
252  current = FMap->alpha0(current);
253 
254  if (AOppositeDart!=NULL)
255  {
256  if (round==0 && AReturnedDart==1)
257  * AOppositeDart = current;
258 
259  if (round==1 && AReturnedDart==2)
260  * AOppositeDart = current;
261  }
262 
263  current = FMap->alpha1(current);
264 
265  for (int j=0; j<ASy; ++j)
266  {
267  if (FMap->isMarked(current, AMarkNumberNotY1) ||
268  (AMarkNumberNotY2>=0 &&
269  FMap->isMarked(current, AMarkNumberNotY2)))
270  return false;
271 
272  if (FMap->isMarked(FMap->alpha0(current), AMarkNumberNotY1) ||
273  (AMarkNumberNotY2>=0 &&
274  FMap->isMarked(FMap->alpha0(current), AMarkNumberNotY2)))
275  return false;
276 
277  if (j<ASy-1)
278  current = SUCC(current);
279  }
280 
281  current = FMap->alpha01(current);
282 
283  if (AOppositeDart!=NULL)
284  {
285  if (round==0 && AReturnedDart==3)
286  * AOppositeDart = current;
287  }
288  }
289 
290  return true;
291 }
292 //******************************************************************************
294  CDart* ADart1, CDart* ADart2,
295  int AS)
296 {
297  assert(ADim==1 || ADim==2);
298  assert(ADart1!=NULL);
299  assert(ADart2!=NULL);
300 
301  CDart* (CGMapGeneric::* succ) (CDart*) const
302  = ADim==1 ? & CGMapGeneric::alpha01 : & CGMapGeneric::alpha0121;
303 
304  CDart* current1 = ADart1;
305  CDart* current2 = ADart2;
306 
307  for (int i=0; i<AS; ++i)
308  {
309  if (FMap->alpha2(current1)!=current2)
310  return NULL;
311 
312  if (i<AS-1)
313  {
314  current1 = SUCC(current1);
315  current2 = SUCC(current2);
316  }
317  }
318 
319  return FMap->alpha0(current1);
320 }
321 //******************************************************************************
322 bool CMeshGeneric::isTopoCube(CDart* ADart)
323 {
324  assert(ADart!=NULL);
325 
326  return isTopoCube1Meshed(ADart, 1,1,1);
327 }
328 //******************************************************************************
329 bool CMeshGeneric::isTopoCube1Meshed(CDart* ADart, int ASx, int ASy, int ASz)
330 {
331  assert(ADart!=NULL);
332  assert(ASx>0);
333  assert(ASy>0);
334  assert(ASz>0);
335 
336  return isTopoCubeIMeshed(1, ADart, ASx,ASy,ASz);
337 }
338 //******************************************************************************
339 bool CMeshGeneric::isTopoCube2Meshed(CDart* ADart, int ASx, int ASy, int ASz)
340 {
341  assert(ADart!=NULL);
342  assert(ASx>0);
343  assert(ASy>0);
344  assert(ASz>0);
345 
346  return isTopoCubeIMeshed(2, ADart, ASx,ASy,ASz);
347 }
348 //******************************************************************************
349 bool CMeshGeneric::isTopoCube3Meshed(CDart* ADart, int ASx, int ASy, int ASz)
350 {
351  assert(ADart!=NULL);
352  assert(ASx>0);
353  assert(ASy>0);
354  assert(ASz>0);
355 
356  CDart* currentX = ADart;
357 
358  for (int i=0; i<ASx; ++i)
359  {
360  CDart* currentY = FMap->alpha12(currentX);
361 
362  for (int j=0; j<ASy; ++j)
363  {
364  CDart* currentZ = FMap->alpha12(currentY);
365 
366  for (int k=0; k<ASz; ++k)
367  {
368  if (!isTopoCube(currentZ))
369  return false;
370 
371  if (k<ASz-1)
372  {
373  currentZ = FMap->alpha012(currentZ);
374 
375  if (FMap->isFree3(currentZ))
376  return false;
377 
378  currentZ = FMap->alpha321(currentZ);
379  }
380  }
381 
382  if (j<ASy-1)
383  {
384  currentY = FMap->alpha012(currentY);
385 
386  if (FMap->isFree3(currentY))
387  return false;
388 
389  currentY = FMap->alpha321(currentY);
390  }
391  }
392 
393  if (i<ASx-1)
394  {
395  currentX = FMap->alpha012(currentX);
396 
397  if (FMap->isFree3(currentX))
398  return false;
399 
400  currentX = FMap->alpha321(currentX);
401  }
402  }
403 
404  return true;
405 }
406 //******************************************************************************
408  CDart* ADart, int ASx, int ASy, int ASz)
409 {
410  assert(ADim>=0 && ADim<=3);
411  assert(ADart!=NULL);
412 
413  if (ADim==0) return isTopoCube(ADart);
414  if (ADim==3) return isTopoCube3Meshed(ADart, ASx,ASy,ASz);
415 
416  // Cas où ADim==1 ou 2:
417 
418  CDart* memo[4];
419  CDart* current = ADart;
420  int i;
421 
422  // Face du bas:
423  if (!isTopoSquareIMeshed(ADim, current, ASx, ASy))
424  return false;
425 
426  for (i=0; i<4; ++i)
427  {
428  memo[i] = current;
429 
430  int len = i%2 == 0 ? ASx : ASy;
431 
432  // Face latérale:
433  if (FMap->isFree2(current) ||
434  ! isTopoSquareIMeshed(ADim, FMap->alpha2(current), len, ASz))
435  return false;
436 
437  // Coutures bas/latérale:
438  current = isTopoEdgeOfCubeIMeshed(ADim, current,
439  FMap->alpha2(current), len);
440 
441  if (current==NULL)
442  return false;
443 
444  current = FMap->alpha1(current);
445  }
446 
447  // On vérifie que les 4 coins du bas sont bien de degré 3:
448  for (i=0; i<4; ++i)
449  if (FMap->degree(memo[i], 0, 3) != 3)
450  return false;
451 
452  // Coutures d'arêtes verticales:
453  for (i=0; i<4; ++i)
454  {
455  memo[i] = FMap->alpha21(memo[i]);
456 
457  if (FMap->isFree2(memo[i]))
458  return false;
459 
460  memo[i] = isTopoEdgeOfCubeIMeshed(ADim, memo[i],
461  FMap->alpha2(memo[i]), ASz);
462 
463  if (memo[i]==NULL || FMap->isFree2(FMap->alpha1(memo[i])))
464  return false;
465 
466  memo[i] = FMap->alpha12(memo[i]);
467  }
468 
469  // Face du haut:
470  if (! isTopoSquareIMeshed(ADim, memo[0], ASx, ASy))
471  return false;
472 
473  // On vérifie que les 4 coins du haut sont bien de degré 3:
474  for (i=0; i<4; ++i)
475  if (FMap->degree(memo[i], 0, 3) != 3)
476  return false;
477 
478  // Coutures haut/latérale:
479  for (i=0; i<4; ++i)
480  {
481  int len = i%2 == 0 ? ASx : ASy;
482 
483  if (isTopoEdgeOfCubeIMeshed(ADim, memo[i],
484  FMap->alpha2(memo[i]), len) == NULL)
485  return false;
486  }
487 
488  return true;
489 }
490 //******************************************************************************
491 bool CMeshGeneric::isFreeTopoCubeIMeshed(int ADim, CDart* ADart,
492  int ASx, int ASy, int ASz,
493  int AMarkNumberNotX1,
494  int AMarkNumberNotX2,
495  int AMarkNumberNotY1,
496  int AMarkNumberNotY2,
497  int AMarkNumberNotZ1,
498  int AMarkNumberNotZ2)
499 {
500  assert(ADim>=0 && ADim<=3);
501  assert(ADart!=NULL);
502  assert(ASx>0);
503  assert(ASy>0);
504  assert(ASz>0);
505  assert(isTopoCubeIMeshed(ADim, ADart, ASx,ASy,ASz));
506  assert(AMarkNumberNotX1>0);
507  assert(AMarkNumberNotY1>0);
508  assert(AMarkNumberNotZ1>0);
509 
510  if (ADim==0)
511  ASx = ASy = ASz = 1;
512 
513  int s[3] = { ASx, ASy, ASz };
514  int m[3][2] =
515  {
516  { AMarkNumberNotX1, AMarkNumberNotX2 },
517  { AMarkNumberNotY1, AMarkNumberNotY2 },
518  { AMarkNumberNotZ1, AMarkNumberNotZ2 },
519  };
520 
521  CDart* current = ADart;
522 
523  for (int dim=0; dim<3; ++dim)
524  {
525  CDart* next;
526 
527  if (! isFreeTopoSquareIMeshed(ADim, current, s[dim], s[(dim+1)%3],
528  m[dim][0], m[dim][1],
529  m[(dim+1)%3][0], m[(dim+1)%3][1],
530  3, &next))
531  return false;
532 
533  if (! isFreeTopoSquareIMeshed(ADim, FMap->alpha12(next),
534  s[(dim+1)%3], s[(dim+2)%3],
535  m[(dim+1)%3][0], m[(dim+1)%3][1],
536  m[(dim+2)%3][0], m[(dim+2)%3][1]))
537  return false;
538 
539  current = FMap->alpha12(current);
540  }
541 
542  return true;
543 }
544 //******************************************************************************