diff --git a/vcg/complex/allocate.h b/vcg/complex/allocate.h index 0fc427eb..e05917fd 100644 --- a/vcg/complex/allocate.h +++ b/vcg/complex/allocate.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -33,7 +33,7 @@ namespace tri { /** \addtogroup trimesh @{ */ - + template size_t Index(MeshType &m, const typename MeshType::VertexType &v) {return &v-&*m.vert.begin();} template @@ -51,17 +51,17 @@ namespace tri { size_t Index(MeshType &m, const typename MeshType::EdgeType* e) {return e-&*m.edge.begin();} template size_t Index(MeshType &m, const typename MeshType::HEdgeType* h) {return h-&*m.hedge.begin();} - + 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::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::PointerToAttribute)(*ai)).Resize(sz); } @@ -74,8 +74,8 @@ namespace tri { It also provide an accessory class vcg::tri::PointerUpdater for updating pointers to mesh elements that are kept by the user. */ template - class Allocator - { + class Allocator + { public: typedef typename MeshType::VertexType VertexType; @@ -112,37 +112,37 @@ namespace tri { It can also be used to prevent any update of the various mesh fields (e.g. in case you are building all the connections by hand as in a importer); \sa \ref allocation - */ + */ template class PointerUpdater { public: PointerUpdater(void) : newBase(0), oldBase(0), newEnd(0), oldEnd(0), preventUpdateFlag(false) { ; } - void Clear(){newBase=oldBase=newEnd=oldEnd=0;} - /*! \brief Update a pointer to an element of a mesh after a reallocation + void Clear(){newBase=oldBase=newEnd=oldEnd=0;} + /*! \brief Update a pointer to an element of a mesh after a reallocation The updating is correctly done only if this PointerUpdater have been passed to the corresponing allocation call. \sa \ref allocation */ - void Update(SimplexPointerType &vp) - { - //if(vp>=newBase && vpoldEnd) return; - assert(vp>=oldBase); - assert(vp=newBase && vpoldEnd) return; + assert(vp>=oldBase); + assert(vp remap; + std::vector remap; // this vector keep the new position of an element. Uninitialized elements have max_int value to denote an element that has not to be remapped. bool preventUpdateFlag; /// when true no update is considered necessary. }; @@ -225,11 +225,11 @@ namespace tri { PointerUpdater pu; VertexIterator v_ret = AddVertices(m, n,pu); - typename std::vector::iterator vi; + typename std::vector::iterator vi; for(vi=local_vec.begin();vi!=local_vec.end();++vi) pu.Update(**vi); - return v_ret; - } + return v_ret; + } /* ++++++++++ edges +++++++++++++ */ /** \brief Add n edges to the mesh. @@ -242,15 +242,15 @@ namespace tri { \retval the iterator to the first element added. */ static EdgeIterator AddEdges(MeshType &m,int n, PointerUpdater &pu) - { - EdgeIterator last; - if(n == 0) return m.edge.end(); - pu.Clear(); - if(m.edge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element - else { - pu.oldBase=&*m.edge.begin(); - pu.oldEnd=&m.edge.back()+1; - } + { + EdgeIterator last; + if(n == 0) return m.edge.end(); + pu.Clear(); + if(m.edge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element + else { + pu.oldBase=&*m.edge.begin(); + pu.oldEnd=&m.edge.back()+1; + } m.edge.resize(m.edge.size()+n); m.en+=n; @@ -260,22 +260,22 @@ namespace tri { ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.edge.size()); pu.newBase = &*m.edge.begin(); - pu.newEnd = &m.edge.back()+1; - if(pu.NeedUpdate()) + pu.newEnd = &m.edge.back()+1; + if(pu.NeedUpdate()) { FaceIterator fi; for (fi=m.face.begin(); fi!=m.face.end(); ++fi){ - //if(HasFHEAdjacency(m)) - // pu.Update((*fi).FHEp()); + //if(HasFHEAdjacency(m)) + // pu.Update((*fi).FHEp()); if(!(*fi).IsD()) for(int i=0; i < (*fi).VN(); ++i) if ((*fi).cFEp(i)!=0) pu.Update((*fi).FEp(i)); } - VertexIterator vi; + VertexIterator vi; if(HasVEAdjacency(m)) for (vi=m.vert.begin(); vi!=m.vert.end(); ++vi) - if(!(*vi).IsD()) + if(!(*vi).IsD()) if ((*vi).cVEp()!=0) pu.Update((*vi).VEp()); HEdgeIterator hi; @@ -287,11 +287,11 @@ namespace tri { } - unsigned int siz=(unsigned int)m.edge.size()-n; - - last = m.edge.begin(); + unsigned int siz=(unsigned int)m.edge.size()-n; + + last = m.edge.begin(); advance(last,siz); - + return last;// deve restituire l'iteratore alla prima faccia aggiunta; } @@ -312,33 +312,33 @@ namespace tri { PointerUpdater pu; EdgeIterator v_ret = AddEdges(m, n,pu); - typename std::vector::iterator ei; + typename std::vector::iterator ei; for(ei=local_vec.begin();ei!=local_vec.end();++ei) pu.Update(**ei); - return v_ret; - } + return v_ret; + } /* ++++++++++ hedges +++++++++++++ */ /** Function to add n halfedges to the mesh. The second parameter hold a vector of - pointers to pointer to elements of the mesh that should be updated after a - possible vector realloc. - \sa PointerUpdater - \param m the mesh to be modified - \param n the number of elements to be added - \param pu a PointerUpdater initialized so that it can be used to update pointers to edges that could have become invalid after this adding. - \retval the iterator to the first element added. - */ - static HEdgeIterator AddHEdges(MeshType &m,int n, PointerUpdater &pu) - { - HEdgeIterator last; - if(n == 0) return m.hedge.end(); - pu.Clear(); - if(m.hedge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element - else { - pu.oldBase=&*m.hedge.begin(); - pu.oldEnd=&m.hedge.back()+1; - } + pointers to pointer to elements of the mesh that should be updated after a + possible vector realloc. + \sa PointerUpdater + \param m the mesh to be modified + \param n the number of elements to be added + \param pu a PointerUpdater initialized so that it can be used to update pointers to edges that could have become invalid after this adding. + \retval the iterator to the first element added. + */ + static HEdgeIterator AddHEdges(MeshType &m,int n, PointerUpdater &pu) + { + HEdgeIterator last; + if(n == 0) return m.hedge.end(); + pu.Clear(); + if(m.hedge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element + else { + pu.oldBase=&*m.hedge.begin(); + pu.oldEnd=&m.hedge.back()+1; + } m.hedge.resize(m.hedge.size()+n); m.hn+=n; @@ -354,7 +354,7 @@ namespace tri { { if(HasFHAdjacency(m)) if(!(*fi).IsD() && (*fi).FHp()) - pu.Update((*fi).FHp()); + pu.Update((*fi).FHp()); } { @@ -390,7 +390,7 @@ namespace tri { ++hi; } } - } + } unsigned int siz = (unsigned int)m.hedge.size()-n; last = m.hedge.begin(); @@ -432,7 +432,7 @@ namespace tri { return AddFaces(m,n,pu); } - /** Function to add n faces to the mesh. + /** Function to add n faces to the mesh. Second Wrapper, with a vector of face pointer to be updated. */ static FaceIterator AddFaces(MeshType &m, int n,std::vector &local_vec) @@ -440,28 +440,28 @@ namespace tri { PointerUpdater pu; FaceIterator f_ret= AddFaces(m,n,pu); - typename std::vector::iterator fi; + typename std::vector::iterator fi; for(fi=local_vec.begin();fi!=local_vec.end();++fi) pu.Update(**fi); - return f_ret; - } + return f_ret; + } - /** Function to add n faces to the mesh. + /** Function to add n faces to the mesh. This is the only full featured function that is able to manage correctly all the internal pointers of the mesh (ff and vf relations). - NOTE: THIS FUNCTION ALSO UPDATE FN - */ - static FaceIterator AddFaces(MeshType &m, int n, PointerUpdater &pu) - { - FaceIterator last, fi; - if(n == 0) return m.face.end(); - pu.Clear(); - if(m.face.empty()) { - pu.oldBase=0; // if the vector is empty we cannot find the last valid element - } else { - pu.oldBase=&*m.face.begin(); - pu.oldEnd=&m.face.back()+1; - last=m.face.end(); - } + NOTE: THIS FUNCTION ALSO UPDATE FN + */ + static FaceIterator AddFaces(MeshType &m, int n, PointerUpdater &pu) + { + FaceIterator last, fi; + if(n == 0) return m.face.end(); + pu.Clear(); + if(m.face.empty()) { + pu.oldBase=0; // if the vector is empty we cannot find the last valid element + } else { + pu.oldBase=&*m.face.begin(); + pu.oldEnd=&m.face.back()+1; + last=m.face.end(); + } m.face.resize(m.face.size()+n); m.fn+=n; @@ -473,7 +473,7 @@ namespace tri { pu.newBase = &*m.face.begin(); pu.newEnd = &m.face.back()+1; - + if(pu.NeedUpdate()) { int ii = 0; @@ -485,7 +485,7 @@ namespace tri { if(HasFFAdjacency(m)) for(int i = 0; i < (*fi).VN(); ++i) if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i)); - + if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m)) for(int i = 0; i < (*fi).VN(); ++i) if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i)); @@ -500,8 +500,8 @@ namespace tri { if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m)) if ((*vi).cVFp()!=0) pu.Update((FaceType * &)(*vi).VFp()); - // Note the above cast is probably not useful if you have correctly defined - // your vertex type with the correct name of the facetype as a template argument; + // Note the above cast is probably not useful if you have correctly defined + // your vertex type with the correct name of the facetype as a template argument; // pu.Update((FaceType*)(*vi).VFp()); compiles on old gcc and borland // pu.Update((*vi).VFp()); compiles on .net and newer gcc } @@ -512,12 +512,12 @@ namespace tri { if(HasEFAdjacency(m)) if ((*ei).cEFp()!=0) pu.Update((FaceType * &)(*ei).EFp()); - // Note the above cast is probably not useful if you have correctly defined - // your vertex type with the correct name of the facetype as a template argument; + // Note the above cast is probably not useful if you have correctly defined + // your vertex type with the correct name of the facetype as a template argument; // pu.Update((FaceType*)(*vi).VFp()); compiles on old gcc and borland // pu.Update((*vi).VFp()); compiles on .net and newer gcc } - + HEdgeIterator hi; for (hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) if(!(*hi).IsD()) @@ -525,36 +525,36 @@ namespace tri { if(HasHFAdjacency(m)) if ((*hi).cHFp()!=0) pu.Update((FaceType * &)(*hi).HFp()); - // Note the above cast is probably not useful if you have correctly defined - // your vertex type with the correct name of the facetype as a template argument; + // Note the above cast is probably not useful if you have correctly defined + // your vertex type with the correct name of the facetype as a template argument; // pu.Update((FaceType*)(*vi).VFp()); compiles on old gcc and borland // pu.Update((*vi).VFp()); compiles on .net and newer gcc } } - unsigned int siz=(unsigned int)m.face.size()-n; - last = m.face.begin(); + unsigned int siz=(unsigned int)m.face.size()-n; + last = m.face.begin(); advance(last,siz); return last; } - /** Function to delete a face from the mesh. + /** Function to delete a face from the mesh. NOTE: THIS FUNCTION ALSO UPDATE FN */ static void DeleteFace(MeshType &m, FaceType &f) { - assert(&f >= &m.face.front() && &f <= &m.face.back()); + assert(&f >= &m.face.front() && &f <= &m.face.back()); assert(!f.IsD()); f.SetD(); --m.fn; } - /** Function to delete a vertex from the mesh. + /** Function to delete a vertex from the mesh. NOTE: THIS FUNCTION ALSO UPDATE vn */ static void DeleteVertex(MeshType &m, VertexType &v) { - assert(&v >= &m.vert.front() && &v <= &m.vert.back()); + assert(&v >= &m.vert.front() && &v <= &m.vert.back()); assert(!v.IsD()); v.SetD(); --m.vn; @@ -574,76 +574,77 @@ namespace tri { /** Function to delete a hedge from the mesh. NOTE: THIS FUNCTION ALSO UPDATE en */ - static void DeleteHEdge(MeshType &m, HEdgeType &h) + static void DeleteHEdge(MeshType &m, HEdgeType &h) { - assert(!h.IsD()); - h.SetD(); + assert(!h.IsD()); + h.SetD(); --m.hn; } - + /* Function to rearrange the vertex vector according to a given index permutation the permutation is vector such that after calling this function - + m.vert[ newVertIndex[i] ] = m.vert[i]; - + e.g. newVertIndex[i] is the new index of the vertex i - + */ - static void PermutateVertexVector(MeshType &m, PointerUpdater &pu) - { - if(m.vert.empty()) return; - for(unsigned int i=0;i &pu) + { + if(m.vert.empty()) return; + for(unsigned int i=0;i &pu ) { // If already compacted fast return please! - if(m.vn==(int)m.vert.size()) return; - + if(m.vn==(int)m.vert.size()) return; + // newVertIndex [ ] gives you the new position of the vertex in the vector; pu.remap.resize( m.vert.size(),std::numeric_limits::max() ); - + size_t pos=0; size_t i=0; - + for(i=0;i &pu ) - { - // If already compacted fast return please! - if(m.en==(int)m.edge.size()) return; + { + // If already compacted fast return please! + if(m.en==(int)m.edge.size()) return; // remap [ ] gives you the new position of the edge in the vector; pu.remap.resize( m.edge.size(),std::numeric_limits::max() ); @@ -793,67 +794,69 @@ namespace tri { \brief Compact vector of faces removing deleted elements. Deleted elements are put to the end of the vector and the vector is resized. Order between elements is preserved but not their position (hence the PointerUpdater) - After calling this function the \c IsD() test in the scanning a vector, is no more necessary. + Immediately after calling this function the \c IsD() test during the scanning a vector, is no more necessary. \warning It should not be called when TemporaryData is active (but works correctly if attributes are present) */ static void CompactFaceVector( MeshType &m, PointerUpdater &pu ) { // If already compacted fast return please! - if(m.fn==(int)m.face.size()) return; - + if(m.fn==(int)m.face.size()) return; + // newFaceIndex [ ] gives you the new position of the face in the vector; pu.remap.resize( m.face.size(),std::numeric_limits::max() ); - + size_t pos=0; - size_t i=0; - - for(i=0;i - static + static bool IsValidHandle( MeshType & m, const typename MeshType::template PerVertexAttributeHandle & a){ if(a._handle == NULL) return false; for(AttrIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i) @@ -920,7 +923,7 @@ public: template static typename MeshType::template PerVertexAttributeHandle - AddPerVertexAttribute( MeshType & m, std::string name){ + AddPerVertexAttribute( MeshType & m, std::string name){ PAIte i; PointerToAttribute h; h._name = name; @@ -964,9 +967,9 @@ public: /*! \brief Try to retrieve an handle to an attribute with a given name and ATTR_TYPE \returns a invalid handle if no attribute with that name and type exists. */ - template + template static typename MeshType::template PerVertexAttributeHandle - FindPerVertexAttribute( MeshType & m, const std::string & name) + FindPerVertexAttribute( MeshType & m, const std::string & name) { assert(!name.empty()); PointerToAttribute h1; h1._name = name; @@ -985,17 +988,17 @@ public: } return typename MeshType::template PerVertexAttributeHandle((*i)._handle,(*i).n_attr); } - return typename MeshType:: template PerVertexAttributeHandle(NULL,0); + return typename MeshType:: template PerVertexAttributeHandle(NULL,0); } /*! \brief query the mesh for all the attributes per vertex \returns the name of all attributes with a non-empy name. */ - template + template static void GetAllPerVertexAttribute(MeshType & m, std::vector &all){ all.clear(); - typename std::set ::const_iterator i; - for(i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i ) + typename std::set ::const_iterator i; + for(i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i ) if(!(*i)._name.empty()) { typename MeshType:: template PerVertexAttributeHandle hh; @@ -1003,7 +1006,7 @@ public: if(IsValidHandle(m,hh)) all.push_back((*i)._name); } - } + } template static @@ -1021,14 +1024,14 @@ public: /*! \brief If the per-vertex attribute exists, delete it. */ 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); + 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;} } @@ -1050,7 +1053,7 @@ public: /// Per Edge Attributes template - static + static bool IsValidHandle( MeshType & m, const typename MeshType::template PerEdgeAttributeHandle & a){ if(a._handle == NULL) return false; for(AttrIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i) @@ -1058,7 +1061,7 @@ public: return false; } - template + template static typename MeshType::template PerEdgeAttributeHandle AddPerEdgeAttribute( MeshType & m, std::string name){ @@ -1073,19 +1076,19 @@ public: h._padding = 0; // h._typename = typeid(ATTR_TYPE).name(); h._handle = new SimpleTempData(m.edge); - m.attrn++; - h.n_attr = m.attrn; - std::pair < AttrIterator , bool> res = m.edge_attr.insert(h); - return typename MeshType::template PerEdgeAttributeHandle(res.first->_handle,res.first->n_attr); - } + m.attrn++; + h.n_attr = m.attrn; + std::pair < AttrIterator , bool> res = m.edge_attr.insert(h); + return typename MeshType::template PerEdgeAttributeHandle(res.first->_handle,res.first->n_attr); + } - template + template static typename MeshType::template PerEdgeAttributeHandle AddPerEdgeAttribute( MeshType & m){ return AddPerEdgeAttribute(m,std::string("")); } - + /*! \brief gives a handle to a per-edge attribute with a given name and ATTR_TYPE \returns a valid handle. If the name is not empty and an attribute with that name and type exists returns a handle to it. Otherwise return a hanlde to a newly created. @@ -1104,10 +1107,10 @@ public: } - template + template static typename MeshType::template PerEdgeAttributeHandle - FindPerEdgeAttribute( MeshType & m, const std::string & name){ + FindPerEdgeAttribute( MeshType & m, const std::string & name){ assert(!name.empty()); PointerToAttribute h1; h1._name = name; typename std::set ::const_iterator i; @@ -1131,31 +1134,31 @@ public: template static void GetAllPerEdgeAttribute(const MeshType & m, std::vector &all){ - all.clear(); - typename std::set :: const_iterator i; - for(i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i ) - if(!(*i)._name.empty()) - { - typename MeshType:: template PerEdgeAttributeHandle hh; - hh = Allocator:: template FindPerEdgeAttribute (m,(*i)._name); - if(IsValidHandle(m,hh)) - all.push_back((*i)._name); - } - } + all.clear(); + typename std::set :: const_iterator i; + for(i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i ) + if(!(*i)._name.empty()) + { + typename MeshType:: template PerEdgeAttributeHandle hh; + hh = Allocator:: template FindPerEdgeAttribute (m,(*i)._name); + if(IsValidHandle(m,hh)) + all.push_back((*i)._name); + } + } /*! \brief If the per-edge attribute exists, delete it. */ template - static - void - DeletePerEdgeAttribute( MeshType & m,typename MeshType::template PerEdgeAttributeHandle & h){ - 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); - m.edge_attr.erase(i); - return;} - } + static + void + DeletePerEdgeAttribute( MeshType & m,typename MeshType::template PerEdgeAttributeHandle & h){ + 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); + m.edge_attr.erase(i); + return;} + } // Generic DeleteAttribute. // It must not crash if you try to delete a non existing attribute, @@ -1173,7 +1176,7 @@ public: /// Per Face Attributes template - static + static bool IsValidHandle( MeshType & m, const typename MeshType::template PerFaceAttributeHandle & a){ if(a._handle == NULL) return false; for(AttrIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i) @@ -1181,7 +1184,7 @@ public: return false; } - template + template static typename MeshType::template PerFaceAttributeHandle AddPerFaceAttribute( MeshType & m, std::string name){ @@ -1193,16 +1196,16 @@ public: assert(i ==m.face_attr.end() );// an attribute with this name exists } - h._sizeof = sizeof(ATTR_TYPE); + h._sizeof = sizeof(ATTR_TYPE); h._padding = 0; h._handle = new SimpleTempData(m.face); - m.attrn++; - h.n_attr = m.attrn; - std::pair < AttrIterator , bool> res = m.face_attr.insert(h); - return typename MeshType::template PerFaceAttributeHandle(res.first->_handle,res.first->n_attr); - } + m.attrn++; + h.n_attr = m.attrn; + std::pair < AttrIterator , bool> res = m.face_attr.insert(h); + return typename MeshType::template PerFaceAttributeHandle(res.first->_handle,res.first->n_attr); + } - template + template static typename MeshType::template PerFaceAttributeHandle AddPerFaceAttribute( MeshType & m){ @@ -1226,17 +1229,17 @@ public: return AddPerFaceAttribute(m,name); } - template + template static typename MeshType::template PerFaceAttributeHandle - FindPerFaceAttribute( MeshType & m, const std::string & name){ + FindPerFaceAttribute( MeshType & m, const std::string & name){ assert(!name.empty()); PointerToAttribute h1; h1._name = name; typename std::set ::iterator i; i =m.face_attr.find(h1); if(i!=m.face_attr.end()) - if((*i)._sizeof == sizeof(ATTR_TYPE) ){ + if((*i)._sizeof == sizeof(ATTR_TYPE) ){ if( (*i)._padding != 0 ){ PointerToAttribute attr = (*i); // copy the PointerToAttribute m.face_attr.erase(i); // remove it from the set @@ -1250,11 +1253,11 @@ public: return typename MeshType:: template PerFaceAttributeHandle(NULL,0); } - template + template static void GetAllPerFaceAttribute(MeshType & m, std::vector &all){ all.clear(); - typename std::set :: const_iterator i; - for(i = m.face_attr.begin(); i != m.face_attr.end(); ++i ) + typename std::set :: const_iterator i; + for(i = m.face_attr.begin(); i != m.face_attr.end(); ++i ) if(!(*i)._name.empty()) { typename MeshType:: template PerFaceAttributeHandle hh; @@ -1262,22 +1265,22 @@ public: if(IsValidHandle(m,hh)) all.push_back((*i)._name); } - } + } /*! \brief If the per-face attribute exists, delete it. */ - 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;} + 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;} - } + } // Generic DeleteAttribute. // It must not crash if you try to delete a non existing attribute, @@ -1295,7 +1298,7 @@ public: /// Per Mesh Attributes template - static + static bool IsValidHandle( MeshType & m, const typename MeshType::template PerMeshAttributeHandle & a){ if(a._handle == NULL) return false; for(AttrIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i) @@ -1303,7 +1306,7 @@ public: return false; } - template + template static typename MeshType::template PerMeshAttributeHandle AddPerMeshAttribute( MeshType & m, std::string name){ @@ -1315,14 +1318,14 @@ public: assert(i ==m.mesh_attr.end() );// an attribute with this name exists } h._sizeof = sizeof(ATTR_TYPE); - h._padding = 0; + h._padding = 0; h._handle = new Attribute(); m.attrn++; h.n_attr = m.attrn; std::pair < AttrIterator , bool> res = m.mesh_attr.insert(h); return typename MeshType::template PerMeshAttributeHandle(res.first->_handle,res.first->n_attr); } - + /*! \brief gives a handle to a per-edge attribute with a given name and ATTR_TYPE \returns a valid handle. If the name is not empty and an attribute with that name and type exists returns a handle to it. Otherwise return a hanlde to a newly created. @@ -1340,17 +1343,17 @@ public: return AddPerMeshAttribute(m,name); } - template + template static typename MeshType::template PerMeshAttributeHandle - FindPerMeshAttribute( MeshType & m, const std::string & name){ + FindPerMeshAttribute( MeshType & m, const std::string & name){ assert(!name.empty()); PointerToAttribute h1; h1._name = name; typename std::set ::iterator i; i =m.mesh_attr.find(h1); if(i!=m.mesh_attr.end()) - if((*i)._sizeof == sizeof(ATTR_TYPE) ){ + if((*i)._sizeof == sizeof(ATTR_TYPE) ){ if( (*i)._padding != 0 ){ PointerToAttribute attr = (*i); // copy the PointerToAttribute m.mesh_attr.erase(i); // remove it from the set @@ -1370,23 +1373,23 @@ public: static void GetAllPerMeshAttribute(const MeshType & m, std::vector &all){ typename std::set :: iterator i; for(i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i ) - if((*i)._sizeof == sizeof(ATTR_TYPE)) + if((*i)._sizeof == sizeof(ATTR_TYPE)) all.push_back((*i)._name); } /*! \brief If the per-mesh attribute exists, delete it. */ template - static - void - DeletePerMeshAttribute( MeshType & m,typename MeshType::template PerMeshAttributeHandle & h){ - 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); - m.mesh_attr.erase(i); - return;} - } + static + void + DeletePerMeshAttribute( MeshType & m,typename MeshType::template PerMeshAttributeHandle & h){ + 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); + m.mesh_attr.erase(i); + return;} + } static void DeletePerMeshAttribute( MeshType & m, std::string name){ @@ -1394,7 +1397,7 @@ public: PointerToAttribute h1; h1._name = name; i = m.mesh_attr.find(h1); assert(i!=m.mesh_attr.end()); - delete ((SimpleTempDataBase *)(*i)._handle); + delete ((SimpleTempDataBase *)(*i)._handle); m.mesh_attr.erase(i); } @@ -1456,7 +1459,7 @@ public: } template - static + static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){ // create the container of the right type @@ -1466,12 +1469,12 @@ public: _handle->Resize(m.face.size()); for(unsigned int i = 0; i < m.face.size(); ++i){ ATTR_TYPE * dest = &(*_handle)[i]; - char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); - memcpy((void*)dest , + char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); + memcpy((void*)dest , (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); } - // remove the padded container + // remove the padded container delete ((SimpleTempDataBase*) pa._handle); // update the pointer to data @@ -1480,23 +1483,23 @@ public: // update the pointer to data pa._handle = _handle; - // zero the padding + // zero the padding pa._padding = 0; } - + template - static - void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){ + static + void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){ // create the container of the right type Attribute * _handle = new Attribute(); - // copy the padded container in the new one + // copy the padded container in the new one char * ptr = (char*)( ((Attribute *)pa._handle)->DataBegin()); - memcpy((void*)_handle->attribute ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE)); + memcpy((void*)_handle->attribute ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE)); - // remove the padded container + // remove the padded container delete ( (Attribute *) pa._handle); // update the pointer to data @@ -1505,14 +1508,14 @@ public: // update the pointer to data pa._handle = _handle; - // zero the padding + // zero the padding pa._padding = 0; } }; // end class - + /*@}*/ } // End Namespace TriMesh