00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 & ){
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 &){
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
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;
00158
00159 bool preventUpdateFlag;
00160 };
00161
00162
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;
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
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
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;
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
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;
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;
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
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;
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))
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;
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
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())
00591 {
00592 pu.oldBase=&*m.face.begin();
00593 pu.oldEnd=&m.face.back()+1;
00594 }
00595
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 {
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 {
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
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
00698
00699
00700
00701
00702
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
00736 ReorderAttribute(m.vert_attr,pu.remap,m);
00737
00738
00739 pu.oldBase = &m.vert[0];
00740 pu.oldEnd = &m.vert.back()+1;
00741
00742
00743 m.vert.resize(m.vn);
00744
00745
00746 pu.newBase = (m.vert.empty())?0:&m.vert[0];
00747 pu.newEnd = (m.vert.empty())?0:&m.vert.back()+1;
00748
00749
00750 ResizeAttribute(m.vert_attr,m.vn,m);
00751
00752
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
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
00789 if(m.vn==(int)m.vert.size()) return;
00790
00791
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
00828 if(m.en==(int)m.edge.size()) return;
00829
00830
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
00847 for(size_t i=0;i<m.edge.size();++i)
00848 {
00849 if(pu.remap[i]<size_t(m.en))
00850 {
00851 assert(!m.edge[i].IsD());
00852 m.edge[ pu.remap [i] ].ImportData(m.edge[i]);
00853
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
00857 if(HasVEAdjacency(m))
00858
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
00877 ReorderAttribute(m.edge_attr, pu.remap,m);
00878
00879
00880 pu.oldBase = &m.edge[0];
00881 pu.oldEnd = &m.edge.back()+1;
00882
00883
00884 m.edge.resize(m.en);
00885
00886
00887 pu.newBase = (m.edge.empty())?0:&m.edge[0];
00888 pu.newEnd = (m.edge.empty())?0:&m.edge.back()+1;
00889
00890
00891 ResizeAttribute(m.edge_attr,m.en,m);
00892
00893
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
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
00926 if(m.fn==(int)m.face.size()) return;
00927
00928
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
00970 ReorderAttribute(m.face_attr,pu.remap,m);
00971
00972 FacePointer fbase=&m.face[0];
00973
00974
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
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
01000 ResizeAttribute(m.face_attr,m.fn,m);
01001
01002
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() );
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);
01113 m.vert_attr.erase(i);
01114 FixPaddedPerVertexAttribute<ATTR_TYPE>(m,attr);
01115 std::pair<AttrIterator,bool> new_i = m.vert_attr.insert(attr);
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
01169
01170
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() );
01204 }
01205 h._sizeof = sizeof(ATTR_TYPE);
01206 h._padding = 0;
01207
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);
01253 m.edge_attr.erase(i);
01254 FixPaddedPerEdgeAttribute<ATTR_TYPE>(m,attr);
01255 std::pair<AttrIterator,bool> new_i = m.edge_attr.insert(attr);
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
01294
01295
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() );
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);
01375 m.face_attr.erase(i);
01376 FixPaddedPerFaceAttribute<ATTR_TYPE>(m,attr);
01377 std::pair<AttrIterator,bool> new_i = m.face_attr.insert(attr);
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
01414
01415
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() );
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);
01486 m.mesh_attr.erase(i);
01487 FixPaddedPerMeshAttribute<ATTR_TYPE>(m,attr);
01488 std::pair<AttrIterator,bool> new_i = m.mesh_attr.insert(attr);
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
01532 SimpleTempData<VertContainer,ATTR_TYPE>* _handle = new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
01533
01534
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
01544 delete ((SimpleTempDataBase*) pa._handle);
01545
01546
01547 pa._sizeof = sizeof(ATTR_TYPE);
01548
01549
01550 pa._handle = _handle;
01551
01552
01553 pa._padding = 0;
01554 }
01555 template <class ATTR_TYPE>
01556 static void FixPaddedPerEdgeAttribute (MeshType & m, PointerToAttribute & pa){
01557
01558
01559 SimpleTempData<EdgeContainer,ATTR_TYPE>* _handle = new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
01560
01561
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
01571 delete ((SimpleTempDataBase*) pa._handle);
01572
01573
01574 pa._sizeof = sizeof(ATTR_TYPE);
01575
01576
01577 pa._handle = _handle;
01578
01579
01580 pa._padding = 0;
01581 }
01582
01583 template <class ATTR_TYPE>
01584 static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){
01585
01586
01587 SimpleTempData<FaceContainer,ATTR_TYPE>* _handle = new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
01588
01589
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
01599 delete ((SimpleTempDataBase*) pa._handle);
01600
01601
01602 pa._sizeof = sizeof(ATTR_TYPE);
01603
01604
01605 pa._handle = _handle;
01606
01607
01608 pa._padding = 0;
01609 }
01610
01611
01612 template <class ATTR_TYPE>
01613 static void FixPaddedPerMeshAttribute ( MeshType & ,PointerToAttribute & pa){
01614
01615
01616 Attribute<ATTR_TYPE> * _handle = new Attribute<ATTR_TYPE>();
01617
01618
01619 char * ptr = (char*)( ((Attribute<ATTR_TYPE> *)pa._handle)->DataBegin());
01620 memcpy((void*)_handle->attribute ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE));
01621
01622
01623 delete ( (Attribute<ATTR_TYPE> *) pa._handle);
01624
01625
01626 pa._sizeof = sizeof(ATTR_TYPE);
01627
01628
01629 pa._handle = _handle;
01630
01631
01632 pa._padding = 0;
01633 }
01634
01635 };
01636
01637
01639 }
01640 }
01641
01642 #endif