diff --git a/Orthtree/include/CGAL/Octree.h b/Orthtree/include/CGAL/Octree.h index e59a19be46d5..b5d3f600d7ce 100644 --- a/Orthtree/include/CGAL/Octree.h +++ b/Orthtree/include/CGAL/Octree.h @@ -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 */ diff --git a/Orthtree/include/CGAL/Orthtree.h b/Orthtree/include/CGAL/Orthtree.h index 074d90b8bc49..6850afbf472c 100644 --- a/Orthtree/include/CGAL/Orthtree.h +++ b/Orthtree/include/CGAL/Orthtree.h @@ -125,7 +125,7 @@ class Orthtree { /// @{ #ifndef DOXYGEN_RUNNING static inline constexpr bool has_data = Orthtree_impl::has_Node_data::value; - static inline constexpr bool supports_neighbor_search = true;// Orthtree_impl::has_Squared_distance_of_element::value; + static inline constexpr bool supports_neighbor_search = Orthtree_impl::has_Squared_distance_of_element::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. @@ -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 + auto refine(size_t max_depth = 10, size_t bucket_size = 20) -> std::enable_if_t { refine(Orthtrees::Maximum_depth_and_maximum_contained_elements(max_depth, bucket_size)); } @@ -681,10 +682,10 @@ class Orthtree { \warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`. */ - template + template auto nearest_k_neighbors(const Point& query, std::size_t k, - OutputIterator output) const -> std::enable_if_t { + OutputIterator output) const -> std::enable_if_t { Sphere query_sphere(query, (std::numeric_limits::max)()); CGAL_precondition(k > 0); @@ -704,8 +705,8 @@ class Orthtree { \warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`. */ - template - auto neighbors_within_radius(const Sphere& query, OutputIterator output) const -> std::enable_if_t { + template + auto neighbors_within_radius(const Sphere& query, OutputIterator output) const -> std::enable_if_t { return nearest_k_neighbors_within_radius(query, (std::numeric_limits::max)(), output); } @@ -726,12 +727,12 @@ class Orthtree { \warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`. */ - template + template auto nearest_k_neighbors_within_radius( const Sphere& query, std::size_t k, OutputIterator output - ) const -> std::enable_if_t { + ) const -> std::enable_if_t { CGAL_precondition(k > 0); Sphere query_sphere = query; @@ -1298,13 +1299,13 @@ class Orthtree { return output; } - template + template auto nearest_k_neighbors_recursive( Sphere& search_bounds, Node_index node, std::vector& results, std::size_t k, - FT epsilon = 0) const -> std::enable_if_t { + FT epsilon = 0) const -> std::enable_if_t { // Check whether the node has children if (is_leaf(node)) { diff --git a/Orthtree/include/CGAL/Orthtree/Split_predicates.h b/Orthtree/include/CGAL/Orthtree/Split_predicates.h index c3b0d929b62e..8638387189f2 100644 --- a/Orthtree/include/CGAL/Orthtree/Split_predicates.h +++ b/Orthtree/include/CGAL/Orthtree/Split_predicates.h @@ -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. diff --git a/Orthtree/include/CGAL/Orthtree_traits_base.h b/Orthtree/include/CGAL/Orthtree_traits_base.h index 2d1ade67e927..dc31ba2dd2ff 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_base.h +++ b/Orthtree/include/CGAL/Orthtree_traits_base.h @@ -89,11 +89,16 @@ struct Orthtree_traits_base { using Adjacency = int; /// @} - auto construct_point_d_object() const { - return [](auto... Args) -> Point_d { - std::initializer_list args_list{Args...}; - return Point_d{static_cast(args_list.size()), args_list.begin(), args_list.end()}; - }; + struct Construct_point_d { + template > + Point_d operator()(Args ...args) { + std::initializer_list args_list{ args... }; + return Point_d{ static_cast(args_list.size()), args_list.begin(), args_list.end() }; + } + }; + + Construct_point_d construct_point_d_object() const { + return Construct_point_d(); } }; @@ -115,7 +120,9 @@ struct Orthtree_traits_base { 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}; }; @@ -153,7 +160,9 @@ struct Orthtree_traits_base { 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}; }; diff --git a/Orthtree/include/CGAL/Orthtree_traits_point.h b/Orthtree/include/CGAL/Orthtree_traits_point.h index f05416b91db7..130d6f2a1873 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_point.h +++ b/Orthtree/include/CGAL/Orthtree_traits_point.h @@ -96,11 +96,15 @@ struct Orthtree_traits_point : public Orthtree_traits_base::value_type; + static_assert(std::is_same_v::iterator_category, std::random_access_iterator_tag>); + 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 { @@ -152,41 +156,65 @@ struct Orthtree_traits_point : public Orthtree_traits_base 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) {} + 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;