24#ifndef __VCG_TRI_UPDATE_TOPOLOGY
25#define __VCG_TRI_UPDATE_TOPOLOGY
29#include <vcg/complex/base.h>
30#include <vcg/simplex/face/topology.h>
31#include <vcg/simplex/edge/pos.h>
41template <
class UpdateMeshType>
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;
78 PFace (TetraPointer tp,
const int nz) { this->Set(tp, nz); }
80 void Set (TetraPointer tp ,
const int nz )
83 assert (nz >= 0 && nz < 4);
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));
89 assert(v[0] != v[1] && v[1] != v[2]);
92 std::swap(v[0], v[1]);
94 std::swap(v[1], v[2]);
96 std::swap(v[0], v[1]);
104 inline bool operator < (
const PFace & pf)
const
110 if (v[0] > pf.v[0])
return false;
116 if (v[1] > pf.v[1])
return false;
118 return (v[2] < pf.v[2]);
123 inline bool operator == (
const PFace & pf)
const
125 return v[0] == pf.v[0] && v[1] == pf.v[1] && v[2] == pf.v[2];
129static void FillFaceVector (MeshType & m, std::vector<PFace> & fvec)
132 for (
int i = 0; i < 4; ++i)
133 fvec.push_back(
PFace(&t, i));
137static void FillUniqueFaceVector (MeshType & m, std::vector<PFace> & fvec)
139 FillFaceVector(m, fvec);
140 std::sort(fvec.begin(), fvec.end());
141 typename std::vector<PFace>::iterator newEnd = std::unique(fvec.begin(), fvec.end());
158 PEdge(FacePointer pf,
const int nz) { this->Set(pf,nz); }
159 void Set( FacePointer pf,
const int nz )
166 v[1] = pf->V(pf->Next(nz));
167 assert(v[0] != v[1]);
169 if( v[0] > v[1] ) std::swap(v[0],v[1]);
174 inline bool operator < (
const PEdge & pe )
const
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];
181 inline bool operator == (
const PEdge & pe )
const
183 return v[0]==pe.v[0] && v[1]==pe.v[1];
190 interp[ this->z ] = u;
191 interp[(this->z+1)%3] = 1.0f-u;
200static void FillEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec,
bool includeFauxEdge=
true)
202 edgeVec.reserve(m.fn*3);
203 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
205 for(
int j=0;j<(*fi).VN();++j)
206 if(includeFauxEdge || !(*fi).IsF(j))
207 edgeVec.push_back(
PEdge(&*fi,j));
210static void FillUniqueEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec,
bool includeFauxEdge=
true,
bool computeBorderFlag=
false)
213 sort(edgeVec.begin(), edgeVec.end());
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;
224 typename std::vector< PEdge>::iterator newEnd = std::unique(edgeVec.begin(), edgeVec.end());
226 edgeVec.resize(newEnd-edgeVec.begin());
229static void FillSelectedFaceEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec)
231 edgeVec.reserve(m.fn*3);
233 for(
int j=0;j<f.VN();++j)
235 edgeVec.push_back(PEdge(&f,j));
238 sort(edgeVec.begin(), edgeVec.end());
239 edgeVec.erase(std::unique(edgeVec.begin(), edgeVec.end()),edgeVec.end());
252 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
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());
264 if(tri::HasEVAdjacency(m))
266 for(
size_t i=0; i< Edges.size(); ++i)
268 m.edge[i].V(0) = Edges[i].v[0];
269 m.edge[i].V(1) = Edges[i].v[1];
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();
279 if(tri::HasEFAdjacency(m))
281 for(
size_t i=0; i< Edges.size(); ++i)
283 std::vector<FacePointer> fpVec;
284 std::vector<int> eiVec;
286 m.edge[i].EFp() = Edges[i].f;
287 m.edge[i].EFi() = Edges[i].z;
291 if(tri::HasFEAdjacency(m))
293 for(
size_t i=0; i< Edges.size(); ++i)
295 std::vector<FacePointer> fpVec;
296 std::vector<int> eiVec;
298 for(
size_t j=0;j<fpVec.size();++j)
299 fpVec[j]->FEp(eiVec[j])=&(m.edge[i]);
328 RequireTTAdjacency(m);
330 for (
int i = 0; i < 4; ++i)
341 RequireTTAdjacency(m);
342 if (m.tn == 0)
return;
344 std::vector<PFace> fvec;
345 FillFaceVector(m, fvec);
346 std::sort(fvec.begin(), fvec.end());
348 typename std::vector<PFace>::iterator pback, pfront;
349 pback = fvec.begin();
350 pfront = fvec.begin();
354 if (pfront == fvec.end() || !(*pfront == *pback))
356 typename std::vector<PFace>::iterator q, q_next;
357 for (q = pback; q < pfront - 1; ++q)
362 assert((*q_next).z >= 0 && (*q_next).z < 4);
364 (*q).t->TTp(q->z) = (*q_next).t;
365 (*q).t->TTi(q->z) = (*q_next).z;
368 (*q).t->TTp(q->z) = pback->t;
369 (*q).t->TTi(q->z) = pback->z;
372 if (pfront == fvec.end())
break;
380 RequireFFAdjacency(m);
381 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
385 for(
int j=0;j<fi->VN();++j)
397 RequireFFAdjacency(m);
398 if( m.fn == 0 )
return;
400 std::vector<PEdge> e;
402 sort(e.begin(), e.end());
410 if( pe==e.end() || !(*pe == *ps) )
412 typename std::vector<PEdge>::iterator q,q_next;
413 for (q=ps;q<pe-1;++q)
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;
425 assert((*q).z< (*q).f->VN());
426 (*q).f->FFp((*q).z) = ps->f;
427 (*q).f->FFi((*q).z) = ps->z;
430 if(pe==e.end())
break;
439 RequireVTAdjacency(m);
450 for (
int i = 0; i < 4; ++i)
452 t.VTp(i) = t.V(i)->VTp();
453 t.VTi(i) = t.V(i)->VTi();
469 RequireVFAdjacency(m);
471 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
477 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
480 for(
int j=0;j<(*fi).VN();++j)
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;
502 typename FaceType::TexCoordType v[2];
508 void Set( FacePointer pf,
const int nz )
515 v[1] = pf->WT(pf->Next(nz));
516 assert(v[0] != v[1]);
518 if( v[1] < v[0] ) std::swap(v[0],v[1]);
523 inline bool operator < (
const PEdgeTex & pe )
const
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];
529 inline bool operator == (
const PEdgeTex & pe )
const
531 return (v[0]==pe.v[0]) && (v[1]==pe.v[1]);
533 inline bool operator != (
const PEdgeTex & pe )
const
535 return (v[0]!=pe.v[0]) || (v[1]!=pe.v[1]);
549 const FaceType &g = *f.cFFp(i);
550 const int j = f.cFFi(i);
551 if (f.cV(i) == g.cV(j))
552 return f.cWT(i) != g.cWT(j) || f.cWT(f.Next(i)) != g.cWT(g.Next(j));
553 return f.cWT(i) != g.cWT(g.Next(j)) || f.cWT(f.Next(i)) != g.cWT(j);
565 RequireFFAdjacency(m);
566 RequirePerFaceWedgeTexCoord(m);
568 for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
572 for (
int i = 0; i < (*fi).VN(); i++)
584 std::vector<int> numVertex(m.vert.size(),0);
586 tri::RequireVEAdjacency(m);
588 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
592 assert(tri::IsValidPointer(m,ei->V(0)));
593 assert(tri::IsValidPointer(m,ei->V(1)));
594 if(ei->VEp(0)) assert(tri::IsValidPointer(m,ei->VEp(0)));
595 if(ei->VEp(1)) assert(tri::IsValidPointer(m,ei->VEp(1)));
596 numVertex[tri::Index(m,(*ei).V(0))]++;
597 numVertex[tri::Index(m,(*ei).V(1))]++;
601 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
606 for(edge::VEIterator<EdgeType> vei(&*vi);!vei.End();++vei)
608 assert((numVertex[tri::Index(m,*vi)] == 0) == (vi->VEp()==0) );
609 assert(cnt==numVertex[tri::Index(m,*vi)]);
619 SimpleTempData<typename MeshType::VertContainer, int > numVertex(m.vert,0);
621 assert(tri::HasPerVertexVFAdjacency(m));
623 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
627 numVertex[(*fi).V0(0)]++;
628 numVertex[(*fi).V1(0)]++;
629 numVertex[(*fi).V2(0)]++;
633 vcg::face::VFIterator<FaceType> VFi;
635 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
641 assert(tri::IsValidPointer(m, vi->VFp()));
647 assert(!VFi.F()->IsD());
648 assert((VFi.F()->V(VFi.I()))==&(*vi));
651 assert(num==numVertex[&(*vi)]);
660 assert(HasFFAdjacency(m));
662 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
666 for (
int i=0;i<(*fi).VN();i++)
668 FaceType *ffpi=fi->FFp(i);
671 assert(ffpi->FFp(e) == &(*fi));
672 assert(ffpi->FFi(e) == i);
676 VertexPointer v0i= fi->V0(i);
677 VertexPointer v1i= fi->V1(i);
679 VertexPointer ffv0i= ffpi->V0(e);
680 VertexPointer ffv1i= ffpi->V1(e);
682 assert( (ffv0i==v0i) || (ffv0i==v1i) );
683 assert( (ffv1i==v0i) || (ffv1i==v1i) );
711inline bool operator < (
const PVertexEdge & pe )
const {
return ( v<pe.v ); }
712inline bool operator == (
const PVertexEdge & pe )
const {
return ( v==pe.v ); }
713inline bool operator != (
const PVertexEdge & pe )
const {
return ( v!=pe.v ); }
718static void EdgeEdge(MeshType &m)
720 RequireEEAdjacency(m);
721 std::vector<PVertexEdge> v;
722 if( m.en == 0 )
return;
724 for(EdgeIterator pf=m.edge.begin(); pf!=m.edge.end(); ++pf)
731 sort(v.begin(), v.end());
737 if( pe==v.end() || !(*pe == *ps) )
739 typename std::vector<PVertexEdge>::iterator q,q_next;
740 for (q=ps;q<pe-1;++q)
746 assert((*q_next).z>=0);
747 assert((*q_next).z< 2);
748 (*q).e->EEp(q->z) = (*q_next).e;
749 (*q).e->EEi(q->z) = (*q_next).z;
753 (*q).e->EEp((*q).z) = ps->e;
754 (*q).e->EEi((*q).z) = ps->z;
757 if(pe==v.end())
break;
762static void VertexEdge(MeshType &m)
764 RequireVEAdjacency(m);
766 for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
772 for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
776 { assert(tri::IsValidPointer(m,ei->V(j)));
777 (*ei).VEp(j) = (*ei).V(j)->VEp();
778 (*ei).VEi(j) = (*ei).V(j)->VEi();
779 (*ei).V(j)->VEp() = &(*ei);
780 (*ei).V(j)->VEi() = j;
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:339
static void CompactEdgeVector(MeshType &m, PointerUpdater< EdgePointer > &pu)
Compact vector of edges removing deleted elements.
Definition: allocate.h:1128
static void DeleteEdge(MeshType &m, EdgeType &e)
Definition: allocate.h:952
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:693
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:563
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:617
static bool IsTexCoordSeam(const FaceType &f, int i)
Tell whether the faces joined by FF along edge i of f disagree on the per-wedge texture coordinates o...
Definition: topology.h:547
static void TestFaceFace(MeshType &m)
Test correctness of FFtopology (only for 2Manifold Meshes!)
Definition: topology.h:658
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:582
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