Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __VCG_TRI_UPDATE_SELECTION
00024 #define __VCG_TRI_UPDATE_SELECTION
00025
00026 #include <queue>
00027 #include <vcg/complex/algorithms/update/flag.h>
00028
00029 namespace vcg {
00030 namespace tri {
00033
00037 template <class ComputeMeshType>
00038 class SelectionStack
00039 {
00040 typedef typename ComputeMeshType::template PerVertexAttributeHandle< bool > vsHandle;
00041 typedef typename ComputeMeshType::template PerEdgeAttributeHandle< bool > esHandle;
00042 typedef typename ComputeMeshType::template PerFaceAttributeHandle< bool > fsHandle;
00043
00044 public:
00045 SelectionStack(ComputeMeshType &m)
00046 {
00047 _m=&m;
00048 }
00049
00050 bool push()
00051 {
00052 vsHandle vsH = Allocator<ComputeMeshType>::template AddPerVertexAttribute< bool >(*_m);
00053 esHandle esH = Allocator<ComputeMeshType>::template AddPerEdgeAttribute< bool >(*_m);
00054 fsHandle fsH = Allocator<ComputeMeshType>::template AddPerFaceAttribute< bool > (*_m);
00055 typename ComputeMeshType::VertexIterator vi;
00056 for(vi = _m->vert.begin(); vi != _m->vert.end(); ++vi)
00057 if( !(*vi).IsD() ) vsH[*vi] = (*vi).IsS() ;
00058
00059 typename ComputeMeshType::EdgeIterator ei;
00060 for(ei = _m->edge.begin(); ei != _m->edge.end(); ++ei)
00061 if( !(*ei).IsD() ) esH[*ei] = (*ei).IsS() ;
00062
00063 typename ComputeMeshType::FaceIterator fi;
00064 for(fi = _m->face.begin(); fi != _m->face.end(); ++fi)
00065 if( !(*fi).IsD() ) fsH[*fi] = (*fi).IsS() ;
00066
00067 vsV.push_back(vsH);
00068 esV.push_back(esH);
00069 fsV.push_back(fsH);
00070 return true;
00071 }
00072
00073 bool popOr()
00074 {
00075 return pop(true);
00076 }
00077
00078 bool pop(bool mergeFlag=false)
00079 {
00080 if(vsV.empty()) return false;
00081 vsHandle vsH = vsV.back();
00082 esHandle esH = esV.back();
00083 fsHandle fsH = fsV.back();
00084 if(! (Allocator<ComputeMeshType>::template IsValidHandle(*_m, vsH))) return false;
00085
00086 typename ComputeMeshType::VertexIterator vi;
00087 for(vi = _m->vert.begin(); vi != _m->vert.end(); ++vi)
00088 if( !(*vi).IsD() )
00089 {
00090 if(vsH[*vi])
00091 (*vi).SetS();
00092 else
00093 if(!mergeFlag)
00094 (*vi).ClearS();
00095 }
00096
00097 typename ComputeMeshType::EdgeIterator ei;
00098 for(ei = _m->edge.begin(); ei != _m->edge.end(); ++ei)
00099 if( !(*ei).IsD() )
00100 {
00101 if(esH[*ei])
00102 (*ei).SetS();
00103 else
00104 if(!mergeFlag)
00105 (*ei).ClearS();
00106 }
00107 typename ComputeMeshType::FaceIterator fi;
00108 for(fi = _m->face.begin(); fi != _m->face.end(); ++fi)
00109 if( !(*fi).IsD() )
00110 {
00111 if(fsH[*fi])
00112 (*fi).SetS();
00113 else
00114 if(!mergeFlag)
00115 (*fi).ClearS();
00116 }
00117
00118 Allocator<ComputeMeshType>::template DeletePerVertexAttribute<bool>(*_m,vsH);
00119 Allocator<ComputeMeshType>::template DeletePerEdgeAttribute<bool>(*_m,esH);
00120 Allocator<ComputeMeshType>::template DeletePerFaceAttribute<bool>(*_m,fsH);
00121 vsV.pop_back();
00122 esV.pop_back();
00123 fsV.pop_back();
00124 return true;
00125 }
00126
00127 private:
00128 ComputeMeshType *_m;
00129 std::vector<vsHandle> vsV;
00130 std::vector<esHandle> esV;
00131 std::vector<fsHandle> fsV;
00132 };
00133
00135
00137
00139
00143 template <class ComputeMeshType>
00144 class UpdateSelection
00145 {
00146
00147 public:
00148 typedef ComputeMeshType MeshType;
00149 typedef typename MeshType::ScalarType ScalarType;
00150 typedef typename MeshType::VertexType VertexType;
00151 typedef typename MeshType::VertexPointer VertexPointer;
00152 typedef typename MeshType::VertexIterator VertexIterator;
00153 typedef typename MeshType::EdgeIterator EdgeIterator;
00154 typedef typename MeshType::FaceType FaceType;
00155 typedef typename MeshType::FacePointer FacePointer;
00156 typedef typename MeshType::FaceIterator FaceIterator;
00157 typedef typename vcg::Box3<ScalarType> Box3Type;
00158
00160 static size_t VertexAll(MeshType &m)
00161 {
00162 for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00163 if( !(*vi).IsD() ) (*vi).SetS();
00164 return m.vn;
00165 }
00166
00168 static size_t EdgeAll(MeshType &m)
00169 {
00170 for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
00171 if( !(*ei).IsD() ) (*ei).SetS();
00172 return m.fn;
00173 }
00175 static size_t FaceAll(MeshType &m)
00176 {
00177 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00178 if( !(*fi).IsD() ) (*fi).SetS();
00179 return m.fn;
00180 }
00181
00183 static size_t VertexClear(MeshType &m)
00184 {
00185 for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00186 if( !(*vi).IsD() ) (*vi).ClearS();
00187 return 0;
00188 }
00189
00191 static size_t EdgeClear(MeshType &m)
00192 {
00193 for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
00194 if( !(*ei).IsD() ) (*ei).ClearS();
00195 return 0;
00196 }
00197
00199 static size_t FaceClear(MeshType &m)
00200 {
00201 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00202 if( !(*fi).IsD() ) (*fi).ClearS();
00203 return 0;
00204 }
00205
00207 static void Clear(MeshType &m)
00208 {
00209 VertexClear(m);
00210 EdgeClear(m);
00211 FaceClear(m);
00212 }
00213
00215 static size_t FaceCount(MeshType &m)
00216 {
00217 size_t selCnt=0;
00218 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00219 if(!(*fi).IsD() && (*fi).IsS()) ++selCnt;
00220 return selCnt;
00221 }
00222
00224 static size_t EdgeCount(MeshType &m)
00225 {
00226 size_t selCnt=0;
00227 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00228 if(!(*ei).IsD() && (*ei).IsS()) ++selCnt;
00229 return selCnt;
00230 }
00231
00233 static size_t VertexCount(MeshType &m)
00234 {
00235 size_t selCnt=0;
00236 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00237 if(!(*vi).IsD() && (*vi).IsS()) ++selCnt;
00238 return selCnt;
00239 }
00240
00242 static size_t FaceInvert(MeshType &m)
00243 {
00244 size_t selCnt=0;
00245 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00246 if(!(*fi).IsD())
00247 {
00248 if((*fi).IsS()) (*fi).ClearS();
00249 else {
00250 (*fi).SetS();
00251 ++selCnt;
00252 }
00253 }
00254 return selCnt;
00255 }
00256
00258 static size_t EdgeInvert(MeshType &m)
00259 {
00260 size_t selCnt=0;
00261 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00262 if(!(*ei).IsD())
00263 {
00264 if((*ei).IsS()) (*ei).ClearS();
00265 else {
00266 (*ei).SetS();
00267 ++selCnt;
00268 }
00269 }
00270 return selCnt;
00271 }
00272
00274 static size_t VertexInvert(MeshType &m)
00275 {
00276 size_t selCnt=0;
00277 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00278 if(!(*vi).IsD())
00279 {
00280 if((*vi).IsS()) (*vi).ClearS();
00281 else {
00282 (*vi).SetS();
00283 ++selCnt;
00284 }
00285 }
00286 return selCnt;
00287 }
00288
00290 static size_t VertexFromFaceLoose(MeshType &m, bool preserveSelection=false)
00291 {
00292 size_t selCnt=0;
00293
00294 if(!preserveSelection) VertexClear(m);
00295 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00296 if( !(*fi).IsD() && (*fi).IsS())
00297 for(int i = 0; i < (*fi).VN(); ++i)
00298 if( !(*fi).V(i)->IsS()) { (*fi).V(i)->SetS(); ++selCnt; }
00299 return selCnt;
00300 }
00301
00303 static size_t VertexFromEdgeLoose(MeshType &m, bool preserveSelection=false)
00304 {
00305 size_t selCnt=0;
00306
00307 if(!preserveSelection) VertexClear(m);
00308 for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
00309 if( !(*ei).IsD() && (*ei).IsS())
00310 {
00311 if( !(*ei).V(0)->IsS()) { (*ei).V(0)->SetS(); ++selCnt; }
00312 if( !(*ei).V(1)->IsS()) { (*ei).V(1)->SetS(); ++selCnt; }
00313 }
00314 return selCnt;
00315 }
00316
00318
00320 static size_t VertexFromFaceStrict(MeshType &m, bool preserveSelection=false)
00321 {
00322 SelectionStack<MeshType> ss(m);
00323 if(preserveSelection) ss.push();
00324 VertexFromFaceLoose(m);
00325 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00326 if( !(*fi).IsD() && !(*fi).IsS())
00327 for(int i = 0; i < (*fi).VN(); ++i)
00328 (*fi).V(i)->ClearS();
00329
00330 if(preserveSelection) ss.popOr();
00331 return VertexCount(m);
00332 }
00333
00335 static size_t FaceFromVertexStrict(MeshType &m, bool preserveSelection=false)
00336 {
00337 SelectionStack<MeshType> ss(m);
00338 if(preserveSelection) ss.push();
00339 size_t selCnt=0;
00340 FaceClear(m);
00341 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00342 if( !(*fi).IsD())
00343 {
00344 bool selFlag=true;
00345 for(int i = 0; i < (*fi).VN(); ++i)
00346 if(!(*fi).V(i)->IsS())
00347 selFlag =false;
00348 if(selFlag)
00349 {
00350 (*fi).SetS();
00351 ++selCnt;
00352 }
00353 }
00354
00355 if(preserveSelection) ss.popOr();
00356 return selCnt;
00357 }
00358
00360 static size_t FaceFromVertexLoose(MeshType &m, bool preserveSelection=false)
00361 {
00362 size_t selCnt=0;
00363 if(!preserveSelection) FaceClear(m);
00364 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00365 if( !(*fi).IsD())
00366 {
00367 bool selVert=false;
00368 for(int i = 0; i < (*fi).VN(); ++i)
00369 if((*fi).V(i)->IsS())
00370 selVert=true;
00371
00372 if(selVert) {
00373 (*fi).SetS();
00374 ++selCnt;
00375 }
00376 }
00377 return selCnt;
00378 }
00379
00381 static size_t VertexFromBorderFlag(MeshType &m, bool preserveSelection=false)
00382 {
00383 size_t selCnt=0;
00384 if(!preserveSelection) VertexClear(m);
00385 for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00386 if( !(*vi).IsD() )
00387 {
00388 if((*vi).IsB() )
00389 {
00390 (*vi).SetS();
00391 ++selCnt;
00392 }
00393 }
00394 return selCnt;
00395 }
00396
00398 static size_t FaceFromBorderFlag(MeshType &m, bool preserveSelection=false)
00399 {
00400 tri::RequireTriangularMesh(m);
00401 size_t selCnt=0;
00402 if(!preserveSelection) FaceClear(m);
00403 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00404 if( !(*fi).IsD() )
00405 {
00406 bool bordFlag=false;
00407 for(int i = 0; i < 3; ++i)
00408 if((*fi).IsB(i)) bordFlag=true;
00409 if(bordFlag)
00410 {
00411 (*fi).SetS();
00412 ++selCnt;
00413 }
00414 }
00415 return selCnt;
00416 }
00417
00420 static size_t FaceOutOfRangeEdge(MeshType &m, ScalarType MinEdgeThr, ScalarType MaxEdgeThr=(std::numeric_limits<ScalarType>::max)(), bool preserveSelection=false)
00421 {
00422 if(!preserveSelection) FaceClear(m);
00423 size_t selCnt = 0;
00424 MinEdgeThr=MinEdgeThr*MinEdgeThr;
00425 MaxEdgeThr=MaxEdgeThr*MaxEdgeThr;
00426 for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
00427 if(!(*fi).IsD())
00428 {
00429 for(int i=0;i<(*fi).VN();++i)
00430 {
00431 const ScalarType squaredEdge=SquaredDistance((*fi).V0(i)->cP(),(*fi).V1(i)->cP());
00432 if((squaredEdge<=MinEdgeThr) || (squaredEdge>=MaxEdgeThr) )
00433 {
00434 selCnt++;
00435 (*fi).SetS();
00436 break;
00437 }
00438 }
00439 }
00440 return selCnt;
00441 }
00442
00444 static size_t FaceConnectedFF(MeshType &m, bool preserveSelection=false)
00445 {
00446 if(!preserveSelection) FaceClear(m);
00447
00448 RequireFFAdjacency(m);
00449 UpdateFlags<MeshType>::FaceClearV(m);
00450
00451 std::deque<FacePointer> visitStack;
00452 size_t selCnt=0;
00453 for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00454 if( !(*fi).IsD() && (*fi).IsS() && !(*fi).IsV() )
00455 visitStack.push_back(&*fi);
00456
00457 while(!visitStack.empty())
00458 {
00459 FacePointer fp = visitStack.front();
00460 visitStack.pop_front();
00461 assert(!fp->IsV());
00462 fp->SetV();
00463 for(int i=0;i<fp->VN();++i) {
00464 FacePointer ff = fp->FFp(i);
00465 if(! ff->IsS())
00466 {
00467 ff->SetS();
00468 ++selCnt;
00469 visitStack.push_back(ff);
00470 assert(!ff->IsV());
00471 }
00472 }
00473 }
00474 return selCnt;
00475 }
00477 static size_t FaceFromQualityRange(MeshType &m,float minq, float maxq, bool preserveSelection=false)
00478 {
00479 size_t selCnt=0;
00480 if(!preserveSelection) FaceClear(m);
00481 RequirePerFaceQuality(m);
00482 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00483 if(!(*fi).IsD())
00484 {
00485 if( (*fi).Q()>=minq && (*fi).Q()<=maxq )
00486 {
00487 (*fi).SetS();
00488 ++selCnt;
00489 }
00490 }
00491 return selCnt;
00492 }
00493
00495 static size_t VertexFromQualityRange(MeshType &m,float minq, float maxq, bool preserveSelection=false)
00496 {
00497 size_t selCnt=0;
00498 if(!preserveSelection) VertexClear(m);
00499 RequirePerVertexQuality(m);
00500 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00501 if(!(*vi).IsD())
00502 {
00503 if( (*vi).Q()>=minq && (*vi).Q()<=maxq )
00504 {
00505 (*vi).SetS();
00506 ++selCnt;
00507 }
00508 }
00509 return selCnt;
00510 }
00511
00513 static int VertexInBox( MeshType & m, const Box3Type &bb, bool preserveSelection=false)
00514 {
00515 if(!preserveSelection) VertexClear(m);
00516 int selCnt=0;
00517 for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD())
00518 {
00519 if(bb.IsIn((*vi).cP()) ) {
00520 (*vi).SetS();
00521 ++selCnt;
00522 }
00523 }
00524 return selCnt;
00525 }
00526
00527
00528 void VertexNonManifoldEdges(MeshType &m, bool preserveSelection=false)
00529 {
00530 assert(HasFFTopology(m));
00531
00532 if(!preserveSelection) VertexClear(m);
00533 for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if (!fi->IsD())
00534 {
00535 for(int i=0;i<fi->VN();++i)
00536 if(!IsManifold(*fi,i)){
00537 (*fi).V0(i)->SetS();
00538 (*fi).V1(i)->SetS();
00539 }
00540 }
00541 }
00542
00543 };
00544
00545 }
00546 }
00547
00548
00549 #endif