From 04e2464e3db2f703069c6f4bf52c148e020ddf32 Mon Sep 17 00:00:00 2001 From: cnr-isti-vclab Date: Wed, 11 Mar 2009 16:43:16 +0000 Subject: [PATCH] Added RemoveTVertexByCollapse and RemoveTVertexByFlip methods --- vcg/complex/trimesh/clean.h | 89 +++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/vcg/complex/trimesh/clean.h b/vcg/complex/trimesh/clean.h index 2b8de764..83b9862c 100644 --- a/vcg/complex/trimesh/clean.h +++ b/vcg/complex/trimesh/clean.h @@ -228,6 +228,8 @@ Initial Release #include #include #include +#include +#include namespace vcg { @@ -245,6 +247,7 @@ class ConnectedIterator typedef typename MeshType::FacePointer FacePointer; typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::FaceContainer FaceContainer; + typedef typename vcg::Box3 Box3Type; public: @@ -1103,6 +1106,92 @@ private: } } + static int RemoveTVertexByFlip(MeshType &m, float threshold=40, bool repeat=true) + { + assert(m.HasFFTopology()); + assert(m.HasPerVertexMark()); + //Counters for logging and convergence + int count, total = 0; + + do { + tri::UpdateTopology::FaceFace(m); + m.UnMarkAll(); + count = 0; + + //detection stage + for(unsigned int index = 0 ; index < m.face.size(); ++index ) + { + CMeshO::FacePointer f = &(m.face[index]); float sides[3]; Point3 dummy; + sides[0] = Distance(f->P(0), f->P(1)); sides[1] = Distance(f->P(1), f->P(2)); sides[2] = Distance(f->P(2), f->P(0)); + int i = std::find(sides, sides+3, std::max( std::max(sides[0],sides[1]), sides[2])) - (sides); + if( m.IsMarked(f->V2(i) )) continue; + + if( PSDist(f->P2(i),f->P(i),f->P1(i),dummy)*threshold <= sides[i] ) + { + m.Mark(f->V2(i)); + if(face::CheckFlipEdge( *f, i )) { + // Check if EdgeFlipping improves quality + CMeshO::FacePointer g = f->FFp(i); int k = f->FFi(i); + Triangle3 t1(f->P(i), f->P1(i), f->P2(i)), t2(g->P(k), g->P1(k), g->P2(k)), + t3(f->P(i), g->P2(k), f->P2(i)), t4(g->P(k), f->P2(i), g->P2(k)); + + if ( std::min( t1.QualityFace(), t2.QualityFace() ) < std::min( t3.QualityFace(), t4.QualityFace() )) + { + face::FlipEdge( *f, i ); + ++count; ++total; + } + } + + } + } + + tri::UpdateNormals::PerFace(m); + } + while( repeat && count ); + + return total; + } + + static int RemoveTVertexByCollapse(MeshType &m, float threshold=40, bool repeat=true) + { + assert(m.HasPerVertexMark()); + //Counters for logging and convergence + int count, total = 0; + + do { + m.UnMarkAll(); + count = 0; + + //detection stage + for(unsigned int index = 0 ; index < m.face.size(); ++index ) + { + CMeshO::FacePointer f = &(m.face[index]); float sides[3]; Point3 dummy; + sides[0] = Distance(f->P(0), f->P(1)); sides[1] = Distance(f->P(1), f->P(2)); sides[2] = Distance(f->P(2), f->P(0)); + int i = std::find(sides, sides+3, std::max( std::max(sides[0],sides[1]), sides[2])) - (sides); + if( m.IsMarked(f->V2(i) )) continue; + + if( PSDist(f->P2(i),f->P(i),f->P1(i),dummy)*threshold <= sides[i] ) + { + m.Mark(f->V2(i)); + + int j = Distance(dummy,f->P(i))P1(i))?i:(i+1)%3; + f->P2(i) = f->P(j); m.Mark(f->V(j)); + ++count; ++total; + } + } + + + tri::Clean::RemoveDuplicateVertex(m); + tri::Allocator::CompactFaceVector(m); + tri::Allocator::CompactVertexVector(m); + + + } + while( repeat && count ); + + return total; + } + static bool SelfIntersections(MeshType &m, std::vector &ret) { //assert(FaceType::HasMark()); // Needed by the UG