selection.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
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; // skip the rest of the edges of the tri
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   // it also assumes that the FF adjacency is well computed.
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 }; // end class
00544 
00545 }       // End namespace
00546 }       // End namespace
00547 
00548 
00549 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:35:14