From 730bbba98bbce3c9983644e02a66fb45c508cdf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 20 Nov 2023 10:03:16 +0100 Subject: [PATCH] add an example with a dummy custom sizing field --- .../Polygon_mesh_processing/CMakeLists.txt | 1 + ...c_remeshing_with_custom_sizing_example.cpp | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 590305c0c8a..38d1bce078b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -51,6 +51,7 @@ create_single_source_cgal_program("match_faces.cpp") create_single_source_cgal_program("cc_compatible_orientations.cpp") create_single_source_cgal_program("hausdorff_distance_remeshing_example.cpp") create_single_source_cgal_program("hausdorff_bounded_error_distance_example.cpp") +create_single_source_cgal_program("isotropic_remeshing_with_custom_sizing_example.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) include(CGAL_Eigen3_support) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp new file mode 100644 index 00000000000..1fc70906f7d --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +// a sizing fied that is increasing the size of edge along the y-axis +// starting at a minimum size at y-max and ending at a maximum size at +// y-min, with a linear interpolation of sizes in between the two extreme +// sizing values +struct My_sizing_field +{ + double min_size, max_size; + double ymin, ymax; + const Mesh& mesh; + + My_sizing_field(double min_size, double max_size, double ymin, double ymax, const Mesh& mesh) + : min_size(min_size) + , max_size(max_size) + , ymin(ymin) + , ymax(ymax) + , mesh(mesh) + {} + + double at(K::Point_3 p) const + { + double y=p.y(); + return CGAL::square( (y-ymin)/(ymax-ymin) * (min_size - max_size) + max_size ); + } + double at(const Mesh::Vertex_index v) const { return at(mesh.point(v)); } + + std::optional is_too_long(const Mesh::Vertex_index va, + const Mesh::Vertex_index vb) const + { + // TODO: no mesh as parameters? + K::Point_3 mp = CGAL::midpoint(mesh.point(va), mesh.point(vb)); + double sql_at = at(mp); + double sql = CGAL::squared_distance(mesh.point(va), mesh.point(vb)); + if (sql > sql_at) + return sql / sql_at; + return std::nullopt; + } + + std::optional is_too_short(const Mesh::Halfedge_index h, + const Mesh&) const + { + K::Point_3 mp = CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + double sql_at = at(mp); + double sql = CGAL::squared_distance(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + if (sql < sql_at) + return sql / sql_at; + return std::nullopt; + } + + K::Point_3 split_placement(const Mesh::Halfedge_index h, + const Mesh&) const + { + return CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + } + + void update(const Mesh::Vertex_index, const Mesh&) {} +}; + + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elk.off"); + + Mesh mesh; + if (!PMP::IO::read_polygon_mesh(filename, mesh) || !CGAL::is_triangle_mesh(mesh)) { + std::cerr << "Not a valid input file." << std::endl; + return 1; + } + + std::cout << "Start remeshing of " << filename + << " (" << num_faces(mesh) << " faces)..." << std::endl; + + CGAL::Bbox_3 bb = PMP::bbox(mesh); + My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax(), mesh); + unsigned int nb_iter = 5; + + PMP::isotropic_remeshing( + faces(mesh), + sizing_field, + mesh, + CGAL::parameters::number_of_iterations(nb_iter) + .number_of_relaxation_steps(3) + ); + + CGAL::IO::write_polygon_mesh("custom_remesh_out.off", mesh, CGAL::parameters::stream_precision(17)); + + std::cout << "Remeshing done." << std::endl; + + return 0; +}