From 83c88da327052ef7ca3259eb75a534474e592d5c Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Mar 2024 16:28:46 +0100 Subject: [PATCH 01/10] move clear_cells_and_facets_from_c3t3() inside the constructor of Mesher_3 to make sure the input c3t3 is fully clean before starting refinement --- Mesh_3/include/CGAL/Mesh_3/Mesher_3.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index 185efe6229c..a4374383b5b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -404,6 +404,13 @@ Mesher_3::Mesher_3(C3T3& c3t3, cells_mesher_.set_stop_pointer(stop_ptr); facets_mesher_.set_stop_pointer(stop_ptr); #endif + + // First surface mesh could modify c3t3 without notifying cells_mesher + // So we have to ensure that no old cell will be left in c3t3 + // Second, the c3t3 object could have been corrupted since the last call + // to `refine_mesh`, for example by inserting new vertices in the + // triangulation. + r_c3t3_.clear_cells_and_facets_from_c3t3(); } @@ -424,13 +431,6 @@ refine_mesh(std::string dump_after_refine_surface_prefix) auto refine_volume_mesh_task_handle = __itt_string_handle_create("Mesher_3 refine volume mesh"); #endif // CGAL_MESH_3_USE_INTEL_ITT - // First surface mesh could modify c3t3 without notifying cells_mesher - // So we have to ensure that no old cell will be left in c3t3 - // Second, the c3t3 object could have been corrupted since the last call - // to `refine_mesh`, for example by inserting new vertices in the - // triangulation. - r_c3t3_.clear_cells_and_facets_from_c3t3(); - const Triangulation& r_tr = r_c3t3_.triangulation(); CGAL_USE(r_tr); From d085faba0cfc1cf19b8376542550c829912e9143 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Mar 2024 16:31:11 +0100 Subject: [PATCH 02/10] remove duplicate --- Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index 8374a106b62..b7d489a096b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -289,7 +289,6 @@ public: return Container_::no_longer_element_to_refine_impl(); } - // Gets the point to insert from the element to refine /// Gets the point to insert from the element to refine Bare_point refinement_point_impl(const Facet& facet) const { From 4e81649dd99d2e98dce10f9838fd08185c345ef4 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Mar 2024 16:32:29 +0100 Subject: [PATCH 03/10] use set_surface_only() to be more explicit --- Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h index 8c7e57e1dd9..efb5c975470 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h @@ -296,7 +296,7 @@ public: } tree_.build(); } - bounding_tree_ = 0; + set_surface_only(); } /// Destructor From 80fd8759dd59299f0237fea1ed2110f957c0a096 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Mar 2024 16:40:28 +0100 Subject: [PATCH 04/10] avoid insertion of points inside protecting balls, during initialization step --- Mesh_3/include/CGAL/make_mesh_3.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 79277f1643f..840daf29d07 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -45,9 +45,11 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; - typedef std::vector > Initial_points_vector; + typedef typename std::pair PI; + typedef std::vector Initial_points_vector; typedef typename Initial_points_vector::iterator Ipv_iterator; typedef typename C3T3::Vertex_handle Vertex_handle; + typedef CGAL::Mesh_3::Triangulation_helpers Th; // Mesh initialization : get some points and add them to the mesh Initial_points_vector initial_points; @@ -61,17 +63,19 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); // Insert points and set their index and dimension - for ( Ipv_iterator it = initial_points.begin() ; - it != initial_points.end() ; - ++it ) + const Vertex_handle vhint = c3t3.triangulation().finite_vertices_begin(); + for (const PI& pi : initial_points) { - Vertex_handle v = c3t3.triangulation().insert(cwp(it->first)); + if(Th().inside_protecting_balls(c3t3.triangulation(), vhint, pi.first)) + continue; + + Vertex_handle v = c3t3.triangulation().insert(cwp(pi.first)); // v could be null if point is hidden if ( v != Vertex_handle() ) { c3t3.set_dimension(v,2); // by construction, points are on surface - c3t3.set_index(v,it->second); + c3t3.set_index(v, pi.second); } } } From 18dd164769cc38887f7036b5c0cb0f824bbee279 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Mar 2024 16:48:05 +0100 Subject: [PATCH 05/10] fix clear_cells_and_facets_from_c3t3() we actually need to clear C3T3 from all facets and cells, including the infinite ones. Indeed, extra point insertions during (e.g.) the initialization step may have made invalid the metadata in all cells, including the infinite ones --- .../CGAL/Mesh_complex_3_in_triangulation_3.h | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h index 643de3ff7da..f805e5e7f09 100644 --- a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -1423,28 +1423,27 @@ public: } } - void clear_cells_and_facets_from_c3t3() { - for (typename Tr::Finite_cells_iterator - cit = this->triangulation().finite_cells_begin(), - end = this->triangulation().finite_cells_end(); - cit != end; ++cit) + void clear_cells_and_facets_from_c3t3() + { + //clear cells + for (Cell_handle cit : this->triangulation().all_cell_handles()) { set_subdomain_index(cit, Subdomain_index()); } this->number_of_cells_ = 0; - for (typename Tr::Finite_facets_iterator - fit = this->triangulation().finite_facets_begin(), - end = this->triangulation().finite_facets_end(); - fit != end; ++fit) + + //clear facets + for (const Facet& facet : this->triangulation().all_facets()) { - Facet facet = *fit; set_surface_patch_index(facet.first, facet.second, Surface_patch_index()); if (this->triangulation().dimension() > 2) { - Facet mirror = tr_.mirror_facet(facet); + const Facet& mirror = tr_.mirror_facet(facet); set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index()); } } this->number_of_facets_ = 0; + + //clear manifold info clear_manifold_info(); } From 5b004ffbe617ceefbc2a0426cf112c37e4b10eb0 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Mar 2024 17:27:47 +0100 Subject: [PATCH 06/10] add a test for one_step() loop with features on tiny data --- Data/data/meshes/halfcube.off | 13 +++ Mesh_3/test/Mesh_3/CMakeLists.txt | 2 + ...st_meshing_with_one_step_with_features.cpp | 86 +++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 Data/data/meshes/halfcube.off create mode 100644 Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp diff --git a/Data/data/meshes/halfcube.off b/Data/data/meshes/halfcube.off new file mode 100644 index 00000000000..4c9a166bc42 --- /dev/null +++ b/Data/data/meshes/halfcube.off @@ -0,0 +1,13 @@ +OFF +5 4 0 + +-1 -1 1 +-1 1 1 +1 -1 -1 +-1 1 -1 +-1 -1 -1 +3 0 4 2 +3 2 4 3 +3 4 0 1 +3 1 3 4 + diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 2a8e19e1c38..37e41ec079a 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -53,6 +53,7 @@ create_single_source_cgal_program( "test_meshing_without_features_determinism.cp create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" ) create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" ) create_single_source_cgal_program( "test_meshing_with_one_step.cpp" ) +create_single_source_cgal_program( "test_meshing_with_one_step_with_features.cpp" ) create_single_source_cgal_program( "test_mesh_cell_base_3.cpp") create_single_source_cgal_program( "test_min_edge_length.cpp") @@ -85,6 +86,7 @@ foreach(target test_mesh_polyhedral_domain_with_features_deprecated test_mesh_cell_base_3 test_meshing_with_one_step + test_meshing_with_one_step_with_features test_min_edge_length test_min_size_criteria ) diff --git a/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp new file mode 100644 index 00000000000..7a0935c474e --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp @@ -0,0 +1,86 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Polyhedron; +typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; + +typedef CGAL::Sequential_tag Concurrency_tag; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; + +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +typedef CGAL::Mesh_3::Mesher_3 Mesher; + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +int main(int argc, char*argv[]) +{ + const std::string fname = CGAL::data_file_path("meshes/halfcube.off"); + // Create input polyhedron + Polyhedron polyhedron; + std::ifstream input(fname); + input >> polyhedron; + if(input.fail()){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } + input.close(); + + if (!CGAL::is_triangle_mesh(polyhedron)){ + std::cerr << "Input geometry is not triangulated." << std::endl; + return EXIT_FAILURE; + } + + // Create domain + + std::vector polyhedra; + polyhedra.push_back(&polyhedron); + + Mesh_domain domain(polyhedra.begin(), polyhedra.end()); + domain.detect_features(); + + // Mesh criteria (no cell_size set) + Mesh_criteria criteria(facet_angle = 25, + facet_size = 0.17, + facet_distance = 0.017, + edge_size = 0.17); + + // Mesh generation + namespace p = CGAL::parameters; + C3t3 c3t3; + CGAL::Mesh_3::internal::C3t3_initializer()(c3t3, domain, criteria, true); + + Mesher mesher(c3t3, domain, criteria, CGAL::FACET_VERTICES_ON_SURFACE); + mesher.initialize(); + mesher.display_number_of_bad_elements(); + while ( ! mesher.is_algorithm_done() ) mesher.one_step(); + assert(c3t3.triangulation().number_of_vertices() > 200); + + // Output + mesher.display_number_of_bad_elements(); + + return EXIT_SUCCESS; +} From 44e176b88a520b8fdf44ad9eab06d3c58e5fa3ee Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 21 Mar 2024 16:13:30 +0100 Subject: [PATCH 07/10] unused typedef Co-authored-by: Sebastien Loriot --- Mesh_3/include/CGAL/make_mesh_3.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 840daf29d07..942e207458d 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -47,7 +47,6 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, typedef typename MeshDomain::Index Index; typedef typename std::pair PI; typedef std::vector Initial_points_vector; - typedef typename Initial_points_vector::iterator Ipv_iterator; typedef typename C3T3::Vertex_handle Vertex_handle; typedef CGAL::Mesh_3::Triangulation_helpers Th; From 644d6493ebfe53d084ea26959c146f9c213015f5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 21 Mar 2024 16:33:26 +0100 Subject: [PATCH 08/10] nearest_power_vertex() does not work on an empty triangulation --- Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h | 7 ++++++- Mesh_3/include/CGAL/make_mesh_3.h | 3 +-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h index 6459aaeb047..c3b0b3ac034 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h @@ -382,11 +382,16 @@ inside_protecting_balls(const Tr& tr, const Vertex_handle v, const Bare_point& p) const { + if(tr.number_of_vertices() == 0) + return false; + typename Gt::Compare_weighted_squared_radius_3 cwsr = tr.geom_traits().compare_weighted_squared_radius_3_object(); - Vertex_handle nv = tr.nearest_power_vertex(p, v->cell()); + Cell_handle hint = (v == Vertex_handle()) ? Cell_handle() : v->cell(); + Vertex_handle nv = tr.nearest_power_vertex(p, hint); const Point& nvwp = tr.point(nv); + if(cwsr(nvwp, FT(0)) == CGAL::SMALLER) { typename Tr::Geom_traits::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 942e207458d..68d6198cbbb 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -62,10 +62,9 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); // Insert points and set their index and dimension - const Vertex_handle vhint = c3t3.triangulation().finite_vertices_begin(); for (const PI& pi : initial_points) { - if(Th().inside_protecting_balls(c3t3.triangulation(), vhint, pi.first)) + if(Th().inside_protecting_balls(c3t3.triangulation(), Vertex_handle(), pi.first)) continue; Vertex_handle v = c3t3.triangulation().insert(cwp(pi.first)); From 369cfb6a373e3123a5cfd13abe0af11e5d210538 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 21 Mar 2024 17:08:53 +0100 Subject: [PATCH 09/10] full iterator types for P3M3 --- SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h index f805e5e7f09..34d8b73f7c2 100644 --- a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -1426,15 +1426,20 @@ public: void clear_cells_and_facets_from_c3t3() { //clear cells - for (Cell_handle cit : this->triangulation().all_cell_handles()) + for (typename Tr::All_cells_iterator cit = this->triangulation().all_cells_begin(); + cit != this->triangulation().all_cells_end(); + ++cit) { set_subdomain_index(cit, Subdomain_index()); } this->number_of_cells_ = 0; //clear facets - for (const Facet& facet : this->triangulation().all_facets()) + for (typename Tr::All_facets_iterator fit = this->triangulation().all_facets_begin(); + fit != this->triangulation().all_facets_end(); + ++fit) { + const auto& facet = *fit; set_surface_patch_index(facet.first, facet.second, Surface_patch_index()); if (this->triangulation().dimension() > 2) { const Facet& mirror = tr_.mirror_facet(facet); From ad98ab16b79874cff3b26f28278cc956b9c4687a Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 22 Mar 2024 10:22:48 +0100 Subject: [PATCH 10/10] unused argc, argv --- Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp index 7a0935c474e..c3b01f084e7 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_with_one_step_with_features.cpp @@ -33,7 +33,7 @@ typedef CGAL::Mesh_3::Mesher_3