VCG Library
flag.h
1 /****************************************************************************
2 * VCGLib o o *
3 * Visual and Computer Graphics Library o o *
4 * _ O _ *
5 * Copyright(C) 2004-2016 \/)\/ *
6 * Visual Computing Lab /\/| *
7 * ISTI - Italian National Research Council | *
8 * \ *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 #ifndef __VCG_TRI_UPDATE_FLAGS
24 #define __VCG_TRI_UPDATE_FLAGS
25 
26 namespace vcg {
27 namespace tri {
29 
31 
33 
38 template <class UpdateMeshType>
40 {
41 
42 public:
43  typedef UpdateMeshType MeshType;
44  typedef typename MeshType::ScalarType ScalarType;
45  typedef typename MeshType::VertexType VertexType;
46  typedef typename MeshType::VertexPointer VertexPointer;
47  typedef typename MeshType::VertexIterator VertexIterator;
48  typedef typename MeshType::EdgeType EdgeType;
49  typedef typename MeshType::EdgePointer EdgePointer;
50  typedef typename MeshType::EdgeIterator EdgeIterator;
51  typedef typename MeshType::FaceType FaceType;
52  typedef typename MeshType::FacePointer FacePointer;
53  typedef typename MeshType::FaceIterator FaceIterator;
54  typedef typename MeshType::TetraType TetraType;
55  typedef typename MeshType::TetraPointer TetraPointer;
56  typedef typename MeshType::TetraIterator TetraIterator;
57 
59 
60  static void Clear(MeshType &m)
61  {
62  if(HasPerVertexFlags(m) )
63  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
64  (*vi).Flags() = 0;
65  if(HasPerEdgeFlags(m) )
66  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
67  (*ei).Flags() = 0;
68  if(HasPerFaceFlags(m) )
69  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
70  (*fi).Flags() = 0;
71  if(HasPerTetraFlags(m) )
72  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
73  (*ti).Flags() = 0;
74  }
75 
76 
77  static void VertexClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
78  {
79  RequirePerVertexFlags(m);
80  int andMask = ~FlagMask;
81  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
82  if(!(*vi).IsD()) (*vi).Flags() &= andMask ;
83  }
84 
85  static void EdgeClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
86  {
87  RequirePerEdgeFlags(m);
88  int andMask = ~FlagMask;
89  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
90  if(!(*ei).IsD()) (*ei).Flags() &= andMask ;
91  }
92 
93  static void FaceClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
94  {
95  RequirePerFaceFlags(m);
96  int andMask = ~FlagMask;
97  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
98  if(!(*fi).IsD()) (*fi).Flags() &= andMask ;
99  }
100 
101  static void TetraClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
102  {
103  RequirePerTetraFlags(m);
104  int andMask = ~FlagMask;
105  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
106  if(!(*ti).IsD()) (*ti).Flags() &= andMask ;
107  }
108 
109  static void VertexSet(MeshType &m, unsigned int FlagMask)
110  {
111  RequirePerVertexFlags(m);
112  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
113  if(!(*vi).IsD()) (*vi).Flags() |= FlagMask ;
114  }
115 
116  static void EdgeSet(MeshType &m, unsigned int FlagMask)
117  {
118  RequirePerEdgeFlags(m);
119  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
120  if(!(*ei).IsD()) (*ei).Flags() |= FlagMask ;
121  }
122 
123  static void FaceSet(MeshType &m, unsigned int FlagMask)
124  {
125  RequirePerFaceFlags(m);
126  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
127  if(!(*fi).IsD()) (*fi).Flags() |= FlagMask ;
128  }
129 
130  static void TetraSet(MeshType &m, unsigned int FlagMask)
131  {
132  RequirePerTetraFlags(m);
133  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
134  if(!(*ti).IsD()) (*ti).Flags() |= FlagMask ;
135  }
136 
137 
138 
139  static void VertexClearV(MeshType &m) { VertexClear(m,VertexType::VISITED);}
140  static void VertexClearS(MeshType &m) { VertexClear(m,VertexType::SELECTED);}
141  static void VertexClearB(MeshType &m) { VertexClear(m,VertexType::BORDER);}
142  static void EdgeClearV(MeshType &m) { EdgeClear(m,EdgeType::VISITED);}
143  static void FaceClearV(MeshType &m) { FaceClear(m,FaceType::VISITED);}
144  static void FaceClearB(MeshType &m) { FaceClear(m,FaceType::BORDER012);}
145  static void FaceClearS(MeshType &m) {FaceClear(m,FaceType::SELECTED);}
146  static void FaceClearF(MeshType &m) { FaceClear(m,FaceType::FAUX012);}
147  static void FaceClearFaceEdgeS(MeshType &m) { FaceClear(m,FaceType::FACEEDGESEL012 ); }
148 
149  static void EdgeSetV(MeshType &m) { EdgeSet(m,EdgeType::VISITED);}
150  static void VertexSetV(MeshType &m) { VertexSet(m,VertexType::VISITED);}
151  static void VertexSetS(MeshType &m) { VertexSet(m,VertexType::SELECTED);}
152  static void VertexSetB(MeshType &m) { VertexSet(m,VertexType::BORDER);}
153  static void FaceSetV(MeshType &m) { FaceSet(m,FaceType::VISITED);}
154  static void FaceSetB(MeshType &m) { FaceSet(m,FaceType::BORDER);}
155  static void FaceSetF(MeshType &m) { FaceSet(m,FaceType::FAUX012);}
156  static void TetraClearV(MeshType &m) { TetraClear(m, TetraType::VISITED); }
157  static void TetraClearS(MeshType &m) { TetraClear(m, TetraType::SELECTED); }
158  static void TetraClearB(MeshType &m) { TetraClear(m, TetraType::BORDER0123); }
159  static void TetraSetV(MeshType &m) { TetraSet(m, TetraType::VISITED); }
160  static void TetraSetS(MeshType &m) { TetraSet(m, TetraType::SELECTED); }
161  static void TetraSetB(MeshType &m) { TetraSet(m, TetraType::BORDER0123); }
163 
166  static void FaceBorderFromFF(MeshType &m)
167  {
168  RequirePerFaceFlags(m);
169  RequireFFAdjacency(m);
170 
171  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
172  for(int j=0;j<fi->VN();++j)
173  {
174  if(face::IsBorder(*fi,j)) (*fi).SetB(j);
175  else (*fi).ClearB(j);
176  }
177  }
178 
180 
183  static void TetraBorderFromTT(MeshType &m)
184  {
185  RequirePerTetraFlags(m);
186  RequireTTAdjacency(m);
187 
188  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
189  if(!(*ti).IsD())
190  for(int j = 0; j < 4; ++j)
191  {
192  if (tetrahedron::IsBorder(*ti,j)) (*ti).SetB(j);
193  else (*ti).ClearB(j);
194  }
195  }
196 
197  static void VertexBorderFromTT(MeshType &m)
198  {
199  RequirePerVertexFlags(m);
200  RequireTTAdjacency(m);
201 
202  VertexClearB(m);
203 
204  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
205  if(!(*ti).IsD())
206  for(int j = 0; j < 4; ++j)
207  {
208  if (tetrahedron::IsBorder(*ti,j))
209  {
210  for (int i = 0; i < 3; ++i)
211  ti->V(Tetra::VofF(j, i))->SetB();
212  }
213  }
214  }
215 
216 
217  static void FaceBorderFromVF(MeshType &m)
218  {
219  RequirePerFaceFlags(m);
220  RequireVFAdjacency(m);
221 
222  FaceClearB(m);
223  int visitedBit=VertexType::NewBitFlag();
224 
225  // Calcolo dei bordi
226  // per ogni vertice vi si cercano i vertici adiacenti che sono toccati da una faccia sola
227  // (o meglio da un numero dispari di facce)
228 
229  const int BORDERFLAG[3]={FaceType::BORDER0, FaceType::BORDER1, FaceType::BORDER2};
230 
231  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
232  if(!(*vi).IsD())
233  {
234  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
235  {
236  vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
237  vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
238  }
239  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
240  {
241  if(vfi.f->V1(vfi.z)->IsUserBit(visitedBit)) vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
242  else vfi.f->V1(vfi.z)->SetUserBit(visitedBit);
243  if(vfi.f->V2(vfi.z)->IsUserBit(visitedBit)) vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
244  else vfi.f->V2(vfi.z)->SetUserBit(visitedBit);
245  }
246  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
247  {
248  if(vfi.f->V(vfi.z)< vfi.f->V1(vfi.z) && vfi.f->V1(vfi.z)->IsUserBit(visitedBit))
249  vfi.f->Flags() |= BORDERFLAG[vfi.z];
250  if(vfi.f->V(vfi.z)< vfi.f->V2(vfi.z) && vfi.f->V2(vfi.z)->IsUserBit(visitedBit))
251  vfi.f->Flags() |= BORDERFLAG[(vfi.z+2)%3];
252  }
253  }
254  VertexType::DeleteBitFlag(visitedBit);
255  }
256 
257 
258  class EdgeSorter
259  {
260  public:
261 
262  VertexPointer v[2]; // Puntatore ai due vertici (Ordinati)
263  FacePointer f; // Puntatore alla faccia generatrice
264  int z; // Indice dell'edge nella faccia
265 
266  EdgeSorter() {} // Nothing to do
267 
268 
269  void Set( const FacePointer pf, const int nz )
270  {
271  assert(pf!=0);
272  assert(nz>=0);
273  assert(nz<3);
274 
275  v[0] = pf->V(nz);
276  v[1] = pf->V((nz+1)%3);
277  assert(v[0] != v[1]);
278 
279  if( v[0] > v[1] ) std::swap(v[0],v[1]);
280  f = pf;
281  z = nz;
282  }
283 
284  inline bool operator < ( const EdgeSorter & pe ) const {
285  if( v[0]<pe.v[0] ) return true;
286  else if( v[0]>pe.v[0] ) return false;
287  else return v[1] < pe.v[1];
288  }
289 
290  inline bool operator == ( const EdgeSorter & pe ) const
291  {
292  return v[0]==pe.v[0] && v[1]==pe.v[1];
293  }
294  inline bool operator != ( const EdgeSorter & pe ) const
295  {
296  return v[0]!=pe.v[0] || v[1]!=pe.v[1];
297  }
298 
299  };
300 
301 
302  // versione minimale che non calcola i complex flag.
303  static void VertexBorderFromNone(MeshType &m)
304  {
305  RequirePerVertexFlags(m);
306 
307  std::vector<EdgeSorter> e;
308  typename UpdateMeshType::FaceIterator pf;
309  typename std::vector<EdgeSorter>::iterator p;
310 
311  if( m.fn == 0 )
312  return;
313 
314  e.resize(m.fn*3); // Alloco il vettore ausiliario
315  p = e.begin();
316  for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
317  if( ! (*pf).IsD() )
318  for(int j=0;j<3;++j)
319  {
320  (*p).Set(&(*pf),j);
321  (*pf).ClearB(j);
322  ++p;
323  }
324  assert(p==e.end());
325  sort(e.begin(), e.end()); // Lo ordino per vertici
326 
327  typename std::vector<EdgeSorter>::iterator pe,ps;
328  for(ps = e.begin(), pe = e.begin(); pe < e.end(); ++pe) // Scansione vettore ausiliario
329  {
330  if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali
331  {
332  if(pe-ps==1) {
333  ps->v[0]->SetB();
334  ps->v[1]->SetB();
335  }/* else
336  if(pe-ps!=2) { // not twomanyfold!
337  for(;ps!=pe;++ps) {
338  ps->v[0]->SetB(); // Si settano border anche i complex.
339  ps->v[1]->SetB();
340  }
341  }*/
342  ps = pe;
343  }
344  }
345  }
346 
349  static void FaceBorderFromNone(MeshType &m)
350  {
351  RequirePerFaceFlags(m);
352 
353  std::vector<EdgeSorter> e;
354  typename UpdateMeshType::FaceIterator pf;
355  typename std::vector<EdgeSorter>::iterator p;
356 
357  for(VertexIterator v=m.vert.begin();v!=m.vert.end();++v)
358  (*v).ClearB();
359 
360  if( m.fn == 0 )
361  return;
362 
363  FaceIterator fi;
364  int n_edges = 0;
365  for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
366  e.resize(n_edges);
367 
368  p = e.begin();
369  for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
370  if( ! (*pf).IsD() )
371  for(int j=0;j<(*pf).VN();++j)
372  {
373  (*p).Set(&(*pf),j);
374  (*pf).ClearB(j);
375  ++p;
376  }
377  assert(p==e.end());
378  sort(e.begin(), e.end()); // Lo ordino per vertici
379 
380  typename std::vector<EdgeSorter>::iterator pe,ps;
381  ps = e.begin();pe=e.begin();
382  do
383  {
384  if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali
385  {
386  if(pe-ps==1) {
387  ps->f->SetB(ps->z);
388  } /*else
389  if(pe-ps!=2) { // Caso complex!!
390  for(;ps!=pe;++ps)
391  ps->f->SetB(ps->z); // Si settano border anche i complex.
392  }*/
393  ps = pe;
394  }
395  if(pe==e.end()) break;
396  ++pe;
397  } while(true);
398  // TRACE("found %i border (%i complex) on %i edges\n",nborder,ncomplex,ne);
399  }
400 
402  static void VertexBorderFromFaceAdj(MeshType &m)
403  {
404  RequirePerFaceFlags(m);
405  RequirePerVertexFlags(m);
406  RequireFFAdjacency(m);
407  // MeshAssert<MeshType>::FFAdjacencyIsInitialized(m);
408 
409  VertexClearB(m);
410  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
411  if(!(*fi).IsD())
412  {
413 
414  for(int z=0;z<(*fi).VN();++z)
415  if( face::IsBorder(*fi,z))
416  {
417  (*fi).V0(z)->SetB();
418  (*fi).V1(z)->SetB();
419  }
420  }
421  }
422 
424  static void VertexBorderFromFaceBorder(MeshType &m)
425  {
426  RequirePerFaceFlags(m);
427  RequirePerVertexFlags(m);
428  VertexClearB(m);
429  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
430  if(!(*fi).IsD())
431  {
432  for(int z=0;z<(*fi).VN();++z)
433  if( (*fi).IsB(z) )
434  {
435  (*fi).V(z)->SetB();
436  (*fi).V((*fi).Next(z))->SetB();
437  }
438  }
439  }
440 
442  static void VertexBorderFromEdgeAdj(MeshType &m)
443  {
444  RequirePerVertexFlags(m);
445  RequireEEAdjacency(m);
446 
447  VertexClearB(m);
448  for (EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
449  if (!ei->IsD())
450  {
451  for (int z=0; z<2; ++z)
452  if (edge::IsEdgeBorder(*ei, z))
453  {
454  ei->V(z)->SetB();
455  }
456  }
457  }
458 
468  static void FaceEdgeSelSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag = false )
469  {
470  RequirePerFaceFlags(m);
471  RequireFFAdjacency(m);
472  //initially Nothing is faux (e.g all crease)
473  FaceClearFaceEdgeS(m);
474  // Then mark faux only if the signed angle is the range.
475  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
476  {
477  for(int z=0;z<(*fi).VN();++z)
478  {
479  if(!face::IsBorder(*fi,z) )
480  {
481  ScalarType angle = DihedralAngleRad(*fi,z);
482  if(angle<AngleRadNeg || angle>AngleRadPos)
483  (*fi).SetFaceEdgeS(z);
484  }
485  else
486  {
487  if(MarkBorderFlag) (*fi).SetFaceEdgeS(z);
488  }
489  }
490  }
491  }
492 
495  static void FaceEdgeSelBorder(MeshType &m)
496  {
497  RequirePerFaceFlags(m);
498  RequireFFAdjacency(m);
499  //initially Nothing is selected
500  FaceClearFaceEdgeS(m);
501  for (FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
502  if (!fi->IsD())
503  {
504  for (int z=0; z<(*fi).VN(); ++z)
505  {
506  if (face::IsBorder(*fi,z))
507  fi->SetFaceEdgeS(z);
508  }
509  }
510  }
511 
517  static void FaceEdgeSelCrease(MeshType &m,float AngleRad)
518  {
519  FaceEdgeSelSignedCrease(m,-AngleRad,AngleRad);
520  }
521 
522 
523 }; // end class
524 
525 } // End namespace tri
526 } // End namespace vcg
527 
528 
529 #endif