From 992ab0ca2e36db59097480be65ebc1f0710d2139 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Mon, 11 Sep 2017 14:47:32 +0200 Subject: [PATCH] edgemesh uniform sampler fixed + voronoi remesher improved --- .../trimesh_voronoi_remesh.cpp | 2 +- vcg/complex/algorithms/point_sampling.h | 55 +++++++++++++++---- vcg/complex/algorithms/voronoi_remesher.h | 24 +++++--- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/apps/sample/trimesh_voronoi_remesh/trimesh_voronoi_remesh.cpp b/apps/sample/trimesh_voronoi_remesh/trimesh_voronoi_remesh.cpp index 573d014d..10dfcde4 100644 --- a/apps/sample/trimesh_voronoi_remesh/trimesh_voronoi_remesh.cpp +++ b/apps/sample/trimesh_voronoi_remesh/trimesh_voronoi_remesh.cpp @@ -78,7 +78,7 @@ int main( int argc, char **argv ) } catch (exception &) {} } std::cout << "Remeshing using sampling radius: " << samplingRadius << std::endl; - auto remeshed = Remesher::Remesh(startMesh, samplingRadius, 50.0, 0.0); + auto remeshed = Remesher::Remesh(startMesh, samplingRadius, 70.0); tri::io::ExporterPLY::Save(*remeshed,"Full.ply",tri::io::Mask::IOM_VERTCOLOR|tri::io::Mask::IOM_WEDGTEXCOORD ); diff --git a/vcg/complex/algorithms/point_sampling.h b/vcg/complex/algorithms/point_sampling.h index fb88adbb..a0712c9e 100644 --- a/vcg/complex/algorithms/point_sampling.h +++ b/vcg/complex/algorithms/point_sampling.h @@ -46,6 +46,7 @@ sampling strategies (montecarlo, stratified etc). #include #include #include + namespace vcg { namespace tri @@ -769,14 +770,14 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c tri::RequirePerVertexFlags(m); tri::UpdateTopology::EdgeEdge(m); tri::UpdateFlags::EdgeClearV(m); - tri::MeshAssert::EEOneManifold(m); + tri::MeshAssert::EEOneManifold(m); + for (EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei) { if (!ei->IsV()) { edge::Pos ep(&*ei,0); - edge::Pos startep = ep; - VertexPointer startVertex = 0; + edge::Pos startep = ep; do // first loop to search a boundary component. { ep.NextE(); @@ -786,10 +787,33 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c if (!ep.IsBorder()) { // it's a loop - startVertex = ep.V(); + assert(ep == startep); + + // to keep the uniform resampling order-independent: + // 1) start from the 'lowest' point... + edge::Pos altEp = ep; + altEp.NextE(); + while (altEp != startep) { + if (altEp.V()->cP() < ep.V()->cP()) + { + ep = altEp; + } + altEp.NextE(); + } + + // 2) ... with consistent direction + const auto dir0 = ep.VFlip()->cP() - ep.V()->cP(); + ep.FlipE(); + const auto dir1 = ep.VFlip()->cP() - ep.V()->cP(); + if (dir0 < dir1) + { + ep.FlipE(); + } } else { + // not a loop + // to keep the uniform resampling order-independent // start from the border with 'lowest' point edge::Pos altEp = ep; @@ -805,17 +829,22 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c ScalarType totalLen = 0; ep.FlipV(); - // second loop to compute length of the chain. + // second loop to compute the length of the chain. do { ep.E()->SetV(); totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP()); ep.NextE(); - } while (!ep.IsBorder() && ep.V() != startVertex); - ep.E()->SetV(); - totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP()); + } while (!ep.E()->IsV() && !ep.IsBorder()); + if (ep.IsBorder()) + { + ep.E()->SetV(); + totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP()); + } - // Third loop actually perform the sampling. + VertexPointer startVertex = ep.V(); + + // Third loop actually performs the sampling. int sampleNum = conservative ? floor(totalLen / radius) : ceil(totalLen / radius); ScalarType sampleDist = totalLen / sampleNum; @@ -824,11 +853,11 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c ScalarType curLen = 0; int sampleCnt = 1; ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0); - do - { + + do { ep.NextE(); assert(ep.E()->IsV()); - ScalarType edgeLen = Distance(ep.V()->cP(), ep.VFlip()->cP()); + ScalarType edgeLen = Distance(ep.VFlip()->cP(), ep.V()->cP()); ScalarType d0 = curLen; ScalarType d1 = d0 + edgeLen; @@ -843,7 +872,9 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c } while(!ep.IsBorder() && ep.V() != startVertex); if(ep.V() != startVertex) + { ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0); + } } } } diff --git a/vcg/complex/algorithms/voronoi_remesher.h b/vcg/complex/algorithms/voronoi_remesher.h index 5068fa39..54541533 100644 --- a/vcg/complex/algorithms/voronoi_remesher.h +++ b/vcg/complex/algorithms/voronoi_remesher.h @@ -265,6 +265,8 @@ protected: // QElapsedTimer timer; // timer.start(); + (void)idx; + RequireCompactness(original); RequirePerFaceFlags(original); @@ -295,9 +297,10 @@ protected: } } const int manifoldSplits = vcg::tri::Clean::SplitSelectedVertexOnEdgeMesh(em); -// std::cout << manifoldSplits << " non-manifold splits" << std::endl; + (void)manifoldSplits; #ifdef DEBUG_VORO + std::cout << manifoldSplits << " non-manifold splits" << std::endl; io::ExporterOBJ::Save(em, QString("edgeMesh_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX); #endif @@ -309,11 +312,13 @@ protected: UpdateFlags::VertexClearV(em); Clean::SelectCreaseVertexOnEdgeMesh(em, vcg::math::ToRad(borderCreaseAngleDeg)); const int splits = Clean::SplitSelectedVertexOnEdgeMesh(em); -// std::cout << splits << " splits" << std::endl; - } + (void)splits; + #ifdef DEBUG_VORO - io::ExporterOBJ::Save(em, QString("edgeMesh_split_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX); + std::cout << splits << " splits" << std::endl; + io::ExporterOBJ::Save(em, QString("edgeMesh_split_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX); #endif + } // Samples vector std::vector borderSamples; @@ -321,7 +326,7 @@ protected: // uniform edge sampling UpdateTopology::EdgeEdge(em); - SurfaceSampling::EdgeMeshUniform(em, ps, samplingRadius, true); + SurfaceSampling::EdgeMeshUniform(em, ps, samplingRadius, false); BuildMeshFromCoordVector(poissonEdgeMesh, borderSamples); UpdateBounding::Box(poissonEdgeMesh); @@ -538,9 +543,12 @@ protected: if (!vit->IsD() && vit->IsB()) borderPts.push_back(vit->cP()); } - BuildMeshFromCoordVector(borderMesh,borderPts); - borderMesh.bbox = m.bbox; - borderHG.Set(borderMesh.vert.begin(), borderMesh.vert.end(), bbox); + if (!borderPts.empty()) + { + BuildMeshFromCoordVector(borderMesh,borderPts); + borderMesh.bbox = m.bbox; + borderHG.Set(borderMesh.vert.begin(), borderMesh.vert.end(), bbox); + } } const ScalarType dist_upper_bound=samplingRadius*4;