traversals are now templated by OrthtreeTraits

This commit is contained in:
Sven Oesau 2024-02-02 09:32:29 +01:00
parent 834b405a09
commit 3c55548967
4 changed files with 52 additions and 59 deletions

View File

@ -15,7 +15,7 @@ using Octree = CGAL::Orthtree<OTraits>;
void dump_as_polylines(const Octree& ot)
{
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))
continue;

View File

@ -12,7 +12,7 @@ using Point = Kernel::Point_3;
using Point_set = CGAL::Point_set_3<Point>;
using Point_map = 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) {

View File

@ -333,7 +333,7 @@ public:
// Collect all the 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);
}
@ -390,16 +390,11 @@ public:
/*!
* \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; }
/*!
\brief provides access to the root node, and by
extension the rest of the tree.
\return Node_index of the root node.
\brief provides access to the root node, and by extension the rest of the tree.
*/
Node_index root() const { return 0; }
@ -448,35 +443,6 @@ public:
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.
@ -1143,6 +1109,33 @@ public:
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); }
template <typename... Indices>
@ -1241,7 +1234,7 @@ public:
friend std::ostream& operator<<(std::ostream& os, const Self& orthtree) {
// 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
for (std::size_t i = 0; i < orthtree.depth(n); ++i)
os << ". ";

View File

@ -28,23 +28,23 @@ namespace Orthtrees {
\ingroup PkgOrthtreeTraversal
\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.
\cgalModels{OrthtreeTraversal}
*/
template <typename Tree>
template <typename GeomTraits>
struct Preorder_traversal {
private:
const Tree& m_orthtree;
const Orthtree<GeomTraits>& m_orthtree;
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 {
return m_orthtree.root();
@ -72,23 +72,23 @@ public:
\ingroup PkgOrthtreeTraversal
\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.
\cgalModels{OrthtreeTraversal}
*/
template <typename Tree>
template <typename GeomTraits>
struct Postorder_traversal {
private:
const Tree& m_orthtree;
const Orthtree<GeomTraits>& m_orthtree;
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 {
return m_orthtree.deepest_first_child(m_orthtree.root());
@ -103,23 +103,23 @@ public:
\ingroup PkgOrthtreeTraversal
\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.
\cgalModels{OrthtreeTraversal}
*/
template <typename Tree>
template <typename GeomTraits>
struct Leaves_traversal {
private:
const Tree& m_orthtree;
const Orthtree<GeomTraits>& m_orthtree;
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 {
return m_orthtree.deepest_first_child(m_orthtree.root());
@ -141,7 +141,7 @@ public:
\ingroup PkgOrthtreeTraversal
\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
@ -149,21 +149,21 @@ public:
\cgalModels{OrthtreeTraversal}
*/
template <typename Tree>
template <typename GeomTraits>
struct Level_traversal {
private:
const Tree& m_orthtree;
const Orthtree<GeomTraits>& m_orthtree;
const std::size_t m_depth;
public:
using Node_index = typename Tree::Node_index;
using Node_index = typename Orthtree<GeomTraits>::Node_index;
/*!
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 {
// assumes the tree has at least one child at m_depth