Fix traversal concept, model and examples

This commit is contained in:
Simon Giraudot 2021-01-19 13:31:41 +01:00
parent 11aa2c24f5
commit a906b12b3c
11 changed files with 64 additions and 27 deletions

View File

@ -3,28 +3,33 @@
\ingroup PkgOrthtreeConcepts
\cgalConcept
\brief a Traversal provides the functions needed to traverse the
\brief a traversal provides the functions needed to traverse the
nodes of an Orthtree.
A traversal is used to iterate on a tree with a user-selected order
(e.g. Preorder, Postorder).
Template parameters are the template parameters of the `CGAL::Orthtree`,
please refer to the documentation of this class for more
information.
\cgalHasModel `CGAL::Orthtrees::Traversal::Preorder`
\cgalHasModel `CGAL::Orthtrees::Traversal::Postorder`
\cgalHasModel `CGAL::Orthtrees::Traversal::Leaves`
*/
template<typename T, typename PR, typename PM>
class Traversal {
public:
using Node = typename CGAL::Orthtree<T,PR,PM>::Node; ///< The node type
/*!
\brief returns the first node to iterate to, given the root of the Orthtree.
*/
template<typename Node>
Node first (Node root) const;
/*!
\brief returns the next node to iterate to, given the previous node.
*/
template<typename Node>
Node next(Node n) const;
};

View File

@ -57,8 +57,8 @@
- `CGAL::Orthtrees::Split_predicate::Maximum_depth_and_maximum_number_of_inliers`
\cgalCRPSection{%Traversal}
- `CGAL::Orthtrees::Traversal::Preorder`
- `CGAL::Orthtrees::Traversal::Postorder`
- `CGAL::Orthtrees::Traversal::Leaves`
- `CGAL::Orthtrees::Traversal::Preorder<Traits, PointRange, PointMap>`
- `CGAL::Orthtrees::Traversal::Postorder<Traits, PointRange, PointMap>`
- `CGAL::Orthtrees::Traversal::Leaves<Traits, PointRange, PointMap>`
*/

View File

