From e4e13e2f571adf44fe2107d064ed801b18067ba5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 14 Nov 2023 12:28:18 +0100 Subject: [PATCH 1/6] do not check the graph of features after protection when minimal_size is set when minimal_size is set, the graph of features is likely to be invalid or at least inconsistent with the input graph so checking its topology does not make any sense and could lead to - assertions failing in debug mode, - hanging in release mode --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 721984601811..4cd4d1c3af41 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -1456,7 +1456,7 @@ refine_balls() dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif // Check edges - if(!forced_stop()) { + if(!forced_stop() && minimal_size_ == FT()) { check_and_repopulate_edges(); } } From 54677b388c8fa8ad5cbae15c0948ac82c302ef81 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Dec 2023 15:35:06 +0100 Subject: [PATCH 2/6] set default minimal_size_ to -1 and add helper function to check if it is set --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 4cd4d1c3af41..a04664e8de6c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -139,7 +139,7 @@ class Protect_edges_sizing_field Protect_edges_sizing_field(C3T3& c3t3, const MeshDomain& domain, SizingFunction size=SizingFunction(), - const FT minimal_size = FT(), + const FT minimal_size = FT(-1), std::size_t maximal_number_of_vertices = 0, Mesh_error_code* error_code = 0 #ifndef CGAL_NO_ATOMIC @@ -455,12 +455,17 @@ class Protect_edges_sizing_field return s; } + bool use_minimal_size() const + { + return minimal_size_ != FT(-1); + } + private: C3T3& c3t3_; const MeshDomain& domain_; SizingFunction size_; - FT minimal_size_; - Weight minimal_weight_; + const FT minimal_size_; + const Weight minimal_weight_; std::set treated_edges_; Vertex_set unchecked_vertices_; int refine_balls_iteration_nb; @@ -540,7 +545,7 @@ operator()(const bool refine) std::cerr << "refine_balls() done. Nb of points in triangulation: " << c3t3_.triangulation().number_of_vertices() << std::endl; #endif - CGAL_assertion(minimal_size_ > 0 || c3t3_.is_valid()); + CGAL_assertion(use_minimal_size() || c3t3_.is_valid()); } // debug_dump_c3t3("dump-mesh-after-protect_edges.binary.cgal", c3t3_); @@ -760,10 +765,10 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, while ( ! is_special(nearest_vh) && cwsr(c3t3_.triangulation().point(nearest_vh), - sq_d) == CGAL::SMALLER ) { - CGAL_assertion( minimal_size_ > 0 || sq_d > 0 ); + CGAL_assertion( use_minimal_size() || sq_d > 0); bool special_ball = false; - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight_) { sq_d = minimal_weight_; w = minimal_weight_; @@ -817,7 +822,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, const FT sq_d = tr.min_squared_distance(p, cp(c3t3_.triangulation().point(v))); - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) { + if(use_minimal_size() && sq_d < minimal_weight_) { insert_a_special_ball = true; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 nearest_point = c3t3_.triangulation().point(v); @@ -876,7 +881,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, if ( cwsr(it_wp, - sq_d) == CGAL::SMALLER ) { bool special_ball = false; - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight_) { sq_d = minimal_weight_; w = minimal_weight_; @@ -1436,7 +1441,7 @@ refine_balls() const Vertex_handle v = it->first; const FT new_size = it->second; // Set size of the ball to new value - if(minimal_size_ != FT() && new_size < minimal_size_) { + if(use_minimal_size() && new_size < minimal_size_) { if(!is_special(v)) { change_ball_size(v, minimal_weight_, true); // special ball @@ -1456,7 +1461,7 @@ refine_balls() dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif // Check edges - if(!forced_stop() && minimal_size_ == FT()) { + if(!forced_stop() && !use_minimal_size()) { check_and_repopulate_edges(); } } From 85b8da120dce6246320bc7565983a60cd74083e5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Dec 2023 15:36:57 +0100 Subject: [PATCH 3/6] constify more --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index a04664e8de6c..61e13ee4bda1 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -140,7 +140,7 @@ class Protect_edges_sizing_field const MeshDomain& domain, SizingFunction size=SizingFunction(), const FT minimal_size = FT(-1), - std::size_t maximal_number_of_vertices = 0, + const std::size_t maximal_number_of_vertices = 0, Mesh_error_code* error_code = 0 #ifndef CGAL_NO_ATOMIC , std::atomic* stop_ptr = 0 @@ -470,7 +470,7 @@ class Protect_edges_sizing_field Vertex_set unchecked_vertices_; int refine_balls_iteration_nb; bool nonlinear_growth_of_balls; - std::size_t maximal_number_of_vertices_; + const std::size_t maximal_number_of_vertices_; Mesh_error_code* const error_code_; #ifndef CGAL_NO_ATOMIC /// Pointer to the atomic Boolean that can stop the process @@ -483,7 +483,7 @@ template Protect_edges_sizing_field:: Protect_edges_sizing_field(C3T3& c3t3, const MD& domain, Sf size, const FT minimal_size, - std::size_t maximal_number_of_vertices, + const std::size_t maximal_number_of_vertices, Mesh_error_code* error_code #ifndef CGAL_NO_ATOMIC , std::atomic* stop_ptr From 7fa2db8dfc9552d18744f45ebe148a704592ff13 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Dec 2023 19:01:57 +0100 Subject: [PATCH 4/6] add helper function minimal_weight() --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 61e13ee4bda1..885c6f53160a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -459,6 +459,13 @@ class Protect_edges_sizing_field { return minimal_size_ != FT(-1); } + Weight minimal_weight() const + { + if (use_minimal_size()) + return minimal_weight_; + else + return Weight(0); + } private: C3T3& c3t3_; @@ -822,16 +829,16 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, const FT sq_d = tr.min_squared_distance(p, cp(c3t3_.triangulation().point(v))); - if(use_minimal_size() && sq_d < minimal_weight_) { + if(use_minimal_size() && sq_d < minimal_weight()) { insert_a_special_ball = true; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 nearest_point = c3t3_.triangulation().point(v); #endif - min_sq_d = minimal_weight_; + min_sq_d = minimal_weight(); if(! is_special(v)) { *out++ = v; - ch = change_ball_size(v, minimal_weight_, true)->cell(); // special ball + ch = change_ball_size(v, minimal_weight(), true)->cell(); // special ball } } else @@ -881,10 +888,10 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, if ( cwsr(it_wp, - sq_d) == CGAL::SMALLER ) { bool special_ball = false; - if(use_minimal_size() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight()) { - sq_d = minimal_weight_; - w = minimal_weight_; + sq_d = minimal_weight(); + w = minimal_weight(); special_ball = true; insert_a_special_ball = true; } @@ -938,13 +945,13 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, add_handle_to_unchecked = true; } - if( w < minimal_weight_) { + if( w < minimal_weight()) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 std::cerr << "smart_insert_point: weight " << w - << " was smaller than minimal weight (" << minimal_weight_ << ")\n"; + << " was smaller than minimal weight (" << minimal_weight() << ")\n"; #endif - w = minimal_weight_; + w = minimal_weight(); insert_a_special_ball = true; } Vertex_handle v = insert_point(p,w,dim,index, insert_a_special_ball); @@ -1179,7 +1186,7 @@ insert_balls(const Vertex_handle& vp, const FT d_signF = static_cast(d_sign); int n = static_cast(std::floor(FT(2)*(d-sq) / (sp+sq))+.5); - // if( minimal_weight_ != 0 && n == 0 ) return; + // if( minimal_weight() != 0 && n == 0 ) return; if(nonlinear_growth_of_balls && refine_balls_iteration_nb < 3) { @@ -1188,7 +1195,7 @@ insert_balls(const Vertex_handle& vp, // balls at corner. When the curve segment is long enough, pick a point // at the middle and choose a new size. if(n >= internal::max_nb_vertices_to_reevaluate_size && - d >= (internal::max_nb_vertices_to_reevaluate_size * minimal_weight_)) { + d >= (internal::max_nb_vertices_to_reevaluate_size * minimal_weight())) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 const Weighted_point& vq_wp = c3t3_.triangulation().point(vq); std::cerr << "Number of to-be-inserted balls is: " @@ -1443,7 +1450,7 @@ refine_balls() // Set size of the ball to new value if(use_minimal_size() && new_size < minimal_size_) { if(!is_special(v)) { - change_ball_size(v, minimal_weight_, true); // special ball + change_ball_size(v, minimal_weight(), true); // special ball // Loop will have to be run again restart = true; From 3ef2ce91639f99b8ac277311af568fc542e03b00 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 15 Dec 2023 14:44:33 +0100 Subject: [PATCH 5/6] check_and_repopulate_edges() reactivated with minimal size disabling it may give too bad results change the arc_length computation when minimal size is used, instead, by approximating it by the segment length --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 885c6f53160a..c74e2ca63e00 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -1468,7 +1468,7 @@ refine_balls() dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif // Check edges - if(!forced_stop() && !use_minimal_size()) { + if(!forced_stop()) { check_and_repopulate_edges(); } } @@ -1771,7 +1771,9 @@ is_sampling_dense_enough(const Vertex_handle& v1, const Vertex_handle& v2, const Weighted_point& v1_wp = c3t3_.triangulation().point(v1); const Weighted_point& v2_wp = c3t3_.triangulation().point(v2); - FT arc_length = domain_.curve_segment_length(cp(v1_wp), + FT arc_length = use_minimal_size() + ? compute_distance(v1, v2) //curve polyline may not be consistent + : domain_.curve_segment_length(cp(v1_wp), cp(v2_wp), curve_index, orientation); From a66e78a6729a83d74c6d39d9da40ab917f26c211 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 15 Dec 2023 15:52:02 +0100 Subject: [PATCH 6/6] when curves topology is valid, use curve_segment_length --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index c74e2ca63e00..a2e13b811237 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -1763,20 +1763,33 @@ is_sampling_dense_enough(const Vertex_handle& v1, const Vertex_handle& v2, FT size_v1 = get_radius(v1); FT size_v2 = get_radius(v2); - CGAL_assertion(get_dimension(v1) != 1 || - curve_index == domain_.curve_index(v1->index())); - CGAL_assertion(get_dimension(v2) != 1 || - curve_index == domain_.curve_index(v2->index())); + bool v1_valid_curve_index = true; + bool v2_valid_curve_index = true; + + if(use_minimal_size()) + { + v1_valid_curve_index = (get_dimension(v1) != 1 + || curve_index == domain_.curve_index(v1->index())); + v2_valid_curve_index = (get_dimension(v2) != 1 + || curve_index == domain_.curve_index(v2->index())); + } + else + { + CGAL_assertion(get_dimension(v1) != 1 || + curve_index == domain_.curve_index(v1->index())); + CGAL_assertion(get_dimension(v2) != 1 || + curve_index == domain_.curve_index(v2->index())); + } const Weighted_point& v1_wp = c3t3_.triangulation().point(v1); const Weighted_point& v2_wp = c3t3_.triangulation().point(v2); - FT arc_length = use_minimal_size() - ? compute_distance(v1, v2) //curve polyline may not be consistent - : domain_.curve_segment_length(cp(v1_wp), + FT arc_length = (v1_valid_curve_index && v2_valid_curve_index) + ? domain_.curve_segment_length(cp(v1_wp), cp(v2_wp), curve_index, - orientation); + orientation) + : compute_distance(v1, v2); //curve polyline may not be consistent // Sufficient condition so that the curve portion between v1 and v2 is // inside the union of the two balls.