diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h index c1e827c33fc..14504b02c06 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h @@ -1031,10 +1031,13 @@ bool is_cells_set_manifold(const C3t3&, return true; } -template +template typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge, C3t3& c3t3, - const typename C3t3::Triangulation::Geom_traits::FT& sqhigh, + const Sizing& sizing, const bool /* protect_boundaries */, CellSelector cell_selector, Visitor& ) @@ -1106,6 +1109,8 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge, } } + const auto sqhigh = squared_upper_size_bound(edge, sizing, c3t3.triangulation()); + if (are_edge_lengths_valid(edge, c3t3, new_pos, sqhigh, cell_selector/*, adaptive = false*/) && collapse_preserves_surface_star(edge, c3t3, new_pos, cell_selector)) { @@ -1205,17 +1210,9 @@ void collapse_short_edges(C3T3& c3t3, typedef typename Boost_bimap::value_type short_edge; T3& tr = c3t3.triangulation(); - typename Gt::Compute_squared_length_3 sql - = tr.geom_traits().compute_squared_length_3_object(); - - const FT target_edge_length = sizing(CGAL::ORIGIN, 0, 0); - const FT low = FT(4) / FT(5) * target_edge_length; - const FT high = FT(4) / FT(3) * target_edge_length; - const FT sq_low = low*low; - const FT sq_high = high*high; #ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - std::cout << "Collapse short edges (" << low << ", " << high << ")..."; + std::cout << "Collapse short edges..."; std::cout.flush(); std::size_t nb_collapses = 0; #endif @@ -1227,9 +1224,9 @@ void collapse_short_edges(C3T3& c3t3, if (!can_be_collapsed(e, c3t3, protect_boundaries, cell_selector)) continue; - FT sqlen = sql(tr.segment(e)); - if (sqlen < sq_low) - short_edges.insert(short_edge(make_vertex_pair(e), sqlen)); + const auto sqlen = is_too_short(e, sizing, tr); + if(sqlen != std::nullopt) + short_edges.insert(short_edge(make_vertex_pair(e), sqlen.value())); } #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG @@ -1254,12 +1251,13 @@ void collapse_short_edges(C3T3& c3t3, std::cout << nb_collapses << " collapses)"; std::cout.flush(); #endif + Cell_handle cell; int i1, i2; if ( tr.tds().is_vertex(e.first) && tr.tds().is_vertex(e.second) && tr.tds().is_edge(e.first, e.second, cell, i1, i2) - && tr.segment(Edge(cell, i1, i2)).squared_length() < sq_low) + && is_too_short(Edge(cell, i1, i2), sizing, tr)) { #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG const typename T3::Point p1 = e.first->point(); @@ -1276,7 +1274,7 @@ void collapse_short_edges(C3T3& c3t3, continue; } - Vertex_handle vh = collapse_edge(edge, c3t3, sq_high, + Vertex_handle vh = collapse_edge(edge, c3t3, sizing, protect_boundaries, cell_selector, visitor); if (vh != Vertex_handle()) @@ -1289,9 +1287,9 @@ void collapse_short_edges(C3T3& c3t3, if (!can_be_collapsed(eshort, c3t3, protect_boundaries, cell_selector)) continue; - const FT sqlen = sql(tr.segment(eshort)); - if (sqlen < sq_low) - short_edges.insert(short_edge(make_vertex_pair(eshort), sqlen)); + const auto sqlen = is_too_short(eshort, sizing, tr); + if (sqlen != std::nullopt) + short_edges.insert(short_edge(make_vertex_pair(eshort), sqlen.value())); } //debug::dump_c3t3(c3t3, "dump_after_collapse"); diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h index 4467c713c8b..57f17b540f5 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace CGAL { @@ -234,6 +235,8 @@ bool can_be_split(const typename C3T3::Edge& e, } } + + template, + boost::bimaps::set_of, boost::bimaps::multiset_of > > Boost_bimap; typedef typename Boost_bimap::value_type long_edge; - const FT target_edge_length = sizing(CGAL::ORIGIN, 0, 0); - const FT high = FT(4) / FT(3) * target_edge_length; - #ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - std::cout << "Split long edges (" << high << ")..."; + std::cout << "Split long edges..."; std::cout.flush(); std::size_t nb_splits = 0; #endif - const FT sq_high = high*high; //collect long edges T3& tr = c3t3.triangulation(); @@ -275,11 +274,9 @@ void split_long_edges(C3T3& c3t3, if (!can_be_split(e, c3t3, protect_boundaries, cell_selector)) continue; - typename Gt::Compute_squared_length_3 sql - = tr.geom_traits().compute_squared_length_3_object(); - FT sqlen = sql(tr.segment(e)); - if (sqlen > sq_high) - long_edges.insert(long_edge(make_vertex_pair(e), sqlen)); + const std::optional sqlen = is_too_long(e, sizing, tr); + if(sqlen != std::nullopt) + long_edges.insert(long_edge(make_vertex_pair(e), sqlen.value())); } #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index d6ccc1fe834..fb0bce2a041 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -174,16 +174,6 @@ public: return m_c3t3_pbackup != NULL; } - bool is_too_long(const Edge& e) const - { - const FT target_edge_length - = m_sizing(CGAL::midpoint(tr().segment(e)), - 0, - 0); - const FT emax = FT(4)/FT(3) * target_edge_length; - return tr().segment(e).squared_length() > CGAL::square(emax * emax); - } - bool is_too_short(const Edge& e) const { const FT target_edge_length diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h index f566ab1890f..0fbbe30850f 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h @@ -31,6 +31,8 @@ #include #include +#include + namespace CGAL { namespace Tetrahedral_remeshing @@ -982,6 +984,74 @@ bool topology_test(const typename C3t3::Edge& edge, return true; } +template +typename Tr::Geom_traits::FT +squared_upper_size_bound(const typename Tr::Edge& e, + const Sizing& sizing, + const Tr& tr) +{ + using FT = typename Tr::Geom_traits::FT; + + const FT target_edge_length + = sizing(CGAL::midpoint(tr.segment(e)), + 0, + 0); + const FT emax = FT(4) / FT(3) * target_edge_length; + return CGAL::square(emax); +} + +template +typename Tr::Geom_traits::FT +squared_lower_size_bound(const typename Tr::Edge& e, + const Sizing& sizing, + const Tr& tr) +{ + using FT = typename Tr::Geom_traits::FT; + + const FT target_edge_length + = sizing(CGAL::midpoint(tr.segment(e)), + 0, + 0); + const FT emin = FT(4) / FT(5) * target_edge_length; + return CGAL::square(emin); +} + +template +std::optional +is_too_long(const typename Tr::Edge& e, + const Sizing& sizing, + const Tr& tr) +{ + using FT = typename Tr::Geom_traits::FT; + auto sql = tr.geom_traits().compute_squared_length_3_object(); + + const FT sq_max = squared_upper_size_bound(e, sizing, tr); + const FT sqlen = sql(tr.segment(e)); + + if (sqlen > sq_max) + return sqlen; + else + return std::nullopt; +} + +template +std::optional +is_too_short(const typename Tr::Edge& e, + const Sizing& sizing, + const Tr& tr) +{ + using FT = typename Tr::Geom_traits::FT; + auto sql = tr.geom_traits().compute_squared_length_3_object(); + + const FT sq_min = squared_lower_size_bound(e, sizing, tr); + const FT sqlen = sql(tr.segment(e)); + + if (sqlen < sq_min) + return sqlen; + else + return std::nullopt; +} + template Subdomain_relation compare_subdomains(const typename C3t3::Vertex_handle v0, const typename C3t3::Vertex_handle v1,