Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Orthtree: Doc and traits bugfixes #8678

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Orthtree/include/CGAL/Octree.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace CGAL {
\brief Alias that specializes the `Orthtree` class to a 3D octree storing 3D points.

\tparam GeomTraits a model of `Kernel`
\tparam PointRange a model of `Range` whose value type is the key type of `PointMap`
\tparam PointRange a model of `Range` whose value type is the key type of `PointMap` and whose iterator type is a model of `RandomAccessIterator`
\tparam PointMap a model of `ReadablePropertyMap` whose value type is `GeomTraits::Point_3`
\tparam cubic_nodes Boolean to enforce cubic nodes
*/
Expand Down
21 changes: 11 additions & 10 deletions Orthtree/include/CGAL/Orthtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class Orthtree {
/// @{
#ifndef DOXYGEN_RUNNING
static inline constexpr bool has_data = Orthtree_impl::has_Node_data<GeomTraits>::value;
static inline constexpr bool supports_neighbor_search = true;// Orthtree_impl::has_Squared_distance_of_element<GeomTraits>::value;
static inline constexpr bool supports_neighbor_search = Orthtree_impl::has_Squared_distance_of_element<GeomTraits>::value;
#else
static inline constexpr bool has_data = bool_value; ///< `true` if `GeomTraits` is a model of `OrthtreeTraitsWithData` and `false` otherwise.
static inline constexpr bool supports_neighbor_search = bool_value; ///< `true` if `GeomTraits` is a model of `CollectionPartitioningOrthtreeTraits` and `false` otherwise.
Expand Down Expand Up @@ -385,7 +385,8 @@ class Orthtree {
\param max_depth deepest a tree is allowed to be (nodes at this depth will not be split).
\param bucket_size maximum number of items a node is allowed to contain.
*/
void refine(size_t max_depth = 10, size_t bucket_size = 20) {
template<typename Orthtree = Self>
auto refine(size_t max_depth = 10, size_t bucket_size = 20) -> std::enable_if_t<Orthtree::has_data, void> {
refine(Orthtrees::Maximum_depth_and_maximum_contained_elements(max_depth, bucket_size));
}

Expand Down Expand Up @@ -681,10 +682,10 @@ class Orthtree {

\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
*/
template<typename OutputIterator>
template<typename OutputIterator, typename Orthtree = Self>
auto nearest_k_neighbors(const Point& query,
std::size_t k,
OutputIterator output) const -> std::enable_if_t<supports_neighbor_search, OutputIterator> {
OutputIterator output) const -> std::enable_if_t<Orthtree::supports_neighbor_search, OutputIterator> {
Sphere query_sphere(query, (std::numeric_limits<FT>::max)());
CGAL_precondition(k > 0);

Expand All @@ -704,8 +705,8 @@ class Orthtree {

\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
*/
template<typename OutputIterator>
auto neighbors_within_radius(const Sphere& query, OutputIterator output) const -> std::enable_if_t<supports_neighbor_search, OutputIterator> {
template<typename OutputIterator, typename Orthtree = Self>
auto neighbors_within_radius(const Sphere& query, OutputIterator output) const -> std::enable_if_t<Orthtree::supports_neighbor_search, OutputIterator> {
return nearest_k_neighbors_within_radius(query, (std::numeric_limits<std::size_t>::max)(), output);
}

Expand All @@ -726,12 +727,12 @@ class Orthtree {

\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
*/
template <typename OutputIterator>
template <typename OutputIterator, typename Orthtree = Self>
auto nearest_k_neighbors_within_radius(
const Sphere& query,
std::size_t k,
OutputIterator output
) const -> std::enable_if_t<supports_neighbor_search, OutputIterator> {
) const -> std::enable_if_t<Orthtree::supports_neighbor_search, OutputIterator> {
CGAL_precondition(k > 0);
Sphere query_sphere = query;

Expand Down Expand Up @@ -1298,13 +1299,13 @@ class Orthtree {
return output;
}

template <typename Result>
template <typename Result, typename Orthtree = Self>
auto nearest_k_neighbors_recursive(
Sphere& search_bounds,
Node_index node,
std::vector<Result>& results,
std::size_t k,
FT epsilon = 0) const -> std::enable_if_t<supports_neighbor_search> {
FT epsilon = 0) const -> std::enable_if_t<Orthtree::supports_neighbor_search> {

// Check whether the node has children
if (is_leaf(node)) {
Expand Down
2 changes: 1 addition & 1 deletion Orthtree/include/CGAL/Orthtree/Split_predicates.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class Maximum_depth {
\ingroup PkgOrthtreeSplitPredicates
\brief A class used to choose when a node should be split depending on the depth and the number of contained elements.

This predicate makes a note split if it contains more than a
This predicate makes a node split if it contains more than a
certain number of items and if its depth is lower than a certain
limit.

Expand Down
10 changes: 8 additions & 2 deletions Orthtree/include/CGAL/Orthtree_traits_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ struct Orthtree_traits_base {
using Adjacency = int;
/// @}

//using Construct_point_d = Point_d(*)(std::initializer_list<FT> args);

auto construct_point_d_object() const {
return [](auto... Args) -> Point_d {
std::initializer_list<FT> args_list{Args...};
Expand All @@ -115,7 +117,9 @@ struct Orthtree_traits_base<GeomTraits, 2> {
UP
};

auto construct_point_d_object() const {
using Construct_point_d = Point_d(*)(const FT&, const FT&);

Construct_point_d construct_point_d_object() const {
return [](const FT& x, const FT& y) -> Point_d {
return {x, y};
};
Expand Down Expand Up @@ -153,7 +157,9 @@ struct Orthtree_traits_base<GeomTraits, 3> {
RIGHT_TOP_FRONT
};

auto construct_point_d_object() const {
using Construct_point_d = Point_d(*)(const FT&, const FT&, const FT&);

Construct_point_d construct_point_d_object() const {
return [](const FT& x, const FT& y, const FT& z) -> Point_d {
return {x, y, z};
};
Expand Down
52 changes: 40 additions & 12 deletions Orthtree/include/CGAL/Orthtree_traits_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,15 @@ struct Orthtree_traits_point : public Orthtree_traits_base<GeomTraits, dimension
using Node_index = typename Base::Node_index;
using Node_data_element = typename std::iterator_traits<typename PointRange::iterator>::value_type;

static_assert(std::is_same<typename std::iterator_traits<typename PointRange::iterator>::iterator_category, std::random_access_iterator_tag>::value);
soesau marked this conversation as resolved.
Show resolved Hide resolved

Orthtree_traits_point(
PointRange& points,
PointMap point_map = PointMap()
) : m_points(points), m_point_map(point_map) {}

using Construct_root_node_bbox = typename Self::Bbox_d(*)();

auto construct_root_node_bbox_object() const {
return [&]() -> typename Self::Bbox_d {

Expand Down Expand Up @@ -152,41 +156,65 @@ struct Orthtree_traits_point : public Orthtree_traits_base<GeomTraits, dimension
};
}

auto construct_root_node_contents_object() const {
return [&]() -> typename Self::Node_data {
return {m_points.begin(), m_points.end()};
};
struct Construct_root_node_contents {
PointRange& m_points;
Construct_root_node_contents(PointRange& points) : m_points(points) {}
typename Self::Node_data operator()() {
return { m_points.begin(), m_points.end() };
}
};

Construct_root_node_contents construct_root_node_contents_object() const {
return Construct_root_node_contents(m_points);
}

auto distribute_node_contents_object() const {
return [&](Node_index n, Tree& tree, const typename Self::Point_d& center) {
struct Distribute_node_contents {
const PointMap m_point_map;
Distribute_node_contents(const PointMap& point_map) : m_point_map(point_map) {}
typename void operator()(Node_index n, Tree& tree, const typename Self::Point_d& center) {
CGAL_precondition(!tree.is_leaf(n));
reassign_points(tree, m_point_map, n, center, tree.data(n));
};
};

Distribute_node_contents distribute_node_contents_object() const {
return Distribute_node_contents(m_point_map);
}

auto construct_sphere_d_object() const {
using Construct_sphere_d = typename Self::Sphere_d(*)(const typename Self::Point_d&, const typename Self::FT&);

Construct_sphere_d construct_sphere_d_object() const {
return [](const typename Self::Point_d& center, const typename Self::FT& squared_radius) -> typename Self::Sphere_d {
return typename Self::Sphere_d(center, squared_radius);
};
}

auto construct_center_d_object() const {
using Construct_center_d = typename Self::Point_d(*)(const typename Self::Sphere_d&);

Construct_center_d construct_center_d_object() const {
return [](const typename Self::Sphere_d& sphere) -> typename Self::Point_d {
return sphere.center();
};
}

auto compute_squared_radius_d_object() const {
using Compute_squared_radius_d = typename Self::FT(*)(const typename Self::Sphere_d&);

Compute_squared_radius_d compute_squared_radius_d_object() const {
return [](const typename Self::Sphere_d& sphere) -> typename Self::FT {
return sphere.squared_radius();
};
}

auto squared_distance_of_element_object() const {
return [&](const Node_data_element& index, const typename Self::Point_d& point) -> typename Self::FT {
struct Squared_distance_of_element {
const PointMap m_point_map;
Squared_distance_of_element(const PointMap& point_map) : m_point_map(point_map) {}
typename Self::FT operator()(const Node_data_element& index, const typename Self::Point_d& point) {
return CGAL::squared_distance(get(m_point_map, index), point);
};
};
};

Squared_distance_of_element squared_distance_of_element_object() const {
return Squared_distance_of_element(m_point_map);
}

PointRange& m_points;
Expand Down
Loading