diff --git a/vcg/complex/trimesh/edge_collapse.h b/vcg/complex/trimesh/edge_collapse.h index cd8da25e..b1081493 100644 --- a/vcg/complex/trimesh/edge_collapse.h +++ b/vcg/complex/trimesh/edge_collapse.h @@ -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 VFIterator; + // at the end of the loop each vertex must be counted twice + // except for boundary vertex. + std::map VertCnt; + std::map,int> EdgeCnt; + + // the list of the boundary vertexes for the two endpoints + std::vector 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()::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 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, 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::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();