$darkmode
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 #include <vcg/simplex/face/pos.h>
27 #include <vcg/simplex/tetrahedron/pos.h>
28 #include <vcg/simplex/edge/pos.h>
29 
30 namespace vcg {
31 namespace tri {
33 
35 
37 
42 template <class UpdateMeshType>
44 {
45 
46 public:
47  typedef UpdateMeshType MeshType;
48  typedef typename MeshType::ScalarType ScalarType;
49  typedef typename MeshType::VertexType VertexType;
50  typedef typename MeshType::VertexPointer VertexPointer;
51  typedef typename MeshType::VertexIterator VertexIterator;
52  typedef typename MeshType::EdgeType EdgeType;
53  typedef typename MeshType::EdgePointer EdgePointer;
54  typedef typename MeshType::EdgeIterator EdgeIterator;
55  typedef typename MeshType::FaceType FaceType;
56  typedef typename MeshType::FacePointer FacePointer;
57  typedef typename MeshType::FaceIterator FaceIterator;
58  typedef typename MeshType::TetraType TetraType;
59  typedef typename MeshType::TetraPointer TetraPointer;
60  typedef typename MeshType::TetraIterator TetraIterator;
61 
63 
64  static void Clear(MeshType &m)
65  {
66  if(HasPerVertexFlags(m) )
67  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
68  (*vi).Flags() = 0;
69  if(HasPerEdgeFlags(m) )
70  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
71  (*ei).Flags() = 0;
72  if(HasPerFaceFlags(m) )
73  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
74  (*fi).Flags() = 0;
75  if(HasPerTetraFlags(m) )
76  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
77  (*ti).Flags() = 0;
78  }
79 
80 
81  static void VertexClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
82  {
83  RequirePerVertexFlags(m);
84  int andMask = ~FlagMask;
85  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
86  if(!(*vi).IsD()) (*vi).Flags() &= andMask ;
87  }
88 
89  static void EdgeClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
90  {
91  RequirePerEdgeFlags(m);
92  int andMask = ~FlagMask;
93  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
94  if(!(*ei).IsD()) (*ei).Flags() &= andMask ;
95  }
96 
97  static void FaceClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
98  {
99  RequirePerFaceFlags(m);
100  int andMask = ~FlagMask;
101  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
102  if(!(*fi).IsD()) (*fi).Flags() &= andMask ;
103  }
104 
105  static void TetraClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
106  {
107  RequirePerTetraFlags(m);
108  int andMask = ~FlagMask;
109  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
110  if(!(*ti).IsD()) (*ti).Flags() &= andMask ;
111  }
112 
113  static void VertexSet(MeshType &m, unsigned int FlagMask)
114  {
115  RequirePerVertexFlags(m);
116  for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
117  if(!(*vi).IsD()) (*vi).Flags() |= FlagMask ;
118  }
119 
120  static void EdgeSet(MeshType &m, unsigned int FlagMask)
121  {
122  RequirePerEdgeFlags(m);
123  for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
124  if(!(*ei).IsD()) (*ei).Flags() |= FlagMask ;
125  }
126 
127  static void FaceSet(MeshType &m, unsigned int FlagMask)
128  {
129  RequirePerFaceFlags(m);
130  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
131  if(!(*fi).IsD()) (*fi).Flags() |= FlagMask ;
132  }
133 
134  static void TetraSet(MeshType &m, unsigned int FlagMask)
135  {
136  RequirePerTetraFlags(m);
137  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
138  if(!(*ti).IsD()) (*ti).Flags() |= FlagMask ;
139  }
140 
141 
142 
143  static void VertexClearV(MeshType &m) { VertexClear(m,VertexType::VISITED);}
144  static void VertexClearS(MeshType &m) { VertexClear(m,VertexType::SELECTED);}
145  static void VertexClearB(MeshType &m) { VertexClear(m,VertexType::BORDER);}
146  static void EdgeClearV(MeshType &m) { EdgeClear(m,EdgeType::VISITED);}
147  static void FaceClearV(MeshType &m) { FaceClear(m,FaceType::VISITED);}
148  static void FaceClearB(MeshType &m) { FaceClear(m,FaceType::BORDER012);}
149  static void FaceClearS(MeshType &m) {FaceClear(m,FaceType::SELECTED);}
150  static void FaceClearF(MeshType &m) { FaceClear(m,FaceType::FAUX012);}
151  static void FaceClearFaceEdgeS(MeshType &m) { FaceClear(m,FaceType::FACEEDGESEL012 ); }
152 
153  static void EdgeSetV(MeshType &m) { EdgeSet(m,EdgeType::VISITED);}
154  static void VertexSetV(MeshType &m) { VertexSet(m,VertexType::VISITED);}
155  static void VertexSetS(MeshType &m) { VertexSet(m,VertexType::SELECTED);}
156  static void VertexSetB(MeshType &m) { VertexSet(m,VertexType::BORDER);}
157  static void FaceSetV(MeshType &m) { FaceSet(m,FaceType::VISITED);}
158  static void FaceSetB(MeshType &m) { FaceSet(m,FaceType::BORDER);}
159  static void FaceSetF(MeshType &m) { FaceSet(m,FaceType::FAUX012);}
160  static void TetraClearV(MeshType &m) { TetraClear(m, TetraType::VISITED); }
161  static void TetraClearS(MeshType &m) { TetraClear(m, TetraType::SELECTED); }
162  static void TetraClearB(MeshType &m) { TetraClear(m, TetraType::BORDER0123); }
163  static void TetraSetV(MeshType &m) { TetraSet(m, TetraType::VISITED); }
164  static void TetraSetS(MeshType &m) { TetraSet(m, TetraType::SELECTED); }
165  static void TetraSetB(MeshType &m) { TetraSet(m, TetraType::BORDER0123); }
167 
170  static void FaceBorderFromFF(MeshType &m)
171  {
172  RequirePerFaceFlags(m);
173  RequireFFAdjacency(m);
174 
175  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
176  for(int j=0;j<fi->VN();++j)
177  {
178  if(face::IsBorder(*fi,j)) (*fi).SetB(j);
179  else (*fi).ClearB(j);
180  }
181  }
182 
184 
187  static void TetraBorderFromTT(MeshType &m)
188  {
189  RequirePerTetraFlags(m);
190  RequireTTAdjacency(m);
191 
192  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
193  if(!(*ti).IsD())
194  for(int j = 0; j < 4; ++j)
195  {
196  if (IsTTBorder(*ti,j)) (*ti).SetB(j);
197  else (*ti).ClearB(j);
198  }
199  }
200 
201  static void VertexBorderFromTT(MeshType &m)
202  {
203  RequirePerVertexFlags(m);
204  RequireTTAdjacency(m);
205 
206  VertexClearB(m);
207 
208  for(TetraIterator ti=m.tetra.begin(); ti!=m.tetra.end(); ++ti)
209  if(!(*ti).IsD())
210  for(int j = 0; j < 4; ++j)
211  {
212  if (IsTTBorder(*ti,j))
213  {
214  for (int i = 0; i < 3; ++i)
215  ti->V(Tetra::VofF(j, i))->SetB();
216  }
217  }
218  }
219 
220 
221  static void FaceBorderFromVF(MeshType &m)
222  {
223  RequirePerFaceFlags(m);
224  RequireVFAdjacency(m);
225 
226  FaceClearB(m);
227  int visitedBit=VertexType::NewBitFlag();
228 
229  // Calcolo dei bordi
230  // per ogni vertice vi si cercano i vertici adiacenti che sono toccati da una faccia sola
231  // (o meglio da un numero dispari di facce)
232 
233  const int BORDERFLAG[3]={FaceType::BORDER0, FaceType::BORDER1, FaceType::BORDER2};
234 
235  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
236  if(!(*vi).IsD())
237  {
238  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
239  {
240  vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
241  vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
242  }
243  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
244  {
245  if(vfi.f->V1(vfi.z)->IsUserBit(visitedBit)) vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
246  else vfi.f->V1(vfi.z)->SetUserBit(visitedBit);
247  if(vfi.f->V2(vfi.z)->IsUserBit(visitedBit)) vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
248  else vfi.f->V2(vfi.z)->SetUserBit(visitedBit);
249  }
250  for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
251  {
252  if(vfi.f->V(vfi.z)< vfi.f->V1(vfi.z) && vfi.f->V1(vfi.z)->IsUserBit(visitedBit))
253  vfi.f->Flags() |= BORDERFLAG[vfi.z];
254  if(vfi.f->V(vfi.z)< vfi.f->V2(vfi.z) && vfi.f->V2(vfi.z)->IsUserBit(visitedBit))
255  vfi.f->Flags() |= BORDERFLAG[(vfi.z+2)%3];
256  }
257  }
258  VertexType::DeleteBitFlag(visitedBit);
259  }
260 
261 
263  {
264  public:
265 
266  VertexPointer v[2]; // Puntatore ai due vertici (Ordinati)
267  FacePointer f; // Puntatore alla faccia generatrice
268  int z; // Indice dell'edge nella faccia
269 
270  EdgeSorter() {} // Nothing to do
271 
272 
273  void Set( const FacePointer pf, const int nz )
274  {
275  assert(pf!=0);
276  assert(nz>=0);
277  assert(nz<3);
278 
279  v[0] = pf->V(nz);
280  v[1] = pf->V((nz+1)%3);
281  assert(v[0] != v[1]);
282 
283  if( v[0] > v[1] ) std::swap(v[0],v[1]);
284  f = pf;
285  z = nz;
286  }
287 
288  inline bool operator < ( const EdgeSorter & pe ) const {
289  if( v[0]<pe.v[0] ) return true;
290  else if( v[0]>pe.v[0] ) return false;
291  else return v[1] < pe.v[1];
292  }
293 
294  inline bool operator == ( const EdgeSorter & pe ) const
295  {
296  return v[0]==pe.v[0] && v[1]==pe.v[1];
297  }
298  inline bool operator != ( const EdgeSorter & pe ) const
299  {
300  return v[0]!=pe.v[0] || v[1]!=pe.v[1];
301  }
302 
303  };
304 
305 
306  // versione minimale che non calcola i complex flag.
307  static void VertexBorderFromNone(MeshType &m)
308  {
309  RequirePerVertexFlags(m);
310 
311  std::vector<EdgeSorter> e;
312  typename UpdateMeshType::FaceIterator pf;
313  typename std::vector<EdgeSorter>::iterator p;
314 
315  if( m.fn == 0 )
316  return;
317 
318  e.resize(m.fn*3); // Alloco il vettore ausiliario
319  p = e.begin();
320  for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
321  if( ! (*pf).IsD() )
322  for(int j=0;j<3;++j)
323  {
324  (*p).Set(&(*pf),j);
325  (*pf).ClearB(j);
326  ++p;
327  }
328  assert(p==e.end());
329  sort(e.begin(), e.end()); // Lo ordino per vertici
330 
331  typename std::vector<EdgeSorter>::iterator pe,ps;
332  for(ps = e.begin(), pe = e.begin(); pe < e.end(); ++pe) // Scansione vettore ausiliario
333  {
334  if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali
335  {
336  if(pe-ps==1) {
337  ps->v[0]->SetB();
338  ps->v[1]->SetB();
339  }/* else
340  if(pe-ps!=2) { // not twomanyfold!
341  for(;ps!=pe;++ps) {
342  ps->v[0]->SetB(); // Si settano border anche i complex.
343  ps->v[1]->SetB();
344  }
345  }*/
346  ps = pe;
347  }
348  }
349  }
350 
353  static void FaceBorderFromNone(MeshType &m)
354  {
355  RequirePerFaceFlags(m);
356 
357  std::vector<EdgeSorter> e;
358  typename UpdateMeshType::FaceIterator pf;
359  typename std::vector<EdgeSorter>::iterator p;
360 
361  for(VertexIterator v=m.vert.begin();v!=m.vert.end();++v)
362  (*v).ClearB();
363 
364  if( m.fn == 0 )
365  return;
366 
367  FaceIterator fi;
368  int n_edges = 0;
369  for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
370  e.resize(n_edges);
371 
372  p = e.begin();
373  for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
374  if( ! (*pf).IsD() )
375  for(int j=0;j<(*pf).VN();++j)
376  {
377  (*p).Set(&(*pf),j);
378  (*pf).ClearB(j);
379  ++p;
380  }
381  assert(p==e.end());
382  sort(e.begin(), e.end()); // Lo ordino per vertici
383 
384  typename std::vector<EdgeSorter>::iterator pe,ps;
385  ps = e.begin();pe=e.begin();
386  do
387  {
388  if( pe==e.end() || *pe != *ps ) // Trovo blocco di edge uguali
389  {
390  if(pe-ps==1) {
391  ps->f->SetB(ps->z);
392  } /*else
393  if(pe-ps!=2) { // Caso complex!!
394  for(;ps!=pe;++ps)
395  ps->f->SetB(ps->z); // Si settano border anche i complex.
396  }*/
397  ps = pe;
398  }
399  if(pe==e.end()) break;
400  ++pe;
401  } while(true);
402  // TRACE("found %i border (%i complex) on %i edges\n",nborder,ncomplex,ne);
403  }
404 
406  static void VertexBorderFromFaceAdj(MeshType &m)
407  {
408  RequirePerFaceFlags(m);
409  RequirePerVertexFlags(m);
410  RequireFFAdjacency(m);
411  // MeshAssert<MeshType>::FFAdjacencyIsInitialized(m);
412 
413  VertexClearB(m);
414  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
415  if(!(*fi).IsD())
416  {
417 
418  for(int z=0;z<(*fi).VN();++z)
419  if( face::IsBorder(*fi,z))
420  {
421  (*fi).V0(z)->SetB();
422  (*fi).V1(z)->SetB();
423  }
424  }
425  }
426 
428  static void VertexBorderFromFaceBorder(MeshType &m)
429  {
430  RequirePerFaceFlags(m);
431  RequirePerVertexFlags(m);
432  VertexClearB(m);
433  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
434  if(!(*fi).IsD())
435  {
436  for(int z=0;z<(*fi).VN();++z)
437  if( (*fi).IsB(z) )
438  {
439  (*fi).V(z)->SetB();
440  (*fi).V((*fi).Next(z))->SetB();
441  }
442  }
443  }
444 
446  static void VertexBorderFromEdgeAdj(MeshType &m)
447  {
448  RequirePerVertexFlags(m);
449  RequireEEAdjacency(m);
450 
451  VertexClearB(m);
452  for (EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
453  if (!ei->IsD())
454  {
455  for (int z=0; z<2; ++z)
456  if (edge::IsEdgeBorder(*ei, z))
457  {
458  ei->V(z)->SetB();
459  }
460  }
461  }
462 
472  static void FaceEdgeSelSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag = false )
473  {
474  RequirePerFaceFlags(m);
475  RequireFFAdjacency(m);
476  //initially Nothing is faux (e.g all crease)
477  FaceClearFaceEdgeS(m);
478  // Then mark faux only if the signed angle is the range.
479  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
480  {
481  for(int z=0;z<(*fi).VN();++z)
482  {
483  if(!face::IsBorder(*fi,z) )
484  {
485  ScalarType angle = DihedralAngleRad(*fi,z);
486  if(angle<AngleRadNeg || angle>AngleRadPos)
487  (*fi).SetFaceEdgeS(z);
488  }
489  else
490  {
491  if(MarkBorderFlag) (*fi).SetFaceEdgeS(z);
492  }
493  }
494  }
495  }
496 
499  static void FaceEdgeSelBorder(MeshType &m)
500  {
501  RequirePerFaceFlags(m);
502  RequireFFAdjacency(m);
503  //initially Nothing is selected
504  FaceClearFaceEdgeS(m);
505  for (FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
506  if (!fi->IsD())
507  {
508  for (int z=0; z<(*fi).VN(); ++z)
509  {
510  if (face::IsBorder(*fi,z))
511  fi->SetFaceEdgeS(z);
512  }
513  }
514  }
515 
521  static void FaceEdgeSelCrease(MeshType &m,float AngleRad)
522  {
523  FaceEdgeSelSignedCrease(m,-AngleRad,AngleRad);
524  }
525 
526 
527 }; // end class
528 
529 } // End namespace tri
530 } // End namespace vcg
531 
532 
533 #endif
Definition: flag.h:263
Management, updating and computation of per-vertex and per-face flags (like border flags).
Definition: flag.h:44
static void VertexBorderFromFaceAdj(MeshType &m)
Compute the PerVertex Border flag deriving it from the face-face adjacency.
Definition: flag.h:406
static void FaceEdgeSelSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag=false)
Marks feature edges according to two signed dihedral angles. Actually it uses the face_edge selection...
Definition: flag.h:472
static void Clear(MeshType &m)
Reset all the mesh flags (vertexes edge faces) setting everithing to zero (the default value for flag...
Definition: flag.h:64
static void FaceEdgeSelCrease(MeshType &m, float AngleRad)
Marks feature edges according to a given angle Actually it uses the face_edge selection bit on faces,...
Definition: flag.h:521
static void FaceBorderFromNone(MeshType &m)
Definition: flag.h:353
static void VertexBorderFromFaceBorder(MeshType &m)
Compute the PerVertex Border flag deriving it from the border flag of faces.
Definition: flag.h:428
static void FaceBorderFromFF(MeshType &m)
Compute the border flags for the faces using the Face-Face Topology.
Definition: flag.h:170
static void TetraBorderFromTT(MeshType &m)
Compute the border flags for the tetras using the Tetra-Tetra Topology.
Definition: flag.h:187
static void FaceEdgeSelBorder(MeshType &m)
Selects feature edges according to Face adjacency.
Definition: flag.h:499
static void VertexBorderFromEdgeAdj(MeshType &m)
Compute the PerVertex Border flag deriving it from the Edge-Edge adjacency (made for edgemeshes)
Definition: flag.h:446
bool IsBorder(FaceType const &f, const int j)
Definition: topology.h:55
Definition: namespaces.dox:6