VCG Library
allocate.h
1 /***************************************************************************
2 * VCGLib o o *
3 * Visual and Computer Graphics Library o o *
4 * _ O _ *
5 * Copyright(C) 2004-2016 \/)\/ *
6 * Visual Computing Lab /\/| *
7 * ISTI - Italian National Research Council | *
8 * \ *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 #ifndef __VCGLIB_TRIALLOCATOR
24 #define __VCGLIB_TRIALLOCATOR
25 
26 #ifndef __VCG_MESH
27 #error "This file should not be included alone. It is automatically included by complex.h"
28 #endif
29 
30 namespace vcg {
31 namespace tri {
36 template<class MeshType>
37 size_t Index(MeshType &m, const typename MeshType::VertexType &v) {return &v-&*m.vert.begin();}
38 template<class MeshType>
39 size_t Index(MeshType &m, const typename MeshType::FaceType &f) {return &f-&*m.face.begin();}
40 template<class MeshType>
41 size_t Index(MeshType &m, const typename MeshType::EdgeType &e) {return &e-&*m.edge.begin();}
42 template<class MeshType>
43 size_t Index(MeshType &m, const typename MeshType::HEdgeType &h) {return &h-&*m.hedge.begin();}
44 
45 template<class MeshType>
46 size_t Index(MeshType &m, const typename MeshType::VertexType *vp) {return vp-&*m.vert.begin();}
47 template<class MeshType>
48 size_t Index(MeshType &m, const typename MeshType::FaceType * fp) {return fp-&*m.face.begin();}
49 template<class MeshType>
50 size_t Index(MeshType &m, const typename MeshType::EdgeType* e) {return e-&*m.edge.begin();}
51 template<class MeshType>
52 size_t Index(MeshType &m, const typename MeshType::HEdgeType* h) {return h-&*m.hedge.begin();}
53 
54 template<class MeshType>
55 bool IsValidPointer( MeshType & m, const typename MeshType::VertexType *vp) { return ( m.vert.size() > 0 && (vp >= &*m.vert.begin()) && (vp <= &m.vert.back()) ); }
56 template<class MeshType>
57 bool IsValidPointer(MeshType & m, const typename MeshType::EdgeType *ep) { return ( m.edge.size() > 0 && (ep >= &*m.edge.begin()) && (ep <= &m.edge.back())); }
58 template<class MeshType>
59 bool IsValidPointer(MeshType & m, const typename MeshType::FaceType *fp) { return ( m.face.size() > 0 && (fp >= &*m.face.begin()) && (fp <= &m.face.back())); }
60 template<class MeshType>
61 bool IsValidPointer(MeshType & m, const typename MeshType::HEdgeType *hp) { return ( m.hedge.size() > 0 && (hp >= &*m.hedge.begin()) && (hp <= &m.hedge.back())); }
62 
63 template <class MeshType, class ATTR_CONT>
64 void ReorderAttribute(ATTR_CONT &c, std::vector<size_t> & newVertIndex, MeshType & /* m */){
65  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
66  for(ai = c.begin(); ai != c.end(); ++ai)
67  ((typename MeshType::PointerToAttribute)(*ai)).Reorder(newVertIndex);
68 }
69 
70 template <class MeshType, class ATTR_CONT>
71 void ResizeAttribute(ATTR_CONT &c, size_t sz, MeshType &/*m*/){
72  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
73  for(ai =c.begin(); ai != c.end(); ++ai)
74  ((typename MeshType::PointerToAttribute)(*ai)).Resize(sz);
75 }
76 
84 template <class MeshType>
85 class Allocator
86 {
87 
88 public:
89  typedef typename MeshType::VertexType VertexType;
90  typedef typename MeshType::VertexPointer VertexPointer;
91  typedef typename MeshType::VertexIterator VertexIterator;
92  typedef typename MeshType::VertContainer VertContainer;
93 
94  typedef typename MeshType::EdgeType EdgeType;
95  typedef typename MeshType::EdgePointer EdgePointer;
96  typedef typename MeshType::EdgeIterator EdgeIterator;
97  typedef typename MeshType::EdgeContainer EdgeContainer;
98 
99  typedef typename MeshType::FaceType FaceType;
100  typedef typename MeshType::FacePointer FacePointer;
101  typedef typename MeshType::FaceIterator FaceIterator;
102  typedef typename MeshType::FaceContainer FaceContainer;
103 
104  typedef typename MeshType::HEdgeType HEdgeType;
105  typedef typename MeshType::HEdgePointer HEdgePointer;
106  typedef typename MeshType::HEdgeIterator HEdgeIterator;
107  typedef typename MeshType::HEdgeContainer HEdgeContainer;
108 
109  typedef typename MeshType::CoordType CoordType;
110 
111 
112  typedef typename MeshType::PointerToAttribute PointerToAttribute;
113  typedef typename std::set<PointerToAttribute>::iterator AttrIterator;
114  typedef typename std::set<PointerToAttribute>::const_iterator AttrConstIterator;
115  typedef typename std::set<PointerToAttribute >::iterator PAIte;
116 
128  template<class SimplexPointerType>
130  {
131  public:
132  PointerUpdater(void) : newBase(0), oldBase(0), newEnd(0), oldEnd(0), preventUpdateFlag(false) { ; }
133  void Clear(){newBase=oldBase=newEnd=oldEnd=0; remap.clear();}
138  void Update(SimplexPointerType &vp)
139  {
140  //if(vp>=newBase && vp<newEnd) return;
141  if(vp<oldBase || vp>oldEnd) return;
142  assert(vp>=oldBase);
143  assert(vp<oldEnd);
144  vp=newBase+(vp-oldBase);
145  if(!remap.empty())
146  vp = newBase + remap[vp-newBase];
147  }
151  bool NeedUpdate() {if((oldBase && newBase!=oldBase && !preventUpdateFlag) || !remap.empty()) return true; else return false;}
152 
153  SimplexPointerType newBase;
154  SimplexPointerType oldBase;
155  SimplexPointerType newEnd;
156  SimplexPointerType oldEnd;
157  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.
158 
159  bool preventUpdateFlag;
160  };
161 
162  /* +++++++++++++++ Add Vertices ++++++++++++++++ */
163 
174  static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater<VertexPointer> &pu)
175  {
176  VertexIterator last;
177  if(n == 0) return m.vert.end();
178  pu.Clear();
179  if(m.vert.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element
180  else {
181  pu.oldBase=&*m.vert.begin();
182  pu.oldEnd=&m.vert.back()+1;
183  }
184 
185  m.vert.resize(m.vert.size()+n);
186  m.vn+=int(n);
187 
188  typename std::set<PointerToAttribute>::iterator ai;
189  for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai)
190  ((PointerToAttribute)(*ai)).Resize(m.vert.size());
191 
192  pu.newBase = &*m.vert.begin();
193  pu.newEnd = &m.vert.back()+1;
194  if(pu.NeedUpdate())
195  {
196  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
197  if(!(*fi).IsD())
198  for(int i=0; i < (*fi).VN(); ++i)
199  if ((*fi).cV(i)!=0) pu.Update((*fi).V(i));
200 
201  for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
202  if(!(*ei).IsD())
203  {
204  if(HasEVAdjacency (m)) { pu.Update((*ei).V(0)); pu.Update((*ei).V(1));}
205  // if(HasEVAdjacency(m)) pu.Update((*ei).EVp());
206  }
207  HEdgeIterator hi;
208  for (hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
209  if(!(*hi).IsD())
210  {
211  if(HasHVAdjacency (m))
212  {
213  pu.Update((*hi).HVp());
214  }
215  }
216 
217  // e poiche' lo spazio e' cambiato si ricalcola anche last da zero
218  }
219  size_t siz=(size_t)(m.vert.size()-n);
220 
221  last = m.vert.begin();
222  advance(last,siz);
223 
224  return last;// deve restituire l'iteratore alla prima faccia aggiunta;
225  }
226 
229  static VertexIterator AddVertices(MeshType &m, size_t n)
230  {
232  return AddVertices(m, n,pu);
233  }
234 
237  static VertexIterator AddVertices(MeshType &m, size_t n, std::vector<VertexPointer *> &local_vec)
238  {
240  VertexIterator v_ret = AddVertices(m, n,pu);
241 
242  typename std::vector<VertexPointer *>::iterator vi;
243  for(vi=local_vec.begin();vi!=local_vec.end();++vi)
244  pu.Update(**vi);
245  return v_ret;
246  }
247 
250  static VertexIterator AddVertex(MeshType &m, const CoordType &p)
251  {
252  VertexIterator v_ret = AddVertices(m, 1);
253  v_ret->P()=p;
254  return v_ret;
255  }
256 
259  static VertexIterator AddVertex(MeshType &m, const CoordType &p, const CoordType &n)
260  {
261  VertexIterator v_ret = AddVertices(m, 1);
262  v_ret->P()=p;
263  v_ret->N()=n;
264  return v_ret;
265  }
266 
269  static VertexIterator AddVertex(MeshType &m, const CoordType &p, const Color4b &c)
270  {
271  VertexIterator v_ret = AddVertices(m, 1);
272  v_ret->P()=p;
273  v_ret->C()=c;
274  return v_ret;
275  }
276 
277  /* +++++++++++++++ Add Edges ++++++++++++++++ */
278 
288  static EdgeIterator AddEdges(MeshType &m, size_t n, PointerUpdater<EdgePointer> &pu)
289  {
290  if(n == 0) return m.edge.end();
291  pu.Clear();
292  if(m.edge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element
293  else {
294  pu.oldBase=&*m.edge.begin();
295  pu.oldEnd=&m.edge.back()+1;
296  }
297 
298  m.edge.resize(m.edge.size()+n);
299  m.en+=int(n);
300  size_t siz=(size_t)(m.edge.size()-n);
301  EdgeIterator firstNewEdge = m.edge.begin();
302  advance(firstNewEdge,siz);
303 
304  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
305  for(ai = m.edge_attr.begin(); ai != m.edge_attr.end(); ++ai)
306  ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.edge.size());
307 
308  pu.newBase = &*m.edge.begin();
309  pu.newEnd = &m.edge.back()+1;
310  if(pu.NeedUpdate())
311  {
312  if(HasFEAdjacency(m))
313  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi){
314  if(!(*fi).IsD())
315  for(int i=0; i < (*fi).VN(); ++i)
316  if ((*fi).cFEp(i)!=0) pu.Update((*fi).FEp(i));
317  }
318 
319  if(HasVEAdjacency(m)){
320  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
321  if(!(*vi).IsD())
322  if ((*vi).cVEp()!=0) pu.Update((*vi).VEp());
323  for(EdgeIterator ei=m.edge.begin();ei!=firstNewEdge;++ei)
324  if(!(*ei).IsD())
325  {
326  if ((*ei).cVEp(0)!=0) pu.Update((*ei).VEp(0));
327  if ((*ei).cVEp(1)!=0) pu.Update((*ei).VEp(1));
328  }
329  }
330 
331  if(HasHEAdjacency(m))
332  for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
333  if(!(*hi).IsD())
334  if ((*hi).cHEp()!=0) pu.Update((*hi).HEp());
335  }
336 
337  return firstNewEdge;// deve restituire l'iteratore alla prima faccia aggiunta;
338  }
339 
342  static EdgeIterator AddEdge(MeshType &m, VertexPointer v0, VertexPointer v1)
343  {
344  EdgeIterator ei= AddEdges(m, 1);
345  ei->V(0)=v0;
346  ei->V(1)=v1;
347  return ei;
348  }
349 
352  static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1)
353  {
354  VertexIterator vi = AddVertices(m,2);
355  EdgeIterator ei = AddEdges(m,1);
356  vi->P()=p0;
357  ei->V(0)=&*vi++;
358  vi->P()=p1;
359  ei->V(1)=&*vi++;
360  return ei;
361  }
362 
366  static EdgeIterator AddEdges(MeshType &m, size_t n)
367  {
369  return AddEdges(m, n,pu);
370  }
371 
375  static EdgeIterator AddEdges(MeshType &m, size_t n, std::vector<EdgePointer*> &local_vec)
376  {
378  EdgeIterator v_ret = AddEdges(m, n,pu);
379 
380  typename std::vector<EdgePointer *>::iterator ei;
381  for(ei=local_vec.begin();ei!=local_vec.end();++ei)
382  pu.Update(**ei);
383  return v_ret;
384  }
385 
386  /* +++++++++++++++ Add HalfEdges ++++++++++++++++ */
387 
397  static HEdgeIterator AddHEdges(MeshType &m, size_t n, PointerUpdater<HEdgePointer> &pu)
398  {
399  HEdgeIterator last;
400  if(n == 0) return m.hedge.end();
401  pu.Clear();
402  if(m.hedge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element
403  else {
404  pu.oldBase=&*m.hedge.begin();
405  pu.oldEnd=&m.hedge.back()+1;
406  }
407 
408  m.hedge.resize(m.hedge.size()+n);
409  m.hn+=int(n);
410 
411  pu.newBase = &*m.hedge.begin();
412  pu.newEnd = &m.hedge.back()+1;
413 
414  if(pu.NeedUpdate())
415  {
416  if(HasFHAdjacency(m)) {
417  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
418  {
419  if(!(*fi).IsD() && (*fi).FHp())
420  pu.Update((*fi).FHp());
421  }
422  }
423  if(HasVHAdjacency(m)) {
424  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
425  if(!(*vi).IsD() && (*vi).cVHp()!=0)
426  pu.Update((*vi).VHp());
427  }
428  if(HasEHAdjacency(m)) {
429  for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
430  if(!(*ei).IsD() && (*ei).cEHp()!=0)
431  pu.Update((*ei).EHp());
432  }
433 
434  int ii = 0;
435  HEdgeIterator hi = m.hedge.begin();
436  while(ii < m.hn - int(n))// cycle on all the faces except the new ones
437  {
438  if(!(*hi).IsD())
439  {
440  if(HasHNextAdjacency(m)) pu.Update((*hi).HNp());
441  if(HasHPrevAdjacency(m)) pu.Update((*hi).HPp());
442  if(HasHOppAdjacency(m)) pu.Update((*hi).HOp());
443  ++ii;
444  }
445  ++hi;
446  }
447  }
448  size_t siz = (size_t)(m.hedge.size()-n);
449 
450  last = m.hedge.begin();
451  advance(last,siz);
452 
453  return last;// deve restituire l'iteratore alla prima faccia aggiunta;
454  }
455 
459  static HEdgeIterator AddHEdges(MeshType &m, size_t n)
460  {
462  return AddHEdges(m, n,pu);
463  }
464 
468  static HEdgeIterator AddHEdges(MeshType &m, size_t n, std::vector<HEdgePointer*> &local_vec)
469  {
471  HEdgeIterator v_ret = AddHEdges(m, n,pu);
472 
473  typename std::vector<HEdgePointer *>::iterator ei;
474  for(ei=local_vec.begin();ei!=local_vec.end();++ei)
475  pu.Update(**ei);
476  return v_ret;
477  }
478 
479  /* +++++++++++++++ Add Faces ++++++++++++++++ */
480 
483  static FaceIterator AddFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2)
484  {
485  assert(m.vert.size()>0);
486  assert((v0!=v1) && (v1!=v2) && (v0!=v2));
487  assert(v0>=&m.vert.front() && v0<=&m.vert.back());
488  assert(v1>=&m.vert.front() && v1<=&m.vert.back());
489  assert(v2>=&m.vert.front() && v2<=&m.vert.back());
491  FaceIterator fi = AddFaces(m,1,pu);
492  fi->Alloc(3);
493  fi->V(0)=v0;
494  fi->V(1)=v1;
495  fi->V(2)=v2;
496  return fi;
497  }
498 
501  static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2)
502  {
503  assert((v0!=v1) && (v1!=v2) && (v0!=v2));
504  assert(v0>=0 && v0<=m.vert.size());
505  assert(v1>=0 && v1<=m.vert.size());
506  assert(v2>=0 && v2<=m.vert.size());
507  return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2]));
508  }
511  static FaceIterator AddFace(MeshType &m, CoordType p0, CoordType p1, CoordType p2)
512  {
513  VertexIterator vi = AddVertices(m,3);
514  FaceIterator fi = AddFaces(m,1);
515  fi->Alloc(3);
516  vi->P()=p0;
517  fi->V(0)=&*vi++;
518  vi->P()=p1;
519  fi->V(1)=&*vi++;
520  vi->P()=p2;
521  fi->V(2)=&*vi;
522  return fi;
523  }
524 
529  static FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
530  {
531  assert(m.vert.size()>0);
532  assert(v0>=&m.vert.front() && v0<=&m.vert.back());
533  assert(v1>=&m.vert.front() && v1<=&m.vert.back());
534  assert(v2>=&m.vert.front() && v2<=&m.vert.back());
535  assert(v3>=&m.vert.front() && v3<=&m.vert.back());
537  if(FaceType::HasPolyInfo())
538  {
539  FaceIterator fi = AddFaces(m,1,pu);
540  fi->Alloc(4);
541  fi->V(0)=v0; fi->V(1)=v1;
542  fi->V(2)=v2; fi->V(3)=v3;
543  return fi;
544  }
545  else
546  {
547  FaceIterator fi = AddFaces(m,2,pu);
548  fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v1; fi->V(2)=v2;
549  fi->SetF(2);
550  ++fi;
551  fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v2; fi->V(2)=v3;
552  fi->SetF(0);
553  return fi;
554  }
555  }
559  static FaceIterator AddFaces(MeshType &m, size_t n)
560  {
562  return AddFaces(m,n,pu);
563  }
564 
568  static FaceIterator AddFaces(MeshType &m, size_t n,std::vector<FacePointer *> &local_vec)
569  {
571  FaceIterator f_ret= AddFaces(m,n,pu);
572 
573  typename std::vector<FacePointer *>::iterator fi;
574  for(fi=local_vec.begin();fi!=local_vec.end();++fi)
575  pu.Update(**fi);
576  return f_ret;
577  }
578 
591  static FaceIterator AddFaces(MeshType &m, size_t n, PointerUpdater<FacePointer> &pu)
592  {
593  pu.Clear();
594  if(n == 0) return m.face.end();
595  if(!m.face.empty()) // if the vector is empty we cannot find the last valid element
596  {
597  pu.oldBase=&*m.face.begin();
598  pu.oldEnd=&m.face.back()+1;
599  }
600  // The actual resize
601  m.face.resize(m.face.size()+n);
602  m.fn+=int(n);
603 
604  size_t siz=(size_t)(m.face.size()-n);
605  FaceIterator firstNewFace = m.face.begin();
606  advance(firstNewFace,siz);
607 
608  typename std::set<PointerToAttribute>::iterator ai;
609  for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai)
610  ((PointerToAttribute)(*ai)).Resize(m.face.size());
611 
612  pu.newBase = &*m.face.begin();
613  pu.newEnd = &m.face.back()+1;
614 
615  if(pu.NeedUpdate())
616  {
617  if(HasFFAdjacency(m))
618  { // cycle on all the faces except the new ones
619  for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi)
620  if(!(*fi).IsD())
621  for(int i = 0; i < (*fi).VN(); ++i)
622  if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i));
623  }
624 
625  if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m))
626  { // cycle on all the faces except the new ones
627  for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi)
628  if(!(*fi).IsD())
629  for(int i = 0; i < (*fi).VN(); ++i)
630  if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i));
631 
632  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
633  if(!(*vi).IsD() && (*vi).cVFp()!=0)
634  pu.Update((*vi).VFp());
635  }
636 
637  if(HasEFAdjacency(m))
638  {
639  for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
640  if(!(*ei).IsD() && (*ei).cEFp()!=0)
641  pu.Update((*ei).EFp());
642  }
643 
644  if(HasHFAdjacency(m))
645  {
646  for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
647  if(!(*hi).IsD() && (*hi).cHFp()!=0)
648  pu.Update((*hi).HFp());
649  }
650  }
651  return firstNewFace;
652  }
653 
654  /* +++++++++++++++ Deleting ++++++++++++++++ */
655 
659  static void DeleteFace(MeshType &m, FaceType &f)
660  {
661  assert(&f >= &m.face.front() && &f <= &m.face.back());
662  assert(!f.IsD());
663  f.Dealloc();
664  f.SetD();
665  --m.fn;
666  }
667 
671  static void DeleteVertex(MeshType &m, VertexType &v)
672  {
673  assert(&v >= &m.vert.front() && &v <= &m.vert.back());
674  assert(!v.IsD());
675  v.SetD();
676  --m.vn;
677  }
678 
682  static void DeleteEdge(MeshType &m, EdgeType &e)
683  {
684  assert(&e >= &m.edge.front() && &e <= &m.edge.back());
685  assert(!e.IsD());
686  e.SetD();
687  --m.en;
688  }
689 
693  static void DeleteHEdge(MeshType &m, HEdgeType &h)
694  {
695  assert(&h >= &m.hedge.front() && &h <= &m.hedge.back());
696  assert(!h.IsD());
697  h.SetD();
698  --m.hn;
699  }
700 
701  /*
702  Function to rearrange the vertex vector according to a given index permutation
703  the permutation is vector such that after calling this function
704 
705  m.vert[ newVertIndex[i] ] = m.vert[i];
706 
707  e.g. newVertIndex[i] is the new index of the vertex i
708 
709  */
710  static void PermutateVertexVector(MeshType &m, PointerUpdater<VertexPointer> &pu)
711  {
712  if(m.vert.empty()) return;
713  for(size_t i=0;i<m.vert.size();++i)
714  {
715  if(pu.remap[i]<size_t(m.vn))
716  {
717  assert(!m.vert[i].IsD());
718  m.vert[ pu.remap [i] ].ImportData(m.vert[i]);
719  if(HasVFAdjacency(m))
720  {
721  if (m.vert[i].IsVFInitialized())
722  {
723  m.vert[ pu.remap[i] ].VFp() = m.vert[i].cVFp();
724  m.vert[ pu.remap[i] ].VFi() = m.vert[i].cVFi();
725  }
726  else m.vert [ pu.remap[i] ].VFClear();
727  }
728  if(HasVEAdjacency(m))
729  {
730  if (m.vert[i].IsVEInitialized())
731  {
732  m.vert[ pu.remap[i] ].VEp() = m.vert[i].cVEp();
733  m.vert[ pu.remap[i] ].VEi() = m.vert[i].cVEi();
734  }
735  else m.vert [ pu.remap[i] ].VEClear();
736  }
737  }
738  }
739 
740  // reorder the optional atttributes in m.vert_attr to reflect the changes
741  ReorderAttribute(m.vert_attr,pu.remap,m);
742 
743  // setup the pointer updater
744  pu.oldBase = &m.vert[0];
745  pu.oldEnd = &m.vert.back()+1;
746 
747  // resize
748  m.vert.resize(m.vn);
749 
750  // setup the pointer updater
751  pu.newBase = (m.vert.empty())?0:&m.vert[0];
752  pu.newEnd = (m.vert.empty())?0:&m.vert.back()+1;
753 
754  // resize the optional atttributes in m.vert_attr to reflect the changes
755  ResizeAttribute(m.vert_attr,m.vn,m);
756 
757  // Loop on the face to update the pointers FV relation (vertex refs)
758  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
759  if(!(*fi).IsD())
760  for(int i=0;i<fi->VN();++i)
761  {
762  size_t oldIndex = (*fi).V(i) - pu.oldBase;
763  assert(pu.oldBase <= (*fi).V(i) && oldIndex < pu.remap.size());
764  (*fi).V(i) = pu.newBase+pu.remap[oldIndex];
765  }
766  // Loop on the edges to update the pointers EV relation
767  if(HasEVAdjacency(m))
768  for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
769  if(!(*ei).IsD())
770  {
771  pu.Update((*ei).V(0));
772  pu.Update((*ei).V(1));
773  }
774  }
775 
776  static void CompactEveryVector( MeshType &m)
777  {
778  CompactVertexVector(m);
779  CompactEdgeVector(m);
780  CompactFaceVector(m);
781  }
782 
783 
791  static void CompactVertexVector( MeshType &m, PointerUpdater<VertexPointer> &pu )
792  {
793  // If already compacted fast return please!
794  if(m.vn==(int)m.vert.size()) return;
795 
796  // newVertIndex [ <old_vert_position> ] gives you the new position of the vertex in the vector;
797  pu.remap.resize( m.vert.size(),std::numeric_limits<size_t>::max() );
798 
799  size_t pos=0;
800  size_t i=0;
801 
802  for(i=0;i<m.vert.size();++i)
803  {
804  if(!m.vert[i].IsD())
805  {
806  pu.remap[i]=pos;
807  ++pos;
808  }
809  }
810  assert((int)pos==m.vn);
811 
812  PermutateVertexVector(m, pu);
813 
814  }
815 
817  static void CompactVertexVector( MeshType &m ) {
819  CompactVertexVector(m,pu);
820  }
821 
830  static void CompactEdgeVector( MeshType &m, PointerUpdater<EdgePointer> &pu )
831  {
832  // If already compacted fast return please!
833  if(m.en==(int)m.edge.size()) return;
834 
835  // remap [ <old_edge_position> ] gives you the new position of the edge in the vector;
836  pu.remap.resize( m.edge.size(),std::numeric_limits<size_t>::max() );
837 
838  size_t pos=0;
839  size_t i=0;
840 
841  for(i=0;i<m.edge.size();++i)
842  {
843  if(!m.edge[i].IsD())
844  {
845  pu.remap[i]=pos;
846  ++pos;
847  }
848  }
849  assert((int)pos==m.en);
850 
851  // the actual copying of the data.
852  for(size_t i=0;i<m.edge.size();++i)
853  {
854  if(pu.remap[i]<size_t(m.en)) // uninitialized entries in the remap vector has max_int value;
855  {
856  assert(!m.edge[i].IsD());
857  m.edge[ pu.remap [i] ].ImportData(m.edge[i]);
858  // copy the vertex reference (they are not data!)
859  m.edge[ pu.remap[i] ].V(0) = m.edge[i].cV(0);
860  m.edge[ pu.remap[i] ].V(1) = m.edge[i].cV(1);
861  // Now just copy the adjacency pointers (without changing them, to be done later)
862  if(HasVEAdjacency(m))
863  //if (m.edge[i].cVEp(0)!=0)
864  {
865  m.edge[ pu.remap[i] ].VEp(0) = m.edge[i].cVEp(0);
866  m.edge[ pu.remap[i] ].VEi(0) = m.edge[i].cVEi(0);
867  m.edge[ pu.remap[i] ].VEp(1) = m.edge[i].cVEp(1);
868  m.edge[ pu.remap[i] ].VEi(1) = m.edge[i].cVEi(1);
869  }
870  if(HasEEAdjacency(m))
871  if (m.edge[i].cEEp(0)!=0)
872  {
873  m.edge[ pu.remap[i] ].EEp(0) = m.edge[i].cEEp(0);
874  m.edge[ pu.remap[i] ].EEi(0) = m.edge[i].cEEi(0);
875  m.edge[ pu.remap[i] ].EEp(1) = m.edge[i].cEEp(1);
876  m.edge[ pu.remap[i] ].EEi(1) = m.edge[i].cEEi(1);
877  }
878  }
879  }
880 
881  // reorder the optional attributes in m.vert_attr to reflect the changes
882  ReorderAttribute(m.edge_attr, pu.remap,m);
883 
884  // setup the pointer updater
885  pu.oldBase = &m.edge[0];
886  pu.oldEnd = &m.edge.back()+1;
887 
888  // THE resize
889  m.edge.resize(m.en);
890 
891  // setup the pointer updater
892  pu.newBase = (m.edge.empty())?0:&m.edge[0];
893  pu.newEnd = (m.edge.empty())?0:&m.edge.back()+1;
894 
895  // resize the optional atttributes in m.vert_attr to reflect the changes
896  ResizeAttribute(m.edge_attr,m.en,m);
897 
898  // Loop on the vertices to update the pointers of VE relation
899  if(HasVEAdjacency(m))
900  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
901  if(!(*vi).IsD()) pu.Update((*vi).VEp());
902 
903  // Loop on the edges to update the pointers EE VE relation
904  for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
905  for(unsigned int i=0;i<2;++i)
906  {
907  if(HasVEAdjacency(m))
908  pu.Update((*ei).VEp(i));
909  if(HasEEAdjacency(m))
910  pu.Update((*ei).EEp(i));
911  }
912  }
913 
915  static void CompactEdgeVector( MeshType &m ) {
917  CompactEdgeVector(m,pu);
918  }
919 
928  static void CompactFaceVector( MeshType &m, PointerUpdater<FacePointer> &pu )
929  {
930  // If already compacted fast return please!
931  if(m.fn==(int)m.face.size()) return;
932 
933  // newFaceIndex [ <old_face_position> ] gives you the new position of the face in the vector;
934  pu.remap.resize( m.face.size(),std::numeric_limits<size_t>::max() );
935 
936  size_t pos=0;
937  for(size_t i=0;i<m.face.size();++i)
938  {
939  if(!m.face[i].IsD())
940  {
941  if(pos!=i)
942  {
943  m.face[pos].ImportData(m.face[i]);
944  if(FaceType::HasPolyInfo())
945  {
946  m.face[pos].Dealloc();
947  m.face[pos].Alloc(m.face[i].VN());
948  }
949  for(int j=0;j<m.face[i].VN();++j)
950  m.face[pos].V(j) = m.face[i].V(j);
951 
952  if(HasVFAdjacency(m))
953  for(int j=0;j<m.face[i].VN();++j)
954  {
955  if (m.face[i].IsVFInitialized(j)) {
956  m.face[pos].VFp(j) = m.face[i].cVFp(j);
957  m.face[pos].VFi(j) = m.face[i].cVFi(j);
958  }
959  else m.face[pos].VFClear(j);
960  }
961  if(HasFFAdjacency(m))
962  for(int j=0;j<m.face[i].VN();++j)
963  {
964  m.face[pos].FFp(j) = m.face[i].cFFp(j);
965  m.face[pos].FFi(j) = m.face[i].cFFi(j);
966  }
967  }
968  pu.remap[i]=pos;
969  ++pos;
970  }
971  }
972  assert((int)pos==m.fn);
973 
974  // reorder the optional atttributes in m.face_attr to reflect the changes
975  ReorderAttribute(m.face_attr,pu.remap,m);
976 
977  FacePointer fbase=&m.face[0];
978 
979  // Loop on the vertices to correct VF relation
980  if(HasVFAdjacency(m))
981  {
982  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
983  if(!(*vi).IsD())
984  {
985  if ((*vi).IsVFInitialized() && (*vi).VFp()!=0 )
986  {
987  size_t oldIndex = (*vi).cVFp() - fbase;
988  assert(fbase <= (*vi).cVFp() && oldIndex < pu.remap.size());
989  (*vi).VFp() = fbase+pu.remap[oldIndex];
990  }
991  }
992  }
993 
994  // Loop on the faces to correct VF and FF relations
995  pu.oldBase = &m.face[0];
996  pu.oldEnd = &m.face.back()+1;
997  for(size_t i=m.fn;i<m.face.size();++i)
998  m.face[i].Dealloc();
999  m.face.resize(m.fn);
1000  pu.newBase = (m.face.empty())?0:&m.face[0];
1001  pu.newEnd = (m.face.empty())?0:&m.face.back()+1;
1002 
1003 
1004  // resize the optional atttributes in m.face_attr to reflect the changes
1005  ResizeAttribute(m.face_attr,m.fn,m);
1006 
1007  // now we update the various (not null) face pointers (inside VF and FF relations)
1008  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
1009  if(!(*fi).IsD())
1010  {
1011  if(HasVFAdjacency(m))
1012  for(int i=0;i<(*fi).VN();++i)
1013  if ((*fi).IsVFInitialized(i) && (*fi).VFp(i)!=0 )
1014  {
1015  size_t oldIndex = (*fi).VFp(i) - fbase;
1016  assert(fbase <= (*fi).VFp(i) && oldIndex < pu.remap.size());
1017  (*fi).VFp(i) = fbase+pu.remap[oldIndex];
1018  }
1019  if(HasFFAdjacency(m))
1020  for(int i=0;i<(*fi).VN();++i)
1021  if ((*fi).cFFp(i)!=0)
1022  {
1023  size_t oldIndex = (*fi).FFp(i) - fbase;
1024  assert(fbase <= (*fi).FFp(i) && oldIndex < pu.remap.size());
1025  (*fi).FFp(i) = fbase+pu.remap[oldIndex];
1026  }
1027  }
1028 
1029 
1030 
1031  }
1032 
1034  static void CompactFaceVector( MeshType &m ) {
1036  CompactFaceVector(m,pu);
1037  }
1038 
1039 
1040 
1041 public:
1042 
1045  template <class ATTR_TYPE>
1046  static
1047  bool IsValidHandle( MeshType & m, const typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & a){
1048  if(a._handle == NULL) return false;
1049  for(AttrIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i)
1050  if ( (*i).n_attr == a.n_attr ) return true;
1051  return false;
1052  }
1053 
1058  template <class ATTR_TYPE>
1059  static
1060  typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1061  AddPerVertexAttribute( MeshType & m, std::string name){
1062  PAIte i;
1063  PointerToAttribute h;
1064  h._name = name;
1065  if(!name.empty()){
1066  i = m.vert_attr.find(h);
1067  assert(i ==m.vert_attr.end() );// an attribute with this name exists
1068  }
1069 
1070  h._sizeof = sizeof(ATTR_TYPE);
1071  h._padding = 0;
1072  h._handle = new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
1073  h._type = typeid(ATTR_TYPE);
1074  m.attrn++;
1075  h.n_attr = m.attrn;
1076  std::pair < AttrIterator , bool> res = m.vert_attr.insert(h);
1077  return typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr );
1078  }
1079 
1080  template <class ATTR_TYPE>
1081  static typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1082  AddPerVertexAttribute( MeshType & m){
1083  return AddPerVertexAttribute<ATTR_TYPE>(m,std::string(""));
1084  }
1085 
1090  template <class ATTR_TYPE>
1091  static
1092  typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1093  GetPerVertexAttribute( MeshType & m, std::string name = std::string("")){
1094  typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> h;
1095  if(!name.empty()){
1096  h = FindPerVertexAttribute<ATTR_TYPE>(m,name);
1097  if(IsValidHandle(m,h))
1098  return h;
1099  }
1100  return AddPerVertexAttribute<ATTR_TYPE>(m,name);
1101  }
1102 
1106  template <class ATTR_TYPE>
1107  static typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1108  FindPerVertexAttribute( MeshType & m, const std::string & name)
1109  {
1110  assert(!name.empty());
1111  PointerToAttribute h1; h1._name = name;
1112  typename std::set<PointerToAttribute > :: iterator i;
1113 
1114  i =m.vert_attr.find(h1);
1115  if(i!=m.vert_attr.end())
1116  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1117  if( (*i)._padding != 0 ){
1118  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1119  m.vert_attr.erase(i); // remove it from the set
1120  FixPaddedPerVertexAttribute<ATTR_TYPE>(m,attr);
1121  std::pair<AttrIterator,bool> new_i = m.vert_attr.insert(attr); // insert the modified PointerToAttribute
1122  assert(new_i.second);
1123  i = new_i.first;
1124  }
1125  return typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1126  }
1127  return typename MeshType:: template PerVertexAttributeHandle<ATTR_TYPE>(NULL,0);
1128  }
1129 
1133  template <class ATTR_TYPE>
1134  static void GetAllPerVertexAttribute(MeshType & m, std::vector<std::string> &all){
1135  all.clear();
1136  typename std::set<PointerToAttribute > ::const_iterator i;
1137  for(i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i )
1138  if(!(*i)._name.empty())
1139  {
1140  typename MeshType:: template PerVertexAttributeHandle<ATTR_TYPE> hh;
1141  hh = Allocator<MeshType>:: template FindPerVertexAttribute <ATTR_TYPE>(m,(*i)._name);
1142  if(IsValidHandle<ATTR_TYPE>(m,hh))
1143  all.push_back((*i)._name);
1144  }
1145  }
1146 
1147  template <class ATTR_TYPE>
1148  static
1149  void
1150  ClearPerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h){
1151  typename std::set<PointerToAttribute > ::iterator i;
1152  for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i)
1153  if( (*i)._handle == h._handle ){
1154  for(typename MeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
1155  h[vi] = ATTR_TYPE();
1156  return;}
1157  assert(0);
1158  }
1159 
1162  template <class ATTR_TYPE>
1163  static
1164  void
1165  DeletePerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h){
1166  typename std::set<PointerToAttribute > ::iterator i;
1167  for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i)
1168  if( (*i)._handle == h._handle ){
1169  delete ((SimpleTempData<VertContainer,ATTR_TYPE>*)(*i)._handle);
1170  m.vert_attr.erase(i);
1171  return;}
1172  }
1173 
1174  // Generic DeleteAttribute.
1175  // It must not crash if you try to delete a non existing attribute,
1176  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1177  static
1178  bool DeletePerVertexAttribute( MeshType & m, std::string name){
1179  AttrIterator i;
1180  PointerToAttribute h1; h1._name = name;
1181  i = m.vert_attr.find(h1);
1182  if(i==m.vert_attr.end()) return false;
1183  delete ((SimpleTempDataBase*)(*i)._handle);
1184  m.vert_attr.erase(i);
1185  return true;
1186  }
1187 
1188 
1189 
1191  template <class ATTR_TYPE>
1192  static
1193  bool IsValidHandle( MeshType & m, const typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> & a){
1194  if(a._handle == NULL) return false;
1195  for(AttrIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i)
1196  if ( (*i).n_attr == a.n_attr ) return true;
1197  return false;
1198  }
1199 
1200  template <class ATTR_TYPE>
1201  static
1202  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1203  AddPerEdgeAttribute( MeshType & m, std::string name){
1204  PAIte i;
1205  PointerToAttribute h;
1206  h._name = name;
1207  if(!name.empty()){
1208  i = m.edge_attr.find(h);
1209  assert(i ==m.edge_attr.end() );// an attribute with this name exists
1210  }
1211  h._sizeof = sizeof(ATTR_TYPE);
1212  h._padding = 0;
1213  // h._typename = typeid(ATTR_TYPE).name();
1214  h._handle = new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
1215  h._type = typeid(ATTR_TYPE);
1216  m.attrn++;
1217  h.n_attr = m.attrn;
1218  std::pair < AttrIterator , bool> res = m.edge_attr.insert(h);
1219  return typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
1220  }
1221 
1222  template <class ATTR_TYPE>
1223  static
1224  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1225  AddPerEdgeAttribute( MeshType & m){
1226  return AddPerEdgeAttribute<ATTR_TYPE>(m,std::string(""));
1227  }
1228 
1233  template <class ATTR_TYPE>
1234  static
1235  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1236  GetPerEdgeAttribute( MeshType & m, std::string name = std::string("")){
1237  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> h;
1238  if(!name.empty()){
1239  h = FindPerEdgeAttribute<ATTR_TYPE>(m,name);
1240  if(IsValidHandle(m,h))
1241  return h;
1242  }
1243  return AddPerEdgeAttribute<ATTR_TYPE>(m,name);
1244  }
1245 
1246 
1247  template <class ATTR_TYPE>
1248  static
1249  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1250  FindPerEdgeAttribute( MeshType & m, const std::string & name){
1251  assert(!name.empty());
1252  PointerToAttribute h1; h1._name = name;
1253  typename std::set<PointerToAttribute > ::const_iterator i;
1254 
1255  i =m.edge_attr.find(h1);
1256  if(i!=m.edge_attr.end())
1257  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1258  if( (*i)._padding != 0 ){
1259  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1260  m.edge_attr.erase(i); // remove it from the set
1261  FixPaddedPerEdgeAttribute<ATTR_TYPE>(m,attr);
1262  std::pair<AttrIterator,bool> new_i = m.edge_attr.insert(attr); // insert the modified PointerToAttribute
1263  assert(new_i.second);
1264  i = new_i.first;
1265  }
1266  return typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1267  }
1268 
1269  return typename MeshType:: template PerEdgeAttributeHandle<ATTR_TYPE>(NULL,0);
1270  }
1271 
1272  template <class ATTR_TYPE>
1273  static void GetAllPerEdgeAttribute(const MeshType & m, std::vector<std::string> &all){
1274  all.clear();
1275  typename std::set<PointerToAttribute > :: const_iterator i;
1276  for(i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i )
1277  if(!(*i)._name.empty())
1278  {
1279  typename MeshType:: template PerEdgeAttributeHandle<ATTR_TYPE> hh;
1280  hh = Allocator<MeshType>:: template FindPerEdgeAttribute <ATTR_TYPE>(m,(*i)._name);
1281  if(IsValidHandle<ATTR_TYPE>(m,hh))
1282  all.push_back((*i)._name);
1283  }
1284  }
1285 
1288  template <class ATTR_TYPE>
1289  static
1290  void
1291  DeletePerEdgeAttribute( MeshType & m,typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> & h){
1292  typename std::set<PointerToAttribute > ::iterator i;
1293  for( i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i)
1294  if( (*i)._handle == h._handle ){
1295  delete ((SimpleTempData<FaceContainer,ATTR_TYPE>*)(*i)._handle);
1296  m.edge_attr.erase(i);
1297  return;}
1298  }
1299 
1300  // Generic DeleteAttribute.
1301  // It must not crash if you try to delete a non existing attribute,
1302  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1303  static
1304  bool DeletePerEdgeAttribute( MeshType & m, std::string name){
1305  AttrIterator i;
1306  PointerToAttribute h1; h1._name = name;
1307  i = m.edge_attr.find(h1);
1308  if(i==m.edge_attr.end()) return false;
1309  delete ((SimpleTempDataBase*)(*i)._handle);
1310  m.edge_attr.erase(i);
1311  return true;
1312  }
1313 
1315  template <class ATTR_TYPE>
1316  static
1317  bool IsValidHandle( MeshType & m, const typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> & a){
1318  if(a._handle == NULL) return false;
1319  for(AttrIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i)
1320  if ( (*i).n_attr == a.n_attr ) return true;
1321  return false;
1322  }
1323 
1324  template <class ATTR_TYPE>
1325  static
1326  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1327  AddPerFaceAttribute( MeshType & m, std::string name){
1328  PAIte i;
1329  PointerToAttribute h;
1330  h._name = name;
1331  if(!name.empty()){
1332  i = m.face_attr.find(h);
1333  assert(i ==m.face_attr.end() );// an attribute with this name exists
1334  }
1335 
1336  h._sizeof = sizeof(ATTR_TYPE);
1337  h._padding = 0;
1338  h._handle = new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
1339  h._type = typeid(ATTR_TYPE);
1340  m.attrn++;
1341  h.n_attr = m.attrn;
1342  std::pair < AttrIterator , bool> res = m.face_attr.insert(h);
1343  return typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
1344  }
1345 
1346  template <class ATTR_TYPE>
1347  static
1348  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1349  AddPerFaceAttribute( MeshType & m){
1350  return AddPerFaceAttribute<ATTR_TYPE>(m,std::string(""));
1351  }
1352 
1357  template <class ATTR_TYPE>
1358  static
1359  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1360  GetPerFaceAttribute( MeshType & m, std::string name = std::string("")){
1361  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> h;
1362  if(!name.empty()){
1363  h = FindPerFaceAttribute<ATTR_TYPE>(m,name);
1364  if(IsValidHandle(m,h))
1365  return h;
1366  }
1367  return AddPerFaceAttribute<ATTR_TYPE>(m,name);
1368  }
1369 
1370  template <class ATTR_TYPE>
1371  static
1372  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1373  FindPerFaceAttribute( MeshType & m, const std::string & name){
1374  assert(!name.empty());
1375  PointerToAttribute h1; h1._name = name;
1376  typename std::set<PointerToAttribute > ::iterator i;
1377 
1378  i =m.face_attr.find(h1);
1379  if(i!=m.face_attr.end())
1380  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1381  if( (*i)._padding != 0 ){
1382  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1383  m.face_attr.erase(i); // remove it from the set
1384  FixPaddedPerFaceAttribute<ATTR_TYPE>(m,attr);
1385  std::pair<AttrIterator,bool> new_i = m.face_attr.insert(attr); // insert the modified PointerToAttribute
1386  assert(new_i.second);
1387  i = new_i.first;
1388  }
1389  return typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1390  }
1391  return typename MeshType:: template PerFaceAttributeHandle<ATTR_TYPE>(NULL,0);
1392  }
1393 
1394  template <class ATTR_TYPE>
1395  static void GetAllPerFaceAttribute(MeshType & m, std::vector<std::string> &all){
1396  all.clear();
1397  typename std::set<PointerToAttribute > :: const_iterator i;
1398  for(i = m.face_attr.begin(); i != m.face_attr.end(); ++i )
1399  if(!(*i)._name.empty())
1400  {
1401  typename MeshType:: template PerFaceAttributeHandle<ATTR_TYPE> hh;
1402  hh = Allocator<MeshType>:: template FindPerFaceAttribute <ATTR_TYPE>(m,(*i)._name);
1403  if(IsValidHandle<ATTR_TYPE>(m,hh))
1404  all.push_back((*i)._name);
1405  }
1406  }
1407 
1410  template <class ATTR_TYPE>
1411  static void DeletePerFaceAttribute( MeshType & m,typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> & h){
1412  typename std::set<PointerToAttribute > ::iterator i;
1413  for( i = m.face_attr.begin(); i != m.face_attr.end(); ++i)
1414  if( (*i)._handle == h._handle ){
1415  delete ((SimpleTempData<FaceContainer,ATTR_TYPE>*)(*i)._handle);
1416  m.face_attr.erase(i);
1417  return;}
1418 
1419  }
1420 
1421  // Generic DeleteAttribute.
1422  // It must not crash if you try to delete a non existing attribute,
1423  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1424  static bool DeletePerFaceAttribute( MeshType & m, std::string name){
1425  AttrIterator i;
1426  PointerToAttribute h1; h1._name = name;
1427  i = m.face_attr.find(h1);
1428  if(i==m.face_attr.end()) return false;
1429  delete ((SimpleTempDataBase*)(*i)._handle);
1430  m.face_attr.erase(i);
1431  return true;
1432  }
1433 
1435  template <class ATTR_TYPE>
1436  static
1437  bool IsValidHandle( MeshType & m, const typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> & a){
1438  if(a._handle == NULL) return false;
1439  for(AttrIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i)
1440  if ( (*i).n_attr == a.n_attr ) return true;
1441  return false;
1442  }
1443 
1444  template <class ATTR_TYPE>
1445  static
1446  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
1447  AddPerMeshAttribute( MeshType & m, std::string name){
1448  PAIte i;
1449  PointerToAttribute h;
1450  h._name = name;
1451  if(!name.empty()){
1452  i = m.mesh_attr.find(h);
1453  assert(i ==m.mesh_attr.end() );// an attribute with this name exists
1454  }
1455  h._sizeof = sizeof(ATTR_TYPE);
1456  h._padding = 0;
1457  h._handle = new Attribute<ATTR_TYPE>();
1458  h._type = typeid(ATTR_TYPE);
1459  m.attrn++;
1460  h.n_attr = m.attrn;
1461  std::pair < AttrIterator , bool> res = m.mesh_attr.insert(h);
1462  return typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
1463  }
1464 
1469  template <class ATTR_TYPE>
1470  static
1471  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
1472  GetPerMeshAttribute( MeshType & m, std::string name = std::string("")){
1473  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> h;
1474  if(!name.empty()){
1475  h = FindPerMeshAttribute<ATTR_TYPE>(m,name);
1476  if(IsValidHandle(m,h))
1477  return h;
1478  }
1479  return AddPerMeshAttribute<ATTR_TYPE>(m,name);
1480  }
1481 
1482  template <class ATTR_TYPE>
1483  static
1484  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
1485  FindPerMeshAttribute( MeshType & m, const std::string & name){
1486  assert(!name.empty());
1487  PointerToAttribute h1; h1._name = name;
1488  typename std::set<PointerToAttribute > ::iterator i;
1489 
1490  i =m.mesh_attr.find(h1);
1491  if(i!=m.mesh_attr.end())
1492  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1493  if( (*i)._padding != 0 ){
1494  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1495  m.mesh_attr.erase(i); // remove it from the set
1496  FixPaddedPerMeshAttribute<ATTR_TYPE>(m,attr);
1497  std::pair<AttrIterator,bool> new_i = m.mesh_attr.insert(attr); // insert the modified PointerToAttribute
1498  assert(new_i.second);
1499  i = new_i.first;
1500  }
1501 
1502  return typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1503  }
1504 
1505  return typename MeshType:: template PerMeshAttributeHandle<ATTR_TYPE>(NULL,0);
1506  }
1507 
1508  template <class ATTR_TYPE>
1509  static void GetAllPerMeshAttribute(const MeshType & m, std::vector<std::string> &all){
1510  typename std::set<PointerToAttribute > :: iterator i;
1511  for(i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i )
1512  if((*i)._sizeof == sizeof(ATTR_TYPE))
1513  all.push_back((*i)._name);
1514  }
1515 
1518  template <class ATTR_TYPE>
1519  static void DeletePerMeshAttribute( MeshType & m,typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> & h){
1520  typename std::set<PointerToAttribute > ::iterator i;
1521  for( i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i)
1522  if( (*i)._handle == h._handle ){
1523  delete (( Attribute<ATTR_TYPE> *)(*i)._handle);
1524  m.mesh_attr.erase(i);
1525  return;}
1526  }
1527 
1528  // Generic DeleteAttribute.
1529  // It must not crash if you try to delete a non existing attribute,
1530  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1531  static bool DeletePerMeshAttribute( MeshType & m, std::string name){
1532  AttrIterator i;
1533  PointerToAttribute h1; h1._name = name;
1534  i = m.mesh_attr.find(h1);
1535  if (i==m.mesh_attr.end())
1536  return false;
1537  delete ((SimpleTempDataBase *)(*i)._handle);
1538  m.mesh_attr.erase(i);
1539  return true;
1540  }
1541 
1542  template <class ATTR_TYPE>
1543  static void FixPaddedPerVertexAttribute (MeshType & m, PointerToAttribute & pa){
1544 
1545  // create the container of the right type
1546  SimpleTempData<VertContainer,ATTR_TYPE>* _handle = new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
1547 
1548  // copy the padded container in the new one
1549  _handle->Resize(m.vert.size());
1550  for(size_t i = 0; i < m.vert.size(); ++i){
1551  ATTR_TYPE * dest = &(*_handle)[i];
1552  char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
1553  memcpy((void*)dest ,
1554  (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
1555  }
1556 
1557  // remove the padded container
1558  delete ((SimpleTempDataBase*) pa._handle);
1559 
1560  // update the pointer to data
1561  pa._sizeof = sizeof(ATTR_TYPE);
1562 
1563  // update the pointer to data
1564  pa._handle = _handle;
1565 
1566  // zero the padding
1567  pa._padding = 0;
1568  }
1569  template <class ATTR_TYPE>
1570  static void FixPaddedPerEdgeAttribute (MeshType & m, PointerToAttribute & pa){
1571 
1572  // create the container of the right type
1573  SimpleTempData<EdgeContainer,ATTR_TYPE>* _handle = new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
1574 
1575  // copy the padded container in the new one
1576  _handle->Resize(m.edge.size());
1577  for(size_t i = 0; i < m.edge.size(); ++i){
1578  ATTR_TYPE * dest = &(*_handle)[i];
1579  char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
1580  memcpy((void*)dest ,
1581  (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
1582  }
1583 
1584  // remove the padded container
1585  delete ((SimpleTempDataBase*) pa._handle);
1586 
1587  // update the pointer to data
1588  pa._sizeof = sizeof(ATTR_TYPE);
1589 
1590  // update the pointer to data
1591  pa._handle = _handle;
1592 
1593  // zero the padding
1594  pa._padding = 0;
1595  }
1596 
1597  template <class ATTR_TYPE>
1598  static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){
1599 
1600  // create the container of the right type
1601  SimpleTempData<FaceContainer,ATTR_TYPE>* _handle = new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
1602 
1603  // copy the padded container in the new one
1604  _handle->Resize(m.face.size());
1605  for(size_t i = 0; i < m.face.size(); ++i){
1606  ATTR_TYPE * dest = &(*_handle)[i];
1607  char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
1608  memcpy((void*)dest ,
1609  (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
1610  }
1611 
1612  // remove the padded container
1613  delete ((SimpleTempDataBase*) pa._handle);
1614 
1615  // update the pointer to data
1616  pa._sizeof = sizeof(ATTR_TYPE);
1617 
1618  // update the pointer to data
1619  pa._handle = _handle;
1620 
1621  // zero the padding
1622  pa._padding = 0;
1623  }
1624 
1625 
1626  template <class ATTR_TYPE>
1627  static void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){
1628 
1629  // create the container of the right type
1630  Attribute<ATTR_TYPE> * _handle = new Attribute<ATTR_TYPE>();
1631 
1632  // copy the padded container in the new one
1633  char * ptr = (char*)( ((Attribute<ATTR_TYPE> *)pa._handle)->DataBegin());
1634  memcpy((void*)_handle->attribute ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE));
1635 
1636  // remove the padded container
1637  delete ( (Attribute<ATTR_TYPE> *) pa._handle);
1638 
1639  // update the pointer to data
1640  pa._sizeof = sizeof(ATTR_TYPE);
1641 
1642  // update the pointer to data
1643  pa._handle = _handle;
1644 
1645  // zero the padding
1646  pa._padding = 0;
1647  }
1648 
1649 }; // end Allocator class
1650 
1651  // end doxygen group trimesh
1653 } // end namespace tri
1654 } // end namespace vcg
1655 
1656 #endif