@ -13,16 +13,15 @@ typedef CGAL::Point_set_3<Point> Point_set;
typedef Point_set::Point_map Point_map;
typedef CGAL::Octree<Kernel, Point_set, Point_map> Octree;
typedef Octree::Node Node;
struct First_branch_traversal
{
template <typename Node>
Node first (Node root) const
{
return root;
}
template <typename Node>
Node next (Node n) const
{
if (n.is_leaf())

View File

@ -13,6 +13,7 @@ typedef CGAL::Point_set_3<Point> Point_set;
typedef Point_set::Point_map Point_map;
typedef CGAL::Octree<Kernel, Point_set, Point_map> Octree;
typedef CGAL::Orthtrees::Traversal::Preorder<typename Octree::Traits, Point_set, Point_map> Preorder_traversal;
int main(int argc, char **argv) {
@ -36,7 +37,7 @@ int main(int argc, char **argv) {
octree.refine();
// Print out the octree using preorder traversal
for (Octree::Node node : octree.traverse<CGAL::Orthtrees::Traversal::Preorder>()) {
for (Octree::Node node : octree.traverse<Preorder_traversal>()) {
std::cout << node << std::endl;
}

View File

@ -139,6 +139,9 @@ public:
typedef typename PointRange::iterator Range_iterator;
typedef typename std::iterator_traits<Range_iterator>::value_type Range_type;
typedef internal::Cartesian_ranges<Traits> Cartesian_ranges;
typedef Orthtrees::Traversal::Leaves<Traits, PointRange, PointMap> Leaves_traversal;
typedef Orthtrees::Traversal::Preorder<Traits, PointRange, PointMap> Preorder_traversal;
/// \endcond
/// @}
@ -311,7 +314,7 @@ public:
// Collect all the leaf nodes
std::queue<Node> leaf_nodes;
for (Node leaf : traverse(Orthtrees::Traversal::Leaves())) {
for (Node leaf : traverse(Leaves_traversal())) {
// TODO: I'd like to find a better (safer) way of doing this
leaf_nodes.push(leaf);
}
@ -403,8 +406,7 @@ public:
Node first = traversal.first(m_root);
Node_traversal_method_const next = std::bind(&Traversal::template next<Node>,
traversal, _1);
Node_traversal_method_const next = std::bind(&Traversal::next, traversal, _1);
return boost::make_iterator_range(Traversal_iterator<Node>(first, next),
Traversal_iterator<Node>());
@ -864,7 +866,7 @@ public:
friend std::ostream& operator<< (std::ostream& os, const Self& orthtree)
{
// Create a range of nodes
auto nodes = orthtree.traverse(CGAL::Orthtrees::Traversal::Preorder());
auto nodes = orthtree.traverse(Preorder_traversal());
// Iterate over the range
for (auto &n : nodes) {
// Show the depth

View File

@ -20,6 +20,12 @@
namespace CGAL {
/// \cond SKIP_IN_MANUAL
// Forward declaration
template<typename T, typename PR, typename PM>
class Orthtree;
/// \endcond
namespace Orthtrees {
/// \cond SKIP_IN_MANUAL
@ -86,16 +92,22 @@ namespace Traversal {
/*!
\ingroup PkgOrthtreeTraversal
\brief preorder traversal, starting from the root towards the leaves.
Template parameters are the template parameters of the `Orthtree`,
please refer to the documentation of this class for more
information.
\cgalModels Traversal
*/
template <typename T, typename PR, typename PM>
struct Preorder {
template <typename Node>
using Node = typename Orthtree<T,PR,PM>::Node;
Node first(Node root) const {
return root;
}
template <typename Node>
Node next(Node n) const {
if (n.is_leaf()) {
@ -116,17 +128,23 @@ struct Preorder {
/*!
\ingroup PkgOrthtreeTraversal
\brief preorder traversal, starting from the leaves towards the root.
Template parameters are the template parameters of the `Orthtree`,
please refer to the documentation of this class for more
information.
\cgalModels Traversal
*/
template <typename T, typename PR, typename PM>
struct Postorder {
template <typename Node>
using Node = typename Orthtree<T,PR,PM>::Node;
Node first(Node root) const {
return deepest_first_child(root);
}
template <typename Node>
Node next(Node n) const {
Node next = deepest_first_child(next_sibling(n));
@ -141,17 +159,23 @@ struct Postorder {
/*!
\ingroup PkgOrthtreeTraversal
\brief leaves traversal, ignoring all non-leave nodes.
Template parameters are the template parameters of the `Orthtree`,
please refer to the documentation of this class for more
information.
\cgalModels Traversal
*/
template <typename T, typename PR, typename PM>
struct Leaves {
template <typename Node>
using Node = typename Orthtree<T,PR,PM>::Node;
Node first(Node root) const {
return deepest_first_child(root);
}
template <typename Node>
Node next(Node n) const {
Node next = deepest_first_child(next_sibling(n));

View File

@ -12,6 +12,8 @@
#ifndef CGAL_ORTHTREE_TRAITS_3_H
#define CGAL_ORTHTREE_TRAITS_3_H
#include <CGAL/license/Orthtree.h>
namespace CGAL
{

View File

@ -12,6 +12,8 @@
#ifndef CGAL_ORTHTREE_TRAITS_3_H
#define CGAL_ORTHTREE_TRAITS_3_H
#include <CGAL/license/Orthtree.h>
namespace CGAL
{

View File

@ -12,6 +12,8 @@
#ifndef CGAL_ORTHTREE_TRAITS_D_H
#define CGAL_ORTHTREE_TRAITS_D_H
#include <CGAL/license/Orthtree.h>
namespace CGAL
{

View File

@ -14,14 +14,14 @@ typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::FT FT;
typedef CGAL::Point_set_3<Point> Point_set;
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map>
Octree;
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map> Octree;
typedef CGAL::Orthtrees::Traversal::Leaves<typename Octree::Traits, Point_set, typename Point_set::Point_map> Leaves_traversal;
std::size_t count_jumps(Octree &octree) {
std::size_t jumps = 0;
for (auto &node : octree.traverse(CGAL::Orthtrees::Traversal::Leaves())) {
for (auto &node : octree.traverse(Leaves_traversal())) {
for (int direction = 0; direction < 6; ++direction) {

View File

@ -11,8 +11,8 @@
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Point_set_3<Point> Point_set;
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map>
Octree;
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map> Octree;
typedef CGAL::Orthtrees::Traversal::Preorder<typename Octree::Traits, Point_set, typename Point_set::Point_map> Preorder_traversal;
bool test_preorder_1_node() {
@ -25,7 +25,7 @@ bool test_preorder_1_node() {
octree.refine(10, 1);
// Create the range
auto nodes = octree.traverse<CGAL::Orthtrees::Traversal::Preorder>();
auto nodes = octree.traverse<Preorder_traversal>();
// Check each item in the range
auto iter = nodes.begin();
@ -46,7 +46,7 @@ bool test_preorder_9_nodes() {
octree.refine(10, 1);
// Create the range
auto nodes = octree.traverse<CGAL::Orthtrees::Traversal::Preorder>();
auto nodes = octree.traverse<Preorder_traversal>();
// Check each item in the range
auto iter = nodes.begin();
@ -73,7 +73,7 @@ bool test_preorder_25_nodes() {
octree.refine(10, 1);
// Create the range
auto nodes = octree.traverse<CGAL::Orthtrees::Traversal::Preorder>();
auto nodes = octree.traverse<Preorder_traversal>();
// Check each item in the range
auto iter = nodes.begin();