From 54d19e3059db1c92b42a7bdc8d2052d450153c0e Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Thu, 5 Apr 2018 18:43:05 +0200 Subject: [PATCH 1/3] added function to compute mesh boundary length --- vcg/complex/algorithms/stat.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/vcg/complex/algorithms/stat.h b/vcg/complex/algorithms/stat.h index 8b3c8d90..ca1f3de5 100644 --- a/vcg/complex/algorithms/stat.h +++ b/vcg/complex/algorithms/stat.h @@ -212,6 +212,21 @@ public: return area/ScalarType(2.0); } + static ScalarType ComputeBorderLength(MeshType & m) + { + RequireFFAdjacency(m); + ScalarType sum = 0; + tri::UpdateTopology::FaceFace(m); + ForEachFace(m, [&](FaceType &f) { + for (int k=0; k &h, bool selectionOnly = false) // V1.0 { tri::RequirePerVertexQuality(m); From 6011f049fc25711480bccff633870396fbc5ce43 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Thu, 5 Apr 2018 18:43:43 +0200 Subject: [PATCH 2/3] voronoi remesher tweaked --- vcg/complex/algorithms/voronoi_remesher.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/vcg/complex/algorithms/voronoi_remesher.h b/vcg/complex/algorithms/voronoi_remesher.h index 54541533..f2521b26 100644 --- a/vcg/complex/algorithms/voronoi_remesher.h +++ b/vcg/complex/algorithms/voronoi_remesher.h @@ -133,7 +133,7 @@ protected: } public: - static const int VoroRelaxationStep = 20; + static const int VoroRelaxationStep = 30; /// /// \brief Remesh the main function that remeshes a mesh preserving creases. @@ -355,7 +355,7 @@ protected: // refine to obtain a base mesh VoronoiProcessingParameter vpp; - vpp.refinementRatio = 4.0f; + vpp.refinementRatio = 5.0f; Voronoi::PreprocessForVoronoi(baseMesh, samplingRadius, vpp); // Poisson sampling preserving border @@ -372,7 +372,15 @@ protected: // Montecarlo oversampling Mesh montecarloMesh; - int poissonCount = SurfaceSampler::ComputePoissonSampleNum(original, samplingRadius) * 0.7; +// const int poissonCount = SurfaceSampler::ComputePoissonSampleNum(original, samplingRadius)/* * 0.7*/; + int poissonCount = 0; + { + const ScalarType meshArea = Stat::ComputeMeshArea(original); + const ScalarType meshBoundary = Stat::ComputeBorderLength(original); + const double factor = math::Sqrt(3)/2; + const ScalarType areaPerSample = samplingRadius*samplingRadius * factor; + poissonCount = meshArea / areaPerSample - meshBoundary * samplingRadius * factor * 0.5; // totalArea / (r^2 * sqrt(3)/2) - (totalBoundary * r * sqrt(3)/4) + } // std::cout << "poisson Count: " << poissonCount << std::endl; if (poissonCount <= 0) @@ -386,7 +394,7 @@ protected: else { // Montecarlo poisson sampling - SurfaceSampler::MontecarloPoisson(original, mps, poissonCount * 20); + SurfaceSampler::MontecarloPoisson(original, mps, poissonCount * 40); BuildMeshFromCoordVector(montecarloMesh,sampleVec); #ifdef DEBUG_VORO @@ -421,6 +429,7 @@ protected: vpp.seedPerturbationProbability = 0.0f; Voronoi::RestrictedVoronoiRelaxing(baseMesh, seedPointVec, seedFixedVec, VoroRelaxationStep, vpp); + #ifdef DEBUG_VORO BuildMeshFromCoordVector(poissonMesh,seedPointVec); io::ExporterPLY::Save(poissonMesh, QString("relaxedMesh_%1.ply").arg(idx).toStdString().c_str()); From 6a31fa64baa844fff902f221cff187e59dde1f58 Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 6 Apr 2018 14:03:39 +1000 Subject: [PATCH 3/3] Refactored ReprojectBorder and added MergeAlongEdges Function --- vcg/complex/algorithms/polygonal_algorithms.h | 218 +++++++++++++++--- 1 file changed, 190 insertions(+), 28 deletions(-) diff --git a/vcg/complex/algorithms/polygonal_algorithms.h b/vcg/complex/algorithms/polygonal_algorithms.h index e699cd40..a839af28 100644 --- a/vcg/complex/algorithms/polygonal_algorithms.h +++ b/vcg/complex/algorithms/polygonal_algorithms.h @@ -471,6 +471,41 @@ public: } } + template + static void ReprojectBorder(PolyMeshType &poly_m, + TriMeshType &tri_mesh, + bool FixS=true) + { + //then reproject on border + for (size_t i=0;i::max(); + CoordType closPos; + for (size_t j=0;j Seg(P0,P1); + ScalarType testD; + CoordType closTest; + vcg::SegmentPointDistance(Seg,testPos,closTest,testD); + if (testD>minD)continue; + minD=testD; + closPos=closTest; + } + poly_m.vert[i].P()=closPos; + } + } + /*! \brief This function smooth the borders of the polygonal mesh and reproject back to the triangolar one * except the vertices that are considered as corner wrt the angleDeg threshold */ @@ -507,33 +542,34 @@ public: AvVert[i]*(1-Damp); } - //then reproject on border - for (size_t i=0;i::max(); - CoordType closPos; - for (size_t j=0;j::max(); +// CoordType closPos; +// for (size_t j=0;j Seg(P0,P1); - ScalarType testD; - CoordType closTest; - vcg::SegmentPointDistance(Seg,testPos,closTest,testD); - if (testD>minD)continue; - minD=testD; - closPos=closTest; - } - poly_m.vert[i].P()=closPos; - } +// CoordType P0,P1; +// P0.Import(tri_mesh.face[j].cP0(k)); +// P1.Import(tri_mesh.face[j].cP1(k)); +// vcg::Segment3 Seg(P0,P1); +// ScalarType testD; +// CoordType closTest; +// vcg::SegmentPointDistance(Seg,testPos,closTest,testD); +// if (testD>minD)continue; +// minD=testD; +// closPos=closTest; +// } +// poly_m.vert[i].P()=closPos; +// } + ReprojectBorder(poly_m,tri_mesh); } } @@ -797,6 +833,47 @@ public: vcg::PolygonalAlgorithm::SmoothReprojectPCA(poly_m,GuideSurf,relaxStep,fixIrr,Damp,SharpDeg,WeightByQuality); } + static void Reproject(PolyMeshType &poly_m, + PolyMeshType &target) + { + vcg::tri::UpdateTopology::FaceFace(poly_m); + vcg::tri::UpdateFlags::VertexBorderFromFaceAdj(poly_m); + + //transform into triangular + TempMesh GuideSurf; + //vcg::tri::PolygonSupport:(GuideSurf,poly_m); + TriangulateToTriMesh(target,GuideSurf); + vcg::tri::UpdateBounding::Box(GuideSurf); + vcg::tri::UpdateNormal::PerVertexNormalizedPerFace(GuideSurf); + vcg::tri::UpdateTopology::FaceFace(GuideSurf); + vcg::tri::UpdateFlags::FaceBorderFromFF(GuideSurf); + + //initialize the grid + typedef typename TempMesh::FaceType FaceType; + typedef vcg::GridStaticPtr TriMeshGrid; + TriMeshGrid grid; + grid.Set(GuideSurf.face.begin(),GuideSurf.face.end()); + + ScalarType MaxD=GuideSurf.bbox.Diag(); + + for (size_t i=0;i=0); + assert(StartI NewV; + for (size_t i=0;iVN(); + ReorderFaceVert(*f1,FirstV1); + + std::vector NewV; + for (size_t i=0;i<(f.VN()-1);i++) + NewV.push_back(f.V(i)); + + for (size_t i=0;i<(f1->VN()-1);i++) + NewV.push_back(f1->V(i)); + + f.Dealloc(); + f.Alloc(NewV.size()); + for (size_t i=0;i::DeleteFace(poly_m,*f1); + } + + static void MergeAlongEdges(PolyMeshType &poly_m, + const std::vector &PolyF, + const std::vector &EdgeI) + { + //create a table with all edges that have to be merged + std::set > NeedMerge; + for (size_t i=0;iP0(EdgeI[i]); + CoordType P1=PolyF[i]->P1(EdgeI[i]); + std::pair key(std::min(P0,P1),std::max(P0,P1)); + NeedMerge.insert(key); + } + + //then cycle and collapse + do{ + for (size_t i=0;i key(std::min(P0,P1),std::max(P0,P1)); + if (NeedMerge.count(key)==0)continue; + + //do the merge + MergeAlongEdge(poly_m,poly_m.face[i],j); + //remove it + NeedMerge.erase(key); + break; + } + } + vcg::tri::Allocator::CompactEveryVector(poly_m); + }while (!NeedMerge.empty()); + } static void Triangulate(PolyMeshType &poly_m) {