diff --git a/vcg/complex/trimesh/allocate.h b/vcg/complex/trimesh/allocate.h index 9e4a0ccc..9170e046 100644 --- a/vcg/complex/trimesh/allocate.h +++ b/vcg/complex/trimesh/allocate.h @@ -201,16 +201,16 @@ namespace vcg { template void ReorderAttribute(ATTR_CONT &c,std::vector & newVertIndex, MeshType &m){ - typename std::set::iterator ai; + typename std::set::iterator ai; for(ai = c.begin(); ai != c.end(); ++ai) - ((typename MeshType::HandlesWrapper)(*ai)).Reorder(newVertIndex); + ((typename MeshType::PointerToAttribute)(*ai)).Reorder(newVertIndex); } template void ResizeAttribute(ATTR_CONT &c,const int & sz, MeshType &m){ - typename std::set::iterator ai; + typename std::set::iterator ai; for(ai =c.begin(); ai != c.end(); ++ai) - ((typename MeshType::HandlesWrapper)(*ai)).Resize(m.vn); + ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.vn); } /*@{*/ @@ -236,10 +236,10 @@ namespace vcg { 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; + typedef typename MeshType::PointerToAttribute PtrToAttr; + typedef typename std::set::iterator AttrIterator; + typedef typename std::set::const_iterator AttrConstIterator; + typedef typename std::set::iterator PAIte; /** 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. @@ -290,9 +290,9 @@ namespace vcg { m.vert.resize(m.vert.size()+n); m.vn+=n; - typename std::set::iterator ai; + 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()); + ((PtrToAttr)(*ai)).Resize(m.vert.size()); pu.newBase = &*m.vert.begin(); pu.newEnd = &m.vert.back()+1; @@ -365,9 +365,9 @@ namespace vcg { m.edge.resize(m.edge.size()+n); m.en+=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()); + typename std::set::iterator ai; + for(ai = m.edge_attr.begin(); ai != m.edge_attr.end(); ++ai) + ((typename MeshType::PtrToAttr)(*ai)).Resize(m.edge.size()); pu.newBase = &*m.edge.begin(); pu.newEnd = &m.edge.back()+1; @@ -478,9 +478,9 @@ namespace vcg { m.fn+=n; - typename std::set::iterator ai; + 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()); + ((PtrToAttr)(*ai)).Resize(m.face.size()); pu.newBase = &*m.face.begin(); pu.newEnd = &m.face.back()+1; @@ -708,7 +708,7 @@ public: static bool IsValidHandle( MeshType & m, const typename MeshType::template PerVertexAttributeHandle & a){ if(a._handle == NULL) return false; - for(HandlesIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i) + for(AttrIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i) if ( (*i).n_attr == a.n_attr ) return true; return false; } @@ -717,17 +717,19 @@ public: static typename MeshType::template PerVertexAttributeHandle AddPerVertexAttribute( MeshType & m, std::string name){ - HWIte i; - HandlesWrapper h; + PAIte i; + PtrToAttr 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._sizeof = sizeof(ATTR_TYPE); + h._padding = 0; h._handle = (void*) new SimpleTempData(m.vert); m.attrn++; h.n_attr = m.attrn; - std::pair < HandlesIterator , bool> res = m.vert_attr.insert(h); + std::pair < AttrIterator , bool> res = m.vert_attr.insert(h); return typename MeshType::template PerVertexAttributeHandle(res.first->_handle,res.first->n_attr ); } @@ -741,23 +743,35 @@ public: template static typename MeshType::template PerVertexAttributeHandle - GetPerVertexAttribute( const MeshType & m, const std::string & name){ + GetPerVertexAttribute( MeshType & m, const std::string & name){ assert(!name.empty()); - HandlesWrapper h1; h1._name = name; - typename std::set ::const_iterator i; + PtrToAttr h1; h1._name = name; + typename std::set :: iterator i; i =m.vert_attr.find(h1); - if(i!=m.vert_attr.end()) - return typename MeshType::template PerVertexAttributeHandle((*i)._handle,(*i).n_attr); + if(i!=m.vert_attr.end()){ + if( (*i)._padding != 0 ){ + PtrToAttr attr = (*i); // copy the PointerToAttribute + m.vert_attr.erase(i); // remove it from the set + FixPaddedPerVertexAttribute(m,attr); + std::pair new_i = m.vert_attr.insert(attr); // insert the modified PointerToAttribute + assert(new_i.second); + i = new_i.first; + } + + return typename MeshType::template PerVertexAttributeHandle((*i)._handle,(*i).n_attr); + + } else return typename MeshType:: template PerVertexAttributeHandle(NULL,0); + } template static void DeletePerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle & h){ - typename std::set ::iterator i; + 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); @@ -768,20 +782,22 @@ public: static void DeletePerVertexAttribute( MeshType & m, std::string name){ - HandlesIterator i; - HandlesWrapper h1; h1._name = name; + AttrIterator i; + PtrToAttr h1; h1._name = name; i = m.vert_attr.find(h1); assert(i!=m.vert_attr.end()); delete ((SimpleTempDataBase*)(*i)._handle); m.vert_attr.erase(i); } + + /// Per Edge Attributes template static bool IsValidHandle( MeshType & m, const typename MeshType::template PerEdgeAttributeHandle & a){ if(a._handle == NULL) return false; - for(HandlesIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i) + for(AttrIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i) if ( (*i).n_attr == a.n_attr ) return true; return false; } @@ -790,8 +806,8 @@ public: static typename MeshType::template PerEdgeAttributeHandle AddPerEdgeAttribute( MeshType & m, std::string name){ - HWIte i; - HandlesWrapper h; + PAIte i; + PtrToAttr h; h._name = name; if(!name.empty()){ i = m.edge_attr.find(h); @@ -800,7 +816,7 @@ public: h._handle = (void*) new SimpleTempData(m.edge); m.attrn++; h.n_attr = m.attrn; - std::pair < HandlesIterator , bool> res = m.edge_attr.insert(h); + std::pair < AttrIterator , bool> res = m.edge_attr.insert(h); return typename MeshType::template PerEdgeAttributeHandle(res.first->_handle,res.first->n_attr); } @@ -816,8 +832,8 @@ public: typename MeshType::template PerEdgeAttributeHandle GetPerEdgeAttribute( const MeshType & m, const std::string & name){ assert(!name.empty()); - HandlesWrapper h1; h1._name = name; - typename std::set ::const_iterator i; + PtrToAttr h1; h1._name = name; + typename std::set ::const_iterator i; i =m.edge_attr.find(h1); if(i!=m.edge_attr.end()) @@ -830,7 +846,7 @@ public: static void DeletePerEdgeAttribute( MeshType & m,typename MeshType::template PerEdgeAttributeHandle & h){ - typename std::set ::iterator i; + typename std::set ::iterator i; for( i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i) if( (*i)._handle == h._handle ){ delete ((SimpleTempData*)(*i)._handle); @@ -841,8 +857,8 @@ public: static void DeletePerEdgeAttribute( MeshType & m, std::string name){ - HandlesIterator i; - HandlesWrapper h1; h1._name = name; + AttrIterator i; + PtrToAttr h1; h1._name = name; i = m.edge_attr.find(h1); assert(i!=m.edge_attr.end()); delete ((SimpleTempDataBase*)(*i)._handle); @@ -854,7 +870,7 @@ public: static bool IsValidHandle( MeshType & m, const typename MeshType::template PerFaceAttributeHandle & a){ if(a._handle == NULL) return false; - for(HandlesIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i) + for(AttrIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i) if ( (*i).n_attr == a.n_attr ) return true; return false; } @@ -863,8 +879,8 @@ public: static typename MeshType::template PerFaceAttributeHandle AddPerFaceAttribute( MeshType & m, std::string name){ - HWIte i; - HandlesWrapper h; + PAIte i; + PtrToAttr h; h._name = name; if(!name.empty()){ i = m.face_attr.find(h); @@ -873,7 +889,7 @@ public: h._handle = (void*) new SimpleTempData(m.face); m.attrn++; h.n_attr = m.attrn; - std::pair < HandlesIterator , bool> res = m.face_attr.insert(h); + std::pair < AttrIterator , bool> res = m.face_attr.insert(h); return typename MeshType::template PerFaceAttributeHandle(res.first->_handle,res.first->n_attr); } @@ -889,8 +905,8 @@ public: 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; + PtrToAttr h1; h1._name = name; + typename std::set ::const_iterator i; i =m.face_attr.find(h1); if(i!=m.face_attr.end()) @@ -903,7 +919,7 @@ public: static void DeletePerFaceAttribute( MeshType & m,typename MeshType::template PerFaceAttributeHandle & h){ - typename std::set ::iterator i; + 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); @@ -914,8 +930,8 @@ public: static void DeletePerFaceAttribute( MeshType & m, std::string name){ - HandlesIterator i; - HandlesWrapper h1; h1._name = name; + AttrIterator i; + PtrToAttr h1; h1._name = name; i = m.face_attr.find(h1); assert(i!=m.face_attr.end()); delete ((SimpleTempDataBase*)(*i)._handle); @@ -927,7 +943,7 @@ public: static bool IsValidHandle( MeshType & m, const typename MeshType::template PerMeshAttributeHandle & a){ if(a._handle == NULL) return false; - for(HandlesIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i) + for(AttrIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i) if ( (*i).n_attr == a.n_attr ) return true; return false; } @@ -936,8 +952,8 @@ public: static typename MeshType::template PerMeshAttributeHandle AddPerMeshAttribute( MeshType & m, std::string name){ - HWIte i; - HandlesWrapper h; + PAIte i; + PtrToAttr h; h._name = name; if(!name.empty()){ i = m.mesh_attr.find(h); @@ -946,7 +962,7 @@ public: h._handle = (void*) new Attribute(); m.attrn++; h.n_attr = m.attrn; - std::pair < HandlesIterator , bool> res = m.mesh_attr.insert(h); + std::pair < AttrIterator , bool> res = m.mesh_attr.insert(h); return typename MeshType::template PerMeshAttributeHandle(res.first->_handle,res.first->n_attr); } @@ -955,8 +971,8 @@ public: typename MeshType::template PerMeshAttributeHandle GetPerMeshAttribute( const MeshType & m, const std::string & name){ assert(!name.empty()); - HandlesWrapper h1; h1._name = name; - typename std::set ::const_iterator i; + PtrToAttr h1; h1._name = name; + typename std::set ::const_iterator i; i =m.mesh_attr.find(h1); if(i!=m.mesh_attr.end()) @@ -969,7 +985,7 @@ public: static void DeletePerMeshAttribute( MeshType & m,typename MeshType::template PerMeshAttributeHandle & h){ - typename std::set ::iterator i; + typename std::set ::iterator i; for( i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i) if( (*i)._handle == h._handle ){ delete (( Attribute *)(*i)._handle); @@ -980,13 +996,39 @@ public: static void DeletePerMeshAttribute( MeshType & m, std::string name){ - HandlesIterator i; - HandlesWrapper h1; h1._name = name; + AttrIterator i; + PtrToAttr h1; h1._name = name; i = m.mesh_attr.find(h1); assert(i!=m.mesh_attr.end()); delete ((AttributeBase *)(*i)._handle); m.mesh_attr.erase(i); } + + template + static + void FixPaddedPerVertexAttribute ( MeshType & m,PtrToAttr & pa){ + + // create the container of the right type + SimpleTempData* _handle = new SimpleTempData(m.vert); + + // copy the padded container in the new one + _handle->Resize(m.vert.size()); + for(int i = 0; i < m.vert.size(); ++i){ + ATTR_TYPE * dest = &(*_handle)[i]; + char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); + memcpy((void*)dest , + (void*) &(ptr[i * pa._sizeof + pa._padding]) ,sizeof(ATTR_TYPE)); + } + + // remove the padded container + delete ((SimpleTempDataBase*) pa._handle); + + // update the pointer to data + pa._handle = _handle; + + // zero the padding + pa._padding = 0; + } }; // end class diff --git a/vcg/complex/trimesh/base.h b/vcg/complex/trimesh/base.h index a422cddd..df0422d6 100644 --- a/vcg/complex/trimesh/base.h +++ b/vcg/complex/trimesh/base.h @@ -238,19 +238,23 @@ class TriMesh: public TriMeshEdgeHolder*)_handle)->Resize(sz);} void Reorder(std::vector & newVertIndex){((SimpleTempDataBase*)_handle)->Reorder(newVertIndex);} - bool operator<(const HandlesWrapper b) const { return(_name.empty()&&b._name.empty())?(_handle < b._handle):( _name < b._name);} + bool operator<(const PointerToAttribute b) const { return(_name.empty()&&b._name.empty())?(_handle < b._handle):( _name < b._name);} }; - std::set< HandlesWrapper > vert_attr; - std::set< HandlesWrapper > edge_attr; - std::set< HandlesWrapper > face_attr; - std::set< HandlesWrapper > mesh_attr; + std::set< PointerToAttribute > vert_attr; + std::set< PointerToAttribute > edge_attr; + std::set< PointerToAttribute > face_attr; + std::set< PointerToAttribute > mesh_attr; template @@ -263,8 +267,14 @@ class TriMesh: public TriMeshEdgeHolder * _handle; - int n_attr; // its attribute number + + // its attribute number + int n_attr; + + // access function template ATTR_TYPE & operator [](const RefType & i){return (*_handle)[i];} }; @@ -337,7 +347,7 @@ public: /// destructor ~TriMesh() { - typename std::set< HandlesWrapper>::iterator i; + typename std::set< PointerToAttribute>::iterator i; for( i = vert_attr.begin(); i != vert_attr.end(); ++i) delete ((SimpleTempDataBase*)(*i)._handle); for( i = face_attr.begin(); i != face_attr.end(); ++i) @@ -350,7 +360,7 @@ public: } int Mem(const int & nv, const int & nf) const { - typename std::set< HandlesWrapper>::const_iterator i; + typename std::set< PointerToAttribute>::const_iterator i; int size = 0; size += sizeof(TriMesh)+sizeof(VertexType)*nv+sizeof(FaceType)*nf; @@ -583,16 +593,16 @@ bool HasVFAdjacency (const TriMesh < VertContainerType , FaceContainerType, Ed 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; + typename std::set< typename MESH_TYPE::PointerToAttribute>::const_iterator ai; + typename MESH_TYPE::PointerToAttribute 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; + typename std::set< typename MESH_TYPE::PointerToAttribute>::const_iterator ai; + typename MESH_TYPE::PointerToAttribute h; h._name = name; ai = m.face_attr.find(h); return (ai!= m.face_attr.end() ) ; @@ -600,8 +610,8 @@ bool HasPerFaceAttribute(const MESH_TYPE &m, std::string name){ template bool HasPerMeshAttribute(const MESH_TYPE &m, std::string name){ - typename std::set< typename MESH_TYPE::HandlesWrapper>::const_iterator ai; - typename MESH_TYPE::HandlesWrapper h; + typename std::set< typename MESH_TYPE::PointerToAttribute>::const_iterator ai; + typename MESH_TYPE::PointerToAttribute h; h._name = name; ai = m.mesh_attr.find(h); return (ai!= m.mesh_attr.end() ) ;