mirror of https://github.com/CGAL/cgal
traversals are now templated by OrthtreeTraits
This commit is contained in:
parent
834b405a09
commit
3c55548967
|
|
@ -15,7 +15,7 @@ using Octree = CGAL::Orthtree<OTraits>;
|
||||||
void dump_as_polylines(const Octree& ot)
|
void dump_as_polylines(const Octree& ot)
|
||||||
{
|
{
|
||||||
std::ofstream out("octree.polylines.txt");
|
std::ofstream out("octree.polylines.txt");
|
||||||
for (Octree::Node_index node : ot.traverse(CGAL::Orthtrees::Leaves_traversal<Octree>(ot)))
|
for (Octree::Node_index node : ot.traverse(CGAL::Orthtrees::Leaves_traversal<OTraits>(ot)))
|
||||||
{
|
{
|
||||||
if (!ot.is_leaf(node))
|
if (!ot.is_leaf(node))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ using Point = Kernel::Point_3;
|
||||||
using Point_set = CGAL::Point_set_3<Point>;
|
using Point_set = CGAL::Point_set_3<Point>;
|
||||||
using Point_map = Point_set::Point_map;
|
using Point_map = Point_set::Point_map;
|
||||||
using Octree = CGAL::Octree<Kernel, Point_set, Point_map>;
|
using Octree = CGAL::Octree<Kernel, Point_set, Point_map>;
|
||||||
using Preorder_traversal = CGAL::Orthtrees::Preorder_traversal<Octree>;
|
using Preorder_traversal = CGAL::Orthtrees::Preorder_traversal<typename Octree::Traits>;
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ public:
|
||||||
|
|
||||||
// Collect all the leaf nodes
|
// Collect all the leaf nodes
|
||||||
std::queue<Node_index> leaf_nodes;
|
std::queue<Node_index> leaf_nodes;
|
||||||
for (Node_index leaf: traverse(Orthtrees::Leaves_traversal<Self>(*this))) {
|
for (Node_index leaf: traverse(Orthtrees::Leaves_traversal<Traits>(*this))) {
|
||||||
leaf_nodes.push(leaf);
|
leaf_nodes.push(leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -390,16 +390,11 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief provides direct read-only access to the tree traits.
|
* \brief provides direct read-only access to the tree traits.
|
||||||
*
|
|
||||||
* @return a const reference to the traits instantiation.
|
|
||||||
*/
|
*/
|
||||||
const Traits& traits() const { return m_traits; }
|
const Traits& traits() const { return m_traits; }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief provides access to the root node, and by
|
\brief provides access to the root node, and by extension the rest of the tree.
|
||||||
extension the rest of the tree.
|
|
||||||
|
|
||||||
\return Node_index of the root node.
|
|
||||||
*/
|
*/
|
||||||
Node_index root() const { return 0; }
|
Node_index root() const { return 0; }
|
||||||
|
|
||||||
|
|
@ -448,35 +443,6 @@ public:
|
||||||
return traverse(Traversal{*this, std::forward<Args>(args)...});
|
return traverse(Traversal{*this, std::forward<Args>(args)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO shall we document it?
|
|
||||||
FT
|
|
||||||
compute_cartesian_coordinate(std::uint32_t gc, std::size_t depth, int ci) const
|
|
||||||
{
|
|
||||||
CGAL_assertion(depth <= m_side_per_depth.size());
|
|
||||||
// an odd coordinate will be first compute at the current depth,
|
|
||||||
// while an even coordinate has already been computed at a previous depth.
|
|
||||||
// So while the coordinate is even, we decrease the depth to end up of the first
|
|
||||||
// non-even coordinate to compute it (with particular case for bbox limits).
|
|
||||||
// Note that is depth becomes too large, we might end up with incorrect coordinates
|
|
||||||
// due to rounding errors.
|
|
||||||
if (gc == (1u << depth)) return (m_bbox.max)()[ci]; // gc == 2^node_depth
|
|
||||||
if (gc == 0) return (m_bbox.min)()[ci];
|
|
||||||
if (gc % 2 !=0)
|
|
||||||
{
|
|
||||||
FT size = depth < m_side_per_depth.size()
|
|
||||||
? m_side_per_depth[depth][ci]
|
|
||||||
: m_side_per_depth[depth-1][ci]/FT(2);
|
|
||||||
return (m_bbox.min)()[ci] + int(gc) * size;
|
|
||||||
}
|
|
||||||
std::size_t nd = depth;
|
|
||||||
do{
|
|
||||||
--nd;
|
|
||||||
gc = gc >> 1;
|
|
||||||
}
|
|
||||||
while((gc&1)==0); // while even, shift
|
|
||||||
return (m_bbox.min)()[ci] + int(gc) * m_side_per_depth[nd][ci];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief constructs the bounding box of a node.
|
\brief constructs the bounding box of a node.
|
||||||
|
|
||||||
|
|
@ -1143,6 +1109,33 @@ public:
|
||||||
|
|
||||||
private: // functions :
|
private: // functions :
|
||||||
|
|
||||||
|
FT compute_cartesian_coordinate(std::uint32_t gc, std::size_t depth, int ci) const
|
||||||
|
{
|
||||||
|
CGAL_assertion(depth <= m_side_per_depth.size());
|
||||||
|
// an odd coordinate will be first compute at the current depth,
|
||||||
|
// while an even coordinate has already been computed at a previous depth.
|
||||||
|
// So while the coordinate is even, we decrease the depth to end up of the first
|
||||||
|
// non-even coordinate to compute it (with particular case for bbox limits).
|
||||||
|
// Note that is depth becomes too large, we might end up with incorrect coordinates
|
||||||
|
// due to rounding errors.
|
||||||
|
if (gc == (1u << depth)) return (m_bbox.max)()[ci]; // gc == 2^node_depth
|
||||||
|
if (gc == 0) return (m_bbox.min)()[ci];
|
||||||
|
if (gc % 2 != 0)
|
||||||
|
{
|
||||||
|
FT size = depth < m_side_per_depth.size()
|
||||||
|
? m_side_per_depth[depth][ci]
|
||||||
|
: m_side_per_depth[depth - 1][ci] / FT(2);
|
||||||
|
return (m_bbox.min)()[ci] + int(gc) * size;
|
||||||
|
}
|
||||||
|
std::size_t nd = depth;
|
||||||
|
do {
|
||||||
|
--nd;
|
||||||
|
gc = gc >> 1;
|
||||||
|
} while ((gc & 1) == 0); // while even, shift
|
||||||
|
return (m_bbox.min)()[ci] + int(gc) * m_side_per_depth[nd][ci];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Node_index recursive_descendant(Node_index node, std::size_t i) { return child(node, i); }
|
Node_index recursive_descendant(Node_index node, std::size_t i) { return child(node, i); }
|
||||||
|
|
||||||
template <typename... Indices>
|
template <typename... Indices>
|
||||||
|
|
@ -1241,7 +1234,7 @@ public:
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Self& orthtree) {
|
friend std::ostream& operator<<(std::ostream& os, const Self& orthtree) {
|
||||||
// Iterate over all nodes
|
// Iterate over all nodes
|
||||||
for (auto n: orthtree.traverse(Orthtrees::Preorder_traversal<Self>(orthtree))) {
|
for (auto n: orthtree.traverse(Orthtrees::Preorder_traversal<Traits>(orthtree))) {
|
||||||
// Show the depth
|
// Show the depth
|
||||||
for (std::size_t i = 0; i < orthtree.depth(n); ++i)
|
for (std::size_t i = 0; i < orthtree.depth(n); ++i)
|
||||||
os << ". ";
|
os << ". ";
|
||||||
|
|
|
||||||
|
|
@ -28,23 +28,23 @@ namespace Orthtrees {
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief A class used for performing a preorder traversal.
|
\brief A class used for performing a preorder traversal.
|
||||||
|
|
||||||
\tparam Tree an instance of `Orthtree`
|
\tparam GeomTraits must be a model of `OrthtreeTraits`
|
||||||
|
|
||||||
A preorder traversal starts from the root towards the leaves.
|
A preorder traversal starts from the root towards the leaves.
|
||||||
|
|
||||||
\cgalModels{OrthtreeTraversal}
|
\cgalModels{OrthtreeTraversal}
|
||||||
*/
|
*/
|
||||||
template <typename Tree>
|
template <typename GeomTraits>
|
||||||
struct Preorder_traversal {
|
struct Preorder_traversal {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Tree& m_orthtree;
|
const Orthtree<GeomTraits>& m_orthtree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Node_index = typename Tree::Node_index;
|
using Node_index = typename Orthtree<GeomTraits>::Node_index;
|
||||||
|
|
||||||
Preorder_traversal(const Tree& orthtree) : m_orthtree(orthtree) {}
|
Preorder_traversal(const Orthtree<GeomTraits>& orthtree) : m_orthtree(orthtree) {}
|
||||||
|
|
||||||
Node_index first_index() const {
|
Node_index first_index() const {
|
||||||
return m_orthtree.root();
|
return m_orthtree.root();
|
||||||
|
|
@ -72,23 +72,23 @@ public:
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief A class used for performing a postorder traversal.
|
\brief A class used for performing a postorder traversal.
|
||||||
|
|
||||||
\tparam Tree an instance of `Orthtree`
|
\tparam GeomTraits must be a model of `OrthtreeTraits`
|
||||||
|
|
||||||
A postorder traversal starts from the leaves towards the root.
|
A postorder traversal starts from the leaves towards the root.
|
||||||
|
|
||||||
\cgalModels{OrthtreeTraversal}
|
\cgalModels{OrthtreeTraversal}
|
||||||
*/
|
*/
|
||||||
template <typename Tree>
|
template <typename GeomTraits>
|
||||||
struct Postorder_traversal {
|
struct Postorder_traversal {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Tree& m_orthtree;
|
const Orthtree<GeomTraits>& m_orthtree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Node_index = typename Tree::Node_index;
|
using Node_index = typename Orthtree<GeomTraits>::Node_index;
|
||||||
|
|
||||||
Postorder_traversal(const Tree& orthtree) : m_orthtree(orthtree) {}
|
Postorder_traversal(const Orthtree<GeomTraits>& orthtree) : m_orthtree(orthtree) {}
|
||||||
|
|
||||||
Node_index first_index() const {
|
Node_index first_index() const {
|
||||||
return m_orthtree.deepest_first_child(m_orthtree.root());
|
return m_orthtree.deepest_first_child(m_orthtree.root());
|
||||||
|
|
@ -103,23 +103,23 @@ public:
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief A class used for performing a traversal on leaves only.
|
\brief A class used for performing a traversal on leaves only.
|
||||||
|
|
||||||
\tparam Tree an instance of `Orthtree`
|
\tparam GeomTraits must be a model of `OrthtreeTraits`
|
||||||
|
|
||||||
All non-leaf nodes are ignored.
|
All non-leaf nodes are ignored.
|
||||||
|
|
||||||
\cgalModels{OrthtreeTraversal}
|
\cgalModels{OrthtreeTraversal}
|
||||||
*/
|
*/
|
||||||
template <typename Tree>
|
template <typename GeomTraits>
|
||||||
struct Leaves_traversal {
|
struct Leaves_traversal {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Tree& m_orthtree;
|
const Orthtree<GeomTraits>& m_orthtree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Node_index = typename Tree::Node_index;
|
using Node_index = typename Orthtree<GeomTraits>::Node_index;
|
||||||
|
|
||||||
Leaves_traversal(const Tree& orthtree) : m_orthtree(orthtree) {}
|
Leaves_traversal(const Orthtree<GeomTraits>& orthtree) : m_orthtree(orthtree) {}
|
||||||
|
|
||||||
Node_index first_index() const {
|
Node_index first_index() const {
|
||||||
return m_orthtree.deepest_first_child(m_orthtree.root());
|
return m_orthtree.deepest_first_child(m_orthtree.root());
|
||||||
|
|
@ -141,7 +141,7 @@ public:
|
||||||
\ingroup PkgOrthtreeTraversal
|
\ingroup PkgOrthtreeTraversal
|
||||||
\brief A class used for performing a traversal of a specific depth level.
|
\brief A class used for performing a traversal of a specific depth level.
|
||||||
|
|
||||||
\tparam Tree an instance of `Orthtree`
|
\tparam GeomTraits must be a model of `OrthtreeTraits`
|
||||||
|
|
||||||
All tree nodes at another depth are ignored. If the selected depth is
|
All tree nodes at another depth are ignored. If the selected depth is
|
||||||
All tree nodes at another depth are ignored. If the selected depth is
|
All tree nodes at another depth are ignored. If the selected depth is
|
||||||
|
|
@ -149,21 +149,21 @@ public:
|
||||||
|
|
||||||
\cgalModels{OrthtreeTraversal}
|
\cgalModels{OrthtreeTraversal}
|
||||||
*/
|
*/
|
||||||
template <typename Tree>
|
template <typename GeomTraits>
|
||||||
struct Level_traversal {
|
struct Level_traversal {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Tree& m_orthtree;
|
const Orthtree<GeomTraits>& m_orthtree;
|
||||||
const std::size_t m_depth;
|
const std::size_t m_depth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Node_index = typename Tree::Node_index;
|
using Node_index = typename Orthtree<GeomTraits>::Node_index;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
constructs a `depth`-level traversal.
|
constructs a `depth`-level traversal.
|
||||||
*/
|
*/
|
||||||
Level_traversal(const Tree& orthtree, std::size_t depth) : m_orthtree(orthtree), m_depth(depth) {}
|
Level_traversal(const Orthtree<GeomTraits>& orthtree, std::size_t depth) : m_orthtree(orthtree), m_depth(depth) {}
|
||||||
|
|
||||||
Node_index first_index() const {
|
Node_index first_index() const {
|
||||||
// assumes the tree has at least one child at m_depth
|
// assumes the tree has at least one child at m_depth
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue