From 7326fb52ceea2c98462000cb6170e28ee1d8e0be Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Tue, 16 May 2023 22:56:41 +0200 Subject: [PATCH] Add initial preparations for adaptive sizing field Add Adaptive_sizing_field header with edge min and max limits, and tolerance Adjust the example --- ...sotropic_remeshing_with_sizing_example.cpp | 10 +- .../Adaptive_sizing_field.h | 112 ++++++++++++++++++ .../CGAL/Polygon_mesh_processing/remesh.h | 18 +++ 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/Adaptive_sizing_field.h diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_sizing_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_sizing_example.cpp index fa5dc55d789..96325e6d861 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_sizing_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_sizing_example.cpp @@ -11,7 +11,7 @@ namespace PMP = CGAL::Polygon_mesh_processing; int main(int argc, char* argv[]) { - const char* filename = (argc > 1) ? argv[1] : "data/pig.off"; + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/pig.off"); std::ifstream input(filename); Mesh mesh; @@ -20,7 +20,8 @@ int main(int argc, char* argv[]) return 1; } - double target_edge_length = 0.04; + const std::pair edge_min_max{0.1, 0.4}; + const double tol = 0.1; unsigned int nb_iter = 3; std::cout << "Start remeshing of " << filename @@ -28,11 +29,14 @@ int main(int argc, char* argv[]) PMP::isotropic_remeshing( faces(mesh), - target_edge_length, + edge_min_max, + tol, mesh, PMP::parameters::number_of_iterations(nb_iter) ); + CGAL::IO::write_polygon_mesh("out.off", mesh, CGAL::parameters::stream_precision(17)); + std::cout << "Remeshing done." << std::endl; return 0; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/Adaptive_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/Adaptive_sizing_field.h new file mode 100644 index 00000000000..6b48181388e --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/Adaptive_sizing_field.h @@ -0,0 +1,112 @@ +// Copyright (c) 2020 GeometryFactory (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Jane Tournois + +#ifndef CGAL_PMP_REMESHING_ADAPTIVE_SIZING_FIELD_H +#define CGAL_PMP_REMESHING_ADAPTIVE_SIZING_FIELD_H + +#include + +#include + +#include + +namespace CGAL +{ +namespace Polygon_mesh_processing +{ +template +class Adaptive_sizing_field : public CGAL::Sizing_field +{ +private: + typedef CGAL::Sizing_field Base; + +public: + typedef typename Base::FT FT; + typedef typename Base::Point_3 Point_3; + typedef typename Base::halfedge_descriptor halfedge_descriptor; + typedef typename Base::vertex_descriptor vertex_descriptor; + + Adaptive_sizing_field(const std::pair& edge_len_min_max + , const FT& tolerance + , const PolygonMesh& pmesh) + : m_sq_short( CGAL::square(edge_len_min_max.first)) + , m_sq_long( CGAL::square(edge_len_min_max.second)) + , tol(tolerance) + , m_pmesh(pmesh) + { + // calculate and store curvature and sizing field here in constructor? + // todo what about updating it? + } + +private: + FT sqlength(const vertex_descriptor& va, + const vertex_descriptor& vb) const + { + typename boost::property_map::const_type + vpmap = get(CGAL::vertex_point, m_pmesh); + return FT(CGAL::squared_distance(get(vpmap, va), get(vpmap, vb))); + } + + FT sqlength(const halfedge_descriptor& h) const + { + return sqlength(target(h, m_pmesh), source(h, m_pmesh)); + } + +public: + boost::optional is_too_long(const halfedge_descriptor& h) const + { + const FT sqlen = sqlength(h); + if(sqlen > m_sq_long) + return sqlen; + else + return boost::none; + } + + boost::optional is_too_long(const vertex_descriptor& va, + const vertex_descriptor& vb) const + { + const FT sqlen = sqlength(va, vb); + if (sqlen > m_sq_long) + return sqlen; + else + return boost::none; + } + + boost::optional is_too_short(const halfedge_descriptor& h) const + { + const FT sqlen = sqlength(h); + if (sqlen < m_sq_long) + return sqlen; + else + return boost::none; + } + + virtual Point_3 split_placement(const halfedge_descriptor& h) const + { + typename boost::property_map::const_type + vpmap = get(CGAL::vertex_point, m_pmesh); + return CGAL::midpoint(get(vpmap, target(h, m_pmesh)), + get(vpmap, source(h, m_pmesh))); + } + +private: + FT m_sq_short; + FT m_sq_long; + FT tol; + const PolygonMesh& m_pmesh; + //todo add property map containing sizing field form m_pmesh here +}; + +}//end namespace Polygon_mesh_processing +}//end namespace CGAL + +#endif //CGAL_PMP_REMESHING_ADAPTIVE_SIZING_FIELD_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h index 54c99b2de43..4ba686e9e19 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -218,6 +219,23 @@ void isotropic_remeshing(const FaceRange& faces np); } +template +void isotropic_remeshing(const FaceRange& faces + , const std::pair& edge_len_min_max //todo add defaults? + , const double& tolerance //todo add defaults? + , PolygonMesh& pmesh + , const NamedParameters& np = parameters::default_values()) +{ + typedef Adaptive_sizing_field Adaptive_sizing; + isotropic_remeshing( + faces, + Adaptive_sizing(edge_len_min_max, tolerance, pmesh), + pmesh, + np); +} + template