24 #ifndef __VCGLIB_HALFEDGE_
25 #define __VCGLIB_HALFEDGE_
27 #include <vcg/complex/algorithms/clean.h>
28 #include <vcg/complex/algorithms/update/topology.h>
29 #include <vcg/complex/algorithms/update/halfedge_topology.h>
39 template <
class MeshType >
42 typedef typename MeshType::VertexType VertexType;
43 typedef typename MeshType::VertexPointer VertexPointer;
44 typedef typename MeshType::VertexIterator VertexIterator;
45 typedef typename MeshType::HEdgePointer HEdgePointer;
46 typedef typename MeshType::HEdgeType HEdgeType;
47 typedef typename MeshType::EdgePointer EdgePointer;
48 typedef typename MeshType::EdgeType EdgeType;
49 typedef typename MeshType::EdgeIterator EdgeIterator;
50 typedef typename MeshType::HEdgeIterator HEdgeIterator;
51 typedef typename MeshType::FaceIterator FaceIterator;
52 typedef typename MeshType::FaceType FaceType;
55 VertexPairEdgePtr(VertexPointer _v0,VertexPointer _v1,HEdgePointer _ep):v0(_v0),v1(_v1),ep(_ep){
if(v0>v1) std::swap(v0,v1);}
56 bool operator <(
const VertexPairEdgePtr &o)
const {
return (v0 == o.v0)? (v1<o.v1):(v0<o.v0);}
57 bool operator ==(
const VertexPairEdgePtr &o)
const {
return (v0 == o.v0)&& (v1==o.v1);}
63 FacePtrInt ( FaceType * _f,
int _i):f(_f),i(_i){}
68 typedef std::vector<bool> BitVector;
76 assert(HasFVAdjacency(m));
77 assert(HasHOppAdjacency(m));
78 assert(HasHNextAdjacency(m));
80 typename MeshType::template PerFaceAttributeHandle<BitVector> flagVisited =
82 std::vector<FacePtrInt > borderEdges;
86 unsigned int n_edges = 0;
89 for(fi = m.face.begin(); fi != m.face.end(); ++fi)
if(! (*fi).IsD())
91 for(
int i = 0; i < (*fi).VN(); ++i)
92 if(vcg::face::IsBorder<FaceType>((*fi),(i)))
103 std::vector<VertexPairEdgePtr> all;
105 for(fi = m.face.begin(); fi != m.face.end(); ++fi)
if(!(*fi).IsD()){
106 assert((*fi).VN()>2);
107 if(flagVisited[*fi].empty()) {flagVisited[*fi].resize((*fi).VN());}
109 for(
int i = 0; i < (*fi).VN(); ++i,++ei)
111 (*ei).HVp() = (*fi).V(i);
112 (*ei).HNp() = &m.hedge[firstEdge + (i +1) % (*fi).VN()];
113 if(MeshType::HEdgeType::HasHFAdjacency())
114 (*ei).HFp() = &(*fi);
115 if( MeshType::FaceType::HasFHAdjacency())
116 (*fi).FHp() = &(*ei);
117 if(MeshType::HEdgeType::HasHPrevAdjacency())
118 (*ei).HPp() = &m.hedge[firstEdge + (i +(*fi).VN()-1) % (*fi).VN()];
119 if(HasVHAdjacency(m))
120 (*ei).HVp()->VHp() = &(*ei);
123 if( vcg::face::IsBorder<FaceType>((*fi),(i)))
126 firstEdge += (*fi).VN();
131 typename std::vector<FacePtrInt >::iterator ebi;
132 for( ebi = borderEdges.begin(); ebi != borderEdges.end(); ++ebi)
133 if( !flagVisited[(*ebi).f][(*ebi).i])
137 vcg::face::Pos<FaceType> bp((*ebi).f,(*ebi).i);
140 VertexType * start = ((*ebi).f)->V((*ebi).i);
142 all.push_back(
VertexPairEdgePtr ( bp.f->V( bp.f->Next(bp.z) ),bp.f->V( bp.z ),&(*ei)));
143 (*ei).HVp() = bp.f->V(bp.f->Next(bp.z)) ;
144 flagVisited[bp.f][bp.z] =
true;
148 }
while (bp.v != start);
153 for(
int be = 0; be < borderLength; ++be)
155 if(MeshType::HEdgeType::HasHFAdjacency())
156 m.hedge[firstEdge + be].HFp() = NULL;
158 if(MeshType::HEdgeType::HasHPrevAdjacency())
159 m.hedge[firstEdge + be].HPp() = &m.hedge[firstEdge + (be +borderLength-1) % borderLength];
161 m.hedge[firstEdge + be].HNp() = &m.hedge[firstEdge + (be +1) % borderLength];
163 firstEdge+=borderLength;
168 std::sort(all.begin(),all.end());
169 assert(all.size() == n_edges);
171 for(
unsigned int i = 0 ; i < all.size(); )
172 if(all[i] == all[i+1])
174 all[i].ep->HOp() = all[i+1].ep;
175 all[i+1].ep->HOp() = all[i].ep;
180 all[i].ep->HOp() = all[i].ep;
184 if(HasEHAdjacency(m) && HasHEAdjacency(m))
186 assert(m.edge.size() == 0 || m.edge.size() == n_edges/2);
188 if ( m.edge.size() == 0 )
194 for(ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
196 if((*ei).HEp() == NULL)
198 (*ei).HEp() = &(*edge_i);
199 (*ei).HOp()->HEp() = &(*edge_i);
201 (*edge_i).EHp() = &(*ei);
211 if(HasEVAdjacency(m) && HasHEAdjacency(m) && HasEHAdjacency(m))
215 for(
typename MeshType::EdgeIterator ei1 = m.edge.begin(); ei1 != m.edge.end(); ++ei1 )
219 for(
typename std::vector<HEdgePointer>::iterator hi = hedges.begin(); hi != hedges.end(); ++hi)
221 if((*hi)->HOp()->HVp() == (*ei1).V(1))
224 assert((*hi)->HEp() == NULL);
225 assert((*hi)->HOp()->HEp() == NULL);
231 (*hi)->HEp() = &(*ei1);
232 (*hi)->HOp()->HEp() = &(*ei1);
249 assert(MeshType::FaceType::HasFHAdjacency());
251 for(fi = m.face.begin(); fi != m.face.end(); ++fi)
253 if((*fi).FHp() < &(*m.hedge.begin()))
return false;
254 if((*fi).FHp() > &(m.hedge.back()))
return false;
263 assert(MeshType::HEdgeType::HasHNextAdjacency());
264 assert(MeshType::HEdgeType::HasHOppAdjacency());
265 assert(MeshType::HEdgeType::HasHVAdjacency());
266 assert(MeshType::FaceType::HasFHAdjacency());
269 bool hasHP = ( MeshType::HEdgeType::HasHPrevAdjacency());
275 if( MeshType::HEdgeType::HasHFAdjacency() )
278 for(fi = m.face.begin(); fi != m.face.end(); ++fi,++iDb)
281 ep = ep1 = (*fi).FHp();
288 if(ep->HFp() != &(*fi))
302 for( hi = m.hedge.begin(); hi != m.hedge.end(); ++hi)
306 epPrev = ep = ep1 = &(*hi);
315 if( ep->HNp()->HPp() != ep)
317 if( ep->HPp()->IsD())
327 if( ep->HOp()->IsD())
330 if( ep->HOp()->HOp() != ep)
333 if( HasHFAdjacency(m) )
337 if( ep->HFp()->IsD())
342 if( HasHEAdjacency(m) && (m.en!=0))
347 if( ep->HEp()->IsD())
350 if(ep->HEp() != ep->HOp()->HEp())
353 if(ep->HEp()->EHp() != ep && ep->HEp()->EHp() != ep->HOp() )
362 if( ep->HNp() == ep )
365 if( ep->HNp()->IsD())
369 if( ep->HNp()->HPp() != ep)
372 if( HasHVAdjacency(m) )
377 if( ep->HVp()->IsD() )
380 if( HasVHAdjacency(m) )
381 if( ! (ep->HVp()->VHp()) )
388 if( ep->HVp() != epPrev->HOp()->HVp())
399 if(HasEHAdjacency(m) && HasHEAdjacency(m))
400 for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
407 if( (*ei).EHp()->HEp() != &(*ei) )
410 if( (*ei).EHp()->IsD())
415 if(HasVHAdjacency(m))
416 for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
421 if( (*vi).VHp()->HVp() != &(*vi) )
423 if( (*vi).VHp()->IsD())
435 static void SetRelationsLoopFace(HEdgeType * e0, FaceType * f){
436 assert(HEdgeType::HasHNextAdjacency());
437 assert(FaceType::HasFHAdjacency());
441 do{ e->HFp() = f; e = e->HNp(); }
while(e != e0);
448 static void MergeFaces(FaceType *, FaceType *){}
453 static HEdgeType * PreviousEdge(HEdgeType * e0){
456 if(ep->HNp() == e0)
return ep;
474 static void AddHEdge(MeshType &m, HEdgeType * e0, HEdgeType * e1){
475 assert(e1!=e0->HNp());
476 assert(e0!=e1->HNp());
477 bool hasP = MeshType::HEdgeType::HasHPrevAdjacency();
478 assert(e0->HOp() != e1);
479 assert(e0!=e1->HNp());
481 std::vector<typename MeshType::HEdgePointer* > toUpdate;
482 toUpdate.push_back(&e0);
483 toUpdate.push_back(&e1);
486 HEdgeIterator ei1 = ei0; ++ei1;
487 (*ei0).HNp() = e1;(*ei0).HVp() = e0->HVp();
488 (*ei1).HNp() = e0;(*ei1).HVp() = e1->HVp();
490 HEdgePointer e0_HEPp = 0,e1_HEPp = 0,ep =0;
497 if(ep->HNp() == e0) e0_HEPp = ep;
498 if(ep->HNp() == e1) e1_HEPp = ep;
503 (*ei0).HPp() = e0->HPp();
504 (*ei1).HPp() = e1->HPp();
508 e0_HEPp -> HNp() = &(*ei0);
509 e1_HEPp -> HNp() = &(*ei1);
511 (*ei0).HOp() = &(*ei1);
512 (*ei1).HOp() = &(*ei0);
515 if( HEdgeType::HasHFAdjacency() && FaceType::HasFHAdjacency()){
517 m.face.back().ImportData(*e0->HFp());
518 SetRelationsLoopFace(&(*ei0),e1->HFp());
519 SetRelationsLoopFace(&(*ei1),&m.face.back());
534 assert(MeshType::HEdgeType::HasHNextAdjacency());
535 assert(MeshType::HEdgeType::HasHOppAdjacency());
536 assert(MeshType::FaceType::HasFHAdjacency());
538 bool hasP = MeshType::HEdgeType::HasHPrevAdjacency();
539 HEdgePointer e_HEPp,eO_HEPp;
543 eO_HEPp = e->HOp()->HPp();
545 e_HEPp = PreviousEdge(e);
546 eO_HEPp = PreviousEdge(e->HOp());
549 assert(e_HEPp->HNp() == e);
550 assert(eO_HEPp->HNp() == e->HOp());
551 e_HEPp->HNp() = e->HOp()->HNp();
552 eO_HEPp->HNp() = e-> HNp();
555 e->HOp()->HNp()->HPp() = e_HEPp;
556 e->HNp()->HPp() = eO_HEPp;
559 e-> HOp()->HPp() = NULL;
564 if(MeshType::HEdgeType::HasHFAdjacency()){
565 MergeFaces(e_HEPp->HFp(),eO_HEPp->HFp());
567 SetRelationsLoopFace(e_HEPp,e_HEPp->HFp());
576 template <
class MeshType >
578 typedef typename MeshType::VertexType VertexType;
579 typedef typename MeshType::VertexPointer VertexPointer;
580 typedef typename MeshType::HEdgePointer HEdgePointer;
581 typedef typename MeshType::HEdgeType HEdgeType;
582 typedef typename MeshType::HEdgeIterator HEdgeIterator;
583 typedef typename MeshType::FaceIterator FaceIterator;
584 typedef typename MeshType::FaceType FaceType;
587 VertexPairEdgePtr(VertexPointer _v0,VertexPointer _v1,HEdgePointer _ep):v0(_v0),v1(_v1),ep(_ep){
if(v0>v1) std::swap(v0,v1);}
588 bool operator <(
const VertexPairEdgePtr &o)
const {
return (v0 == o.v0)? (v1<o.v1):(v0<o.v0);}
589 bool operator ==(
const VertexPairEdgePtr &o)
const {
return (v0 == o.v0)&& (v1==o.v1);}
602 assert(HasFVAdjacency(m));
603 assert(MeshType::HEdgeType::HasHNextAdjacency());
604 assert(MeshType::HEdgeType::HasHVAdjacency());
605 assert(MeshType::HEdgeType::HasHOppAdjacency());
606 assert(MeshType::FaceType::HasFHAdjacency());
613 typename MeshType::HEdgeIterator ei;
614 typename MeshType::FacePointer fp;
615 typename MeshType::FaceIterator fi;
616 typename MeshType::HEdgePointer ep,epF;
618 vcg::SimpleTempData<typename MeshType::HEdgeContainer,bool> hV(m.hedge);
620 hasHEF = (MeshType::HEdgeType::HasHFAdjacency());
621 assert( !hasHEF || (hasHEF && m.fn>0));
626 for ( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
628 if(!hasHEF || ( hasHEF && (*ei).HFp()!=NULL))
638 std::vector<VertexPointer> vpts;
639 do{vpts.push_back((*ep).HVp()); ep=ep->HNp();}
while(ep!=epF);
641 if(
size_t(fp->VN()) != vpts.size()){
643 fp ->Alloc(vpts.size());
646 for(
size_t i = 0; i < vpts.size();++i) fp ->V(i) = vpts[i];
Class to safely add and delete elements in a mesh.
Definition: allocate.h:97
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 DeleteFace(MeshType &m, FaceType &f)
Definition: allocate.h:923
static void DeleteHEdge(MeshType &m, HEdgeType &h)
Definition: allocate.h:957
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 HEdgeIterator AddHEdges(MeshType &m, size_t n, PointerUpdater< HEdgePointer > &pu)
Definition: allocate.h:453
static std::vector< HEdgePointer > get_incident_hedges(VertexPointer vp, HEdgePointer starting_he=NULL)
Definition: halfedge_topology.h:1593
This class is used to build edge based data structure from indexed data structure and viceversa.
Definition: halfedge_indexed.h:40
static void RemoveHEdge(MeshType &m, HEdgeType *e)
Definition: halfedge_indexed.h:533
static void FromIndexed(MeshType &m)
Definition: halfedge_indexed.h:75
static bool CheckConsistency(MeshType &m)
Definition: halfedge_indexed.h:262
static bool CheckConsistency_FHp(MeshType &m)
Definition: halfedge_indexed.h:248
static void AddHEdge(MeshType &m, HEdgeType *e0, HEdgeType *e1)
Definition: halfedge_indexed.h:474
Definition: namespaces.dox:6
Definition: halfedge_indexed.h:62
Definition: halfedge_indexed.h:54
Definition: halfedge_indexed.h:586
Definition: halfedge_indexed.h:577
static void FromHalfEdges(MeshType &m)
Definition: halfedge_indexed.h:601