Surface_mesh_approximation: Deal with boundary edges

This commit is contained in:
Andreas Fabri 2023-07-05 08:44:38 +01:00
parent f7a78677fc
commit 75a0366160
2 changed files with 67 additions and 51 deletions

View File

@ -222,6 +222,7 @@ CGAL_add_named_parameter(number_of_relaxations_t, number_of_relaxations, number_
CGAL_add_named_parameter(use_convex_hull_t, use_convex_hull, use_convex_hull) CGAL_add_named_parameter(use_convex_hull_t, use_convex_hull, use_convex_hull)
// meshing parameters // meshing parameters
CGAL_add_named_parameter(boundary_subdivision_ratio_t, boundary_subdivision_ratio, boundary_subdivision_ratio)
CGAL_add_named_parameter(subdivision_ratio_t, subdivision_ratio, subdivision_ratio) CGAL_add_named_parameter(subdivision_ratio_t, subdivision_ratio, subdivision_ratio)
CGAL_add_named_parameter(relative_to_chord_t, relative_to_chord, relative_to_chord) CGAL_add_named_parameter(relative_to_chord_t, relative_to_chord, relative_to_chord)
CGAL_add_named_parameter(with_dihedral_angle_t, with_dihedral_angle, with_dihedral_angle) CGAL_add_named_parameter(with_dihedral_angle_t, with_dihedral_angle, with_dihedral_angle)

View File

@ -795,6 +795,12 @@ public:
* \cgalParamDefault{`5.0`} * \cgalParamDefault{`5.0`}
* \cgalParamNEnd * \cgalParamNEnd
* *
* \cgalParamNBegin{boundary_subdivision_ratio}
* \cgalParamDescription{the chord subdivision ratio threshold to the chord length or average edge length for boundary edges}
* \cgalParamType{`geom_traits::FT`}
* \cgalParamDefault{`5.0`}
* \cgalParamNEnd
*
* \cgalParamNBegin{relative_to_chord} * \cgalParamNBegin{relative_to_chord}
* \cgalParamDescription{If `true`, the `subdivision_ratio` is the ratio of the furthest vertex distance * \cgalParamDescription{If `true`, the `subdivision_ratio` is the ratio of the furthest vertex distance
* to the chord length, otherwise is the average edge length} * to the chord length, otherwise is the average edge length}
@ -827,6 +833,7 @@ public:
using parameters::choose_parameter; using parameters::choose_parameter;
const FT subdivision_ratio = choose_parameter(get_parameter(np, internal_np::subdivision_ratio), FT(5.0)); const FT subdivision_ratio = choose_parameter(get_parameter(np, internal_np::subdivision_ratio), FT(5.0));
const FT boundary_subdivision_ratio = choose_parameter(get_parameter(np, internal_np::boundary_subdivision_ratio), FT(5.0));
const bool relative_to_chord = choose_parameter(get_parameter(np, internal_np::relative_to_chord), false); const bool relative_to_chord = choose_parameter(get_parameter(np, internal_np::relative_to_chord), false);
const bool with_dihedral_angle = choose_parameter(get_parameter(np, internal_np::with_dihedral_angle), false); const bool with_dihedral_angle = choose_parameter(get_parameter(np, internal_np::with_dihedral_angle), false);
const bool optimize_anchor_location = choose_parameter(get_parameter(np, internal_np::optimize_anchor_location), true); const bool optimize_anchor_location = choose_parameter(get_parameter(np, internal_np::optimize_anchor_location), true);
@ -848,7 +855,7 @@ public:
// generate anchors // generate anchors
find_anchors(); find_anchors();
find_edges(subdivision_ratio, relative_to_chord, with_dihedral_angle); find_edges(subdivision_ratio, boundary_subdivision_ratio, relative_to_chord, with_dihedral_angle);
add_anchors(); add_anchors();
// discrete constrained Delaunay triangulation // discrete constrained Delaunay triangulation
@ -1519,6 +1526,7 @@ private:
* @param with_dihedral_angle if set to `true`, add dihedral angle weight to the distance. * @param with_dihedral_angle if set to `true`, add dihedral angle weight to the distance.
*/ */
void find_edges(const FT subdivision_ratio, void find_edges(const FT subdivision_ratio,
const FT boundary_subdivision_ratio,
const bool relative_to_chord, const bool relative_to_chord,
const bool with_dihedral_angle) { const bool with_dihedral_angle) {
// collect candidate halfedges in a set // collect candidate halfedges in a set
@ -1550,7 +1558,7 @@ private:
Boundary_chord chord; Boundary_chord chord;
walk_to_next_anchor(he_start, chord); walk_to_next_anchor(he_start, chord);
m_bcycles.back().num_anchors += subdivide_chord(chord.begin(), chord.end(), m_bcycles.back().num_anchors += subdivide_chord(chord.begin(), chord.end(),
subdivision_ratio, relative_to_chord, with_dihedral_angle); subdivision_ratio, boundary_subdivision_ratio, relative_to_chord, with_dihedral_angle);
#ifdef CGAL_SURFACE_MESH_APPROXIMATION_DEBUG #ifdef CGAL_SURFACE_MESH_APPROXIMATION_DEBUG
std::cerr << "#chord_anchor " << m_bcycles.back().num_anchors << std::endl; std::cerr << "#chord_anchor " << m_bcycles.back().num_anchors << std::endl;
@ -1846,6 +1854,7 @@ private:
const Boundary_chord_iterator &chord_begin, const Boundary_chord_iterator &chord_begin,
const Boundary_chord_iterator &chord_end, const Boundary_chord_iterator &chord_end,
const FT subdivision_ratio, const FT subdivision_ratio,
const FT boundary_subdivision_ratio,
const bool relative_to_chord, const bool relative_to_chord,
const bool with_dihedral_angle) { const bool with_dihedral_angle) {
const std::size_t chord_size = std::distance(chord_begin, chord_end); const std::size_t chord_size = std::distance(chord_begin, chord_end);
@ -1854,6 +1863,8 @@ private:
const std::size_t anchor_first = get(m_vanchor_map, source(he_first, *m_ptm)); const std::size_t anchor_first = get(m_vanchor_map, source(he_first, *m_ptm));
const std::size_t anchor_last = get(m_vanchor_map, target(he_last, *m_ptm)); const std::size_t anchor_last = get(m_vanchor_map, target(he_last, *m_ptm));
bool is_boundary = is_border_edge(he_first, *m_ptm);
// do not subdivide trivial non-circular chord // do not subdivide trivial non-circular chord
if ((anchor_first != anchor_last) && (chord_size < 4)) if ((anchor_first != anchor_last) && (chord_size < 4))
return 1; return 1;
@ -1927,19 +1938,23 @@ private:
} }
criterion *= norm_sin; criterion *= norm_sin;
} }
if (is_boundary) {
if (criterion > boundary_subdivision_ratio)
if_subdivide = true;
}
else {
if (criterion > subdivision_ratio) if (criterion > subdivision_ratio)
if_subdivide = true; if_subdivide = true;
} }
}
if (if_subdivide) { if (if_subdivide) {
// subdivide at the most remote vertex // subdivide at the most remote vertex
attach_anchor(*chord_max); attach_anchor(*chord_max);
const std::size_t num_left = subdivide_chord(chord_begin, chord_max + 1, const std::size_t num_left = subdivide_chord(chord_begin, chord_max + 1,
subdivision_ratio, relative_to_chord, with_dihedral_angle); subdivision_ratio, boundary_subdivision_ratio, relative_to_chord, with_dihedral_angle);
const std::size_t num_right = subdivide_chord(chord_max + 1, chord_end, const std::size_t num_right = subdivide_chord(chord_max + 1, chord_end,
subdivision_ratio, relative_to_chord, with_dihedral_angle); subdivision_ratio, boundary_subdivision_ratio, relative_to_chord, with_dihedral_angle);
return num_left + num_right; return num_left + num_right;
} }