VCG Library
Loading...
Searching...
No Matches
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
30namespace vcg {
31namespace tri {
33
35
37
42template <class UpdateMeshType>
44{
45
46public:
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 marked
477 FaceClearFaceEdgeS(m);
478 // Then select the edge as crease only if the signed angle is outside 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: color4.h:30