More corrections from review

This commit is contained in:
Simon Giraudot 2021-04-01 14:21:01 +02:00
parent 1794620ab9
commit 4d761ed9cd
16 changed files with 135 additions and 126 deletions

View File

@ -14,7 +14,7 @@ Release date: June 2021
A comprehensive list of the supported file formats is available in the Stream_support package [here](https://doc.cgal.org/5.3/Stream_support/index.html#IOstreamSupportedFormats); inversely, the following [page](https://doc.cgal.org/5.3/Stream_support/IOStreamSupportedFileFormats.html) can be used to find out which CGAL data structures can be used given a specific file format. A comprehensive list of the supported file formats is available in the Stream_support package [here](https://doc.cgal.org/5.3/Stream_support/index.html#IOstreamSupportedFormats); inversely, the following [page](https://doc.cgal.org/5.3/Stream_support/IOStreamSupportedFileFormats.html) can be used to find out which CGAL data structures can be used given a specific file format.
### [Quadtrees, Octrees and Orthtrees](https://doc.cgal.org/5.3/Manual/packages.html#PkgOrthree) (new package) ### [Quadtrees, Octrees, and Orthtrees](https://doc.cgal.org/5.3/Manual/packages.html#PkgOrthree) (new package)
- This package implements a tree data structure in which each node - This package implements a tree data structure in which each node
encloses a hypercubic section of space and each non-leave node has encloses a hypercubic section of space and each non-leave node has

View File

@ -32,7 +32,7 @@ Minkowski_sum_3 3D Minkowski Sum of Polyhedra
Nef_2 2D Boolean Operations on Nef Polygons Nef_2 2D Boolean Operations on Nef Polygons
Nef_3 3D Boolean Operations on Nef Polyhedra Nef_3 3D Boolean Operations on Nef Polyhedra
Nef_S2 2D Boolean Operations on Nef Polygons Embedded on the Sphere Nef_S2 2D Boolean Operations on Nef Polygons Embedded on the Sphere
Orthtree Quadtrees, Octrees and Orthrees Orthtree Quadtrees, Octrees, and Orthrees
Optimal_bounding_box Optimal Bounding Box Optimal_bounding_box Optimal Bounding Box
Optimal_transportation_reconstruction_2 Optimal Transportation Curve Reconstruction Optimal_transportation_reconstruction_2 Optimal Transportation Curve Reconstruction
Partition_2 2D Polygon Partitioning Partition_2 2D Polygon Partitioning

View File

@ -37,7 +37,7 @@ public:
typedef unspecified_type Construct_point_d_from_array; typedef unspecified_type Construct_point_d_from_array;
/*! /*!
Functor with an operator to construct a `Bbox_d` from two `Point_d` object (minimum and maximum points). Functor with an operator to construct a `Bbox_d` from two `Array` objects (coordinates of minimum and maximum points).
*/ */
typedef unspecified_type Construct_bbox_d; typedef unspecified_type Construct_bbox_d;

View File

@ -1,6 +1,6 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Quadtrees, Octrees and Orthtrees" PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Quadtrees, Octrees, and Orthtrees"
EXTRACT_ALL = false EXTRACT_ALL = false
HIDE_UNDOC_MEMBERS = true HIDE_UNDOC_MEMBERS = true

View File

@ -17,7 +17,7 @@ exactly 8 children.
We call the generalization of such data structure "orthtrees", as We call the generalization of such data structure "orthtrees", as
orthants are generalizations of quadrants and octants. The term orthants are generalizations of quadrants and octants. The term
"hyperoctree" can also be found in litterature to name such data "hyperoctree" can also be found in literature to name such data
structures in dimensions 4 and higher. structures in dimensions 4 and higher.
This package provides a general data structure `Orthtree` along with This package provides a general data structure `Orthtree` along with
@ -188,14 +188,14 @@ The naive way of finding the nearest neighbor of a point requires finding the di
An orthtree can be used to perform the same task in significantly less time. An orthtree can be used to perform the same task in significantly less time.
For large numbers of points, this can be a large enough difference to outweigh the time spent building the tree. For large numbers of points, this can be a large enough difference to outweigh the time spent building the tree.
Note that a kD-tree is expected to outperform the orthtree for this task, Note that a kd-tree is expected to outperform the orthtree for this task,
it should be preferred unless features specific to the orthtree are needed. it should be preferred unless features specific to the orthtree are needed.
The following example illustrates how to use an octree to accelerate the search for points close to a location. The following example illustrates how to use an octree to accelerate the search for points close to a location.
Points are loaded from a file and an octree is built. Points are loaded from a file and an octree is built.
The nearest neighbor method is invoked for several input points. The nearest neighbor method is invoked for several input points.
A k value of 1 is used to find the single closest point. A `k` value of 1 is used to find the single closest point.
Results are put in a vector, and then printed. Results are put in a vector, and then printed.
\cgalExample{Orthtree/octree_find_nearest_neighbor.cpp} \cgalExample{Orthtree/octree_find_nearest_neighbor.cpp}
@ -224,7 +224,7 @@ The tree is printed before and after grading, so that the differences are visibl
Tree construction benchmarks were conducted by randomly generating a collection of points, Tree construction benchmarks were conducted by randomly generating a collection of points,
and then timing the process of creating a fully refined tree which contains them. and then timing the process of creating a fully refined tree which contains them.
Because of its simplicity, an octree can be constructed faster than a kD-tree. Because of its simplicity, an octree can be constructed faster than a kd-tree.
\cgalFigureBegin{Orthtree_construction_benchmark_fig, construction_benchmark.png} \cgalFigureBegin{Orthtree_construction_benchmark_fig, construction_benchmark.png}
%Plot of the time to construct a tree. %Plot of the time to construct a tree.
@ -232,7 +232,7 @@ Because of its simplicity, an octree can be constructed faster than a kD-tree.
\subsection Section_Orthtree_Performance_Nearest_Neighbors Nearest Neighbors \subsection Section_Orthtree_Performance_Nearest_Neighbors Nearest Neighbors
%Orthtree nodes are uniform, so orthtrees will tend to have deeper hierarchies than equivalent kD-trees. %Orthtree nodes are uniform, so orthtrees will tend to have deeper hierarchies than equivalent kd-trees.
As a result, orthtrees will generally perform worse for nearest neighbor searches. As a result, orthtrees will generally perform worse for nearest neighbor searches.
Both nearest neighbor algorithms have a theoretical complexity of O(log(n)), Both nearest neighbor algorithms have a theoretical complexity of O(log(n)),
but the orthtree can generally be expected to have a higher coefficient. but the orthtree can generally be expected to have a higher coefficient.
@ -246,7 +246,7 @@ but both algorithms compare very favorably to the linear complexity of the naive
which involves comparing every point to the search point. which involves comparing every point to the search point.
Using the orthtree for nearest neighbor computations instead of the Using the orthtree for nearest neighbor computations instead of the
kD-tree can be justified either when few queries are needed (as the kd-tree can be justified either when few queries are needed (as the
construction is faster) or when the orthtree is also needed for other construction is faster) or when the orthtree is also needed for other
purposes. purposes.
@ -254,7 +254,7 @@ purposes.
%Plot of the time to find nearest neighbors using tree methods and a naive approach. %Plot of the time to find nearest neighbors using tree methods and a naive approach.
\cgalFigureEnd \cgalFigureEnd
For nontrivial point counts, the naive approach's calculation time dwarfs that of either the %orthtree or kD-tree. For nontrivial point counts, the naive approach's calculation time dwarfs that of either the %orthtree or kd-tree.
\section Section_Orthtree_History History \section Section_Orthtree_History History

View File

@ -18,10 +18,10 @@
/*! /*!
\addtogroup PkgOrthtreeRef \addtogroup PkgOrthtreeRef
\cgalPkgDescriptionBegin{Quadtrees\, Octrees and Orthtrees,PkgOrthtree} \cgalPkgDescriptionBegin{Quadtrees\, Octrees\, and Orthtrees,PkgOrthtree}
\cgalPkgPicture{octree_thumbnail.png} \cgalPkgPicture{octree_thumbnail.png}
\cgalPkgSummaryBegin \cgalPkgSummaryBegin
\cgalPkgAuthor{Jackson Campolattaro, Simon Giraudot, Cédric Portaneri, Tong Zhao, Pierre Alliez} \cgalPkgAuthors{Jackson Campolattaro, Simon Giraudot, Cédric Portaneri, Tong Zhao, Pierre Alliez}
\cgalPkgDesc{The Orthtree package provides a data structure that subdivides space, with specializations for 2D (Quadtree) and 3D (Octree), along with a collection of algorithms for operating on these structures.} \cgalPkgDesc{The Orthtree package provides a data structure that subdivides space, with specializations for 2D (Quadtree) and 3D (Octree), along with a collection of algorithms for operating on these structures.}
\cgalPkgManuals{Chapter_Orthtree,PkgOrthtreeRef} \cgalPkgManuals{Chapter_Orthtree,PkgOrthtreeRef}
\cgalPkgSummaryEnd \cgalPkgSummaryEnd

View File

@ -22,7 +22,7 @@ namespace CGAL {
/*! /*!
\ingroup PkgOrthtreeClasses \ingroup PkgOrthtreeClasses
\brief Alias that specialized the `Orthtree` class to a 3D Octree. \brief Alias that specializes the `Orthtree` class to a 3D octree.
These two types are exactly equivalent: These two types are exactly equivalent:
- `Octree<GeomTraits, PointRange, PointMap>` - `Octree<GeomTraits, PointRange, PointMap>`
@ -31,9 +31,9 @@ namespace CGAL {
\warning This is a not a real class but an alias, please refer to \warning This is a not a real class but an alias, please refer to
the documentation of `Orthtree`. the documentation of `Orthtree`.
\tparam GeomTraits is a model of Kernel \tparam GeomTraits must be a model of `Kernel`
\tparam PointRange_ is a model of range whose value type is the key type of `PointMap` \tparam PointRange_ must be a model of range whose value type is the key type of `PointMap`
\tparam PointMap is a model of `ReadablePropertyMap` whose value type is `GeomTraits::Point_3` \tparam PointMap must be a model of `ReadablePropertyMap` whose value type is `GeomTraits::Point_3`
*/ */
template <typename GeomTraits, typename PointRange, template <typename GeomTraits, typename PointRange,
typename PointMap = Identity_property_map typename PointMap = Identity_property_map

View File

@ -40,29 +40,28 @@
#include <vector> #include <vector>
#include <math.h> #include <math.h>
using namespace std::placeholders;
namespace CGAL { namespace CGAL {
/*! /*!
\ingroup PkgOrthtreeClasses \ingroup PkgOrthtreeClasses
\brief A data structure using an axis aligned hybercubic \brief A data structure using an axis-aligned hybercubic
decomposition of dD space for efficient point access and decomposition of dD space for efficient point access and
computations. computations.
\details It builds a hierarchy of nodes which subdivide the space \details It builds a hierarchy of nodes which subdivide the space
based on a collection of points. Each node represents an axis based on a collection of points. Each node represents an
aligned hypercubic region of space. A node contains the range of axis-aligned hypercubic region of space. A node contains the range
points that are present in the region it defines, and it may contain of points that are present in the region it defines, and it may
\f$2^{dim}\f$ other nodes which further subdivide the region. contain \f$2^{dim}\f$ other nodes which further subdivide the
region.
\sa Quadtree \sa `CGAL::Quadtree`
\sa Octree \sa `CGAL::Octree`
\tparam Traits_ is a model of `OrthtreeTraits` \tparam Traits_ must be a model of `OrthtreeTraits`
\tparam PointRange_ is a model of range whose value type is the key type of `PointMap_` \tparam PointRange_ must be a model of range whose value type is the key type of `PointMap_`
\tparam PointMap_ is a model of `ReadablePropertyMap` whose value type is `Traits_::Point_d` \tparam PointMap_ must be a model of `ReadablePropertyMap` whose value type is `Traits_::Point_d`
*/ */
template<typename Traits_, typename PointRange_, template<typename Traits_, typename PointRange_,
typename PointMap_ = Identity_property_map<typename Traits_::Point_d> > typename PointMap_ = Identity_property_map<typename Traits_::Point_d> >
@ -99,22 +98,22 @@ public:
/// @{ /// @{
/*! /*!
* \brief self typedef for convenience * \brief Self typedef for convenience.
*/ */
typedef Orthtree<Traits, PointRange, PointMap> Self; typedef Orthtree<Traits, PointRange, PointMap> Self;
/*! /*!
* \brief Degree of the tree (number of children of non-leaf nodes) * \brief Degree of the tree (number of children of non-leaf nodes).
*/ */
typedef Dimension_tag<(2 << (Dimension::value-1))> Degree; typedef Dimension_tag<(2 << (Dimension::value-1))> Degree;
/*! /*!
* \brief The Sub-tree / Orthant type * \brief The Sub-tree / Orthant type.
*/ */
class Node; class Node;
/*! /*!
* \brief A predicate that determines whether a node must be split when refining a tree * \brief A predicate that determines whether a node must be split when refining a tree.
*/ */
typedef std::function<bool(Node)> Split_predicate; typedef std::function<bool(Node)> Split_predicate;
@ -130,7 +129,7 @@ public:
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
/*! /*!
* \brief A function that determines the next node in a traversal given the current one * \brief A function that determines the next node in a traversal given the current one.
*/ */
typedef std::function<Node(Node)> Node_traversal_method_const; typedef std::function<Node(Node)> Node_traversal_method_const;
@ -139,7 +138,7 @@ public:
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
typedef typename PointRange::iterator Range_iterator; typedef typename PointRange::iterator Range_iterator;
typedef typename std::iterator_traits<Range_iterator>::value_type Range_type; typedef typename std::iterator_traits<Range_iterator>::value_type Range_type;
typedef internal::Cartesian_ranges<Traits> Cartesian_ranges; typedef Orthtrees::internal::Cartesian_ranges<Traits> Cartesian_ranges;
/// \endcond /// \endcond
/// @} /// @}
@ -164,7 +163,7 @@ public:
/// @{ /// @{
/*! /*!
\brief Create an orthtree from a collection of points \brief creates an orthtree from a collection of points.
The constructed orthtree has a root node, with no children, that The constructed orthtree has a root node, with no children, that
contains the points passed. That root node has a bounding box that contains the points passed. That root node has a bounding box that
@ -181,7 +180,7 @@ public:
with all Orthtree functionality, but any performance benefits are with all Orthtree functionality, but any performance benefits are
unlikely to be realized until `refine()` is called. unlikely to be realized until `refine()` is called.
\warning the input point range is not copied. It is used directly \warning The input point range is not copied. It is used directly
and is rearranged by the `Orthtree`. Altering the point range and is rearranged by the `Orthtree`. Altering the point range
after creating the orthtree might leave it in an invalid state. after creating the orthtree might leave it in an invalid state.
@ -293,11 +292,11 @@ public:
/*! /*!
\brief recursively subdivides the orthtree until it meets the given criteria. \brief recursively subdivides the orthtree until it meets the given criteria.
The split predicate is a `std::function` that takes a Node and The split predicate is a `std::function` that takes a `Node` and
returns a Boolean value (where `true` implies that a Node needs to returns a Boolean value (where `true` implies that a `Node` needs to
be split, `false` that the Node should be a leaf). be split, `false` that the `Node` should be a leaf).
This function function may be called several times with different This function may be called several times with different
predicates: in that case, nodes already split are left unaltered, predicates: in that case, nodes already split are left unaltered,
while nodes that were not split and for which `split_predicate` while nodes that were not split and for which `split_predicate`
returns `true` are split. returns `true` are split.
@ -348,15 +347,15 @@ public:
/*! /*!
\brief convenience overload that refines an orthtree using a \brief Convenience overload that refines an orthtree using a
maximum depth and maximum number of points in a node as split maximum depth and maximum number of points in a node as split
predicate. predicate.
This is equivalent to calling This is equivalent to calling
`refine(Orthtrees::Maximum_depth_and_maximum_number_of_inliers(min_depth, `refine(Orthtrees::Maximum_depth_and_maximum_number_of_inliers(max_depth,
bucket_size))`. bucket_size))`.
The refinement is stopped as soon as one of the condition is The refinement is stopped as soon as one of the conditions is
violated: if a node has more inliers than `bucket_size` but is violated: if a node has more inliers than `bucket_size` but is
already at `max_depth`, it is not split. Similarly, a node that is already at `max_depth`, it is not split. Similarly, a node that is
at a depth smaller than `max_depth` but already has fewer inliers at a depth smaller than `max_depth` but already has fewer inliers
@ -439,7 +438,7 @@ public:
Node root() const { return m_root; } Node root() const { return m_root; }
/*! /*!
\brief convenience function to access the child nodes of the root \brief Convenience function to access the child nodes of the root
node by their indices. node by their indices.
`my_tree[5]` is equivalent to `my_tree.root()[5]`. `my_tree[5]` is equivalent to `my_tree.root()[5]`.
@ -457,14 +456,16 @@ public:
std::size_t depth() const { return m_side_per_depth.size() - 1; } std::size_t depth() const { return m_side_per_depth.size() - 1; }
/*! /*!
\brief constructs a node range using a tree traversal function. \brief constructs a node range using a tree-traversal function.
This method allows to iterate on the nodes of the tree with a This method allows to iterate on the nodes of the tree with a
user-selected order (preorder, postorder, leaves only, etc.). user-selected order (preorder, postorder, leaves-only, etc.).
\tparam Traversal model of `OrthtreeTraversal` that provides functions \tparam Traversal model of `OrthtreeTraversal` that provides functions
compatible with the type of the orthree compatible with the type of the orthree
\param traversal
\param traversal the instance of `Traversal` used
\return a forward input iterator over the nodes of the tree \return a forward input iterator over the nodes of the tree
*/ */
template<typename Traversal> template<typename Traversal>
@ -511,7 +512,7 @@ public:
/// @{ /// @{
/*! /*!
\brief find the leaf node which contains the point `p`. \brief finds the leaf node which contains the point `p`.
Traverses the orthtree and finds the deepest cell that has a Traverses the orthtree and finds the deepest cell that has a
domain enclosing the point passed. The point passed must be within domain enclosing the point passed. The point passed must be within
@ -555,9 +556,9 @@ public:
`query`. `query`.
\tparam OutputIterator a model of `OutputIterator` that accept `Point_d` objects. \tparam OutputIterator a model of `OutputIterator` that accept `Point_d` objects.
\param query query point. \param query a query point.
\param k number of neighbors. \param k the number of neighbors.
\param output output iterator. \param output the output iterator.
*/ */
template<typename OutputIterator> template<typename OutputIterator>
OutputIterator nearest_neighbors (const Point& query, OutputIterator nearest_neighbors (const Point& query,
@ -585,7 +586,7 @@ public:
} }
/*! /*!
\brief find the leaf nodes that intersect with any primitive. \brief finds the leaf nodes that intersect with any primitive.
\note this function requires the function \note this function requires the function
`bool CGAL::do_intersect(QueryType, Traits::Bbox_d)` to be defined. `bool CGAL::do_intersect(QueryType, Traits::Bbox_d)` to be defined.
@ -608,7 +609,7 @@ public:
/// @{ /// @{
/*! /*!
\brief compares the topology of the orthtree with `rhs`. \brief compares the topology of the orthtree with that of `rhs`.
Trees may be considered equivalent even if they contain different points. Trees may be considered equivalent even if they contain different points.
Equivalent trees must have the same bounding box and the same node structure. Equivalent trees must have the same bounding box and the same node structure.
@ -629,7 +630,7 @@ public:
} }
/*! /*!
\brief compares the topology of the orthtree with `rhs`. \brief compares the topology of the orthtree with that of `rhs`.
*/ */
bool operator!=(const Self &rhs) const { bool operator!=(const Self &rhs) const {
return !operator==(rhs); return !operator==(rhs);
@ -697,7 +698,7 @@ private: // functions :
void split(Node& node) { void split(Node& node) {
// Make sure the node hasn't already been split // Make sure the node hasn't already been split
assert(node.is_leaf()); CGAL_precondition (node.is_leaf());
// Split the node to create children // Split the node to create children
node.split(); node.split();
@ -731,6 +732,11 @@ private: // functions :
struct Node_index_with_distance { struct Node_index_with_distance {
typename Node::Local_coordinates index; typename Node::Local_coordinates index;
FT distance; FT distance;
Node_index_with_distance (const typename Node::Local_coordinates& index,
const FT& distance)
: index(index), distance(distance)
{ }
}; };
void nearest_k_neighbors_recursive(Sphere& search_bounds, const Node &node, void nearest_k_neighbors_recursive(Sphere& search_bounds, const Node &node,
@ -791,10 +797,8 @@ private: // functions :
Node child_node = node[index]; Node child_node = node[index];
// Add a child to the list, with its distance // Add a child to the list, with its distance
children_with_distances.push_back( children_with_distances.emplace_back(typename Node::Local_coordinates(index),
{typename Node::Local_coordinates(index), CGAL::squared_distance(search_bounds.center(), barycenter(child_node)));
CGAL::squared_distance(search_bounds.center(), barycenter(child_node))}
);
} }
// Sort the children by their distance from the search point // Sort the children by their distance from the search point
@ -841,14 +845,14 @@ private: // functions :
\brief finds the `k` points within a specific radius that are nearest to `query`. \brief finds the `k` points within a specific radius that are nearest to `query`.
This function guarantees that there are no closer points than the ones returned, This function guarantees that there are no closer points than the ones returned,
but it does not guarantee that it will return at least K points. but it does not guarantee that it will return at least `k` points.
For a query where the search radius encloses K or fewer points, all enclosed points will be returned. For a query where the search radius encloses `k` or fewer points, all enclosed points will be returned.
If the search radius passed is too small, no points may be returned. If the search radius passed is too small, no points may be returned.
This function is useful when the user already knows how sparse the points are, This function is useful when the user already knows how sparse the points are,
or if they don't care about points that are too far away. or if they do not care about points that are too far away.
Setting a small radius may have performance benefits. Setting a small radius may have performance benefits.
\tparam Point_output_iterator an output iterator type that will accept points \tparam OutputIterator must be a model of `OutputIterator` that accepts points
\param search_point the location to find points near \param search_point the location to find points near
\param search_radius_squared the size of the region to search within \param search_radius_squared the size of the region to search within
\param k the number of points to find \param k the number of points to find

View File

@ -20,6 +20,9 @@
namespace CGAL namespace CGAL
{ {
namespace Orthtrees
{
namespace internal namespace internal
{ {
@ -54,6 +57,8 @@ struct Cartesian_ranges
} // namespace internal } // namespace internal
} // namespace Orthtrees
} // namespace CGAL } // namespace CGAL

View File

@ -52,12 +52,12 @@ struct Node_access
/*! /*!
\brief represents a single node of the tree. Alternatively referred \brief represents a single node of the tree. Alternatively referred
to as a cell, orthant, or subtree. to as a cell, orthant, or sub-tree.
A `Node` is a lightweight object and thus generally passed by A `Node` is a lightweight object and thus generally passed by
copy. It is also a `ConstRange` whose value type is `Traits::Point_d`. copy. It is also a model of `ConstRange` with value type `Traits::Point_d`.
\cgalModels ConstRange \cgalModels `ConstRange`
*/ */
template<typename Traits, typename PointRange, typename PointMap> template<typename Traits, typename PointRange, typename PointMap>
class Orthtree<Traits, PointRange, PointMap>::Node class Orthtree<Traits, PointRange, PointMap>::Node
@ -73,33 +73,33 @@ public:
typedef typename Enclosing::Degree Degree; ///< Degree type. typedef typename Enclosing::Degree Degree; ///< Degree type.
/*! /*!
\brief self typedef for convenience \brief Self typedef for convenience.
*/ */
typedef typename Orthtree<Traits, PointRange, PointMap>::Node Self; typedef typename Orthtree<Traits, PointRange, PointMap>::Node Self;
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
/*! /*!
* \brief array for containing the child nodes of this node * \brief Array for containing the child nodes of this node.
*/ */
typedef std::array<Self, Degree::value> Children; typedef std::array<Self, Degree::value> Children;
/// \endcond /// \endcond
/*! /*!
\brief set of bits representing this node's relationship to its parent. \brief Set of bits representing this node's relationship to its parent.
Equivalent to an array of Booleans, where index[0] is whether x Equivalent to an array of Booleans, where index[0] is whether `x`
is greater, index[1] is whether y is greater, index[2] is whether is greater, index[1] is whether `y` is greater, index[2] is whether
z is greater, and so on for higher dimensions if needed. `z` is greater, and so on for higher dimensions if needed.
Used to represent a node's relationship to the center of its parent. Used to represent a node's relationship to the center of its parent.
*/ */
typedef std::bitset<Dimension::value> Local_coordinates; typedef std::bitset<Dimension::value> Local_coordinates;
/*! /*!
\brief coordinates representing this node's relationship \brief Coordinates representing this node's relationship
with the rest of the tree. with the rest of the tree.
Each value (x, y, z, ...) of global coordinates is calculated by doubling Each value `(x, y, z, ...)` of global coordinates is calculated by doubling
the parent's global coordinates and adding the local coordinates. the parent's global coordinates and adding the local coordinates.
*/ */
typedef std::array<std::uint32_t, Dimension::value> Global_coordinates; typedef std::array<std::uint32_t, Dimension::value> Global_coordinates;
@ -108,7 +108,7 @@ public:
typedef typename PointRange::const_iterator const_iterator; ///< constant iterator type. typedef typename PointRange::const_iterator const_iterator; ///< constant iterator type.
/*! /*!
\brief easy access to adjacency directions. \brief Adjacency directions.
*/ */
typedef typename Traits::Adjacency Adjacency; typedef typename Traits::Adjacency Adjacency;
@ -150,7 +150,7 @@ private:
friend Orthtrees::Node_access; friend Orthtrees::Node_access;
/*! /*!
* \brief access to the content held by this node * \brief Access to the content held by this node
* \return a reference to the collection of point indices * \return a reference to the collection of point indices
*/ */
Point_range &points() { return m_data->points; } Point_range &points() { return m_data->points; }
@ -217,17 +217,17 @@ private:
/// @{ /// @{
/*! /*!
\brief split a node into subnodes \brief splits a node into subnodes.
Only leaf nodes should be split. Only leaf nodes should be split.
When a node is split it is no longer a leaf node. When a node is split it is no longer a leaf node.
8 Children are constructed automatically, and their values are set. A number of `Degree::value` children are constructed automatically, and their values are set.
Contents of this node are _not_ propagated automatically. Contents of this node are _not_ propagated automatically.
It's the responsibility of the caller to redistribute the points contained by a node after splitting It is the responsibility of the caller to redistribute the points contained by a node after splitting
*/ */
void split() { void split() {
assert(is_leaf()); CGAL_precondition (is_leaf());
m_data->children = std::make_unique<Children>(); m_data->children = std::make_unique<Children>();
for (int index = 0; index < Degree::value; index++) { for (int index = 0; index < Degree::value; index++) {
@ -238,10 +238,10 @@ private:
} }
/*! /*!
* \brief eliminate this node's children, making it a leaf node * \brief eliminates this node's children, making it a leaf node.
* *
* When a node is un-split, its children are automatically deleted. * When a node is un-split, its children are automatically deleted.
* After un-splitting a node it will be considered a leaf node * After un-splitting a node it will be considered a leaf node.
*/ */
void unsplit() { void unsplit() {
@ -355,7 +355,7 @@ public:
interpreted as a bitmap, where each bit matches a dimension interpreted as a bitmap, where each bit matches a dimension
(starting by the least significant bit for coordinate X). (starting by the least significant bit for coordinate X).
For example, it the case of an octree (dimension 3): For example, in the case of an octree (dimension 3):
- index 0 (000 in binary) is the children on the "minimum corner" (xmin, ymin, zmin) - index 0 (000 in binary) is the children on the "minimum corner" (xmin, ymin, zmin)
- index 1 (001 in binary) is on (xmax, ymin, zmin) - index 1 (001 in binary) is on (xmax, ymin, zmin)
@ -406,7 +406,7 @@ public:
} }
/*! /*!
\brief find the directly adjacent node in a specific direction \brief finds the directly adjacent node in a specific direction
\pre `!is_null()` \pre `!is_null()`
\pre `direction.to_ulong < 2 * Dimension::value` \pre `direction.to_ulong < 2 * Dimension::value`
@ -506,7 +506,7 @@ public:
} }
/*! /*!
\brief equivalent to adjacent_node, with an adjacency direction \brief equivalent to `adjacent_node()`, with an adjacency direction
rather than a bitset. rather than a bitset.
*/ */
Self adjacent_node(Adjacency adjacency) const { Self adjacent_node(Adjacency adjacency) const {
@ -519,7 +519,7 @@ public:
/// @{ /// @{
/*! /*!
\brief returns the number of points of this node. \brief checks whether the node is empty of points or not.
*/ */
bool empty() const { bool empty() const {
return m_data->points.empty(); return m_data->points.empty();
@ -529,7 +529,7 @@ public:
\brief returns the number of points of this node. \brief returns the number of points of this node.
*/ */
std::size_t size() const { std::size_t size() const {
return std::distance(m_data->points.begin(), m_data->points.end()); return std::size_t(std::distance(m_data->points.begin(), m_data->points.end()));
} }
/*! /*!
@ -551,12 +551,12 @@ public:
/// @{ /// @{
/*! /*!
* \brief compare the topology of this node to another node * \brief compares the topology of this node to another node.
* *
* \todo * \todo
* *
* \param rhs node to compare with * \param rhs node to compare with
* \return whether the nodes have different topology * \return whether the nodes have different topology.
*/ */
bool operator==(const Self &rhs) const { bool operator==(const Self &rhs) const {
return m_data == rhs.m_data; return m_data == rhs.m_data;

View File

@ -24,7 +24,8 @@ namespace Orthtrees {
\ingroup PkgOrthtreeSplitPredicates \ingroup PkgOrthtreeSplitPredicates
\brief A class used to choose when a node should be split depending on the number of inliers. \brief A class used to choose when a node should be split depending on the number of inliers.
This is bucket size predicate that splits a node if it contains more than a certain number of items. This is a bucket size predicate that considers a node should be
split if it contains more than a certain number of items.
*/ */
class Maximum_number_of_inliers { class Maximum_number_of_inliers {
@ -50,7 +51,7 @@ public:
\ingroup PkgOrthtreeSplitPredicates \ingroup PkgOrthtreeSplitPredicates
\brief A class used to choose when a node should be split depending on the depth. \brief A class used to choose when a node should be split depending on the depth.
This predicate makes a node split if its depth is lower than a certain limit. This predicate makes a node be split if its depth is lower than a certain limit.
*/ */
class Maximum_depth { class Maximum_depth {
@ -80,7 +81,7 @@ public:
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.
The refinement is stopped as soon as one of the condition is The refinement is stopped as soon as one of the conditions is
violated: if a node has more inliers than `bucket_size` but is violated: if a node has more inliers than `bucket_size` but is
already at `max_depth`, it is not split. Similarly, a node that is already at `max_depth`, it is not split. Similarly, a node that is
at a depth smaller than `max_depth` but already has fewer inliers at a depth smaller than `max_depth` but already has fewer inliers
@ -93,8 +94,7 @@ class Maximum_depth_and_maximum_number_of_inliers {
public: public:
/*! /*! \brief creates a predicate using maximum depth or bucket size.
\brief creates a predicate using minimum depth or bucket size.
*/ */
Maximum_depth_and_maximum_number_of_inliers(std::size_t max_depth, std::size_t bucket_size) : Maximum_depth_and_maximum_number_of_inliers(std::size_t max_depth, std::size_t bucket_size) :
m_max_depth(max_depth), m_bucket_size(bucket_size) {} m_max_depth(max_depth), m_bucket_size(bucket_size) {}
@ -104,8 +104,8 @@ public:
*/ */
template<typename Node> template<typename Node>
bool operator()(const Node &n) const { bool operator()(const Node &n) const {
size_t num_points = n.size(); std::size_t num_points = n.size();
size_t depth = n.depth(); std::size_t depth = n.depth();
return (num_points > m_bucket_size && depth < m_max_depth); return (num_points > m_bucket_size && depth < m_max_depth);
} }
}; };

View File

@ -48,7 +48,7 @@ Node next_sibling(Node n) {
constexpr static int degree = Node::Degree::value; constexpr static int degree = Node::Degree::value;
// Return null if this is the last child // Return null if this is the last child
if (index == degree - 1) if (int(index) == degree - 1)
return Node(); return Node();
// Otherwise, return the next child // Otherwise, return the next child
@ -108,8 +108,8 @@ Node first_child_at_depth(Node n, std::size_t depth) {
return node; return node;
if (!node.is_leaf()) if (!node.is_leaf())
for (std::size_t i = 0; i < Node::Degree::value; ++ i) for (int i = 0; i < Node::Degree::value; ++ i)
todo.push(node[Node::Degree::value - 1 - i]); todo.push(node[std::size_t(Node::Degree::value - 1 - i)]);
} }
return Node(); return Node();
@ -123,7 +123,7 @@ Node first_child_at_depth(Node n, std::size_t depth) {
A preorder traversal starts from the root towards the leaves. A preorder traversal starts from the root towards the leaves.
\cgalModels OrthtreeTraversal \cgalModels `OrthtreeTraversal`
*/ */
struct Preorder_traversal { struct Preorder_traversal {
@ -156,7 +156,7 @@ struct Preorder_traversal {
A postorder traversal starts from the leaves towards the root. A postorder traversal starts from the leaves towards the root.
\cgalModels OrthtreeTraversal \cgalModels `OrthtreeTraversal`
*/ */
struct Postorder_traversal { struct Postorder_traversal {
@ -184,7 +184,7 @@ struct Postorder_traversal {
All non-leave nodes are ignored. All non-leave nodes are ignored.
\cgalModels OrthtreeTraversal \cgalModels `OrthtreeTraversal`
*/ */
struct Leaves_traversal { struct Leaves_traversal {
@ -213,7 +213,7 @@ struct Leaves_traversal {
All trees at another depth are ignored. If the selected depth is All trees at another depth are ignored. If the selected depth is
higher than the maximum depth of the orthtree, no node will be traversed. higher than the maximum depth of the orthtree, no node will be traversed.
\cgalModels OrthtreeTraversal \cgalModels `OrthtreeTraversal`
*/ */
struct Level_traversal { struct Level_traversal {

View File

@ -28,10 +28,10 @@ namespace CGAL
\tparam GeomTraits model of `Kernel`. \tparam GeomTraits model of `Kernel`.
\cgalModels OrthtreeTraits \cgalModels `OrthtreeTraits`
\sa Quadtree \sa `CGAL::Quadtree`
\sa Orthtree_traits_3 \sa `CGAL::Orthtree_traits_3`
\sa Orthtree_traits_d \sa `CGAL::Orthtree_traits_d`
*/ */
template <typename GeomTraits> template <typename GeomTraits>
struct Orthtree_traits_2 struct Orthtree_traits_2
@ -50,9 +50,9 @@ public:
typedef std::array<FT, Dimension::value> Array; ///< Array type. typedef std::array<FT, Dimension::value> Array; ///< Array type.
/*! /*!
* \brief two directions along each axis in cartesian space, relative to a node * \brief Two directions along each axis in Cartesian space, relative to a node.
* *
* Directions are mapped to numbers as 2-bit integers * Directions are mapped to numbers as 2-bit integers.
* *
* The first bit indicates the axis (0 = x, 1 = y), * The first bit indicates the axis (0 = x, 1 = y),
* the second bit indicates the direction along that axis (0 = -, 1 = +). * the second bit indicates the direction along that axis (0 = -, 1 = +).
@ -104,7 +104,7 @@ public:
#ifdef DOXYGEN_RUNNING #ifdef DOXYGEN_RUNNING
/*! /*!
Functor with an operator to construct a `Bbox_d` from two `Point_d` object (minimum and maximum points). Functor with an operator to construct a `Bbox_d` from two `Array` objects (coordinates of minimum and maximum points).
*/ */
typedef unspecified_type Construct_bbox_d; typedef unspecified_type Construct_bbox_d;
#else #else

View File

@ -28,10 +28,10 @@ namespace CGAL
\tparam GeomTraits model of `Kernel`. \tparam GeomTraits model of `Kernel`.
\cgalModels OrthtreeTraits \cgalModels `OrthtreeTraits`
\sa Octree \sa `CGAL::Octree`
\sa Orthtree_traits_2 \sa `CGAL::Orthtree_traits_2`
\sa Orthtree_traits_d \sa `CGAL::Orthtree_traits_d`
*/ */
template <typename GeomTraits> template <typename GeomTraits>
struct Orthtree_traits_3 struct Orthtree_traits_3
@ -50,7 +50,7 @@ public:
typedef std::array<FT, Dimension::value> Array; ///< Array type. typedef std::array<FT, Dimension::value> Array; ///< Array type.
/*! /*!
* \brief two directions along each axis in cartesian space, relative to a node * \brief Two directions along each axis in Cartesian space, relative to a node.
* *
* Directions are mapped to numbers as 3-bit integers, * Directions are mapped to numbers as 3-bit integers,
* though the numbers 6 and 7 are not used because there are only 6 different directions. * though the numbers 6 and 7 are not used because there are only 6 different directions.
@ -121,7 +121,7 @@ public:
#ifdef DOXYGEN_RUNNING #ifdef DOXYGEN_RUNNING
/*! /*!
Functor with an operator to construct a `Bbox_d` from two `Point_d` object (minimum and maximum points). Functor with an operator to construct a `Bbox_d` from two `Array` objects (coordinates of minimum and maximum points).
*/ */
typedef unspecified_type Construct_bbox_d; typedef unspecified_type Construct_bbox_d;
#else #else

View File

@ -28,10 +28,10 @@ namespace CGAL
\tparam GeomTraits model of `Kernel`. \tparam GeomTraits model of `Kernel`.
\tparam DimensionTag specialization of `CGAL::Dimension_tag`. \tparam DimensionTag specialization of `CGAL::Dimension_tag`.
\cgalModels OrthtreeTraits \cgalModels `OrthtreeTraits`
\sa Orthtree \sa `CGAL::Orthtree`
\sa Orthtree_traits_2 \sa `CGAL::Orthtree_traits_2`
\sa Orthtree_traits_3 \sa `CGAL::Orthtree_traits_3`
*/ */
template <typename GeomTraits, typename DimensionTag> template <typename GeomTraits, typename DimensionTag>
@ -97,7 +97,7 @@ public:
#ifdef DOXYGEN_RUNNING #ifdef DOXYGEN_RUNNING
/*! /*!
Functor with an operator to construct a `Bbox_d` from two `Point_d` object (minimum and maximum points). Functor with an operator to construct a `Bbox_d` from two `Array` objects (coordinates of minimum and maximum points).
*/ */
typedef unspecified_type Construct_bbox_d; typedef unspecified_type Construct_bbox_d;
#else #else

View File

@ -22,7 +22,7 @@ namespace CGAL {
/*! /*!
\ingroup PkgOrthtreeClasses \ingroup PkgOrthtreeClasses
\brief Alias that specialized the `Orthtree` class to a 2D Quadtree. \brief Alias that specializes the `Orthtree` class to a 2D quadtree.
These two types are exactly equivalent: These two types are exactly equivalent:
- `Quadtree<GeomTraits, PointRange, PointMap>` - `Quadtree<GeomTraits, PointRange, PointMap>`
@ -31,9 +31,9 @@ namespace CGAL {
\warning This is a not a real class but an alias, please refer to \warning This is a not a real class but an alias, please refer to
the documentation of `Orthtree`. the documentation of `Orthtree`.
\tparam GeomTraits is a model of Kernel \tparam GeomTraits must be a model of `Kernel`
\tparam PointRange_ is a model of range whose value type is the key type of `PointMap` \tparam PointRange_ must be a model of range whose value type is the key type of `PointMap`
\tparam PointMap is a model of `ReadablePropertyMap` whose value type is `GeomTraits::Point_2` \tparam PointMap must be a model of `ReadablePropertyMap` whose value type is `GeomTraits::Point_2`
*/ */
template <typename GeomTraits, typename PointRange, template <typename GeomTraits, typename PointRange,
typename PointMap = Identity_property_map typename PointMap = Identity_property_map