mirror of https://github.com/CGAL/cgal
Orthtree: Doc and traits bugfixes (#8678)
## Summary of Changes Octree doc states requirement of RandomAccessIterator for point range added missing _object types for functors in traits ## Release Management * Affected package(s): Orthtree
This commit is contained in:
commit
17e6644f9f
|
|
@ -25,7 +25,7 @@ namespace CGAL {
|
||||||
\brief Alias that specializes the `Orthtree` class to a 3D octree storing 3D points.
|
\brief Alias that specializes the `Orthtree` class to a 3D octree storing 3D points.
|
||||||
|
|
||||||
\tparam GeomTraits a model of `Kernel`
|
\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 PointMap a model of `ReadablePropertyMap` whose value type is `GeomTraits::Point_3`
|
||||||
\tparam cubic_nodes Boolean to enforce cubic nodes
|
\tparam cubic_nodes Boolean to enforce cubic nodes
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
static inline constexpr bool has_data = Orthtree_impl::has_Node_data<GeomTraits>::value;
|
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
|
#else
|
||||||
static inline constexpr bool has_data = bool_value; ///< `true` if `GeomTraits` is a model of `OrthtreeTraitsWithData` and `false` otherwise.
|
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.
|
static inline constexpr bool supports_neighbor_search = bool_value; ///< `true` if `GeomTraits` is a model of `CollectionPartitioningOrthtreeTraits` and `false` otherwise.
|
||||||
|
|
@ -385,7 +385,8 @@ public:
|
||||||
\param max_depth deepest a tree is allowed to be (nodes at this depth will not be split).
|
\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.
|
\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));
|
refine(Orthtrees::Maximum_depth_and_maximum_contained_elements(max_depth, bucket_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -681,10 +682,10 @@ public:
|
||||||
|
|
||||||
\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
|
\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,
|
auto nearest_k_neighbors(const Point& query,
|
||||||
std::size_t k,
|
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)());
|
Sphere query_sphere(query, (std::numeric_limits<FT>::max)());
|
||||||
CGAL_precondition(k > 0);
|
CGAL_precondition(k > 0);
|
||||||
|
|
||||||
|
|
@ -704,8 +705,8 @@ public:
|
||||||
|
|
||||||
\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
|
\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
|
||||||
*/
|
*/
|
||||||
template<typename OutputIterator>
|
template<typename OutputIterator, typename Orthtree = Self>
|
||||||
auto neighbors_within_radius(const Sphere& query, OutputIterator output) const -> std::enable_if_t<supports_neighbor_search, OutputIterator> {
|
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);
|
return nearest_k_neighbors_within_radius(query, (std::numeric_limits<std::size_t>::max)(), output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -726,12 +727,12 @@ public:
|
||||||
|
|
||||||
\warning Nearest neighbor searches requires `GeomTraits` to be a model of `CollectionPartitioningOrthtreeTraits`.
|
\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(
|
auto nearest_k_neighbors_within_radius(
|
||||||
const Sphere& query,
|
const Sphere& query,
|
||||||
std::size_t k,
|
std::size_t k,
|
||||||
OutputIterator output
|
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);
|
CGAL_precondition(k > 0);
|
||||||
Sphere query_sphere = query;
|
Sphere query_sphere = query;
|
||||||
|
|
||||||
|
|
@ -1298,13 +1299,13 @@ private: // functions :
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Result>
|
template <typename Result, typename Orthtree = Self>
|
||||||
auto nearest_k_neighbors_recursive(
|
auto nearest_k_neighbors_recursive(
|
||||||
Sphere& search_bounds,
|
Sphere& search_bounds,
|
||||||
Node_index node,
|
Node_index node,
|
||||||
std::vector<Result>& results,
|
std::vector<Result>& results,
|
||||||
std::size_t k,
|
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
|
// Check whether the node has children
|
||||||
if (is_leaf(node)) {
|
if (is_leaf(node)) {
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ public:
|
||||||
\ingroup PkgOrthtreeSplitPredicates
|
\ingroup PkgOrthtreeSplitPredicates
|
||||||
\brief A class used to choose when a node should be split depending on the depth and the number of contained elements.
|
\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
|
certain number of items and if its depth is lower than a certain
|
||||||
limit.
|
limit.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,11 +89,16 @@ struct Orthtree_traits_base {
|
||||||
using Adjacency = int;
|
using Adjacency = int;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
auto construct_point_d_object() const {
|
struct Construct_point_d {
|
||||||
return [](auto... Args) -> Point_d {
|
template <typename ...Args, typename T = std::common_type_t<Args...>>
|
||||||
std::initializer_list<FT> args_list{Args...};
|
Point_d operator()(Args ...args) {
|
||||||
return Point_d{static_cast<int>(args_list.size()), args_list.begin(), args_list.end()};
|
std::initializer_list<T> args_list{ args... };
|
||||||
};
|
return Point_d{ static_cast<int>(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<GeomTraits, 2> {
|
||||||
UP
|
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 [](const FT& x, const FT& y) -> Point_d {
|
||||||
return {x, y};
|
return {x, y};
|
||||||
};
|
};
|
||||||
|
|
@ -153,7 +160,9 @@ struct Orthtree_traits_base<GeomTraits, 3> {
|
||||||
RIGHT_TOP_FRONT
|
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 [](const FT& x, const FT& y, const FT& z) -> Point_d {
|
||||||
return {x, y, z};
|
return {x, y, z};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -96,11 +96,15 @@ public:
|
||||||
using Node_index = typename Base::Node_index;
|
using Node_index = typename Base::Node_index;
|
||||||
using Node_data_element = typename std::iterator_traits<typename PointRange::iterator>::value_type;
|
using Node_data_element = typename std::iterator_traits<typename PointRange::iterator>::value_type;
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<typename std::iterator_traits<typename PointRange::iterator>::iterator_category, std::random_access_iterator_tag>);
|
||||||
|
|
||||||
Orthtree_traits_point(
|
Orthtree_traits_point(
|
||||||
PointRange& points,
|
PointRange& points,
|
||||||
PointMap point_map = PointMap()
|
PointMap point_map = PointMap()
|
||||||
) : m_points(points), m_point_map(point_map) {}
|
) : m_points(points), m_point_map(point_map) {}
|
||||||
|
|
||||||
|
using Construct_root_node_bbox = typename Self::Bbox_d(*)();
|
||||||
|
|
||||||
auto construct_root_node_bbox_object() const {
|
auto construct_root_node_bbox_object() const {
|
||||||
return [&]() -> typename Self::Bbox_d {
|
return [&]() -> typename Self::Bbox_d {
|
||||||
|
|
||||||
|
|
@ -152,41 +156,65 @@ public:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto construct_root_node_contents_object() const {
|
struct Construct_root_node_contents {
|
||||||
return [&]() -> typename Self::Node_data {
|
PointRange& m_points;
|
||||||
return {m_points.begin(), m_points.end()};
|
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 {
|
struct Distribute_node_contents {
|
||||||
return [&](Node_index n, Tree& tree, const typename Self::Point_d& center) {
|
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));
|
CGAL_precondition(!tree.is_leaf(n));
|
||||||
reassign_points(tree, m_point_map, n, center, tree.data(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 [](const typename Self::Point_d& center, const typename Self::FT& squared_radius) -> typename Self::Sphere_d {
|
||||||
return typename Self::Sphere_d(center, squared_radius);
|
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 [](const typename Self::Sphere_d& sphere) -> typename Self::Point_d {
|
||||||
return sphere.center();
|
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 [](const typename Self::Sphere_d& sphere) -> typename Self::FT {
|
||||||
return sphere.squared_radius();
|
return sphere.squared_radius();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto squared_distance_of_element_object() const {
|
struct Squared_distance_of_element {
|
||||||
return [&](const Node_data_element& index, const typename Self::Point_d& point) -> typename Self::FT {
|
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);
|
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;
|
PointRange& m_points;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue