Complete re-wrote of the link condition test for topology preserving edge collapse. Now it is much slower but really correct. Hopefully.
This commit is contained in:
parent
212c15b77b
commit
830fb74a0f
|
@ -66,6 +66,7 @@ class EdgeCollapse
|
|||
typedef typename TriMeshType::FaceType FaceType;
|
||||
/// The vertex type
|
||||
typedef typename FaceType::VertexType VertexType;
|
||||
typedef typename FaceType::VertexPointer VertexPointer;
|
||||
/// The vertex iterator type
|
||||
typedef typename TriMeshType::VertexIterator VertexIterator;
|
||||
/// The tetra iterator type
|
||||
|
@ -139,8 +140,109 @@ class EdgeCollapse
|
|||
if(zv0==-1) AV1().push_back( x ); // la faccia x.f non ha il vertice v1 => e' incidente solo in v0
|
||||
}
|
||||
}
|
||||
/*
|
||||
Link Conditions test, as described in
|
||||
|
||||
bool LinkConditions(EdgeType pos){
|
||||
Topology Preserving Edge Contraction
|
||||
T. Dey, H. Edelsbrunner,
|
||||
Pub. Inst. Math. 1999
|
||||
|
||||
Lk (sigma) is the set of all the faces of the cofaces of sigma that are disjoint from sigma
|
||||
|
||||
Lk(v0) inters Lk(v1) == Lk(v0-v1)
|
||||
|
||||
To perform these tests using only the VF adjacency we resort to some virtual counters over
|
||||
the vertices and the edges, we implement them as std::maps, and we increase these counters
|
||||
by running over all the faces around each vertex of the collapsing edge.
|
||||
|
||||
At the end (after adding dummy stuff) we should have
|
||||
2 for vertices not shared
|
||||
4 for vertices shared
|
||||
2 for edges shared
|
||||
1 for edges not shared.
|
||||
|
||||
|
||||
*/
|
||||
bool LinkConditions(EdgeType pos)
|
||||
{
|
||||
typedef typename vcg::face::VFIterator<FaceType> VFIterator;
|
||||
// at the end of the loop each vertex must be counted twice
|
||||
// except for boundary vertex.
|
||||
std::map<VertexPointer,int> VertCnt;
|
||||
std::map<std::pair<VertexPointer,VertexPointer>,int> EdgeCnt;
|
||||
|
||||
// the list of the boundary vertexes for the two endpoints
|
||||
std::vector<VertexPointer> BoundaryVertexVec[2];
|
||||
|
||||
// Collect vertexes and edges of V0 and V1
|
||||
VFIterator vfi;
|
||||
for(int i=0;i<2;++i)
|
||||
{
|
||||
vfi = VFIterator(pos.V(i));
|
||||
for( ;!vfi.End();++vfi)
|
||||
{
|
||||
++ VertCnt[vfi.V1()];
|
||||
++ VertCnt[vfi.V2()];
|
||||
if(vfi.V1()<vfi.V2()) ++EdgeCnt[make_pair(vfi.V1(),vfi.V2())];
|
||||
else ++EdgeCnt[make_pair(vfi.V2(),vfi.V1())];
|
||||
}
|
||||
// Now a loop to add dummy stuff: add the dummy vertex and two dummy edges
|
||||
// (and remember to increase the counters for the two boundary vertexes involved)
|
||||
typename std::map<VertexPointer,int>::iterator vcmit;
|
||||
for(vcmit=VertCnt.begin();vcmit!=VertCnt.end();++vcmit)
|
||||
{
|
||||
if((*vcmit).second==1) // boundary vertexes are counted only once
|
||||
BoundaryVertexVec[i].push_back((*vcmit).first);
|
||||
}
|
||||
if(BoundaryVertexVec[i].size()==2)
|
||||
{ // aha! one of the two vertex of the collapse is on the boundary
|
||||
// so add dummy vertex and two dummy edges
|
||||
VertCnt[0]+=2;
|
||||
++ EdgeCnt[std::make_pair(VertexPointer(0),BoundaryVertexVec[i][0]) ] ;
|
||||
++ EdgeCnt[std::make_pair(VertexPointer(0),BoundaryVertexVec[i][1]) ] ;
|
||||
// remember to hide the boundaryness of the two boundary vertexes
|
||||
++VertCnt[BoundaryVertexVec[i][0]];
|
||||
++VertCnt[BoundaryVertexVec[i][1]];
|
||||
}
|
||||
}
|
||||
|
||||
// Final loop to find cardinality of lk( V0-V1 )
|
||||
// Note that Lk(edge) is only a set of vertices.
|
||||
std::vector<VertexPointer> LkEdge;
|
||||
|
||||
for( vfi = VFIterator(pos.V(0)); !vfi.End(); ++vfi)
|
||||
{
|
||||
if(vfi.V1() == pos.V(1) ) LkEdge.push_back(pos.V(2));
|
||||
if(vfi.V2() == pos.V(1) ) LkEdge.push_back(pos.V(1));
|
||||
}
|
||||
|
||||
// if the collapsing edge was a boundary edge, we must add the dummy vertex.
|
||||
// Note that this implies that Lk(edge) >=2;
|
||||
if(LkEdge.size()==1)
|
||||
{
|
||||
LkEdge.push_back(0);
|
||||
}
|
||||
|
||||
// NOW COUNT!!!
|
||||
size_t SharedEdgeCnt=0;
|
||||
typename std::map<std::pair<VertexPointer,VertexPointer>, int>::iterator eci;
|
||||
for(eci=EdgeCnt.begin();eci!=EdgeCnt.end();++eci)
|
||||
if((*eci).second == 2) SharedEdgeCnt ++;
|
||||
|
||||
if(SharedEdgeCnt>0) return false;
|
||||
size_t SharedVertCnt=0;
|
||||
typename std::map<VertexPointer,int>::iterator vci;
|
||||
for(vci=VertCnt.begin();vci!=VertCnt.end();++vci)
|
||||
if((*vci).second == 4) SharedVertCnt++;
|
||||
|
||||
if(SharedVertCnt != LkEdge.size() ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool LinkConditionsOld(EdgeType pos){
|
||||
|
||||
const int ADJ_1 = TriMeshType::VertexType::NewBitFlag();
|
||||
const int ADJ_E = TriMeshType::VertexType::NewBitFlag();
|
||||
|
|
Loading…
Reference in New Issue