[temporary commit, it is to be moved to trimesh/update/halfedge_indexed.h]

This commit is contained in:
ganovelli 2010-03-25 16:23:09 +00:00
parent 1fb9d1c555
commit e06c7f7e70
1 changed files with 140 additions and 136 deletions

View File

@ -43,23 +43,23 @@ namespace vcg
*/ */
template <class MeshType > template <class MeshType >
class EdgeSupport{ class HEdgeSupport{
public: public:
typedef typename MeshType::VertexType VertexType; typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::EdgePointer EdgePointer; typedef typename MeshType::HEdgePointer HEdgePointer;
typedef typename MeshType::EdgeType EdgeType; typedef typename MeshType::HEdgeType HEdgeType;
typedef typename MeshType::EdgeIterator EdgeIterator; typedef typename MeshType::HEdgeIterator HEdgeIterator;
typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::FaceIterator FaceIterator;
typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FaceType FaceType;
struct VertexPairEdgePtr{ struct VertexPairEdgePtr{
VertexPairEdgePtr(VertexPointer _v0,VertexPointer _v1,EdgePointer _ep):v0(_v0),v1(_v1),ep(_ep){if(v0>v1) std::swap(v0,v1);} VertexPairEdgePtr(VertexPointer _v0,VertexPointer _v1,HEdgePointer _ep):v0(_v0),v1(_v1),ep(_ep){if(v0>v1) std::swap(v0,v1);}
const bool operator <(const VertexPairEdgePtr &o) const {return (v0 == o.v0)? (v1<o.v1):(v0<o.v0);} const bool operator <(const VertexPairEdgePtr &o) const {return (v0 == o.v0)? (v1<o.v1):(v0<o.v0);}
const bool operator ==(const VertexPairEdgePtr &o) const {return (v0 == o.v0)&& (v1==o.v1);} const bool operator ==(const VertexPairEdgePtr &o) const {return (v0 == o.v0)&& (v1==o.v1);}
VertexPointer v0,v1; VertexPointer v0,v1;
EdgePointer ep; HEdgePointer ep;
}; };
struct FacePtrInt{ struct FacePtrInt{
FacePtrInt ( FaceType * _f,int _i):f(_f),i(_i){} FacePtrInt ( FaceType * _f,int _i):f(_f),i(_i){}
@ -76,8 +76,8 @@ namespace vcg
**/ **/
static void ComputeHalfEdgeFromIndexed(MeshType & m){ static void ComputeHalfEdgeFromIndexed(MeshType & m){
assert(HasFVAdjacency(m)); assert(HasFVAdjacency(m));
assert(MeshType::EdgeType::HasHENextAdjacency()); assert(HasHOppAdjacency(m));
assert(MeshType::EdgeType::HasHEOppAdjacency()); assert(HasHNextAdjacency(m));
typename MeshType::template PerFaceAttributeHandle<BitVector> flagVisited = typename MeshType::template PerFaceAttributeHandle<BitVector> flagVisited =
vcg::tri::Allocator<MeshType>::template AddPerFaceAttribute<BitVector>(m,""); vcg::tri::Allocator<MeshType>::template AddPerFaceAttribute<BitVector>(m,"");
@ -96,7 +96,7 @@ namespace vcg
} }
// allocate the half edges // allocate the half edges
typename MeshType::EdgeIterator ei = vcg::tri::Allocator<MeshType>::AddEdges(m,n_edges); typename MeshType::HEdgeIterator ei = vcg::tri::Allocator<MeshType>::AddHEdges(m,n_edges);
std::vector<VertexPairEdgePtr> all; std::vector<VertexPairEdgePtr> all;
int firstEdge = 0; int firstEdge = 0;
@ -106,16 +106,16 @@ namespace vcg
for(int i = 0; i < (*fi).VN(); ++i,++ei) for(int i = 0; i < (*fi).VN(); ++i,++ei)
{ {
(*ei).HEVp() = (*fi).V(i); (*ei).HVp() = (*fi).V(i);
(*ei).HENp() = &m.edge[firstEdge + (i +1) % (*fi).VN()]; (*ei).HNp() = &m.hedge[firstEdge + (i +1) % (*fi).VN()];
if(MeshType::EdgeType::HasEFAdjacency()) if(MeshType::HEdgeType::HasHFAdjacency())
(*ei).EFp() = &(*fi); (*ei).HFp() = &(*fi);
if( MeshType::FaceType::HasFHEAdjacency()) if( MeshType::FaceType::HasFHAdjacency())
(*fi).FHEp() = &(*ei); (*fi).FHp() = &(*ei);
if(MeshType::EdgeType::HasHEPrevAdjacency()) if(MeshType::HEdgeType::HasHPrevAdjacency())
(*ei).HEPp() = &m.edge[firstEdge + (i +(*fi).VN()-1) % (*fi).VN()]; (*ei).HPp() = &m.hedge[firstEdge + (i +(*fi).VN()-1) % (*fi).VN()];
if(HasVEAdjacency(m)) if(HasVHAdjacency(m))
(*ei).HEVp()->VEp() = &(*ei); (*ei).HVp()->VHp() = &(*ei);
all.push_back(VertexPairEdgePtr((*fi).V(i), (*fi).V((*fi).Next(i)),&(*ei)));// it will be used to link the hedges all.push_back(VertexPairEdgePtr((*fi).V(i), (*fi).V((*fi).Next(i)),&(*ei)));// it will be used to link the hedges
if( vcg::face::IsBorder<FaceType>((*fi),(i))) if( vcg::face::IsBorder<FaceType>((*fi),(i)))
@ -126,7 +126,7 @@ namespace vcg
// add all the border edges // add all the border edges
int borderLength; int borderLength;
typename std::vector<FacePtrInt >::iterator ebi; typename std::vector<FacePtrInt >::iterator ebi;
for( ebi = borderEdges.begin(); ebi != borderEdges.end(); ++ebi) for( ebi = borderEdges.begin(); ebi != borderEdges.end(); ++ebi)
if( !flagVisited[(*ebi).f][(*ebi).i])// not already inserted if( !flagVisited[(*ebi).f][(*ebi).i])// not already inserted
{ {
@ -136,7 +136,7 @@ namespace vcg
FaceType * start = (*ebi).f; FaceType * start = (*ebi).f;
do{ do{
all.push_back( VertexPairEdgePtr ( bp.f->V( bp.f->Next(bp.z) ),bp.f->V( bp.z ),&(*ei))); all.push_back( VertexPairEdgePtr ( bp.f->V( bp.f->Next(bp.z) ),bp.f->V( bp.z ),&(*ei)));
(*ei).HEVp() = bp.f->V(bp.f->Next(bp.z)) ; (*ei).HVp() = bp.f->V(bp.f->Next(bp.z)) ;
flagVisited[bp.f][bp.z] = true; flagVisited[bp.f][bp.z] = true;
++ei; ++ei;
bp.NextB(); bp.NextB();
@ -145,11 +145,11 @@ namespace vcg
// run over the border edges to link the adjacencies // run over the border edges to link the adjacencies
for(int be = 0; be < borderLength; ++be){ for(int be = 0; be < borderLength; ++be){
if(MeshType::EdgeType::HasEFAdjacency()) if(MeshType::HEdgeType::HasHFAdjacency())
m.edge[firstEdge + be].EFp() = NULL; m.hedge[firstEdge + be].HFp() = NULL;
if(MeshType::EdgeType::HasHEPrevAdjacency()) if(MeshType::HEdgeType::HasHPrevAdjacency())
m.edge[firstEdge + be].HEPp() = &m.edge[firstEdge + (be +borderLength-1) % borderLength]; m.hedge[firstEdge + be].HPp() = &m.hedge[firstEdge + (be +borderLength-1) % borderLength];
m.edge[firstEdge + be].HENp() = &m.edge[firstEdge + (be +1) % borderLength]; m.hedge[firstEdge + be].HNp() = &m.hedge[firstEdge + (be +1) % borderLength];
} }
firstEdge+=borderLength; firstEdge+=borderLength;
} }
@ -160,13 +160,13 @@ namespace vcg
for(int i = 0 ; i < all.size(); ) for(int i = 0 ; i < all.size(); )
if(all[i] == all[i+1]) if(all[i] == all[i+1])
{ {
all[i].ep->HEOp() = all[i+1].ep; all[i].ep->HOp() = all[i+1].ep;
all[i+1].ep->HEOp() = all[i].ep; all[i+1].ep->HOp() = all[i].ep;
i+=2; i+=2;
} }
else else
{ {
all[i].ep->HEOp() = all[i].ep; all[i].ep->HOp() = all[i].ep;
i+=1; i+=1;
} }
@ -179,63 +179,65 @@ namespace vcg
**/ **/
static void ComputeIndexedFromHalfEdge( MeshType & m ){ static void ComputeIndexedFromHalfEdge( MeshType & m ){
assert(HasFVAdjacency(m)); assert(HasFVAdjacency(m));
assert(MeshType::EdgeType::HasHENextAdjacency()); assert(MeshType::HEdgeType::HasHNextAdjacency());
assert(MeshType::EdgeType::HasHEVAdjacency()); assert(MeshType::HEdgeType::HasHVAdjacency());
assert(MeshType::EdgeType::HasHEOppAdjacency()); assert(MeshType::HEdgeType::HasHOppAdjacency());
assert(MeshType::FaceType::HasFHEAdjacency()); assert(MeshType::FaceType::HasFHAdjacency());
bool createFace,hasHEF,hasFHE; bool createFace,hasHEF,hasFHE;
typename MeshType::template PerEdgeAttributeHandle<bool> hV = Allocator<MeshType>::template AddPerEdgeAttribute<bool>(m,""); // typename MeshType::template PerHEdgeAttributeHandle<bool> hV = Allocator<MeshType>::template AddPerHEdgeAttribute<bool>(m,"");
typename MeshType::EdgeIterator ei;
typename MeshType::HEdgeIterator ei;
typename MeshType::FacePointer fp; typename MeshType::FacePointer fp;
typename MeshType::FaceIterator fi; typename MeshType::FaceIterator fi;
typename MeshType::EdgePointer ep,epF; typename MeshType::HEdgePointer ep,epF;
int vi = 0; int vi = 0;
vcg::SimpleTempData<typename MeshType::HEdgeContainer,bool> hV(m.hedge);
hasHEF = (MeshType::EdgeType::HasEFAdjacency()); hasHEF = (MeshType::HEdgeType::HasHFAdjacency());
assert( !hasHEF || (hasHEF && m.fn>0)); assert( !hasHEF || (hasHEF && m.fn>0));
// if the edgetype has the pointer to face // if the edgetype has the pointer to face
// it is assumed the the edget2face pointer (HEFp) are correct // it is assumed the the edget2face pointer (HEFp) are correct
// and the faces are allocated // and the faces are allocated
for ( ei = m.edge.begin(); ei != m.edge.end(); ++ei) for ( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
if(!(*ei).IsD()) // it has not been deleted if(!(*ei).IsD()) // it has not been deleted
if(!hasHEF || ( hasHEF && (*ei).EFp()!=NULL)) // if it has a pointer to the face it is if(!hasHEF || ( hasHEF && (*ei).HFp()!=NULL)) // if it has a pointer to the face it is
// not null (i.e. it is not a border edge) // not null (i.e. it is not a border edge)
if(!hV[(*ei)] ) // it has not be visited yet if(!hV[(*ei)] ) // it has not be visited yet
{ {
if(!hasHEF)// if it has if(!hasHEF)// if it has
fp = &(* Allocator<MeshType>::AddFaces(m,1)); fp = &(* Allocator<MeshType>::AddFaces(m,1));
else else
fp = (*ei).EFp(); fp = (*ei).HFp();
ep = epF = &(*ei); ep = epF = &(*ei);
std::vector<VertexPointer> vpts; std::vector<VertexPointer> vpts;
do{vpts.push_back((*ep).HEVp()); ep=ep->HENp();}while(ep!=epF); do{vpts.push_back((*ep).HVp()); ep=ep->HNp();}while(ep!=epF);
int idbg =fp->VN(); int idbg =fp->VN();
if(fp->VN() != vpts.size()){ if(fp->VN() != vpts.size()){
fp->Dealloc(); fp->Dealloc();
fp ->Alloc(vpts.size()); fp ->Alloc(vpts.size());
} }
int idbg1 =fp->VN(); int idbg1 =fp->VN();
for(int i = 0; i < vpts.size();++i) fp ->V(i) = vpts[i];// set the pointer from face to vertex for(unsigned int i = 0; i < vpts.size();++i) fp ->V(i) = vpts[i];// set the pointer from face to vertex
hV[(*ei)] = true; hV[(*ei)] = true;
} }
Allocator<MeshType>::DeletePerEdgeAttribute(m,hV); //Allocator<MeshType>::DeletePerHEdgeAttribute(m,hV);
} }
/** /**
Checks pointers FHEp() are valid Checks pointers FHEp() are valid
**/ **/
static bool CheckConsistency_FHEp(MeshType & m){ static bool CheckConsistency_FHp(MeshType & m){
assert(MeshType::FaceType::HasFHEAdjacency()); assert(MeshType::FaceType::HasFHAdjacency());
FaceIterator fi; FaceIterator fi;
for(fi = m.face.begin(); fi != m.face.end(); ++fi) for(fi = m.face.begin(); fi != m.face.end(); ++fi)
if(!(*fi).IsD()){ if(!(*fi).IsD()){
if((*fi).FHEp() < &(*m.edge.begin())) return false; if((*fi).FHp() < &(*m.hedge.begin())) return false;
if((*fi).FHEp() > &(m.edge.back())) return false; if((*fi).FHp() > &(m.hedge.back())) return false;
} }
return true; return true;
} }
@ -244,62 +246,62 @@ namespace vcg
Checks that half edges and face relation are consistent Checks that half edges and face relation are consistent
**/ **/
static bool CheckConsistency(MeshType & m){ static bool CheckConsistency(MeshType & m){
assert(MeshType::EdgeType::HasHENextAdjacency()); assert(MeshType::HEdgeType::HasHNextAdjacency());
assert(MeshType::EdgeType::HasHEOppAdjacency()); assert(MeshType::HEdgeType::HasHOppAdjacency());
assert(MeshType::EdgeType::HasHEVAdjacency()); assert(MeshType::HEdgeType::HasHVAdjacency());
assert(MeshType::FaceType::HasFHEAdjacency()); assert(MeshType::FaceType::HasFHAdjacency());
bool hasHEF = ( MeshType::EdgeType::HasEFAdjacency()); bool hasHEF = ( MeshType::HEdgeType::HasHFAdjacency());
bool hasHEP = ( MeshType::EdgeType::HasHEPrevAdjacency()); bool hasHEP = ( MeshType::HEdgeType::HasHPrevAdjacency());
FaceIterator fi; FaceIterator fi;
EdgePointer ep,ep1; HEdgePointer ep,ep1;
int cnt = 0; int cnt = 0;
if(( MeshType::EdgeType::HasEFAdjacency())){ if(( MeshType::HEdgeType::HasHFAdjacency())){
int iDb = 0; int iDb = 0;
for(fi = m.face.begin(); fi != m.face.end(); ++fi,++iDb) for(fi = m.face.begin(); fi != m.face.end(); ++fi,++iDb)
if(!(*fi).IsD()) if(!(*fi).IsD())
{ {
ep = ep1 = (*fi).FHEp(); ep = ep1 = (*fi).FHp();
do{ do{
if(ep->IsD()) if(ep->IsD())
return false; // the edge should not be connected, it has been deleted return false; // the edge should not be connected, it has been deleted
if(ep->EFp() != &(*fi)) if(ep->HFp() != &(*fi))
return false;// edge is not pointing to the rigth face return false;// edge is not pointing to the rigth face
ep = ep->HENp(); ep = ep->HNp();
if(cnt++ > m.en) if(cnt++ > m.hn)
return false; // edges are ill connected (HENp()) return false; // edges are ill connected (HENp())
}while(ep!=ep1); }while(ep!=ep1);
} }
} }
EdgePointer epPrev; HEdgePointer epPrev;
EdgeIterator ei; HEdgeIterator ei;
bool extEdge ; bool extEdge ;
for( ei = m.edge.begin(); ei != m.edge.end(); ++ei) for( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
if(!(*ei).IsD()) if(!(*ei).IsD())
{ {
cnt = 0; cnt = 0;
epPrev = ep = ep1 = &(*ei); epPrev = ep = ep1 = &(*ei);
do{ do{
extEdge = (ep->EFp()==NULL); extEdge = (ep->HFp()==NULL);
if(hasHEP){ if(hasHEP){
if( ep->HENp()->HEPp() != ep) if( ep->HNp()->HPp() != ep)
return false; // next and prev relation are not mutual return false; // next and prev relation are not mutual
if( ep->HEPp() == ep) if( ep->HPp() == ep)
return false; // the previous of an edge cannot be the edge itself return false; // the previous of an edge cannot be the edge itself
} }
if( ep->HEOp() == ep) if( ep->HOp() == ep)
return false; // opposite relation is not mutual return false; // opposite relation is not mutual
if( ep->HEOp()->HEOp() != ep) if( ep->HOp()->HOp() != ep)
return false; // opposite relation is not mutual return false; // opposite relation is not mutual
if(ep->HENp() == ep) if(ep->HNp() == ep)
return false; // the next of an edge cannot be the edge itself return false; // the next of an edge cannot be the edge itself
ep = ep->HENp(); ep = ep->HNp();
if( ep->HEVp() != epPrev->HEOp()->HEVp()) if( ep->HVp() != epPrev->HOp()->HVp())
return false; // the opposite edge points to a vertex different that the vertex of the next edge return false; // the opposite edge points to a vertex different that the vertex of the next edge
epPrev = ep; epPrev = ep;
if(cnt++ > m.en) if(cnt++ > m.hn)
return false; // edges are ill connected (HENp()) return false; // edges are ill connected (HENp())
}while(ep!=ep1); }while(ep!=ep1);
} }
@ -307,17 +309,17 @@ namespace vcg
return true; return true;
} }
/** Set the relations HEFp(), FHEp() from a loop of edges to a face /** Set the relations HFp(), FHp() from a loop of edges to a face
*/ */
private: private:
static void SetRelationsLoopFace(EdgeType * e0, FaceType * f){ static void SetRelationsLoopFace(HEdgeType * e0, FaceType * f){
assert(EdgeType::HasHENextAdjacency()); assert(HEdgeType::HasHNextAdjacency());
assert(FaceType::HasFHEAdjacency()); assert(FaceType::HasFHAdjacency());
EdgeType *e = e0; HEdgeType *e = e0;
assert(e!=NULL); assert(e!=NULL);
do{ e->EFp() = f; e = e->HENp(); } while(e != e0); do{ e->HFp() = f; e = e->HNp(); } while(e != e0);
f->FHEp() = e0; f->FHp() = e0;
} }
/** /**
@ -328,12 +330,14 @@ namespace vcg
/** /**
Find previous hedge in the loop Find previous hedge in the loop
*/ */
static EdgeType * PreviousEdge(EdgeType * e0){ static HEdgeType * PreviousEdge(HEdgeType * e0){
EdgeType * ep = e0; HEdgeType * ep = e0;
do{ do{
if(ep->HENp() == e0) return ep; if(ep->HNp() == e0) return ep;
ep = ep->HENp(); ep = ep->HNp();
}while(ep!=e0); }while(ep!=e0);
assert(0); // degenerate loop
return 0;
} }
public: public:
@ -347,54 +351,54 @@ namespace vcg
v v
----e0_HEPp-> X ----- e0 ------> ----e0_HEPp-> X ----- e0 ------>
*/ */
static void AddEdge(MeshType &m, EdgeType * e0, EdgeType * e1){ static void AddHEdge(MeshType &m, HEdgeType * e0, HEdgeType * e1){
EdgeType *iii =e0->HENp(); HEdgeType *iii =e0->HNp();
assert(e1!=e0->HENp()); assert(e1!=e0->HNp());
assert(e0!=e1->HENp()); assert(e0!=e1->HNp());
EdgePointer tmp; HEdgePointer tmp;
bool hasP = MeshType::EdgeType::HasHEPrevAdjacency(); bool hasP = MeshType::HEdgeType::HasHPrevAdjacency();
assert(e0->HEOp() != e1); // the hedge already exists assert(e0->HOp() != e1); // the hedge already exists
assert(e0!=e1->HENp()); assert(e0!=e1->HNp());
std::vector<typename MeshType::EdgePointer* > toUpdate; std::vector<typename MeshType::HEdgePointer* > toUpdate;
toUpdate.push_back(&e0); toUpdate.push_back(&e0);
toUpdate.push_back(&e1); toUpdate.push_back(&e1);
EdgeIterator ei0 = vcg::tri::Allocator<MeshType>::AddEdges(m,2,toUpdate); HEdgeIterator ei0 = vcg::tri::Allocator<MeshType>::AddHEdges(m,2,toUpdate);
EdgeIterator ei1 = ei0; ++ei1; HEdgeIterator ei1 = ei0; ++ei1;
(*ei0).HENp() = e1;(*ei0).HEVp() = e0->HEVp(); (*ei0).HNp() = e1;(*ei0).HVp() = e0->HVp();
(*ei1).HENp() = e0;(*ei1).HEVp() = e1->HEVp(); (*ei1).HNp() = e0;(*ei1).HVp() = e1->HVp();
EdgePointer e0_HEPp = 0,e1_HEPp = 0,ep =0; HEdgePointer e0_HEPp = 0,e1_HEPp = 0,ep =0;
if(hasP){ if(hasP){
e0_HEPp = e0->HEPp(); e0_HEPp = e0->HPp();
e1_HEPp = e1->HEPp(); e1_HEPp = e1->HPp();
}else{// does not have pointer to previous, it must be computed }else{// does not have pointer to previous, it must be computed
ep = e0; ep = e0;
do{ do{
if(ep->HENp() == e0) e0_HEPp = ep; if(ep->HNp() == e0) e0_HEPp = ep;
if(ep->HENp() == e1) e1_HEPp = ep; if(ep->HNp() == e1) e1_HEPp = ep;
ep = ep->HENp(); ep = ep->HNp();
}while(ep!=e0); }while(ep!=e0);
} }
if(hasP){ if(hasP){
(*ei0).HEPp() = e0->HEPp(); (*ei0).HPp() = e0->HPp();
(*ei1).HEPp() = e1->HEPp(); (*ei1).HPp() = e1->HPp();
e0->HEPp() = &(*ei1); e0->HPp() = &(*ei1);
e1->HEPp() = &(*ei0); e1->HPp() = &(*ei0);
} }
e0_HEPp -> HENp() = &(*ei0); e0_HEPp -> HNp() = &(*ei0);
e1_HEPp -> HENp() = &(*ei1); e1_HEPp -> HNp() = &(*ei1);
(*ei0).HEOp() = &(*ei1); (*ei0).HOp() = &(*ei1);
(*ei1).HEOp() = &(*ei0); (*ei1).HOp() = &(*ei0);
if( EdgeType::HasEFAdjacency() && FaceType::HasFHEAdjacency()){ if( HEdgeType::HasHFAdjacency() && FaceType::HasFHAdjacency()){
FaceIterator fi0 = vcg::tri::Allocator<MeshType>::AddFaces(m,1); FaceIterator fi0 = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
m.face.back().ImportLocal(*e0->EFp()); m.face.back().ImportLocal(*e0->HFp());
SetRelationsLoopFace(&(*ei0),e1->EFp()); // one loop to the old face SetRelationsLoopFace(&(*ei0),e1->HFp()); // one loop to the old face
SetRelationsLoopFace(&(*ei1),&m.face.back()); // the other to the new face SetRelationsLoopFace(&(*ei1),&m.face.back()); // the other to the new face
} }
} }
@ -409,45 +413,45 @@ namespace vcg
----e_HEPp--> X ----- e->HEOp->HENPp() ------> ----e_HEPp--> X ----- e->HEOp->HENPp() ------>
*/ */
static void RemoveEdge(MeshType &m, EdgeType * e){ static void RemoveHEdge(MeshType &m, HEdgeType * e){
assert(MeshType::EdgeType::HasHENextAdjacency()); assert(MeshType::HEdgeType::HasHNextAdjacency());
assert(MeshType::EdgeType::HasHEOppAdjacency()); assert(MeshType::HEdgeType::HasHOppAdjacency());
assert(MeshType::FaceType::HasFHEAdjacency()); assert(MeshType::FaceType::HasFHAdjacency());
bool hasP = MeshType::EdgeType::HasHEPrevAdjacency(); bool hasP = MeshType::HEdgeType::HasHPrevAdjacency();
EdgePointer e_HEPp,eO_HEPp; HEdgePointer e_HEPp,eO_HEPp;
if(hasP){ if(hasP){
e_HEPp = e->HEPp(); e_HEPp = e->HPp();
eO_HEPp = e->HEOp()->HEPp(); eO_HEPp = e->HOp()->HPp();
}else{ }else{
e_HEPp = PreviousEdge(e); e_HEPp = PreviousEdge(e);
eO_HEPp = PreviousEdge(e->HEOp()); eO_HEPp = PreviousEdge(e->HOp());
} }
assert(e_HEPp->HENp() == e); assert(e_HEPp->HNp() == e);
assert(eO_HEPp->HENp() == e->HEOp()); assert(eO_HEPp->HNp() == e->HOp());
e_HEPp->HENp() = e->HEOp()->HENp(); e_HEPp->HNp() = e->HOp()->HNp();
eO_HEPp->HENp() = e-> HENp(); eO_HEPp->HNp() = e-> HNp();
if(hasP) { if(hasP) {
e->HEOp()->HENp()->HEPp() = e_HEPp; e->HOp()->HNp()->HPp() = e_HEPp;
e->HENp()->HEPp() = eO_HEPp; e->HNp()->HPp() = eO_HEPp;
e->HEPp() = NULL; e->HPp() = NULL;
e-> HEOp()->HEPp() = NULL; e-> HOp()->HPp() = NULL;
} }
// take care of the faces // take care of the faces
if(MeshType::EdgeType::HasEFAdjacency()){ if(MeshType::HEdgeType::HasHFAdjacency()){
MergeFaces(e_HEPp->EFp(),eO_HEPp->EFp()); MergeFaces(e_HEPp->HFp(),eO_HEPp->HFp());
vcg::tri::Allocator<MeshType>::DeleteFace(m,*eO_HEPp->EFp()); vcg::tri::Allocator<MeshType>::DeleteFace(m,*eO_HEPp->HFp());
SetRelationsLoopFace(e_HEPp,e_HEPp->EFp()); SetRelationsLoopFace(e_HEPp,e_HEPp->HFp());
} }
vcg::tri::Allocator<MeshType>::DeleteEdge(m,*e->HEOp()); vcg::tri::Allocator<MeshType>::DeleteHEdge(m,*e->HOp());
vcg::tri::Allocator<MeshType>::DeleteEdge(m,*e); vcg::tri::Allocator<MeshType>::DeleteHEdge(m,*e);
} }