From 666040bcf5d2a950c16b92508a93dccdec01a10d Mon Sep 17 00:00:00 2001 From: ganovelli Date: Thu, 15 May 2008 16:32:27 +0000 Subject: [PATCH] PerVertexAttribute and PerFaceAttribute added to Trimesh --- vcg/complex/trimesh/allocate.h | 166 +++++++++++++++++++++++++++++++++ vcg/complex/trimesh/base.h | 54 +++++++++++ 2 files changed, 220 insertions(+) diff --git a/vcg/complex/trimesh/allocate.h b/vcg/complex/trimesh/allocate.h index 96ced512..29c9bced 100644 --- a/vcg/complex/trimesh/allocate.h +++ b/vcg/complex/trimesh/allocate.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.43 2008/04/18 17:45:23 cignoni +fast return for compacting functions if no compacting is needed + Revision 1.42 2008/04/10 09:18:57 cignoni moved Index function from append to the allocate @@ -167,6 +170,7 @@ Initial commit #include #include +#include namespace vcg { namespace tri { @@ -192,6 +196,20 @@ namespace vcg { void ReorderVert( std::vector &newVertIndex, std::vector &vert) {} + template + void ReorderAttribute(ATTR_CONT &c,std::vector & newVertIndex, MeshType &m){ + typename std::set::iterator ai; + for(ai = c.begin(); ai != c.end(); ++ai) + ((typename MeshType::HandlesWrapper)(*ai)).Reorder(newVertIndex); + } + + template + void ResizeAttribute(ATTR_CONT &c,const int & sz, MeshType &m){ + typename std::set::iterator ai; + for(ai =c.begin(); ai != c.end(); ++ai) + ((typename MeshType::HandlesWrapper)(*ai)).Resize(m.vn); + } + /*@{*/ /// Class to safely add vertexes and faces to a mesh updating all the involved pointers. /// It provides static memeber to add either vertex or faces to a trimesh. @@ -204,9 +222,15 @@ namespace vcg { typedef typename MeshType::VertexType VertexType; typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexIterator VertexIterator; + typedef typename MeshType::VertContainer VertContainer; typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FacePointer FacePointer; typedef typename MeshType::FaceIterator FaceIterator; + typedef typename MeshType::FaceContainer FaceContainer; + typedef typename MeshType::HandlesWrapper HandlesWrapper; + typedef typename std::set::iterator HandlesIterator; + typedef typename std::set::const_iterator HandlesConstIterator; + typedef typename std::set::iterator HWIte; /** This class is used when allocating new vertexes and faces to update the pointers that can be changed when resizing the involved vectors of vertex or faces. @@ -255,6 +279,10 @@ namespace vcg { m.vert.resize(m.vert.size()+n); m.vn+=n; + typename std::set::iterator ai; + for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai) + ((typename MeshType::HandlesWrapper)(*ai)).Resize(m.vert.size()); + pu.newBase = &*m.vert.begin(); pu.newEnd = &m.vert.back()+1; if(pu.NeedUpdate()) @@ -268,6 +296,7 @@ namespace vcg { if ((*fi).cV(2)!=0) pu.Update((*fi).V(2)); } + // e poiche' lo spazio e' cambiato si ricalcola anche last da zero } @@ -330,6 +359,10 @@ namespace vcg { m.face.resize(m.face.size()+n); m.fn+=n; + typename std::set::iterator ai; + for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai) + ((typename MeshType::HandlesWrapper)(*ai)).Resize(m.face.size()); + pu.newBase = &*m.face.begin(); pu.newEnd = &m.face.back()+1; @@ -428,7 +461,14 @@ namespace vcg { // for the default std::vector no work is needed (some work is typically needed for the OCF stuff) ReorderVert(newVertIndex,m.vert); + // reorder the optional atttributes in m.vert_attr to reflect the changes + ReorderAttribute(m.vert_attr,newVertIndex,m); + m.vert.resize(m.vn); + + // resize the optional atttributes in m.vert_attr to reflect the changes + ResizeAttribute(m.vert_attr,m.vn,m); + FaceIterator fi; VertexPointer vbase=&m.vert[0]; for(fi=m.face.begin();fi!=m.face.end();++fi) @@ -475,6 +515,9 @@ namespace vcg { // for the default std::vector no work is needed (some work is typically needed for the OCF stuff) ReorderFace(newFaceIndex,m.face); + // reorder the optional atttributes in m.face_attr to reflect the changes + ReorderAttribute(m.face_attr,newFaceIndex,m); + // Loop on the vertices to correct VF relation VertexIterator vi; FacePointer fbase=&m.face[0]; @@ -492,6 +535,9 @@ namespace vcg { // Loop on the faces to correct VF and FF relations m.face.resize(m.fn); + // resize the optional atttributes in m.face_attr to reflect the changes + ResizeAttribute(m.face_attr,m.vn,m); + FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) @@ -515,6 +561,126 @@ namespace vcg { } } +public: + /// Per Vertex Attributes + template + static + typename MeshType::template PerVertexAttributeHandle + AddPerVertexAttribute( MeshType & m, std::string name){ + HWIte i; + HandlesWrapper h; + h._name = name; + if(!name.empty()){ + i = m.vert_attr.find(h); + assert(i ==m.vert_attr.end() );// an attribute with this name exists + } + h._handle = (void*) new SimpleTempData(m.vert); + std::pair < HandlesIterator , bool> res = m.vert_attr.insert(h); + return typename MeshType::template PerVertexAttributeHandle(res.first->_handle); + } + + template + static + typename MeshType::template PerVertexAttributeHandle + AddPerVertexAttribute( MeshType & m){ + return AddPerVertexAttribute(m,std::string("")); + } + + template + static + typename MeshType::template PerVertexAttributeHandle + GetPerVertexAttribute( const MeshType & m, const std::string & name){ + assert(!name.empty()); + HandlesWrapper h1; h1._name = name; + typename std::set ::const_iterator i; + + i =m.vert_attr.find(h1); + if(i!=m.vert_attr.end()) + return typename MeshType::template PerVertexAttributeHandle((*i)._handle); + else + return typename MeshType:: template PerVertexAttributeHandle(NULL); + } + + template + static + void + DeletePerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle & h){ + typename std::set ::iterator i; + for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i) + if( (*i)._handle == h._handle ){ + delete ((SimpleTempData*)(*i)._handle); + m.vert_attr.erase(i); + return;} + assert(0); + } + + template + static + void DeletePerVertexAttribute( MeshType & m, std::string name){ + HandlesIterator i; + HandlesWrapper h1; h1._name = name; + i = m.vert_attr.find(h1); + assert(i!=m.vert_attr.end()); + delete ((SimpleTempData*)(*i)._handle); + m.vert_attr.erase(i); + } + + /// Per Face Attributes + template + static + typename MeshType::template PerFaceAttributeHandle + AddPerFaceAttribute( MeshType & m, std::string name){ + HWIte i; + HandlesWrapper h; + h._name = name; + if(!name.empty()){ + i = m.face_attr.find(h); + assert(i ==m.face_attr.end() );// an attribute with this name exists + } + h._handle = (void*) new SimpleTempData(m.face); + std::pair < HandlesIterator , bool> res = m.face_attr.insert(h); + return typename MeshType::template PerFaceAttributeHandle(res.first->_handle); + } + + template + static + typename MeshType::template PerFaceAttributeHandle + GetPerFaceAttribute( const MeshType & m, const std::string & name){ + assert(!name.empty()); + HandlesWrapper h1; h1._name = name; + typename std::set ::const_iterator i; + + i =m.face_attr.find(h1); + if(i!=m.face_attr.end()) + return typename MeshType::template PerFaceAttributeHandle((*i)._handle); + else + return typename MeshType:: template PerFaceAttributeHandle(NULL); + } + + template + static + void + DeletePerFaceAttribute( MeshType & m,typename MeshType::template PerFaceAttributeHandle & h){ + typename std::set ::iterator i; + for( i = m.face_attr.begin(); i != m.face_attr.end(); ++i) + if( (*i)._handle == h._handle ){ + delete ((SimpleTempData*)(*i)._handle); + m.face_attr.erase(i); + return;} + assert(0); + } + + template + static + void DeletePerFaceAttribute( MeshType & m, std::string name){ + HandlesIterator i; + HandlesWrapper h1; h1._name = name; + i = m.face_attr.find(h1); + assert(i!=m.face_attr.end()); + delete ((SimpleTempData*)(*i)._handle); + m.face_attr.erase(i); + } + }; // end class diff --git a/vcg/complex/trimesh/base.h b/vcg/complex/trimesh/base.h index dcbf583c..a900817c 100644 --- a/vcg/complex/trimesh/base.h +++ b/vcg/complex/trimesh/base.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.32 2008/04/15 10:34:07 cignoni +added HasPerVertexTexCoord ( mesh ) + Revision 1.31 2008/02/21 17:27:06 cignoni Added HasPerVertexColor static function @@ -126,10 +129,13 @@ Initial commit #include #include #include +#include #include #include #include +#include + /* People should subclass his vertex class from these one... */ @@ -184,6 +190,36 @@ class TriMesh{ // std::vector normalmaps; + class HandlesWrapper{ + public: + void * _handle; std::string _name; + void Resize(const int & sz){((SimpleTempDataBase*)_handle)->Resize(sz);} + void Reorder(std::vector & newVertIndex){((SimpleTempDataBase*)_handle)->Reorder(newVertIndex);} + const bool operator<(const HandlesWrapper b) const { return(_name.empty()&&b._name.empty())?(_handle < b._handle):( _name < b._name);} + }; + + template + class PerVertexAttributeHandle{ + public: + PerVertexAttributeHandle( void *ah):_handle ( (SimpleTempData *)ah ){} + SimpleTempData * _handle; + template + ATTR_TYPE & operator [](const RefType & i){return (*_handle)[i];} + }; + + template + class PerFaceAttributeHandle{ + public: + PerFaceAttributeHandle(void *ah):_handle ( (SimpleTempData *)ah ){} + SimpleTempData * _handle; + template + ATTR_TYPE & operator [](const RefType & i){return (*_handle)[i];} + }; + + + std::set< HandlesWrapper> vert_attr; + std::set< HandlesWrapper> face_attr; + /// La camera Camera camera; // intrinsic Shot shot; // extrinsic @@ -389,6 +425,24 @@ bool HasVFAdjacency (const TriMesh < VertContainerType , FaceContainerType> & /* assert(FaceContainerType::value_type::HasVFAdjacency() == VertContainerType::value_type::HasVFAdjacency()); return FaceContainerType::value_type::HasVFAdjacency(); } + +template +bool HasPerVertexAttribute(const MESH_TYPE &m, std::string name){ + typename std::set< typename MESH_TYPE::HandlesWrapper>::const_iterator ai; + typename MESH_TYPE::HandlesWrapper h; + h._name = name; + ai = m.vert_attr.find(h); + return (ai!= m.vert_attr.end() ) ; +} +template +bool HasPerFaceAttribute(const MESH_TYPE &m, std::string name){ + typename std::set< typename MESH_TYPE::HandlesWrapper>::const_iterator ai; + typename MESH_TYPE::HandlesWrapper h; + h._name = name; + ai = m.face_attr.find(h); + return (ai!= m.face_attr.end() ) ; +} + /*@}*/ /*@}*/ } // end namespace