diff --git a/vcg/complex/allocate.h b/vcg/complex/allocate.h index 734c8614..b2ac4a22 100644 --- a/vcg/complex/allocate.h +++ b/vcg/complex/allocate.h @@ -52,60 +52,60 @@ 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 */){ +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::PointerToAttribute)(*ai)).Reorder(newVertIndex); } template -void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ +void ResizeAttribute(ATTR_CONT &c, size_t sz, MeshType &/*m*/){ typename std::set::iterator ai; for(ai =c.begin(); ai != c.end(); ++ai) ((typename MeshType::PointerToAttribute)(*ai)).Resize(sz); } - /*! +/*! \brief Class to safely add and delete elements in a mesh. Adding elements to a mesh, like faces and vertices can involve the reallocation of the vectors of the involved elements. This class provide the only safe methods to add elements. It also provide an accessory class vcg::tri::PointerUpdater for updating pointers to mesh elements that are kept by the user. */ - template - class Allocator - { +template +class Allocator +{ - public: - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::VertexPointer VertexPointer; - typedef typename MeshType::VertexIterator VertexIterator; - typedef typename MeshType::VertContainer VertContainer; +public: + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::VertexPointer VertexPointer; + typedef typename MeshType::VertexIterator VertexIterator; + typedef typename MeshType::VertContainer VertContainer; - typedef typename MeshType::EdgeType EdgeType; - typedef typename MeshType::EdgePointer EdgePointer; - typedef typename MeshType::EdgeIterator EdgeIterator; - typedef typename MeshType::EdgeContainer EdgeContainer; + typedef typename MeshType::EdgeType EdgeType; + typedef typename MeshType::EdgePointer EdgePointer; + typedef typename MeshType::EdgeIterator EdgeIterator; + typedef typename MeshType::EdgeContainer EdgeContainer; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::FacePointer FacePointer; - typedef typename MeshType::FaceIterator FaceIterator; - typedef typename MeshType::FaceContainer FaceContainer; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::FacePointer FacePointer; + typedef typename MeshType::FaceIterator FaceIterator; + typedef typename MeshType::FaceContainer FaceContainer; - typedef typename MeshType::HEdgeType HEdgeType; - typedef typename MeshType::HEdgePointer HEdgePointer; - typedef typename MeshType::HEdgeIterator HEdgeIterator; - typedef typename MeshType::HEdgeContainer HEdgeContainer; + typedef typename MeshType::HEdgeType HEdgeType; + typedef typename MeshType::HEdgePointer HEdgePointer; + typedef typename MeshType::HEdgeIterator HEdgeIterator; + typedef typename MeshType::HEdgeContainer HEdgeContainer; - typedef typename MeshType::CoordType CoordType; + typedef typename MeshType::CoordType CoordType; - typedef typename MeshType::PointerToAttribute PointerToAttribute; - typedef typename std::set::iterator AttrIterator; - typedef typename std::set::const_iterator AttrConstIterator; - typedef typename std::set::iterator PAIte; + typedef typename MeshType::PointerToAttribute PointerToAttribute; + typedef typename std::set::iterator AttrIterator; + typedef typename std::set::const_iterator AttrConstIterator; + typedef typename std::set::iterator PAIte; - /*! + /*! \brief Accessory class to update pointers after eventual reallocation caused by adding elements. This class is used whenever you trigger some allocation operation that can cause the invalidation of the pointers to mesh elements. @@ -116,43 +116,43 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ This can be useful in case you are building all the internal connections by hand as it happens 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; remap.clear();} - /*! \brief Update a pointer to an element of a mesh after a reallocation + template + class PointerUpdater + { + public: + PointerUpdater(void) : newBase(0), oldBase(0), newEnd(0), oldEnd(0), preventUpdateFlag(false) { ; } + void Clear(){newBase=oldBase=newEnd=oldEnd=0; remap.clear();} + /*! \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; // 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. + SimplexPointerType newBase; + SimplexPointerType oldBase; + SimplexPointerType newEnd; + SimplexPointerType oldEnd; + 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. - }; + bool preventUpdateFlag; /// when true no update is considered necessary. + }; - /* +++++++++++++++ Add Vertices ++++++++++++++++ */ + /* +++++++++++++++ Add Vertices ++++++++++++++++ */ - /** \brief Add n vertices to the mesh. + /** \brief Add n vertices to the mesh. Function to add n vertices to the mesh. The elements are added always to the end of the vector. No attempt of reusing previously deleted element is done. @@ -162,112 +162,112 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ \param pu a PointerUpdater initialized so that it can be used to update pointers to vertices that could have become invalid after this adding. \retval the iterator to the first element added. */ - static VertexIterator AddVertices(MeshType &m,int n, PointerUpdater &pu) - { - VertexIterator last; - if(n == 0) return m.vert.end(); - pu.Clear(); - if(m.vert.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element - else { - pu.oldBase=&*m.vert.begin(); - pu.oldEnd=&m.vert.back()+1; - } + static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater &pu) + { + VertexIterator last; + if(n == 0) return m.vert.end(); + pu.Clear(); + if(m.vert.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element + else { + pu.oldBase=&*m.vert.begin(); + pu.oldEnd=&m.vert.back()+1; + } - m.vert.resize(m.vert.size()+n); - m.vn+=n; + 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) - ((PointerToAttribute)(*ai)).Resize(m.vert.size()); + typename std::set::iterator ai; + for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai) + ((PointerToAttribute)(*ai)).Resize(m.vert.size()); - pu.newBase = &*m.vert.begin(); - pu.newEnd = &m.vert.back()+1; - if(pu.NeedUpdate()) - { - for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi) - if(!(*fi).IsD()) - for(int i=0; i < (*fi).VN(); ++i) - if ((*fi).cV(i)!=0) pu.Update((*fi).V(i)); + pu.newBase = &*m.vert.begin(); + pu.newEnd = &m.vert.back()+1; + if(pu.NeedUpdate()) + { + for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi) + if(!(*fi).IsD()) + for(int i=0; i < (*fi).VN(); ++i) + if ((*fi).cV(i)!=0) pu.Update((*fi).V(i)); - for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei) - if(!(*ei).IsD()) - { - if(HasEVAdjacency (m)) { pu.Update((*ei).V(0)); pu.Update((*ei).V(1));} - // if(HasEVAdjacency(m)) pu.Update((*ei).EVp()); - } - HEdgeIterator hi; - for (hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) - if(!(*hi).IsD()) - { - if(HasHVAdjacency (m)) - { - pu.Update((*hi).HVp()); - } - } + for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei) + if(!(*ei).IsD()) + { + if(HasEVAdjacency (m)) { pu.Update((*ei).V(0)); pu.Update((*ei).V(1));} + // if(HasEVAdjacency(m)) pu.Update((*ei).EVp()); + } + HEdgeIterator hi; + for (hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) + if(!(*hi).IsD()) + { + if(HasHVAdjacency (m)) + { + pu.Update((*hi).HVp()); + } + } - // e poiche' lo spazio e' cambiato si ricalcola anche last da zero - } - unsigned int siz=(unsigned int)m.vert.size()-n; + // e poiche' lo spazio e' cambiato si ricalcola anche last da zero + } + size_t siz=(size_t)(m.vert.size()-n); - last = m.vert.begin(); - advance(last,siz); + last = m.vert.begin(); + advance(last,siz); - return last;// deve restituire l'iteratore alla prima faccia aggiunta; - } + return last;// deve restituire l'iteratore alla prima faccia aggiunta; + } - /** \brief Wrapper to AddVertices(); no PointerUpdater + /** \brief Wrapper to AddVertices(); no PointerUpdater */ - static VertexIterator AddVertices(MeshType &m, int n) - { - PointerUpdater pu; - return AddVertices(m, n,pu); - } + static VertexIterator AddVertices(MeshType &m, size_t n) + { + PointerUpdater pu; + return AddVertices(m, n,pu); + } - /** \brief Wrapper to AddVertices() no PointerUpdater but a vector of VertexPointer pointers to be updated + /** \brief Wrapper to AddVertices() no PointerUpdater but a vector of VertexPointer pointers to be updated */ - static VertexIterator AddVertices(MeshType &m, int n, std::vector &local_vec) - { - PointerUpdater pu; - VertexIterator v_ret = AddVertices(m, n,pu); + static VertexIterator AddVertices(MeshType &m, size_t n, std::vector &local_vec) + { + PointerUpdater pu; + VertexIterator v_ret = AddVertices(m, n,pu); - typename std::vector::iterator vi; - for(vi=local_vec.begin();vi!=local_vec.end();++vi) - pu.Update(**vi); - return v_ret; - } + typename std::vector::iterator vi; + for(vi=local_vec.begin();vi!=local_vec.end();++vi) + pu.Update(**vi); + return v_ret; + } - /** \brief Wrapper to AddVertices() to add a single vertex with given coords + /** \brief Wrapper to AddVertices() to add a single vertex with given coords */ - static VertexIterator AddVertex(MeshType &m, const CoordType &p) - { - VertexIterator v_ret = AddVertices(m, 1); - v_ret->P()=p; - return v_ret; - } + static VertexIterator AddVertex(MeshType &m, const CoordType &p) + { + VertexIterator v_ret = AddVertices(m, 1); + v_ret->P()=p; + return v_ret; + } - /** \brief Wrapper to AddVertices() to add a single vertex with given coords and normal + /** \brief Wrapper to AddVertices() to add a single vertex with given coords and normal */ - static VertexIterator AddVertex(MeshType &m, const CoordType &p, const CoordType &n) - { - VertexIterator v_ret = AddVertices(m, 1); - v_ret->P()=p; - v_ret->N()=n; - return v_ret; - } + static VertexIterator AddVertex(MeshType &m, const CoordType &p, const CoordType &n) + { + VertexIterator v_ret = AddVertices(m, 1); + v_ret->P()=p; + v_ret->N()=n; + return v_ret; + } - /** \brief Wrapper to AddVertices() to add a single vertex with given coords and color + /** \brief Wrapper to AddVertices() to add a single vertex with given coords and color */ - static VertexIterator AddVertex(MeshType &m, const CoordType &p, const Color4b &c) - { - VertexIterator v_ret = AddVertices(m, 1); - v_ret->P()=p; - v_ret->C()=c; - return v_ret; - } + static VertexIterator AddVertex(MeshType &m, const CoordType &p, const Color4b &c) + { + VertexIterator v_ret = AddVertices(m, 1); + v_ret->P()=p; + v_ret->C()=c; + return v_ret; + } - /* +++++++++++++++ Add Edges ++++++++++++++++ */ + /* +++++++++++++++ Add Edges ++++++++++++++++ */ - /** \brief Add n edges to the mesh. + /** \brief Add n edges to the mesh. Function to add n edges to the mesh. The elements are added always to the end of the vector. No attempt of reusing previously deleted element is done. \sa PointerUpdater @@ -276,102 +276,102 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ \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 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; - } + static EdgeIterator AddEdges(MeshType &m, size_t 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; + } - m.edge.resize(m.edge.size()+n); - m.en+=n; + m.edge.resize(m.edge.size()+n); + m.en+=n; - typename std::set::iterator ai; - for(ai = m.edge_attr.begin(); ai != m.edge_attr.end(); ++ai) - ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.edge.size()); + typename std::set::iterator ai; + for(ai = m.edge_attr.begin(); ai != m.edge_attr.end(); ++ai) + ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.edge.size()); - pu.newBase = &*m.edge.begin(); - pu.newEnd = &m.edge.back()+1; - if(pu.NeedUpdate()) - { - if(HasFEAdjacency(m)) - for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi){ - if(!(*fi).IsD()) - for(int i=0; i < (*fi).VN(); ++i) - if ((*fi).cFEp(i)!=0) pu.Update((*fi).FEp(i)); - } + pu.newBase = &*m.edge.begin(); + pu.newEnd = &m.edge.back()+1; + if(pu.NeedUpdate()) + { + if(HasFEAdjacency(m)) + for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi){ + if(!(*fi).IsD()) + for(int i=0; i < (*fi).VN(); ++i) + if ((*fi).cFEp(i)!=0) pu.Update((*fi).FEp(i)); + } - if(HasVEAdjacency(m)) - for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi) - if(!(*vi).IsD()) - if ((*vi).cVEp()!=0) pu.Update((*vi).VEp()); + if(HasVEAdjacency(m)) + for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi) + if(!(*vi).IsD()) + if ((*vi).cVEp()!=0) pu.Update((*vi).VEp()); - if(HasHEAdjacency(m)) - for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) - if(!(*hi).IsD()) - if ((*hi).cHEp()!=0) pu.Update((*hi).HEp()); - } - unsigned int siz=(unsigned int)m.edge.size()-n; + if(HasHEAdjacency(m)) + for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) + if(!(*hi).IsD()) + if ((*hi).cHEp()!=0) pu.Update((*hi).HEp()); + } + size_t siz=(size_t)(m.edge.size()-n); - last = m.edge.begin(); - advance(last,siz); + last = m.edge.begin(); + advance(last,siz); - return last;// deve restituire l'iteratore alla prima faccia aggiunta; - } + return last;// deve restituire l'iteratore alla prima faccia aggiunta; + } - /** Function to add a single edge to the mesh. and initializing it with two VertexPointer + /** Function to add a single edge to the mesh. and initializing it with two VertexPointer */ - static EdgeIterator AddEdge(MeshType &m, VertexPointer v0, VertexPointer v1) - { - EdgeIterator ei= AddEdges(m, 1); - ei->V(0)=v0; - ei->V(1)=v1; - return ei; - } + static EdgeIterator AddEdge(MeshType &m, VertexPointer v0, VertexPointer v1) + { + EdgeIterator ei= AddEdges(m, 1); + ei->V(0)=v0; + ei->V(1)=v1; + return ei; + } - /** Function to add a face to the mesh and initializing it with the three given coords + /** Function to add a face to the mesh and initializing it with the three given coords */ - static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1) - { - VertexIterator vi = AddVertices(m,2); - EdgeIterator ei = AddEdges(m,1); - vi->P()=p0; - ei->V(0)=&*vi++; - vi->P()=p1; - ei->V(1)=&*vi++; - return ei; - } + static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1) + { + VertexIterator vi = AddVertices(m,2); + EdgeIterator ei = AddEdges(m,1); + vi->P()=p0; + ei->V(0)=&*vi++; + vi->P()=p1; + ei->V(1)=&*vi++; + return ei; + } - /** Function to add n edges to the mesh. + /** Function to add n edges to the mesh. First wrapper, with no parameters */ - static EdgeIterator AddEdges(MeshType &m, int n) - { - PointerUpdater pu; - return AddEdges(m, n,pu); - } + static EdgeIterator AddEdges(MeshType &m, size_t n) + { + PointerUpdater pu; + return AddEdges(m, n,pu); + } - /** Function to add n edges to the mesh. + /** Function to add n edges to the mesh. Second Wrapper, with a vector of vertex pointers to be updated. */ - static EdgeIterator AddEdges(MeshType &m, int n, std::vector &local_vec) - { - PointerUpdater pu; - EdgeIterator v_ret = AddEdges(m, n,pu); + static EdgeIterator AddEdges(MeshType &m, size_t n, std::vector &local_vec) + { + PointerUpdater pu; + EdgeIterator v_ret = AddEdges(m, n,pu); - typename std::vector::iterator ei; - for(ei=local_vec.begin();ei!=local_vec.end();++ei) - pu.Update(**ei); - return v_ret; - } + typename std::vector::iterator ei; + for(ei=local_vec.begin();ei!=local_vec.end();++ei) + pu.Update(**ei); + return v_ret; + } - /* +++++++++++++++ Add HalfEdges ++++++++++++++++ */ + /* +++++++++++++++ Add HalfEdges ++++++++++++++++ */ - /** Function to add n halfedges to the mesh. The second parameter hold a vector of + /** 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 @@ -380,200 +380,189 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ \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; - } + static HEdgeIterator AddHEdges(MeshType &m, size_t 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; + m.hedge.resize(m.hedge.size()+n); + m.hn+=n; - pu.newBase = &*m.hedge.begin(); - pu.newEnd = &m.hedge.back()+1; + pu.newBase = &*m.hedge.begin(); + pu.newEnd = &m.hedge.back()+1; - if(pu.NeedUpdate()) - { - int ii = 0; - FaceIterator fi; - for (fi=m.face.begin(); fi!=m.face.end(); ++fi) - { - if(HasFHAdjacency(m)) - if(!(*fi).IsD() && (*fi).FHp()) - pu.Update((*fi).FHp()); - } + if(pu.NeedUpdate()) + { + if(HasFHAdjacency(m)) { + for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi) + { + if(!(*fi).IsD() && (*fi).FHp()) + pu.Update((*fi).FHp()); + } + } + if(HasVHAdjacency(m)) { + for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi) + if(!(*vi).IsD() && (*vi).cVHp()!=0) + pu.Update((*vi).VHp()); + } + if(HasEHAdjacency(m)) { + for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei) + if(!(*ei).IsD() && (*ei).cEHp()!=0) + pu.Update((*ei).EHp()); + } - { - VertexIterator vi; - for (vi=m.vert.begin(); vi!=m.vert.end(); ++vi) - if(HasVHAdjacency(m)) - if(!(*vi).IsD()) - if ((*vi).cVHp()!=0) - pu.Update((*vi).VHp()); - } + int ii = 0; + HEdgeIterator hi = m.hedge.begin(); + while(ii < m.hn - int(n))// cycle on all the faces except the new ones + { + if(!(*hi).IsD()) + { + if(HasHNextAdjacency(m)) pu.Update((*hi).HNp()); + if(HasHPrevAdjacency(m)) pu.Update((*hi).HPp()); + if(HasHOppAdjacency(m)) pu.Update((*hi).HOp()); + ++ii; + } + ++hi; + } + } + size_t siz = (size_t)(m.hedge.size()-n); - { - EdgeIterator ei; - for (ei=m.edge.begin(); ei!=m.edge.end(); ++ei) - if(HasEHAdjacency(m)) - if(!(*ei).IsD()) - if ((*ei).cEHp()!=0) - pu.Update((*ei).EHp()); - } + last = m.hedge.begin(); + advance(last,siz); - { - HEdgeIterator hi = m.hedge.begin(); - while(ii < m.hn - n)// cycle on all the faces except the new ones - { - if(!(*hi).IsD()) - { - if(HasHNextAdjacency(m)) pu.Update((*hi).HNp()); - if(HasHPrevAdjacency(m)) pu.Update((*hi).HPp()); - if(HasHOppAdjacency(m)) pu.Update((*hi).HOp()); - ++ii; - } + return last;// deve restituire l'iteratore alla prima faccia aggiunta; + } - ++hi; - } - } - } - unsigned int siz = (unsigned int)m.hedge.size()-n; - - last = m.hedge.begin(); - advance(last,siz); - - return last;// deve restituire l'iteratore alla prima faccia aggiunta; - } - - /** Function to add n vertices to the mesh. + /** Function to add n vertices to the mesh. First wrapper, with no parameters */ - static HEdgeIterator AddHEdges(MeshType &m, int n) - { - PointerUpdater pu; - return AddHEdges(m, n,pu); - } + static HEdgeIterator AddHEdges(MeshType &m, size_t n) + { + PointerUpdater pu; + return AddHEdges(m, n,pu); + } - /** Function to add n vertices to the mesh. + /** Function to add n vertices to the mesh. Second Wrapper, with a vector of vertex pointers to be updated. */ - static HEdgeIterator AddHEdges(MeshType &m, int n, std::vector &local_vec) - { - PointerUpdater pu; - HEdgeIterator v_ret = AddHEdges(m, n,pu); + static HEdgeIterator AddHEdges(MeshType &m, size_t n, std::vector &local_vec) + { + PointerUpdater pu; + HEdgeIterator v_ret = AddHEdges(m, n,pu); - typename std::vector::iterator ei; - for(ei=local_vec.begin();ei!=local_vec.end();++ei) - pu.Update(**ei); - return v_ret; - } + typename std::vector::iterator ei; + for(ei=local_vec.begin();ei!=local_vec.end();++ei) + pu.Update(**ei); + return v_ret; + } - /* +++++++++++++++ Add Faces ++++++++++++++++ */ + /* +++++++++++++++ Add Faces ++++++++++++++++ */ - /** Function to add a face to the mesh and initializing it with the three given VertexPointers + /** Function to add a face to the mesh and initializing it with the three given VertexPointers */ - static FaceIterator AddFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2) - { - assert(m.vert.size()>0); - assert((v0!=v1) && (v1!=v2) && (v0!=v2)); - assert(v0>=&m.vert.front() && v0<=&m.vert.back()); - assert(v1>=&m.vert.front() && v1<=&m.vert.back()); - assert(v2>=&m.vert.front() && v2<=&m.vert.back()); - PointerUpdater pu; - FaceIterator fi = AddFaces(m,1,pu); - fi->Alloc(3); - fi->V(0)=v0; - fi->V(1)=v1; - fi->V(2)=v2; - return fi; - } + static FaceIterator AddFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2) + { + assert(m.vert.size()>0); + assert((v0!=v1) && (v1!=v2) && (v0!=v2)); + assert(v0>=&m.vert.front() && v0<=&m.vert.back()); + assert(v1>=&m.vert.front() && v1<=&m.vert.back()); + assert(v2>=&m.vert.front() && v2<=&m.vert.back()); + PointerUpdater pu; + FaceIterator fi = AddFaces(m,1,pu); + fi->Alloc(3); + fi->V(0)=v0; + fi->V(1)=v1; + fi->V(2)=v2; + return fi; + } - /** Function to add a face to the mesh and initializing it with three indexes + /** Function to add a face to the mesh and initializing it with three indexes */ - static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2) - { - assert((v0!=v1) && (v1!=v2) && (v0!=v2)); - assert(v0>=0 && v0<=m.vert.size()); - assert(v1>=0 && v1<=m.vert.size()); - assert(v2>=0 && v2<=m.vert.size()); - return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2])); - } - /** Function to add a face to the mesh and initializing it with the three given coords + static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2) + { + assert((v0!=v1) && (v1!=v2) && (v0!=v2)); + assert(v0>=0 && v0<=m.vert.size()); + assert(v1>=0 && v1<=m.vert.size()); + assert(v2>=0 && v2<=m.vert.size()); + return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2])); + } + /** Function to add a face to the mesh and initializing it with the three given coords */ - static FaceIterator AddFace(MeshType &m, CoordType p0, CoordType p1, CoordType p2) - { - VertexIterator vi = AddVertices(m,3); - FaceIterator fi = AddFaces(m,1); - fi->Alloc(3); - vi->P()=p0; - fi->V(0)=&*vi++; - vi->P()=p1; - fi->V(1)=&*vi++; - vi->P()=p2; - fi->V(2)=&*vi; - return fi; - } + static FaceIterator AddFace(MeshType &m, CoordType p0, CoordType p1, CoordType p2) + { + VertexIterator vi = AddVertices(m,3); + FaceIterator fi = AddFaces(m,1); + fi->Alloc(3); + vi->P()=p0; + fi->V(0)=&*vi++; + vi->P()=p1; + fi->V(1)=&*vi++; + vi->P()=p2; + fi->V(2)=&*vi; + return fi; + } - /** Function to add a quad face to the mesh and initializing it with the four given VertexPointers + /** Function to add a quad face to the mesh and initializing it with the four given VertexPointers * * Note that this function add a single polygonal face if the mesh has polygonal info or two tris with the corresponding faux bit set in the standard common case of a triangular mesh. */ - static FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3) - { - assert(m.vert.size()>0); - assert(v0>=&m.vert.front() && v0<=&m.vert.back()); - assert(v1>=&m.vert.front() && v1<=&m.vert.back()); - assert(v2>=&m.vert.front() && v2<=&m.vert.back()); - assert(v3>=&m.vert.front() && v3<=&m.vert.back()); - PointerUpdater pu; - if(FaceType::HasPolyInfo()) - { - FaceIterator fi = AddFaces(m,1,pu); - fi->Alloc(4); - fi->V(0)=v0; fi->V(1)=v1; - fi->V(2)=v2; fi->V(3)=v3; - return fi; - } - else - { - FaceIterator fi = AddFaces(m,2,pu); - fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v1; fi->V(2)=v2; - fi->SetF(2); - ++fi; - fi->Alloc(3); fi->V(0)=v0; fi->V(2)=v1; fi->V(3)=v2; - fi->SetF(0); - return fi; - } - } - /** \brief Function to add n faces to the mesh. + static FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3) + { + assert(m.vert.size()>0); + assert(v0>=&m.vert.front() && v0<=&m.vert.back()); + assert(v1>=&m.vert.front() && v1<=&m.vert.back()); + assert(v2>=&m.vert.front() && v2<=&m.vert.back()); + assert(v3>=&m.vert.front() && v3<=&m.vert.back()); + PointerUpdater pu; + if(FaceType::HasPolyInfo()) + { + FaceIterator fi = AddFaces(m,1,pu); + fi->Alloc(4); + fi->V(0)=v0; fi->V(1)=v1; + fi->V(2)=v2; fi->V(3)=v3; + return fi; + } + else + { + FaceIterator fi = AddFaces(m,2,pu); + fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v1; fi->V(2)=v2; + fi->SetF(2); + ++fi; + fi->Alloc(3); fi->V(0)=v0; fi->V(2)=v1; fi->V(3)=v2; + fi->SetF(0); + return fi; + } + } + /** \brief Function to add n faces to the mesh. First wrapper, with no parameters */ - static FaceIterator AddFaces(MeshType &m, int n) - { - PointerUpdater pu; - return AddFaces(m,n,pu); - } + static FaceIterator AddFaces(MeshType &m, size_t n) + { + PointerUpdater pu; + return AddFaces(m,n,pu); + } - /** \brief Function to add n faces to the mesh. + /** \brief 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) - { - PointerUpdater pu; - FaceIterator f_ret= AddFaces(m,n,pu); + static FaceIterator AddFaces(MeshType &m, size_t n,std::vector &local_vec) + { + PointerUpdater pu; + FaceIterator f_ret= AddFaces(m,n,pu); - typename std::vector::iterator fi; - for(fi=local_vec.begin();fi!=local_vec.end();++fi) - pu.Update(**fi); - return f_ret; - } + typename std::vector::iterator fi; + for(fi=local_vec.begin();fi!=local_vec.end();++fi) + pu.Update(**fi); + return f_ret; + } - /** \brief Function to add n faces to the mesh. + /** \brief Function to add n faces to the mesh. This is the only full featured function that is able to manage correctly all the official internal pointers of the mesh (like the VF and FF adjacency relations) \warning Calling this function can cause the invalidation of any not-managed FacePointer @@ -585,116 +574,116 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ \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 FaceIterator AddFaces(MeshType &m, int n, PointerUpdater &pu) - { - pu.Clear(); - if(n == 0) return m.face.end(); - if(!m.face.empty()) // if the vector is empty we cannot find the last valid element - { - pu.oldBase=&*m.face.begin(); - pu.oldEnd=&m.face.back()+1; - } - // The actual resize - m.face.resize(m.face.size()+n); - m.fn+=n; + static FaceIterator AddFaces(MeshType &m, size_t n, PointerUpdater &pu) + { + pu.Clear(); + if(n == 0) return m.face.end(); + if(!m.face.empty()) // if the vector is empty we cannot find the last valid element + { + pu.oldBase=&*m.face.begin(); + pu.oldEnd=&m.face.back()+1; + } + // The actual resize + m.face.resize(m.face.size()+n); + m.fn+=n; - unsigned int siz=(unsigned int)m.face.size()-n; - FaceIterator firstNewFace = m.face.begin(); - advance(firstNewFace,siz); + size_t siz=(size_t)(m.face.size()-n); + FaceIterator firstNewFace = m.face.begin(); + advance(firstNewFace,siz); - typename std::set::iterator ai; - for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai) - ((PointerToAttribute)(*ai)).Resize(m.face.size()); + typename std::set::iterator ai; + for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai) + ((PointerToAttribute)(*ai)).Resize(m.face.size()); - pu.newBase = &*m.face.begin(); - pu.newEnd = &m.face.back()+1; + pu.newBase = &*m.face.begin(); + pu.newEnd = &m.face.back()+1; - if(pu.NeedUpdate()) - { - if(HasFFAdjacency(m)) - { // cycle on all the faces except the new ones - for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi) - if(!(*fi).IsD()) - for(int i = 0; i < (*fi).VN(); ++i) - if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i)); - } + if(pu.NeedUpdate()) + { + if(HasFFAdjacency(m)) + { // cycle on all the faces except the new ones + for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi) + if(!(*fi).IsD()) + for(int i = 0; i < (*fi).VN(); ++i) + if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i)); + } - if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m)) - { // cycle on all the faces except the new ones - for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi) - if(!(*fi).IsD()) - for(int i = 0; i < (*fi).VN(); ++i) - if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i)); + if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m)) + { // cycle on all the faces except the new ones + for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi) + if(!(*fi).IsD()) + for(int i = 0; i < (*fi).VN(); ++i) + if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i)); - for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi) - if(!(*vi).IsD() && (*vi).cVFp()!=0) - pu.Update((*vi).VFp()); - } + for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi) + if(!(*vi).IsD() && (*vi).cVFp()!=0) + pu.Update((*vi).VFp()); + } - if(HasEFAdjacency(m)) - { - for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei) - if(!(*ei).IsD() && (*ei).cEFp()!=0) - pu.Update((*ei).EFp()); - } + if(HasEFAdjacency(m)) + { + for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei) + if(!(*ei).IsD() && (*ei).cEFp()!=0) + pu.Update((*ei).EFp()); + } - if(HasHFAdjacency(m)) - { - for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) - if(!(*hi).IsD() && (*hi).cHFp()!=0) - pu.Update((*hi).HFp()); - } - } - return firstNewFace; - } + if(HasHFAdjacency(m)) + { + for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi) + if(!(*hi).IsD() && (*hi).cHFp()!=0) + pu.Update((*hi).HFp()); + } + } + return firstNewFace; + } - /* +++++++++++++++ Deleting ++++++++++++++++ */ + /* +++++++++++++++ Deleting ++++++++++++++++ */ - /** 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.IsD()); - f.SetD(); - --m.fn; - } + static void DeleteFace(MeshType &m, FaceType &f) + { + 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.IsD()); - v.SetD(); - --m.vn; - } + static void DeleteVertex(MeshType &m, VertexType &v) + { + assert(&v >= &m.vert.front() && &v <= &m.vert.back()); + assert(!v.IsD()); + v.SetD(); + --m.vn; + } - /** Function to delete an edge from the mesh. + /** Function to delete an edge from the mesh. NOTE: THIS FUNCTION ALSO UPDATE en */ - static void DeleteEdge(MeshType &m, EdgeType &e) - { - assert(&e >= &m.edge.front() && &e <= &m.edge.back()); - assert(!e.IsD()); - e.SetD(); - --m.en; - } + static void DeleteEdge(MeshType &m, EdgeType &e) + { + assert(&e >= &m.edge.front() && &e <= &m.edge.back()); + assert(!e.IsD()); + e.SetD(); + --m.en; + } - /** Function to delete a hedge from the mesh. + /** Function to delete a hedge from the mesh. NOTE: THIS FUNCTION ALSO UPDATE en */ - static void DeleteHEdge(MeshType &m, HEdgeType &h) - { - assert(&h >= &m.hedge.front() && &h <= &m.hedge.back()); - assert(!h.IsD()); - h.SetD(); - --m.hn; - } + static void DeleteHEdge(MeshType &m, HEdgeType &h) + { + assert(&h >= &m.hedge.front() && &h <= &m.hedge.back()); + 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 @@ -703,110 +692,110 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ 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;iVN();++i) - { - size_t oldIndex = (*fi).V(i) - pu.oldBase; - assert(pu.oldBase <= (*fi).V(i) && oldIndex < pu.remap.size()); - (*fi).V(i) = pu.newBase+pu.remap[oldIndex]; - } - // Loop on the edges to update the pointers EV relation - if(HasEVAdjacency(m)) - for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) - if(!(*ei).IsD()) - for(unsigned int i=0;i<2;++i) - { - pu.Update((*ei).V(i)); - } - } - - static void CompactEveryVector( MeshType &m) + static void PermutateVertexVector(MeshType &m, PointerUpdater &pu) + { + if(m.vert.empty()) return; + for(size_t i=0;iVN();++i) + { + size_t oldIndex = (*fi).V(i) - pu.oldBase; + assert(pu.oldBase <= (*fi).V(i) && oldIndex < pu.remap.size()); + (*fi).V(i) = pu.newBase+pu.remap[oldIndex]; + } + // Loop on the edges to update the pointers EV relation + if(HasEVAdjacency(m)) + for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) + if(!(*ei).IsD()) + { + pu.Update((*ei).V(0)); + pu.Update((*ei).V(1)); + } + } + + static void CompactEveryVector( MeshType &m) + { + CompactVertexVector(m); + CompactEdgeVector(m); + CompactFaceVector(m); + } - /*! + /*! \brief Compact vector of vertices 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. \warning It should not be called when TemporaryData is active (but works correctly if attributes are present) */ - static void CompactVertexVector( MeshType &m, PointerUpdater &pu ) - { - // If already compacted fast return please! - if(m.vn==(int)m.vert.size()) return; + static void CompactVertexVector( MeshType &m, PointerUpdater &pu ) + { + // If already compacted fast return please! + 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() ); + // 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; + size_t pos=0; + size_t i=0; - for(i=0;i pu; - CompactVertexVector(m,pu); - } + /*! \brief Wrapper without the PointerUpdater. */ + static void CompactVertexVector( MeshType &m ) { + PointerUpdater pu; + CompactVertexVector(m,pu); + } - /*! + /*! \brief Compact vector of edges 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) @@ -814,97 +803,97 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ \warning It should not be called when TemporaryData is active (but works correctly if attributes are present) */ - static void CompactEdgeVector( MeshType &m, PointerUpdater &pu ) + static void CompactEdgeVector( MeshType &m, PointerUpdater &pu ) + { + // 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() ); + + size_t pos=0; + size_t i=0; + + for(i=0;i ] gives you the new position of the edge in the vector; - pu.remap.resize( m.edge.size(),std::numeric_limits::max() ); - - size_t pos=0; - size_t i=0; - - for(i=0;i pu; - CompactEdgeVector(m,pu); - } + // reorder the optional attributes in m.vert_attr to reflect the changes + ReorderAttribute(m.edge_attr, pu.remap,m); - /*! + // setup the pointer updater + pu.oldBase = &m.edge[0]; + pu.oldEnd = &m.edge.back()+1; + + // THE resize + m.edge.resize(m.en); + + // setup the pointer updater + pu.newBase = (m.edge.empty())?0:&m.edge[0]; + pu.newEnd = (m.edge.empty())?0:&m.edge.back()+1; + + // resize the optional atttributes in m.vert_attr to reflect the changes + ResizeAttribute(m.edge_attr,m.en,m); + + // Loop on the vertices to update the pointers of VE relation + if(HasPerVertexVEAdjacency(m) &&HasPerEdgeVEAdjacency(m)) + for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi) + if(!(*vi).IsD()) pu.Update((*vi).VEp()); + + // Loop on the edges to update the pointers EE VE relation + for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) + for(unsigned int i=0;i<2;++i) + { + if(HasPerVertexVEAdjacency(m) &&HasPerEdgeVEAdjacency(m)) + pu.Update((*ei).VEp(i)); + if(HasEEAdjacency(m)) + pu.Update((*ei).EEp(i)); + } + } + + /*! \brief Wrapper without the PointerUpdater. */ + static void CompactEdgeVector( MeshType &m ) { + PointerUpdater pu; + CompactEdgeVector(m,pu); + } + + /*! \brief Compact face vector by removing deleted elements. Deleted elements are put to the end of the vector and the vector is resized. @@ -912,715 +901,715 @@ void ResizeAttribute(ATTR_CONT &c,const int & sz , MeshType &/*m*/){ 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 some TemporaryData is active (but works correctly if attributes are present) */ - static void CompactFaceVector( MeshType &m, PointerUpdater &pu ) + static void CompactFaceVector( MeshType &m, PointerUpdater &pu ) + { + // If already compacted fast return please! + 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; + for(size_t i=0;i ] 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; - for(size_t i=0;i pu; - CompactFaceVector(m,pu); - } + // Loop on the faces to correct VF and FF relations + pu.oldBase = &m.face[0]; + pu.oldEnd = &m.face.back()+1; + m.face.resize(m.fn); + pu.newBase = (m.face.empty())?0:&m.face[0]; + pu.newEnd = (m.face.empty())?0:&m.face.back()+1; + + + // resize the optional atttributes in m.face_attr to reflect the changes + ResizeAttribute(m.face_attr,m.fn,m); + + // now we update the various (not null) face pointers (inside VF and FF relations) + for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + { + if(HasVFAdjacency(m)) + for(int i=0;i<(*fi).VN();++i) + if ((*fi).IsVFInitialized(i) && (*fi).VFp(i)!=0 ) + { + size_t oldIndex = (*fi).VFp(i) - fbase; + assert(fbase <= (*fi).VFp(i) && oldIndex < pu.remap.size()); + (*fi).VFp(i) = fbase+pu.remap[oldIndex]; + } + if(HasFFAdjacency(m)) + for(int i=0;i<(*fi).VN();++i) + if ((*fi).cFFp(i)!=0) + { + size_t oldIndex = (*fi).FFp(i) - fbase; + assert(fbase <= (*fi).FFp(i) && oldIndex < pu.remap.size()); + (*fi).FFp(i) = fbase+pu.remap[oldIndex]; + } + } + + + + } + + /*! \brief Wrapper without the PointerUpdater. */ + static void CompactFaceVector( MeshType &m ) { + PointerUpdater pu; + CompactFaceVector(m,pu); + } public: - /*! \brief Check if an handle to a Per-Vertex Attribute is valid + /*! \brief Check if an handle to a Per-Vertex Attribute is valid */ - template - 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) - if ( (*i).n_attr == a.n_attr ) return true; - return false; - } + template + 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) + if ( (*i).n_attr == a.n_attr ) return true; + return false; + } - /*! \brief Add a Per-Vertex Attribute of the given ATTR_TYPE with the given name. + /*! \brief Add a Per-Vertex Attribute of the given ATTR_TYPE with the given name. No attribute with that name must exists (even of different type) */ - template - static - typename MeshType::template PerVertexAttributeHandle - AddPerVertexAttribute( MeshType & m, std::string name){ - PAIte i; - PointerToAttribute 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 - } + template + static + typename MeshType::template PerVertexAttributeHandle + AddPerVertexAttribute( MeshType & m, std::string name){ + PAIte i; + PointerToAttribute 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 = new SimpleTempData(m.vert); - m.attrn++; - h.n_attr = m.attrn; - std::pair < AttrIterator , bool> res = m.vert_attr.insert(h); - return typename MeshType::template PerVertexAttributeHandle(res.first->_handle,res.first->n_attr ); - } + h._sizeof = sizeof(ATTR_TYPE); + h._padding = 0; + h._handle = new SimpleTempData(m.vert); + m.attrn++; + h.n_attr = m.attrn; + std::pair < AttrIterator , bool> res = m.vert_attr.insert(h); + return typename MeshType::template PerVertexAttributeHandle(res.first->_handle,res.first->n_attr ); + } - template - static typename MeshType::template PerVertexAttributeHandle - AddPerVertexAttribute( MeshType & m){ - return AddPerVertexAttribute(m,std::string("")); - } + template + static typename MeshType::template PerVertexAttributeHandle + AddPerVertexAttribute( MeshType & m){ + return AddPerVertexAttribute(m,std::string("")); + } - /*! \brief gives a handle to a per-vertex attribute with a given name and ATTR_TYPE + /*! \brief gives a handle to a per-vertex 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. */ - template - static - typename MeshType::template PerVertexAttributeHandle - GetPerVertexAttribute( MeshType & m, std::string name = std::string("")){ - typename MeshType::template PerVertexAttributeHandle h; - if(!name.empty()){ - h = FindPerVertexAttribute(m,name); - if(IsValidHandle(m,h)) - return h; - } - return AddPerVertexAttribute(m,name); + template + static + typename MeshType::template PerVertexAttributeHandle + GetPerVertexAttribute( MeshType & m, std::string name = std::string("")){ + typename MeshType::template PerVertexAttributeHandle h; + if(!name.empty()){ + h = FindPerVertexAttribute(m,name); + if(IsValidHandle(m,h)) + return h; } + return AddPerVertexAttribute(m,name); + } - /*! \brief Try to retrieve an handle to an attribute with a given name and ATTR_TYPE + /*! \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 - static typename MeshType::template PerVertexAttributeHandle - FindPerVertexAttribute( MeshType & m, const std::string & name) - { - assert(!name.empty()); - PointerToAttribute h1; h1._name = name; - typename std::set :: iterator i; + template + static typename MeshType::template PerVertexAttributeHandle + FindPerVertexAttribute( MeshType & m, const std::string & name) + { + assert(!name.empty()); + PointerToAttribute h1; h1._name = name; + typename std::set :: iterator i; - i =m.vert_attr.find(h1); - if(i!=m.vert_attr.end()) - if((*i)._sizeof == sizeof(ATTR_TYPE) ){ - if( (*i)._padding != 0 ){ - PointerToAttribute 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); + i =m.vert_attr.find(h1); + if(i!=m.vert_attr.end()) + if((*i)._sizeof == sizeof(ATTR_TYPE) ){ + if( (*i)._padding != 0 ){ + PointerToAttribute 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(NULL,0); - } + return typename MeshType::template PerVertexAttributeHandle((*i)._handle,(*i).n_attr); + } + return typename MeshType:: template PerVertexAttributeHandle(NULL,0); + } - /*! \brief query the mesh for all the attributes per vertex + /*! \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 ) - if(!(*i)._name.empty()) - { - typename MeshType:: template PerVertexAttributeHandle hh; - hh = Allocator:: template FindPerVertexAttribute (m,(*i)._name); - if(IsValidHandle(m,hh)) - all.push_back((*i)._name); - } - } + 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; + hh = Allocator:: template FindPerVertexAttribute (m,(*i)._name); + if(IsValidHandle(m,hh)) + all.push_back((*i)._name); + } + } template static void ClearPerVertexAttribute( 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 ){ - for(typename MeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) - h[vi] = ATTR_TYPE(); - return;} - assert(0); + typename std::set ::iterator i; + for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i) + if( (*i)._handle == h._handle ){ + for(typename MeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) + h[vi] = ATTR_TYPE(); + return;} + assert(0); } /*! \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); - return;} - } - - // Generic DeleteAttribute. - // It must not crash if you try to delete a non existing attribute, - // because you do not have a way of asking for a handle of an attribute for which you do not know the type. - static - bool DeletePerVertexAttribute( MeshType & m, std::string name){ - AttrIterator i; - PointerToAttribute h1; h1._name = name; - i = m.vert_attr.find(h1); - if(i==m.vert_attr.end()) return false; - delete ((SimpleTempDataBase*)(*i)._handle); + 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 true; + return;} + } + + // Generic DeleteAttribute. + // It must not crash if you try to delete a non existing attribute, + // because you do not have a way of asking for a handle of an attribute for which you do not know the type. + static + bool DeletePerVertexAttribute( MeshType & m, std::string name){ + AttrIterator i; + PointerToAttribute h1; h1._name = name; + i = m.vert_attr.find(h1); + if(i==m.vert_attr.end()) return false; + delete ((SimpleTempDataBase*)(*i)._handle); + m.vert_attr.erase(i); + return true; + } + + + + /// Per Edge Attributes + template + 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) + if ( (*i).n_attr == a.n_attr ) return true; + return false; + } + + template + static + typename MeshType::template PerEdgeAttributeHandle + AddPerEdgeAttribute( MeshType & m, std::string name){ + PAIte i; + PointerToAttribute h; + h._name = name; + if(!name.empty()){ + i = m.edge_attr.find(h); + assert(i ==m.edge_attr.end() );// an attribute with this name exists } + h._sizeof = sizeof(ATTR_TYPE); + 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); + } + template + static + typename MeshType::template PerEdgeAttributeHandle + AddPerEdgeAttribute( MeshType & m){ + return AddPerEdgeAttribute(m,std::string("")); + } - - /// Per Edge Attributes - template - 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) - if ( (*i).n_attr == a.n_attr ) return true; - return false; - } - - template - static - typename MeshType::template PerEdgeAttributeHandle - AddPerEdgeAttribute( MeshType & m, std::string name){ - PAIte i; - PointerToAttribute h; - h._name = name; - if(!name.empty()){ - i = m.edge_attr.find(h); - assert(i ==m.edge_attr.end() );// an attribute with this name exists - } - h._sizeof = sizeof(ATTR_TYPE); - 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); - } - - 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 + /*! \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. */ - template - static - typename MeshType::template PerEdgeAttributeHandle - GetPerEdgeAttribute( MeshType & m, std::string name = std::string("")){ - typename MeshType::template PerEdgeAttributeHandle h; - if(!name.empty()){ - h = FindPerEdgeAttribute(m,name); - if(IsValidHandle(m,h)) - return h; - } - return AddPerEdgeAttribute(m,name); + template + static + typename MeshType::template PerEdgeAttributeHandle + GetPerEdgeAttribute( MeshType & m, std::string name = std::string("")){ + typename MeshType::template PerEdgeAttributeHandle h; + if(!name.empty()){ + h = FindPerEdgeAttribute(m,name); + if(IsValidHandle(m,h)) + return h; } + return AddPerEdgeAttribute(m,name); + } - template - static - typename MeshType::template PerEdgeAttributeHandle - FindPerEdgeAttribute( MeshType & m, const std::string & name){ - assert(!name.empty()); - PointerToAttribute h1; h1._name = name; - typename std::set ::const_iterator i; + template + static + typename MeshType::template PerEdgeAttributeHandle + FindPerEdgeAttribute( MeshType & m, const std::string & name){ + assert(!name.empty()); + PointerToAttribute h1; h1._name = name; + typename std::set ::const_iterator i; - i =m.edge_attr.find(h1); - if(i!=m.edge_attr.end()) - if((*i)._sizeof == sizeof(ATTR_TYPE) ){ - if( (*i)._padding != 0 ){ - PointerToAttribute attr = (*i); // copy the PointerToAttribute - m.edge_attr.erase(i); // remove it from the set - FixPaddedPerEdgeAttribute(m,attr); - std::pair new_i = m.edge_attr.insert(attr); // insert the modified PointerToAttribute - assert(new_i.second); - i = new_i.first; - } - return typename MeshType::template PerEdgeAttributeHandle((*i)._handle,(*i).n_attr); + i =m.edge_attr.find(h1); + if(i!=m.edge_attr.end()) + if((*i)._sizeof == sizeof(ATTR_TYPE) ){ + if( (*i)._padding != 0 ){ + PointerToAttribute attr = (*i); // copy the PointerToAttribute + m.edge_attr.erase(i); // remove it from the set + FixPaddedPerEdgeAttribute(m,attr); + std::pair new_i = m.edge_attr.insert(attr); // insert the modified PointerToAttribute + assert(new_i.second); + i = new_i.first; } + return typename MeshType::template PerEdgeAttributeHandle((*i)._handle,(*i).n_attr); + } - return typename MeshType:: template PerEdgeAttributeHandle(NULL,0); - } + return typename MeshType:: template PerEdgeAttributeHandle(NULL,0); + } - 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); - } - } + 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); + } + } - /*! \brief If the per-edge attribute exists, delete it. + /*! \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;} - } - - // Generic DeleteAttribute. - // It must not crash if you try to delete a non existing attribute, - // because you do not have a way of asking for a handle of an attribute for which you do not know the type. - static - bool DeletePerEdgeAttribute( MeshType & m, std::string name){ - AttrIterator i; - PointerToAttribute h1; h1._name = name; - i = m.edge_attr.find(h1); - if(i==m.edge_attr.end()) return false; - delete ((SimpleTempDataBase*)(*i)._handle); + 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 true; + return;} + } + + // Generic DeleteAttribute. + // It must not crash if you try to delete a non existing attribute, + // because you do not have a way of asking for a handle of an attribute for which you do not know the type. + static + bool DeletePerEdgeAttribute( MeshType & m, std::string name){ + AttrIterator i; + PointerToAttribute h1; h1._name = name; + i = m.edge_attr.find(h1); + if(i==m.edge_attr.end()) return false; + delete ((SimpleTempDataBase*)(*i)._handle); + m.edge_attr.erase(i); + return true; + } + + /// Per Face Attributes + template + 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) + if ( (*i).n_attr == a.n_attr ) return true; + return false; + } + + template + static + typename MeshType::template PerFaceAttributeHandle + AddPerFaceAttribute( MeshType & m, std::string name){ + PAIte i; + PointerToAttribute 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 } - /// Per Face Attributes - template - 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) - if ( (*i).n_attr == a.n_attr ) return true; - return false; - } + 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); + } - template - static - typename MeshType::template PerFaceAttributeHandle - AddPerFaceAttribute( MeshType & m, std::string name){ - PAIte i; - PointerToAttribute 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 - } + template + static + typename MeshType::template PerFaceAttributeHandle + AddPerFaceAttribute( MeshType & m){ + return AddPerFaceAttribute(m,std::string("")); + } - 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); - } - - template - static - typename MeshType::template PerFaceAttributeHandle - AddPerFaceAttribute( MeshType & m){ - return AddPerFaceAttribute(m,std::string("")); - } - - /*! \brief gives a handle to a per-edge attribute with a given name and ATTR_TYPE + /*! \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. */ - template - static - typename MeshType::template PerFaceAttributeHandle - GetPerFaceAttribute( MeshType & m, std::string name = std::string("")){ - typename MeshType::template PerFaceAttributeHandle h; - if(!name.empty()){ - h = FindPerFaceAttribute(m,name); - if(IsValidHandle(m,h)) - return h; + template + static + typename MeshType::template PerFaceAttributeHandle + GetPerFaceAttribute( MeshType & m, std::string name = std::string("")){ + typename MeshType::template PerFaceAttributeHandle h; + if(!name.empty()){ + h = FindPerFaceAttribute(m,name); + if(IsValidHandle(m,h)) + return h; + } + return AddPerFaceAttribute(m,name); + } + + template + static + typename MeshType::template PerFaceAttributeHandle + 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)._padding != 0 ){ + PointerToAttribute attr = (*i); // copy the PointerToAttribute + m.face_attr.erase(i); // remove it from the set + FixPaddedPerFaceAttribute(m,attr); + std::pair new_i = m.face_attr.insert(attr); // insert the modified PointerToAttribute + assert(new_i.second); + i = new_i.first; } - return AddPerFaceAttribute(m,name); - } + return typename MeshType::template PerFaceAttributeHandle((*i)._handle,(*i).n_attr); + } + return typename MeshType:: template PerFaceAttributeHandle(NULL,0); + } - template - static - typename MeshType::template PerFaceAttributeHandle - 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)._padding != 0 ){ - PointerToAttribute attr = (*i); // copy the PointerToAttribute - m.face_attr.erase(i); // remove it from the set - FixPaddedPerFaceAttribute(m,attr); - std::pair new_i = m.face_attr.insert(attr); // insert the modified PointerToAttribute - assert(new_i.second); - i = new_i.first; - } - return typename MeshType::template PerFaceAttributeHandle((*i)._handle,(*i).n_attr); - } - 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 ) - if(!(*i)._name.empty()) - { - typename MeshType:: template PerFaceAttributeHandle hh; - hh = Allocator:: template FindPerFaceAttribute (m,(*i)._name); - if(IsValidHandle(m,hh)) - all.push_back((*i)._name); - } - } + 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; + hh = Allocator:: template FindPerFaceAttribute (m,(*i)._name); + 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;} - - } - - // Generic DeleteAttribute. - // It must not crash if you try to delete a non existing attribute, - // because you do not have a way of asking for a handle of an attribute for which you do not know the type. - static bool DeletePerFaceAttribute( MeshType & m, std::string name){ - AttrIterator i; - PointerToAttribute h1; h1._name = name; - i = m.face_attr.find(h1); - if(i==m.face_attr.end()) return false; - delete ((SimpleTempDataBase*)(*i)._handle); + 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 true; + return;} + + } + + // Generic DeleteAttribute. + // It must not crash if you try to delete a non existing attribute, + // because you do not have a way of asking for a handle of an attribute for which you do not know the type. + static bool DeletePerFaceAttribute( MeshType & m, std::string name){ + AttrIterator i; + PointerToAttribute h1; h1._name = name; + i = m.face_attr.find(h1); + if(i==m.face_attr.end()) return false; + delete ((SimpleTempDataBase*)(*i)._handle); + m.face_attr.erase(i); + return true; + } + + /// Per Mesh Attributes + template + 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) + if ( (*i).n_attr == a.n_attr ) return true; + return false; + } + + template + static + typename MeshType::template PerMeshAttributeHandle + AddPerMeshAttribute( MeshType & m, std::string name){ + PAIte i; + PointerToAttribute h; + h._name = name; + if(!name.empty()){ + i = m.mesh_attr.find(h); + assert(i ==m.mesh_attr.end() );// an attribute with this name exists } + h._sizeof = sizeof(ATTR_TYPE); + 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); + } - /// Per Mesh Attributes - template - 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) - if ( (*i).n_attr == a.n_attr ) return true; - return false; - } - - template - static - typename MeshType::template PerMeshAttributeHandle - AddPerMeshAttribute( MeshType & m, std::string name){ - PAIte i; - PointerToAttribute h; - h._name = name; - if(!name.empty()){ - i = m.mesh_attr.find(h); - assert(i ==m.mesh_attr.end() );// an attribute with this name exists - } - h._sizeof = sizeof(ATTR_TYPE); - 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 + /*! \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. */ - template - static - typename MeshType::template PerMeshAttributeHandle - GetPerMeshAttribute( MeshType & m, std::string name = std::string("")){ - typename MeshType::template PerMeshAttributeHandle h; - if(!name.empty()){ - h = FindPerMeshAttribute(m,name); - if(IsValidHandle(m,h)) - return h; - } - return AddPerMeshAttribute(m,name); + template + static + typename MeshType::template PerMeshAttributeHandle + GetPerMeshAttribute( MeshType & m, std::string name = std::string("")){ + typename MeshType::template PerMeshAttributeHandle h; + if(!name.empty()){ + h = FindPerMeshAttribute(m,name); + if(IsValidHandle(m,h)) + return h; } + return AddPerMeshAttribute(m,name); + } - template - static - typename MeshType::template PerMeshAttributeHandle - FindPerMeshAttribute( MeshType & m, const std::string & name){ - assert(!name.empty()); - PointerToAttribute h1; h1._name = name; - typename std::set ::iterator i; + template + static + typename MeshType::template PerMeshAttributeHandle + 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)._padding != 0 ){ - PointerToAttribute attr = (*i); // copy the PointerToAttribute - m.mesh_attr.erase(i); // remove it from the set - FixPaddedPerMeshAttribute(m,attr); - std::pair new_i = m.mesh_attr.insert(attr); // insert the modified PointerToAttribute - assert(new_i.second); - i = new_i.first; - } - - return typename MeshType::template PerMeshAttributeHandle((*i)._handle,(*i).n_attr); + i =m.mesh_attr.find(h1); + if(i!=m.mesh_attr.end()) + 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 + FixPaddedPerMeshAttribute(m,attr); + std::pair new_i = m.mesh_attr.insert(attr); // insert the modified PointerToAttribute + assert(new_i.second); + i = new_i.first; } - return typename MeshType:: template PerMeshAttributeHandle(NULL,0); - } + return typename MeshType::template PerMeshAttributeHandle((*i)._handle,(*i).n_attr); + } - template - 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)) - all.push_back((*i)._name); - } + return typename MeshType:: template PerMeshAttributeHandle(NULL,0); + } - /*! \brief If the per-mesh attribute exists, delete it. + template + 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)) + 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, std::string name){ - AttrIterator i; - PointerToAttribute h1; h1._name = name; - i = m.mesh_attr.find(h1); - assert(i!=m.mesh_attr.end()); - delete ((SimpleTempDataBase *)(*i)._handle); + 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, std::string name){ + AttrIterator i; + PointerToAttribute h1; h1._name = name; + i = m.mesh_attr.find(h1); + assert(i!=m.mesh_attr.end()); + delete ((SimpleTempDataBase *)(*i)._handle); + m.mesh_attr.erase(i); + } + + template + static void FixPaddedPerVertexAttribute (MeshType & m, PointerToAttribute & 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(size_t 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 ]) ,sizeof(ATTR_TYPE)); } - template - static void FixPaddedPerVertexAttribute (MeshType & m, PointerToAttribute & pa){ + // remove the padded container + delete ((SimpleTempDataBase*) pa._handle); - // create the container of the right type - SimpleTempData* _handle = new SimpleTempData(m.vert); + // update the pointer to data + pa._sizeof = sizeof(ATTR_TYPE); - // copy the padded container in the new one - _handle->Resize(m.vert.size()); - for(unsigned 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 ]) ,sizeof(ATTR_TYPE)); - } + // update the pointer to data + pa._handle = _handle; - // remove the padded container - delete ((SimpleTempDataBase*) pa._handle); + // zero the padding + pa._padding = 0; + } + template + static void FixPaddedPerEdgeAttribute (MeshType & m, PointerToAttribute & pa){ - // update the pointer to data - pa._sizeof = sizeof(ATTR_TYPE); + // create the container of the right type + SimpleTempData* _handle = new SimpleTempData(m.edge); - // update the pointer to data - pa._handle = _handle; - - // zero the padding - pa._padding = 0; - } - template - static void FixPaddedPerEdgeAttribute (MeshType & m, PointerToAttribute & pa){ - - // create the container of the right type - SimpleTempData* _handle = new SimpleTempData(m.edge); - - // copy the padded container in the new one - _handle->Resize(m.edge.size()); - for(unsigned int i = 0; i < m.edge.size(); ++i){ - ATTR_TYPE * dest = &(*_handle)[i]; - char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); - memcpy((void*)dest , - (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); - } - - // remove the padded container - delete ((SimpleTempDataBase*) pa._handle); - - // update the pointer to data - pa._sizeof = sizeof(ATTR_TYPE); - - // update the pointer to data - pa._handle = _handle; - - // zero the padding - pa._padding = 0; + // copy the padded container in the new one + _handle->Resize(m.edge.size()); + for(size_t i = 0; i < m.edge.size(); ++i){ + ATTR_TYPE * dest = &(*_handle)[i]; + char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); + memcpy((void*)dest , + (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); } - template - static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){ + // remove the padded container + delete ((SimpleTempDataBase*) pa._handle); - // create the container of the right type - SimpleTempData* _handle = new SimpleTempData(m.face); + // update the pointer to data + pa._sizeof = sizeof(ATTR_TYPE); - // copy the padded container in the new one - _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 , - (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); - } + // update the pointer to data + pa._handle = _handle; - // remove the padded container - delete ((SimpleTempDataBase*) pa._handle); + // zero the padding + pa._padding = 0; + } - // update the pointer to data - pa._sizeof = sizeof(ATTR_TYPE); + template + static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){ - // update the pointer to data - pa._handle = _handle; + // create the container of the right type + SimpleTempData* _handle = new SimpleTempData(m.face); - // zero the padding - pa._padding = 0; + // copy the padded container in the new one + _handle->Resize(m.face.size()); + for(size_t i = 0; i < m.face.size(); ++i){ + ATTR_TYPE * dest = &(*_handle)[i]; + char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); + memcpy((void*)dest , + (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); } + // remove the padded container + delete ((SimpleTempDataBase*) pa._handle); - template - static void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){ + // update the pointer to data + pa._sizeof = sizeof(ATTR_TYPE); - // create the container of the right type - Attribute * _handle = new Attribute(); + // update the pointer to data + pa._handle = _handle; - // 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)); + // zero the padding + pa._padding = 0; + } - // remove the padded container - delete ( (Attribute *) pa._handle); - // update the pointer to data - pa._sizeof = sizeof(ATTR_TYPE); + template + static void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){ - // update the pointer to data - pa._handle = _handle; + // create the container of the right type + Attribute * _handle = new Attribute(); - // zero the padding - pa._padding = 0; - } + // 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)); + + // remove the padded container + delete ( (Attribute *) pa._handle); + + // update the pointer to data + pa._sizeof = sizeof(ATTR_TYPE); + + // update the pointer to data + pa._handle = _handle; + + // zero the padding + pa._padding = 0; + } }; // end Allocator class