VCG Library
Loading...
Searching...
No Matches
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
33namespace vcg {
34namespace tri {
39template<class MeshType>
40size_t Index(const MeshType &m, const typename MeshType::VertexType &v) {return &v-&*m.vert.begin();}
41template<class MeshType>
42size_t Index(const MeshType &m, const typename MeshType::FaceType &f) {return &f-&*m.face.begin();}
43template<class MeshType>
44size_t Index(const MeshType &m, const typename MeshType::EdgeType &e) {return &e-&*m.edge.begin();}
45template<class MeshType>
46size_t Index(const MeshType &m, const typename MeshType::HEdgeType &h) {return &h-&*m.hedge.begin();}
47template <class MeshType>
48size_t Index(const MeshType &m, const typename MeshType::TetraType &t) { return &t - &*m.tetra.begin(); }
49
50
51template<class MeshType>
52size_t Index(const MeshType &m, const typename MeshType::VertexType *vp) {return vp-&*m.vert.begin();}
53template<class MeshType>
54size_t Index(const MeshType &m, const typename MeshType::FaceType * fp) {return fp-&*m.face.begin();}
55template<class MeshType>
56size_t Index(const MeshType &m, const typename MeshType::EdgeType* e) {return e-&*m.edge.begin();}
57template<class MeshType>
58size_t Index(const MeshType &m, const typename MeshType::HEdgeType* h) {return h-&*m.hedge.begin();}
59template <class MeshType>
60size_t Index(const MeshType &m, const typename MeshType::TetraType *t) { return t - &*m.tetra.begin(); }
61
62
63template<class MeshType>
64bool IsValidPointer( MeshType & m, const typename MeshType::VertexType *vp) { return ( m.vert.size() > 0 && (vp >= &*m.vert.begin()) && (vp <= &m.vert.back()) ); }
65template<class MeshType>
66bool IsValidPointer(MeshType & m, const typename MeshType::EdgeType *ep) { return ( m.edge.size() > 0 && (ep >= &*m.edge.begin()) && (ep <= &m.edge.back())); }
67template<class MeshType>
68bool IsValidPointer(MeshType & m, const typename MeshType::FaceType *fp) { return ( m.face.size() > 0 && (fp >= &*m.face.begin()) && (fp <= &m.face.back())); }
69template<class MeshType>
70bool IsValidPointer(MeshType & m, const typename MeshType::HEdgeType *hp) { return ( m.hedge.size() > 0 && (hp >= &*m.hedge.begin()) && (hp <= &m.hedge.back())); }
71template <class MeshType>
72bool IsValidPointer(MeshType &m, const typename MeshType::TetraType *tp) { return (m.tetra.size() > 0 && (tp >= &*m.tetra.begin()) && (tp <= &m.tetra.back())); }
73
74template <class MeshType, class ATTR_CONT>
75void 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
81template <class MeshType, class ATTR_CONT>
82void 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
95template <class MeshType>
97{
98
99public:
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 {
1075 }
1076
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
1463public:
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 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 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 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 VertexIterator AddVertex(MeshType &m, const CoordType &p)
Wrapper to AddVertices() to add a single vertex with given coords.
Definition: allocate.h:295
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 bool IsValidHandle(const MeshType &m, const typename MeshType::template PerTetraAttributeHandle< ATTR_TYPE > &a)
Per Tetra Attributes.
Definition: allocate.h:1989
static void DeleteTetra(MeshType &m, TetraType &t)
Definition: allocate.h:968
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 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 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 DeleteVertex(MeshType &m, VertexType &v)
Definition: allocate.h:935
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 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 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 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 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 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 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 FaceIterator AddQuadFace(MeshType &m, VertexPointer v0, VertexPointer v1, VertexPointer v2, VertexPointer v3)
Definition: allocate.h:585
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
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 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 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 EdgeIterator AddEdges(MeshType &m, size_t n, std::vector< EdgePointer * > &local_vec)
Definition: allocate.h:431
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 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 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 DeletePerFaceAttribute(MeshType &m, typename MeshType::template PerFaceAttributeHandle< ATTR_TYPE > &h)
If the per-face attribute exists, delete it.
Definition: allocate.h:1964
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 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
Definition: color4.h:30