From 980cb959bc52aeb0c897c5a774bc8c86e913fa05 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Mon, 14 Oct 2024 17:53:20 +0200 Subject: [PATCH] Added Catmull-Clark Subdivision surfaces --- .../filter_meshing/meshfilter.cpp | 33 +++++++++++-------- src/vcglib | 2 +- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/meshlabplugins/filter_meshing/meshfilter.cpp b/src/meshlabplugins/filter_meshing/meshfilter.cpp index 2a95ab4cf..985eb8a8b 100644 --- a/src/meshlabplugins/filter_meshing/meshfilter.cpp +++ b/src/meshlabplugins/filter_meshing/meshfilter.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include "quadric_simp.h" @@ -358,11 +359,11 @@ QString ExtraMeshFilterPlugin::filterInfo(ActionIDType filterID) const case FP_LOOP_SS : return tr("Apply Loop's Subdivision Surface algorithm. It is an approximant refinement method and it works for every triangle and has rules for extraordinary vertices.
"); case FP_BUTTERFLY_SS : return tr("Apply Butterfly Subdivision Surface algorithm. It is an interpolated refinement method, defined on arbitrary triangular meshes. The scheme is known to be C1 but not C2 on regular meshes
"); case FP_MIDPOINT : return tr("Apply a plain subdivision scheme where every edge is split on its midpoint. Useful to uniformly refine a mesh substituting each triangle with four smaller triangles."); - case FP_REFINE_CATMULL : return tr("Apply the Catmull-Clark Subdivision Surfaces. Note that position of the new vertices is simply linearly interpolated. " + case FP_REFINE_CATMULL : return tr("Apply a number of iteration of the classical Catmull-Clark Subdivision Surfaces. " "If the mesh is triangle based (no faux edges) it generates a quad mesh, otherwise it honores it the faux-edge bits"); case FP_REFINE_DOOSABIN : return tr("Apply the DooSabin Subdivision Surfaces. It is a Dual approximating refinement scheme that creates a new face for each vertex, edge and face. On a pure quad mesh it will add non quad face for each extraordinarhy vertex in the mesh (e.g. in a cube it will add a triangular face for each corner. On the other hand after a refinement step all the vertices will have degree 4."); case FP_REFINE_HALF_CATMULL : return tr("Convert a tri mesh into a quad mesh by applying a 4-8 subdivision scheme." - "It introduces less overhead than the plain Catmull-Clark Subdivision Surfaces" + "It introduces less overhead than the plain Catmull-Clark Subdivision Surfaces, and applying two step of this procedure generates the same connectivity of the Catmull-Clark subdivision approach." "(it adds only a single vertex for each triangle instead of four)." "
See:
" "4-8 Subdivision" @@ -537,6 +538,10 @@ RichParameterList ExtraMeshFilterPlugin::initParameterList(const QAction * actio parlst.addParam(RichInt("Iterations", 2, "Iterations", "Number of times the model is subdivided.")); break; + case FP_REFINE_CATMULL: + parlst.addParam(RichInt("Iterations", 2, "Iterations", "Number of times the model is subdivided.")); + break; + case FP_CLUSTERING: // TODO implement selection @@ -1661,17 +1666,19 @@ std::map ExtraMeshFilterPlugin::applyFilter( case FP_REFINE_CATMULL : { - if (!vcg::tri::BitQuadCreation::IsTriQuadOnly(m.cm)) - { - throw MLException("To be applied filter " + filter->text() + " requires a mesh with only triangular and/or quad faces."); - } - // in practice it is just a simple double application of the FP_REFINE_HALF_CATMULL. - m.updateDataMask(MeshModel::MM_FACEQUALITY | MeshModel::MM_FACEFACETOPO); - tri::BitQuadCreation::MakePureByRefine(m.cm); - tri::BitQuadCreation::MakePureByRefine(m.cm); - tri::UpdateNormal::PerBitQuadFaceNormalized(m.cm); - m.clearDataMask(MeshModel::MM_FACEFACETOPO); - m.updateDataMask(MeshModel::MM_POLYGONAL); + PMesh baseIn, refinedOut; + int iteration = par.getInt("Iterations"); + m.updateDataMask(MeshModel::MM_FACEFACETOPO); + tri::PolygonSupport::ImportFromTriMesh(baseIn,m.cm); + tri::Clean::RemoveUnreferencedVertex(baseIn); + tri::Allocator::CompactEveryVector(baseIn); + tri::CatmullClark::Refine(baseIn, refinedOut,iteration); + m.cm.Clear(); + tri::PolygonSupport::ImportFromPolyMesh(m.cm,refinedOut); + m.updateDataMask(MeshModel::MM_FACEFACETOPO); + tri::UpdateTopology::FaceFace(m.cm); + tri::UpdateNormal::PerBitPolygonFaceNormalized(m.cm); + tri::UpdateNormal::PerVertexFromCurrentFaceNormal(m.cm); } break; case FP_REFINE_DOOSABIN : diff --git a/src/vcglib b/src/vcglib index fed8698c5..390cd5b9d 160000 --- a/src/vcglib +++ b/src/vcglib @@ -1 +1 @@ -Subproject commit fed8698c5706a3ebef0fe6d29bbb8cc1577640d9 +Subproject commit 390cd5b9d1f9c82b26c1b6616bc78ccd72a227f6