VCG Library
Loading...
Searching...
No Matches
topology.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
24#ifndef __VCG_TRI_UPDATE_TOPOLOGY
25#define __VCG_TRI_UPDATE_TOPOLOGY
26
27#include <cassert>
28
29#include <vcg/complex/base.h>
30#include <vcg/simplex/face/topology.h>
31#include <vcg/simplex/edge/pos.h>
32
33namespace vcg {
34namespace tri {
36
38
40
41template <class UpdateMeshType>
43{
44
45public:
46typedef UpdateMeshType MeshType;
47typedef typename MeshType::ScalarType ScalarType;
48typedef typename MeshType::VertexType VertexType;
49typedef typename MeshType::VertexPointer VertexPointer;
50typedef typename MeshType::VertexIterator VertexIterator;
51typedef typename MeshType::EdgeType EdgeType;
52typedef typename MeshType::EdgePointer EdgePointer;
53typedef typename MeshType::EdgeIterator EdgeIterator;
54typedef typename MeshType::FaceType FaceType;
55typedef typename MeshType::FacePointer FacePointer;
56typedef typename MeshType::FaceIterator FaceIterator;
57typedef typename MeshType::TetraType TetraType;
58typedef typename MeshType::TetraPointer TetraPointer;
59typedef typename MeshType::TetraIterator TetraIterator;
60
61
63
65
69class PFace
70{
71public:
72 VertexPointer v[3]; //three ordered vertex pointers, identify a face
73 TetraPointer t; //the pointer to the tetra where this face belongs
74 int z; //index in [0..3] of the face in the tetra
75 bool isBorder;
76
77 PFace () {}
78 PFace (TetraPointer tp, const int nz) { this->Set(tp, nz); }
79
80 void Set (TetraPointer tp /*the tetra pointer*/, const int nz /*the face index*/)
81 {
82 assert (tp != 0);
83 assert (nz >= 0 && nz < 4);
84
85 v[0] = tp->V(Tetra::VofF(nz, 0));
86 v[1] = tp->V(Tetra::VofF(nz, 1));
87 v[2] = tp->V(Tetra::VofF(nz, 2));
88
89 assert(v[0] != v[1] && v[1] != v[2]); //no degenerate faces
90
91 if (v[0] > v[1])
92 std::swap(v[0], v[1]);
93 if (v[1] > v[2])
94 std::swap(v[1], v[2]);
95 if (v[0] > v[1])
96 std::swap(v[0], v[1]);
97
98 t = tp;
99 z = nz;
100
101
102 }
103
104 inline bool operator < (const PFace & pf) const
105 {
106 if (v[0] < pf.v[0])
107 return true;
108 else
109 {
110 if (v[0] > pf.v[0]) return false;
111
112 if (v[1] < pf.v[1])
113 return true;
114 else
115 {
116 if (v[1] > pf.v[1]) return false;
117
118 return (v[2] < pf.v[2]);
119 }
120 }
121 }
122
123 inline bool operator == (const PFace & pf) const
124 {
125 return v[0] == pf.v[0] && v[1] == pf.v[1] && v[2] == pf.v[2];
126 }
127};
128
129static void FillFaceVector (MeshType & m, std::vector<PFace> & fvec)
130{
131 ForEachTetra(m, [&fvec] (TetraType & t) {
132 for (int i = 0; i < 4; ++i)
133 fvec.push_back(PFace(&t, i));
134 });
135}
136
137static void FillUniqueFaceVector (MeshType & m, std::vector<PFace> & fvec)
138{
139 FillFaceVector(m, fvec);
140 std::sort(fvec.begin(), fvec.end());
141 typename std::vector<PFace>::iterator newEnd = std::unique(fvec.begin(), fvec.end());
142}
143
145
148class PEdge
149{
150public:
151
152 VertexPointer v[2]; // the two Vertex pointer are ordered!
153 FacePointer f; // the face where this edge belong
154 int z; // index in [0..2] of the edge of the face
155 bool isBorder;
156
157 PEdge() {}
158 PEdge(FacePointer pf, const int nz) { this->Set(pf,nz); }
159 void Set( FacePointer pf, const int nz )
160 {
161 assert(pf!=0);
162 assert(nz>=0);
163 assert(nz<pf->VN());
164
165 v[0] = pf->V(nz);
166 v[1] = pf->V(pf->Next(nz));
167 assert(v[0] != v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
168
169 if( v[0] > v[1] ) std::swap(v[0],v[1]);
170 f = pf;
171 z = nz;
172 }
173
174 inline bool operator < ( const PEdge & pe ) const
175 {
176 if( v[0]<pe.v[0] ) return true;
177 else if( v[0]>pe.v[0] ) return false;
178 else return v[1] < pe.v[1];
179 }
180
181 inline bool operator == ( const PEdge & pe ) const
182 {
183 return v[0]==pe.v[0] && v[1]==pe.v[1];
184 }
188 {
189 Point3<ScalarType> interp(0,0,0);
190 interp[ this->z ] = u;
191 interp[(this->z+1)%3] = 1.0f-u;
192 return interp;
193 }
194};
195
199
200static void FillEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec, bool includeFauxEdge=true)
201{
202 edgeVec.reserve(m.fn*3);
203 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
204 if( ! (*fi).IsD() )
205 for(int j=0;j<(*fi).VN();++j)
206 if(includeFauxEdge || !(*fi).IsF(j))
207 edgeVec.push_back(PEdge(&*fi,j));
208}
209
210static void FillUniqueEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec, bool includeFauxEdge=true, bool computeBorderFlag=false)
211{
212 FillEdgeVector(m,edgeVec,includeFauxEdge);
213 sort(edgeVec.begin(), edgeVec.end()); // oredering by vertex
214
215 if (computeBorderFlag) {
216 for (size_t i=0; i<edgeVec.size(); i++)
217 edgeVec[ i ].isBorder = true;
218 for (size_t i=1; i<edgeVec.size(); i++) {
219 if (edgeVec[i]==edgeVec[i-1])
220 edgeVec[i].isBorder = edgeVec[i-1].isBorder = false;
221 }
222 }
223
224 typename std::vector< PEdge>::iterator newEnd = std::unique(edgeVec.begin(), edgeVec.end());
225
226 edgeVec.resize(newEnd-edgeVec.begin()); // redundant! remove?
227}
228
229static void FillSelectedFaceEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec)
230{
231 edgeVec.reserve(m.fn*3);
232 ForEachFace(m, [&](FaceType &f){
233 for(int j=0;j<f.VN();++j)
234 if(f.IsFaceEdgeS(j))
235 edgeVec.push_back(PEdge(&f,j));
236 });
237
238 sort(edgeVec.begin(), edgeVec.end()); // oredering by vertex
239 edgeVec.erase(std::unique(edgeVec.begin(), edgeVec.end()),edgeVec.end());
240}
241
242
243
249static void AllocateEdge(MeshType &m)
250{
251 // Delete all the edges (if any)
252 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
255
256 // Compute and add edges
257 std::vector<PEdge> Edges;
258 FillUniqueEdgeVector(m,Edges,true,tri::HasPerEdgeFlags(m) );
259 assert(m.edge.empty());
261 assert(m.edge.size()==Edges.size());
262
263 // Setup adjacency relations
264 if(tri::HasEVAdjacency(m))
265 {
266 for(size_t i=0; i< Edges.size(); ++i)
267 {
268 m.edge[i].V(0) = Edges[i].v[0];
269 m.edge[i].V(1) = Edges[i].v[1];
270 }
271 }
272
273 if (tri::HasPerEdgeFlags(m)){
274 for(size_t i=0; i< Edges.size(); ++i) {
275 if (Edges[i].isBorder) m.edge[i].SetB(); else m.edge[i].ClearB();
276 }
277 }
278
279 if(tri::HasEFAdjacency(m)) // Note it is an unordered relation.
280 {
281 for(size_t i=0; i< Edges.size(); ++i)
282 {
283 std::vector<FacePointer> fpVec;
284 std::vector<int> eiVec;
285 face::EFStarFF(Edges[i].f,Edges[i].z,fpVec,eiVec);
286 m.edge[i].EFp() = Edges[i].f;
287 m.edge[i].EFi() = Edges[i].z;
288 }
289 }
290
291 if(tri::HasFEAdjacency(m))
292 {
293 for(size_t i=0; i< Edges.size(); ++i)
294 {
295 std::vector<FacePointer> fpVec;
296 std::vector<int> eiVec;
297 face::EFStarFF(Edges[i].f,Edges[i].z,fpVec,eiVec);
298 for(size_t j=0;j<fpVec.size();++j)
299 fpVec[j]->FEp(eiVec[j])=&(m.edge[i]);
300
301// Edges[i].f->FE(Edges[i].z) = &(m.edge[i]);
302// Connect in loop the non manifold
303// FaceType* fpit=fp;
304// int eit=ei;
305
306// do
307// {
308// faceVec.push_back(fpit);
309// indVed.push_back(eit);
310// FaceType *new_fpit = fpit->FFp(eit);
311// int new_eit = fpit->FFi(eit);
312// fpit=new_fpit;
313// eit=new_eit;
314// } while(fpit != fp);
315
316
317// m.edge[i].EFp() = Edges[i].f;
318// m.edge[i].EFi() = ;
319 }
320 }
321
322}
323
326static void ClearTetraTetra (MeshType & m)
327{
328 RequireTTAdjacency(m);
329 ForEachTetra(m, [] (TetraType & t) {
330 for (int i = 0; i < 4; ++i)
331 {
332 t.TTp(i) = NULL;
333 t.TTi(i) = -1;
334 }
335 });
336}
337
339static void TetraTetra (MeshType & m)
340{
341 RequireTTAdjacency(m);
342 if (m.tn == 0) return;
343
344 std::vector<PFace> fvec;
345 FillFaceVector(m, fvec);
346 std::sort(fvec.begin(), fvec.end());
347
348 typename std::vector<PFace>::iterator pback, pfront;
349 pback = fvec.begin();
350 pfront = fvec.begin();
351
352 do
353 {
354 if (pfront == fvec.end() || !(*pfront == *pback))
355 {
356 typename std::vector<PFace>::iterator q, q_next;
357 for (q = pback; q < pfront - 1; ++q)
358 {
359 assert((*q).z >= 0);
360 q_next = q;
361 ++q_next;
362 assert((*q_next).z >= 0 && (*q_next).z < 4);
363
364 (*q).t->TTp(q->z) = (*q_next).t;
365 (*q).t->TTi(q->z) = (*q_next).z;
366 }
367
368 (*q).t->TTp(q->z) = pback->t;
369 (*q).t->TTi(q->z) = pback->z;
370 pback = pfront;
371 }
372 if (pfront == fvec.end()) break;
373 ++pfront;
374 } while (true);
375}
378static void ClearFaceFace(MeshType &m)
379{
380 RequireFFAdjacency(m);
381 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
382 {
383 if( ! (*fi).IsD() )
384 {
385 for(int j=0;j<fi->VN();++j)
386 {
387 fi->FFp(j)=0;
388 fi->FFi(j)=-1;
389 }
390 }
391 }
392}
393
395static void FaceFace(MeshType &m)
396{
397 RequireFFAdjacency(m);
398 if( m.fn == 0 ) return;
399 // we use an auxiliary vector of pairs (face,edge index) to sort the edges
400 std::vector<PEdge> e;
401 FillEdgeVector(m,e);
402 sort(e.begin(), e.end());
403
404 auto ps = e.begin();
405 auto pe = e.begin();
406 // scans the sorted vector of edges searching for edges with the same pair of vertices
407 // and connect the corresponding faces
408 do
409 {
410 if( pe==e.end() || !(*pe == *ps) )
411 {
412 typename std::vector<PEdge>::iterator q,q_next;
413 for (q=ps;q<pe-1;++q)
414 {
415 assert((*q).z>=0);
416 //assert((*q).z< 3);
417 q_next = q;
418 ++q_next;
419 assert((*q_next).z>=0);
420 assert((*q_next).z< (*q_next).f->VN());
421 (*q).f->FFp(q->z) = (*q_next).f;
422 (*q).f->FFi(q->z) = (*q_next).z;
423 }
424 assert((*q).z>=0);
425 assert((*q).z< (*q).f->VN());
426 (*q).f->FFp((*q).z) = ps->f;
427 (*q).f->FFi((*q).z) = ps->z;
428 ps = pe;
429 }
430 if(pe==e.end()) break;
431 ++pe;
432 } while(true);
433}
434
435
437static void VertexTetra(MeshType & m)
438{
439 RequireVTAdjacency(m);
440
441
442 ForEachVertex(m, [] (VertexType & v) {
443 v.VTp() = NULL;
444 v.VTi() = 0;
445 });
446
447 ForEachTetra(m, [] (TetraType & t) {
448 //this works like this: the first iteration defines the end of the chain
449 //then it backwards chains everything
450 for (int i = 0; i < 4; ++i)
451 {
452 t.VTp(i) = t.V(i)->VTp();
453 t.VTi(i) = t.V(i)->VTi();
454 t.V(i)->VTp() = &t;
455 t.V(i)->VTi() = i;
456 }
457 });
458}
460
467static void VertexFace(MeshType &m)
468{
469 RequireVFAdjacency(m);
470
471 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
472 {
473 (*vi).VFp() = 0;
474 (*vi).VFi() = 0; // note that (0,-1) means uninitiazlied while 0,0 is the valid initialized values for isolated vertices.
475 }
476
477 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
478 if( ! (*fi).IsD() )
479 {
480 for(int j=0;j<(*fi).VN();++j)
481 {
482 (*fi).VFp(j) = (*fi).V(j)->VFp();
483 (*fi).VFi(j) = (*fi).V(j)->VFi();
484 (*fi).V(j)->VFp() = &(*fi);
485 (*fi).V(j)->VFi() = j;
486 }
487 }
488}
489
490
492
494
499{
500public:
501
502 typename FaceType::TexCoordType v[2]; // the two TexCoord are ordered!
503 FacePointer f; // the face where this edge belong
504 int z; // index in [0..2] of the edge of the face
505
506 PEdgeTex() {}
507
508 void Set( FacePointer pf, const int nz )
509 {
510 assert(pf!=0);
511 assert(nz>=0);
512 assert(nz<3);
513
514 v[0] = pf->WT(nz);
515 v[1] = pf->WT(pf->Next(nz));
516 assert(v[0] != v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
517
518 if( v[1] < v[0] ) std::swap(v[0],v[1]);
519 f = pf;
520 z = nz;
521 }
522
523 inline bool operator < ( const PEdgeTex & pe ) const
524 {
525 if( v[0]<pe.v[0] ) return true;
526 else if( pe.v[0]<v[0] ) return false;
527 else return v[1] < pe.v[1];
528 }
529 inline bool operator == ( const PEdgeTex & pe ) const
530 {
531 return (v[0]==pe.v[0]) && (v[1]==pe.v[1]);
532 }
533 inline bool operator != ( const PEdgeTex & pe ) const
534 {
535 return (v[0]!=pe.v[0]) || (v[1]!=pe.v[1]);
536 }
537
538};
539
540
542
548static void FaceFaceFromTexCoord(MeshType &m)
549{
550 RequireFFAdjacency(m);
551 RequirePerFaceWedgeTexCoord(m);
553 for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
554 {
555 if (!(*fi).IsD())
556 {
557 for (int i = 0; i < (*fi).VN(); i++)
558 {
559 if (!vcg::face::IsBorder((*fi), i))
560 {
561 typename MeshType::FacePointer nextFace = (*fi).FFp(i);
562 int nextEdgeIndex = (*fi).FFi(i);
563 bool border = false;
564 if ((*fi).cV(i) == nextFace->cV(nextEdgeIndex))
565 {
566 if ((*fi).WT(i) != nextFace->WT(nextEdgeIndex) || (*fi).WT((*fi).Next(i)) != nextFace->WT(nextFace->Next(nextEdgeIndex)))
567 border = true;
568 }
569 else
570 {
571 if ((*fi).WT(i) != nextFace->WT(nextFace->Next(nextEdgeIndex)) || (*fi).WT((*fi).Next(i)) != nextFace->WT(nextEdgeIndex))
572 border = true;
573 }
574 if (border)
575 vcg::face::FFDetach((*fi), i);
576
577 }
578 }
579 }
580 }
581}
582
584static void TestVertexEdge(MeshType &m)
585{
586 std::vector<int> numVertex(m.vert.size(),0);
587
588 tri::RequireVEAdjacency(m);
589
590 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
591 {
592 if (!(*ei).IsD())
593 {
594 assert(tri::IsValidPointer(m,ei->V(0)));
595 assert(tri::IsValidPointer(m,ei->V(1)));
596 if(ei->VEp(0)) assert(tri::IsValidPointer(m,ei->VEp(0)));
597 if(ei->VEp(1)) assert(tri::IsValidPointer(m,ei->VEp(1)));
598 numVertex[tri::Index(m,(*ei).V(0))]++;
599 numVertex[tri::Index(m,(*ei).V(1))]++;
600 }
601 }
602
603 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
604 {
605 if (!vi->IsD())
606 {
607 int cnt =0;
608 for(edge::VEIterator<EdgeType> vei(&*vi);!vei.End();++vei)
609 cnt++;
610 assert((numVertex[tri::Index(m,*vi)] == 0) == (vi->VEp()==0) );
611 assert(cnt==numVertex[tri::Index(m,*vi)]);
612 (void)cnt;
613 }
614 }
615}
616
617
619static void TestVertexFace(MeshType &m)
620{
621 SimpleTempData<typename MeshType::VertContainer, int > numVertex(m.vert,0);
622
623 assert(tri::HasPerVertexVFAdjacency(m));
624
625 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
626 {
627 if (!(*fi).IsD())
628 {
629 numVertex[(*fi).V0(0)]++;
630 numVertex[(*fi).V1(0)]++;
631 numVertex[(*fi).V2(0)]++;
632 }
633 }
634
635 vcg::face::VFIterator<FaceType> VFi;
636
637 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
638 {
639 if (!vi->IsD())
640 if(vi->VFp()!=0) // unreferenced vertices MUST have VF == 0;
641 {
642 int num=0;
643 assert(tri::IsValidPointer(m, vi->VFp()));
644 VFi.f=vi->VFp();
645 VFi.z=vi->VFi();
646 while (!VFi.End())
647 {
648 num++;
649 assert(!VFi.F()->IsD());
650 assert((VFi.F()->V(VFi.I()))==&(*vi));
651 ++VFi;
652 }
653 assert(num==numVertex[&(*vi)]);
654 (void)num;
655 }
656 }
657}
658
660static void TestFaceFace(MeshType &m)
661{
662 assert(HasFFAdjacency(m));
663
664 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
665 {
666 if (!fi->IsD())
667 {
668 for (int i=0;i<(*fi).VN();i++)
669 {
670 FaceType *ffpi=fi->FFp(i);
671 int e=fi->FFi(i);
672 //invariant property of FF topology for two manifold meshes
673 assert(ffpi->FFp(e) == &(*fi));
674 assert(ffpi->FFi(e) == i);
675
676 // Test that the two faces shares the same edge
677 // Vertices of the i-th edges of the first face
678 VertexPointer v0i= fi->V0(i);
679 VertexPointer v1i= fi->V1(i);
680 // Vertices of the corresponding edge on the other face
681 VertexPointer ffv0i= ffpi->V0(e);
682 VertexPointer ffv1i= ffpi->V1(e);
683
684 assert( (ffv0i==v0i) || (ffv0i==v1i) );
685 assert( (ffv1i==v0i) || (ffv1i==v1i) );
686 }
687
688 }
689 }
690}
691
695{
696public:
697
698 VertexPointer v; // the two Vertex pointer are ordered!
699 EdgePointer e; // the edge where this vertex belong
700 int z; // index in [0..1] of the vertex of the edge
701
702 PVertexEdge( ) {}
703 PVertexEdge( EdgePointer pe, const int nz )
704{
705 assert(pe!=0);
706 assert(nz>=0);
707 assert(nz<2);
708
709 v= pe->V(nz);
710 e = pe;
711 z = nz;
712}
713inline bool operator < ( const PVertexEdge & pe ) const { return ( v<pe.v ); }
714inline bool operator == ( const PVertexEdge & pe ) const { return ( v==pe.v ); }
715inline bool operator != ( const PVertexEdge & pe ) const { return ( v!=pe.v ); }
716};
717
718
719
720static void EdgeEdge(MeshType &m)
721{
722 RequireEEAdjacency(m);
723 std::vector<PVertexEdge> v;
724 if( m.en == 0 ) return;
725
726 for(EdgeIterator pf=m.edge.begin(); pf!=m.edge.end(); ++pf)
727 if( ! (*pf).IsD() )
728 for(int j=0;j<2;++j)
729 {
730 v.push_back(PVertexEdge(&*pf,j));
731 }
732
733 sort(v.begin(), v.end());
734
735 auto ps = v.begin();
736 auto pe = v.begin();
737 do
738 {
739 if( pe==v.end() || !(*pe == *ps) ) // search for blocs of edges with the same vertex
740 {
741 typename std::vector<PVertexEdge>::iterator q,q_next;
742 for (q=ps;q<pe-1;++q)
743 {
744 assert((*q).z>=0);
745 assert((*q).z< 2);
746 q_next = q;
747 ++q_next;
748 assert((*q_next).z>=0);
749 assert((*q_next).z< 2);
750 (*q).e->EEp(q->z) = (*q_next).e;
751 (*q).e->EEi(q->z) = (*q_next).z;
752 }
753 assert((*q).z>=0);
754 assert((*q).z< 2);
755 (*q).e->EEp((*q).z) = ps->e;
756 (*q).e->EEi((*q).z) = ps->z;
757 ps = pe;
758 }
759 if(pe==v.end()) break;
760 ++pe;
761 } while(true);
762}
763
764static void VertexEdge(MeshType &m)
765{
766 RequireVEAdjacency(m);
767
768 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
769 {
770 (*vi).VEp() = 0;
771 (*vi).VEi() = 0;
772 }
773
774 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
775 if( ! (*ei).IsD() )
776 {
777 for(int j=0;j<2;++j)
778 { assert(tri::IsValidPointer(m,ei->V(j)));
779 (*ei).VEp(j) = (*ei).V(j)->VEp();
780 (*ei).VEi(j) = (*ei).V(j)->VEi();
781 (*ei).V(j)->VEp() = &(*ei);
782 (*ei).V(j)->VEi() = j;
783 }
784 }
785}
786
787}; // end class
788
789} // End namespace
790} // End namespace
791
792
793#endif
Definition: point3.h:43
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 CompactEdgeVector(MeshType &m, PointerUpdater< EdgePointer > &pu)
Compact vector of edges removing deleted elements.
Definition: allocate.h:1122
static void DeleteEdge(MeshType &m, EdgeType &e)
Definition: allocate.h:946
Auxiliairy data structure for computing face face adjacency information.
Definition: topology.h:499
Auxiliary data structure for computing face face adjacency information.
Definition: topology.h:149
Point3< ScalarType > EdgeBarycentricToFaceBarycentric(ScalarType u) const
Definition: topology.h:187
Auxiliary data structure for computing tetra tetra adjacency information.
Definition: topology.h:70
Definition: topology.h:695
Generation of per-vertex and per-face topological information.
Definition: topology.h:43
static void ClearFaceFace(MeshType &m)
Clear the Face-Face topological relation setting each involved pointer to null. useful when you passe...
Definition: topology.h:378
static void VertexFace(MeshType &m)
Update the Vertex-Face topological relation.
Definition: topology.h:467
static void FaceFaceFromTexCoord(MeshType &m)
Update the Face-Face topological relation so that it reflects the per-wedge texture connectivity.
Definition: topology.h:548
static void FillEdgeVector(MeshType &m, std::vector< PEdge > &edgeVec, bool includeFauxEdge=true)
Definition: topology.h:200
static void FaceFace(MeshType &m)
Update the Face-Face topological relation by allowing to retrieve for each face what other faces shar...
Definition: topology.h:395
static void TestVertexFace(MeshType &m)
Test correctness of VFtopology.
Definition: topology.h:619
static void TestFaceFace(MeshType &m)
Test correctness of FFtopology (only for 2Manifold Meshes!)
Definition: topology.h:660
static void AllocateEdge(MeshType &m)
Initialize the edge vector all the edges that can be inferred from current face vector,...
Definition: topology.h:249
static void VertexTetra(MeshType &m)
Update the vertex-tetra topological relation.
Definition: topology.h:437
static void TetraTetra(MeshType &m)
Updates the Tetra-Tetra topological relation by allowing to retrieve for each tetra what other tetras...
Definition: topology.h:339
static void TestVertexEdge(MeshType &m)
Test correctness of VEtopology.
Definition: topology.h:584
static void ClearTetraTetra(MeshType &m)
Clear the tetra-tetra topological relation, setting each involved pointer to null....
Definition: topology.h:326
void ForEachTetra(const MeshType &m, Callable action)
Definition: foreach.h:270
void ForEachFace(const MeshType &m, Callable action)
Definition: foreach.h:78
void ForEachVertex(const MeshType &m, Callable action)
Definition: foreach.h:126
void EFStarFF(FaceType *fp, int ei, std::vector< FaceType * > &faceVec, std::vector< int > &indVed)
Compute the set of faces incident onto a given edge using FF adjacency.
Definition: topology.h:1020
bool IsBorder(FaceType const &f, const int j)
Definition: topology.h:55
void FFDetach(FaceType &f, const int e)
Definition: topology.h:250
Definition: color4.h:30