mirror of https://github.com/CGAL/cgal
Mirror AW2 improvements into AW3
This commit is contained in:
parent
57e5d7db09
commit
48d09df6e6
|
|
@ -1,5 +1,4 @@
|
||||||
// Copyright (c) 2019-2022 Google LLC (USA).
|
// Copyright (c) 2019-2022 Google LLC (USA).
|
||||||
// Copyright (c) 2025 GeometryFactory (France).
|
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
|
@ -110,6 +109,10 @@ public:
|
||||||
void add_points(const PointRange& points,
|
void add_points(const PointRange& points,
|
||||||
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_AW2_DEBUG
|
||||||
|
std::cout << "Insert into AABB tree (points)..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(points.empty())
|
if(points.empty())
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW2_DEBUG
|
#ifdef CGAL_AW2_DEBUG
|
||||||
|
|
@ -121,10 +124,6 @@ public:
|
||||||
const std::size_t old_size = m_points_ptr->size();
|
const std::size_t old_size = m_points_ptr->size();
|
||||||
m_points_ptr->insert(std::cend(*m_points_ptr), std::cbegin(points), std::cend(points));
|
m_points_ptr->insert(std::cend(*m_points_ptr), std::cbegin(points), std::cend(points));
|
||||||
|
|
||||||
#ifdef CGAL_AW2_DEBUG
|
|
||||||
std::cout << "Insert into AABB tree (points)..." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->tree().rebuild(std::cbegin(*m_points_ptr), std::cend(*m_points_ptr));
|
this->tree().rebuild(std::cbegin(*m_points_ptr), std::cend(*m_points_ptr));
|
||||||
|
|
||||||
// Manually constructing it here purely for profiling reasons: if we keep the lazy approach,
|
// Manually constructing it here purely for profiling reasons: if we keep the lazy approach,
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,8 @@ int main(int argc, char** argv)
|
||||||
Oracle oracle(ss_oracle);
|
Oracle oracle(ss_oracle);
|
||||||
|
|
||||||
oracle.add_triangle_soup(points, faces, CGAL::parameters::default_values());
|
oracle.add_triangle_soup(points, faces, CGAL::parameters::default_values());
|
||||||
oracle.add_segment_soup(segments, CGAL::parameters::default_values());
|
oracle.add_segments(segments, CGAL::parameters::default_values());
|
||||||
oracle.add_point_set(ps_points, CGAL::parameters::default_values());
|
oracle.add_points(ps_points, CGAL::parameters::default_values());
|
||||||
|
|
||||||
CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3<Oracle> aw3(oracle);
|
CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3<Oracle> aw3(oracle);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -207,13 +207,27 @@ public:
|
||||||
static_assert(std::is_floating_point<FT>::value);
|
static_assert(std::is_floating_point<FT>::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_oracle.clear();
|
||||||
|
m_bbox = {};
|
||||||
|
m_alpha = m_sq_alpha = FT(-1);
|
||||||
|
m_offset = m_sq_offset = FT(-1);
|
||||||
|
m_seeds.clear();
|
||||||
|
m_tr.clear();
|
||||||
|
m_queue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Geom_traits& geom_traits() const { return m_tr.geom_traits(); }
|
const Geom_traits& geom_traits() const { return m_tr.geom_traits(); }
|
||||||
Oracle& oracle() { return m_oracle; }
|
Oracle& oracle() { return m_oracle; }
|
||||||
const Oracle& oracle() const { return m_oracle; }
|
const Oracle& oracle() const { return m_oracle; }
|
||||||
Triangulation& triangulation() { return m_tr; }
|
Triangulation& triangulation() { return m_tr; }
|
||||||
const Triangulation& triangulation() const { return m_tr; }
|
const Triangulation& triangulation() const { return m_tr; }
|
||||||
|
Alpha_PQ& queue() { return m_queue; }
|
||||||
const Alpha_PQ& queue() const { return m_queue; }
|
const Alpha_PQ& queue() const { return m_queue; }
|
||||||
|
const FT& alpha() const { return m_alpha; }
|
||||||
|
const FT& offset() const { return m_offset; }
|
||||||
|
|
||||||
double default_alpha() const
|
double default_alpha() const
|
||||||
{
|
{
|
||||||
|
|
@ -365,6 +379,11 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS
|
||||||
|
IO::write_polygon_mesh("final_wrap.off", output_mesh, CGAL::parameters::stream_precision(17));
|
||||||
|
dump_triangulation_faces("final_tr.off", false /*only_boundary_faces*/);
|
||||||
|
#endif
|
||||||
|
|
||||||
extract_surface(output_mesh, ovpm, !do_enforce_manifoldness);
|
extract_surface(output_mesh, ovpm, !do_enforce_manifoldness);
|
||||||
|
|
||||||
#ifdef CGAL_AW3_TIMER
|
#ifdef CGAL_AW3_TIMER
|
||||||
|
|
@ -375,11 +394,6 @@ public:
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
std::cout << "Alpha wrap vertices: " << vertices(output_mesh).size() << std::endl;
|
std::cout << "Alpha wrap vertices: " << vertices(output_mesh).size() << std::endl;
|
||||||
std::cout << "Alpha wrap faces: " << faces(output_mesh).size() << std::endl;
|
std::cout << "Alpha wrap faces: " << faces(output_mesh).size() << std::endl;
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS
|
|
||||||
IO::write_polygon_mesh("final_wrap.off", output_mesh, CGAL::parameters::stream_precision(17));
|
|
||||||
dump_triangulation_faces("final_tr.off", false /*only_boundary_faces*/);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
visitor.on_alpha_wrapping_end(*this);
|
visitor.on_alpha_wrapping_end(*this);
|
||||||
|
|
@ -501,7 +515,7 @@ private:
|
||||||
// which yields
|
// which yields
|
||||||
// r = a * sin(2pi / 5) =~ 0.95105651629515353 * a
|
// r = a * sin(2pi / 5) =~ 0.95105651629515353 * a
|
||||||
// Faces of an icosahedron are equilateral triangles with size a and circumradius a / sqrt(3)
|
// Faces of an icosahedron are equilateral triangles with size a and circumradius a / sqrt(3)
|
||||||
// Since we want faces of the icosahedron to be traversable, we want a such that
|
// Since we want faces of the icosahedron to be traversable, we want `a` such that
|
||||||
// a / sqrt(3) > alpha
|
// a / sqrt(3) > alpha
|
||||||
// Hence r such that
|
// Hence r such that
|
||||||
// r / (sqrt(3) * sin(2pi/5)) > alpha
|
// r / (sqrt(3) * sin(2pi/5)) > alpha
|
||||||
|
|
@ -509,7 +523,7 @@ private:
|
||||||
//
|
//
|
||||||
// Furthermore, the triangles between edges of the icosahedron and the center of the icosahedron
|
// Furthermore, the triangles between edges of the icosahedron and the center of the icosahedron
|
||||||
// are not equilateral triangles since a is slightly bigger than r. They are
|
// are not equilateral triangles since a is slightly bigger than r. They are
|
||||||
// slightly flattened isocele triangles with base 'a' and the circumradius is smaller.
|
// slightly flattened isocele triangles with base `a` and the circumradius is smaller.
|
||||||
// The circumradius is
|
// The circumradius is
|
||||||
// r_iso = r² / (2 * h) = r² / (2 * sqrt(r² - (a / 2)²))
|
// r_iso = r² / (2 * h) = r² / (2 * sqrt(r² - (a / 2)²))
|
||||||
// Since r = a * sin(2pi / 5)
|
// Since r = a * sin(2pi / 5)
|
||||||
|
|
@ -896,6 +910,16 @@ private:
|
||||||
return less_squared_radius_of_min_empty_sphere(m_sq_alpha, f, m_tr);
|
return less_squared_radius_of_min_empty_sphere(m_sq_alpha, f, m_tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Steiner_status compute_steiner_point(const Gate& gate,
|
||||||
|
Point_2& steiner_point) const
|
||||||
|
{
|
||||||
|
const Face_handle fh = gate.face();
|
||||||
|
const Cell_handle ch = f.first;
|
||||||
|
const int s = f.second;
|
||||||
|
const Cell_handle nh = ch->neighbor(s);
|
||||||
|
return compute_steiner_point(ch, nh, steiner_point);
|
||||||
|
}
|
||||||
|
|
||||||
bool compute_steiner_point(const Cell_handle ch,
|
bool compute_steiner_point(const Cell_handle ch,
|
||||||
const Cell_handle neighbor,
|
const Cell_handle neighbor,
|
||||||
Point_3& steiner_point) const
|
Point_3& steiner_point) const
|
||||||
|
|
@ -950,7 +974,7 @@ private:
|
||||||
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
||||||
std::cout << "Steiner found through first_intersection(): " << steiner_point << std::endl;
|
std::cout << "Steiner found through first_intersection(): " << steiner_point << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return Steiner_status::RULE_1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -959,6 +983,10 @@ private:
|
||||||
{
|
{
|
||||||
// steiner point is the closest point on input from cell centroid with offset
|
// steiner point is the closest point on input from cell centroid with offset
|
||||||
const Point_3 closest_pt = m_oracle.closest_point(neighbor_cc);
|
const Point_3 closest_pt = m_oracle.closest_point(neighbor_cc);
|
||||||
|
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
||||||
|
std::cout << "Steiner found through neighboring triangle intersecting the input" << std::endl;
|
||||||
|
std::cout << "Closest point: " << closest_pt << std::endl;
|
||||||
|
#endif
|
||||||
CGAL_assertion(closest_pt != neighbor_cc);
|
CGAL_assertion(closest_pt != neighbor_cc);
|
||||||
|
|
||||||
Vector_3 unit = vector(closest_pt, neighbor_cc);
|
Vector_3 unit = vector(closest_pt, neighbor_cc);
|
||||||
|
|
@ -968,19 +996,18 @@ private:
|
||||||
steiner_point = translate(closest_pt, unit);
|
steiner_point = translate(closest_pt, unit);
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
||||||
std::cout << "Steiner found through neighboring tet intersecting the input: " << steiner_point << std::endl;
|
std::cout << "Direction: " << unit << std::endl;
|
||||||
std::cout << "Closest point: " << closest_pt << std::endl;
|
std::cout << "Steiner: " << steiner_point << std::endl;
|
||||||
std::cout << "Direction: " << vector(closest_pt, neighbor_cc) << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return Steiner_status::RULE_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
#ifdef CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
||||||
std::cout << "No Steiner point" << std::endl;
|
std::cout << "No Steiner point" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return Steiner_status::NO_STEINER_POINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -1043,7 +1070,12 @@ public:
|
||||||
CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE);
|
CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE);
|
||||||
|
|
||||||
if(m_tr.is_infinite(nh))
|
if(m_tr.is_infinite(nh))
|
||||||
|
{
|
||||||
|
#ifdef CGAL_AW3_DEBUG_FACET_STATUS
|
||||||
|
std::cout << "Infinite neighboring cell" << std::endl;
|
||||||
|
#endif
|
||||||
return Facet_status::HAS_INFINITE_NEIGHBOR;
|
return Facet_status::HAS_INFINITE_NEIGHBOR;
|
||||||
|
}
|
||||||
|
|
||||||
if(nh->is_outside())
|
if(nh->is_outside())
|
||||||
{
|
{
|
||||||
|
|
@ -1104,9 +1136,23 @@ private:
|
||||||
const FT sqr = smallest_squared_radius_3(f, m_tr);
|
const FT sqr = smallest_squared_radius_3(f, m_tr);
|
||||||
const bool is_permissive = (status == Facet_status::HAS_INFINITE_NEIGHBOR ||
|
const bool is_permissive = (status == Facet_status::HAS_INFINITE_NEIGHBOR ||
|
||||||
status == Facet_status::SCAFFOLDING);
|
status == Facet_status::SCAFFOLDING);
|
||||||
m_queue.resize_and_push(Gate(f, sqr, is_permissive));
|
Gate new_gate(f, sqr, is_permissive);
|
||||||
#else
|
#else
|
||||||
m_queue.push(Gate(f, m_tr));
|
Gate new_gate(f, m_tr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGAL_AW2_COMPUTE_AND_STORE_STEINER_INFO_AT_GATE_CREATION
|
||||||
|
Point_3 steiner_point;
|
||||||
|
Steiner_status steiner_status = compute_steiner_point(new_gate, steiner_point);
|
||||||
|
new_gate.m_steiner_status = steiner_status;
|
||||||
|
if(steiner_status == Steiner_status::RULE_1 || steiner_status == Steiner_status::RULE_2)
|
||||||
|
new_gate.m_steiner_point = steiner_point;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE
|
||||||
|
m_queue.resize_and_push(new_gate);
|
||||||
|
#else
|
||||||
|
m_queue.push(new_gate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG_QUEUE
|
#ifdef CGAL_AW3_DEBUG_QUEUE
|
||||||
|
|
@ -1241,26 +1287,25 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Facet& f = gate.facet();
|
const Facet& f = gate.facet();
|
||||||
CGAL_precondition(!m_tr.is_infinite(f));
|
|
||||||
|
|
||||||
const Cell_handle ch = f.first;
|
const Cell_handle ch = f.first;
|
||||||
const int s = f.second;
|
const int s = f.second;
|
||||||
CGAL_precondition(ch->is_outside());
|
|
||||||
|
|
||||||
const Cell_handle nh = ch->neighbor(s);
|
const Cell_handle nh = ch->neighbor(s);
|
||||||
CGAL_precondition(nh->label() == Cell_label::INSIDE || nh->label() == Cell_label::OUTSIDE);
|
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG_QUEUE
|
#ifdef CGAL_AW3_DEBUG_QUEUE
|
||||||
static int fid = 0;
|
static int fid = 0;
|
||||||
std::cout << m_tr.number_of_vertices() << " DT vertices" << std::endl;
|
std::cout << m_tr.number_of_vertices() << " DT vertices" << std::endl;
|
||||||
std::cout << m_queue.size() << " facets in the queue" << std::endl;
|
std::cout << m_queue.size() << " facets in the queue" << std::endl;
|
||||||
std::cout << "Face " << fid++ << "\n"
|
std::cout << "Face " << fid++ << " ["
|
||||||
<< "c = " << &*ch << " (" << m_tr.is_infinite(ch) << "), n = " << &*nh << " (" << m_tr.is_infinite(nh) << ")" << "\n"
|
<< m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << " "
|
||||||
<< m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n"
|
<< m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << " "
|
||||||
<< m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n"
|
<< m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << "]" << std::endl;
|
||||||
<< m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl;
|
std::cout << "c = " << &*ch << " (inf: " << m_tr.is_infinite(ch) << ", label: " << ch->label() << "), n = "
|
||||||
|
<< &*nh << " (inf: " << m_tr.is_infinite(nh) << ", label: " << nh->label() << ")" << "\n"
|
||||||
|
|
||||||
|
# ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE
|
||||||
std::cout << "Priority: " << gate.priority() << " (sq alpha: " << m_sq_alpha << ")" << std::endl;
|
std::cout << "Priority: " << gate.priority() << " (sq alpha: " << m_sq_alpha << ")" << std::endl;
|
||||||
std::cout << "Permissiveness: " << gate.is_permissive_facet() << std::endl;
|
std::cout << "Permissiveness: " << gate.is_permissive_facet() << std::endl;
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP
|
#ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP
|
||||||
|
|
@ -1277,6 +1322,10 @@ private:
|
||||||
face_out.close();
|
face_out.close();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CGAL_precondition(!m_tr.is_infinite(f));
|
||||||
|
CGAL_precondition(ch->is_outside());
|
||||||
|
CGAL_precondition(nh->label() == Cell_label::INSIDE || nh->label() == Cell_label::OUTSIDE);
|
||||||
|
|
||||||
visitor.before_facet_treatment(*this, gate);
|
visitor.before_facet_treatment(*this, gate);
|
||||||
|
|
||||||
m_queue.pop();
|
m_queue.pop();
|
||||||
|
|
@ -1291,7 +1340,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
Point_3 steiner_point;
|
Point_3 steiner_point;
|
||||||
if(compute_steiner_point(ch, nh, steiner_point))
|
Steiner_status ss = compute_steiner_point(ch, nh, steiner_point);
|
||||||
|
if(ss != Steiner_status::NO_STEINER_POINT)
|
||||||
{
|
{
|
||||||
// std::cout << CGAL::abs(CGAL::approximate_sqrt(m_oracle.squared_distance(steiner_point)) - m_offset)
|
// std::cout << CGAL::abs(CGAL::approximate_sqrt(m_oracle.squared_distance(steiner_point)) - m_offset)
|
||||||
// << " vs " << 1e-2 * m_offset << std::endl;
|
// << " vs " << 1e-2 * m_offset << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,33 @@ namespace internal {
|
||||||
enum class Cell_label
|
enum class Cell_label
|
||||||
{
|
{
|
||||||
// Cells that have been carved
|
// Cells that have been carved
|
||||||
OUTSIDE,
|
OUTSIDE = 0,
|
||||||
// Cells that have not yet been carved
|
// Cells that have not yet been carved
|
||||||
INSIDE,
|
INSIDE,
|
||||||
// OUTSIDE cells that have been labeled "inside" again as to make the result manifold
|
// OUTSIDE cells that have been labeled "inside" again as to make the result manifold
|
||||||
MANIFOLD
|
MANIFOLD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline std::string label_string(const Cell_label& label) {
|
||||||
|
switch(label) {
|
||||||
|
case Cell_label::OUTSIDE:
|
||||||
|
return "OUTSIDE";
|
||||||
|
case Cell_label::INSIDE:
|
||||||
|
return "INSIDE";
|
||||||
|
case Cell_label::MANIFOLD:
|
||||||
|
return "MANIFOLD";
|
||||||
|
default:
|
||||||
|
CGAL_assertion_msg(false, "Unknown label");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator <<(std::ostream& os, const Cell_label& label)
|
||||||
|
{
|
||||||
|
os << static_cast<std::underlying_type<Cell_label>::type>(label);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
template < typename GT,
|
template < typename GT,
|
||||||
typename Cb = CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<GT> >
|
typename Cb = CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<GT> >
|
||||||
class Alpha_wrap_triangulation_cell_base_3
|
class Alpha_wrap_triangulation_cell_base_3
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,11 @@ public:
|
||||||
bool empty() const { return m_tree_ptr->empty(); }
|
bool empty() const { return m_tree_ptr->empty(); }
|
||||||
bool do_call() const { return (!empty() || base().do_call()); }
|
bool do_call() const { return (!empty() || base().do_call()); }
|
||||||
|
|
||||||
void clear() { m_tree_ptr->clear() && base().clear(); }
|
void clear()
|
||||||
|
{
|
||||||
|
m_tree_ptr->clear();
|
||||||
|
base().clear();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typename AABB_tree::Bounding_box bbox() const
|
typename AABB_tree::Bounding_box bbox() const
|
||||||
|
|
|
||||||
|
|
@ -97,12 +97,22 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_points_ptr->clear();
|
||||||
|
Oracle_base::clear();
|
||||||
|
}
|
||||||
|
|
||||||
// adds a range of points to the oracle
|
// adds a range of points to the oracle
|
||||||
template <typename PointRange,
|
template <typename PointRange,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
void add_point_set(const PointRange& points,
|
void add_points(const PointRange& points,
|
||||||
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "Insert into AABB tree (points)..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(points.empty())
|
if(points.empty())
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
|
@ -114,20 +124,18 @@ public:
|
||||||
const std::size_t old_size = m_points_ptr->size();
|
const std::size_t old_size = m_points_ptr->size();
|
||||||
m_points_ptr->insert(std::cend(*m_points_ptr), std::cbegin(points), std::cend(points));
|
m_points_ptr->insert(std::cend(*m_points_ptr), std::cbegin(points), std::cend(points));
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
this->tree().rebuild(std::cbegin(*m_points_ptr), std::cend(*m_points_ptr));
|
||||||
std::cout << "Insert into AABB tree (points)..." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->tree().insert(std::next(std::cbegin(*m_points_ptr), old_size), std::cend(*m_points_ptr));
|
|
||||||
|
|
||||||
// Manually constructing it here purely for profiling reasons: if we keep the lazy approach,
|
// Manually constructing it here purely for profiling reasons: if we keep the lazy approach,
|
||||||
// it will be done at the first treatment of a facet that needs a Steiner point.
|
// it will be done at the first treatment of a facet that needs a Steiner point.
|
||||||
// So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes
|
// So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes
|
||||||
// to accelerate the tree.
|
// to accelerate the tree.
|
||||||
this->tree().accelerate_distance_queries();
|
this->tree().accelerate_distance_queries();
|
||||||
|
|
||||||
CGAL_postcondition(this->tree().size() == m_points_ptr->size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_AW2_DEBUG
|
||||||
|
std::cout << "PS Tree: " << this->tree().size() << " primitives" << std::endl;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,21 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_segments_ptr->clear();
|
||||||
|
Oracle_base::clear();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename SegmentRange,
|
template <typename SegmentRange,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
void add_segment_soup(const SegmentRange& segments,
|
void add_segments(const SegmentRange& segments,
|
||||||
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "Insert into AABB Tree (" << segments.size() << " segments)..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(segments.empty())
|
if(segments.empty())
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
|
@ -129,10 +139,7 @@ public:
|
||||||
m_segments_ptr->push_back(s);
|
m_segments_ptr->push_back(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
this->tree().rebuild(std::cbegin(*m_segments_ptr), std::cend(*m_segments_ptr));
|
||||||
std::cout << "Insert into AABB tree (segments)..." << std::endl;
|
|
||||||
#endif
|
|
||||||
this->tree().insert(std::next(std::cbegin(*m_segments_ptr), old_size), std::cend(*m_segments_ptr));
|
|
||||||
|
|
||||||
// Manually constructing it here purely for profiling reasons: if we keep the lazy approach,
|
// Manually constructing it here purely for profiling reasons: if we keep the lazy approach,
|
||||||
// it will be done at the first treatment of a facet that needs a Steiner point.
|
// it will be done at the first treatment of a facet that needs a Steiner point.
|
||||||
|
|
@ -140,7 +147,9 @@ public:
|
||||||
// to accelerate the tree.
|
// to accelerate the tree.
|
||||||
this->tree().accelerate_distance_queries();
|
this->tree().accelerate_distance_queries();
|
||||||
|
|
||||||
CGAL_postcondition(this->tree().size() == m_segments_ptr->size());
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "SS Tree: " << this->tree().size() << " primitives" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,10 @@ public:
|
||||||
using VPM = typename GetVertexPointMap<TriangleMesh>::const_type;
|
using VPM = typename GetVertexPointMap<TriangleMesh>::const_type;
|
||||||
using Point_ref = typename boost::property_traits<VPM>::reference;
|
using Point_ref = typename boost::property_traits<VPM>::reference;
|
||||||
|
|
||||||
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "Insert into AABB tree (" << faces(tmesh).size() << " faces)..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
CGAL_precondition(CGAL::is_triangle_mesh(tmesh));
|
CGAL_precondition(CGAL::is_triangle_mesh(tmesh));
|
||||||
|
|
||||||
if(is_empty(tmesh))
|
if(is_empty(tmesh))
|
||||||
|
|
@ -140,10 +144,6 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
|
||||||
std::cout << "Insert into AABB tree (faces)..." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
get_const_property_map(vertex_point, tmesh));
|
get_const_property_map(vertex_point, tmesh));
|
||||||
static_assert(std::is_same<typename boost::property_traits<VPM>::value_type, Point_3>::value);
|
static_assert(std::is_same<typename boost::property_traits<VPM>::value_type, Point_3>::value);
|
||||||
|
|
@ -176,7 +176,7 @@ public:
|
||||||
this->tree().accelerate_distance_queries();
|
this->tree().accelerate_distance_queries();
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
std::cout << "Tree: " << this->tree().size() << " primitives (" << num_faces(tmesh) << " faces in input)" << std::endl;
|
std::cout << "Tree: " << this->tree().size() << " primitives" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,10 @@ public:
|
||||||
|
|
||||||
using Face = typename boost::range_value<FaceRange>::type;
|
using Face = typename boost::range_value<FaceRange>::type;
|
||||||
|
|
||||||
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "Insert into AABB Tree (" << faces.size() << " faces)..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(points.empty() || faces.empty())
|
if(points.empty() || faces.empty())
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
|
@ -138,10 +142,6 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
|
||||||
std::cout << "Insert into AABB Tree (triangles)..." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PPM pm = choose_parameter<PPM>(get_parameter(np, internal_np::point_map));
|
PPM pm = choose_parameter<PPM>(get_parameter(np, internal_np::point_map));
|
||||||
static_assert(std::is_same<typename boost::property_traits<PPM>::value_type, Point_3>::value);
|
static_assert(std::is_same<typename boost::property_traits<PPM>::value_type, Point_3>::value);
|
||||||
|
|
||||||
|
|
@ -181,15 +181,19 @@ public:
|
||||||
this->tree().accelerate_distance_queries();
|
this->tree().accelerate_distance_queries();
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
std::cout << "Tree: " << this->tree().size() << " primitives (" << faces.size() << " faces in input)" << std::endl;
|
std::cout << "TS Tree: " << this->tree().size() << " primitives" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TriangleRange,
|
template <typename TriangleRange,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
void add_triangle_soup(const TriangleRange& triangles,
|
void add_triangles(const TriangleRange& triangles,
|
||||||
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values())
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "Insert into AABB Tree (" << triangles.size() << " triangles)..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(triangles.empty())
|
if(triangles.empty())
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
|
@ -198,10 +202,6 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_AW3_DEBUG
|
|
||||||
std::cout << "Insert into AABB Tree (triangles)..." << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object();
|
typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object();
|
||||||
|
|
||||||
Splitter_base::reserve(triangles.size());
|
Splitter_base::reserve(triangles.size());
|
||||||
|
|
@ -218,6 +218,9 @@ public:
|
||||||
|
|
||||||
Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits());
|
Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits());
|
||||||
}
|
}
|
||||||
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
std::cout << "TS Tree: " << this->tree().size() << " primitives" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,46 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Alpha_wraps_3 {
|
namespace Alpha_wraps_3 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
enum class Steiner_status
|
||||||
|
{
|
||||||
|
UNKONWN = 0,
|
||||||
|
NO_STEINER_POINT,
|
||||||
|
RULE_1,
|
||||||
|
RULE_2
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CGAL_AW2_COMPUTE_AND_STORE_STEINER_INFO_AT_GATE_CREATION
|
||||||
|
template <typename Tr>
|
||||||
|
struct Gate_steiner_info
|
||||||
|
{
|
||||||
|
using Point_3 = typename Tr::Geom_traits::Point_3;
|
||||||
|
|
||||||
|
Steiner_status m_steiner_status = Steiner_status::UNKNOWN;
|
||||||
|
std::optional<Point_3> m_steiner_point = std::nullopt;
|
||||||
|
|
||||||
|
bool has_steiner_point() const { return m_steiner_point.has_value(); }
|
||||||
|
bool has_steiner_from_projection() const { return (m_steiner_status == Steiner_status::RULE_2); }
|
||||||
|
const Point_3& steiner_point() const {
|
||||||
|
CGAL_precondition(has_steiner_point());
|
||||||
|
return *m_steiner_point;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE
|
#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE
|
||||||
|
|
||||||
// Represents an alpha-traversable facet in the mutable priority queue
|
// Represents an alpha-traversable facet in the mutable priority queue
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
class Gate
|
class Gate
|
||||||
|
#ifdef CGAL_AW2_COMPUTE_AND_STORE_STEINER_INFO_AT_GATE_CREATION
|
||||||
|
: public Gate_steiner_info<Tr>
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
using Facet = typename Tr::Facet;
|
using Facet = typename Tr::Facet;
|
||||||
using FT = typename Tr::Geom_traits::FT;
|
using FT = typename Tr::Geom_traits::FT;
|
||||||
|
|
@ -97,6 +127,9 @@ struct Less_gate
|
||||||
// Represents an alpha-traversable facet in the mutable priority queue
|
// Represents an alpha-traversable facet in the mutable priority queue
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
class Gate
|
class Gate
|
||||||
|
#ifdef CGAL_AW2_COMPUTE_AND_STORE_STEINER_INFO_AT_GATE_CREATION
|
||||||
|
: public Gate_steiner_info<Tr>
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
using Facet = typename Tr::Facet;
|
using Facet = typename Tr::Facet;
|
||||||
using FT = typename Tr::Geom_traits::FT;
|
using FT = typename Tr::Geom_traits::FT;
|
||||||
|
|
|
||||||
|
|
@ -65,20 +65,30 @@ bool has_degenerated_faces(const TriangleMesh& mesh,
|
||||||
// Edge length is bounded by twice the circumradius
|
// Edge length is bounded by twice the circumradius
|
||||||
template <typename TriangleMesh,
|
template <typename TriangleMesh,
|
||||||
typename NamedParameters = parameters::Default_named_parameters>
|
typename NamedParameters = parameters::Default_named_parameters>
|
||||||
bool check_edge_length(const TriangleMesh& output_mesh,
|
bool has_bounded_edge_length(const TriangleMesh& wrap,
|
||||||
const double alpha,
|
const double alpha,
|
||||||
const NamedParameters& np = CGAL::parameters::default_values())
|
const NamedParameters& np = CGAL::parameters::default_values())
|
||||||
{
|
{
|
||||||
const auto sq_alpha_bound = 4 * square(alpha);
|
using Geom_traits = typename GetGeomTraits<TriangleMesh, NamedParameters>::type;
|
||||||
for(auto e : edges(output_mesh))
|
using FT = typename Geom_traits::FT;
|
||||||
|
using VPM = typename CGAL::GetVertexPointMap<PolygonMesh, NamedParameters>::type;
|
||||||
|
|
||||||
|
Geom_traits gt = choose_parameter<Geom_traits>(get_parameter(in_np, internal_np::geom_traits));
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(vertex_point, tmesh));
|
||||||
|
|
||||||
|
const FT sq_alpha_bound = 4 * square(alpha);
|
||||||
|
for(auto e : edges(wrap))
|
||||||
{
|
{
|
||||||
const auto sqd = Polygon_mesh_processing::squared_edge_length(e, output_mesh, np);
|
if(gt.compare_squared_distance(get(vpm, source(e, wrap)),
|
||||||
if(sqd > sq_alpha_bound) // alpha is the circumradius
|
get(vpm, target(e, wrap)),
|
||||||
|
sq_alpha_bound) == LARGER)
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
|
const FT sqd = Polygon_mesh_processing::squared_edge_length(e, wrap, np);
|
||||||
std::cerr << "Error: " << sqd << " greater than " << sq_alpha_bound << std::endl;
|
std::cerr << "Error: " << sqd << " greater than " << sq_alpha_bound << std::endl;
|
||||||
std::cerr << get(CGAL::vertex_point, output_mesh, source(e, output_mesh)) << std::endl;
|
std::cerr << "source pt: " << get(vpm, source(e, wrap)) << std::endl;
|
||||||
std::cerr << get(CGAL::vertex_point, output_mesh, target(e, output_mesh)) << std::endl;
|
std::cerr << "target pt: " << get(vpm, target(e, wrap)) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -346,13 +356,12 @@ bool is_outer_wrap_of_point_set(const TriangleMesh& wrap,
|
||||||
|
|
||||||
CGAL::Side_of_triangle_mesh<TriangleMesh, K, OVPM> side_of_wrap(wrap, out_vpm);
|
CGAL::Side_of_triangle_mesh<TriangleMesh, K, OVPM> side_of_wrap(wrap, out_vpm);
|
||||||
|
|
||||||
// @speed a single vertex per CC would be sufficient
|
|
||||||
for(const auto& p : points)
|
for(const auto& p : points)
|
||||||
{
|
{
|
||||||
if(side_of_wrap(get(in_pm, p)) != CGAL::ON_BOUNDED_SIDE)
|
if(side_of_wrap(get(in_pm, p)) != CGAL::ON_BOUNDED_SIDE)
|
||||||
{
|
{
|
||||||
#ifdef CGAL_AW3_DEBUG
|
#ifdef CGAL_AW3_DEBUG
|
||||||
std::cerr << "Part(s) of the input mesh are outside the wrap: " << get(in_pm, p) << std::endl;
|
std::cerr << "An input point is outside the wrap: " << get(in_pm, p) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ void alpha_wrap_3(const PointRange& points,
|
||||||
Geom_traits gt = choose_parameter<Geom_traits>(get_parameter(in_np, internal_np::geom_traits));
|
Geom_traits gt = choose_parameter<Geom_traits>(get_parameter(in_np, internal_np::geom_traits));
|
||||||
|
|
||||||
Oracle oracle(gt);
|
Oracle oracle(gt);
|
||||||
oracle.add_point_set(points, in_np);
|
oracle.add_points(points, in_np);
|
||||||
AW3 alpha_wrap_builder(oracle);
|
AW3 alpha_wrap_builder(oracle);
|
||||||
alpha_wrap_builder(alpha, offset, alpha_wrap, in_np, out_np);
|
alpha_wrap_builder(alpha, offset, alpha_wrap, in_np, out_np);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!enforce_manifoldness)
|
if(!enforce_manifoldness)
|
||||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
assert(AW3::internal::has_bounded_edge_length(wrap, alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ void alpha_wrap_triangle_manifoldness(Mesh& input_mesh,
|
||||||
assert(AW3::internal::has_expected_Hausdorff_distance(nm_wrap, input_mesh, alpha, offset));
|
assert(AW3::internal::has_expected_Hausdorff_distance(nm_wrap, input_mesh, alpha, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(AW3::internal::check_edge_length(nm_wrap, alpha));
|
assert(AW3::internal::has_bounded_edge_length(nm_wrap, alpha));
|
||||||
|
|
||||||
FT base_vol = 0;
|
FT base_vol = 0;
|
||||||
if(!is_closed(nm_wrap))
|
if(!is_closed(nm_wrap))
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ void alpha_wrap_triangle_soup(Points& pr,
|
||||||
|
|
||||||
// AW3
|
// AW3
|
||||||
Oracle oracle;
|
Oracle oracle;
|
||||||
oracle.add_triangle_soup(pr, fr);
|
oracle.add_triangles(pr, fr);
|
||||||
AW3::internal::Alpha_wrapper_3<Oracle> aw3(oracle);
|
AW3::internal::Alpha_wrapper_3<Oracle> aw3(oracle);
|
||||||
|
|
||||||
Mesh wrap;
|
Mesh wrap;
|
||||||
|
|
@ -65,7 +65,7 @@ void alpha_wrap_triangle_soup(Points& pr,
|
||||||
assert(AW3::internal::is_valid_wrap(wrap, false /*manifoldness*/));
|
assert(AW3::internal::is_valid_wrap(wrap, false /*manifoldness*/));
|
||||||
assert(AW3::internal::is_outer_wrap_of_triangle_soup(wrap, pr, fr));
|
assert(AW3::internal::is_outer_wrap_of_triangle_soup(wrap, pr, fr));
|
||||||
assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
||||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
assert(AW3::internal::has_bounded_edge_length(wrap, alpha));
|
||||||
|
|
||||||
alpha *= 2;
|
alpha *= 2;
|
||||||
offset *= 2;
|
offset *= 2;
|
||||||
|
|
@ -83,7 +83,7 @@ void alpha_wrap_triangle_soup(Points& pr,
|
||||||
assert(AW3::internal::is_valid_wrap(wrap_2, false /*manifoldness*/));
|
assert(AW3::internal::is_valid_wrap(wrap_2, false /*manifoldness*/));
|
||||||
assert(AW3::internal::is_outer_wrap_of_triangle_soup(wrap_2, pr, fr));
|
assert(AW3::internal::is_outer_wrap_of_triangle_soup(wrap_2, pr, fr));
|
||||||
assert(AW3::internal::has_expected_Hausdorff_distance(wrap_2, input_mesh, alpha, offset));
|
assert(AW3::internal::has_expected_Hausdorff_distance(wrap_2, input_mesh, alpha, offset));
|
||||||
assert(AW3::internal::check_edge_length(wrap_2, alpha));
|
assert(AW3::internal::has_bounded_edge_length(wrap_2, alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
void alpha_wrap_triangle_soup(const std::string& filename)
|
void alpha_wrap_triangle_soup(const std::string& filename)
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!enforce_manifoldness)
|
if(!enforce_manifoldness)
|
||||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
assert(AW3::internal::has_bounded_edge_length(wrap, alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
void alpha_wrap_triangle_mesh(const std::string& filename,
|
void alpha_wrap_triangle_mesh(const std::string& filename,
|
||||||
|
|
|
||||||
|
|
@ -732,11 +732,11 @@ public Q_SLOTS:
|
||||||
Oracle oracle(ss_oracle);
|
Oracle oracle(ss_oracle);
|
||||||
|
|
||||||
if(wrap_triangles)
|
if(wrap_triangles)
|
||||||
oracle.add_triangle_soup(triangles);
|
oracle.add_triangles(triangles);
|
||||||
if(wrap_segments)
|
if(wrap_segments)
|
||||||
oracle.add_segment_soup(segments);
|
oracle.add_segments(segments);
|
||||||
if(wrap_points)
|
if(wrap_points)
|
||||||
oracle.add_point_set(points);
|
oracle.add_points(points);
|
||||||
|
|
||||||
if(!oracle.do_call())
|
if(!oracle.do_call())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue