From 6807df8ea11159ee9159928249404ad67b266a29 Mon Sep 17 00:00:00 2001 From: cignoni Date: Mon, 21 Mar 2011 14:45:38 +0000 Subject: [PATCH] added SelectionStack utility class. --- vcg/complex/trimesh/update/selection.h | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/vcg/complex/trimesh/update/selection.h b/vcg/complex/trimesh/update/selection.h index 492a2007..fc552e9b 100644 --- a/vcg/complex/trimesh/update/selection.h +++ b/vcg/complex/trimesh/update/selection.h @@ -28,6 +28,73 @@ namespace vcg { namespace tri { +/// \ingroup trimesh +/// \brief A stack for saving and restoring selection. +/** + This class is used to save the current selection onto a stack for later use. + \todo it should be generalized to other attributes with a templated approach. +*/ +template +class SelectionStack +{ + typedef typename ComputeMeshType::template PerVertexAttributeHandle< bool > vsHandle; + typedef typename ComputeMeshType::template PerFaceAttributeHandle< bool > fsHandle; + +public: + SelectionStack(ComputeMeshType &m) + { + _m=&m; + } + + bool push() + { + vsHandle vsH = Allocator::template AddPerVertexAttribute< bool >(*_m); + fsHandle fsH = Allocator::template AddPerFaceAttribute< bool > (*_m); + typename ComputeMeshType::VertexIterator vi; + for(vi = _m->vert.begin(); vi != _m->vert.end(); ++vi) + if( !(*vi).IsD() ) vsH[*vi] = (*vi).IsS() ; + + typename ComputeMeshType::FaceIterator fi; + for(fi = _m->face.begin(); fi != _m->face.end(); ++fi) + if( !(*fi).IsD() ) fsH[*fi] = (*fi).IsS() ; + + vsV.push_back(vsH); + fsV.push_back(fsH); + return true; + } + + bool pop() + { + if(vsV.empty()) return false; + vsHandle vsH = vsV.back(); + fsHandle fsH = fsV.back(); + if(! (Allocator::template IsValidHandle(*_m, vsH))) return false; + + typename ComputeMeshType::VertexIterator vi; + for(vi = _m->vert.begin(); vi != _m->vert.end(); ++vi) + if( !(*vi).IsD() ) + if(vsH[*vi]) (*vi).SetS() ; + else (*vi).ClearS() ; + + typename ComputeMeshType::FaceIterator fi; + for(fi = _m->face.begin(); fi != _m->face.end(); ++fi) + if( !(*fi).IsD() ) + if(fsH[*fi]) (*fi).SetS() ; + else (*fi).ClearS() ; + + Allocator::template DeletePerVertexAttribute(*_m,vsH); + Allocator::template DeletePerFaceAttribute(*_m,fsH); + vsV.pop_back(); + fsV.pop_back(); + return true; + } + +private: + ComputeMeshType *_m; + std::vector vsV; + std::vector fsV; + +}; /// \ingroup trimesh