From 7f517386f039770c21088840c2220d9c5f1b769f Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Thu, 2 Jan 2020 14:31:04 +0930 Subject: [PATCH] Optimize remesh Introduce isotropic remesh before QuadriFlow This will unify the edge length of all the faces before the mesh got subdived in QuadriFlow --- src/remesher.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ src/remesher.h | 1 + 2 files changed, 52 insertions(+) diff --git a/src/remesher.cpp b/src/remesher.cpp index 84e5feb1..1253d4b6 100644 --- a/src/remesher.cpp +++ b/src/remesher.cpp @@ -6,7 +6,31 @@ #ifdef WITH_CUDA #include #endif +#include +#include +#include +#include +#include +#include #include "remesher.h" +#include "booleanmesh.h" + +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; +namespace PMP = CGAL::Polygon_mesh_processing; + +struct halfedge2edge +{ + halfedge2edge(const CgalMesh& m, std::vector& edges) + : m_mesh(m), m_edges(edges) + {} + void operator()(const halfedge_descriptor& h) const + { + m_edges.push_back(edge(h, m_mesh)); + } + const CgalMesh& m_mesh; + std::vector& m_edges; +}; using namespace qflow; @@ -36,6 +60,31 @@ const std::vector> &Remesher::getRemeshedVertexSources() return m_remeshedVertexSources; } +void Remesher::isotropicRemesh(float targetEdgeLength, unsigned int iterationNum) +{ + CgalMesh *mesh = buildCgalMesh(m_vertices, m_triangles); + if (nullptr == mesh) + return; + + std::vector border; + PMP::border_halfedges(faces(*mesh), + *mesh, + boost::make_function_output_iterator(halfedge2edge(*mesh, border))); + PMP::split_long_edges(border, targetEdgeLength, *mesh); + + PMP::isotropic_remeshing(faces(*mesh), + targetEdgeLength, + *mesh, + PMP::parameters::number_of_iterations(iterationNum) + .protect_constraints(true)); + + m_vertices.clear(); + m_triangles.clear(); + fetchFromCgalMesh(mesh, m_vertices, m_triangles); + + delete mesh; +} + void Remesher::remesh() { Parametrizer field; @@ -44,6 +93,8 @@ void Remesher::remesh() cudaFree(0); #endif + isotropicRemesh(); + field.V.resize(3, m_vertices.size()); field.F.resize(3, m_triangles.size()); for (decltype(m_vertices.size()) i = 0; i < m_vertices.size(); i++) { diff --git a/src/remesher.h b/src/remesher.h index 7aa3a720..e1585567 100644 --- a/src/remesher.h +++ b/src/remesher.h @@ -27,6 +27,7 @@ private: std::vector> m_nodes; std::vector> m_sourceIds; void resolveSources(); + void isotropicRemesh(float targetEdgeLength=0.021, unsigned int iterationNum=3); }; #endif