$darkmode
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 #include <vector>
27 #include <set>
28 
29 #include <vcg/container/simple_temporary_data.h>
30 
31 #include "used_types.h"
32 
33 namespace vcg {
34 namespace tri {
39 template<class MeshType>
40 size_t Index(const MeshType &m, const typename MeshType::VertexType &v) {return &v-&*m.vert.begin();}
41 template<class MeshType>
42 size_t Index(const MeshType &m, const typename MeshType::FaceType &f) {return &f-&*m.face.begin();}
43 template<class MeshType>
44 size_t Index(const MeshType &m, const typename MeshType::EdgeType &e) {return &e-&*m.edge.begin();}
45 template<class MeshType>
46 size_t Index(const MeshType &m, const typename MeshType::HEdgeType &h) {return &h-&*m.hedge.begin();}
47 template <class MeshType>
48 size_t Index(const MeshType &m, const typename MeshType::TetraType &t) { return &t - &*m.tetra.begin(); }
49 
50 
51 template<class MeshType>
52 size_t Index(const MeshType &m, const typename MeshType::VertexType *vp) {return vp-&*m.vert.begin();}
53 template<class MeshType>
54 size_t Index(const MeshType &m, const typename MeshType::FaceType * fp) {return fp-&*m.face.begin();}
55 template<class MeshType>
56 size_t Index(const MeshType &m, const typename MeshType::EdgeType* e) {return e-&*m.edge.begin();}
57 template<class MeshType>
58 size_t Index(const MeshType &m, const typename MeshType::HEdgeType* h) {return h-&*m.hedge.begin();}
59 template <class MeshType>
60 size_t Index(const MeshType &m, const typename MeshType::TetraType *t) { return t - &*m.tetra.begin(); }
61 
62 
63 template<class MeshType>
64 bool IsValidPointer( MeshType & m, const typename MeshType::VertexType *vp) { return ( m.vert.size() > 0 && (vp >= &*m.vert.begin()) && (vp <= &m.vert.back()) ); }
65 template<class MeshType>
66 bool IsValidPointer(MeshType & m, const typename MeshType::EdgeType *ep) { return ( m.edge.size() > 0 && (ep >= &*m.edge.begin()) && (ep <= &m.edge.back())); }
67 template<class MeshType>
68 bool IsValidPointer(MeshType & m, const typename MeshType::FaceType *fp) { return ( m.face.size() > 0 && (fp >= &*m.face.begin()) && (fp <= &m.face.back())); }
69 template<class MeshType>
70 bool IsValidPointer(MeshType & m, const typename MeshType::HEdgeType *hp) { return ( m.hedge.size() > 0 && (hp >= &*m.hedge.begin()) && (hp <= &m.hedge.back())); }
71 template <class MeshType>
72 bool IsValidPointer(MeshType &m, const typename MeshType::TetraType *tp) { return (m.tetra.size() > 0 && (tp >= &*m.tetra.begin()) && (tp <= &m.tetra.back())); }
73 
74 template <class MeshType, class ATTR_CONT>
75 void ReorderAttribute(ATTR_CONT &c, std::vector<size_t> & newVertIndex, MeshType & /* m */){
76  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
77  for(ai = c.begin(); ai != c.end(); ++ai)
78  ((typename MeshType::PointerToAttribute)(*ai)).Reorder(newVertIndex);
79 }
80 
81 template <class MeshType, class ATTR_CONT>
82 void ResizeAttribute(ATTR_CONT &c, size_t sz, MeshType &/*m*/){
83  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
84  for(ai =c.begin(); ai != c.end(); ++ai)
85  ((typename MeshType::PointerToAttribute)(*ai)).Resize(sz);
86 }
87 
95 template <class MeshType>
96 class Allocator
97 {
98 
99 public:
100  typedef typename MeshType::VertexType VertexType;
101  typedef typename MeshType::VertexPointer VertexPointer;
102  typedef typename MeshType::VertexIterator VertexIterator;
103  typedef typename MeshType::VertContainer VertContainer;
104 
105  typedef typename MeshType::EdgeType EdgeType;
106  typedef typename MeshType::EdgePointer EdgePointer;
107  typedef typename MeshType::EdgeIterator EdgeIterator;
108  typedef typename MeshType::EdgeContainer EdgeContainer;
109 
110  typedef typename MeshType::FaceType FaceType;
111  typedef typename MeshType::FacePointer FacePointer;
112  typedef typename MeshType::FaceIterator FaceIterator;
113  typedef typename MeshType::FaceContainer FaceContainer;
114 
115  typedef typename MeshType::HEdgeType HEdgeType;
116  typedef typename MeshType::HEdgePointer HEdgePointer;
117  typedef typename MeshType::HEdgeIterator HEdgeIterator;
118  typedef typename MeshType::HEdgeContainer HEdgeContainer;
119 
120  typedef typename MeshType::TetraType TetraType;
121  typedef typename MeshType::TetraPointer TetraPointer;
122  typedef typename MeshType::TetraIterator TetraIterator;
123  typedef typename MeshType::TetraContainer TetraContainer;
124 
125  typedef typename MeshType::CoordType CoordType;
126 
127  typedef typename MeshType::PointerToAttribute PointerToAttribute;
128  typedef typename std::set<PointerToAttribute>::iterator AttrIterator;
129  typedef typename std::set<PointerToAttribute>::const_iterator AttrConstIterator;
130  typedef typename std::set<PointerToAttribute >::iterator PAIte;
131 
143  template<class SimplexPointerType>
145  {
146  public:
147  PointerUpdater(void) : newBase(0), oldBase(0), newEnd(0), oldEnd(0), preventUpdateFlag(false) { ; }
148  void Clear(){newBase=oldBase=newEnd=oldEnd=0; remap.clear();}
153  void Update(SimplexPointerType &vp)
154  {
155  //if(vp>=newBase && vp<newEnd) return;
156  if(vp<oldBase || vp>oldEnd) return;
157  assert(vp>=oldBase);
158  assert(vp<oldEnd);
159  vp=newBase+(vp-oldBase);
160  if(!remap.empty())
161  vp = newBase + remap[vp-newBase];
162  }
166  bool NeedUpdate() {if((oldBase && newBase!=oldBase && !preventUpdateFlag) || !remap.empty()) return true; else return false;}
167 
168  SimplexPointerType newBase;
169  SimplexPointerType oldBase;
170  SimplexPointerType newEnd;
171  SimplexPointerType oldEnd;
172  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.
173 
174  bool preventUpdateFlag;
175  };
176 
177  /* +++++++++++++++ Add Vertices ++++++++++++++++ */
178 
189  static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater<VertexPointer> &pu)
190  {
191  VertexIterator last;
192  if(n == 0)
193  return m.vert.end();
194  pu.Clear();
195 
196  if(m.vert.empty())
197  pu.oldBase=0; // if the vector is empty we cannot find the last valid element
198  else {
199  pu.oldBase=&*m.vert.begin();
200  pu.oldEnd=&m.vert.back()+1;
201  }
202 
203  m.vert.resize(m.vert.size()+n);
204  m.vn+=int(n);
205 
206  typename std::set<PointerToAttribute>::iterator ai;
207  for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai)
208  ((PointerToAttribute)(*ai)).Resize(m.vert.size());
209 
210  pu.newBase = &*m.vert.begin();
211  pu.newEnd = &m.vert.back()+1;
212  if(pu.NeedUpdate())
213  {
214  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
215  if(!(*fi).IsD())
216  for(int i=0; i < (*fi).VN(); ++i)
217  if ((*fi).cV(i)!=0) pu.Update((*fi).V(i));
218 
219  for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
220  if(!(*ei).IsD())
221  {
222  // if(HasEVAdjacency (m))
223  pu.Update((*ei).V(0));
224  pu.Update((*ei).V(1));
225  // if(HasEVAdjacency(m)) pu.Update((*ei).EVp());
226  }
227 
228  HEdgeIterator hi;
229  for (hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
230  if(!(*hi).IsD())
231  {
232  if(HasHVAdjacency (m))
233  {
234  pu.Update((*hi).HVp());
235  }
236  }
237 
238  for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
239  if (!(*ti).IsD())
240  for (int i = 0; i < 4; ++i)
241  if ((*ti).cV(i) != 0)
242  pu.Update((*ti).V(i));
243 
244  // e poiche' lo spazio e' cambiato si ricalcola anche last da zero
245  }
246  size_t siz=(size_t)(m.vert.size()-n);
247 
248  last = m.vert.begin();
249  advance(last,siz);
250 
251  return last;// deve restituire l'iteratore alla prima faccia aggiunta;
252  }
253 
256  static VertexIterator AddVertices(MeshType &m, size_t n)
257  {
259  return AddVertices(m, n,pu);
260  }
261 
264  static VertexIterator AddVertices(MeshType &m, size_t n, std::vector<VertexPointer *> &local_vec)
265  {
267  VertexIterator v_ret = AddVertices(m, n,pu);
268 
269  typename std::vector<VertexPointer *>::iterator vi;
270  for(vi=local_vec.begin();vi!=local_vec.end();++vi)
271  pu.Update(**vi);
272  return v_ret;
273  }
274 
278  static VertexIterator AddVertices(MeshType &m, const Eigen::MatrixXf &vm)
279  {
280  VertexIterator v_ret = AddVertices(m, vm.rows());
281  VertexIterator v_start = v_ret;
282  for(int i=0;i<vm.rows();++i)
283  {
284  v_ret->P()[0]=vm(i,0);
285  v_ret->P()[1]=vm(i,1);
286  v_ret->P()[2]=vm(i,2);
287  ++v_ret;
288  }
289  return v_start;
290  }
291 
292 
295  static VertexIterator AddVertex(MeshType &m, const CoordType &p)
296  {
297  VertexIterator v_ret = AddVertices(m, 1);
298  v_ret->P()=p;
299  return v_ret;
300  }
301 
304  static VertexIterator AddVertex(MeshType &m, const CoordType &p, const CoordType &n)
305  {
306  VertexIterator v_ret = AddVertices(m, 1);
307  v_ret->P()=p;
308  v_ret->N()=n;
309  return v_ret;
310  }
311 
314  static VertexIterator AddVertex(MeshType &m, const CoordType &p, const Color4b &c)
315  {
316  VertexIterator v_ret = AddVertices(m, 1);
317  v_ret->P()=p;
318  v_ret->C()=c;
319  return v_ret;
320  }
321 
322  /* +++++++++++++++ Add Edges ++++++++++++++++ */
323 
333  static EdgeIterator AddEdges(MeshType &m, size_t n, PointerUpdater<EdgePointer> &pu)
334  {
335  if(n == 0) return m.edge.end();
336  pu.Clear();
337  if(m.edge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element
338  else {
339  pu.oldBase=&*m.edge.begin();
340  pu.oldEnd=&m.edge.back()+1;
341  }
342 
343  m.edge.resize(m.edge.size()+n);
344  m.en+=int(n);
345  size_t siz=(size_t)(m.edge.size()-n);
346  EdgeIterator firstNewEdge = m.edge.begin();
347  advance(firstNewEdge,siz);
348 
349  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
350  for(ai = m.edge_attr.begin(); ai != m.edge_attr.end(); ++ai)
351  ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.edge.size());
352 
353  pu.newBase = &*m.edge.begin();
354  pu.newEnd = &m.edge.back()+1;
355  if(pu.NeedUpdate())
356  {
357  if(HasFEAdjacency(m))
358  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi){
359  if(!(*fi).IsD())
360  for(int i=0; i < (*fi).VN(); ++i)
361  if ((*fi).cFEp(i)!=0) pu.Update((*fi).FEp(i));
362  }
363 
364  if(HasVEAdjacency(m)){
365  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
366  if(!(*vi).IsD())
367  if ((*vi).cVEp()!=0) pu.Update((*vi).VEp());
368  for(EdgeIterator ei=m.edge.begin();ei!=firstNewEdge;++ei)
369  if(!(*ei).IsD())
370  {
371  if ((*ei).cVEp(0)!=0) pu.Update((*ei).VEp(0));
372  if ((*ei).cVEp(1)!=0) pu.Update((*ei).VEp(1));
373  }
374  }
375 
376  if(HasHEAdjacency(m))
377  for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
378  if(!(*hi).IsD())
379  if ((*hi).cHEp()!=0) pu.Update((*hi).HEp());
380  }
381 
382  return firstNewEdge;// deve restituire l'iteratore alla prima faccia aggiunta;
383  }
384 
387  static EdgeIterator AddEdge(MeshType &m, VertexPointer v0, VertexPointer v1)
388  {
389  EdgeIterator ei= AddEdges(m, 1);
390  ei->V(0)=v0;
391  ei->V(1)=v1;
392  return ei;
393  }
394 
397  static EdgeIterator AddEdge(MeshType &m, size_t v0, size_t v1)
398  {
399  assert(v0!=v1);
400  assert(v0>=0 && v0<m.vert.size());
401  assert(v1>=0 && v1<m.vert.size());
402  return AddEdge(m,&(m.vert[v0]),&(m.vert[v1]));
403  }
404 
405 
408  static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1)
409  {
410  VertexIterator vi = AddVertices(m,2);
411  EdgeIterator ei = AddEdges(m,1);
412  vi->P()=p0;
413  ei->V(0)=&*vi++;
414  vi->P()=p1;
415  ei->V(1)=&*vi++;
416  return ei;
417  }
418 
422  static EdgeIterator AddEdges(MeshType &m, size_t n)
423  {
425  return AddEdges(m, n,pu);
426  }
427 
431  static EdgeIterator AddEdges(MeshType &m, size_t n, std::vector<EdgePointer*> &local_vec)
432  {
434  EdgeIterator v_ret = AddEdges(m, n,pu);
435 
436  typename std::vector<EdgePointer *>::iterator ei;
437  for(ei=local_vec.begin();ei!=local_vec.end();++ei)
438  pu.Update(**ei);
439  return v_ret;
440  }
441 
442  /* +++++++++++++++ Add HalfEdges ++++++++++++++++ */
443 
453  static HEdgeIterator AddHEdges(MeshType &m, size_t n, PointerUpdater<HEdgePointer> &pu)
454  {
455  HEdgeIterator last;
456  if(n == 0) return m.hedge.end();
457  pu.Clear();
458  if(m.hedge.empty()) pu.oldBase=0; // if the vector is empty we cannot find the last valid element
459  else {
460  pu.oldBase=&*m.hedge.begin();
461  pu.oldEnd=&m.hedge.back()+1;
462  }
463 
464  m.hedge.resize(m.hedge.size()+n);
465  m.hn+=int(n);
466 
467  pu.newBase = &*m.hedge.begin();
468  pu.newEnd = &m.hedge.back()+1;
469 
470  if(pu.NeedUpdate())
471  {
472  if(HasFHAdjacency(m)) {
473  for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
474  {
475  if(!(*fi).IsD() && (*fi).FHp())
476  pu.Update((*fi).FHp());
477  }
478  }
479  if(HasVHAdjacency(m)) {
480  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
481  if(!(*vi).IsD() && (*vi).cVHp()!=0)
482  pu.Update((*vi).VHp());
483  }
484  if(HasEHAdjacency(m)) {
485  for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
486  if(!(*ei).IsD() && (*ei).cEHp()!=0)
487  pu.Update((*ei).EHp());
488  }
489 
490  int ii = 0;
491  HEdgeIterator hi = m.hedge.begin();
492  while(ii < m.hn - int(n))// cycle on all the faces except the new ones
493  {
494  if(!(*hi).IsD())
495  {
496  if(HasHNextAdjacency(m)) pu.Update((*hi).HNp());
497  if(HasHPrevAdjacency(m)) pu.Update((*hi).HPp());
498  if(HasHOppAdjacency(m)) pu.Update((*hi).HOp());
499  ++ii;
500  }
501  ++hi;
502  }
503  }
504  size_t siz = (size_t)(m.hedge.size()-n);
505 
506  last = m.hedge.begin();
507  advance(last,siz);
508 
509  return last;// deve restituire l'iteratore alla prima faccia aggiunta;
510  }
511 
515  static HEdgeIterator AddHEdges(MeshType &m, size_t n)
516  {
518  return AddHEdges(m, n,pu);
519  }
520 
524  static HEdgeIterator AddHEdges(MeshType &m, size_t n, std::vector<HEdgePointer*> &local_vec)
525  {
527  HEdgeIterator v_ret = AddHEdges(m, n,pu);
528 
529  typename std::vector<HEdgePointer *>::iterator ei;
530  for(ei=local_vec.begin();ei!=local_vec.end();++ei)
531  pu.Update(**ei);
532  return v_ret;
533  }
534 
535  /* +++++++++++++++ Add Faces ++++++++++++++++ */
536 
539  static FaceIterator AddFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2)
540  {
541  assert(m.vert.size()>0);
542  assert((v0!=v1) && (v1!=v2) && (v0!=v2));
543  assert(v0>=&m.vert.front() && v0<=&m.vert.back());
544  assert(v1>=&m.vert.front() && v1<=&m.vert.back());
545  assert(v2>=&m.vert.front() && v2<=&m.vert.back());
547  FaceIterator fi = AddFaces(m,1,pu);
548  fi->Alloc(3);
549  fi->V(0)=v0;
550  fi->V(1)=v1;
551  fi->V(2)=v2;
552  return fi;
553  }
554 
557  static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2)
558  {
559  assert((v0!=v1) && (v1!=v2) && (v0!=v2));
560  assert(v0>=0 && v0<m.vert.size());
561  assert(v1>=0 && v1<m.vert.size());
562  assert(v2>=0 && v2<m.vert.size());
563  return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2]));
564  }
567  static FaceIterator AddFace(MeshType &m, CoordType p0, CoordType p1, CoordType p2)
568  {
569  VertexIterator vi = AddVertices(m,3);
570  FaceIterator fi = AddFaces(m,1);
571  fi->Alloc(3);
572  vi->P()=p0;
573  fi->V(0)=&*vi++;
574  vi->P()=p1;
575  fi->V(1)=&*vi++;
576  vi->P()=p2;
577  fi->V(2)=&*vi;
578  return fi;
579  }
580 
585  static FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
586  {
587  assert(m.vert.size()>0);
588  assert(v0>=&m.vert.front() && v0<=&m.vert.back());
589  assert(v1>=&m.vert.front() && v1<=&m.vert.back());
590  assert(v2>=&m.vert.front() && v2<=&m.vert.back());
591  assert(v3>=&m.vert.front() && v3<=&m.vert.back());
593  if(FaceType::HasPolyInfo())
594  {
595  FaceIterator fi = AddFaces(m,1,pu);
596  fi->Alloc(4);
597  fi->V(0)=v0; fi->V(1)=v1;
598  fi->V(2)=v2; fi->V(3)=v3;
599  return fi;
600  }
601  else
602  {
603  FaceIterator fi = AddFaces(m,2,pu);
604  fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v1; fi->V(2)=v2;
605  fi->SetF(2);
606  ++fi;
607  fi->Alloc(3); fi->V(0)=v0; fi->V(1)=v2; fi->V(2)=v3;
608  fi->SetF(0);
609  return fi;
610  }
611  }
615  static FaceIterator AddFaces(MeshType &m, size_t n)
616  {
618  return AddFaces(m,n,pu);
619  }
620 
624  static FaceIterator AddFaces(MeshType &m, size_t n,std::vector<FacePointer *> &local_vec)
625  {
627  FaceIterator f_ret= AddFaces(m,n,pu);
628 
629  typename std::vector<FacePointer *>::iterator fi;
630  for(fi=local_vec.begin();fi!=local_vec.end();++fi)
631  pu.Update(**fi);
632  return f_ret;
633  }
634 
638  static FaceIterator AddFaces(MeshType &m, const Eigen::MatrixXi &fm)
639  {
641  FaceIterator f_start = AddFaces(m,fm.rows(),pu);
642  FaceIterator f_ret=f_start;
643  for(int i=0;i<fm.rows();++i)
644  {
645  f_start->V(0)= &m.vert[fm(i,0)];
646  f_start->V(1)= &m.vert[fm(i,1)];
647  f_start->V(2)= &m.vert[fm(i,2)];
648  ++f_start;
649  }
650  return f_ret;
651  }
652 
665  static FaceIterator AddFaces(MeshType &m, size_t n, PointerUpdater<FacePointer> &pu)
666  {
667  pu.Clear();
668  if(n == 0) return m.face.end();
669  if(!m.face.empty()) // if the vector is empty we cannot find the last valid element
670  {
671  pu.oldBase=&*m.face.begin();
672  pu.oldEnd=&m.face.back()+1;
673  }
674  // The actual resize
675  m.face.resize(m.face.size()+n);
676  m.fn+=int(n);
677 
678  size_t siz=(size_t)(m.face.size()-n);
679  FaceIterator firstNewFace = m.face.begin();
680  advance(firstNewFace,siz);
681 
682  typename std::set<PointerToAttribute>::iterator ai;
683  for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai)
684  ((PointerToAttribute)(*ai)).Resize(m.face.size());
685 
686  pu.newBase = &*m.face.begin();
687  pu.newEnd = &m.face.back()+1;
688 
689  if(pu.NeedUpdate())
690  {
691  if(HasFFAdjacency(m))
692  { // cycle on all the faces except the new ones
693  for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi)
694  if(!(*fi).IsD())
695  for(int i = 0; i < (*fi).VN(); ++i)
696  if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i));
697  }
698 
699  if(HasPerVertexVFAdjacency(m) && HasPerFaceVFAdjacency(m))
700  { // cycle on all the faces except the new ones
701  for(FaceIterator fi=m.face.begin();fi!=firstNewFace;++fi)
702  if(!(*fi).IsD())
703  for(int i = 0; i < (*fi).VN(); ++i)
704  if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i));
705 
706  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
707  if(!(*vi).IsD() && (*vi).cVFp()!=0)
708  pu.Update((*vi).VFp());
709  }
710 
711  if(HasEFAdjacency(m))
712  {
713  for (EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
714  if(!(*ei).IsD() && (*ei).cEFp()!=0)
715  pu.Update((*ei).EFp());
716  }
717 
718  if(HasHFAdjacency(m))
719  {
720  for (HEdgeIterator hi=m.hedge.begin(); hi!=m.hedge.end(); ++hi)
721  if(!(*hi).IsD() && (*hi).cHFp()!=0)
722  pu.Update((*hi).HFp());
723  }
724  }
725  return firstNewFace;
726  }
727 
728  //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
729  //:::::::::::::::::TETRAS ADDER FUNCTIONS:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
730 
743  static TetraIterator AddTetras(MeshType &m, size_t n, PointerUpdater<TetraPointer> &pu)
744  {
745  //nothing to do
746  if (n == 0)
747  return m.tetra.end();
748 
749  //prepare the pointerupdater info
750  pu.Clear();
751  if (m.tetra.empty())
752  pu.oldBase = 0;
753  else
754  {
755  pu.oldBase = &*m.tetra.begin();
756  pu.oldEnd = &m.tetra.back() + 1;
757  }
758 
759  //resize the tetra list and update tetra count
760  m.tetra.resize(m.tetra.size() + n);
761  m.tn += n;
762 
763  //get the old size and advance to the first new tetrahedron position
764  size_t oldSize = (size_t)(m.tetra.size() - n);
765 
766  TetraIterator firstNewTetra = m.tetra.begin();
767  advance(firstNewTetra, oldSize);
768 
769  //for each attribute make adapt the list size
770  typename std::set<typename MeshType::PointerToAttribute>::iterator ai;
771  for (ai = m.tetra_attr.begin(); ai != m.tetra_attr.end(); ++ai)
772  ((typename MeshType::PointerToAttribute)(*ai)).Resize(m.tetra.size());
773 
774  //do the update
775  pu.newBase = &*m.tetra.begin();
776  pu.newEnd = &m.tetra.back() + 1;
777  if (pu.NeedUpdate())
778  {
779  if (HasVTAdjacency(m))
780  {
781  for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
782  if (!vi->IsD())
783  pu.Update(vi->VTp());
784 
785  for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
786  if (!ti->IsD())
787  {
788  pu.Update(ti->VTp(0));
789  pu.Update(ti->VTp(1));
790  pu.Update(ti->VTp(2));
791  pu.Update(ti->VTp(3));
792  }
793  }
794 
795  //do edge and face adjacency
796  if (HasTTAdjacency(m))
797  for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
798  if (!ti->IsD())
799  {
800  pu.Update(ti->TTp(0));
801  pu.Update(ti->TTp(1));
802  pu.Update(ti->TTp(2));
803  pu.Update(ti->TTp(3));
804  }
805  }
806 
807  return firstNewTetra;
808  }
809 
810 //TODO: ADD 4 FACES then add tetra
813  static TetraIterator AddTetra(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
814  {
815  assert(m.vert.size() > 0);
816  assert((v0 != v1) && (v0 != v2) && (v0 != v3) && (v1 != v2) && (v1 != v3) && (v2 != v3));
817  assert(v0 >= &m.vert.front() && v0 <= &m.vert.back());
818  assert(v1 >= &m.vert.front() && v1 <= &m.vert.back());
819  assert(v2 >= &m.vert.front() && v2 <= &m.vert.back());
820  assert(v3 >= &m.vert.front() && v3 <= &m.vert.back());
821 
822 // AddFace(m, v0, v1, v2);
823 // AddFace(m, v0, v3, v1);
824 // AddFace(m, v0, v2, v3);
825 // AddFace(m, v1, v3, v2);
826 
828  TetraIterator ti = AddTetras(m, 1, pu);
829  ti->V(0) = v0;
830  ti->V(1) = v1;
831  ti->V(2) = v2;
832  ti->V(3) = v3;
833  return ti;
834  }
835 
838  static TetraIterator AddTetra(MeshType &m, const size_t v0, const size_t v1, const size_t v2, const size_t v3)
839  {
840  assert(m.vert.size() > 0);
841  assert((v0 != v1) && (v0 != v2) && (v0 != v3) && (v1 != v2) && (v1 != v3) && (v2 != v3));
842  assert(v0 >= 0 && v0 < m.vert.size());
843  assert(v1 >= 0 && v1 < m.vert.size());
844  assert(v2 >= 0 && v2 < m.vert.size());
845  assert(v3 >= 0 && v3 < m.vert.size());
846 
847  return AddTetra(m, &(m.vert[v0]), &(m.vert[v1]), &(m.vert[v2]), &(m.vert[v3]));
848  }
851  static TetraIterator AddTetra(MeshType &m, const CoordType & p0, const CoordType & p1, const CoordType & p2, const CoordType & p3)
852  {
853  VertexIterator vi = AddVertices(m, 4);
854 
855  VertexPointer v0 = &*vi++;
856  VertexPointer v1 = &*vi++;
857  VertexPointer v2 = &*vi++;
858  VertexPointer v3 = &*vi++;
859 
860  v0->P() = p0;
861  v1->P() = p1;
862  v2->P() = p2;
863  v3->P() = p3;
864 
865  return AddTetra(m, v0, v1, v2, v3);
866  }
867 
868 // //requires no duplicate vertices on faces you use
869 // static TetraIterator AddTetra(MeshType &m, const FaceType & f0, const FaceType & f1, const FaceType & f2, const FaceType & f3)
870 // {
871 // assert(m.face.size() > 0);
872 // assert((f0 != f1) && (f0 != f2) && (f0 != f3) && (f1 != f2) && (f1 != f3) && (f2 != f3));
873 // assert(f1 >= 0 && f1 < m.face.size());
874 // assert(f2 >= 0 && f2 < m.face.size());
875 // assert(f3 >= 0 && f3 < m.face.size());
876 // assert(f0 >= 0 && f0 < m.face.size());
877 // //TODO: decide if you want to address this like this
878 // //ERROR: can't use position...so..could force to have no dup verts..and use pointers or avoid this kind of thing
879 // assert(f0.V(0) == f1.V(0) && f0.V(0) == f2.V(0) && //v0
880 // f0.V(1) == f1.V(2) && f0.V(1) == f3.V(0) && //v1
881 // f0.V(2) == f2.V(1) && f0.V(2) == f3.V(2) && //v2
882 // f1.V(1) == f2.V(2) && f1.V(1) == f3.V(1) ) //v3
883 
884 // //add a tetra...and set vertices correctly
885 // PointerUpdater<TetraPointer> pu;
886 // TetraIterator ti = AddTetras(m, 1, pu);
887 // ti->V(0) = f0.V(0);
888 // ti->V(1) = f0.V(1);
889 // ti->V(2) = f0.V(2);
890 // ti->V(3) = f1.V(1);
891 
892 // return ti;
893 // }
894 
898  static TetraIterator AddTetras(MeshType &m, size_t n)
899  {
901  return AddTetras(m, n, pu);
902  }
903 
907  static TetraIterator AddTetras(MeshType &m, size_t n, std::vector<TetraPointer *> &local_vec)
908  {
910  TetraIterator t_ret = AddTetras(m, n, pu);
911 
912  typename std::vector<TetraPointer *>::iterator ti;
913  for (ti = local_vec.begin(); ti != local_vec.end(); ++ti)
914  pu.Update(**ti);
915  return t_ret;
916  }
917 
918  /* +++++++++++++++ Deleting ++++++++++++++++ */
919 
923  static void DeleteFace(MeshType &m, FaceType &f)
924  {
925  assert(&f >= &m.face.front() && &f <= &m.face.back());
926  assert(!f.IsD());
927  f.Dealloc();
928  f.SetD();
929  --m.fn;
930  }
931 
935  static void DeleteVertex(MeshType &m, VertexType &v)
936  {
937  assert(&v >= &m.vert.front() && &v <= &m.vert.back());
938  assert(!v.IsD());
939  v.SetD();
940  --m.vn;
941  }
942 
946  static void DeleteEdge(MeshType &m, EdgeType &e)
947  {
948  assert(&e >= &m.edge.front() && &e <= &m.edge.back());
949  assert(!e.IsD());
950  e.SetD();
951  --m.en;
952  }
953 
957  static void DeleteHEdge(MeshType &m, HEdgeType &h)
958  {
959  assert(&h >= &m.hedge.front() && &h <= &m.hedge.back());
960  assert(!h.IsD());
961  h.SetD();
962  --m.hn;
963  }
964 
968  static void DeleteTetra(MeshType &m, TetraType &t)
969  {
970  assert(&t >= &m.tetra.front() && &t <= &m.tetra.back());
971  assert(!t.IsD());
972  t.SetD();
973  --m.tn;
974  }
975 
976  /*
977  Function to rearrange the vertex vector according to a given index permutation
978  the permutation is vector such that after calling this function
979 
980  m.vert[ newVertIndex[i] ] = m.vert[i];
981 
982  e.g. newVertIndex[i] is the new index of the vertex i
983 
984  */
985  static void PermutateVertexVector(MeshType &m, PointerUpdater<VertexPointer> &pu)
986  {
987  if(m.vert.empty()) return;
988  for(size_t i=0;i<m.vert.size();++i)
989  {
990  if(pu.remap[i]<size_t(m.vn))
991  {
992  assert(!m.vert[i].IsD());
993  m.vert[ pu.remap [i] ].ImportData(m.vert[i]);
994  if(HasVFAdjacency(m))
995  {
996  if (m.vert[i].IsVFInitialized())
997  {
998  m.vert[ pu.remap[i] ].VFp() = m.vert[i].cVFp();
999  m.vert[ pu.remap[i] ].VFi() = m.vert[i].cVFi();
1000  }
1001  else m.vert [ pu.remap[i] ].VFClear();
1002  }
1003  if(HasVEAdjacency(m))
1004  {
1005  if (m.vert[i].IsVEInitialized())
1006  {
1007  m.vert[ pu.remap[i] ].VEp() = m.vert[i].cVEp();
1008  m.vert[ pu.remap[i] ].VEi() = m.vert[i].cVEi();
1009  }
1010  else m.vert [ pu.remap[i] ].VEClear();
1011  }
1012  if (HasVTAdjacency(m))
1013  {
1014  if (m.vert[i].IsVTInitialized())
1015  {
1016  m.vert[ pu.remap[i] ].VTp() = m.vert[i].cVTp();
1017  m.vert[ pu.remap[i] ].VTi() = m.vert[i].cVTi();
1018  }
1019  else m.vert[ pu.remap[i] ].VTClear();
1020  }
1021  }
1022  }
1023 
1024  // reorder the optional atttributes in m.vert_attr to reflect the changes
1025  ReorderAttribute(m.vert_attr,pu.remap,m);
1026 
1027  // setup the pointer updater
1028  pu.oldBase = &m.vert[0];
1029  pu.oldEnd = &m.vert.back()+1;
1030 
1031  // resize
1032  m.vert.resize(m.vn);
1033 
1034  // setup the pointer updater
1035  pu.newBase = (m.vert.empty())?0:&m.vert[0];
1036  pu.newEnd = (m.vert.empty())?0:&m.vert.back()+1;
1037 
1038  // resize the optional atttributes in m.vert_attr to reflect the changes
1039  ResizeAttribute(m.vert_attr,m.vn,m);
1040 
1041  // Loop on the face to update the pointers FV relation (vertex refs)
1042  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
1043  if(!(*fi).IsD())
1044  for(int i=0;i<fi->VN();++i)
1045  {
1046  size_t oldIndex = (*fi).V(i) - pu.oldBase;
1047  assert(pu.oldBase <= (*fi).V(i) && oldIndex < pu.remap.size());
1048  (*fi).V(i) = pu.newBase+pu.remap[oldIndex];
1049  }
1050  // Loop on the tetras to update the pointers TV relation (vertex refs)
1051  for(TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
1052  if(!(*ti).IsD())
1053  for(int i = 0; i < 4; ++i)
1054  {
1055  size_t oldIndex = (*ti).V(i) - pu.oldBase;
1056  assert(pu.oldBase <= (*ti).V(i) && oldIndex < pu.remap.size());
1057  (*ti).V(i) = pu.newBase+pu.remap[oldIndex];
1058  }
1059  // Loop on the edges to update the pointers EV relation (vertex refs)
1060  // if(HasEVAdjacency(m))
1061  for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
1062  if(!(*ei).IsD())
1063  {
1064  pu.Update((*ei).V(0));
1065  pu.Update((*ei).V(1));
1066  }
1067  }
1068 
1069  static void CompactEveryVector(MeshType &m)
1070  {
1072  CompactEdgeVector(m);
1073  CompactFaceVector(m);
1074  CompactTetraVector(m);
1075  }
1076 
1084  static void CompactVertexVector( MeshType &m, PointerUpdater<VertexPointer> &pu )
1085  {
1086  // If already compacted fast return please!
1087  if(m.vn==(int)m.vert.size()) return;
1088 
1089  // newVertIndex [ <old_vert_position> ] gives you the new position of the vertex in the vector;
1090  pu.remap.resize( m.vert.size(),std::numeric_limits<size_t>::max() );
1091 
1092  size_t pos=0;
1093  size_t i=0;
1094 
1095  for(i=0;i<m.vert.size();++i)
1096  {
1097  if(!m.vert[i].IsD())
1098  {
1099  pu.remap[i]=pos;
1100  ++pos;
1101  }
1102  }
1103  assert((int)pos==m.vn);
1104 
1105  PermutateVertexVector(m, pu);
1106  }
1107 
1109  static void CompactVertexVector( MeshType &m ) {
1111  CompactVertexVector(m,pu);
1112  }
1113 
1122  static void CompactEdgeVector( MeshType &m, PointerUpdater<EdgePointer> &pu )
1123  {
1124  // If already compacted fast return please!
1125  if(m.en==(int)m.edge.size()) return;
1126 
1127  // remap [ <old_edge_position> ] gives you the new position of the edge in the vector;
1128  pu.remap.resize( m.edge.size(),std::numeric_limits<size_t>::max() );
1129 
1130  size_t pos=0;
1131  size_t i=0;
1132 
1133  for(i=0;i<m.edge.size();++i)
1134  {
1135  if(!m.edge[i].IsD())
1136  {
1137  pu.remap[i]=pos;
1138  ++pos;
1139  }
1140  }
1141  assert((int)pos==m.en);
1142 
1143  // the actual copying of the data.
1144  for(size_t i=0;i<m.edge.size();++i)
1145  {
1146  if(pu.remap[i]<size_t(m.en)) // uninitialized entries in the remap vector has max_int value;
1147  {
1148  assert(!m.edge[i].IsD());
1149  m.edge[ pu.remap [i] ].ImportData(m.edge[i]);
1150  // copy the vertex reference (they are not data!)
1151  m.edge[ pu.remap[i] ].V(0) = m.edge[i].cV(0);
1152  m.edge[ pu.remap[i] ].V(1) = m.edge[i].cV(1);
1153  // Now just copy the adjacency pointers (without changing them, to be done later)
1154  if(HasVEAdjacency(m))
1155  //if (m.edge[i].cVEp(0)!=0)
1156  {
1157  m.edge[ pu.remap[i] ].VEp(0) = m.edge[i].cVEp(0);
1158  m.edge[ pu.remap[i] ].VEi(0) = m.edge[i].cVEi(0);
1159  m.edge[ pu.remap[i] ].VEp(1) = m.edge[i].cVEp(1);
1160  m.edge[ pu.remap[i] ].VEi(1) = m.edge[i].cVEi(1);
1161  }
1162  if(HasEEAdjacency(m))
1163 // if (m.edge[i].cEEp(0)!=0)
1164  {
1165  m.edge[ pu.remap[i] ].EEp(0) = m.edge[i].cEEp(0);
1166  m.edge[ pu.remap[i] ].EEi(0) = m.edge[i].cEEi(0);
1167  m.edge[ pu.remap[i] ].EEp(1) = m.edge[i].cEEp(1);
1168  m.edge[ pu.remap[i] ].EEi(1) = m.edge[i].cEEi(1);
1169  }
1170  if(HasEFAdjacency(m))
1171 // if (m.edge[i].cEEp(0)!=0)
1172  {
1173  m.edge[ pu.remap[i] ].EFp() = m.edge[i].cEFp();
1174  m.edge[ pu.remap[i] ].EFi() = m.edge[i].cEFi();
1175  m.edge[ pu.remap[i] ].EFp() = m.edge[i].cEFp();
1176  m.edge[ pu.remap[i] ].EFi() = m.edge[i].cEFi();
1177  }
1178 
1179  }
1180  }
1181 
1182  // reorder the optional attributes in m.vert_attr to reflect the changes
1183  ReorderAttribute(m.edge_attr, pu.remap,m);
1184 
1185  // setup the pointer updater
1186  pu.oldBase = &m.edge[0];
1187  pu.oldEnd = &m.edge.back()+1;
1188 
1189  // THE resize
1190  m.edge.resize(m.en);
1191 
1192  // setup the pointer updater
1193  pu.newBase = (m.edge.empty())?0:&m.edge[0];
1194  pu.newEnd = (m.edge.empty())?0:&m.edge.back()+1;
1195 
1196  // resize the optional atttributes in m.vert_attr to reflect the changes
1197  ResizeAttribute(m.edge_attr,m.en,m);
1198 
1199  // Loop on the vertices to update the pointers of VE relation
1200  if(HasVEAdjacency(m))
1201  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
1202  if(!(*vi).IsD()) pu.Update((*vi).VEp());
1203 
1204  // Loop on the edges to update the pointers EE VE relation
1205  for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
1206  for(unsigned int i=0;i<2;++i)
1207  {
1208  if(HasVEAdjacency(m))
1209  pu.Update((*ei).VEp(i));
1210  if(HasEEAdjacency(m))
1211  pu.Update((*ei).EEp(i));
1212 // if(HasEFAdjacency(m))
1213 // pu.Update((*ei).EFp());
1214  }
1215  }
1216 
1218  static void CompactEdgeVector( MeshType &m ) {
1220  CompactEdgeVector(m,pu);
1221  }
1222 
1231  static void CompactFaceVector( MeshType &m, PointerUpdater<FacePointer> &pu )
1232  {
1233  // If already compacted fast return please!
1234  if(m.fn==(int)m.face.size()) return;
1235 
1236  // newFaceIndex [ <old_face_position> ] gives you the new position of the face in the vector;
1237  pu.remap.resize( m.face.size(),std::numeric_limits<size_t>::max() );
1238 
1239  size_t pos=0;
1240  for(size_t i=0;i<m.face.size();++i)
1241  {
1242  if(!m.face[i].IsD())
1243  {
1244  if(pos!=i)
1245  {
1246  m.face[pos].ImportData(m.face[i]);
1247  if(FaceType::HasPolyInfo())
1248  {
1249  m.face[pos].Dealloc();
1250  m.face[pos].Alloc(m.face[i].VN());
1251  }
1252  for(int j=0;j<m.face[i].VN();++j)
1253  m.face[pos].V(j) = m.face[i].V(j);
1254 
1255  if(HasVFAdjacency(m))
1256  for(int j=0;j<m.face[i].VN();++j)
1257  {
1258  if (m.face[i].IsVFInitialized(j)) {
1259  m.face[pos].VFp(j) = m.face[i].cVFp(j);
1260  m.face[pos].VFi(j) = m.face[i].cVFi(j);
1261  }
1262  else m.face[pos].VFClear(j);
1263  }
1264  if(HasFFAdjacency(m))
1265  for(int j=0;j<m.face[i].VN();++j)
1266  {
1267  m.face[pos].FFp(j) = m.face[i].cFFp(j);
1268  m.face[pos].FFi(j) = m.face[i].cFFi(j);
1269  }
1270  }
1271  pu.remap[i]=pos;
1272  ++pos;
1273  }
1274  }
1275  assert((int)pos==m.fn);
1276 
1277  // reorder the optional atttributes in m.face_attr to reflect the changes
1278  ReorderAttribute(m.face_attr,pu.remap,m);
1279 
1280  FacePointer fbase=&m.face[0];
1281 
1282  // Loop on the vertices to correct VF relation
1283  if(HasVFAdjacency(m))
1284  {
1285  for (VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
1286  if(!(*vi).IsD())
1287  {
1288  if ((*vi).IsVFInitialized() && (*vi).VFp()!=0 )
1289  {
1290  size_t oldIndex = (*vi).cVFp() - fbase;
1291  assert(fbase <= (*vi).cVFp() && oldIndex < pu.remap.size());
1292  (*vi).VFp() = fbase+pu.remap[oldIndex];
1293  }
1294  }
1295  }
1296 
1297  // Loop on the faces to correct VF and FF relations
1298  pu.oldBase = &m.face[0];
1299  pu.oldEnd = &m.face.back()+1;
1300  for(size_t i=m.fn;i<m.face.size();++i)
1301  m.face[i].Dealloc();
1302  m.face.resize(m.fn);
1303  pu.newBase = (m.face.empty())?0:&m.face[0];
1304  pu.newEnd = (m.face.empty())?0:&m.face.back()+1;
1305 
1306 
1307  // resize the optional atttributes in m.face_attr to reflect the changes
1308  ResizeAttribute(m.face_attr,m.fn,m);
1309 
1310  // now we update the various (not null) face pointers (inside VF and FF relations)
1311  for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
1312  if(!(*fi).IsD())
1313  {
1314  if(HasVFAdjacency(m))
1315  for(int i=0;i<(*fi).VN();++i)
1316  if ((*fi).IsVFInitialized(i) && (*fi).VFp(i)!=0 )
1317  {
1318  size_t oldIndex = (*fi).VFp(i) - fbase;
1319  assert(fbase <= (*fi).VFp(i) && oldIndex < pu.remap.size());
1320  (*fi).VFp(i) = fbase+pu.remap[oldIndex];
1321  }
1322  if(HasFFAdjacency(m))
1323  for(int i=0;i<(*fi).VN();++i)
1324  if ((*fi).cFFp(i)!=0)
1325  {
1326  size_t oldIndex = (*fi).FFp(i) - fbase;
1327  assert(fbase <= (*fi).FFp(i) && oldIndex < pu.remap.size());
1328  (*fi).FFp(i) = fbase+pu.remap[oldIndex];
1329  }
1330  }
1331 
1332 
1333 
1334  }
1335 
1337  static void CompactFaceVector( MeshType &m ) {
1339  CompactFaceVector(m,pu);
1340  }
1341 
1350  static void CompactTetraVector(MeshType & m, PointerUpdater<TetraPointer> & pu)
1351  {
1352  //nothing to do
1353  if (size_t(m.tn) == m.tetra.size())
1354  return;
1355 
1356  //init the remap
1357  pu.remap.resize(m.tetra.size(), std::numeric_limits<size_t>::max());
1358 
1359  //cycle over all the tetras, pos is the last not D() position, I is the index
1360  //when pos != i and !tetra[i].IsD() => we need to compact and update adj
1361  size_t pos = 0;
1362  for (size_t i = 0; i < m.tetra.size(); ++i)
1363  {
1364  if (!m.tetra[i].IsD())
1365  {
1366  if (pos != i)
1367  {
1368  //import data
1369  m.tetra[pos].ImportData(m.tetra[i]);
1370  //import vertex refs
1371  for (int j = 0; j < 4; ++j)
1372  m.tetra[pos].V(j) = m.tetra[i].V(j);
1373  //import VT adj
1374  if (HasVTAdjacency(m))
1375  for (int j = 0; j < 4; ++j)
1376  {
1377  if (m.tetra[i].IsVTInitialized(j))
1378  {
1379  m.tetra[pos].VTp(j) = m.tetra[i].VTp(j);
1380  m.tetra[pos].VTi(j) = m.tetra[i].VTi(j);
1381  }
1382  else
1383  m.tetra[pos].VTClear(j);
1384  }
1385  //import TT adj
1386  if (HasTTAdjacency(m))
1387  for (int j = 0; j < 4; ++j)
1388  {
1389  m.tetra[pos].TTp(j) = m.tetra[i].cTTp(j);
1390  m.tetra[pos].TTi(j) = m.tetra[i].cTTi(j);
1391  }
1392  }
1393  //update remapping and advance pos
1394  pu.remap[i] = pos;
1395  ++pos;
1396  }
1397  }
1398 
1399  assert(size_t(m.tn) == pos);
1400  //reorder the optional attributes in m.tetra_attr
1401  ReorderAttribute(m.tetra_attr, pu.remap, m);
1402  // resize the optional atttributes in m.tetra_attr to reflect the changes
1403  ResizeAttribute(m.tetra_attr, m.tn, m);
1404 
1405  // Loop on the tetras to correct VT and TT relations
1406  pu.oldBase = &m.tetra[0];
1407  pu.oldEnd = &m.tetra.back() + 1;
1408 
1409  m.tetra.resize(m.tn);
1410  pu.newBase = (m.tetra.empty()) ? 0 : &m.tetra[0];
1411  pu.newEnd = (m.tetra.empty()) ? 0 : &m.tetra.back() + 1;
1412 
1413  TetraPointer tbase = &m.tetra[0];
1414 
1415  //Loop on the vertices to correct VT relation (since we moved things around)
1416  if (HasVTAdjacency(m))
1417  {
1418  for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
1419  if (!(*vi).IsD())
1420  {
1421  if ((*vi).IsVTInitialized() && (*vi).VTp() != 0)
1422  {
1423  size_t oldIndex = (*vi).cVTp() - tbase;
1424  assert(tbase <= (*vi).cVTp() && oldIndex < pu.remap.size());
1425  (*vi).VTp() = tbase + pu.remap[oldIndex];
1426  }
1427  }
1428  }
1429 
1430  // Loop on the tetras to correct the VT and TT relations
1431  for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
1432  if (!(*ti).IsD())
1433  {
1434  //VT
1435  if (HasVTAdjacency(m))
1436  for (int i = 0; i < 4; ++i)
1437  if ((*ti).IsVTInitialized(i) && (*ti).VTp(i) != 0)
1438  {
1439  size_t oldIndex = (*ti).VTp(i) - tbase;
1440  assert(tbase <= (*ti).VTp(i) && oldIndex < pu.remap.size());
1441  (*ti).VTp(i) = tbase + pu.remap[oldIndex];
1442  }
1443  //TT
1444  if (HasTTAdjacency(m))
1445  for (int i = 0; i < 4; ++i)
1446  if ((*ti).cTTp(i) != 0)
1447  {
1448  size_t oldIndex = (*ti).TTp(i) - tbase;
1449  assert(tbase <= (*ti).TTp(i) && oldIndex < pu.remap.size());
1450  (*ti).TTp(i) = tbase + pu.remap[oldIndex];
1451  }
1452  }
1453  }
1454 
1456  static void CompactTetraVector(MeshType &m)
1457  {
1459  CompactTetraVector(m, pu);
1460  }
1461 
1462 
1463 public:
1464 
1468  template <class ATTR_TYPE>
1469  static
1470  bool IsValidHandle( const MeshType & m, const typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & a){
1471  if(a._handle == nullptr) return false;
1472  for(AttrIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i)
1473  if ( (*i).n_attr == a.n_attr ) return true;
1474  return false;
1475  }
1476 
1480  template <class ATTR_TYPE>
1481  static
1482  bool IsValidHandle( const MeshType & m, const typename MeshType::template ConstPerVertexAttributeHandle<ATTR_TYPE> & a){
1483  if(a._handle == nullptr) return false;
1484  for(AttrIterator i = m.vert_attr.begin(); i!=m.vert_attr.end();++i)
1485  if ( (*i).n_attr == a.n_attr ) return true;
1486  return false;
1487  }
1488 
1493  template <class ATTR_TYPE>
1494  static
1495  typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1496  AddPerVertexAttribute( MeshType & m, std::string name){
1497  PAIte i;
1498  PointerToAttribute h;
1499  h._name = name;
1500  if(!name.empty()){
1501  i = m.vert_attr.find(h);
1502  assert(i ==m.vert_attr.end() );// an attribute with this name exists
1503  }
1504 
1505  h._sizeof = sizeof(ATTR_TYPE);
1506  h._padding = 0;
1507  h._handle = new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
1508  h._type = typeid(ATTR_TYPE);
1509  m.attrn++;
1510  h.n_attr = m.attrn;
1511  std::pair < AttrIterator , bool> res = m.vert_attr.insert(h);
1512  return typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr );
1513  }
1514 
1515  template <class ATTR_TYPE>
1516  static typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1517  AddPerVertexAttribute( MeshType & m){
1518  return AddPerVertexAttribute<ATTR_TYPE>(m,std::string(""));
1519  }
1520 
1525  template <class ATTR_TYPE>
1526  static
1527  typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1528  GetPerVertexAttribute( MeshType & m, std::string name = std::string("")){
1529  typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> h;
1530  if(!name.empty()){
1531  h = FindPerVertexAttribute<ATTR_TYPE>(m,name);
1532  if(IsValidHandle(m,h))
1533  return h;
1534  }
1535  return AddPerVertexAttribute<ATTR_TYPE>(m,name);
1536  }
1537 
1542  template <class ATTR_TYPE>
1543  static
1544  typename MeshType::template ConstPerVertexAttributeHandle<ATTR_TYPE>
1545  GetPerVertexAttribute( const MeshType & m, std::string name = std::string("")){
1546  return FindPerVertexAttribute<ATTR_TYPE>(m,name);
1547  }
1548 
1552  template <class ATTR_TYPE>
1553  static typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>
1554  FindPerVertexAttribute( MeshType & m, const std::string & name)
1555  {
1556  assert(!name.empty());
1557  PointerToAttribute h1; h1._name = name;
1558  typename std::set<PointerToAttribute > :: iterator i;
1559 
1560  i =m.vert_attr.find(h1);
1561  if(i!=m.vert_attr.end())
1562  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1563  if( (*i)._padding != 0 ){
1564  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1565  m.vert_attr.erase(i); // remove it from the set
1566  FixPaddedPerVertexAttribute<ATTR_TYPE>(m,attr);
1567  std::pair<AttrIterator,bool> new_i = m.vert_attr.insert(attr); // insert the modified PointerToAttribute
1568  assert(new_i.second);
1569  i = new_i.first;
1570  }
1571  return typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1572  }
1573  return typename MeshType:: template PerVertexAttributeHandle<ATTR_TYPE>(nullptr,0);
1574  }
1575 
1582  template <class ATTR_TYPE>
1583  static typename MeshType::template ConstPerVertexAttributeHandle<ATTR_TYPE>
1584  FindPerVertexAttribute( const MeshType & m, const std::string & name)
1585  {
1586  if(!name.empty()){
1587  PointerToAttribute h1; h1._name = name;
1588  typename std::set<PointerToAttribute > :: iterator i;
1589 
1590  i =m.vert_attr.find(h1);
1591  if(i!=m.vert_attr.end()){
1592  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1593  return typename MeshType::template ConstPerVertexAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1594  }
1595  }
1596  }
1597  return typename MeshType:: template ConstPerVertexAttributeHandle<ATTR_TYPE>(nullptr,0);
1598  }
1599 
1603  template <class ATTR_TYPE>
1604  static void GetAllPerVertexAttribute(const MeshType & m, std::vector<std::string> &all){
1605  all.clear();
1606  typename std::set<PointerToAttribute > ::const_iterator i;
1607  for(i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i )
1608  if(!(*i)._name.empty())
1609  {
1610  typename MeshType:: template ConstPerVertexAttributeHandle<ATTR_TYPE> hh;
1611  hh = Allocator<MeshType>:: template FindPerVertexAttribute <ATTR_TYPE>(m,(*i)._name);
1612  if(IsValidHandle<ATTR_TYPE>(m,hh))
1613  all.push_back((*i)._name);
1614  }
1615  }
1616 
1617  template <class ATTR_TYPE>
1618  static
1619  void
1620  ClearPerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h, const ATTR_TYPE & initVal = ATTR_TYPE()){
1621  typename std::set<PointerToAttribute > ::iterator i;
1622  for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i)
1623  if( (*i)._handle == h._handle ){
1624  for(typename MeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
1625  h[vi] = initVal;
1626  return;}
1627  assert(0);
1628  }
1629 
1632  template <class ATTR_TYPE>
1633  static
1634  void
1635  DeletePerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h){
1636  typename std::set<PointerToAttribute > ::iterator i;
1637  for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i)
1638  if( (*i)._handle == h._handle ){
1639  delete ((SimpleTempData<VertContainer,ATTR_TYPE>*)(*i)._handle);
1640  m.vert_attr.erase(i);
1641  return;}
1642  }
1643 
1644  // Generic DeleteAttribute.
1645  // It must not crash if you try to delete a non existing attribute,
1646  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1647  static
1648  bool DeletePerVertexAttribute( MeshType & m, std::string name){
1649  AttrIterator i;
1650  PointerToAttribute h1; h1._name = name;
1651  i = m.vert_attr.find(h1);
1652  if(i==m.vert_attr.end()) return false;
1653  delete ((SimpleTempDataBase*)(*i)._handle);
1654  m.vert_attr.erase(i);
1655  return true;
1656  }
1657 
1658 
1659 
1661  template <class ATTR_TYPE>
1662  static
1663  bool IsValidHandle( const MeshType & m, const typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> & a){
1664  if(a._handle == nullptr) return false;
1665  for(AttrIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i)
1666  if ( (*i).n_attr == a.n_attr ) return true;
1667  return false;
1668  }
1669 
1670  template <class ATTR_TYPE>
1671  static
1672  bool IsValidHandle( const MeshType & m, const typename MeshType::template ConstPerEdgeAttributeHandle<ATTR_TYPE> & a){
1673  if(a._handle == nullptr) return false;
1674  for(AttrIterator i = m.edge_attr.begin(); i!=m.edge_attr.end();++i)
1675  if ( (*i).n_attr == a.n_attr ) return true;
1676  return false;
1677  }
1678 
1679  template <class ATTR_TYPE>
1680  static
1681  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1682  AddPerEdgeAttribute( MeshType & m, std::string name){
1683  PAIte i;
1684  PointerToAttribute h;
1685  h._name = name;
1686  if(!name.empty()){
1687  i = m.edge_attr.find(h);
1688  assert(i ==m.edge_attr.end() );// an attribute with this name exists
1689  }
1690  h._sizeof = sizeof(ATTR_TYPE);
1691  h._padding = 0;
1692  // h._typename = typeid(ATTR_TYPE).name();
1693  h._handle = new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
1694  h._type = typeid(ATTR_TYPE);
1695  m.attrn++;
1696  h.n_attr = m.attrn;
1697  std::pair < AttrIterator , bool> res = m.edge_attr.insert(h);
1698  return typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
1699  }
1700 
1701  template <class ATTR_TYPE>
1702  static
1703  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1704  AddPerEdgeAttribute( MeshType & m){
1705  return AddPerEdgeAttribute<ATTR_TYPE>(m,std::string(""));
1706  }
1707 
1712  template <class ATTR_TYPE>
1713  static
1714  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1715  GetPerEdgeAttribute( MeshType & m, std::string name = std::string("")){
1716  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> h;
1717  if(!name.empty()){
1718  h = FindPerEdgeAttribute<ATTR_TYPE>(m,name);
1719  if(IsValidHandle(m,h))
1720  return h;
1721  }
1722  return AddPerEdgeAttribute<ATTR_TYPE>(m,name);
1723  }
1724 
1725  template <class ATTR_TYPE>
1726  static
1727  typename MeshType::template ConstPerEdgeAttributeHandle<ATTR_TYPE>
1728  GetPerEdgeAttribute( const MeshType & m, std::string name = std::string("")){
1729  return FindPerEdgeAttribute<ATTR_TYPE>(m,name);
1730  }
1731 
1732  template <class ATTR_TYPE>
1733  static
1734  typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>
1735  FindPerEdgeAttribute( MeshType & m, const std::string & name){
1736  assert(!name.empty());
1737  PointerToAttribute h1; h1._name = name;
1738  typename std::set<PointerToAttribute > ::const_iterator i;
1739 
1740  i =m.edge_attr.find(h1);
1741  if(i!=m.edge_attr.end())
1742  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1743  if( (*i)._padding != 0 ){
1744  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1745  m.edge_attr.erase(i); // remove it from the set
1746  FixPaddedPerEdgeAttribute<ATTR_TYPE>(m,attr);
1747  std::pair<AttrIterator,bool> new_i = m.edge_attr.insert(attr); // insert the modified PointerToAttribute
1748  assert(new_i.second);
1749  i = new_i.first;
1750  }
1751  return typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1752  }
1753 
1754  return typename MeshType:: template PerEdgeAttributeHandle<ATTR_TYPE>(nullptr,0);
1755  }
1756 
1757  template <class ATTR_TYPE>
1758  static
1759  typename MeshType::template ConstPerEdgeAttributeHandle<ATTR_TYPE>
1760  FindPerEdgeAttribute( const MeshType & m, const std::string & name){
1761  if(!name.empty()){
1762  PointerToAttribute h1; h1._name = name;
1763  typename std::set<PointerToAttribute > ::const_iterator i;
1764 
1765  i =m.edge_attr.find(h1);
1766  if(i!=m.edge_attr.end()){
1767  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1768  return typename MeshType::template ConstPerEdgeAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1769  }
1770  }
1771  }
1772  return typename MeshType:: template ConstPerEdgeAttributeHandle<ATTR_TYPE>(nullptr,0);
1773  }
1774 
1775  template <class ATTR_TYPE>
1776  static void GetAllPerEdgeAttribute(const MeshType & m, std::vector<std::string> &all){
1777  all.clear();
1778  typename std::set<PointerToAttribute > :: const_iterator i;
1779  for(i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i )
1780  if(!(*i)._name.empty())
1781  {
1782  typename MeshType:: template ConstPerEdgeAttributeHandle<ATTR_TYPE> hh;
1783  hh = Allocator<MeshType>:: template FindPerEdgeAttribute <ATTR_TYPE>(m,(*i)._name);
1784  if(IsValidHandle<ATTR_TYPE>(m,hh))
1785  all.push_back((*i)._name);
1786  }
1787  }
1788 
1791  template <class ATTR_TYPE>
1792  static
1793  void
1794  DeletePerEdgeAttribute( MeshType & m,typename MeshType::template PerEdgeAttributeHandle<ATTR_TYPE> & h){
1795  typename std::set<PointerToAttribute > ::iterator i;
1796  for( i = m.edge_attr.begin(); i != m.edge_attr.end(); ++i)
1797  if( (*i)._handle == h._handle ){
1798  delete ((SimpleTempData<EdgeContainer,ATTR_TYPE>*)(*i)._handle);
1799  m.edge_attr.erase(i);
1800  return;}
1801  }
1802 
1803  // Generic DeleteAttribute.
1804  // It must not crash if you try to delete a non existing attribute,
1805  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1806  static
1807  bool DeletePerEdgeAttribute( MeshType & m, std::string name){
1808  AttrIterator i;
1809  PointerToAttribute h1; h1._name = name;
1810  i = m.edge_attr.find(h1);
1811  if(i==m.edge_attr.end()) return false;
1812  delete ((SimpleTempDataBase*)(*i)._handle);
1813  m.edge_attr.erase(i);
1814  return true;
1815  }
1816 
1818 
1821  template <class ATTR_TYPE>
1822  static
1823  bool IsValidHandle( const MeshType & m, const typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> & a){
1824  if(a._handle == nullptr) return false;
1825  for(AttrIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i)
1826  if ( (*i).n_attr == a.n_attr ) return true;
1827  return false;
1828  }
1829 
1833  template <class ATTR_TYPE>
1834  static
1835  bool IsValidHandle( const MeshType & m, const typename MeshType::template ConstPerFaceAttributeHandle<ATTR_TYPE> & a){
1836  if(a._handle == nullptr) return false;
1837  for(AttrIterator i = m.face_attr.begin(); i!=m.face_attr.end();++i)
1838  if ( (*i).n_attr == a.n_attr ) return true;
1839  return false;
1840  }
1841 
1842  template <class ATTR_TYPE>
1843  static
1844  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1845  AddPerFaceAttribute( MeshType & m, std::string name){
1846  PAIte i;
1847  PointerToAttribute h;
1848  h._name = name;
1849  if(!name.empty()){
1850  i = m.face_attr.find(h);
1851  assert(i ==m.face_attr.end() );// an attribute with this name exists
1852  }
1853 
1854  h._sizeof = sizeof(ATTR_TYPE);
1855  h._padding = 0;
1856  h._handle = new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
1857  h._type = typeid(ATTR_TYPE);
1858  m.attrn++;
1859  h.n_attr = m.attrn;
1860  std::pair < AttrIterator , bool> res = m.face_attr.insert(h);
1861  return typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
1862  }
1863 
1864  template <class ATTR_TYPE>
1865  static
1866  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1867  AddPerFaceAttribute( MeshType & m){
1868  return AddPerFaceAttribute<ATTR_TYPE>(m,std::string(""));
1869  }
1870 
1875  template <class ATTR_TYPE>
1876  static
1877  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1878  GetPerFaceAttribute( MeshType & m, std::string name = std::string("")){
1879  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> h;
1880  if(!name.empty()){
1881  h = FindPerFaceAttribute<ATTR_TYPE>(m,name);
1882  if(IsValidHandle(m,h))
1883  return h;
1884  }
1885  return AddPerFaceAttribute<ATTR_TYPE>(m,name);
1886  }
1887 
1892  template <class ATTR_TYPE>
1893  static
1894  typename MeshType::template ConstPerFaceAttributeHandle<ATTR_TYPE>
1895  GetPerFaceAttribute( const MeshType & m, std::string name = std::string("")){
1896  return FindPerFaceAttribute<ATTR_TYPE>(m,name);
1897  }
1898 
1899  template <class ATTR_TYPE>
1900  static
1901  typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>
1902  FindPerFaceAttribute( MeshType & m, const std::string & name){
1903  assert(!name.empty());
1904  PointerToAttribute h1; h1._name = name;
1905  typename std::set<PointerToAttribute > ::iterator i;
1906 
1907  i =m.face_attr.find(h1);
1908  if(i!=m.face_attr.end())
1909  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1910  if( (*i)._padding != 0 ){
1911  PointerToAttribute attr = (*i); // copy the PointerToAttribute
1912  m.face_attr.erase(i); // remove it from the set
1913  FixPaddedPerFaceAttribute<ATTR_TYPE>(m,attr);
1914  std::pair<AttrIterator,bool> new_i = m.face_attr.insert(attr); // insert the modified PointerToAttribute
1915  assert(new_i.second);
1916  i = new_i.first;
1917  }
1918  return typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1919  }
1920  return typename MeshType:: template PerFaceAttributeHandle<ATTR_TYPE>(nullptr,0);
1921  }
1922 
1929  template <class ATTR_TYPE>
1930  static
1931  typename MeshType::template ConstPerFaceAttributeHandle<ATTR_TYPE>
1932  FindPerFaceAttribute( const MeshType & m, const std::string & name){
1933  if(!name.empty()){
1934  PointerToAttribute h1; h1._name = name;
1935  typename std::set<PointerToAttribute > ::iterator i;
1936 
1937  i =m.face_attr.find(h1);
1938  if(i!=m.face_attr.end()){
1939  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
1940  return typename MeshType::template ConstPerFaceAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
1941  }
1942  }
1943  }
1944  return typename MeshType:: template ConstPerFaceAttributeHandle<ATTR_TYPE>(nullptr,0);
1945  }
1946 
1947  template <class ATTR_TYPE>
1948  static void GetAllPerFaceAttribute(const MeshType & m, std::vector<std::string> &all){
1949  all.clear();
1950  typename std::set<PointerToAttribute > :: const_iterator i;
1951  for(i = m.face_attr.begin(); i != m.face_attr.end(); ++i )
1952  if(!(*i)._name.empty())
1953  {
1954  typename MeshType:: template ConstPerFaceAttributeHandle<ATTR_TYPE> hh;
1955  hh = Allocator<MeshType>:: template FindPerFaceAttribute <ATTR_TYPE>(m,(*i)._name);
1956  if(IsValidHandle<ATTR_TYPE>(m,hh))
1957  all.push_back((*i)._name);
1958  }
1959  }
1960 
1963  template <class ATTR_TYPE>
1964  static void DeletePerFaceAttribute( MeshType & m,typename MeshType::template PerFaceAttributeHandle<ATTR_TYPE> & h){
1965  typename std::set<PointerToAttribute > ::iterator i;
1966  for( i = m.face_attr.begin(); i != m.face_attr.end(); ++i)
1967  if( (*i)._handle == h._handle ){
1968  delete ((SimpleTempData<FaceContainer,ATTR_TYPE>*)(*i)._handle);
1969  m.face_attr.erase(i);
1970  return;}
1971 
1972  }
1973 
1974  // Generic DeleteAttribute.
1975  // It must not crash if you try to delete a non existing attribute,
1976  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
1977  static bool DeletePerFaceAttribute( MeshType & m, std::string name){
1978  AttrIterator i;
1979  PointerToAttribute h1; h1._name = name;
1980  i = m.face_attr.find(h1);
1981  if(i==m.face_attr.end()) return false;
1982  delete ((SimpleTempDataBase*)(*i)._handle);
1983  m.face_attr.erase(i);
1984  return true;
1985  }
1986 
1988  template <class ATTR_TYPE>
1989  static bool IsValidHandle(const MeshType & m, const typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> & a)
1990  {
1991  if (a._handle == nullptr)
1992  return false;
1993  for (AttrIterator i = m.tetra_attr.begin(); i != m.tetra_attr.end(); ++i)
1994  if ((*i).n_attr == a.n_attr)
1995  return true;
1996  return false;
1997  }
1998 
1999  template <class ATTR_TYPE>
2000  static bool IsValidHandle(const MeshType & m, const typename MeshType::template ConstPerTetraAttributeHandle<ATTR_TYPE> & a)
2001  {
2002  if (a._handle == nullptr)
2003  return false;
2004  for (AttrIterator i = m.tetra_attr.begin(); i != m.tetra_attr.end(); ++i)
2005  if ((*i).n_attr == a.n_attr)
2006  return true;
2007  return false;
2008  }
2009 
2010  template <class ATTR_TYPE>
2011  static typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> AddPerTetraAttribute(MeshType & m, std::string name)
2012  {
2013  PAIte i;
2014  PointerToAttribute h;
2015  h._name = name;
2016  if (!name.empty())
2017  {
2018  i = m.tetra_attr.find(h);
2019  assert(i == m.tetra_attr.end());
2020  }
2021 
2022  h._sizeof = sizeof(ATTR_TYPE);
2023  h._padding = 0;
2024  h._handle = new SimpleTempData<TetraContainer, ATTR_TYPE>(m.tetra);
2025  h._type = typeid(ATTR_TYPE);
2026  m.attrn++;
2027  h.n_attr = m.attrn;
2028  std::pair<AttrIterator, bool> res = m.tetra_attr.insert(h);
2029  return typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE>(res.first->_handle, res.first->n_attr);
2030  }
2031 
2032  template <class ATTR_TYPE>
2033  static typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> AddPerTetraAttribute(MeshType &m)
2034  {
2035  return AddPerTetraAttribute<ATTR_TYPE>(m, std::string(""));
2036  }
2037 
2042  template <class ATTR_TYPE>
2043  static typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> GetPerTetraAttribute(MeshType &m, std::string name = std::string(""))
2044  {
2045  typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> h;
2046  if (!name.empty())
2047  {
2048  h = FindPerTetraAttribute<ATTR_TYPE>(m, name);
2049  if (IsValidHandle(m, h))
2050  return h;
2051  }
2052  return AddPerTetraAttribute<ATTR_TYPE>(m, name);
2053  }
2054 
2055  template <class ATTR_TYPE>
2056  static typename MeshType::template ConstPerTetraAttributeHandle<ATTR_TYPE> GetPerTetraAttribute(const MeshType &m, std::string name = std::string(""))
2057  {
2058  return FindPerTetraAttribute<ATTR_TYPE>(m, name);
2059  }
2060 
2061  template <class ATTR_TYPE>
2062  static typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> FindPerTetraAttribute(MeshType &m, const std::string &name)
2063  {
2064  assert(!name.empty());
2065  PointerToAttribute h1;
2066  h1._name = name;
2067  typename std::set<PointerToAttribute>::iterator i;
2068 
2069  i = m.tetra_attr.find(h1);
2070  if (i != m.tetra_attr.end())
2071  if ((*i)._sizeof == sizeof(ATTR_TYPE))
2072  {
2073  if ((*i)._padding != 0)
2074  {
2075  PointerToAttribute attr = (*i); // copy the PointerToAttribute
2076  m.tetra_attr.erase(i); // remove it from the set
2077  FixPaddedPerTetraAttribute<ATTR_TYPE>(m, attr);
2078  std::pair<AttrIterator, bool> new_i = m.tetra_attr.insert(attr); // insert the modified PointerToAttribute
2079  assert(new_i.second);
2080  i = new_i.first;
2081  }
2082  return typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE>((*i)._handle, (*i).n_attr);
2083  }
2084  return typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE>(nullptr, 0);
2085  }
2086 
2087  template <class ATTR_TYPE>
2088  static typename MeshType::template ConstPerTetraAttributeHandle<ATTR_TYPE> FindPerTetraAttribute(const MeshType &m, const std::string &name)
2089  {
2090  if(!name.empty()){
2091  PointerToAttribute h1;
2092  h1._name = name;
2093  typename std::set<PointerToAttribute>::iterator i;
2094 
2095  i = m.tetra_attr.find(h1);
2096  if (i != m.tetra_attr.end()){
2097  if ((*i)._sizeof == sizeof(ATTR_TYPE))
2098  {
2099  return typename MeshType::template ConstPerTetraAttributeHandle<ATTR_TYPE>((*i)._handle, (*i).n_attr);
2100  }
2101  }
2102  }
2103  return typename MeshType::template ConstPerTetraAttributeHandle<ATTR_TYPE>(nullptr, 0);
2104  }
2105 
2106  template <class ATTR_TYPE>
2107  static void GetAllPerTetraAttribute(const MeshType &m, std::vector<std::string> &all)
2108  {
2109  all.clear();
2110  typename std::set<PointerToAttribute>::const_iterator i;
2111  for (i = m.tetra_attr.begin(); i != m.tetra_attr.end(); ++i)
2112  if (!(*i)._name.empty())
2113  {
2114  typename MeshType::template ConstPerTetraAttributeHandle<ATTR_TYPE> hh;
2115  hh = Allocator<MeshType>::template FindPerTetraAttribute<ATTR_TYPE>(m, (*i)._name);
2116  if (IsValidHandle<ATTR_TYPE>(m, hh))
2117  all.push_back((*i)._name);
2118  }
2119  }
2120 
2123  template <class ATTR_TYPE>
2124  static void DeletePerTetraAttribute(MeshType &m, typename MeshType::template PerTetraAttributeHandle<ATTR_TYPE> &h)
2125  {
2126  typename std::set<PointerToAttribute>::iterator i;
2127  for (i = m.tetra_attr.begin(); i != m.tetra_attr.end(); ++i)
2128  if ((*i)._handle == h._handle)
2129  {
2130  delete ((SimpleTempData<TetraContainer, ATTR_TYPE> *)(*i)._handle);
2131  m.tetra_attr.erase(i);
2132  return;
2133  }
2134  }
2135 
2136  // Generic DeleteAttribute.
2137  // It must not crash if you try to delete a non existing attribute,
2138  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
2139  static bool DeletePerTetraAttribute(MeshType &m, std::string name)
2140  {
2141  AttrIterator i;
2142  PointerToAttribute h1;
2143  h1._name = name;
2144  i = m.tetra_attr.find(h1);
2145  if (i == m.tetra_attr.end())
2146  return false;
2147  delete ((SimpleTempDataBase *)(*i)._handle);
2148  m.tetra_attr.erase(i);
2149  return true;
2150  }
2151 
2152 
2154  template <class ATTR_TYPE>
2155  static
2156  bool IsValidHandle(const MeshType & m, const typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> & a){
2157  if(a._handle == nullptr) return false;
2158  for(AttrIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i)
2159  if ( (*i).n_attr == a.n_attr ) return true;
2160  return false;
2161  }
2162 
2163  template <class ATTR_TYPE>
2164  static
2165  bool IsValidHandle(const MeshType & m, const typename MeshType::template ConstPerMeshAttributeHandle<ATTR_TYPE> & a){
2166  if(a._handle == nullptr) return false;
2167  for(AttrIterator i = m.mesh_attr.begin(); i!=m.mesh_attr.end();++i)
2168  if ( (*i).n_attr == a.n_attr ) return true;
2169  return false;
2170  }
2171 
2172  template <class ATTR_TYPE>
2173  static
2174  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
2175  AddPerMeshAttribute( MeshType & m, std::string name){
2176  PAIte i;
2177  PointerToAttribute h;
2178  h._name = name;
2179  if(!name.empty()){
2180  i = m.mesh_attr.find(h);
2181  assert(i ==m.mesh_attr.end() );// an attribute with this name exists
2182  }
2183  h._sizeof = sizeof(ATTR_TYPE);
2184  h._padding = 0;
2185  h._handle = new Attribute<ATTR_TYPE>();
2186  h._type = typeid(ATTR_TYPE);
2187  m.attrn++;
2188  h.n_attr = m.attrn;
2189  std::pair < AttrIterator , bool> res = m.mesh_attr.insert(h);
2190  return typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>(res.first->_handle,res.first->n_attr);
2191  }
2192 
2197  template <class ATTR_TYPE>
2198  static
2199  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
2200  GetPerMeshAttribute( MeshType & m, std::string name = std::string("")){
2201  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> h;
2202  if(!name.empty()){
2203  h = FindPerMeshAttribute<ATTR_TYPE>(m,name);
2204  if(IsValidHandle(m,h))
2205  return h;
2206  }
2207  return AddPerMeshAttribute<ATTR_TYPE>(m,name);
2208  }
2209 
2210  template <class ATTR_TYPE>
2211  static
2212  typename MeshType::template ConstPerMeshAttributeHandle<ATTR_TYPE>
2213  GetPerMeshAttribute(const MeshType & m, std::string name = std::string("")){
2214  return FindPerMeshAttribute<ATTR_TYPE>(m,name);
2215  }
2216 
2217  template <class ATTR_TYPE>
2218  static
2219  typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>
2220  FindPerMeshAttribute( MeshType & m, const std::string & name){
2221  assert(!name.empty());
2222  PointerToAttribute h1; h1._name = name;
2223  typename std::set<PointerToAttribute > ::iterator i;
2224 
2225  i =m.mesh_attr.find(h1);
2226  if(i!=m.mesh_attr.end())
2227  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
2228  if( (*i)._padding != 0 ){
2229  PointerToAttribute attr = (*i); // copy the PointerToAttribute
2230  m.mesh_attr.erase(i); // remove it from the set
2231  FixPaddedPerMeshAttribute<ATTR_TYPE>(m,attr);
2232  std::pair<AttrIterator,bool> new_i = m.mesh_attr.insert(attr); // insert the modified PointerToAttribute
2233  assert(new_i.second);
2234  i = new_i.first;
2235  }
2236 
2237  return typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
2238  }
2239 
2240  return typename MeshType:: template PerMeshAttributeHandle<ATTR_TYPE>(nullptr,0);
2241  }
2242 
2243  template <class ATTR_TYPE>
2244  static
2245  typename MeshType::template ConstPerMeshAttributeHandle<ATTR_TYPE>
2246  FindPerMeshAttribute( const MeshType & m, const std::string & name){
2247  if (!name.empty()){
2248  PointerToAttribute h1; h1._name = name;
2249  typename std::set<PointerToAttribute > ::iterator i;
2250  i =m.mesh_attr.find(h1);
2251  if(i!=m.mesh_attr.end()){
2252  if((*i)._sizeof == sizeof(ATTR_TYPE) ){
2253  return typename MeshType::template ConstPerMeshAttributeHandle<ATTR_TYPE>((*i)._handle,(*i).n_attr);
2254  }
2255  }
2256  }
2257 
2258  return typename MeshType:: template ConstPerMeshAttributeHandle<ATTR_TYPE>(nullptr,0);
2259  }
2260 
2261  template <class ATTR_TYPE>
2262  static void GetAllPerMeshAttribute(const MeshType & m, std::vector<std::string> &all){
2263  typename std::set<PointerToAttribute > :: iterator i;
2264  for(i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i )
2265  if((*i)._sizeof == sizeof(ATTR_TYPE))
2266  all.push_back((*i)._name);
2267  }
2268 
2271  template <class ATTR_TYPE>
2272  static void DeletePerMeshAttribute( MeshType & m,typename MeshType::template PerMeshAttributeHandle<ATTR_TYPE> & h){
2273  typename std::set<PointerToAttribute > ::iterator i;
2274  for( i = m.mesh_attr.begin(); i != m.mesh_attr.end(); ++i)
2275  if( (*i)._handle == h._handle ){
2276  delete (( Attribute<ATTR_TYPE> *)(*i)._handle);
2277  m.mesh_attr.erase(i);
2278  return;}
2279  }
2280 
2281  // Generic DeleteAttribute.
2282  // It must not crash if you try to delete a non existing attribute,
2283  // because you do not have a way of asking for a handle of an attribute for which you do not know the type.
2284  static bool DeletePerMeshAttribute( MeshType & m, std::string name){
2285  AttrIterator i;
2286  PointerToAttribute h1; h1._name = name;
2287  i = m.mesh_attr.find(h1);
2288  if (i==m.mesh_attr.end())
2289  return false;
2290  delete ((SimpleTempDataBase *)(*i)._handle);
2291  m.mesh_attr.erase(i);
2292  return true;
2293  }
2294 
2295  template <class ATTR_TYPE>
2296  static void FixPaddedPerVertexAttribute (MeshType & m, PointerToAttribute & pa){
2297 
2298  // create the container of the right type
2299  SimpleTempData<VertContainer,ATTR_TYPE>* _handle = new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
2300 
2301  // copy the padded container in the new one
2302  _handle->Resize(m.vert.size());
2303  for(size_t i = 0; i < m.vert.size(); ++i){
2304  ATTR_TYPE * dest = &(*_handle)[i];
2305  char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
2306  ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr;
2307  *dest = attrptr[i * pa._sizeof ];
2308  //memcpy((void*)dest ,
2309  //(void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
2310  }
2311 
2312  // remove the padded container
2313  delete ((SimpleTempDataBase*) pa._handle);
2314 
2315  // update the pointer to data
2316  pa._sizeof = sizeof(ATTR_TYPE);
2317 
2318  // update the pointer to data
2319  pa._handle = _handle;
2320 
2321  // zero the padding
2322  pa._padding = 0;
2323  }
2324  template <class ATTR_TYPE>
2325  static void FixPaddedPerEdgeAttribute (MeshType & m, PointerToAttribute & pa){
2326 
2327  // create the container of the right type
2328  SimpleTempData<EdgeContainer,ATTR_TYPE>* _handle = new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
2329 
2330  // copy the padded container in the new one
2331  _handle->Resize(m.edge.size());
2332  for(size_t i = 0; i < m.edge.size(); ++i){
2333  ATTR_TYPE * dest = &(*_handle)[i];
2334  char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
2335  ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr;
2336  *dest = attrptr[i * pa._sizeof ];
2337  //memcpy((void*)dest ,
2338  //(void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
2339  }
2340 
2341  // remove the padded container
2342  delete ((SimpleTempDataBase*) pa._handle);
2343 
2344  // update the pointer to data
2345  pa._sizeof = sizeof(ATTR_TYPE);
2346 
2347  // update the pointer to data
2348  pa._handle = _handle;
2349 
2350  // zero the padding
2351  pa._padding = 0;
2352  }
2353 
2354  template <class ATTR_TYPE>
2355  static void FixPaddedPerFaceAttribute ( MeshType & m,PointerToAttribute & pa){
2356 
2357  // create the container of the right type
2358  SimpleTempData<FaceContainer,ATTR_TYPE>* _handle = new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
2359 
2360  // copy the padded container in the new one
2361  _handle->Resize(m.face.size());
2362  for(size_t i = 0; i < m.face.size(); ++i){
2363  ATTR_TYPE * dest = &(*_handle)[i];
2364  char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin());
2365  ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr;
2366  *dest = attrptr[i * pa._sizeof ];
2367  //memcpy((void*)dest ,
2368  // (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE));
2369  }
2370 
2371  // remove the padded container
2372  delete ((SimpleTempDataBase*) pa._handle);
2373 
2374  // update the pointer to data
2375  pa._sizeof = sizeof(ATTR_TYPE);
2376 
2377  // update the pointer to data
2378  pa._handle = _handle;
2379 
2380  // zero the padding
2381  pa._padding = 0;
2382  }
2383 
2384  template <class ATTR_TYPE>
2385  static void FixPaddedPerTetraAttribute(MeshType &m, PointerToAttribute &pa)
2386  {
2387 
2388  // create the container of the right type
2389  SimpleTempData<TetraContainer, ATTR_TYPE> *_handle = new SimpleTempData<TetraContainer, ATTR_TYPE>(m.tetra);
2390 
2391  // copy the padded container in the new one
2392  _handle->Resize(m.tetra.size());
2393  for (size_t i = 0; i < m.tetra.size(); ++i)
2394  {
2395  ATTR_TYPE *dest = &(*_handle)[i];
2396  char *ptr = (char *)(((SimpleTempDataBase *)pa._handle)->DataBegin());
2397  ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr;
2398  *dest = attrptr[i * pa._sizeof ];
2399  //memcpy((void *)dest,
2400  //(void *)&(ptr[i * pa._sizeof]), sizeof(ATTR_TYPE));
2401  }
2402 
2403  // remove the padded container
2404  delete ((SimpleTempDataBase *)pa._handle);
2405 
2406  // update the pointer to data
2407  pa._sizeof = sizeof(ATTR_TYPE);
2408 
2409  // update the pointer to data
2410  pa._handle = _handle;
2411 
2412  // zero the padding
2413  pa._padding = 0;
2414  }
2415 
2416  template <class ATTR_TYPE>
2417  static void FixPaddedPerMeshAttribute ( MeshType & /* m */,PointerToAttribute & pa){
2418 
2419  // create the container of the right type
2420  Attribute<ATTR_TYPE> * _handle = new Attribute<ATTR_TYPE>();
2421 
2422  // copy the padded container in the new one
2423  ATTR_TYPE* dest = (ATTR_TYPE*)_handle->DataBegin();
2424  char* ptr = (char*)( ((Attribute<ATTR_TYPE> *)pa._handle)->DataBegin());
2425  ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr;
2426  *dest = *attrptr;
2427  //memcpy((void*)dest ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE));
2428 
2429  // remove the padded container
2430  delete ( (Attribute<ATTR_TYPE> *) pa._handle);
2431 
2432  // update the pointer to data
2433  pa._sizeof = sizeof(ATTR_TYPE);
2434 
2435  // update the pointer to data
2436  pa._handle = _handle;
2437 
2438  // zero the padding
2439  pa._padding = 0;
2440  }
2441 
2442 }; // end Allocator class
2443 
2444  // end doxygen group trimesh
2446 } // end namespace tri
2447 } // end namespace vcg
2448 
2449 #endif
Definition: color4.h:41
Accessory class to update pointers after eventual reallocation caused by adding elements.
Definition: allocate.h:145
void Update(SimplexPointerType &vp)
Update a pointer to an element of a mesh after a reallocation.
Definition: allocate.h:153
bool NeedUpdate()
return true if the allocation operation that initialized this PointerUpdater has caused a reallocatio...
Definition: allocate.h:166
Class to safely add and delete elements in a mesh.
Definition: allocate.h:97
static VertexIterator AddVertices(MeshType &m, size_t n)
Wrapper to AddVertices(); no PointerUpdater.
Definition: allocate.h:256
static HEdgeIterator AddHEdges(MeshType &m, size_t n, std::vector< HEdgePointer * > &local_vec)
Definition: allocate.h:524
static VertexIterator AddVertices(MeshType &m, size_t n, std::vector< VertexPointer * > &local_vec)
Wrapper to AddVertices() no PointerUpdater but a vector of VertexPointer pointers to be updated.
Definition: allocate.h:264
static MeshType::template PerVertexAttributeHandle< ATTR_TYPE > AddPerVertexAttribute(MeshType &m, std::string name)
Add a Per-Vertex Attribute of the given ATTR_TYPE with the given name.
Definition: allocate.h:1496
static VertexIterator AddVertex(MeshType &m, const CoordType &p)
Wrapper to AddVertices() to add a single vertex with given coords.
Definition: allocate.h:295
static bool IsValidHandle(const MeshType &m, const typename MeshType::template PerTetraAttributeHandle< ATTR_TYPE > &a)
Per Tetra Attributes.
Definition: allocate.h:1989
static MeshType::template ConstPerFaceAttributeHandle< ATTR_TYPE > FindPerFaceAttribute(const MeshType &m, const std::string &name)
Try to retrieve a const handle to an attribute with a given name and ATTR_TYPE, from the given const ...
Definition: allocate.h:1932
static void DeleteTetra(MeshType &m, TetraType &t)
Definition: allocate.h:968
static MeshType::template PerVertexAttributeHandle< ATTR_TYPE > FindPerVertexAttribute(MeshType &m, const std::string &name)
Try to retrieve an handle to an attribute with a given name and ATTR_TYPE.
Definition: allocate.h:1554
static EdgeIterator AddEdges(MeshType &m, size_t n, PointerUpdater< EdgePointer > &pu)
Add n edges to the mesh. Function to add n edges to the mesh. The elements are added always to the en...
Definition: allocate.h:333
static void DeletePerEdgeAttribute(MeshType &m, typename MeshType::template PerEdgeAttributeHandle< ATTR_TYPE > &h)
If the per-edge attribute exists, delete it.
Definition: allocate.h:1794
static VertexIterator AddVertex(MeshType &m, const CoordType &p, const Color4b &c)
Wrapper to AddVertices() to add a single vertex with given coords and color.
Definition: allocate.h:314
static VertexIterator AddVertex(MeshType &m, const CoordType &p, const CoordType &n)
Wrapper to AddVertices() to add a single vertex with given coords and normal.
Definition: allocate.h:304
static VertexIterator AddVertices(MeshType &m, const Eigen::MatrixXf &vm)
Wrapper to AddVertices() to add an eigen matrix of (vn,3) it returns the iterator to the first vertex...
Definition: allocate.h:278
static MeshType::template PerTetraAttributeHandle< ATTR_TYPE > GetPerTetraAttribute(MeshType &m, std::string name=std::string(""))
gives a handle to a per-tetra attribute with a given name and ATTR_TYPE
Definition: allocate.h:2043
static TetraIterator AddTetras(MeshType &m, size_t n, std::vector< TetraPointer * > &local_vec)
Function to add n faces to the mesh. Second Wrapper, with a vector of face pointer to be updated.
Definition: allocate.h:907
static void CompactFaceVector(MeshType &m, PointerUpdater< FacePointer > &pu)
Compact face vector by removing deleted elements.
Definition: allocate.h:1231
static TetraIterator AddTetra(MeshType &m, const CoordType &p0, const CoordType &p1, const CoordType &p2, const CoordType &p3)
Definition: allocate.h:851
static void DeletePerTetraAttribute(MeshType &m, typename MeshType::template PerTetraAttributeHandle< ATTR_TYPE > &h)
If the per-face attribute exists, delete it.
Definition: allocate.h:2124
static void CompactFaceVector(MeshType &m)
Wrapper without the PointerUpdater.
Definition: allocate.h:1337
static void DeleteFace(MeshType &m, FaceType &f)
Definition: allocate.h:923
static void CompactVertexVector(MeshType &m, PointerUpdater< VertexPointer > &pu)
Compact vector of vertices removing deleted elements. Deleted elements are put to the end of the vect...
Definition: allocate.h:1084
static void CompactEdgeVector(MeshType &m)
Wrapper without the PointerUpdater.
Definition: allocate.h:1218
static HEdgeIterator AddHEdges(MeshType &m, size_t n)
Definition: allocate.h:515
static void DeleteVertex(MeshType &m, VertexType &v)
Definition: allocate.h:935
static MeshType::template PerFaceAttributeHandle< ATTR_TYPE > GetPerFaceAttribute(MeshType &m, std::string name=std::string(""))
gives a handle to a per-face attribute with a given name and ATTR_TYPE
Definition: allocate.h:1878
static bool IsValidHandle(const MeshType &m, const typename MeshType::template PerFaceAttributeHandle< ATTR_TYPE > &a)
Per Face Attributes.
Definition: allocate.h:1823
static void DeleteHEdge(MeshType &m, HEdgeType &h)
Definition: allocate.h:957
static bool IsValidHandle(const MeshType &m, const typename MeshType::template ConstPerFaceAttributeHandle< ATTR_TYPE > &a)
Checks if a const handle to a Per-Face attribute is valid.
Definition: allocate.h:1835
static FaceIterator AddFaces(MeshType &m, size_t n, PointerUpdater< FacePointer > &pu)
Function to add n faces to the mesh. This is the only full featured function that is able to manage c...
Definition: allocate.h:665
static void CompactEdgeVector(MeshType &m, PointerUpdater< EdgePointer > &pu)
Compact vector of edges removing deleted elements.
Definition: allocate.h:1122
static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater< VertexPointer > &pu)
Add n vertices to the mesh. Function to add n vertices to the mesh. The elements are added always to ...
Definition: allocate.h:189
static FaceIterator AddFaces(MeshType &m, const Eigen::MatrixXi &fm)
Function to add n faces to the mesh getting indexes from a (fn, 3) eigen matrix of int .
Definition: allocate.h:638
static bool IsValidHandle(const MeshType &m, const typename MeshType::template ConstPerVertexAttributeHandle< ATTR_TYPE > &a)
Checks if a const handle to a Per-Vertex Attribute is valid.
Definition: allocate.h:1482
static void CompactTetraVector(MeshType &m)
Wrapper without the PointerUpdater.
Definition: allocate.h:1456
static bool IsValidHandle(const MeshType &m, const typename MeshType::template PerVertexAttributeHandle< ATTR_TYPE > &a)
Checks if a handle to a Per-Vertex Attribute is valid.
Definition: allocate.h:1470
static FaceIterator AddFace(MeshType &m, CoordType p0, CoordType p1, CoordType p2)
Definition: allocate.h:567
static void CompactTetraVector(MeshType &m, PointerUpdater< TetraPointer > &pu)
Compact tetra vector by removing deleted elements.
Definition: allocate.h:1350
static MeshType::template PerEdgeAttributeHandle< ATTR_TYPE > GetPerEdgeAttribute(MeshType &m, std::string name=std::string(""))
gives a handle to a per-edge attribute with a given name and ATTR_TYPE
Definition: allocate.h:1715
static void DeletePerVertexAttribute(MeshType &m, typename MeshType::template PerVertexAttributeHandle< ATTR_TYPE > &h)
If the per-vertex attribute exists, delete it.
Definition: allocate.h:1635
static FaceIterator AddFaces(MeshType &m, size_t n)
Function to add n faces to the mesh. First wrapper, with no parameters.
Definition: allocate.h:615
static MeshType::template ConstPerVertexAttributeHandle< ATTR_TYPE > FindPerVertexAttribute(const MeshType &m, const std::string &name)
Try to retrieve a const handle to an attribute with a given name and ATTR_TYPE, from the given const ...
Definition: allocate.h:1584
static FaceIterator AddFaces(MeshType &m, size_t n, std::vector< FacePointer * > &local_vec)
Function to add n faces to the mesh. Second Wrapper, with a vector of face pointer to be updated.
Definition: allocate.h:624
static EdgeIterator AddEdge(MeshType &m, VertexPointer v0, VertexPointer v1)
Definition: allocate.h:387
static MeshType::template ConstPerVertexAttributeHandle< ATTR_TYPE > GetPerVertexAttribute(const MeshType &m, std::string name=std::string(""))
gives a const handle to a per-vertex attribute with a given name and ATTR_TYPE
Definition: allocate.h:1545
static FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
Definition: allocate.h:585
static void GetAllPerVertexAttribute(const MeshType &m, std::vector< std::string > &all)
query the mesh for all the attributes per vertex
Definition: allocate.h:1604
static void DeleteEdge(MeshType &m, EdgeType &e)
Definition: allocate.h:946
static bool IsValidHandle(const MeshType &m, const typename MeshType::template PerMeshAttributeHandle< ATTR_TYPE > &a)
Per Mesh Attributes.
Definition: allocate.h:2156
static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1)
Definition: allocate.h:408
static MeshType::template PerVertexAttributeHandle< ATTR_TYPE > GetPerVertexAttribute(MeshType &m, std::string name=std::string(""))
gives a handle to a per-vertex attribute with a given name and ATTR_TYPE
Definition: allocate.h:1528
static MeshType::template ConstPerFaceAttributeHandle< ATTR_TYPE > GetPerFaceAttribute(const MeshType &m, std::string name=std::string(""))
gives a handle to a per-face attribute with a given name and ATTR_TYPE
Definition: allocate.h:1895
static TetraIterator AddTetras(MeshType &m, size_t n, PointerUpdater< TetraPointer > &pu)
Function to add n tetras to the mesh. This is the only full featured function that is able to manage ...
Definition: allocate.h:743
static TetraIterator AddTetras(MeshType &m, size_t n)
Function to add n faces to the mesh. First wrapper, with no parameters.
Definition: allocate.h:898
static void DeletePerMeshAttribute(MeshType &m, typename MeshType::template PerMeshAttributeHandle< ATTR_TYPE > &h)
If the per-mesh attribute exists, delete it.
Definition: allocate.h:2272
static TetraIterator AddTetra(MeshType &m, const size_t v0, const size_t v1, const size_t v2, const size_t v3)
Definition: allocate.h:838
static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2)
Definition: allocate.h:557
static void CompactVertexVector(MeshType &m)
Wrapper without the PointerUpdater.
Definition: allocate.h:1109
static EdgeIterator AddEdges(MeshType &m, size_t n, std::vector< EdgePointer * > &local_vec)
Definition: allocate.h:431
static FaceIterator AddFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2)
Definition: allocate.h:539
static EdgeIterator AddEdges(MeshType &m, size_t n)
Definition: allocate.h:422
static TetraIterator AddTetra(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
Definition: allocate.h:813
static void DeletePerFaceAttribute(MeshType &m, typename MeshType::template PerFaceAttributeHandle< ATTR_TYPE > &h)
If the per-face attribute exists, delete it.
Definition: allocate.h:1964
static bool IsValidHandle(const MeshType &m, const typename MeshType::template PerEdgeAttributeHandle< ATTR_TYPE > &a)
Per Edge Attributes.
Definition: allocate.h:1663
static HEdgeIterator AddHEdges(MeshType &m, size_t n, PointerUpdater< HEdgePointer > &pu)
Definition: allocate.h:453
static EdgeIterator AddEdge(MeshType &m, size_t v0, size_t v1)
Definition: allocate.h:397
static MeshType::template PerMeshAttributeHandle< ATTR_TYPE > GetPerMeshAttribute(MeshType &m, std::string name=std::string(""))
gives a handle to a per-edge attribute with a given name and ATTR_TYPE
Definition: allocate.h:2200
Definition: namespaces.dox:6