Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmv-burstview.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-vertex.hh"
26 using namespace GMap3d;
27 //******************************************************************************
29 {
30  assert( FIRST_BURST_METHOD<=AMethod && AMethod<LAST_BURST_METHOD );
31  FBurstMethod = AMethod;
32 }
33 //------------------------------------------------------------------------------
35 { return FBurstMethod; }
36 //******************************************************************************
38 {
39  int selected = getNewMark();
40  negateMaskMark(selected);
41  updateMarkedBurstDarts(selected, false);
42  negateMaskMark(selected);
43  freeMark(selected);
44 }
45 //******************************************************************************
47  bool AUpdateIncidentVolumes)
48 {
49  switch (FBurstMethod)
50  {
51  case BURST_METHOD_SCALE:
52  updateMarkedDartsMethodScale(AMarkNumber, AUpdateIncidentVolumes);
53  break;
54  case BURST_METHOD_SHIFT:
55  updateMarkedDartsMethodShift(AMarkNumber, AUpdateIncidentVolumes);
56  break;
57  default: assert(false);
58  }
59 }
60 //******************************************************************************
61 #define GET_VERTEX(DART,INDEX) (getDirectInfoAsAttributeVertex(DART, INDEX))
62 //******************************************************************************
64  bool AUpdateIncidentVolumes)
65 {
66  if (AUpdateIncidentVolumes)
67  {
68  int selected = getNewMark();
69  markIncidentCells(ORBIT_VERTEX, AMarkNumber, selected);
71  updateMarkedBurstDarts(selected, false);
72  unmarkAll(selected);
73  freeMark(selected);
74  return;
75  }
76 
77  TCoordinate k1 = getBurstCoef(1);
78  TCoordinate k2 = getBurstCoef(2);
79  TCoordinate k3 = getBurstCoef(3);
80 
81  int directIndex = getNewDirectInfo();
82 
83  int markV = getNewMark(); // volume mark
84 
85  int mark3 = getNewMark(); // volume mark
86  int mark2 = getNewMark(); // face mark
87  int mark1 = getNewMark(); // edge mark
88 
90 
91  // CARTE ENTIÈRE:
92  for (CDynamicCoverageAll all(this); all.cont(); ++all)
93  if (!isMarked(*all, mark3))
94  {
95  if (!isMarked(*all, AMarkNumber))
96  {
97  setMark(*all, mark3);
98  setMark(*all, mark2);
99  setMark(*all, mark1);
100  }
101  else
102  {
103  // VOLUME:
104  CVertex bary3 =
105  basicBarycenter(*all, ORBIT_012, markV, mark3, directIndex);
106 
107  negateMaskMark(markV);
108 
109  for (CBasicDynamicCoverage012 vol(this, *all, markV);
110  vol.cont(); ++vol)
111  if (!isMarked(*vol, mark2))
112  {
113  if (!isMarked(*vol, AMarkNumber))
114  {
115  setMark(*vol, mark2);
116  setMark(*vol, mark1);
117  }
118  else
119  {
120  // FACE:
121  CVertex bary2 =
122  barycenter(*vol, ORBIT_01, directIndex);
123 
124  markOrbit(*vol, ORBIT_01, mark2);
125 
126  CVertex delta2 = bary2 - bary3;
127 
128  for (CDynamicCoverage01 fac(this, *vol);
129  fac.cont(); ++fac)
130  if (!isMarked(*fac, mark1))
131  {
132  if (!isMarked(*fac, AMarkNumber))
133  setMark(*fac, mark1);
134  else
135  {
136  // ARÊTE:
137  CVertex bary1 =
138  barycenter(*fac, ORBIT_0, directIndex);
139 
140  markOrbit(*fac, ORBIT_0, mark1);
141 
142  CVertex delta1 = bary1 - bary2;
143 
144  CVertex & b1 = getBurstVertex( *fac );
145  CVertex & b2 = getBurstVertex(alpha0(*fac));
146 
147  CAttributeVertex & v1 =
148  * GET_VERTEX( *fac , directIndex);
149 
150  CAttributeVertex & v2 =
151  * GET_VERTEX(alpha0(*fac), directIndex);
152 
153  /* Les lignes suivantes sont équivalentes à:
154  *
155  * b1 = bary3 +
156  * k3*(delta2 +
157  * k2*(delta1 +
158  * k1*(v1-bary1)));
159  *
160  * b2 = bary3 +
161  * k3*(delta2 +
162  * k2*(delta1 +
163  * k1*(v2-bary1)));
164  *
165  * Pour minimiser le nombre d'allocations et de
166  * désallocations, elles sont remplacées par:
167  */
168 
169  b1.setX(bary3.getX() +
170  k3*(delta2.getX() +
171  k2*(delta1.getX() +
172  k1*(v1.getX()-bary1.getX()))));
173 
174  b1.setY(bary3.getY() +
175  k3*(delta2.getY() +
176  k2*(delta1.getY() +
177  k1*(v1.getY()-bary1.getY()))));
178 
179  b1.setZ(bary3.getZ() +
180  k3*(delta2.getZ() +
181  k2*(delta1.getZ() +
182  k1*(v1.getZ()-bary1.getZ()))));
183 
184  b2.setX(bary3.getX() +
185  k3*(delta2.getX() +
186  k2*(delta1.getX() +
187  k1*(v2.getX()-bary1.getX()))));
188 
189  b2.setY(bary3.getY() +
190  k3*(delta2.getY() +
191  k2*(delta1.getY() +
192  k1*(v2.getY()-bary1.getY()))));
193 
194  b2.setZ(bary3.getZ() +
195  k3*(delta2.getZ() +
196  k2*(delta1.getZ() +
197  k1*(v2.getZ()-bary1.getZ()))));
198  }
199  }
200  }
201  }
202 
203  negateMaskMark(markV);
204  }
205  }
206 
207  freeMark(markV);
208  negateMaskMark(mark3); freeMark(mark3);
209  negateMaskMark(mark2); freeMark(mark2);
210  negateMaskMark(mark1); freeMark(mark1);
211 
212  freeDirectInfo(directIndex);
213 }
214 //******************************************************************************
216  bool AUpdateIncidentVolumes)
217 {
219  if (AUpdateIncidentVolumes)
220  {
221  int selected = getNewMark();
222  markIncidentCells(ORBIT_VERTEX, AMarkNumber, selected);
223  markIncidentCells(ORBIT_VOLUME, selected);
224  updateMarkedBurstDarts(selected, false);
225  unmarkAll(selected);
226  freeMark(selected);
227  return;
228  }
229 
230  int directIndex = getNewDirectInfo();
231 
232  int markV = getNewMark(); // volume mark
233 
234  int mark3 = getNewMark(); // volume mark
235  int mark2 = getNewMark(); // face mark
236  int marki = getNewMark(); // mark intersection
237 
239 
240  // CARTE ENTIÈRE:
241  for (CDynamicCoverageAll all(this); all.cont(); ++all)
242  if (!isMarked(*all, mark3))
243  {
244  if (!isMarked(*all, AMarkNumber))
245  {
246  setMark(*all, mark3);
247  setMark(*all, mark2);
248  }
249  else
250  {
251  // VOLUME:
252  CVertex bary3 =
253  basicBarycenter(*all, ORBIT_012, markV, mark3, directIndex);
254 
255  negateMaskMark(markV);
256 
257  for (CBasicDynamicCoverage012 vol(this, *all, markV);
258  vol.cont(); ++vol)
259  if (!isMarked(*vol, mark2))
260  {
261  if (!isMarked(*vol, AMarkNumber))
262  setMark(*vol, mark2);
263  else
264  // Traitement d'une face :
265  updateFaceMethodShift(mark2,marki,*vol, bary3, directIndex);
266  }
267 
268  negateMaskMark(markV);
269  }
270  }
271 
272  freeMark(markV);
273  negateMaskMark(mark3); freeMark(mark3);
274  negateMaskMark(mark2); freeMark(mark2);
275  freeMark(marki);
276  freeDirectInfo(directIndex);
277 }
278 //------------------------------------------------------------------------------
279 // A DEBUGGER !!!!!!!!!!!!!
280 void CGMapVertex::updateFaceMethodShift(int AMarkNumber, int AMarkI,
281  CDart* ADart, const CVertex& ABaryVol,
282  int ADirectIndex)
283 {
284  TCoordinate k1 = 1 - getBurstCoef(1);
285  TCoordinate k2 = 1 - getBurstCoef(2);
286  TCoordinate k3 = 1 - getBurstCoef(3);
287 
288  halfMarkOrbit(ADart, ORBIT_01, AMarkNumber);
289 
290  CVertex normalf = - faceNormalVector(ADart);
291 
292  CDynamicCoverage01 fac(this, ADart);
293 
294  for ( ; fac.cont(); ++fac)
295  if ( !isMarked(*fac, AMarkNumber) || isFree1(*fac) )
296  {
297  // Point associé au sommet :
298  CAttributeVertex& v = * GET_VERTEX(*fac, ADirectIndex);
299 
300  // Recherche de la première extrémité en sautant les arêtes de longueur nulle :
301  CDart* dartExt1 = alpha0(*fac);
302  CAttributeVertex& v1 = * GET_VERTEX(dartExt1, ADirectIndex);
303  if ( !isFree0(*fac) )
304  {
305  while( v1==v && dartExt1!=alpha1(*fac) &&
306  !isFree1(dartExt1) && !isFree0(alpha1(dartExt1)) )
307  {
308  // cout<<"Null edge case 1"<<endl;
309  dartExt1 = alpha10(dartExt1);
310  v1 = * GET_VERTEX(dartExt1, ADirectIndex);
311  }
312  }
313 
314  // Recherche de la deuxième extrémité en sautant les arêtes de longueur nulle :
315  CDart* dartExt2 = isFree1(*fac) ? *fac : alpha10(*fac);
316  CAttributeVertex& v2 = * GET_VERTEX(dartExt2, ADirectIndex);
317  while( v2==v && dartExt2!=*fac &&
318  !isFree1(dartExt2) && !isFree0(alpha1(dartExt2)) )
319  {
320  // cout<<"Null edge case 2"<<endl;
321  dartExt2 = alpha10(dartExt2);
322  v2 = * GET_VERTEX(dartExt2, ADirectIndex);
323  }
324 
325  // Calcul "normal" :
326 
327  CVertex vecteur1 = v - v1;
328  CVertex vecteur2 = v2 - v;
329 
330  CVertex n1 = vecteur1 * normalf; n1 *= k2 / n1.norm();
331  CVertex n2 = vecteur2 * normalf; n2 *= k2 / n2.norm();
332 
333  // Intersection entre les 2 droites :
334  CVertex intersection;
335  if ( (v==v1 && v==v2) || n1==-n2 ) // 2eme cas pour les arêtes parallèles et opposés
336  intersection = v;
337  else
338  if ( v==v1 || n1==n2 ) // 2eme cas pour les arêtes parallèles dans le même sens
339  intersection = v + n2;
340  else
341  if ( v==v2 )
342  {
343  if ( isMarked(*fac, AMarkNumber) )
344  intersection = (v - (vecteur1.normalized() * k2)) - n1;
345  else
346  intersection = (v - (vecteur1.normalized() * k2)) + n1;
347  }
348  else
349  intersection = CGeometry::getLinesIntersection(v + n1, v1 + n1 ,
350  v + n2, v2 + n2 );
351 
352  // Affectation des coordonnées éclatées.
353  dartExt1 = alpha0(dartExt1);
354  while ( dartExt1!=dartExt2 )
355  {
356  setBurstVertex( dartExt1, intersection );
357  setMark ( dartExt1, AMarkNumber );
358 
359  if ( !isFree1(dartExt1) )
360  {
361  setBurstVertex( alpha1(dartExt1), intersection );
362  setMark ( alpha1(dartExt1), AMarkNumber );
363  dartExt1 = alpha10(dartExt1);
364  }
365  else dartExt1 = dartExt2;
366  }
367  }
368 
369  return;
370 
371  unmarkOrbit(ADart, ORBIT_01, AMarkNumber);
372 
373  // Deuxième passe pour l'éclatement sur les arêtes (k1) et les volumes (k3)
374  for (fac.reinit(); fac.cont(); ++fac)
375  if (! isMarked(*fac, AMarkNumber))
376  {
377 
378  CVertex& b1 = getBurstVertex( *fac );
379  CVertex& b2 = getBurstVertex(alpha0(*fac));
380 
381  if ( b1!=b2 )
382  {
383  CVertex vedge = (b1 - b2).normalized();
384  // Point associé au sommet :
385  CVertex & v = * GET_VERTEX(*fac, ADirectIndex);
386  // Points associés aux sommets voisins :
387  CVertex & v1 = * GET_VERTEX(alpha0 (*fac), ADirectIndex);
388 
389  CVertex vecteur1 = (v - v1).normalized();
390 
391 
392  b1 -= vedge * k1;
393  b2 += vedge * k1;
394 
395  b1 += (ABaryVol - b1) * k3;
396  b2 += (ABaryVol - b2) * k3;
397 
398  // TCoordinate cosinus = vecteur1.dot(vedge);
399 
400  if ( ! vedge.isNull() && isNegative(vecteur1.dot(vedge)) )
401  {
402 // setMark(*fac ,AMarkI);
403 // setMark(alpha0(*fac),AMarkI);
404  }
405  }
406 
407  setMark( *fac , AMarkNumber);
408  setMark(alpha0(*fac), AMarkNumber);
409  }
410 
411  return;
412 
413  // Traitement des croisements
414  unmarkOrbit(ADart, ORBIT_01, AMarkNumber);
415 
416  for (fac.reinit(); fac.cont(); ++fac)
417  if ((isMarked(*fac,AMarkI )) && ( ! isMarked(*fac, AMarkNumber ) ))
418  {
419  CVertex& b1 = getBurstVertex( *fac );
420  //Cas ou il y a des intersections consecuitive
421  CVertex& b2 = getBurstVertex(alpha0(*fac));
422  if (b1 != b2)
423  {
424  CVertex vedge = (b1 - b2).normalized();
425 
426  // Point associé au sommet :
427  CVertex & v = * GET_VERTEX(*fac, ADirectIndex);
428  // Points associés aux sommets voisins :
429  CVertex & v1 = * GET_VERTEX(alpha0 (*fac),ADirectIndex);
430 
431  CVertex vecteur1 = (v - v1).normalized();
432 
433  b1 -= vedge * k1;
434  b2 += vedge * k1;
435 
436  // b1 += (ABaryVol - b1) * k3;
437  // b2 += (ABaryVol - b2) * k3;
438 
439  CVertex & b4 = getBurstVertex(alpha1 (*fac));
440  CVertex & b3 = getBurstVertex(alpha01(*fac));
441 
442  b1 = b2 = b3 = b4 = b1 + (b2 - b1) / 2;
443 
444  setMark(*fac , AMarkNumber);
445  setMark(alpha0(*fac) , AMarkNumber);
446 
447  CDart * dartb1 = alpha1(alpha0(*fac));
448 
449  while ( isMarked(dartb1, AMarkI))
450  {
451 
452  CVertex & b5 = getBurstVertex( dartb1 );
453  CVertex & b6 = getBurstVertex(alpha0(dartb1));
454  CVertex & b7 = getBurstVertex(alpha10(dartb1));
455  CVertex & b8 = getBurstVertex(alpha01(dartb1));
456 
457  b5 = b6 = b7 = b8 = b1;
458 
459  dartb1 = alpha1(alpha0(dartb1));
460 
461  setMark(dartb1 , AMarkNumber);
462  setMark(alpha0(dartb1) , AMarkNumber);
463  }
464  }
465  }
466 }
467 
468 //******************************************************************************
469 #undef GET_VERTEX
470 //******************************************************************************