allocate.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004-2014                                           \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 #ifndef __VCGLIB_TRIALLOCATOR
00024 #define __VCGLIB_TRIALLOCATOR
00025 
00026 #ifndef __VCG_MESH
00027 #error "This file should not be included alone. It is automatically included by complex.h"
00028 #endif
00029 
00030 namespace vcg {
00031 namespace tri {
00036 template<class MeshType>
00037 size_t Index(MeshType &m, const typename MeshType::VertexType &v) {return &v-&*m.vert.begin();}
00038 template<class MeshType>
00039 size_t Index(MeshType &m, const typename MeshType::FaceType &f) {return &f-&*m.face.begin();}
00040 template<class MeshType>
00041 size_t Index(MeshType &m, const typename MeshType::EdgeType &e) {return &e-&*m.edge.begin();}
00042 template<class MeshType>
00043 size_t Index(MeshType &m, const typename MeshType::HEdgeType &h) {return &h-&*m.hedge.begin();}
00044 
00045 template<class MeshType>
00046 size_t Index(MeshType &m, const typename MeshType::VertexType *vp) {return vp-&*m.vert.begin();}
00047 template<class MeshType>
00048 size_t Index(MeshType &m, const typename MeshType::FaceType * fp) {return fp-&*m.face.begin();}
00049 template<class MeshType>
00050 size_t Index(MeshType &m, const typename MeshType::EdgeType*  e) {return e-&*m.edge.begin();}
00051 template<class MeshType>
00052 size_t Index(MeshType &m, const typename MeshType::HEdgeType*  h) {return h-&*m.hedge.begin();}
00053 
00054 template<class MeshType>
00055 bool IsValidPointer( MeshType & m, const typename MeshType::VertexType *vp) { return ( (vp >= &*m.vert.begin()) && ( vp < &*m.vert.end()) ); }
00056 template<class MeshType>
00057 bool IsValidPointer( MeshType & m, const typename MeshType::EdgeType   *ep) { return ( (ep >= &*m.edge.begin()) && ( ep < &*m.edge.end()) ); }
00058 template<class MeshType>
00059 bool IsValidPointer( MeshType & m, const typename MeshType::FaceType   *fp) { return ( (fp >= &*m.face.begin()) && ( fp < &*m.face.end()) ); }
00060 template<class MeshType>
00061 bool IsValidPointer( MeshType & m, const typename MeshType::HEdgeType  *hp) { return ( (hp >= &*m.hedge.begin())&& ( hp < &*m.hedge.end()) ); }
00062 
00063 template <class MeshType, class ATTR_CONT>
00064 void ReorderAttribute(ATTR_CONT &c, std::vector<size_t> & newVertIndex, MeshType & /* m */){
00065   typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
00066   for(ai = c.begin(); ai != c.end(); ++ai)
00067     ((typename MeshType::PointerToAttribute)(*ai)).Reorder(newVertIndex);
00068 }
00069 
00070 template <class MeshType, class ATTR_CONT>
00071 void ResizeAttribute(ATTR_CONT &c, size_t sz, MeshType &/*m*/){
00072   typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
00073   for(ai =c.begin(); ai != c.end(); ++ai)
00074     ((typename MeshType::PointerToAttribute)(*ai)).Resize(sz);
00075 }
00076 
00084 template <class MeshType>
00085 class Allocator
00086 {
00087 
00088 public:
00089   typedef typename MeshType::VertexType     VertexType;
00090   typedef typename MeshType::VertexPointer  VertexPointer;
00091   typedef typename MeshType::VertexIterator VertexIterator;
00092   typedef typename MeshType::VertContainer VertContainer;
00093 
00094   typedef typename MeshType::EdgeType     EdgeType;
00095   typedef typename MeshType::EdgePointer  EdgePointer;
00096   typedef typename MeshType::EdgeIterator EdgeIterator;
00097   typedef typename MeshType::EdgeContainer EdgeContainer;
00098 
00099   typedef typename MeshType::FaceType       FaceType;
00100   typedef typename MeshType::FacePointer    FacePointer;
00101   typedef typename MeshType::FaceIterator   FaceIterator;
00102   typedef typename MeshType::FaceContainer FaceContainer;
00103 
00104   typedef typename MeshType::HEdgeType     HEdgeType;
00105   typedef typename MeshType::HEdgePointer  HEdgePointer;
00106   typedef typename MeshType::HEdgeIterator HEdgeIterator;
00107   typedef typename MeshType::HEdgeContainer HEdgeContainer;
00108 
00109   typedef typename MeshType::CoordType     CoordType;
00110 
00111 
00112   typedef typename MeshType::PointerToAttribute PointerToAttribute;
00113   typedef typename std::set<PointerToAttribute>::iterator AttrIterator;
00114   typedef typename std::set<PointerToAttribute>::const_iterator AttrConstIterator;
00115   typedef typename std::set<PointerToAttribute >::iterator PAIte;
00116 
00128   template<class SimplexPointerType>
00129   class PointerUpdater
00130   {
00131   public:
00132     PointerUpdater(void) : newBase(0), oldBase(0), newEnd(0), oldEnd(0), preventUpdateFlag(false) { ; }
00133     void Clear(){newBase=oldBase=newEnd=oldEnd=0; remap.clear();}
00138     void Update(SimplexPointerType &vp)
00139     {
00140       //if(vp>=newBase && vp<newEnd) return;
00141       if(vp<oldBase || vp>oldEnd) return;
00142       assert(vp>=oldBase);
00143       assert(vp<oldEnd);
00144       vp=newBase+(vp-oldBase);
00145       if(!remap.empty())
00146         vp  = newBase + remap[vp-newBase];
00147     }
00151     bool NeedUpdate() {if((oldBase && newBase!=oldBase && !preventUpdateFlag) || !remap.empty()) return true; else return false;}
00152 
00153     SimplexPointerType newBase;
00154     SimplexPointerType oldBase;
00155     SimplexPointerType newEnd;
00156     SimplexPointerType oldEnd;
00157     std::vector<size_t> 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.
00158 
00159     bool preventUpdateFlag; 
00160   };
00161 
00162   /* +++++++++++++++ Add Vertices ++++++++++++++++ */
00163 
00174   static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater<VertexPointer> &pu)
00175   {
00176     VertexIterator last;
00177     if(n == 0) return m.vert.end();
00178     pu.Clear();
00179     if(m.vert.empty()) pu.oldBase=0;  // if the vector is empty we cannot find the last valid element
00180     else {
00181       pu.oldBase=&*m.vert.begin();
00182       pu.oldEnd=&m.vert.back()+1;
00183     }
00184 
00185     m.vert.resize(m.vert.size()+n);
00186     m.vn+=int(n);
00187 
00188     typename std::set<PointerToAttribute>::iterator ai;
00189     for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai)
00190       ((PointerToAttribute)(*ai)).Resize(m.vert.size());
00191 
00192     pu.newBase = &*m.vert.begin();
00193     pu.newEnd =  &m.vert.back()+1;
00194     if(pu.NeedUpdate())
00195     {
00196       for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
00197         if(!(*fi).IsD())
00198           for(int i=0; i < (*fi).VN(); ++i)
00199             if ((*fi).cV(i)!=0) pu.Update((*fi).V(i));
00200 
00201       for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
00202         if(!(*ei).IsD())
00203         {
00204           if(HasEVAdjacency (m)) { pu.Update((*ei).V(0)); pu.Update((*ei).V(1));}
00205           //                                                    if(HasEVAdjacency(m))   pu.Update((*ei).EVp());
00206         }
00207       HEdgeIterator hi;
00208       for (hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
00209         if(!(*hi).IsD())
00210         {
00211           if(HasHVAdjacency (m))
00212           {
00213             pu.Update((*hi).HVp());
00214           }
00215         }
00216 
00217       // e poiche' lo spazio e' cambiato si ricalcola anche last da zero
00218     }
00219     size_t siz=(size_t)(m.vert.size()-n);
00220 
00221     last = m.vert.begin();
00222     advance(last,siz);
00223 
00224     return last;// deve restituire l'iteratore alla prima faccia aggiunta;
00225   }
00226 
00229   static VertexIterator AddVertices(MeshType &m, size_t n)
00230   {
00231     PointerUpdater<VertexPointer> pu;
00232     return AddVertices(m, n,pu);
00233   }
00234 
00237   static VertexIterator AddVertices(MeshType &m, size_t n, std::vector<VertexPointer *> &local_vec)
00238   {
00239     PointerUpdater<VertexPointer> pu;
00240     VertexIterator v_ret =  AddVertices(m, n,pu);
00241 
00242     typename std::vector<VertexPointer *>::iterator vi;
00243     for(vi=local_vec.begin();vi!=local_vec.end();++vi)
00244       pu.Update(**vi);
00245     return v_ret;
00246   }
00247 
00250   static VertexIterator AddVertex(MeshType &m, const CoordType &p)
00251   {
00252     VertexIterator v_ret =  AddVertices(m, 1);
00253     v_ret->P()=p;
00254     return v_ret;
00255   }
00256 
00259   static VertexIterator AddVertex(MeshType &m, const CoordType &p,  const CoordType &n)
00260   {
00261     VertexIterator v_ret =  AddVertices(m, 1);
00262     v_ret->P()=p;
00263     v_ret->N()=n;
00264     return v_ret;
00265   }
00266 
00269   static VertexIterator AddVertex(MeshType &m, const CoordType &p, const Color4b &c)
00270   {
00271     VertexIterator v_ret =  AddVertices(m, 1);
00272     v_ret->P()=p;
00273     v_ret->C()=c;
00274     return v_ret;
00275   }
00276 
00277   /* +++++++++++++++ Add Edges ++++++++++++++++ */
00278 
00288   static EdgeIterator AddEdges(MeshType &m, size_t n, PointerUpdater<EdgePointer> &pu)
00289   {
00290     EdgeIterator last;
00291     if(n == 0) return m.edge.end();
00292     pu.Clear();
00293     if(m.edge.empty()) pu.oldBase=0;  // if the vector is empty we cannot find the last valid element
00294     else {
00295       pu.oldBase=&*m.edge.begin();
00296       pu.oldEnd=&m.edge.back()+1;
00297     }
00298 
00299     m.edge.resize(m.edge.size()+n);
00300     m.en+=int(n);
00301 
00302     typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
00303     for(ai = m.edge_attr.begin(); ai != m.edge_attr.end(); ++ai)
00304       ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.edge.size());
00305 
00306     pu.newBase = &*m.edge.begin();
00307     pu.newEnd =  &m.edge.back()+1;
00308     if(pu.NeedUpdate())
00309     {
00310       if(HasFEAdjacency(m))
00311         for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi){
00312           if(!(*fi).IsD())
00313             for(int i=0; i < (*fi).VN(); ++i)
00314               if ((*fi).cFEp(i)!=0) pu.Update((*fi).FEp(i));
00315         }
00316 
00317       if(HasVEAdjacency(m))
00318         for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00319           if(!(*vi).IsD())
00320             if ((*vi).cVEp()!=0) pu.Update((*vi).VEp());
00321 
00322       if(HasHEAdjacency(m))
00323         for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
00324           if(!(*hi).IsD())
00325             if ((*hi).cHEp()!=0) pu.Update((*hi).HEp());
00326     }
00327     size_t siz=(size_t)(m.edge.size()-n);
00328 
00329     last = m.edge.begin();
00330     advance(last,siz);
00331 
00332     return last;// deve restituire l'iteratore alla prima faccia aggiunta;
00333   }
00334 
00337   static EdgeIterator AddEdge(MeshType &m, VertexPointer v0, VertexPointer v1)
00338   {
00339     EdgeIterator ei= AddEdges(m, 1);
00340     ei->V(0)=v0;
00341     ei->V(1)=v1;
00342     return ei;
00343   }
00344 
00347   static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1)
00348   {
00349     VertexIterator vi = AddVertices(m,2);
00350     EdgeIterator ei = AddEdges(m,1);
00351     vi->P()=p0;
00352     ei->V(0)=&*vi++;
00353     vi->P()=p1;
00354     ei->V(1)=&*vi++;
00355     return ei;
00356   }
00357 
00361   static EdgeIterator AddEdges(MeshType &m, size_t n)
00362   {
00363     PointerUpdater<EdgePointer> pu;
00364     return AddEdges(m, n,pu);
00365   }
00366 
00370   static EdgeIterator AddEdges(MeshType &m, size_t n, std::vector<EdgePointer*> &local_vec)
00371   {
00372     PointerUpdater<EdgePointer> pu;
00373     EdgeIterator v_ret =  AddEdges(m, n,pu);
00374 
00375     typename std::vector<EdgePointer *>::iterator ei;
00376     for(ei=local_vec.begin();ei!=local_vec.end();++ei)
00377       pu.Update(**ei);
00378     return v_ret;
00379   }
00380 
00381   /* +++++++++++++++ Add HalfEdges ++++++++++++++++ */
00382 
00392   static HEdgeIterator AddHEdges(MeshType &m, size_t n, PointerUpdater<HEdgePointer> &pu)
00393   {
00394     HEdgeIterator last;
00395     if(n == 0) return m.hedge.end();
00396     pu.Clear();
00397     if(m.hedge.empty()) pu.oldBase=0;  // if the vector is empty we cannot find the last valid element
00398     else {
00399       pu.oldBase=&*m.hedge.begin();
00400       pu.oldEnd=&m.hedge.back()+1;
00401     }
00402 
00403     m.hedge.resize(m.hedge.size()+n);
00404     m.hn+=int(n);
00405 
00406     pu.newBase = &*m.hedge.begin();
00407     pu.newEnd =  &m.hedge.back()+1;
00408 
00409     if(pu.NeedUpdate())
00410     {
00411       if(HasFHAdjacency(m)) {
00412         for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
00413         {
00414           if(!(*fi).IsD() && (*fi).FHp())
00415             pu.Update((*fi).FHp());
00416         }
00417       }
00418       if(HasVHAdjacency(m)) {
00419         for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00420           if(!(*vi).IsD() && (*vi).cVHp()!=0)
00421               pu.Update((*vi).VHp());
00422       }
00423       if(HasEHAdjacency(m)) {
00424         for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
00425           if(!(*ei).IsD() && (*ei).cEHp()!=0)
00426               pu.Update((*ei).EHp());
00427       }
00428 
00429       int ii = 0;
00430       HEdgeIterator hi = m.hedge.begin();
00431       while(ii < m.hn - int(n))// cycle on all the faces except the new ones
00432       {
00433         if(!(*hi).IsD())
00434         {
00435           if(HasHNextAdjacency(m)) pu.Update((*hi).HNp());
00436           if(HasHPrevAdjacency(m)) pu.Update((*hi).HPp());
00437           if(HasHOppAdjacency(m)) pu.Update((*hi).HOp());
00438           ++ii;
00439         }
00440         ++hi;
00441       }
00442     }
00443     size_t siz = (size_t)(m.hedge.size()-n);
00444 
00445     last = m.hedge.begin();
00446     advance(last,siz);
00447 
00448     return last;// deve restituire l'iteratore alla prima faccia aggiunta;
00449   }
00450 
00454   static HEdgeIterator AddHEdges(MeshType &m, size_t n)
00455   {
00456     PointerUpdater<HEdgePointer> pu;
00457     return AddHEdges(m, n,pu);
00458   }
00459 
00463   static HEdgeIterator AddHEdges(MeshType &m, size_t n, std::vector<HEdgePointer*> &local_vec)
00464   {
00465     PointerUpdater<HEdgePointer> pu;
00466     HEdgeIterator v_ret =  AddHEdges(m, n,pu);
00467 
00468     typename std::vector<HEdgePointer *>::iterator ei;
00469     for(ei=local_vec.begin();ei!=local_vec.end();++ei)
00470       pu.Update(**ei);
00471     return v_ret;
00472   }
00473 
00474   /* +++++++++++++++ Add Faces ++++++++++++++++ */
00475 
00478   static FaceIterator AddFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2)
00479   {
00480     assert(m.vert.size()>0);
00481     assert((v0!=v1) && (v1!=v2) && (v0!=v2));
00482     assert(v0>=&m.vert.front() && v0<=&m.vert.back());
00483     assert(v1>=&m.vert.front() && v1<=&m.vert.back());
00484     assert(v2>=&m.vert.front() && v2<=&m.vert.back());
00485     PointerUpdater<FacePointer> pu;
00486     FaceIterator fi = AddFaces(m,1,pu);
00487     fi->Alloc(3);
00488     fi->V(0)=v0;
00489     fi->V(1)=v1;
00490     fi->V(2)=v2;
00491     return fi;
00492   }
00493 
00496   static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2)
00497   {
00498     assert((v0!=v1) && (v1!=v2) && (v0!=v2));
00499     assert(v0>=0 && v0<=m.vert.size());
00500     assert(v1>=0 && v1<=m.vert.size());
00501     assert(v2>=0 && v2<=m.vert.size());
00502     return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2]));
00503   }
00506   static FaceIterator AddFace(MeshType &m, CoordType p0, CoordType p1, CoordType p2)
00507   {
00508     VertexIterator vi = AddVertices(m,3);
00509     FaceIterator fi = AddFaces(m,1);
00510     fi->Alloc(3);
00511     vi->P()=p0;
00512     fi->V(0)=&*vi++;
00513     vi->P()=p1;
00514     fi->V(1)=&*vi++;
00515     vi->P()=p2;
00516     fi->V(2)=&*vi;
00517     return fi;
00518   }
00519 
00524   static FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
00525   {
00526     assert(m.vert.size()>0);
00527     assert(v0>=&m.vert.front() && v0<=&m.vert.back());
00528     assert(v1>=&m.vert.front() && v1<=&m.vert.back());
00529     assert(v2>=&m.vert.front() && v2<=&m.vert.back());
00530     assert(v3>=&m.vert.front() && v3<=&m.vert.back());
00531     PointerUpdater<FacePointer> pu;
00532     if(FaceType::HasPolyInfo())
00533     {
00534       FaceIterator fi = AddFaces(m,1,pu);
00535       fi->Alloc(4);
00536       fi->V(0)=v0; fi->V(1)=v1;
00537       fi->V(2)=v2; fi->V(3)=v3;
00538       return fi;
00539     }
00540     else
00541     {
00542       FaceIterator fi = AddFaces(m,2,pu);
00543       fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v1; fi->V(2)=v2;
00544       fi->SetF(2);
00545       ++fi;
00546       fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v2; fi->V(2)=v3;
00547       fi->SetF(0);
00548       return fi;
00549     }
00550   }
00554   static FaceIterator AddFaces(MeshType &m, size_t n)
00555   {
00556     PointerUpdater<FacePointer> pu;
00557     return AddFaces(m,n,pu);
00558   }
00559 
00563   static FaceIterator AddFaces(MeshType &m, size_t n,std::vector<FacePointer *> &local_vec)
00564   {
00565     PointerUpdater<FacePointer> pu;
00566     FaceIterator f_ret= AddFaces(m,n,pu);
00567 
00568     typename std::vector<FacePointer *>::iterator fi;
00569     for(fi=local_vec.begin();fi!=local_vec.end();++fi)
00570       pu.Update(**fi);
00571     return f_ret;
00572   }
00573 
00586   static FaceIterator AddFaces(MeshType &m, size_t n, PointerUpdater<FacePointer> &pu)
00587   {
00588     pu.Clear();
00589     if(n == 0) return m.face.end();
00590     if(!m.face.empty()) // if the vector is empty we cannot find the last valid element
00591     {
00592       pu.oldBase=&*m.face.begin();
00593       pu.oldEnd=&m.face.back()+1;
00594     }
00595     // The actual resize
00596     m.face.resize(m.face.size()+n);
00597     m.fn+=int(n);
00598 
00599     size_t siz=(size_t)(m.face.size()-n);
00600     FaceIterator firstNewFace = m.face.begin();
00601     advance(firstNewFace,siz);
00602 
00603     typename std::set<PointerToAttribute>::iterator ai;
00604     for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai)
00605       ((PointerToAttribute)(*ai)).Resize(m.face.size());
00606 
00607     pu.newBase = &*m.face.begin();
00608     pu.newEnd  = &m.face.back()+1;
00609 
00610     if(pu.NeedUpdate())
00611     {
00612       if(HasFFAdjacency(m))
00613       {  // cycle on all the faces except the new ones
00614         for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi)
00615           if(!(*fi).IsD())
00616             for(int i  = 0; i < (*fi).VN(); ++i)
00617               if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i));
00618       }
00619 
00620       if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m))
00621       {  // cycle on all the faces except the new ones
00622         for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi)
00623           if(!(*fi).IsD())
00624             for(int i = 0; i < (*fi).VN(); ++i)
00625               if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i));
00626 
00627         for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00628           if(!(*vi).IsD() && (*vi).cVFp()!=0)
00629             pu.Update((*vi).VFp());
00630       }
00631 
00632       if(HasEFAdjacency(m))
00633       {
00634         for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
00635           if(!(*ei).IsD() && (*ei).cEFp()!=0)
00636             pu.Update((*ei).EFp());
00637       }
00638 
00639       if(HasHFAdjacency(m))
00640       {
00641         for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
00642           if(!(*hi).IsD() && (*hi).cHFp()!=0)
00643             pu.Update((*hi).HFp());
00644       }
00645     }
00646     return firstNewFace;
00647   }
00648 
00649   /* +++++++++++++++ Deleting  ++++++++++++++++ */
00650 
00654   static void DeleteFace(MeshType &m, FaceType &f)
00655   {
00656     assert(&f >= &m.face.front() && &f <= &m.face.back());
00657     assert(!f.IsD());
00658     f.Dealloc();
00659     f.SetD();
00660     --m.fn;
00661   }
00662 
00666   static void DeleteVertex(MeshType &m, VertexType &v)
00667   {
00668     assert(&v >= &m.vert.front() && &v <= &m.vert.back());
00669     assert(!v.IsD());
00670     v.SetD();
00671     --m.vn;
00672   }
00673 
00677   static void DeleteEdge(MeshType &m, EdgeType &e)
00678   {
00679     assert(&e >= &m.edge.front() && &e <= &m.edge.back());
00680     assert(!e.IsD());
00681     e.SetD();
00682     --m.en;
00683   }
00684 
00688   static void DeleteHEdge(MeshType &m, HEdgeType &h)
00689   {
00690     assert(&h >= &m.hedge.front() && &h <= &m.hedge.back());
00691     assert(!h.IsD());
00692     h.SetD();
00693     --m.hn;
00694   }
00695 
00696   /*
00697             Function to rearrange the vertex vector according to a given index permutation
00698             the permutation is vector such that after calling this function
00699 
00700                             m.vert[ newVertIndex[i] ] = m.vert[i];
00701 
00702             e.g. newVertIndex[i] is the new index of the vertex i
00703 
00704            */
00705   static void PermutateVertexVector(MeshType &m, PointerUpdater<VertexPointer> &pu)
00706   {
00707     if(m.vert.empty()) return;
00708     for(size_t i=0;i<m.vert.size();++i)
00709     {
00710       if(pu.remap[i]<size_t(m.vn))
00711       {
00712         assert(!m.vert[i].IsD());
00713         m.vert[ pu.remap [i] ].ImportData(m.vert[i]);
00714         if(HasVFAdjacency(m))
00715         {
00716           if (m.vert[i].IsVFInitialized())
00717           {
00718             m.vert[ pu.remap[i] ].VFp() = m.vert[i].cVFp();
00719             m.vert[ pu.remap[i] ].VFi() = m.vert[i].cVFi();
00720           }
00721           else m.vert [ pu.remap[i] ].VFClear();
00722         }
00723         if(HasVEAdjacency(m))
00724         {
00725           if (m.vert[i].IsVEInitialized())
00726           {
00727             m.vert[ pu.remap[i] ].VEp() = m.vert[i].cVEp();
00728             m.vert[ pu.remap[i] ].VEi() = m.vert[i].cVEi();
00729           }
00730           else m.vert [ pu.remap[i] ].VEClear();
00731         }
00732       }
00733     }
00734 
00735     // reorder the optional atttributes in m.vert_attr to reflect the changes
00736     ReorderAttribute(m.vert_attr,pu.remap,m);
00737 
00738     // setup the pointer updater
00739     pu.oldBase  = &m.vert[0];
00740     pu.oldEnd = &m.vert.back()+1;
00741 
00742     // resize
00743     m.vert.resize(m.vn);
00744 
00745     // setup the pointer updater
00746     pu.newBase  = (m.vert.empty())?0:&m.vert[0];
00747     pu.newEnd = (m.vert.empty())?0:&m.vert.back()+1;
00748 
00749     // resize the optional atttributes in m.vert_attr to reflect the changes
00750     ResizeAttribute(m.vert_attr,m.vn,m);
00751 
00752     // Loop on the face to update the pointers FV relation (vertex refs)
00753     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00754       if(!(*fi).IsD())
00755         for(int i=0;i<fi->VN();++i)
00756         {
00757           size_t oldIndex = (*fi).V(i) - pu.oldBase;
00758           assert(pu.oldBase <= (*fi).V(i) && oldIndex < pu.remap.size());
00759           (*fi).V(i) = pu.newBase+pu.remap[oldIndex];
00760         }
00761     // Loop on the edges to update the pointers EV relation
00762     if(HasEVAdjacency(m))
00763       for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00764         if(!(*ei).IsD())
00765         {
00766           pu.Update((*ei).V(0));
00767           pu.Update((*ei).V(1));
00768         }
00769   }
00770 
00771   static void CompactEveryVector( MeshType &m)
00772   {
00773     CompactVertexVector(m);
00774     CompactEdgeVector(m);
00775     CompactFaceVector(m);
00776   }
00777 
00778 
00786   static void CompactVertexVector( MeshType &m,   PointerUpdater<VertexPointer> &pu   )
00787   {
00788     // If already compacted fast return please!
00789     if(m.vn==(int)m.vert.size()) return;
00790 
00791     // newVertIndex [ <old_vert_position> ] gives you the new position of the vertex in the vector;
00792     pu.remap.resize( m.vert.size(),std::numeric_limits<size_t>::max() );
00793 
00794     size_t pos=0;
00795     size_t i=0;
00796 
00797     for(i=0;i<m.vert.size();++i)
00798     {
00799       if(!m.vert[i].IsD())
00800       {
00801         pu.remap[i]=pos;
00802         ++pos;
00803       }
00804     }
00805     assert((int)pos==m.vn);
00806 
00807     PermutateVertexVector(m, pu);
00808 
00809   }
00810 
00812   static void CompactVertexVector( MeshType &m  ) {
00813     PointerUpdater<VertexPointer>  pu;
00814     CompactVertexVector(m,pu);
00815   }
00816 
00825   static void CompactEdgeVector( MeshType &m,   PointerUpdater<EdgePointer> &pu   )
00826   {
00827     // If already compacted fast return please!
00828     if(m.en==(int)m.edge.size()) return;
00829 
00830     // remap [ <old_edge_position> ] gives you the new position of the edge in the vector;
00831     pu.remap.resize( m.edge.size(),std::numeric_limits<size_t>::max() );
00832 
00833     size_t pos=0;
00834     size_t i=0;
00835 
00836     for(i=0;i<m.edge.size();++i)
00837     {
00838       if(!m.edge[i].IsD())
00839       {
00840         pu.remap[i]=pos;
00841         ++pos;
00842       }
00843     }
00844     assert((int)pos==m.en);
00845 
00846     // the actual copying of the data.
00847     for(size_t i=0;i<m.edge.size();++i)
00848     {
00849       if(pu.remap[i]<size_t(m.en))  // uninitialized entries in the remap vector has max_int value;
00850       {
00851         assert(!m.edge[i].IsD());
00852         m.edge[ pu.remap [i] ].ImportData(m.edge[i]);
00853         // copy the vertex reference (they are not data!)
00854         m.edge[ pu.remap[i] ].V(0) = m.edge[i].cV(0);
00855         m.edge[ pu.remap[i] ].V(1) = m.edge[i].cV(1);
00856         // Now just copy the adjacency pointers (without changing them, to be done later)
00857         if(HasVEAdjacency(m))
00858           //if (m.edge[i].cVEp(0)!=0)
00859           {
00860             m.edge[ pu.remap[i] ].VEp(0) = m.edge[i].cVEp(0);
00861             m.edge[ pu.remap[i] ].VEi(0) = m.edge[i].cVEi(0);
00862             m.edge[ pu.remap[i] ].VEp(1) = m.edge[i].cVEp(1);
00863             m.edge[ pu.remap[i] ].VEi(1) = m.edge[i].cVEi(1);
00864           }
00865         if(HasEEAdjacency(m))
00866           if (m.edge[i].cEEp(0)!=0)
00867           {
00868             m.edge[ pu.remap[i] ].EEp(0) = m.edge[i].cEEp(0);
00869             m.edge[ pu.remap[i] ].EEi(0) = m.edge[i].cEEi(0);
00870             m.edge[ pu.remap[i] ].EEp(1) = m.edge[i].cEEp(1);
00871             m.edge[ pu.remap[i] ].EEi(1) = m.edge[i].cEEi(1);
00872           }
00873       }
00874     }
00875 
00876     // reorder the optional attributes in m.vert_attr to reflect the changes
00877     ReorderAttribute(m.edge_attr, pu.remap,m);
00878 
00879     // setup the pointer updater
00880     pu.oldBase  = &m.edge[0];
00881     pu.oldEnd = &m.edge.back()+1;
00882 
00883     // THE resize
00884     m.edge.resize(m.en);
00885 
00886     // setup the pointer updater
00887     pu.newBase  = (m.edge.empty())?0:&m.edge[0];
00888     pu.newEnd = (m.edge.empty())?0:&m.edge.back()+1;
00889 
00890     // resize the optional atttributes in m.vert_attr to reflect the changes
00891     ResizeAttribute(m.edge_attr,m.en,m);
00892 
00893     // Loop on the vertices to update the pointers of VE relation
00894     if(HasVEAdjacency(m))
00895       for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00896         if(!(*vi).IsD())  pu.Update((*vi).VEp());
00897 
00898     // Loop on the edges to update the pointers EE VE relation
00899     for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00900       for(unsigned int i=0;i<2;++i)
00901       {
00902         if(HasVEAdjacency(m))
00903           pu.Update((*ei).VEp(i));
00904         if(HasEEAdjacency(m))
00905           pu.Update((*ei).EEp(i));
00906       }
00907   }
00908 
00910   static void CompactEdgeVector( MeshType &m  ) {
00911     PointerUpdater<EdgePointer>  pu;
00912     CompactEdgeVector(m,pu);
00913   }
00914 
00923   static void CompactFaceVector( MeshType &m, PointerUpdater<FacePointer> &pu )
00924   {
00925     // If already compacted fast return please!
00926     if(m.fn==(int)m.face.size()) return;
00927 
00928     // newFaceIndex [ <old_face_position> ] gives you the new position of the face in the vector;
00929     pu.remap.resize( m.face.size(),std::numeric_limits<size_t>::max() );
00930 
00931     size_t pos=0;
00932     for(size_t i=0;i<m.face.size();++i)
00933     {
00934       if(!m.face[i].IsD())
00935       {
00936         if(pos!=i)
00937         {
00938           m.face[pos].ImportData(m.face[i]);
00939           if(FaceType::HasPolyInfo())
00940           {
00941             m.face[pos].Dealloc();
00942             m.face[pos].Alloc(m.face[i].VN());
00943           }
00944           for(int j=0;j<m.face[i].VN();++j)
00945             m.face[pos].V(j) = m.face[i].V(j);
00946 
00947           if(HasVFAdjacency(m))
00948             for(int j=0;j<m.face[i].VN();++j)
00949             {
00950               if (m.face[i].IsVFInitialized(j)) {
00951                 m.face[pos].VFp(j) = m.face[i].cVFp(j);
00952                 m.face[pos].VFi(j) = m.face[i].cVFi(j);
00953               }
00954               else m.face[pos].VFClear(j);
00955             }
00956           if(HasFFAdjacency(m))
00957             for(int j=0;j<m.face[i].VN();++j)
00958               {
00959                 m.face[pos].FFp(j) = m.face[i].cFFp(j);
00960                 m.face[pos].FFi(j) = m.face[i].cFFi(j);
00961               }
00962         }
00963         pu.remap[i]=pos;
00964         ++pos;
00965       }
00966     }
00967     assert((int)pos==m.fn);
00968 
00969     // reorder the optional atttributes in m.face_attr to reflect the changes
00970     ReorderAttribute(m.face_attr,pu.remap,m);
00971 
00972     FacePointer fbase=&m.face[0];
00973 
00974     // Loop on the vertices to correct VF relation
00975     if(HasVFAdjacency(m))
00976     {
00977       for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00978         if(!(*vi).IsD())
00979         {
00980           if ((*vi).IsVFInitialized() && (*vi).VFp()!=0 )
00981           {
00982             size_t oldIndex = (*vi).cVFp() - fbase;
00983             assert(fbase <= (*vi).cVFp() && oldIndex < pu.remap.size());
00984             (*vi).VFp() = fbase+pu.remap[oldIndex];
00985           }
00986         }
00987     }
00988 
00989     // Loop on the faces to correct VF and FF relations
00990     pu.oldBase  = &m.face[0];
00991     pu.oldEnd = &m.face.back()+1;
00992     for(size_t i=m.fn;i<m.face.size();++i)
00993       m.face[i].Dealloc();
00994     m.face.resize(m.fn);
00995     pu.newBase  = (m.face.empty())?0:&m.face[0];
00996     pu.newEnd = (m.face.empty())?0:&m.face.back()+1;
00997 
00998 
00999     // resize the optional atttributes in m.face_attr to reflect the changes
01000     ResizeAttribute(m.face_attr,m.fn,m);
01001 
01002     // now we update the various (not null) face pointers (inside VF and FF relations)
01003     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
01004       if(!(*fi).IsD())
01005       {
01006         if(HasVFAdjacency(m))
01007           for(int i=0;i<(*fi).VN();++i)
01008             if ((*fi).IsVFInitialized(i) && (*fi).VFp(i)!=0 )
01009             {
01010               size_t oldIndex = (*fi).VFp(i) - fbase;
01011               assert(fbase <= (*fi).VFp(i) && oldIndex < pu.remap.size());
01012               (*fi).VFp(i) = fbase+pu.remap[oldIndex];
01013             }
01014         if(HasFFAdjacency(m))
01015           for(int i=0;i<(*fi).VN();++i)
01016             if ((*fi).cFFp(i)!=0)
01017             {
01018               size_t oldIndex = (*fi).FFp(i) - fbase;
01019                           assert(fbase <= (*fi).FFp(i) && oldIndex < pu.remap.size());
01020               (*fi).FFp(i) = fbase+pu.remap[oldIndex];
01021             }
01022       }
01023 
01024 
01025 
01026   }
01027 
01029   static void CompactFaceVector( MeshType &m  ) {
01030     PointerUpdater<FacePointer>  pu;
01031     CompactFaceVector(m,pu);
01032   }
01033 
01034 
01035 
01036 public:
01037 
01040   template <class ATTR_TYPE>
01041   static
01042   bool IsValidHandle( MeshType & m,  const typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & a){
01043     if(a._handle == NULL) return false;
01044     for(AttrIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i)
01045       if ( (*i).n_attr == a.n_attr ) return true;
01046     return false;
01047   }
01048 
01053   template <class ATTR_TYPE>
01054   static
01055   typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
01056   AddPerVertexAttribute( MeshType & m, std::string name){
01057     PAIte i;
01058     PointerToAttribute h;
01059     h._name = name;
01060     if(!name.empty()){
01061       i = m.vert_attr.find(h);
01062       assert(i ==m.vert_attr.end() );// an attribute with this name exists
01063     }
01064 
01065     h._sizeof = sizeof(ATTR_TYPE);
01066     h._padding = 0;
01067     h._handle =   new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
01068     m.attrn++;
01069     h.n_attr = m.attrn;
01070     std::pair < AttrIterator , bool> res =  m.vert_attr.insert(h);
01071     return typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr );
01072   }
01073 
01074   template <class ATTR_TYPE>
01075   static typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
01076   AddPerVertexAttribute( MeshType & m){
01077     return AddPerVertexAttribute<ATTR_TYPE>(m,std::string(""));
01078   }
01079 
01084   template <class ATTR_TYPE>
01085   static
01086   typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
01087   GetPerVertexAttribute( MeshType & m, std::string name = std::string("")){
01088     typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> h;
01089     if(!name.empty()){
01090       h =  FindPerVertexAttribute<ATTR_TYPE>(m,name);
01091       if(IsValidHandle(m,h))
01092         return h;
01093     }
01094     return AddPerVertexAttribute<ATTR_TYPE>(m,name);
01095   }
01096 
01100   template <class ATTR_TYPE>
01101   static typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
01102   FindPerVertexAttribute( MeshType & m, const std::string & name)
01103   {
01104     assert(!name.empty());
01105     PointerToAttribute h1; h1._name = name;
01106     typename std::set<PointerToAttribute > :: iterator i;
01107 
01108     i =m.vert_attr.find(h1);
01109     if(i!=m.vert_attr.end())
01110       if((*i)._sizeof == sizeof(ATTR_TYPE) ){
01111         if(     (*i)._padding != 0 ){
01112           PointerToAttribute attr = (*i);                                               // copy the PointerToAttribute
01113           m.vert_attr.erase(i);                                         // remove it from the set
01114           FixPaddedPerVertexAttribute<ATTR_TYPE>(m,attr);
01115           std::pair<AttrIterator,bool> new_i = m.vert_attr.insert(attr);        // insert the modified PointerToAttribute
01116           assert(new_i.second);
01117           i = new_i.first;
01118         }
01119         return typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
01120       }
01121     return typename MeshType:: template PerVertexAttributeHandle<ATTR_TYPE>(NULL,0);
01122   }
01123 
01127   template <class ATTR_TYPE>
01128   static void GetAllPerVertexAttribute(MeshType & m, std::vector<std::string> &all){
01129     all.clear();
01130     typename std::set<PointerToAttribute > ::const_iterator i;
01131     for(i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i )
01132       if(!(*i)._name.empty())
01133       {
01134         typename MeshType:: template PerVertexAttributeHandle<ATTR_TYPE> hh;
01135         hh = Allocator<MeshType>:: template  FindPerVertexAttribute <ATTR_TYPE>(m,(*i)._name);
01136         if(IsValidHandle<ATTR_TYPE>(m,hh))
01137           all.push_back((*i)._name);
01138       }
01139   }
01140 
01141   template <class ATTR_TYPE>
01142   static
01143   void
01144   ClearPerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h){
01145     typename std::set<PointerToAttribute > ::iterator i;
01146     for( i = m.vert_attr.begin(); i !=  m.vert_attr.end(); ++i)
01147       if( (*i)._handle == h._handle ){
01148         for(typename MeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
01149           h[vi] = ATTR_TYPE();
01150         return;}
01151     assert(0);
01152   }
01153 
01156   template <class ATTR_TYPE>
01157   static
01158   void
01159   DeletePerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h){
01160     typename std::set<PointerToAttribute > ::iterator i;
01161     for( i = m.vert_attr.begin(); i !=  m.vert_attr.end(); ++i)
01162       if( (*i)._handle == h._handle ){
01163         delete ((SimpleTempData<VertContainer,ATTR_TYPE>*)(*i)._handle);
01164         m.vert_attr.erase(i);
01165         return;}
01166   }
01167 
01168   // Generic DeleteAttribute.
01169   // It must not crash if you try to delete a non existing attribute,
01170   // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
01171   static
01172   bool DeletePerVertexAttribute( MeshType & m,  std::string name){
01173     AttrIterator i;
01174     PointerToAttribute h1; h1._name = name;
01175     i = m.vert_attr.find(h1);
01176     if(i==m.vert_attr.end()) return false;
01177     delete ((SimpleTempDataBase*)(*i)._handle);
01178     m.vert_attr.erase(i);
01179     return true;
01180   }
01181 
01182 
01183 
01185   template <class ATTR_TYPE>
01186   static
01187   bool IsValidHandle( MeshType & m,  const typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> & a){
01188     if(a._handle == NULL) return false;
01189     for(AttrIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i)
01190       if ( (*i).n_attr == a.n_attr ) return true;
01191     return false;
01192   }
01193 
01194   template <class ATTR_TYPE>
01195   static
01196   typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
01197   AddPerEdgeAttribute( MeshType & m, std::string name){
01198     PAIte i;
01199     PointerToAttribute h;
01200     h._name = name;
01201     if(!name.empty()){
01202       i = m.edge_attr.find(h);
01203       assert(i ==m.edge_attr.end() );// an attribute with this name exists
01204     }
01205     h._sizeof = sizeof(ATTR_TYPE);
01206     h._padding = 0;
01207     //          h._typename = typeid(ATTR_TYPE).name();
01208     h._handle =  new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
01209     m.attrn++;
01210     h.n_attr = m.attrn;
01211     std::pair < AttrIterator , bool> res =  m.edge_attr.insert(h);
01212     return typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
01213   }
01214 
01215   template <class ATTR_TYPE>
01216   static
01217   typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
01218   AddPerEdgeAttribute( MeshType & m){
01219     return AddPerEdgeAttribute<ATTR_TYPE>(m,std::string(""));
01220   }
01221 
01226   template <class ATTR_TYPE>
01227   static
01228   typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
01229   GetPerEdgeAttribute( MeshType & m, std::string name = std::string("")){
01230     typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> h;
01231     if(!name.empty()){
01232       h =  FindPerEdgeAttribute<ATTR_TYPE>(m,name);
01233       if(IsValidHandle(m,h))
01234         return h;
01235     }
01236     return AddPerEdgeAttribute<ATTR_TYPE>(m,name);
01237   }
01238 
01239 
01240   template <class ATTR_TYPE>
01241   static
01242   typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
01243   FindPerEdgeAttribute( MeshType & m, const std::string & name){
01244     assert(!name.empty());
01245     PointerToAttribute h1; h1._name = name;
01246     typename std::set<PointerToAttribute > ::const_iterator i;
01247 
01248     i =m.edge_attr.find(h1);
01249     if(i!=m.edge_attr.end())
01250       if((*i)._sizeof == sizeof(ATTR_TYPE) ){
01251         if(     (*i)._padding != 0 ){
01252           PointerToAttribute attr = (*i);                                               // copy the PointerToAttribute
01253           m.edge_attr.erase(i);                                         // remove it from the set
01254           FixPaddedPerEdgeAttribute<ATTR_TYPE>(m,attr);
01255           std::pair<AttrIterator,bool> new_i = m.edge_attr.insert(attr);        // insert the modified PointerToAttribute
01256           assert(new_i.second);
01257           i = new_i.first;
01258         }
01259         return typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
01260       }
01261 
01262     return typename MeshType:: template PerEdgeAttributeHandle<ATTR_TYPE>(NULL,0);
01263   }
01264 
01265   template <class ATTR_TYPE>
01266   static void GetAllPerEdgeAttribute(const MeshType & m, std::vector<std::string> &all){
01267     all.clear();
01268     typename std::set<PointerToAttribute > :: const_iterator i;
01269     for(i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i )
01270       if(!(*i)._name.empty())
01271       {
01272         typename MeshType:: template PerEdgeAttributeHandle<ATTR_TYPE> hh;
01273         hh = Allocator<MeshType>:: template  FindPerEdgeAttribute <ATTR_TYPE>(m,(*i)._name);
01274         if(IsValidHandle<ATTR_TYPE>(m,hh))
01275           all.push_back((*i)._name);
01276       }
01277   }
01278 
01281   template <class ATTR_TYPE>
01282   static
01283   void
01284   DeletePerEdgeAttribute( MeshType & m,typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> & h){
01285     typename std::set<PointerToAttribute > ::iterator i;
01286     for( i = m.edge_attr.begin(); i !=  m.edge_attr.end(); ++i)
01287       if( (*i)._handle == h._handle ){
01288         delete ((SimpleTempData<FaceContainer,ATTR_TYPE>*)(*i)._handle);
01289         m.edge_attr.erase(i);
01290         return;}
01291   }
01292 
01293   // Generic DeleteAttribute.
01294   // It must not crash if you try to delete a non existing attribute,
01295   // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
01296   static
01297   bool DeletePerEdgeAttribute( MeshType & m,  std::string name){
01298     AttrIterator i;
01299     PointerToAttribute h1; h1._name = name;
01300     i = m.edge_attr.find(h1);
01301     if(i==m.edge_attr.end()) return false;
01302     delete ((SimpleTempDataBase*)(*i)._handle);
01303     m.edge_attr.erase(i);
01304     return true;
01305   }
01306 
01308   template <class ATTR_TYPE>
01309   static
01310   bool IsValidHandle( MeshType & m,  const typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> & a){
01311     if(a._handle == NULL) return false;
01312     for(AttrIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i)
01313       if ( (*i).n_attr == a.n_attr ) return true;
01314     return false;
01315   }
01316 
01317   template <class ATTR_TYPE>
01318   static
01319   typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
01320   AddPerFaceAttribute( MeshType & m, std::string name){
01321     PAIte i;
01322     PointerToAttribute h;
01323     h._name = name;
01324     if(!name.empty()){
01325       i = m.face_attr.find(h);
01326       assert(i ==m.face_attr.end() );// an attribute with this name exists
01327     }
01328 
01329     h._sizeof = sizeof(ATTR_TYPE);
01330     h._padding = 0;
01331     h._handle =   new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
01332     m.attrn++;
01333     h.n_attr = m.attrn;
01334     std::pair < AttrIterator , bool> res =  m.face_attr.insert(h);
01335     return typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
01336   }
01337 
01338   template <class ATTR_TYPE>
01339   static
01340   typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
01341   AddPerFaceAttribute( MeshType & m){
01342     return AddPerFaceAttribute<ATTR_TYPE>(m,std::string(""));
01343   }
01344 
01349   template <class ATTR_TYPE>
01350   static
01351   typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
01352   GetPerFaceAttribute( MeshType & m, std::string name = std::string("")){
01353     typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> h;
01354     if(!name.empty()){
01355       h =  FindPerFaceAttribute<ATTR_TYPE>(m,name);
01356       if(IsValidHandle(m,h))
01357         return h;
01358     }
01359     return AddPerFaceAttribute<ATTR_TYPE>(m,name);
01360   }
01361 
01362   template <class ATTR_TYPE>
01363   static
01364   typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
01365   FindPerFaceAttribute( MeshType & m, const std::string & name){
01366     assert(!name.empty());
01367     PointerToAttribute h1; h1._name = name;
01368     typename std::set<PointerToAttribute > ::iterator i;
01369 
01370     i =m.face_attr.find(h1);
01371     if(i!=m.face_attr.end())
01372       if((*i)._sizeof == sizeof(ATTR_TYPE) ){
01373         if(     (*i)._padding != 0 ){
01374           PointerToAttribute attr = (*i);                                                                                       // copy the PointerToAttribute
01375           m.face_attr.erase(i);                                                                                 // remove it from the set
01376           FixPaddedPerFaceAttribute<ATTR_TYPE>(m,attr);
01377           std::pair<AttrIterator,bool> new_i = m.face_attr.insert(attr);        // insert the modified PointerToAttribute
01378           assert(new_i.second);
01379           i = new_i.first;
01380         }
01381         return typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
01382       }
01383     return typename MeshType:: template PerFaceAttributeHandle<ATTR_TYPE>(NULL,0);
01384   }
01385 
01386   template <class ATTR_TYPE>
01387   static void GetAllPerFaceAttribute(MeshType & m, std::vector<std::string> &all){
01388     all.clear();
01389     typename std::set<PointerToAttribute > :: const_iterator i;
01390     for(i = m.face_attr.begin(); i != m.face_attr.end(); ++i )
01391       if(!(*i)._name.empty())
01392       {
01393         typename MeshType:: template PerFaceAttributeHandle<ATTR_TYPE> hh;
01394         hh = Allocator<MeshType>:: template  FindPerFaceAttribute <ATTR_TYPE>(m,(*i)._name);
01395         if(IsValidHandle<ATTR_TYPE>(m,hh))
01396           all.push_back((*i)._name);
01397       }
01398   }
01399 
01402   template <class ATTR_TYPE>
01403   static void DeletePerFaceAttribute( MeshType & m,typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> & h){
01404     typename std::set<PointerToAttribute > ::iterator i;
01405     for( i = m.face_attr.begin(); i !=  m.face_attr.end(); ++i)
01406       if( (*i)._handle == h._handle ){
01407         delete ((SimpleTempData<FaceContainer,ATTR_TYPE>*)(*i)._handle);
01408         m.face_attr.erase(i);
01409         return;}
01410 
01411   }
01412 
01413   // Generic DeleteAttribute.
01414   // It must not crash if you try to delete a non existing attribute,
01415   // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
01416   static bool DeletePerFaceAttribute( MeshType & m,  std::string name){
01417     AttrIterator i;
01418     PointerToAttribute h1; h1._name = name;
01419     i = m.face_attr.find(h1);
01420     if(i==m.face_attr.end()) return false;
01421     delete ((SimpleTempDataBase*)(*i)._handle);
01422     m.face_attr.erase(i);
01423     return true;
01424   }
01425 
01427   template <class ATTR_TYPE>
01428   static
01429   bool IsValidHandle( MeshType & m,  const typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> & a){
01430     if(a._handle == NULL) return false;
01431     for(AttrIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i)
01432       if ( (*i).n_attr == a.n_attr ) return true;
01433     return false;
01434   }
01435 
01436   template <class ATTR_TYPE>
01437   static
01438   typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
01439   AddPerMeshAttribute( MeshType & m, std::string name){
01440     PAIte i;
01441     PointerToAttribute h;
01442     h._name = name;
01443     if(!name.empty()){
01444       i = m.mesh_attr.find(h);
01445       assert(i ==m.mesh_attr.end() );// an attribute with this name exists
01446     }
01447     h._sizeof = sizeof(ATTR_TYPE);
01448     h._padding = 0;
01449     h._handle =  new Attribute<ATTR_TYPE>();
01450     m.attrn++;
01451     h.n_attr = m.attrn;
01452     std::pair < AttrIterator , bool> res =  m.mesh_attr.insert(h);
01453     return typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
01454   }
01455 
01460   template <class ATTR_TYPE>
01461   static
01462   typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
01463   GetPerMeshAttribute( MeshType & m, std::string name = std::string("")){
01464     typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> h;
01465     if(!name.empty()){
01466       h =  FindPerMeshAttribute<ATTR_TYPE>(m,name);
01467       if(IsValidHandle(m,h))
01468         return h;
01469     }
01470     return AddPerMeshAttribute<ATTR_TYPE>(m,name);
01471   }
01472 
01473   template <class ATTR_TYPE>
01474   static
01475   typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
01476   FindPerMeshAttribute( MeshType & m, const std::string & name){
01477     assert(!name.empty());
01478     PointerToAttribute h1; h1._name = name;
01479     typename std::set<PointerToAttribute > ::iterator i;
01480 
01481     i =m.mesh_attr.find(h1);
01482     if(i!=m.mesh_attr.end())
01483       if((*i)._sizeof == sizeof(ATTR_TYPE)  ){
01484         if(     (*i)._padding != 0 ){
01485           PointerToAttribute attr = (*i);                                                                                       // copy the PointerToAttribute
01486           m.mesh_attr.erase(i);                                                                                 // remove it from the set
01487           FixPaddedPerMeshAttribute<ATTR_TYPE>(m,attr);
01488           std::pair<AttrIterator,bool> new_i = m.mesh_attr.insert(attr);        // insert the modified PointerToAttribute
01489           assert(new_i.second);
01490           i = new_i.first;
01491         }
01492 
01493         return typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
01494       }
01495 
01496     return typename MeshType:: template PerMeshAttributeHandle<ATTR_TYPE>(NULL,0);
01497   }
01498 
01499   template <class ATTR_TYPE>
01500   static void GetAllPerMeshAttribute(const MeshType & m, std::vector<std::string> &all){
01501     typename std::set<PointerToAttribute > :: iterator i;
01502     for(i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i )
01503       if((*i)._sizeof == sizeof(ATTR_TYPE))
01504         all.push_back((*i)._name);
01505   }
01506 
01509   template <class ATTR_TYPE>
01510   static void DeletePerMeshAttribute( MeshType & m,typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> & h){
01511     typename std::set<PointerToAttribute > ::iterator i;
01512     for( i = m.mesh_attr.begin(); i !=  m.mesh_attr.end(); ++i)
01513       if( (*i)._handle == h._handle ){
01514         delete (( Attribute<ATTR_TYPE> *)(*i)._handle);
01515         m.mesh_attr.erase(i);
01516         return;}
01517   }
01518 
01519   static void DeletePerMeshAttribute( MeshType & m,  std::string name){
01520     AttrIterator i;
01521     PointerToAttribute h1; h1._name = name;
01522     i = m.mesh_attr.find(h1);
01523     assert(i!=m.mesh_attr.end());
01524     delete ((SimpleTempDataBase  *)(*i)._handle);
01525     m.mesh_attr.erase(i);
01526   }
01527 
01528   template <class ATTR_TYPE>
01529   static void FixPaddedPerVertexAttribute (MeshType & m, PointerToAttribute & pa){
01530 
01531     // create the container of the right type
01532     SimpleTempData<VertContainer,ATTR_TYPE>* _handle =  new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
01533 
01534     // copy the padded container in the new one
01535     _handle->Resize(m.vert.size());
01536     for(size_t i  = 0; i < m.vert.size(); ++i){
01537       ATTR_TYPE * dest = &(*_handle)[i];
01538       char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
01539       memcpy((void*)dest ,
01540              (void*) &(ptr[i *  pa._sizeof ]) ,sizeof(ATTR_TYPE));
01541     }
01542 
01543     // remove the padded container
01544     delete ((SimpleTempDataBase*) pa._handle);
01545 
01546     // update the pointer to data
01547     pa._sizeof = sizeof(ATTR_TYPE);
01548 
01549     // update the pointer to data
01550     pa._handle = _handle;
01551 
01552     // zero the padding
01553     pa._padding = 0;
01554   }
01555   template <class ATTR_TYPE>
01556   static void FixPaddedPerEdgeAttribute (MeshType & m, PointerToAttribute & pa){
01557 
01558     // create the container of the right type
01559     SimpleTempData<EdgeContainer,ATTR_TYPE>* _handle =  new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
01560 
01561     // copy the padded container in the new one
01562     _handle->Resize(m.edge.size());
01563     for(size_t i  = 0; i < m.edge.size(); ++i){
01564       ATTR_TYPE * dest = &(*_handle)[i];
01565       char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
01566       memcpy((void*)dest ,
01567              (void*) &(ptr[i *  pa._sizeof ]) ,sizeof(ATTR_TYPE));
01568     }
01569 
01570     // remove the padded container
01571     delete ((SimpleTempDataBase*) pa._handle);
01572 
01573     // update the pointer to data
01574     pa._sizeof = sizeof(ATTR_TYPE);
01575 
01576     // update the pointer to data
01577     pa._handle = _handle;
01578 
01579     // zero the padding
01580     pa._padding = 0;
01581   }
01582 
01583   template <class ATTR_TYPE>
01584   static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){
01585 
01586     // create the container of the right type
01587     SimpleTempData<FaceContainer,ATTR_TYPE>* _handle =  new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
01588 
01589     // copy the padded container in the new one
01590     _handle->Resize(m.face.size());
01591     for(size_t i  = 0; i < m.face.size(); ++i){
01592       ATTR_TYPE * dest = &(*_handle)[i];
01593       char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
01594       memcpy((void*)dest ,
01595              (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
01596     }
01597 
01598     // remove the padded container
01599     delete ((SimpleTempDataBase*) pa._handle);
01600 
01601     // update the pointer to data
01602     pa._sizeof = sizeof(ATTR_TYPE);
01603 
01604     // update the pointer to data
01605     pa._handle = _handle;
01606 
01607     // zero the padding
01608     pa._padding = 0;
01609   }
01610 
01611 
01612   template <class ATTR_TYPE>
01613   static void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){
01614 
01615     // create the container of the right type
01616     Attribute<ATTR_TYPE> * _handle =  new Attribute<ATTR_TYPE>();
01617 
01618     // copy the padded container in the new one
01619     char * ptr = (char*)( ((Attribute<ATTR_TYPE> *)pa._handle)->DataBegin());
01620     memcpy((void*)_handle->attribute ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE));
01621 
01622     // remove the padded container
01623     delete ( (Attribute<ATTR_TYPE> *) pa._handle);
01624 
01625     // update the pointer to data
01626     pa._sizeof = sizeof(ATTR_TYPE);
01627 
01628     // update the pointer to data
01629     pa._handle = _handle;
01630 
01631     // zero the padding
01632     pa._padding = 0;
01633   }
01634 
01635 }; // end Allocator class
01636 
01637  // end doxygen group trimesh
01639 } // end namespace tri
01640 } // end namespace vcg
01641 
01642 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:28:53