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 
56 
57  static void Clear(MeshType &m)
58  {
59  if(HasPerVertexFlags(m) )
60  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
61  (*vi).Flags() = 0;
62  if(HasPerEdgeFlags(m) )
63  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
64  (*ei).Flags() = 0;
65  if(HasPerFaceFlags(m) )
66  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
67  (*fi).Flags() = 0;
68  }
69 
70  static void VertexClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
71  {
72  RequirePerVertexFlags(m);
73  int andMask = ~FlagMask;
74  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
75  if(!(*vi).IsD()) (*vi).Flags() &= andMask ;
76  }
77 
78  static void EdgeClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
79  {
80  RequirePerEdgeFlags(m);
81  int andMask = ~FlagMask;
82  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
83  if(!(*ei).IsD()) (*ei).Flags() &= andMask ;
84  }
85 
86  static void FaceClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
87  {
88  RequirePerFaceFlags(m);
89  int andMask = ~FlagMask;
90  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
91  if(!(*fi).IsD()) (*fi).Flags() &= andMask ;
92  }
93 
94  static void VertexSet(MeshType &m, unsigned int FlagMask)
95  {
96  RequirePerVertexFlags(m);
97  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
98  if(!(*vi).IsD()) (*vi).Flags() |= FlagMask ;
99  }
100 
101  static void EdgeSet(MeshType &m, unsigned int FlagMask)
102  {
103  RequirePerEdgeFlags(m);
104  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
105  if(!(*ei).IsD()) (*ei).Flags() |= FlagMask ;
106  }
107 
108  static void FaceSet(MeshType &m, unsigned int FlagMask)
109  {
110  RequirePerFaceFlags(m);
111  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
112  if(!(*fi).IsD()) (*fi).Flags() |= FlagMask ;
113  }
114 
115 
116 
117  static void VertexClearV(MeshType &m) { VertexClear(m,VertexType::VISITED);}
118  static void VertexClearS(MeshType &m) { VertexClear(m,VertexType::SELECTED);}
119  static void VertexClearB(MeshType &m) { VertexClear(m,VertexType::BORDER);}
120  static void EdgeClearV(MeshType &m) { EdgeClear(m,EdgeType::VISITED);}
121  static void FaceClearV(MeshType &m) { FaceClear(m,FaceType::VISITED);}
122  static void FaceClearB(MeshType &m) { FaceClear(m,FaceType::BORDER012);}
123  static void FaceClearS(MeshType &m) {FaceClear(m,FaceType::SELECTED);}
124  static void FaceClearF(MeshType &m) { FaceClear(m,FaceType::FAUX012);}
125  static void FaceClearCreases(MeshType &m) { FaceClear(m,FaceType::CREASE0);
126  FaceClear(m,FaceType::CREASE1);
127  FaceClear(m,FaceType::CREASE2);
128  }
129 
130  static void EdgeSetV(MeshType &m) { EdgeSet(m,EdgeType::VISITED);}
131  static void VertexSetV(MeshType &m) { VertexSet(m,VertexType::VISITED);}
132  static void VertexSetS(MeshType &m) { VertexSet(m,VertexType::SELECTED);}
133  static void VertexSetB(MeshType &m) { VertexSet(m,VertexType::BORDER);}
134  static void FaceSetV(MeshType &m) { FaceSet(m,FaceType::VISITED);}
135  static void FaceSetB(MeshType &m) { FaceSet(m,FaceType::BORDER);}
136  static void FaceSetF(MeshType &m) { FaceSet(m,FaceType::FAUX012);}
137 
139 
143  static void FaceBorderFromFF(MeshType &m)
144  {
145  RequirePerFaceFlags(m);
146  RequireFFAdjacency(m);
147 
148  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
149  for(int j=0;j<fi->VN();++j)
150  {
151  if(face::IsBorder(*fi,j)) (*fi).SetB(j);
152  else (*fi).ClearB(j);
153  }
154  }
155 
156 
157  static void FaceBorderFromVF(MeshType &m)
158  {
159  RequirePerFaceFlags(m);
160  RequireVFAdjacency(m);
161 
162  FaceClearB(m);
163  int visitedBit=VertexType::NewBitFlag();
164 
165  // Calcolo dei bordi
166  // per ogni vertice vi si cercano i vertici adiacenti che sono toccati da una faccia sola
167  // (o meglio da un numero dispari di facce)
168 
169  const int BORDERFLAG[3]={FaceType::BORDER0, FaceType::BORDER1, FaceType::BORDER2};
170 
171  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
172  if(!(*vi).IsD())
173  {
174  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
175  {
176  vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
177  vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
178  }
179  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
180  {
181  if(vfi.f->V1(vfi.z)->IsUserBit(visitedBit)) vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
182  else vfi.f->V1(vfi.z)->SetUserBit(visitedBit);
183  if(vfi.f->V2(vfi.z)->IsUserBit(visitedBit)) vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
184  else vfi.f->V2(vfi.z)->SetUserBit(visitedBit);
185  }
186  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
187  {
188  if(vfi.f->V(vfi.z)< vfi.f->V1(vfi.z) && vfi.f->V1(vfi.z)->IsUserBit(visitedBit))
189  vfi.f->Flags() |= BORDERFLAG[vfi.z];
190  if(vfi.f->V(vfi.z)< vfi.f->V2(vfi.z) && vfi.f->V2(vfi.z)->IsUserBit(visitedBit))
191  vfi.f->Flags() |= BORDERFLAG[(vfi.z+2)%3];
192  }
193  }
194  VertexType::DeleteBitFlag(visitedBit);
195  }
196 
197 
198  class EdgeSorter
199  {
200  public:
201 
202  VertexPointer v[2]; // Puntatore ai due vertici (Ordinati)
203  FacePointer f; // Puntatore alla faccia generatrice
204  int z; // Indice dell'edge nella faccia
205 
206  EdgeSorter() {} // Nothing to do
207 
208 
209  void Set( const FacePointer pf, const int nz )
210  {
211  assert(pf!=0);
212  assert(nz>=0);
213  assert(nz<3);
214 
215  v[0] = pf->V(nz);
216  v[1] = pf->V((nz+1)%3);
217  assert(v[0] != v[1]);
218 
219  if( v[0] > v[1] ) std::swap(v[0],v[1]);
220  f = pf;
221  z = nz;
222  }
223 
224  inline bool operator < ( const EdgeSorter & pe ) const {
225  if( v[0]<pe.v[0] ) return true;
226  else if( v[0]>pe.v[0] ) return false;
227  else return v[1] < pe.v[1];
228  }
229 
230  inline bool operator == ( const EdgeSorter & pe ) const
231  {
232  return v[0]==pe.v[0] && v[1]==pe.v[1];
233  }
234  inline bool operator != ( const EdgeSorter & pe ) const
235  {
236  return v[0]!=pe.v[0] || v[1]!=pe.v[1];
237  }
238 
239  };
240 
241 
242  // versione minimale che non calcola i complex flag.
243  static void VertexBorderFromNone(MeshType &m)
244  {
245  RequirePerVertexFlags(m);
246 
247  std::vector<EdgeSorter> e;
248  typename UpdateMeshType::FaceIterator pf;
249  typename std::vector<EdgeSorter>::iterator p;
250 
251  if( m.fn == 0 )
252  return;
253 
254  e.resize(m.fn*3); // Alloco il vettore ausiliario
255  p = e.begin();
256  for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
257  if( ! (*pf).IsD() )
258  for(int j=0;j<3;++j)
259  {
260  (*p).Set(&(*pf),j);
261  (*pf).ClearB(j);
262  ++p;
263  }
264  assert(p==e.end());
265  sort(e.begin(), e.end()); // Lo ordino per vertici
266 
267  typename std::vector<EdgeSorter>::iterator pe,ps;
268  for(ps = e.begin(), pe = e.begin(); pe < e.end(); ++pe) // Scansione vettore ausiliario
269  {
270  if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali
271  {
272  if(pe-ps==1) {
273  ps->v[0]->SetB();
274  ps->v[1]->SetB();
275  }/* else
276  if(pe-ps!=2) { // not twomanyfold!
277  for(;ps!=pe;++ps) {
278  ps->v[0]->SetB(); // Si settano border anche i complex.
279  ps->v[1]->SetB();
280  }
281  }*/
282  ps = pe;
283  }
284  }
285  }
286 
289  static void FaceBorderFromNone(MeshType &m)
290  {
291  RequirePerFaceFlags(m);
292 
293  std::vector<EdgeSorter> e;
294  typename UpdateMeshType::FaceIterator pf;
295  typename std::vector<EdgeSorter>::iterator p;
296 
297  for(VertexIterator v=m.vert.begin();v!=m.vert.end();++v)
298  (*v).ClearB();
299 
300  if( m.fn == 0 )
301  return;
302 
303  FaceIterator fi;
304  int n_edges = 0;
305  for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
306  e.resize(n_edges);
307 
308  p = e.begin();
309  for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
310  if( ! (*pf).IsD() )
311  for(int j=0;j<(*pf).VN();++j)
312  {
313  (*p).Set(&(*pf),j);
314  (*pf).ClearB(j);
315  ++p;
316  }
317  assert(p==e.end());
318  sort(e.begin(), e.end()); // Lo ordino per vertici
319 
320  typename std::vector<EdgeSorter>::iterator pe,ps;
321  ps = e.begin();pe=e.begin();
322  do
323  {
324  if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali
325  {
326  if(pe-ps==1) {
327  ps->f->SetB(ps->z);
328  } /*else
329  if(pe-ps!=2) { // Caso complex!!
330  for(;ps!=pe;++ps)
331  ps->f->SetB(ps->z); // Si settano border anche i complex.
332  }*/
333  ps = pe;
334  }
335  if(pe==e.end()) break;
336  ++pe;
337  } while(true);
338  // TRACE("found %i border (%i complex) on %i edges\n",nborder,ncomplex,ne);
339  }
340 
342  static void VertexBorderFromFaceAdj(MeshType &m)
343 {
344  RequirePerFaceFlags(m);
345  RequirePerVertexFlags(m);
346  RequireFFAdjacency(m);
347  // MeshAssert<MeshType>::FFAdjacencyIsInitialized(m);
348 
349  VertexClearB(m);
350  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
351  if(!(*fi).IsD())
352  {
353 
354  for(int z=0;z<(*fi).VN();++z)
355  if( face::IsBorder(*fi,z))
356  {
357  (*fi).V0(z)->SetB();
358  (*fi).V1(z)->SetB();
359  }
360  }
361  }
362 
364  static void VertexBorderFromFaceBorder(MeshType &m)
365  {
366  RequirePerFaceFlags(m);
367  RequirePerVertexFlags(m);
368  VertexClearB(m);
369  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
370  if(!(*fi).IsD())
371  {
372  for(int z=0;z<(*fi).VN();++z)
373  if( (*fi).IsB(z) )
374  {
375  (*fi).V(z)->SetB();
376  (*fi).V((*fi).Next(z))->SetB();
377  }
378  }
379  }
380 
381 
391  static void FaceFauxSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag = false )
392  {
393  RequirePerFaceFlags(m);
394  RequireFFAdjacency(m);
395  //initially Nothing is faux (e.g all crease)
396  FaceClearF(m);
397  // Then mark faux only if the signed angle is the range.
398  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
399  {
400  for(int z=0;z<(*fi).VN();++z)
401  {
402  if(!face::IsBorder(*fi,z) )
403  {
404  ScalarType angle = DihedralAngleRad(*fi,z);
405  if(angle>AngleRadNeg && angle<AngleRadPos)
406  (*fi).SetF(z);
407  }
408  else
409  {
410  if(MarkBorderFlag) (*fi).SetF(z);
411  }
412  }
413  }
414  }
415 
419  static void FaceFauxBorder(MeshType &m)
420  {
421  RequirePerFaceFlags(m);
422  RequireFFAdjacency(m);
423  //initially Nothing is faux (e.g all crease)
424  FaceClearF(m);
425  // Then mark faux only if the signed angle is the range.
426  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
427  {
428  for(int z=0;z<(*fi).VN();++z)
429  {
430  if(!face::IsBorder(*fi,z) ) (*fi).SetF(z);
431  }
432  }
433  }
434 
439  static void FaceFauxCrease(MeshType &m,float AngleRad)
440  {
441  FaceFauxSignedCrease(m,-AngleRad,AngleRad);
442  }
443 
444 
445 }; // end class
446 
447 } // End namespace tri
448 } // End namespace vcg
449 
450 
451 #endif