added allocation and conversion of edges in function FromIndexed

added new tests in function CheckConsistency
This commit is contained in:
Paolo Cignoni 2010-04-26 14:33:55 +00:00
parent 01a0a4b93c
commit 5c9ee5cdff
1 changed files with 553 additions and 379 deletions

View File

@ -47,8 +47,12 @@ namespace vcg
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::VertexIterator VertexIterator;
typedef typename MeshType::HEdgePointer HEdgePointer; typedef typename MeshType::HEdgePointer HEdgePointer;
typedef typename MeshType::HEdgeType HEdgeType; typedef typename MeshType::HEdgeType HEdgeType;
typedef typename MeshType::EdgePointer EdgePointer;
typedef typename MeshType::EdgeType EdgeType;
typedef typename MeshType::EdgeIterator EdgeIterator;
typedef typename MeshType::HEdgeIterator HEdgeIterator; 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;
@ -78,6 +82,7 @@ namespace vcg
assert(HasFVAdjacency(m)); assert(HasFVAdjacency(m));
assert(HasHOppAdjacency(m)); assert(HasHOppAdjacency(m));
assert(HasHNextAdjacency(m)); assert(HasHNextAdjacency(m));
assert(HasHEAdjacency(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,"");
@ -85,7 +90,7 @@ namespace vcg
// allocate all new half edges // allocate all new half edges
FaceIterator fi; FaceIterator fi;
int n_edges = 0; unsigned int n_edges = 0;
// count how many half edge to allocate // count how many half edge to allocate
for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD())
@ -95,9 +100,13 @@ namespace vcg
++n_edges; ++n_edges;
} }
m.hedge.clear();
m.hn = 0;
// allocate the half edges // allocate the half edges
typename MeshType::HEdgeIterator ei = vcg::tri::Allocator<MeshType>::AddHEdges(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;
for(fi = m.face.begin(); fi != m.face.end(); ++fi)if(!(*fi).IsD()){ for(fi = m.face.begin(); fi != m.face.end(); ++fi)if(!(*fi).IsD()){
@ -124,7 +133,7 @@ namespace vcg
firstEdge += (*fi).VN(); firstEdge += (*fi).VN();
} }
// add all the border edges // add all the border hedges
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)
@ -133,7 +142,9 @@ namespace vcg
borderLength = 0; borderLength = 0;
vcg::face::Pos<FaceType> bp((*ebi).f,(*ebi).i); vcg::face::Pos<FaceType> bp((*ebi).f,(*ebi).i);
FaceType * start = (*ebi).f;
//FaceType * start = (*ebi).f;
VertexType * start = ((*ebi).f)->V((*ebi).i);
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).HVp() = bp.f->V(bp.f->Next(bp.z)) ; (*ei).HVp() = bp.f->V(bp.f->Next(bp.z)) ;
@ -141,23 +152,30 @@ namespace vcg
++ei; ++ei;
bp.NextB(); bp.NextB();
++borderLength; ++borderLength;
}while (bp.f != start); }while (bp.v != start);
//}while (bp.f != start);
// 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::HEdgeType::HasHFAdjacency()) if(MeshType::HEdgeType::HasHFAdjacency())
m.hedge[firstEdge + be].HFp() = NULL; m.hedge[firstEdge + be].HFp() = NULL;
if(MeshType::HEdgeType::HasHPrevAdjacency()) if(MeshType::HEdgeType::HasHPrevAdjacency())
m.hedge[firstEdge + be].HPp() = &m.hedge[firstEdge + (be +borderLength-1) % borderLength]; m.hedge[firstEdge + be].HPp() = &m.hedge[firstEdge + (be +borderLength-1) % borderLength];
m.hedge[firstEdge + be].HNp() = &m.hedge[firstEdge + (be +1) % borderLength]; m.hedge[firstEdge + be].HNp() = &m.hedge[firstEdge + (be +1) % borderLength];
} }
firstEdge+=borderLength; firstEdge+=borderLength;
} }
vcg::tri::Allocator<MeshType>:: template DeletePerFaceAttribute<BitVector>(m,flagVisited ); vcg::tri::Allocator<MeshType>:: template DeletePerFaceAttribute<BitVector>(m,flagVisited );
std::sort(all.begin(),all.end()); std::sort(all.begin(),all.end());
assert(all.size() == n_edges); assert(all.size() == n_edges);
for(int i = 0 ; i < all.size(); )
for(unsigned int i = 0 ; i < all.size(); )
if(all[i] == all[i+1]) if(all[i] == all[i+1])
{ {
all[i].ep->HOp() = all[i+1].ep; all[i].ep->HOp() = all[i+1].ep;
@ -170,6 +188,55 @@ namespace vcg
i+=1; i+=1;
} }
if(HasEHAdjacency(m) && HasHEAdjacency(m))
{
assert(m.edge.size() == 0 || m.edge.size() == n_edges/2);
if ( m.edge.size() == 0 )
{
m.en = 0;
// allocate the edges
typename MeshType::EdgeIterator edge_i = vcg::tri::Allocator<MeshType>::AddEdges(m,n_edges/2);
for(ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
{
if((*ei).HEp() == NULL)
{
(*ei).HEp() = &(*edge_i);
(*ei).HOp()->HEp() = &(*edge_i);
(*edge_i).EHp() = &(*ei);
++edge_i;
}
}
}
else
{
assert(HasEVAdjacency(m));
//update edge relations
typename MeshType::EdgeIterator ei1;
for( ei1 = m.edge.begin(); ei1 != m.edge.end(); ++ei1 )
for( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei )
if ( ((*ei).HVp() == (*ei1).V(0)) && ((*ei).HOp()->HVp() == (*ei1).V(1)) )
{
// EH
(*ei1).EHp() = &(*ei);
// HE
(*ei).HEp() = &(*ei1);
(*ei).HOp()->HEp() = &(*ei1);
break;
}
}
}
} }
/** /**
@ -193,63 +260,169 @@ namespace vcg
assert(MeshType::HEdgeType::HasHNextAdjacency()); assert(MeshType::HEdgeType::HasHNextAdjacency());
assert(MeshType::HEdgeType::HasHOppAdjacency()); assert(MeshType::HEdgeType::HasHOppAdjacency());
assert(MeshType::HEdgeType::HasHVAdjacency()); assert(MeshType::HEdgeType::HasHVAdjacency());
assert(MeshType::HEdgeType::HasHEAdjacency());
assert(MeshType::FaceType::HasFHAdjacency()); assert(MeshType::FaceType::HasFHAdjacency());
bool hasHEF = ( MeshType::HEdgeType::HasHFAdjacency()); //bool hasHEF = ( MeshType::HEdgeType::HasHFAdjacency());
bool hasHEP = ( MeshType::HEdgeType::HasHPrevAdjacency()); bool hasHP = ( MeshType::HEdgeType::HasHPrevAdjacency());
FaceIterator fi; FaceIterator fi;
HEdgePointer ep,ep1; HEdgePointer ep,ep1;
int cnt = 0; int cnt = 0;
if(( MeshType::HEdgeType::HasHFAdjacency())){
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).FHp(); 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 hedge should not be connected, it has been deleted
if( ! ep->HFp())
return false;
if(ep->HFp() != &(*fi)) if(ep->HFp() != &(*fi))
return false;// edge is not pointing to the rigth face return false;// hedge is not pointing to the rigth face
ep = ep->HNp(); ep = ep->HNp();
if(cnt++ > m.hn) if(cnt++ > m.hn)
return false; // edges are ill connected (HENp()) return false; // hedges are ill connected (HENp())
}while(ep!=ep1); }while(ep!=ep1);
} }
} }
HEdgePointer epPrev; HEdgePointer epPrev;
HEdgeIterator ei; HEdgeIterator hi;
bool extEdge ; //bool extEdge ;
for( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei) for( hi = m.hedge.begin(); hi != m.hedge.end(); ++hi)
if(!(*ei).IsD()) if(!(*hi).IsD())
{ {
cnt = 0; //cnt = 0;
epPrev = ep = ep1 = &(*ei); epPrev = ep = ep1 = &(*hi);
do{ //do{
extEdge = (ep->HFp()==NULL); //extEdge = (ep->HFp()==NULL);
if(hasHEP){ if(hasHP)
if( ep->HNp()->HPp() != ep) {
return false; // next and prev relation are not mutual if( !ep->HPp())
return false;
if( ep->HPp() == 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->HNp()->HPp() != ep)
return false; // next and prev relation are not mutual
if( ep->HPp()->IsD())
return false; //
} }
if( ! ep->HOp() )
return false;
if( ep->HOp() == ep) if( ep->HOp() == ep)
return false; // opposite relation is not mutual return false; // opposite relation is not mutual
if( ep->HOp()->IsD())
return false;
if( ep->HOp()->HOp() != ep) if( ep->HOp()->HOp() != ep)
return false; // opposite relation is not mutual return false; // opposite relation is not mutual
if(ep->HNp() == ep)
return false; // the next of an edge cannot be the edge itself if( HasHFAdjacency(m) )
{
if(ep->HFp())
{
if( ep->HFp()->IsD())
return false; // pointed face must not be deleted
}
}
if( HasHEAdjacency(m) )
{
if( ! ep->HEp())
return false; //halfedge must point to an edge
if( ep->HEp()->IsD())
return false; // pointed edge must not be deleted
if(ep->HEp() != ep->HOp()->HEp())
return false; // he and opposite he must point to the same edge
if(ep->HEp()->EHp() != ep && ep->HEp()->EHp() != ep->HOp() )
return false; // halfedge points to an edge not pointing it or its opposite
}
if( !ep->HNp() )
return false;
if( ep->HNp() == ep )
return false; // the next of an hedge cannot be the hedge itself
if( ep->HNp()->IsD())
return false; //
if( ep->HNp()->HPp() != ep)
return false; //
if( HasHVAdjacency(m) )
{
if( ! ep->HVp() )
return false; // halfedge must point to a vertex
if( ep->HVp()->IsD() )
return false; // pointed vertex must not be deleted
if( HasVHAdjacency(m) )
if( ! (ep->HVp()->VHp()) )
return false; // halfedge points to a vertex pointing NULL
}
ep = ep->HNp(); ep = ep->HNp();
if( ep->HVp() != epPrev->HOp()->HVp()) 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;
epPrev = ep; epPrev = ep;
if(cnt++ > m.hn)
return false; // edges are ill connected (HENp()) // if(cnt++ > m.hn)
}while(ep!=ep1); // return false; // edges are ill connected (HENp())
//}while(ep!=ep1);
} }
if(HasEHAdjacency(m))
for(EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
{
if(!(*ei).IsD())
{
if( !(*ei).EHp())
return false; //edge must have a valid pointer to his halfedge
if( (*ei).EHp()->HEp() != &(*ei) )
return false; // edge's halfedge must point to the edge itself
if( (*ei).EHp()->IsD())
return false;
}
}
if(HasVHAdjacency(m))
for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
{
if( !(*vi).IsD() )
if( (*vi).VHp() )
{
if( (*vi).VHp()->HVp() != &(*vi) )
return false;
if( (*vi).VHp()->IsD())
return false;
}
}
return true; return true;
} }
@ -269,7 +442,7 @@ namespace vcg
/** /**
Merge the two faces. This will probably become a class template or a functor Merge the two faces. This will probably become a class template or a functor
*/ */
static void MergeFaces(FaceType *, FaceType *){}; static void MergeFaces(FaceType *, FaceType *){}
/** /**
Find previous hedge in the loop Find previous hedge in the loop
@ -431,16 +604,17 @@ namespace vcg
assert(MeshType::HEdgeType::HasHVAdjacency()); assert(MeshType::HEdgeType::HasHVAdjacency());
assert(MeshType::HEdgeType::HasHOppAdjacency()); assert(MeshType::HEdgeType::HasHOppAdjacency());
assert(MeshType::FaceType::HasFHAdjacency()); assert(MeshType::FaceType::HasFHAdjacency());
bool createFace,hasHEF,hasFHE; bool hasHEF;
//bool createFace,hasHEF,hasFHE;
// typename MeshType::template PerHEdgeAttributeHandle<bool> hV = Allocator<MeshType>::template AddPerHEdgeAttribute<bool>(m,""); // typename MeshType::template PerHEdgeAttributeHandle<bool> hV = Allocator<MeshType>::template AddPerHEdgeAttribute<bool>(m,"");
typename MeshType::HEdgeIterator ei; typename MeshType::HEdgeIterator ei;
typename MeshType::FacePointer fp; typename MeshType::FacePointer fp;
typename MeshType::FaceIterator fi; typename MeshType::FaceIterator fi;
typename MeshType::HEdgePointer ep,epF; typename MeshType::HEdgePointer ep,epF;
int vi = 0; //int vi = 0;
vcg::SimpleTempData<typename MeshType::HEdgeContainer,bool> hV(m.hedge); vcg::SimpleTempData<typename MeshType::HEdgeContainer,bool> hV(m.hedge);
hasHEF = (MeshType::HEdgeType::HasHFAdjacency()); hasHEF = (MeshType::HEdgeType::HasHFAdjacency());
@ -463,12 +637,12 @@ namespace vcg
ep = epF = &(*ei); ep = epF = &(*ei);
std::vector<VertexPointer> vpts; std::vector<VertexPointer> vpts;
do{vpts.push_back((*ep).HVp()); ep=ep->HNp();}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(unsigned 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;
@ -477,6 +651,6 @@ namespace vcg
} }
}; };
} // end namespace vcg } // end namespace vcg
} }
#endif // __VCGLIB_EDGE_SUPPORT #endif // __VCGLIB_EDGE_SUPPORT