move size comparison to is_too_short(edge) and is_too_long(edge) functions

This commit is contained in:
Jane Tournois 2023-10-25 17:12:00 +02:00 committed by Jane Tournois
parent 6467281c8a
commit 3006d2ef70
4 changed files with 95 additions and 40 deletions

View File

@ -1031,10 +1031,13 @@ bool is_cells_set_manifold(const C3t3&,
return true;
}
template<typename C3t3, typename CellSelector, typename Visitor>
template<typename C3t3,
typename Sizing,
typename CellSelector,
typename Visitor>
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<T3>(e), sqlen));
const auto sqlen = is_too_short(e, sizing, tr);
if(sqlen != std::nullopt)
short_edges.insert(short_edge(make_vertex_pair<T3>(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<T3>(eshort), sqlen));
const auto sqlen = is_too_short(eshort, sizing, tr);
if (sqlen != std::nullopt)
short_edges.insert(short_edge(make_vertex_pair<T3>(eshort), sqlen.value()));
}
//debug::dump_c3t3(c3t3, "dump_after_collapse");

View File

@ -26,6 +26,7 @@
#include <unordered_map>
#include <functional>
#include <utility>
#include <optional>
namespace CGAL
{
@ -234,6 +235,8 @@ bool can_be_split(const typename C3T3::Edge& e,
}
}
template<typename C3T3,
typename Sizing,
typename CellSelector,
@ -253,19 +256,15 @@ void split_long_edges(C3T3& c3t3,
typedef typename T3::Geom_traits Gt;
typedef typename T3::Geom_traits::FT FT;
typedef boost::bimap<
boost::bimaps::set_of<Edge_vv>,
boost::bimaps::set_of<Edge_vv>,
boost::bimaps::multiset_of<FT, std::greater<FT> > > 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<T3>(e), sqlen));
const std::optional<FT> sqlen = is_too_long<T3>(e, sizing, tr);
if(sqlen != std::nullopt)
long_edges.insert(long_edge(make_vertex_pair<T3>(e), sqlen.value()));
}
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG

View File

@ -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

View File

@ -31,6 +31,8 @@
#include <boost/container/flat_set.hpp>
#include <boost/container/small_vector.hpp>
#include <optional>
namespace CGAL
{
namespace Tetrahedral_remeshing
@ -982,6 +984,74 @@ bool topology_test(const typename C3t3::Edge& edge,
return true;
}
template<typename Tr, typename Sizing>
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, typename Sizing>
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<typename Tr, typename Sizing>
std::optional<typename Tr::Geom_traits::FT>
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<typename Tr, typename Sizing>
std::optional<typename Tr::Geom_traits::FT>
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<typename C3t3>
Subdomain_relation compare_subdomains(const typename C3t3::Vertex_handle v0,
const typename C3t3::Vertex_handle v1,