mirror of https://github.com/CGAL/cgal
Fix traversal concept, model and examples
This commit is contained in:
parent
11aa2c24f5
commit
a906b12b3c
|
|
@ -3,28 +3,33 @@
|
||||||
\ingroup PkgOrthtreeConcepts
|
\ingroup PkgOrthtreeConcepts
|
||||||
\cgalConcept
|
\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.
|
nodes of an Orthtree.
|
||||||
|
|
||||||
A traversal is used to iterate on a tree with a user-selected order
|
A traversal is used to iterate on a tree with a user-selected order
|
||||||
(e.g. Preorder, Postorder).
|
(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::Preorder`
|
||||||
\cgalHasModel `CGAL::Orthtrees::Traversal::Postorder`
|
\cgalHasModel `CGAL::Orthtrees::Traversal::Postorder`
|
||||||
\cgalHasModel `CGAL::Orthtrees::Traversal::Leaves`
|
\cgalHasModel `CGAL::Orthtrees::Traversal::Leaves`
|
||||||
*/
|
*/
|
||||||
|
template<typename T, typename PR, typename PM>
|
||||||
class Traversal {
|
class Traversal {
|
||||||
public:
|
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.
|
\brief returns the first node to iterate to, given the root of the Orthtree.
|
||||||
*/
|
*/
|
||||||
template<typename Node>
|
|
||||||
Node first (Node root) const;
|
Node first (Node root) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief returns the next node to iterate to, given the previous node.
|
\brief returns the next node to iterate to, given the previous node.
|
||||||
*/
|
*/
|
||||||
template<typename Node>
|
|
||||||
Node next(Node n) const;
|
Node next(Node n) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@
|
||||||
- `CGAL::Orthtrees::Split_predicate::Maximum_depth_and_maximum_number_of_inliers`
|
- `CGAL::Orthtrees::Split_predicate::Maximum_depth_and_maximum_number_of_inliers`
|
||||||
|
|
||||||
\cgalCRPSection{%Traversal}
|
\cgalCRPSection{%Traversal}
|
||||||
- `CGAL::Orthtrees::Traversal::Preorder`
|
- `CGAL::Orthtrees::Traversal::Preorder<Traits, PointRange, PointMap>`
|
||||||
- `CGAL::Orthtrees::Traversal::Postorder`
|
- `CGAL::Orthtrees::Traversal::Postorder<Traits, PointRange, PointMap>`
|
||||||
- `CGAL::Orthtrees::Traversal::Leaves`
|
- `CGAL::Orthtrees::Traversal::Leaves<Traits, PointRange, PointMap>`
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,15 @@ typedef CGAL::Point_set_3<Point> Point_set;
|
||||||
typedef Point_set::Point_map Point_map;
|
typedef Point_set::Point_map Point_map;
|
||||||
|
|
||||||
typedef CGAL::Octree<Kernel, Point_set, Point_map> Octree;
|
typedef CGAL::Octree<Kernel, Point_set, Point_map> Octree;
|
||||||
|
typedef Octree::Node Node;
|
||||||
|
|
||||||
struct First_branch_traversal
|
struct First_branch_traversal
|
||||||
{
|
{
|
||||||
template <typename Node>
|
|
||||||
Node first (Node root) const
|
Node first (Node root) const
|
||||||
{
|
{
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Node>
|
|
||||||
Node next (Node n) const
|
Node next (Node n) const
|
||||||
{
|
{
|
||||||
if (n.is_leaf())
|
if (n.is_leaf())
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ typedef CGAL::Point_set_3<Point> Point_set;
|
||||||
typedef Point_set::Point_map Point_map;
|
typedef Point_set::Point_map Point_map;
|
||||||
|
|
||||||
typedef CGAL::Octree<Kernel, Point_set, Point_map> Octree;
|
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) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
|
@ -36,7 +37,7 @@ int main(int argc, char **argv) {
|
||||||
octree.refine();
|
octree.refine();
|
||||||
|
|
||||||
// Print out the octree using preorder traversal
|
// 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;
|
std::cout << node << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,9 @@ public:
|
||||||
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 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
|
/// \endcond
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
@ -311,7 +314,7 @@ public:
|
||||||
|
|
||||||
// Collect all the leaf nodes
|
// Collect all the leaf nodes
|
||||||
std::queue<Node> 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
|
// TODO: I'd like to find a better (safer) way of doing this
|
||||||
leaf_nodes.push(leaf);
|
leaf_nodes.push(leaf);
|
||||||
}
|
}
|
||||||
|
|
@ -403,8 +406,7 @@ public:
|
||||||
|
|
||||||
Node first = traversal.first(m_root);
|
Node first = traversal.first(m_root);
|
||||||
|
|
||||||
Node_traversal_method_const next = std::bind(&Traversal::template next<Node>,
|
Node_traversal_method_const next = std::bind(&Traversal::next, traversal, _1);
|
||||||
traversal, _1);
|
|
||||||
|
|
||||||
return boost::make_iterator_range(Traversal_iterator<Node>(first, next),
|
return boost::make_iterator_range(Traversal_iterator<Node>(first, next),
|
||||||
Traversal_iterator<Node>());
|
Traversal_iterator<Node>());
|
||||||
|
|
@ -864,7 +866,7 @@ public:
|
||||||
friend std::ostream& operator<< (std::ostream& os, const Self& orthtree)
|
friend std::ostream& operator<< (std::ostream& os, const Self& orthtree)
|
||||||
{
|
{
|
||||||
// Create a range of nodes
|
// Create a range of nodes
|
||||||
auto nodes = orthtree.traverse(CGAL::Orthtrees::Traversal::Preorder());
|
auto nodes = orthtree.traverse(Preorder_traversal());
|
||||||
// Iterate over the range
|
// Iterate over the range
|
||||||
for (auto &n : nodes) {
|
for (auto &n : nodes) {
|
||||||
// Show the depth
|
// Show the depth
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,12 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
// Forward declaration
|
||||||
|
template<typename T, typename PR, typename PM>
|
||||||
|
class Orthtree;
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
namespace Orthtrees {
|
namespace Orthtrees {
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
@ -86,16 +92,22 @@ namespace Traversal {
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief preorder traversal, starting from the root towards the leaves.
|
\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
|
\cgalModels Traversal
|
||||||
*/
|
*/
|
||||||
|
template <typename T, typename PR, typename PM>
|
||||||
struct Preorder {
|
struct Preorder {
|
||||||
|
|
||||||
template <typename Node>
|
using Node = typename Orthtree<T,PR,PM>::Node;
|
||||||
|
|
||||||
Node first(Node root) const {
|
Node first(Node root) const {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Node>
|
|
||||||
Node next(Node n) const {
|
Node next(Node n) const {
|
||||||
|
|
||||||
if (n.is_leaf()) {
|
if (n.is_leaf()) {
|
||||||
|
|
@ -116,17 +128,23 @@ struct Preorder {
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief preorder traversal, starting from the leaves towards the root.
|
\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
|
\cgalModels Traversal
|
||||||
*/
|
*/
|
||||||
|
template <typename T, typename PR, typename PM>
|
||||||
struct Postorder {
|
struct Postorder {
|
||||||
|
|
||||||
template <typename Node>
|
using Node = typename Orthtree<T,PR,PM>::Node;
|
||||||
|
|
||||||
Node first(Node root) const {
|
Node first(Node root) const {
|
||||||
|
|
||||||
return deepest_first_child(root);
|
return deepest_first_child(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Node>
|
|
||||||
Node next(Node n) const {
|
Node next(Node n) const {
|
||||||
|
|
||||||
Node next = deepest_first_child(next_sibling(n));
|
Node next = deepest_first_child(next_sibling(n));
|
||||||
|
|
@ -141,17 +159,23 @@ struct Postorder {
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief leaves traversal, ignoring all non-leave nodes.
|
\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
|
\cgalModels Traversal
|
||||||
*/
|
*/
|
||||||
|
template <typename T, typename PR, typename PM>
|
||||||
struct Leaves {
|
struct Leaves {
|
||||||
|
|
||||||
template <typename Node>
|
using Node = typename Orthtree<T,PR,PM>::Node;
|
||||||
|
|
||||||
Node first(Node root) const {
|
Node first(Node root) const {
|
||||||
|
|
||||||
return deepest_first_child(root);
|
return deepest_first_child(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Node>
|
|
||||||
Node next(Node n) const {
|
Node next(Node n) const {
|
||||||
|
|
||||||
Node next = deepest_first_child(next_sibling(n));
|
Node next = deepest_first_child(next_sibling(n));
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef CGAL_ORTHTREE_TRAITS_3_H
|
#ifndef CGAL_ORTHTREE_TRAITS_3_H
|
||||||
#define CGAL_ORTHTREE_TRAITS_3_H
|
#define CGAL_ORTHTREE_TRAITS_3_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Orthtree.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef CGAL_ORTHTREE_TRAITS_3_H
|
#ifndef CGAL_ORTHTREE_TRAITS_3_H
|
||||||
#define CGAL_ORTHTREE_TRAITS_3_H
|
#define CGAL_ORTHTREE_TRAITS_3_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Orthtree.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef CGAL_ORTHTREE_TRAITS_D_H
|
#ifndef CGAL_ORTHTREE_TRAITS_D_H
|
||||||
#define CGAL_ORTHTREE_TRAITS_D_H
|
#define CGAL_ORTHTREE_TRAITS_D_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Orthtree.h>
|
||||||
|
|
||||||
namespace CGAL
|
namespace CGAL
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
typedef Kernel::FT FT;
|
typedef Kernel::FT FT;
|
||||||
typedef CGAL::Point_set_3<Point> Point_set;
|
typedef CGAL::Point_set_3<Point> Point_set;
|
||||||
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map>
|
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map> Octree;
|
||||||
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 count_jumps(Octree &octree) {
|
||||||
|
|
||||||
std::size_t jumps = 0;
|
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) {
|
for (int direction = 0; direction < 6; ++direction) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
typedef CGAL::Point_set_3<Point> Point_set;
|
typedef CGAL::Point_set_3<Point> Point_set;
|
||||||
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map>
|
typedef CGAL::Octree<Kernel, Point_set, typename Point_set::Point_map> Octree;
|
||||||
Octree;
|
typedef CGAL::Orthtrees::Traversal::Preorder<typename Octree::Traits, Point_set, typename Point_set::Point_map> Preorder_traversal;
|
||||||
|
|
||||||
bool test_preorder_1_node() {
|
bool test_preorder_1_node() {
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ bool test_preorder_1_node() {
|
||||||
octree.refine(10, 1);
|
octree.refine(10, 1);
|
||||||
|
|
||||||
// Create the range
|
// Create the range
|
||||||
auto nodes = octree.traverse<CGAL::Orthtrees::Traversal::Preorder>();
|
auto nodes = octree.traverse<Preorder_traversal>();
|
||||||
|
|
||||||
// Check each item in the range
|
// Check each item in the range
|
||||||
auto iter = nodes.begin();
|
auto iter = nodes.begin();
|
||||||
|
|
@ -46,7 +46,7 @@ bool test_preorder_9_nodes() {
|
||||||
octree.refine(10, 1);
|
octree.refine(10, 1);
|
||||||
|
|
||||||
// Create the range
|
// Create the range
|
||||||
auto nodes = octree.traverse<CGAL::Orthtrees::Traversal::Preorder>();
|
auto nodes = octree.traverse<Preorder_traversal>();
|
||||||
|
|
||||||
// Check each item in the range
|
// Check each item in the range
|
||||||
auto iter = nodes.begin();
|
auto iter = nodes.begin();
|
||||||
|
|
@ -73,7 +73,7 @@ bool test_preorder_25_nodes() {
|
||||||
octree.refine(10, 1);
|
octree.refine(10, 1);
|
||||||
|
|
||||||
// Create the range
|
// Create the range
|
||||||
auto nodes = octree.traverse<CGAL::Orthtrees::Traversal::Preorder>();
|
auto nodes = octree.traverse<Preorder_traversal>();
|
||||||
|
|
||||||
// Check each item in the range
|
// Check each item in the range
|
||||||
auto iter = nodes.begin();
|
auto iter = nodes.begin();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue