VCG Library
selection.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_SELECTION
24 #define __VCG_TRI_UPDATE_SELECTION
25 
26 namespace vcg {
27 namespace tri {
30 
34 template <class ComputeMeshType>
36 {
37  typedef typename ComputeMeshType::template PerVertexAttributeHandle< bool > vsHandle;
38  typedef typename ComputeMeshType::template PerEdgeAttributeHandle< bool > esHandle;
39  typedef typename ComputeMeshType::template PerFaceAttributeHandle< bool > fsHandle;
40  typedef typename ComputeMeshType::template PerTetraAttributeHandle< bool > tsHandle;
41 
42 
43 public:
44  SelectionStack(ComputeMeshType &m)
45  {
46  _m=&m;
47  }
48 
49  bool push()
50  {
51  vsHandle vsH = Allocator<ComputeMeshType>::template AddPerVertexAttribute< bool >(*_m);
52  esHandle esH = Allocator<ComputeMeshType>::template AddPerEdgeAttribute< bool > (*_m);
53  fsHandle fsH = Allocator<ComputeMeshType>::template AddPerFaceAttribute< bool > (*_m);
54  tsHandle tsH = Allocator<ComputeMeshType>::template AddPerTetraAttribute< bool > (*_m);
55  typename ComputeMeshType::VertexIterator vi;
56  for(vi = _m->vert.begin(); vi != _m->vert.end(); ++vi)
57  if( !(*vi).IsD() ) vsH[*vi] = (*vi).IsS() ;
58 
59  typename ComputeMeshType::EdgeIterator ei;
60  for(ei = _m->edge.begin(); ei != _m->edge.end(); ++ei)
61  if( !(*ei).IsD() ) esH[*ei] = (*ei).IsS() ;
62 
63  typename ComputeMeshType::FaceIterator fi;
64  for(fi = _m->face.begin(); fi != _m->face.end(); ++fi)
65  if( !(*fi).IsD() ) fsH[*fi] = (*fi).IsS() ;
66 
67  typename ComputeMeshType::TetraIterator ti;
68  for(ti = _m->tetra.begin(); ti != _m->tetra.end(); ++ti)
69  if( !(*ti).IsD() ) tsH[*ti] = (*ti).IsS() ;
70 
71  vsV.push_back(vsH);
72  esV.push_back(esH);
73  fsV.push_back(fsH);
74  tsV.push_back(tsH);
75  return true;
76  }
77 
78  bool popOr()
79  {
80  return pop(true,false);
81  }
82 
83  bool popAnd()
84  {
85  return pop(false,true);
86  }
87 
92  bool pop(bool orFlag=false, bool andFlag=false)
93  {
94  if(vsV.empty()) return false;
95  if(orFlag && andFlag) return false;
96 
97  vsHandle vsH = vsV.back();
98  esHandle esH = esV.back();
99  fsHandle fsH = fsV.back();
100  tsHandle tsH = tsV.back();
101 
102  if(! (Allocator<ComputeMeshType>::template IsValidHandle(*_m, vsH))) return false;
103 
104  for(auto vi = _m->vert.begin(); vi != _m->vert.end(); ++vi)
105  if( !(*vi).IsD() )
106  {
107  if(vsH[*vi]) {
108  if(!andFlag) (*vi).SetS();
109  } else {
110  if(!orFlag) (*vi).ClearS();
111  }
112  }
113 
114  for(auto ei = _m->edge.begin(); ei != _m->edge.end(); ++ei)
115  if( !(*ei).IsD() )
116  {
117  if(esH[*ei]) {
118  if(!andFlag) (*ei).SetS();
119  } else {
120  if(!orFlag) (*ei).ClearS();
121  }
122  }
123 
124 
125  for(auto fi = _m->face.begin(); fi != _m->face.end(); ++fi)
126  if( !(*fi).IsD() )
127  {
128  if(fsH[*fi]) {
129  if(!andFlag) (*fi).SetS();
130  } else {
131  if(!orFlag) (*fi).ClearS();
132  }
133  }
134 
135  for (auto ti = _m->tetra.begin(); ti != _m->tetra.end(); ++ti)
136  if (!(*ti).IsD())
137  {
138  if (tsH[*ti]) {
139  if (!andFlag) (*ti).SetS();
140  } else {
141  if (!orFlag) (*ti).ClearS();
142  }
143  }
144 
145  Allocator<ComputeMeshType>::template DeletePerVertexAttribute<bool>(*_m,vsH);
146  Allocator<ComputeMeshType>::template DeletePerEdgeAttribute<bool>(*_m,esH);
147  Allocator<ComputeMeshType>::template DeletePerFaceAttribute<bool>(*_m,fsH);
148  Allocator<ComputeMeshType>::template DeletePerTetraAttribute<bool>(*_m,tsH);
149 
150  vsV.pop_back();
151  esV.pop_back();
152  fsV.pop_back();
153  tsV.pop_back();
154  return true;
155  }
156 
157 private:
158  ComputeMeshType *_m;
159  std::vector<vsHandle> vsV;
160  std::vector<esHandle> esV;
161  std::vector<fsHandle> fsV;
162  std::vector<tsHandle> tsV;
163 
164 };
165 
167 
169 
171 
175 template <class ComputeMeshType>
177 {
178 
179 public:
180 typedef ComputeMeshType MeshType;
181 typedef typename MeshType::ScalarType ScalarType;
182 typedef typename MeshType::VertexType VertexType;
183 typedef typename MeshType::VertexPointer VertexPointer;
184 typedef typename MeshType::VertexIterator VertexIterator;
185 typedef typename MeshType::EdgeIterator EdgeIterator;
186 typedef typename MeshType::FaceType FaceType;
187 typedef typename MeshType::FacePointer FacePointer;
188 typedef typename MeshType::FaceIterator FaceIterator;
189 typedef typename MeshType::TetraType TetraType;
190 typedef typename MeshType::TetraPointer TetraPointer;
191 typedef typename MeshType::TetraIterator TetraIterator;
192 
193 typedef typename vcg::Box3<ScalarType> Box3Type;
194 
196 static size_t VertexAll(MeshType &m)
197 {
198  for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
199  if( !(*vi).IsD() ) (*vi).SetS();
200  return m.vn;
201 }
202 
204 static size_t EdgeAll(MeshType &m)
205 {
206  for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
207  if( !(*ei).IsD() ) (*ei).SetS();
208  return m.fn;
209 }
211 static size_t FaceAll(MeshType &m)
212 {
213  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
214  if( !(*fi).IsD() ) (*fi).SetS();
215  return m.fn;
216 }
217 
219 static size_t TetraAll (MeshType & m)
220 {
221  ForEachTetra(m, [] (TetraType & t) {
222  t.SetS();
223  });
224 
225  return m.tn;
226 }
227 
229 static size_t VertexClear(MeshType &m)
230 {
231  for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
232  if( !(*vi).IsD() ) (*vi).ClearS();
233  return 0;
234 }
235 
237 static size_t EdgeClear(MeshType &m)
238 {
239  for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
240  if( !(*ei).IsD() ) (*ei).ClearS();
241  return 0;
242 }
243 
245 static size_t FaceClear(MeshType &m)
246 {
247  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
248  if( !(*fi).IsD() ) (*fi).ClearS();
249  return 0;
250 }
251 
253 static size_t TetraClear (MeshType & m)
254 {
255  ForEachTetra(m, [] (TetraType & t) {
256  t.ClearS();
257  });
258 
259  return 0;
260 }
261 
263 static void Clear(MeshType &m)
264 {
265  VertexClear(m);
266  EdgeClear(m);
267  FaceClear(m);
268  TetraClear(m);
269 }
270 
272 static size_t FaceCount(MeshType &m)
273 {
274  size_t selCnt=0;
275  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
276  if(!(*fi).IsD() && (*fi).IsS()) ++selCnt;
277  return selCnt;
278 }
279 
281 static size_t EdgeCount(MeshType &m)
282 {
283  size_t selCnt=0;
284  for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
285  if(!(*ei).IsD() && (*ei).IsS()) ++selCnt;
286  return selCnt;
287 }
288 
290 static size_t VertexCount(MeshType &m)
291 {
292  size_t selCnt=0;
293  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
294  if(!(*vi).IsD() && (*vi).IsS()) ++selCnt;
295  return selCnt;
296 }
297 
299 static size_t TetraCount (MeshType & m)
300 {
301  size_t selCnt = 0;
302  ForEachTetra(m, [&selCnt] (TetraType & t) {
303  if (t.IsS())
304  ++selCnt;
305  });
306 
307  return selCnt;
308 }
310 static size_t FaceInvert(MeshType &m)
311 {
312  size_t selCnt=0;
313  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
314  if(!(*fi).IsD())
315  {
316  if((*fi).IsS()) (*fi).ClearS();
317  else {
318  (*fi).SetS();
319  ++selCnt;
320  }
321  }
322  return selCnt;
323 }
324 
326 static size_t EdgeInvert(MeshType &m)
327 {
328  size_t selCnt=0;
329  for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
330  if(!(*ei).IsD())
331  {
332  if((*ei).IsS()) (*ei).ClearS();
333  else {
334  (*ei).SetS();
335  ++selCnt;
336  }
337  }
338  return selCnt;
339 }
340 
342 static size_t VertexInvert(MeshType &m)
343 {
344  size_t selCnt=0;
345  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
346  if(!(*vi).IsD())
347  {
348  if((*vi).IsS()) (*vi).ClearS();
349  else {
350  (*vi).SetS();
351  ++selCnt;
352  }
353  }
354  return selCnt;
355 }
356 
358 static size_t TetraInvert (MeshType & m)
359 {
360  size_t selCnt = 0;
361  ForEachTetra(m, [&selCnt] (TetraType & t) {
362  if (t.IsS())
363  t.ClearS();
364  else
365  {
366  t.SetS();
367  ++selCnt;
368  }
369  });
370 
371  return selCnt;
372 }
373 
374 
376 static size_t VertexFromFaceLoose(MeshType &m, bool preserveSelection=false)
377 {
378  size_t selCnt=0;
379 
380  if(!preserveSelection) VertexClear(m);
381  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
382  if( !(*fi).IsD() && (*fi).IsS())
383  for(int i = 0; i < (*fi).VN(); ++i)
384  if( !(*fi).V(i)->IsS()) { (*fi).V(i)->SetS(); ++selCnt; }
385  return selCnt;
386 }
387 
389 static size_t VertexFromEdgeLoose(MeshType &m, bool preserveSelection=false)
390 {
391  size_t selCnt=0;
392 
393  if(!preserveSelection) VertexClear(m);
394  for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
395  if( !(*ei).IsD() && (*ei).IsS())
396  {
397  if( !(*ei).V(0)->IsS()) { (*ei).V(0)->SetS(); ++selCnt; }
398  if( !(*ei).V(1)->IsS()) { (*ei).V(1)->SetS(); ++selCnt; }
399  }
400  return selCnt;
401 }
402 
404 
406 static size_t VertexFromFaceStrict(MeshType &m, bool preserveSelection=false)
407 {
409  if(preserveSelection) ss.push();
411  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
412  if( !(*fi).IsD() && !(*fi).IsS())
413  for(int i = 0; i < (*fi).VN(); ++i)
414  (*fi).V(i)->ClearS();
415 
416  if(preserveSelection) ss.popOr();
417  return VertexCount(m);
418 }
419 
421 static size_t FaceFromVertexStrict(MeshType &m, bool preserveSelection=false)
422 {
424  if(preserveSelection) ss.push();
425  size_t selCnt=0;
426  FaceClear(m);
427  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
428  if( !(*fi).IsD())
429  {
430  bool selFlag=true;
431  for(int i = 0; i < (*fi).VN(); ++i)
432  if(!(*fi).V(i)->IsS())
433  selFlag =false;
434  if(selFlag)
435  {
436  (*fi).SetS();
437  ++selCnt;
438  }
439  }
440 
441  if(preserveSelection) ss.popOr();
442  return selCnt;
443 }
444 
446 static size_t FaceFromVertexLoose(MeshType &m, bool preserveSelection=false)
447 {
448  size_t selCnt=0;
449  if(!preserveSelection) FaceClear(m);
450  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
451  if( !(*fi).IsD())
452  {
453  bool selVert=false;
454  for(int i = 0; i < (*fi).VN(); ++i)
455  if((*fi).V(i)->IsS())
456  selVert=true;
457 
458  if(selVert) {
459  (*fi).SetS();
460  ++selCnt;
461  }
462  }
463  return selCnt;
464 }
467 static size_t FaceDilate(MeshType &m)
468 {
471 }
472 
475 static size_t FaceErode(MeshType &m)
476 {
479 }
480 
481 
483 static size_t VertexFromBorderFlag(MeshType &m, bool preserveSelection=false)
484 {
485  size_t selCnt=0;
486  if(!preserveSelection) VertexClear(m);
487  for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
488  if( !(*vi).IsD() )
489  {
490  if((*vi).IsB() )
491  {
492  (*vi).SetS();
493  ++selCnt;
494  }
495  }
496  return selCnt;
497 }
498 
500 static size_t FaceFromBorderFlag(MeshType &m, bool preserveSelection=false)
501 {
502  tri::RequireTriangularMesh(m);
503  size_t selCnt=0;
504  if(!preserveSelection) FaceClear(m);
505  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
506  if( !(*fi).IsD() )
507  {
508  bool bordFlag=false;
509  for(int i = 0; i < 3; ++i)
510  if((*fi).IsB(i)) bordFlag=true;
511  if(bordFlag)
512  {
513  (*fi).SetS();
514  ++selCnt;
515  }
516  }
517  return selCnt;
518 }
519 
522 static size_t FaceOutOfRangeEdge(MeshType &m, ScalarType MinEdgeThr, ScalarType MaxEdgeThr=(std::numeric_limits<ScalarType>::max)(), bool preserveSelection=false)
523 {
524  if(!preserveSelection) FaceClear(m);
525  size_t selCnt = 0;
526  MinEdgeThr=MinEdgeThr*MinEdgeThr;
527  MaxEdgeThr=MaxEdgeThr*MaxEdgeThr;
528  for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
529  if(!(*fi).IsD())
530  {
531  for(int i=0;i<(*fi).VN();++i)
532  {
533  const ScalarType squaredEdge=SquaredDistance((*fi).V0(i)->cP(),(*fi).V1(i)->cP());
534  if((squaredEdge<=MinEdgeThr) || (squaredEdge>=MaxEdgeThr) )
535  {
536  selCnt++;
537  (*fi).SetS();
538  break; // skip the rest of the edges of the tri
539  }
540  }
541  }
542  return selCnt;
543 }
544 
546 static size_t FaceConnectedFF(MeshType &m)
547 {
548  // it also assumes that the FF adjacency is well computed.
549  RequireFFAdjacency(m);
551 
552  std::deque<FacePointer> visitStack;
553  size_t selCnt=0;
554  for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
555  if( !(*fi).IsD() && (*fi).IsS() && !(*fi).IsV() )
556  visitStack.push_back(&*fi);
557 
558  while(!visitStack.empty())
559  {
560  FacePointer fp = visitStack.front();
561  visitStack.pop_front();
562  assert(!fp->IsV());
563  fp->SetV();
564  for(int i=0;i<fp->VN();++i) {
565  FacePointer ff = fp->FFp(i);
566  if(! ff->IsS())
567  {
568  ff->SetS();
569  ++selCnt;
570  visitStack.push_back(ff);
571  assert(!ff->IsV());
572  }
573  }
574  }
575  return selCnt;
576 }
578 static size_t FaceFromQualityRange(MeshType &m,float minq, float maxq, bool preserveSelection=false)
579 {
580  size_t selCnt=0;
581  if(!preserveSelection) FaceClear(m);
582  RequirePerFaceQuality(m);
583  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
584  if(!(*fi).IsD())
585  {
586  if( (*fi).Q()>=minq && (*fi).Q()<=maxq )
587  {
588  (*fi).SetS();
589  ++selCnt;
590  }
591  }
592  return selCnt;
593 }
594 
596 static size_t VertexFromQualityRange(MeshType &m,float minq, float maxq, bool preserveSelection=false)
597 {
598  size_t selCnt=0;
599  if(!preserveSelection) VertexClear(m);
600  RequirePerVertexQuality(m);
601  for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
602  if(!(*vi).IsD())
603  {
604  if( (*vi).Q()>=minq && (*vi).Q()<=maxq )
605  {
606  (*vi).SetS();
607  ++selCnt;
608  }
609  }
610  return selCnt;
611 }
612 
614 static size_t VertexInBox( MeshType & m, const Box3Type &bb, bool preserveSelection=false)
615 {
616  if(!preserveSelection) VertexClear(m);
617  int selCnt=0;
618  for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD())
619  {
620  if(bb.IsIn((*vi).cP()) ) {
621  (*vi).SetS();
622  ++selCnt;
623  }
624  }
625  return selCnt;
626 }
627 
631 static size_t VertexCornerBorder(MeshType &m, ScalarType angleRad, bool preserveSelection=false)
632 {
633  if(!preserveSelection) VertexClear(m);
634  SimpleTempData<typename MeshType::VertContainer, ScalarType > angleSumH(m.vert,0);
635  int selCnt=0;
636  for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
637  angleSumH[vi]=0;
638 
639  for(auto fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
640  {
641  for(int i=0;i<(*fi).VN();++i)
642  angleSumH[fi->V(i)] += face::WedgeAngleRad(*fi,i);
643  }
644 
645  for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
646  {
647  if(angleSumH[vi]<angleRad && vi->IsB())
648  {
649  (*vi).SetS();
650  ++selCnt;
651  }
652  }
653  return selCnt;
654 }
655 
656 
657 void VertexNonManifoldEdges(MeshType &m, bool preserveSelection=false)
658 {
659  tri::RequireFFAdjacency(m);
660 
661  if(!preserveSelection) VertexClear(m);
662  for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if (!fi->IsD())
663  {
664  for(int i=0;i<fi->VN();++i)
665  if(!IsManifold(*fi,i)){
666  (*fi).V0(i)->SetS();
667  (*fi).V1(i)->SetS();
668  }
669  }
670 }
671 
672 }; // end class
673 
674 } // End namespace
675 } // End namespace
676 
677 
678 #endif