Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmg-primitive-mesh.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 using namespace GMap3d;
27 //******************************************************************************
29  CDart * AMesh1Corners[2],
30  CDart * ADart)
31 {
32  /* Le maillage créé est un faisceau.
33  * Ce faiseau est composé de m brins "au-dessus" de AExtremity1 et
34  * n brins "au-dessous" (voir schéma).
35  *
36  * Le brin du haut et celui du bas sont éventuellement 3-cousus (le faisceau
37  * est alors fermé).
38  *
39  * Ici, m=2 et n=4.
40  *
41  * -----------------------------
42  * | 3
43  * -----------------------------
44  * | 2
45  * ============================= AExtremity1
46  * | 3
47  * -----------------------------
48  * | 2
49  * -----------------------------
50  * | 3
51  * -----------------------------
52  * | 2
53  * -----------------------------
54  *
55  * Remarque: On peut s'appuyer sur la méthode 'insertVertex', mais le maillage
56  * est plus rapide si on crée tous les brins et si on fait toutes les coutures
57  * "à la main".
58  * Or 'createTopoMesh1' est une méthode de base qui est utilisée par les
59  * méthodes de maillage de dimension supérieure.
60  * Sa complexité en temps doit donc être optimisée.
61  */
62 
63  assert(ASx>=0);
64  assert(AMesh1Corners!=NULL);
65 
66  // On détermine d'abord m,n et closed (booléen indiquant si le faisceau est
67  // fermé):
68  int m = 0, n = 0;
69  bool closed;
70 
71  if (ADart==NULL)
72  closed = false;
73  else
74  {
75  CDart * last = NULL;
76  bool jumped = false;
77 
78  for (CDynamicCoverage23 cov(this, ADart); cov.cont(); ++cov)
79  {
80  last = *cov;
81 
82  switch (cov.prevOperationType())
83  {
84  case OP_ALPHAI:
85  case OP_ALPHAJ:
86  if (jumped) ++n; else ++m;
87  break;
88 
89  case OP_JUMP:
90  jumped = true;
91  ++n;
92  break;
93 
94  case OP_NONE:
95  break;
96  }
97  }
98 
99  closed = !isFree2(last) && !isFree3(last);
100  }
101 
102  // Création du maillage:
103  int i, j;
104  int perimeter = m + n + 1;
105  int length = ASx==0 ? 1 : 2*ASx;
106 
107  CDart *** beam = new CDart ** [length];
108 
109  for (j=0; j<length; ++j)
110  {
111  beam[j] = new CDart * [perimeter];
112 
113  for (i=0; i<perimeter; ++i)
114  beam[j][i] = addMapDart();
115  }
116 
117  // 0 et 1-coutures:
118  for (i=0; i<perimeter; ++i)
119  for (j=1; j<length; j+=2)
120  {
121  linkAlpha0(beam[j-1][i], beam[j][i]);
122 
123  if (j<length-1)
124  linkAlpha1(beam[j][i], beam[j+1][i]);
125  }
126 
127  // 2 et 3-coutures:
128  bool alpha2;
129 
130  // Au-dessus de AExtremity1:
131  for (i=m, alpha2=true; i>0; --i, alpha2=!alpha2)
132  if (alpha2)
133  for (j=0; j<length; ++j)
134  linkAlpha2(beam[j][i], beam[j][i-1]);
135  else
136  for (j=0; j<length; ++j)
137  linkAlpha3(beam[j][i], beam[j][i-1]);
138 
139  // Au-dessous de AExtremity1:
140  for (i=m, alpha2=false; i<perimeter-1; ++i, alpha2=!alpha2)
141  if (alpha2)
142  for (j=0; j<length; ++j)
143  linkAlpha2(beam[j][i], beam[j][i+1]);
144  else
145  for (j=0; j<length; ++j)
146  linkAlpha3(beam[j][i], beam[j][i+1]);
147 
148  // Fermeture:
149  if (closed)
150  for (j=0; j<length; ++j)
151  linkAlpha3(beam[j][0], beam[j][perimeter-1]);
152 
153  // Paramètres en sortie:
154  AMesh1Corners[0] = beam[ 0][m];
155  AMesh1Corners[1] = beam[length-1][m];
156 
157  // Libération de la mémoire occupée par le tableau:
158  for (j=0; j<length; ++j)
159  delete [] beam[j];
160 
161  delete [] beam;
162 }
163 //******************************************************************************
165 {
166  assert(ASx>=0);
167 
168  CDart * extremities[2];
169 
170  createTopoMesh1(ASx, extremities, ADart);
171 
172  return extremities[0];
173 }
174 //******************************************************************************
175 void CGMapGeneric::createTopoMesh2(int ASx, int ASy,
176  CDart * AMesh2Corners[2][2],
177  bool A3Sewed)
178 {
179  assert(ASx>0);
180  assert(ASy>0);
181  assert(AMesh2Corners!=NULL);
182 
183  /* Numérotation des brins de chaque face:
184  *
185  * 5 4
186  * +--- ---+
187  * | |
188  * 6 | | 3
189  *
190  * 7 | | 2
191  * | |
192  * +--- ---+
193  * 0 1
194  */
195 
196  CDart **** D = new CDart *** [ASx];
197  int x,y,n;
198 
199  // Première couche:
200  for (x=0; x<ASx; ++x)
201  {
202  D[x] = new CDart ** [ASy];
203 
204  for (y=0; y<ASy; ++y)
205  {
206  D[x][y] = new CDart * [8];
207 
208  for (n=0; n<8; ++n)
209  D[x][y][n] = addMapDart();
210  }
211  }
212 
213  for (x=0; x<ASx; ++x)
214  for (y=0; y<ASy; ++y)
215  {
216  linkAlpha0( D[x][y][0] , D[x][y][1] );
217  linkAlpha0( D[x][y][2] , D[x][y][3] );
218  linkAlpha0( D[x][y][4] , D[x][y][5] );
219  linkAlpha0( D[x][y][6] , D[x][y][7] );
220 
221  linkAlpha1( D[x][y][1] , D[x][y][2] );
222  linkAlpha1( D[x][y][3] , D[x][y][4] );
223  linkAlpha1( D[x][y][5] , D[x][y][6] );
224  linkAlpha1( D[x][y][7] , D[x][y][0] );
225 
226  if (x>0) topoSew2( D[x][y][7] , D[x-1][y ][2] );
227  if (y>0) topoSew2( D[x][y][0] , D[x ][y-1][5] );
228  }
229 
230  // Deuxième couche:
231  if (A3Sewed)
232  {
233  for (x=0; x<ASx; ++x)
234  for (y=0; y<ASy; ++y)
235  for (n=0; n<8; ++n)
236  linkAlpha3(D[x][y][n], addMapDart());
237 
238  for (x=0; x<ASx; ++x)
239  for (y=0; y<ASy; ++y)
240  {
241  linkAlpha0( alpha3( D[x][y][0] ) , alpha3( D[x][y][1] ) );
242  linkAlpha0( alpha3( D[x][y][2] ) , alpha3( D[x][y][3] ) );
243  linkAlpha0( alpha3( D[x][y][4] ) , alpha3( D[x][y][5] ) );
244  linkAlpha0( alpha3( D[x][y][6] ) , alpha3( D[x][y][7] ) );
245 
246  linkAlpha1( alpha3( D[x][y][1] ) , alpha3( D[x][y][2] ) );
247  linkAlpha1( alpha3( D[x][y][3] ) , alpha3( D[x][y][4] ) );
248  linkAlpha1( alpha3( D[x][y][5] ) , alpha3( D[x][y][6] ) );
249  linkAlpha1( alpha3( D[x][y][7] ) , alpha3( D[x][y][0] ) );
250 
251  if (x>0) topoSew2( alpha3( D[x ][y ][7] ) ,
252  alpha3( D[x-1][y ][2] ) );
253  if (y>0) topoSew2( alpha3( D[x ][y ][0] ) ,
254  alpha3( D[x ][y-1][5] ) );
255  }
256  }
257 
258  // Paramètres en sortie:
259  AMesh2Corners[0][0] = D[ 0 ][ 0 ][0];
260  AMesh2Corners[1][0] = D[ASx-1][ 0 ][1];
261  AMesh2Corners[0][1] = D[ 0 ][ASy-1][5];
262  AMesh2Corners[1][1] = D[ASx-1][ASy-1][4];
263 
264  // Libération de la mémoire occupée par le tableau:
265  for (x=0; x<ASx; ++x)
266  {
267  for (y=0; y<ASy; ++y)
268  delete [] D[x][y];
269 
270  delete [] D[x];
271  }
272 
273  delete [] D;
274 }
275 //******************************************************************************
276 CDart * CGMapGeneric::createTopoMesh2(int ASx, int ASy, bool A3Sewed)
277 {
278  assert(ASx>0);
279  assert(ASy>0);
280 
281  CDart * mesh2Corners[2][2];
282 
283  createTopoMesh2(ASx,ASy, mesh2Corners, A3Sewed);
284 
285  return mesh2Corners[0][0];
286 }
287 //******************************************************************************
288 void CGMapGeneric::createTopoMesh3(int ASx, int ASy, int ASz,
289  CDart * AMesh3Corners[2][2][2])
290 {
291  assert(ASx>0);
292  assert(ASy>0);
293  assert(ASz>0);
294  assert(AMesh3Corners!=NULL);
295 
296  /* Numérotation des brins de chaque cube:
297  *
298  * +---- ----+ +---- ----+
299  * + | 29 28 | / 45 44 / +
300  * /| |30 27| /46 43/ /|
301  * 4/ |3 ARRIERE HAUT 12/ |11
302  * |31 26| /47 42/
303  * 5/ |2 | 24 25 | / 40 41 / 13/ |10
304  * / | +---- ----+ +---- ----+ / |
305  * + G. + + D. +
306  * | / +---- ----+ +---- ----+ | /
307  * 6| /1 / 37 36 / | 21 20 | 14| /9
308  * /38 35/ |22 19|
309  * 7| /0 BAS AVANT 15| /8
310  * |/ /39 34/ |23 18| |/
311  * + / 32 33 / | 16 17 | +
312  * +---- ----+ +---- ----+
313  */
314 
315  CDart ***** D = new CDart **** [ASx];
316  int x, y, z, n;
317 
318  for (x=0; x<ASx; ++x)
319  {
320  D[x] = new CDart *** [ASy];
321 
322  for (y=0; y<ASy; ++y)
323  {
324  D[x][y] = new CDart ** [ASz];
325 
326  for (z=0; z<ASz; ++z)
327  {
328  D[x][y][z] = new CDart * [48];
329 
330  for (n=0; n<48; ++n)
331  D[x][y][z][n] = addMapDart();
332  }
333  }
334  }
335 
336  for (x=0; x<ASx; ++x)
337  for (y=0; y<ASy; ++y)
338  for (z=0; z<ASz; ++z)
339  {
340  linkAlpha0( D[x][y][z][ 0], D[x][y][z][ 1] );
341  linkAlpha0( D[x][y][z][ 2], D[x][y][z][ 3] );
342  linkAlpha0( D[x][y][z][ 4], D[x][y][z][ 5] );
343  linkAlpha0( D[x][y][z][ 6], D[x][y][z][ 7] );
344  linkAlpha0( D[x][y][z][ 8], D[x][y][z][ 9] );
345  linkAlpha0( D[x][y][z][10], D[x][y][z][11] );
346  linkAlpha0( D[x][y][z][12], D[x][y][z][13] );
347  linkAlpha0( D[x][y][z][14], D[x][y][z][15] );
348  linkAlpha0( D[x][y][z][16], D[x][y][z][17] );
349  linkAlpha0( D[x][y][z][18], D[x][y][z][19] );
350  linkAlpha0( D[x][y][z][20], D[x][y][z][21] );
351  linkAlpha0( D[x][y][z][22], D[x][y][z][23] );
352  linkAlpha0( D[x][y][z][24], D[x][y][z][25] );
353  linkAlpha0( D[x][y][z][26], D[x][y][z][27] );
354  linkAlpha0( D[x][y][z][28], D[x][y][z][29] );
355  linkAlpha0( D[x][y][z][30], D[x][y][z][31] );
356  linkAlpha0( D[x][y][z][32], D[x][y][z][33] );
357  linkAlpha0( D[x][y][z][34], D[x][y][z][35] );
358  linkAlpha0( D[x][y][z][36], D[x][y][z][37] );
359  linkAlpha0( D[x][y][z][38], D[x][y][z][39] );
360  linkAlpha0( D[x][y][z][40], D[x][y][z][41] );
361  linkAlpha0( D[x][y][z][42], D[x][y][z][43] );
362  linkAlpha0( D[x][y][z][44], D[x][y][z][45] );
363  linkAlpha0( D[x][y][z][46], D[x][y][z][47] );
364 
365  linkAlpha1( D[x][y][z][ 0], D[x][y][z][ 7] );
366  linkAlpha1( D[x][y][z][ 2], D[x][y][z][ 1] );
367  linkAlpha1( D[x][y][z][ 4], D[x][y][z][ 3] );
368  linkAlpha1( D[x][y][z][ 6], D[x][y][z][ 5] );
369  linkAlpha1( D[x][y][z][ 8], D[x][y][z][15] );
370  linkAlpha1( D[x][y][z][10], D[x][y][z][ 9] );
371  linkAlpha1( D[x][y][z][12], D[x][y][z][11] );
372  linkAlpha1( D[x][y][z][14], D[x][y][z][13] );
373  linkAlpha1( D[x][y][z][16], D[x][y][z][23] );
374  linkAlpha1( D[x][y][z][18], D[x][y][z][17] );
375  linkAlpha1( D[x][y][z][20], D[x][y][z][19] );
376  linkAlpha1( D[x][y][z][22], D[x][y][z][21] );
377  linkAlpha1( D[x][y][z][24], D[x][y][z][31] );
378  linkAlpha1( D[x][y][z][26], D[x][y][z][25] );
379  linkAlpha1( D[x][y][z][28], D[x][y][z][27] );
380  linkAlpha1( D[x][y][z][30], D[x][y][z][29] );
381  linkAlpha1( D[x][y][z][32], D[x][y][z][39] );
382  linkAlpha1( D[x][y][z][34], D[x][y][z][33] );
383  linkAlpha1( D[x][y][z][36], D[x][y][z][35] );
384  linkAlpha1( D[x][y][z][38], D[x][y][z][37] );
385  linkAlpha1( D[x][y][z][40], D[x][y][z][47] );
386  linkAlpha1( D[x][y][z][42], D[x][y][z][41] );
387  linkAlpha1( D[x][y][z][44], D[x][y][z][43] );
388  linkAlpha1( D[x][y][z][46], D[x][y][z][45] );
389 
390  linkAlpha2( D[x][y][z][ 0], D[x][y][z][39] );
391  linkAlpha2( D[x][y][z][ 1], D[x][y][z][38] );
392  linkAlpha2( D[x][y][z][ 2], D[x][y][z][31] );
393  linkAlpha2( D[x][y][z][ 3], D[x][y][z][30] );
394  linkAlpha2( D[x][y][z][ 4], D[x][y][z][46] );
395  linkAlpha2( D[x][y][z][ 5], D[x][y][z][47] );
396  linkAlpha2( D[x][y][z][ 6], D[x][y][z][22] );
397  linkAlpha2( D[x][y][z][ 7], D[x][y][z][23] );
398  linkAlpha2( D[x][y][z][ 8], D[x][y][z][34] );
399  linkAlpha2( D[x][y][z][ 9], D[x][y][z][35] );
400  linkAlpha2( D[x][y][z][10], D[x][y][z][26] );
401  linkAlpha2( D[x][y][z][11], D[x][y][z][27] );
402  linkAlpha2( D[x][y][z][12], D[x][y][z][43] );
403  linkAlpha2( D[x][y][z][13], D[x][y][z][42] );
404  linkAlpha2( D[x][y][z][14], D[x][y][z][19] );
405  linkAlpha2( D[x][y][z][15], D[x][y][z][18] );
406  linkAlpha2( D[x][y][z][16], D[x][y][z][32] );
407  linkAlpha2( D[x][y][z][17], D[x][y][z][33] );
408  linkAlpha2( D[x][y][z][20], D[x][y][z][41] );
409  linkAlpha2( D[x][y][z][21], D[x][y][z][40] );
410  linkAlpha2( D[x][y][z][24], D[x][y][z][37] );
411  linkAlpha2( D[x][y][z][25], D[x][y][z][36] );
412  linkAlpha2( D[x][y][z][28], D[x][y][z][44] );
413  linkAlpha2( D[x][y][z][29], D[x][y][z][45] );
414 
415  if (x>0) topoSew3( D[x][y][z][ 0] , D[x-1][y ][z ][ 8] );
416  if (y>0) topoSew3( D[x][y][z][16] , D[x ][y-1][z ][24] );
417  if (z>0) topoSew3( D[x][y][z][32] , D[x ][y ][z-1][40] );
418  }
419 
420  AMesh3Corners[0][0][0] = D[ 0 ][ 0 ][ 0 ][32];
421  AMesh3Corners[1][0][0] = D[ASx-1][ 0 ][ 0 ][33];
422  AMesh3Corners[0][1][0] = D[ 0 ][ASy-1][ 0 ][37];
423  AMesh3Corners[1][1][0] = D[ASx-1][ASy-1][ 0 ][36];
424  AMesh3Corners[0][0][1] = D[ 0 ][ 0 ][ASz-1][40];
425  AMesh3Corners[1][0][1] = D[ASx-1][ 0 ][ASz-1][41];
426  AMesh3Corners[0][1][1] = D[ 0 ][ASy-1][ASz-1][45];
427  AMesh3Corners[1][1][1] = D[ASx-1][ASy-1][ASz-1][44];
428 
429  // Libération du tableau:
430  for (x=0; x<ASx; ++x)
431  {
432  for (y=0; y<ASy; ++y)
433  {
434  for (z=0; z<ASz; ++z)
435  delete [] D[x][y][z];
436 
437  delete [] D[x][y];
438  }
439 
440  delete [] D[x];
441  }
442 
443  delete [] D;
444 }
445 //******************************************************************************
446 CDart * CGMapGeneric::createTopoMesh3(int ASx, int ASy, int ASz)
447 {
448  assert(ASx>0);
449  assert(ASy>0);
450  assert(ASz>0);
451 
452  CDart * mesh3Corners[2][2][2];
453 
454  createTopoMesh3(ASx,ASy,ASz, mesh3Corners);
455 
456  return mesh3Corners[0][0][0];
457 }
458 //******************************************************************************