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