diff --git a/Orthtree/include/CGAL/Orthtree.h b/Orthtree/include/CGAL/Orthtree.h index 4b4c042ee05..0e2a79e816f 100644 --- a/Orthtree/include/CGAL/Orthtree.h +++ b/Orthtree/include/CGAL/Orthtree.h @@ -197,7 +197,7 @@ public: , m_range(point_range) , m_point_map(point_map) { - m_nodes.reserve(2048); // todo: temporary, for testing + m_nodes.reserve(1'000'000); // todo: temporary, for testing m_nodes.emplace_back(); Array bbox_min; @@ -331,7 +331,7 @@ public: // Process each of its children for (int i = 0; i < Degree::value; ++i) - todo.push(&(*current)[i]); + todo.push(&children(*current)[i]); } } @@ -368,7 +368,7 @@ public: // Collect all the leaf nodes std::queue leaf_nodes; - for (const Node& leaf: traverse(Orthtrees::Leaves_traversal())) { + for (const Node& leaf: traverse(Orthtrees::Leaves_traversal(*this))) { // TODO: I'd like to find a better (safer) way of doing this leaf_nodes.push(const_cast(&leaf)); } @@ -388,7 +388,7 @@ public: for (int direction = 0; direction < 6; ++direction) { // Get the neighbor - auto* neighbor = node->adjacent_node(direction); + auto* neighbor = adjacent_node(*node, direction); // If it doesn't exist, skip it if (!neighbor) @@ -412,7 +412,7 @@ public: // Add newly created children to the queue for (int i = 0; i < Degree::value; ++i) { - leaf_nodes.push(&(*neighbor)[i]); + leaf_nodes.push(&children(*neighbor)[i]); } } } @@ -461,9 +461,9 @@ public: \return a forward input iterator over the nodes of the tree */ template - Node_range traverse(const Traversal& traversal = Traversal()) const { + Node_range traverse(const Traversal& traversal) const { - const Node* first = traversal.first(&root()); + const Node* first = traversal.first(); Node_traversal_method_const next = [&](const Node* n) -> const Node* { return traversal.next(n); }; @@ -472,6 +472,12 @@ public: Traversal_iterator()); } + // todo: document this convenience function + template + Node_range traverse() const { + return traverse(Traversal(*this)); + } + /*! \brief constructs the bounding box of a node. @@ -534,7 +540,7 @@ public: index[dimension++] = (get < 0 > (r) < get < 1 > (r)); // Find the correct sub-node of the current node - node_for_point = &(*node_for_point)[index.to_ulong()]; + node_for_point = &children(*node_for_point)[index.to_ulong()]; } // Return the result @@ -618,7 +624,7 @@ public: return false; // If all else is equal, recursively compare the trees themselves - return Node::is_topology_equal(rhs.root(), root()); + return is_topology_equal(root(), *this, rhs.root(), rhs); } /*! @@ -630,6 +636,21 @@ public: /// @} + /// \name Node Access + /// @{ + + using Children = typename Node::Children; + + Children& children(Node& node) { + CGAL_precondition (!node.is_leaf()); + return node.m_children.get(); + } + + const Children& children(const Node& node) const { + CGAL_precondition (!node.is_leaf()); + return node.m_children.get(); + } + /*! \brief splits the node into subnodes. @@ -711,6 +732,151 @@ public: return construct_point_d_from_array(bary); } + + // todo: this does what the documentation for operator== claims to do! + static bool is_topology_equal(const Node& lhsNode, const Self& lhsTree, const Node& rhsNode, const Self& rhsTree) { + + // If one node is a leaf, and the other isn't, they're not the same + if (lhsNode.is_leaf() != rhsNode.is_leaf()) + return false; + + // If both nodes are non-leaf nodes + if (!lhsNode.is_leaf()) { + + // Check all the children + for (int i = 0; i < Degree::value; ++i) { + // If any child cell is different, they're not the same + if (!is_topology_equal(lhsTree.children(lhsNode)[i], lhsTree, rhsTree.children(rhsNode)[i], rhsTree)) + return false; + } + } + + // If both nodes are leaf nodes, they must be in the same location + return (lhsNode.global_coordinates() == rhsNode.global_coordinates()); + } + + static bool is_topology_equal(const Self& lhs, const Self& rhs) { + return is_topology_equal(lhs.root(), lhs, rhs.root(), rhs); + } + + /*! + \brief finds the directly adjacent node in a specific direction + + \pre `!is_null()` + \pre `direction.to_ulong < 2 * Dimension::value` + + Adjacent nodes are found according to several properties: + - adjacent nodes may be larger than the seek node, but never smaller + - a node has at most `2 * Dimension::value` different adjacent nodes (in 3D: left, right, up, down, front, back) + - adjacent nodes are not required to be leaf nodes + + Here's a diagram demonstrating the concept for a Quadtree: + + ``` + +---------------+---------------+ + | | | + | | | + | | | + | A | | + | | | + | | | + | | | + +-------+-------+---+---+-------+ + | | | | | | + | A | (S) +---A---+ | + | | | | | | + +---+---+-------+---+---+-------+ + | | | | | | + +---+---+ A | | | + | | | | | | + +---+---+-------+-------+-------+ + ``` + + - (S) : Seek node + - A : Adjacent node + + Note how the top adjacent node is larger than the seek node. The + right adjacent node is the same size, even though it contains + further subdivisions. + + This implementation returns the adjacent node if it's found. If + there is no adjacent node in that direction, it returns a null + node. + + \param direction which way to find the adjacent node relative to + this one. Each successive bit selects the direction for the + corresponding dimension: for an Octree in 3D, 010 means: negative + direction in X, position direction in Y, negative direction in Z. + + \return the adjacent node if it exists, a null node otherwise. + */ + const Node* adjacent_node(const Node& node, typename Node::Local_coordinates direction) const { + + // Direction: LEFT RIGHT DOWN UP BACK FRONT + // direction: 000 001 010 011 100 101 + + // Nodes only have up to 2*dim different adjacent nodes (since cubes have 6 sides) + CGAL_precondition(direction.to_ulong() < Dimension::value * 2); + + // The root node has no adjacent nodes! + if (node.is_root()) return nullptr; + + // The least significant bit indicates the sign (which side of the node) + bool sign = direction[0]; + + // The first two bits indicate the dimension/axis (x, y, z) + uint8_t dimension = uint8_t((direction >> 1).to_ulong()); + + // Create an offset so that the bit-significance lines up with the dimension (e.g. 1, 2, 4 --> 001, 010, 100) + int8_t offset = (uint8_t) 1 << dimension; + + // Finally, apply the sign to the offset + offset = (sign ? offset : -offset); + + // Check if this child has the opposite sign along the direction's axis + if (node.local_coordinates()[dimension] != sign) { + // This means the adjacent node is a direct sibling, the offset can be applied easily! + return &children(*node.parent())[node.local_coordinates().to_ulong() + offset]; + } + + // Find the parent's neighbor in that direction, if it exists + const Node* adjacent_node_of_parent = adjacent_node(*node.parent(), direction); + + // If the parent has no neighbor, then this node doesn't have one + if (adjacent_node_of_parent == nullptr) return nullptr; + + // If the parent's adjacent node has no children, then it's this node's adjacent node + if (adjacent_node_of_parent->is_leaf()) + return adjacent_node_of_parent; + + // Return the nearest node of the parent by subtracting the offset instead of adding + return &children(*adjacent_node_of_parent)[node.local_coordinates().to_ulong() - offset]; + + } + + /*! + \brief equivalent to `adjacent_node()`, with an adjacency direction rather than a bitset. + */ + const Node* adjacent_node(const Node& node, typename Node::Adjacency adjacency) const { + return adjacent_node(node, std::bitset(static_cast(adjacency))); + } + + /*! + * \brief equivalent to adjacent_node, except non-const + */ + Node* adjacent_node(Node& node, std::bitset direction) { + return const_cast(const_cast(this)->adjacent_node(node, direction)); + } + + /*! + * \brief equivalent to adjacent_node, with a Direction rather than a bitset and non-const + */ + Node* adjacent_node(Node& node, typename Node::Adjacency adjacency) { + return adjacent_node(node, std::bitset(static_cast(adjacency))); + } + + /// @} + private: // functions : void reassign_points(Node& node, Range_iterator begin, Range_iterator end, const Point& center, @@ -720,7 +886,7 @@ private: // functions : // Root case: reached the last dimension if (dimension == Dimension::value) { - node[coord.to_ulong()].points() = {begin, end}; + children(node)[coord.to_ulong()].points() = {begin, end}; return; } @@ -831,7 +997,7 @@ private: // functions : // Fill the list with child nodes for (int index = 0; index < Degree::value; ++index) { - auto& child_node = node[index]; + auto& child_node = children(node)[index]; // Add a child to the list, with its distance children_with_distances.emplace_back(typename Node::Local_coordinates(index), @@ -845,7 +1011,7 @@ private: // functions : // Loop over the children for (auto child_with_distance: children_with_distances) { - auto& child_node = node[child_with_distance.index.to_ulong()]; + auto& child_node = children(node)[child_with_distance.index.to_ulong()]; // Check whether the bounding box of the child intersects with the search bounds if (do_intersect(child_node, search_bounds)) { @@ -872,7 +1038,7 @@ private: // functions : // Otherwise, each of the children need to be checked for (int i = 0; i < Degree::value; ++i) { - intersected_nodes_recursive(query, node[i], output); + intersected_nodes_recursive(query, children(node)[i], output); } } return output; @@ -970,7 +1136,7 @@ public: friend std::ostream& operator<<(std::ostream& os, const Self& orthtree) { // Create a range of nodes - auto nodes = orthtree.traverse(Orthtrees::Preorder_traversal()); + auto nodes = orthtree.traverse(Orthtrees::Preorder_traversal(orthtree)); // Iterate over the range for (auto& n: nodes) { // Show the depth diff --git a/Orthtree/include/CGAL/Orthtree/Node.h b/Orthtree/include/CGAL/Orthtree/Node.h index e88268e41d3..98acd0bd2cb 100644 --- a/Orthtree/include/CGAL/Orthtree/Node.h +++ b/Orthtree/include/CGAL/Orthtree/Node.h @@ -139,13 +139,6 @@ public: explicit Node(Self* parent, Local_coordinates local_coordinates) : m_parent(parent) { -// if (m_parent) { -// m_depth = m_parent->m_depth + 1; -// -// for (int i = 0; i < Dimension::value; i++) -// m_global_coordinates[i] = (2 * parent->m_global_coordinates[i]) + local_coordinates[i]; -// } - if (parent != nullptr) { m_depth = parent->m_depth + 1; @@ -175,16 +168,6 @@ public: const Point_range& points() const { return m_points; } - Children& children() { - CGAL_precondition (!is_leaf()); - return m_children.get(); - } - - const Children& children() const { - CGAL_precondition (!is_leaf()); - return m_children.get(); - } - /// @} /// \name Type & Location @@ -255,201 +238,6 @@ public: return m_parent; } - /*! - \brief returns the nth child of this node. - - \pre `!is_leaf()` - \pre `0 <= index && index < Degree::value` - - The orthtree subdivides the space in 2 on each dimension - available, so a child node can be accessed by selecting a Boolean - value for each dimension. The `index` parameter is thus - interpreted as a bitmap, where each bit matches a dimension - (starting by the least significant bit for coordinate X). - - 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 1 (001 in binary) is on (xmax, ymin, zmin) - - index 2 (010 in binary) is on (xmin, ymax, zmin) - - index 6 (101 in binary) is on (xmax, ymin, zmax) - - Diagram of a quadtree: - - ``` - Children of the current node: - - Y axis - A - | +-------------------+-------------------+ - | | Coord: Ymax Xmin | Coord: Ymax Xmax | - | | Bitmap: 1 0 | Bitmap: 1 1 | - | | | | - | | -> index = 2 | -> index = 3 | - | | | | - | | | | - | | | | - | | | | - | +-------------------+-------------------+ - | | Coord: Ymin Xmin | Coord: Ymin Xmax | - | | Bitmap: 0 0 | Bitmap: 0 1 | - | | | | - | | -> index = 0 | -> index = 1 | - | | | | - | | | | - | | | | - | | | | - | +-------------------+-------------------+ - | - +--------------------------------------------> X axis - 0 - ``` - - The operator can be chained. For example, `n[5][2][3]` returns the - third child of the second child of the fifth child of a node `n`. - */ - Self& operator[](std::size_t index) { - - CGAL_precondition (!is_leaf()); - CGAL_precondition (index < Degree::value); - - return m_children.get()[index]; - } - - /*! - \brief returns the nth child of this node. - - \pre `!is_leaf()` - \pre `index < Degree::value` - - The operator can be chained. For example, `n[5][2][3]` returns the - third child of the second child of the fifth child of a node `n`. - */ - const Self& operator[](std::size_t index) const { - - CGAL_precondition (!is_leaf()); - CGAL_precondition (index < Degree::value); - - return m_children.get()[index]; - } - - /*! - \brief finds the directly adjacent node in a specific direction - - \pre `!is_null()` - \pre `direction.to_ulong < 2 * Dimension::value` - - Adjacent nodes are found according to several properties: - - adjacent nodes may be larger than the seek node, but never smaller - - a node has at most `2 * Dimension::value` different adjacent nodes (in 3D: left, right, up, down, front, back) - - adjacent nodes are not required to be leaf nodes - - Here's a diagram demonstrating the concept for a Quadtree: - - ``` - +---------------+---------------+ - | | | - | | | - | | | - | A | | - | | | - | | | - | | | - +-------+-------+---+---+-------+ - | | | | | | - | A | (S) +---A---+ | - | | | | | | - +---+---+-------+---+---+-------+ - | | | | | | - +---+---+ A | | | - | | | | | | - +---+---+-------+-------+-------+ - ``` - - - (S) : Seek node - - A : Adjacent node - - Note how the top adjacent node is larger than the seek node. The - right adjacent node is the same size, even though it contains - further subdivisions. - - This implementation returns the adjacent node if it's found. If - there is no adjacent node in that direction, it returns a null - node. - - \param direction which way to find the adjacent node relative to - this one. Each successive bit selects the direction for the - corresponding dimension: for an Octree in 3D, 010 means: negative - direction in X, position direction in Y, negative direction in Z. - - \return the adjacent node if it exists, a null node otherwise. - */ - const Self* adjacent_node(Local_coordinates direction) const { - - // Direction: LEFT RIGHT DOWN UP BACK FRONT - // direction: 000 001 010 011 100 101 - - // Nodes only have up to 2*dim different adjacent nodes (since cubes have 6 sides) - CGAL_precondition(direction.to_ulong() < Dimension::value * 2); - - // The root node has no adjacent nodes! - if (is_root()) return nullptr; - - // The least significant bit indicates the sign (which side of the node) - bool sign = direction[0]; - - // The first two bits indicate the dimension/axis (x, y, z) - uint8_t dimension = uint8_t((direction >> 1).to_ulong()); - - // Create an offset so that the bit-significance lines up with the dimension (e.g. 1, 2, 4 --> 001, 010, 100) - int8_t offset = (uint8_t) 1 << dimension; - - // Finally, apply the sign to the offset - offset = (sign ? offset : -offset); - - // Check if this child has the opposite sign along the direction's axis - if (local_coordinates()[dimension] != sign) { - // This means the adjacent node is a direct sibling, the offset can be applied easily! - return &(*parent())[local_coordinates().to_ulong() + offset]; - } - - // Find the parent's neighbor in that direction, if it exists - const Self* adjacent_node_of_parent = parent()->adjacent_node(direction); - - // If the parent has no neighbor, then this node doesn't have one - if (!adjacent_node_of_parent) return nullptr; - - // If the parent's adjacent node has no children, then it's this node's adjacent node - if (adjacent_node_of_parent->is_leaf()) - return adjacent_node_of_parent; - - // Return the nearest node of the parent by subtracting the offset instead of adding - return &(*adjacent_node_of_parent)[local_coordinates().to_ulong() - offset]; - - } - - /*! - \brief equivalent to `adjacent_node()`, with an adjacency direction - rather than a bitset. - */ - const Self* adjacent_node(Adjacency adjacency) const { - return adjacent_node(std::bitset(static_cast(adjacency))); - } - - /*! - * \brief equivalent to adjacent_node, except non-const - */ - Self* adjacent_node(std::bitset direction) { - return const_cast(const_cast(this)->adjacent_node(direction)); - } - - /*! - * \brief equivalent to adjacent_node, with a Direction rather than a bitset and non-const - */ - Self* adjacent_node(Adjacency adjacency) { - return adjacent_node(std::bitset(static_cast(adjacency))); - } - /// @} /// \name Point Range @@ -505,28 +293,6 @@ public: rhs.m_global_coordinates == m_global_coordinates; } - // todo: this does what the documentation for operator== claims to do! - static bool is_topology_equal(const Self& a, const Self& b) { - - // If one node is a leaf, and the other isn't, they're not the same - if (a.is_leaf() != b.is_leaf()) - return false; - - // If both nodes are non-leaf nodes - if (!a.is_leaf()) { - - // Check all the children - for (int i = 0; i < Degree::value; ++i) { - // If any child cell is different, they're not the same - if (!is_topology_equal(a[i], b[i])) - return false; - } - } - - // If both nodes are leaf nodes, they must be in the same location - return (a.global_coordinates() == b.global_coordinates()); - } - friend std::ostream& operator<<(std::ostream& os, const Self& node) { return internal::print_orthtree_node(os, node); } diff --git a/Orthtree/include/CGAL/Orthtree/Traversals.h b/Orthtree/include/CGAL/Orthtree/Traversals.h index b7de300b3c9..6e51e3ce77c 100644 --- a/Orthtree/include/CGAL/Orthtree/Traversals.h +++ b/Orthtree/include/CGAL/Orthtree/Traversals.h @@ -23,6 +23,7 @@ namespace CGAL { /// \cond SKIP_IN_MANUAL +// todo: is this necessary? // Forward declaration template class Orthtree; @@ -32,8 +33,10 @@ namespace Orthtrees { /// \cond SKIP_IN_MANUAL -template -const Node* next_sibling(const Node* n) { +// todo: all of these could be members of Orthtree + +template +const typename Tree::Node* next_sibling(const Tree &orthtree, const typename Tree::Node* n) { // Passing null returns the first node if (nullptr == n) @@ -46,25 +49,25 @@ const Node* next_sibling(const Node* n) { // Find out which child this is std::size_t index = n->local_coordinates().to_ulong(); - constexpr static int degree = Node::Degree::value; + constexpr static int degree = Tree::Node::Degree::value; // Return null if this is the last child if (int(index) == degree - 1) return nullptr; // Otherwise, return the next child - return &((*n->parent())[index + 1]); + return &(orthtree.children(*n->parent())[index + 1]); } -template -const Node* next_sibling_up(const Node* n) { +template +const typename Tree::Node* next_sibling_up(const Tree &orthtree, const typename Tree::Node* n) { if (!n || n->is_root()) return nullptr; auto up = n->parent(); while (nullptr != up) { - if (nullptr != next_sibling(up)) - return next_sibling(up); + if (nullptr != next_sibling(orthtree, up)) + return next_sibling(orthtree, up); if (up->is_root()) return nullptr; @@ -74,41 +77,42 @@ const Node* next_sibling_up(const Node* n) { return nullptr; } -template -const Node* deepest_first_child(const Node* n) { +template +const typename Tree::Node* deepest_first_child(const Tree &orthtree, const typename Tree::Node* n) { - if (!n) + if (n == nullptr) return nullptr; // Find the deepest child on the left auto first = n; while (!first->is_leaf()) - first = &(*first)[0]; + first = &orthtree.children(*first)[0]; return first; } -template -const Node& first_child_at_depth(const Node* n, std::size_t depth) { + +template +const typename Tree::Node* first_child_at_depth(const Tree &orthtree, const typename Tree::Node* n, std::size_t depth) { if (!n) return nullptr; - std::stack todo; + std::stack todo; todo.push(n); if (n->depth() == depth) return n; while (!todo.empty()) { - const Node* node = todo.top(); + const typename Tree::Node* node = todo.top(); todo.pop(); if (node->depth() == depth) return node; if (!node->is_leaf()) - for (int i = 0; i < Node::Degree::value; ++i) - todo.push(&((*node)[std::size_t(Node::Degree::value - 1 - i)])); + for (int i = 0; i < Tree::Node::Degree::value; ++i) + todo.push(&((*node)[std::size_t(Tree::Node::Degree::value - 1 - i)])); } return nullptr; @@ -124,23 +128,31 @@ const Node& first_child_at_depth(const Node* n, std::size_t depth) { \cgalModels `OrthtreeTraversal` */ +template struct Preorder_traversal { +private: - template - const Node* first(const Node* root) const { - return root; + using Node = typename Tree::Node; + + const Tree& m_orthtree; + +public: + + Preorder_traversal(const Tree& orthtree) : m_orthtree(orthtree) {} + + const Node* first() const { + return &m_orthtree.root(); } - template const Node* next(const Node* n) const { if (n->is_leaf()) { - auto next = next_sibling(n); + auto next = next_sibling(m_orthtree, n); if (nullptr == next) { - return next_sibling_up(n); + return next_sibling_up(m_orthtree, n); } return next; @@ -148,7 +160,7 @@ struct Preorder_traversal { } else { // Return the first child of this node - return &(*n)[0]; + return &m_orthtree.children(*n)[0]; } } @@ -162,18 +174,25 @@ struct Preorder_traversal { \cgalModels `OrthtreeTraversal` */ +template struct Postorder_traversal { +private: - template - const Node* first(const Node* root) const { + using Node = typename Tree::Node; - return deepest_first_child(root); + const Tree& m_orthtree; + +public: + + Postorder_traversal(const Tree& orthtree) : m_orthtree(orthtree) {} + + const Node* first() const { + return deepest_first_child(m_orthtree, m_orthtree.root()); } - template const Node* next(const Node* n) const { - auto next = deepest_first_child(next_sibling(n)); + auto next = deepest_first_child(m_orthtree, next_sibling(m_orthtree, n)); if (!next) next = n->parent(); @@ -190,21 +209,28 @@ struct Postorder_traversal { \cgalModels `OrthtreeTraversal` */ +template struct Leaves_traversal { +private: - template - const Node* first(const Node* root) const { + using Node = typename Tree::Node; - return deepest_first_child(root); + const Tree& m_orthtree; + +public: + + Leaves_traversal(const Tree& orthtree) : m_orthtree(orthtree) {} + + const Node* first() const { + return deepest_first_child(m_orthtree, &m_orthtree.root()); } - template const Node* next(const Node* n) const { - auto next = deepest_first_child(next_sibling(n)); + auto next = deepest_first_child(m_orthtree, next_sibling(m_orthtree, n)); if (!next) - next = deepest_first_child(next_sibling_up(n)); + next = deepest_first_child(m_orthtree, next_sibling_up(m_orthtree, n)); return next; } @@ -219,38 +245,39 @@ struct Leaves_traversal { \cgalModels `OrthtreeTraversal` */ +template struct Level_traversal { - private: - const std::size_t depth; + using Node = typename Tree::Node; + + const Tree& m_orthtree; + const std::size_t m_depth; public: /*! constructs a `depth`-level traversal. */ - Level_traversal(std::size_t depth) : depth(depth) {} + Level_traversal(const Tree& orthtree, std::size_t depth) : m_orthtree(orthtree), m_depth(depth) {} template - const Node* first(const Node* root) const { - return first_child_at_depth(root, depth); + const Node* first() const { + return first_child_at_depth(m_orthtree, m_orthtree.root(), m_depth); } template const Node* next(const Node* n) const { - // fixme: leftover from debugging? - std::cerr << depth << " "; - const Node* next = next_sibling(n); + const Node* next = next_sibling(m_orthtree, n); if (!next) { const Node* up = n; do { - up = next_sibling_up(up); + up = next_sibling_up(m_orthtree, up); if (!up) return nullptr; - next = first_child_at_depth(up, depth); + next = first_child_at_depth(m_orthtree, up, m_depth); } while (!next); } diff --git a/Orthtree/test/Orthtree/test_node_adjacent.cpp b/Orthtree/test/Orthtree/test_node_adjacent.cpp index 1d4e55535d0..feee130ad7f 100644 --- a/Orthtree/test/Orthtree/test_node_adjacent.cpp +++ b/Orthtree/test/Orthtree/test_node_adjacent.cpp @@ -42,36 +42,39 @@ int main(void) { std::cout << octree << std::endl; // Root node should have no siblings - assert(octree.root().adjacent_node(0) == nullptr); - assert(octree.root().adjacent_node(1) == nullptr); - assert(octree.root().adjacent_node(2) == nullptr); - assert(octree.root().adjacent_node(3) == nullptr); - assert(octree.root().adjacent_node(4) == nullptr); - assert(octree.root().adjacent_node(5) == nullptr); + assert(octree.adjacent_node(octree.root(), 0) == nullptr); + assert(octree.adjacent_node(octree.root(), 1) == nullptr); + assert(octree.adjacent_node(octree.root(), 2) == nullptr); + assert(octree.adjacent_node(octree.root(), 3) == nullptr); + assert(octree.adjacent_node(octree.root(), 4) == nullptr); + assert(octree.adjacent_node(octree.root(), 5) == nullptr); // Left Top Front node should have siblings to the Right, Down, and Back - auto left_top_back = octree.root()[Traits::LEFT_TOP_BACK]; + auto left_top_back = octree.children(octree.root())[Traits::LEFT_TOP_BACK]; - assert(&octree.root()[Traits::RIGHT_TOP_BACK] == left_top_back.adjacent_node(Traits::RIGHT)); - assert(&octree.root()[Traits::LEFT_BOTTOM_BACK] == left_top_back.adjacent_node(Traits::DOWN)); - assert(&octree.root()[Traits::LEFT_TOP_FRONT] == left_top_back.adjacent_node(Traits::FRONT)); - assert(left_top_back.adjacent_node(Traits::LEFT) == nullptr); - assert(left_top_back.adjacent_node(Traits::UP) == nullptr); - assert(left_top_back.adjacent_node(Traits::BACK) == nullptr); + assert(&octree.children(octree.root())[Traits::RIGHT_TOP_BACK] == octree.adjacent_node(left_top_back, Traits::RIGHT)); + assert( + &octree.children(octree.root())[Traits::LEFT_BOTTOM_BACK] == octree.adjacent_node(left_top_back, Traits::DOWN)); + assert(&octree.children(octree.root())[Traits::LEFT_TOP_FRONT] == octree.adjacent_node(left_top_back, Traits::FRONT)); + assert(octree.adjacent_node(left_top_back, Traits::LEFT) == nullptr); + assert(octree.adjacent_node(left_top_back, Traits::UP) == nullptr); + assert(octree.adjacent_node(left_top_back, Traits::BACK) == nullptr); - std::cout << octree.root()[Traits::LEFT_BOTTOM_BACK] << std::endl; + std::cout << octree.children(octree.root())[Traits::LEFT_BOTTOM_BACK] << std::endl; - auto right_top_back_of_left_bottom_back = octree.root()[Traits::LEFT_BOTTOM_BACK][Traits::RIGHT_TOP_BACK]; - assert(&octree.root()[Traits::LEFT_BOTTOM_BACK][Traits::LEFT_TOP_BACK] == - right_top_back_of_left_bottom_back.adjacent_node(Traits::LEFT)); - assert(&octree.root()[Traits::RIGHT_BOTTOM_BACK] == right_top_back_of_left_bottom_back.adjacent_node(Traits::RIGHT)); - assert(right_top_back_of_left_bottom_back.adjacent_node(Traits::RIGHT) != nullptr); - assert(right_top_back_of_left_bottom_back.adjacent_node(Traits::UP) != nullptr); - assert(right_top_back_of_left_bottom_back.adjacent_node(Traits::DOWN) != nullptr); - assert(right_top_back_of_left_bottom_back.adjacent_node(Traits::FRONT) != nullptr); + auto right_top_back_of_left_bottom_back = + octree.children(octree.children(octree.root())[Traits::LEFT_BOTTOM_BACK])[Traits::RIGHT_TOP_BACK]; + assert(&octree.children(octree.children(octree.root())[Traits::LEFT_BOTTOM_BACK])[Traits::LEFT_TOP_BACK] == + octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::LEFT)); + assert(&octree.children(octree.root())[Traits::RIGHT_BOTTOM_BACK] == + octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::RIGHT)); + assert(octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::RIGHT) != nullptr); + assert(octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::UP) != nullptr); + assert(octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::DOWN) != nullptr); + assert(octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::FRONT) != nullptr); // A node at the back of the tree should have no neighbor to its back - assert(right_top_back_of_left_bottom_back.adjacent_node(Traits::BACK) == nullptr); + assert(octree.adjacent_node(right_top_back_of_left_bottom_back, Traits::BACK) == nullptr); return 0; } diff --git a/Orthtree/test/Orthtree/test_node_index.cpp b/Orthtree/test/Orthtree/test_node_index.cpp index 9ee08bd1083..fdabd97417c 100644 --- a/Orthtree/test/Orthtree/test_node_index.cpp +++ b/Orthtree/test/Orthtree/test_node_index.cpp @@ -10,7 +10,7 @@ typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Point_set_3 Point_set; typedef CGAL::Octree -Octree; + Octree; int main(void) { @@ -38,9 +38,10 @@ int main(void) { octree.refine(10, 1); std::cout << "root: " << octree.root().local_coordinates() << std::endl; - std::cout << "first child: " << octree.root()[0].local_coordinates() << std::endl; - std::cout << "fifth child: " << octree.root()[4].local_coordinates() << std::endl; - std::cout << "fifth child of first child: " << octree.root()[0][4].local_coordinates() << std::endl; + std::cout << "first child: " << octree.children(octree.root())[0].local_coordinates() << std::endl; + std::cout << "fifth child: " << octree.children(octree.root())[4].local_coordinates() << std::endl; + std::cout << "fifth child of first child: " + << octree.children(octree.children(octree.root())[0])[4].local_coordinates() << std::endl; // TODO diff --git a/Orthtree/test/Orthtree/test_octree_bbox.cpp b/Orthtree/test/Orthtree/test_octree_bbox.cpp index 375894cc54c..097d7442ddc 100644 --- a/Orthtree/test/Orthtree/test_octree_bbox.cpp +++ b/Orthtree/test/Orthtree/test_octree_bbox.cpp @@ -11,7 +11,7 @@ typedef Kernel::Point_3 Point; typedef Kernel::FT FT; typedef CGAL::Point_set_3 Point_set; typedef CGAL::Octree -Octree; + Octree; void test_1_node() { @@ -42,14 +42,14 @@ void test_9_nodes() { assert(octree.bbox(octree.root()) == CGAL::Bbox_3(-1.1, -1.1, -1.1, 1.1, 1.1, 1.1)); // Compare the child nodes - assert(octree.bbox(octree.root()[0]) == CGAL::Bbox_3(-1.1, -1.1, -1.1, 0, 0, 0)); - assert(octree.bbox(octree.root()[1]) == CGAL::Bbox_3(0, -1.1, -1.1, 1.1, 0, 0)); - assert(octree.bbox(octree.root()[2]) == CGAL::Bbox_3(-1.1, 0, -1.1, 0, 1.1, 0)); - assert(octree.bbox(octree.root()[3]) == CGAL::Bbox_3(0, 0, -1.1, 1.1, 1.1, 0)); - assert(octree.bbox(octree.root()[4]) == CGAL::Bbox_3(-1.1, -1.1, 0, 0, 0, 1.1)); - assert(octree.bbox(octree.root()[5]) == CGAL::Bbox_3(0, -1.1, 0, 1.1, 0, 1.1)); - assert(octree.bbox(octree.root()[6]) == CGAL::Bbox_3(-1.1, 0, 0, 0, 1.1, 1.1)); - assert(octree.bbox(octree.root()[7]) == CGAL::Bbox_3(0, 0, 0, 1.1, 1.1, 1.1)); + assert(octree.bbox(octree.children(octree.root())[0]) == CGAL::Bbox_3(-1.1, -1.1, -1.1, 0, 0, 0)); + assert(octree.bbox(octree.children(octree.root())[1]) == CGAL::Bbox_3(0, -1.1, -1.1, 1.1, 0, 0)); + assert(octree.bbox(octree.children(octree.root())[2]) == CGAL::Bbox_3(-1.1, 0, -1.1, 0, 1.1, 0)); + assert(octree.bbox(octree.children(octree.root())[3]) == CGAL::Bbox_3(0, 0, -1.1, 1.1, 1.1, 0)); + assert(octree.bbox(octree.children(octree.root())[4]) == CGAL::Bbox_3(-1.1, -1.1, 0, 0, 0, 1.1)); + assert(octree.bbox(octree.children(octree.root())[5]) == CGAL::Bbox_3(0, -1.1, 0, 1.1, 0, 1.1)); + assert(octree.bbox(octree.children(octree.root())[6]) == CGAL::Bbox_3(-1.1, 0, 0, 0, 1.1, 1.1)); + assert(octree.bbox(octree.children(octree.root())[7]) == CGAL::Bbox_3(0, 0, 0, 1.1, 1.1, 1.1)); } void test_25_nodes() { @@ -69,34 +69,50 @@ void test_25_nodes() { assert(octree.bbox(octree.root()) == CGAL::Bbox_3(-1.5, -1.5, -1.5, 1.5, 1.5, 1.5)); // Compare the child nodes - assert(octree.bbox(octree.root()[0]) == CGAL::Bbox_3(-1.5, -1.5, -1.5, 0, 0, 0)); - assert(octree.bbox(octree.root()[1]) == CGAL::Bbox_3(0, -1.5, -1.5, 1.5, 0, 0)); - assert(octree.bbox(octree.root()[2]) == CGAL::Bbox_3(-1.5, 0, -1.5, 0, 1.5, 0)); - assert(octree.bbox(octree.root()[3]) == CGAL::Bbox_3(0, 0, -1.5, 1.5, 1.5, 0)); - assert(octree.bbox(octree.root()[4]) == CGAL::Bbox_3(-1.5, -1.5, 0, 0, 0, 1.5)); - assert(octree.bbox(octree.root()[5]) == CGAL::Bbox_3(0, -1.5, 0, 1.5, 0, 1.5)); - assert(octree.bbox(octree.root()[6]) == CGAL::Bbox_3(-1.5, 0, 0, 0, 1.5, 1.5)); - assert(octree.bbox(octree.root()[7]) == CGAL::Bbox_3(0, 0, 0, 1.5, 1.5, 1.5)); + assert(octree.bbox(octree.children(octree.root())[0]) == CGAL::Bbox_3(-1.5, -1.5, -1.5, 0, 0, 0)); + assert(octree.bbox(octree.children(octree.root())[1]) == CGAL::Bbox_3(0, -1.5, -1.5, 1.5, 0, 0)); + assert(octree.bbox(octree.children(octree.root())[2]) == CGAL::Bbox_3(-1.5, 0, -1.5, 0, 1.5, 0)); + assert(octree.bbox(octree.children(octree.root())[3]) == CGAL::Bbox_3(0, 0, -1.5, 1.5, 1.5, 0)); + assert(octree.bbox(octree.children(octree.root())[4]) == CGAL::Bbox_3(-1.5, -1.5, 0, 0, 0, 1.5)); + assert(octree.bbox(octree.children(octree.root())[5]) == CGAL::Bbox_3(0, -1.5, 0, 1.5, 0, 1.5)); + assert(octree.bbox(octree.children(octree.root())[6]) == CGAL::Bbox_3(-1.5, 0, 0, 0, 1.5, 1.5)); + assert(octree.bbox(octree.children(octree.root())[7]) == CGAL::Bbox_3(0, 0, 0, 1.5, 1.5, 1.5)); // Compare children of the first child - assert(octree.bbox(octree.root()[0][0]) == CGAL::Bbox_3(-1.5, -1.5, -1.5, -0.75, -0.75, -0.75)); - assert(octree.bbox(octree.root()[0][1]) == CGAL::Bbox_3(-0.75, -1.5, -1.5, 0, -0.75, -0.75)); - assert(octree.bbox(octree.root()[0][2]) == CGAL::Bbox_3(-1.5, -0.75, -1.5, -0.75, 0, -0.75)); - assert(octree.bbox(octree.root()[0][3]) == CGAL::Bbox_3(-0.75, -0.75, -1.5, 0, 0, -0.75)); - assert(octree.bbox(octree.root()[0][4]) == CGAL::Bbox_3(-1.5, -1.5, -0.75, -0.75, -0.75, 0)); - assert(octree.bbox(octree.root()[0][5]) == CGAL::Bbox_3(-0.75, -1.5, -0.75, 0, -0.75, 0)); - assert(octree.bbox(octree.root()[0][6]) == CGAL::Bbox_3(-1.5, -0.75, -0.75, -0.75, 0, 0)); - assert(octree.bbox(octree.root()[0][7]) == CGAL::Bbox_3(-0.75, -0.75, -0.75, 0, 0, 0)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[0]) == + CGAL::Bbox_3(-1.5, -1.5, -1.5, -0.75, -0.75, -0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[1]) == + CGAL::Bbox_3(-0.75, -1.5, -1.5, 0, -0.75, -0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[2]) == + CGAL::Bbox_3(-1.5, -0.75, -1.5, -0.75, 0, -0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[3]) == + CGAL::Bbox_3(-0.75, -0.75, -1.5, 0, 0, -0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[4]) == + CGAL::Bbox_3(-1.5, -1.5, -0.75, -0.75, -0.75, 0)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[5]) == + CGAL::Bbox_3(-0.75, -1.5, -0.75, 0, -0.75, 0)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[6]) == + CGAL::Bbox_3(-1.5, -0.75, -0.75, -0.75, 0, 0)); + assert(octree.bbox(octree.children(octree.children(octree.root())[0])[7]) == + CGAL::Bbox_3(-0.75, -0.75, -0.75, 0, 0, 0)); // Compare children of the last child - assert(octree.bbox(octree.root()[7][0]) == CGAL::Bbox_3(0, 0, 0, 0.75, 0.75, 0.75)); - assert(octree.bbox(octree.root()[7][1]) == CGAL::Bbox_3(0.75, 0, 0, 1.5, 0.75, 0.75)); - assert(octree.bbox(octree.root()[7][2]) == CGAL::Bbox_3(0, 0.75, 0, 0.75, 1.5, 0.75)); - assert(octree.bbox(octree.root()[7][3]) == CGAL::Bbox_3(0.75, 0.75, 0, 1.5, 1.5, 0.75)); - assert(octree.bbox(octree.root()[7][4]) == CGAL::Bbox_3(0, 0, 0.75, 0.75, 0.75, 1.5)); - assert(octree.bbox(octree.root()[7][5]) == CGAL::Bbox_3(0.75, 0, 0.75, 1.5, 0.75, 1.5)); - assert(octree.bbox(octree.root()[7][6]) == CGAL::Bbox_3(0, 0.75, 0.75, 0.75, 1.5, 1.5)); - assert(octree.bbox(octree.root()[7][7]) == CGAL::Bbox_3(0.75, 0.75, 0.75, 1.5, 1.5, 1.5)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[0]) == + CGAL::Bbox_3(0, 0, 0, 0.75, 0.75, 0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[1]) == + CGAL::Bbox_3(0.75, 0, 0, 1.5, 0.75, 0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[2]) == + CGAL::Bbox_3(0, 0.75, 0, 0.75, 1.5, 0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[3]) == + CGAL::Bbox_3(0.75, 0.75, 0, 1.5, 1.5, 0.75)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[4]) == + CGAL::Bbox_3(0, 0, 0.75, 0.75, 0.75, 1.5)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[5]) == + CGAL::Bbox_3(0.75, 0, 0.75, 1.5, 0.75, 1.5)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[6]) == + CGAL::Bbox_3(0, 0.75, 0.75, 0.75, 1.5, 1.5)); + assert(octree.bbox(octree.children(octree.children(octree.root())[7])[7]) == + CGAL::Bbox_3(0.75, 0.75, 0.75, 1.5, 1.5, 1.5)); } int main(void) { diff --git a/Orthtree/test/Orthtree/test_octree_grade.cpp b/Orthtree/test/Orthtree/test_octree_grade.cpp index 686068028fc..9399d70585d 100644 --- a/Orthtree/test/Orthtree/test_octree_grade.cpp +++ b/Orthtree/test/Orthtree/test_octree_grade.cpp @@ -15,17 +15,17 @@ typedef Kernel::Point_3 Point; typedef Kernel::FT FT; typedef CGAL::Point_set_3 Point_set; typedef CGAL::Octree Octree; -typedef CGAL::Orthtrees::Leaves_traversal Leaves_traversal; +typedef CGAL::Orthtrees::Leaves_traversal Leaves_traversal; std::size_t count_jumps(Octree &octree) { std::size_t jumps = 0; - for (auto &node : octree.traverse(Leaves_traversal())) { + for (auto &node : octree.traverse()) { for (int direction = 0; direction < 6; ++direction) { - auto adjacent_node = node.adjacent_node(direction); + auto adjacent_node = octree.adjacent_node(node, direction); if (adjacent_node == nullptr) continue; diff --git a/Orthtree/test/Orthtree/test_octree_intersecting.cpp b/Orthtree/test/Orthtree/test_octree_intersecting.cpp index b731ec04e33..b4bf0a21d9c 100644 --- a/Orthtree/test/Orthtree/test_octree_intersecting.cpp +++ b/Orthtree/test/Orthtree/test_octree_intersecting.cpp @@ -46,7 +46,7 @@ int main(void) { auto query = Point{1, 1, 1}; // Get a list of nodes intersected - std::vector nodes{}; + std::vector nodes{}; octree.intersected_nodes(query, std::back_inserter(nodes)); // A point should only intersect one node @@ -63,15 +63,15 @@ int main(void) { auto query = Kernel::Sphere_3(Point{1, 0.5, 1}, 1.0); // Get a list of nodes intersected - std::vector nodes{}; + std::vector nodes{}; octree.intersected_nodes(query, std::back_inserter(nodes)); // Check the results assert(4 == nodes.size()); - assert(octree.root()[Octree::Traits::RIGHT_TOP_BACK] == *nodes[0]); - assert(octree.root()[Octree::Traits::RIGHT_BOTTOM_FRONT] == *nodes[1]); - assert(octree.root()[Octree::Traits::LEFT_TOP_FRONT] == *nodes[2]); - assert(octree.root()[Octree::Traits::RIGHT_TOP_FRONT] == *nodes[3]); + assert(octree.children(octree.root())[Octree::Traits::RIGHT_TOP_BACK] == *nodes[0]); + assert(octree.children(octree.root())[Octree::Traits::RIGHT_BOTTOM_FRONT] == *nodes[1]); + assert(octree.children(octree.root())[Octree::Traits::LEFT_TOP_FRONT] == *nodes[2]); + assert(octree.children(octree.root())[Octree::Traits::RIGHT_TOP_FRONT] == *nodes[3]); } // Intersection with a ray @@ -81,19 +81,22 @@ int main(void) { auto query = Kernel::Ray_3(Point{1, 1, 1}, Point{0, 0, 0}); // Get a list of nodes intersected - std::vector nodes{}; + std::vector nodes{}; octree.intersected_nodes(query, std::back_inserter(nodes)); // Check the results assert(8 == nodes.size()); - assert(octree.root()[Octree::Traits::LEFT_BOTTOM_BACK] == *nodes[0]); - assert(octree.root()[Octree::Traits::RIGHT_BOTTOM_BACK][Octree::Traits::LEFT_TOP_FRONT] == *nodes[1]); - assert(octree.root()[Octree::Traits::LEFT_TOP_BACK] == *nodes[2]); - assert(octree.root()[Octree::Traits::RIGHT_TOP_BACK] == *nodes[3]); - assert(octree.root()[Octree::Traits::LEFT_BOTTOM_FRONT] == *nodes[4]); - assert(octree.root()[Octree::Traits::RIGHT_BOTTOM_FRONT] == *nodes[5]); - assert(octree.root()[Octree::Traits::LEFT_TOP_FRONT] == *nodes[6]); - assert(octree.root()[Octree::Traits::RIGHT_TOP_FRONT] == *nodes[7]); + assert(octree.children(octree.root())[Octree::Traits::LEFT_BOTTOM_BACK] == *nodes[0]); + assert( + octree.children(octree.children(octree.root())[Octree::Traits::RIGHT_BOTTOM_BACK])[Octree::Traits::LEFT_TOP_FRONT] + == *nodes[1] + ); + assert(octree.children(octree.root())[Octree::Traits::LEFT_TOP_BACK] == *nodes[2]); + assert(octree.children(octree.root())[Octree::Traits::RIGHT_TOP_BACK] == *nodes[3]); + assert(octree.children(octree.root())[Octree::Traits::LEFT_BOTTOM_FRONT] == *nodes[4]); + assert(octree.children(octree.root())[Octree::Traits::RIGHT_BOTTOM_FRONT] == *nodes[5]); + assert(octree.children(octree.root())[Octree::Traits::LEFT_TOP_FRONT] == *nodes[6]); + assert(octree.children(octree.root())[Octree::Traits::RIGHT_TOP_FRONT] == *nodes[7]); } return EXIT_SUCCESS; diff --git a/Orthtree/test/Orthtree/test_octree_locate.cpp b/Orthtree/test/Orthtree/test_octree_locate.cpp index d601e361466..54c7d2e2281 100644 --- a/Orthtree/test/Orthtree/test_octree_locate.cpp +++ b/Orthtree/test/Orthtree/test_octree_locate.cpp @@ -13,7 +13,7 @@ typedef Kernel::Point_3 Point; typedef Kernel::FT FT; typedef CGAL::Point_set_3 Point_set; typedef CGAL::Octree -Octree; + Octree; void test_1_point() { @@ -52,24 +52,24 @@ void test_8_points() { octree.refine(10, 1); // Existing points should end up in the same place - assert(octree.root()[0] == octree.locate({-1, -1, -1})); - assert(octree.root()[1] == octree.locate({1, -1, -1})); - assert(octree.root()[2] == octree.locate({-1, 1, -1})); - assert(octree.root()[3] == octree.locate({1, 1, -1})); - assert(octree.root()[4] == octree.locate({-1, -1, 1})); - assert(octree.root()[5] == octree.locate({1, -1, 1})); - assert(octree.root()[6] == octree.locate({-1, 1, 1})); - assert(octree.root()[7] == octree.locate({1, 1, 1})); + assert(octree.children(octree.root())[0] == octree.locate({-1, -1, -1})); + assert(octree.children(octree.root())[1] == octree.locate({1, -1, -1})); + assert(octree.children(octree.root())[2] == octree.locate({-1, 1, -1})); + assert(octree.children(octree.root())[3] == octree.locate({1, 1, -1})); + assert(octree.children(octree.root())[4] == octree.locate({-1, -1, 1})); + assert(octree.children(octree.root())[5] == octree.locate({1, -1, 1})); + assert(octree.children(octree.root())[6] == octree.locate({-1, 1, 1})); + assert(octree.children(octree.root())[7] == octree.locate({1, 1, 1})); // Points adjacent to the existing points should also end up in the same place - assert(octree.root()[0] == octree.locate({-1.1, -1.1, -1.1})); - assert(octree.root()[1] == octree.locate({1.1, -1.1, -1.1})); - assert(octree.root()[2] == octree.locate({-1.1, 1.1, -1.1})); - assert(octree.root()[3] == octree.locate({1.1, 1.1, -1.1})); - assert(octree.root()[4] == octree.locate({-1.1, -1.1, 1.1})); - assert(octree.root()[5] == octree.locate({1.1, -1.1, 1.1})); - assert(octree.root()[6] == octree.locate({-1.1, 1.1, 1.1})); - assert(octree.root()[7] == octree.locate({1.1, 1.1, 1.1})); + assert(octree.children(octree.root())[0] == octree.locate({-1.1, -1.1, -1.1})); + assert(octree.children(octree.root())[1] == octree.locate({1.1, -1.1, -1.1})); + assert(octree.children(octree.root())[2] == octree.locate({-1.1, 1.1, -1.1})); + assert(octree.children(octree.root())[3] == octree.locate({1.1, 1.1, -1.1})); + assert(octree.children(octree.root())[4] == octree.locate({-1.1, -1.1, 1.1})); + assert(octree.children(octree.root())[5] == octree.locate({1.1, -1.1, 1.1})); + assert(octree.children(octree.root())[6] == octree.locate({-1.1, 1.1, 1.1})); + assert(octree.children(octree.root())[7] == octree.locate({1.1, 1.1, 1.1})); } @@ -93,24 +93,24 @@ void test_10_points() { octree.refine(10, 1); // Existing points should end up in the same place - assert(octree.root()[0] == octree.locate({-1, -1, -1})); - assert(octree.root()[1] == octree.locate({1, -1, -1})); - assert(octree.root()[2] == octree.locate({-1, 1, -1})); - assert(octree.root()[3][3][3] == octree.locate({1, 1, -1})); - assert(octree.root()[4][4][4] == octree.locate({-1, -1, 1})); - assert(octree.root()[5] == octree.locate({1, -1, 1})); - assert(octree.root()[6] == octree.locate({-1, 1, 1})); - assert(octree.root()[7] == octree.locate({1, 1, 1})); + assert(octree.children(octree.root())[0] == octree.locate({-1, -1, -1})); + assert(octree.children(octree.root())[1] == octree.locate({1, -1, -1})); + assert(octree.children(octree.root())[2] == octree.locate({-1, 1, -1})); + assert(octree.children(octree.children(octree.children(octree.root())[3])[3])[3] == octree.locate({1, 1, -1})); + assert(octree.children(octree.children(octree.children(octree.root())[4])[4])[4] == octree.locate({-1, -1, 1})); + assert(octree.children(octree.root())[5] == octree.locate({1, -1, 1})); + assert(octree.children(octree.root())[6] == octree.locate({-1, 1, 1})); + assert(octree.children(octree.root())[7] == octree.locate({1, 1, 1})); // Points adjacent to the existing points might end up in different places - assert(octree.root()[0] == octree.locate({-1.1, -1.1, -1.1})); - assert(octree.root()[1] == octree.locate({1.1, -1.1, -1.1})); - assert(octree.root()[2] == octree.locate({-1.1, 1.1, -1.1})); - assert(octree.root()[3][3][3] == octree.locate({1.1, 1.1, -1.1})); - assert(octree.root()[4][4][4] == octree.locate({-1.1, -1.1, 1.1})); - assert(octree.root()[5] == octree.locate({1.1, -1.1, 1.1})); - assert(octree.root()[6] == octree.locate({-1.1, 1.1, 1.1})); - assert(octree.root()[7] == octree.locate({1.1, 1.1, 1.1})); + assert(octree.children(octree.root())[0] == octree.locate({-1.1, -1.1, -1.1})); + assert(octree.children(octree.root())[1] == octree.locate({1.1, -1.1, -1.1})); + assert(octree.children(octree.root())[2] == octree.locate({-1.1, 1.1, -1.1})); + assert(octree.children(octree.children(octree.children(octree.root())[3])[3])[3] == octree.locate({1.1, 1.1, -1.1})); + assert(octree.children(octree.children(octree.children(octree.root())[4])[4])[4] == octree.locate({-1.1, -1.1, 1.1})); + assert(octree.children(octree.root())[5] == octree.locate({1.1, -1.1, 1.1})); + assert(octree.children(octree.root())[6] == octree.locate({-1.1, 1.1, 1.1})); + assert(octree.children(octree.root())[7] == octree.locate({1.1, 1.1, 1.1})); } diff --git a/Orthtree/test/Orthtree/test_octree_refine.cpp b/Orthtree/test/Orthtree/test_octree_refine.cpp index ae4549588df..30c251e7b3b 100644 --- a/Orthtree/test/Orthtree/test_octree_refine.cpp +++ b/Orthtree/test/Orthtree/test_octree_refine.cpp @@ -43,7 +43,7 @@ void test_2_points() { // The octree should have been split once Octree other(points, points.point_map()); other.split(other.root()); - assert(Node::is_topology_equal(other.root(), octree.root())); + assert(Octree::is_topology_equal(other, octree)); assert(1 == octree.depth()); } @@ -62,9 +62,9 @@ void test_4_points() { // The octree should have been split once on the first level, and twice on the second Octree other(points, points.point_map()); other.split(other.root()); - other.split(other.root()[3]); - other.split(other.root()[7]); - assert(Node::is_topology_equal(other.root(), octree.root())); + other.split(other.children(other.root())[3]); + other.split(other.children(other.root())[7]); + assert(Octree::is_topology_equal(other, octree)); assert(2 == octree.depth()); } diff --git a/Orthtree/test/Orthtree/test_octree_traverse.cpp b/Orthtree/test/Orthtree/test_octree_traverse.cpp index 57853df8dfa..99664d21cb1 100644 --- a/Orthtree/test/Orthtree/test_octree_traverse.cpp +++ b/Orthtree/test/Orthtree/test_octree_traverse.cpp @@ -12,7 +12,7 @@ typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Point_set_3 Point_set; typedef CGAL::Octree Octree; -typedef CGAL::Orthtrees::Preorder_traversal Preorder_traversal; +typedef CGAL::Orthtrees::Preorder_traversal Preorder_traversal; bool test_preorder_1_node() { @@ -53,7 +53,7 @@ bool test_preorder_9_nodes() { assert(*iter == octree.root()); for (int i = 0; i < 8; ++i) { iter++; - assert((*iter == octree.root()[i])); + assert((*iter == octree.children(octree.root())[i])); } return true; @@ -79,28 +79,28 @@ bool test_preorder_25_nodes() { auto iter = nodes.begin(); assert(*iter == octree.root()); iter++; - assert((*iter == octree.root()[0])); + assert((*iter == octree.children(octree.root())[0])); iter++; - assert((*iter == octree.root()[1])); + assert((*iter == octree.children(octree.root())[1])); iter++; - assert((*iter == octree.root()[2])); + assert((*iter == octree.children(octree.root())[2])); iter++; - assert((*iter == octree.root()[3])); + assert((*iter == octree.children(octree.root())[3])); for (int i = 0; i < 8; ++i) { iter++; - assert((*iter == octree.root()[3][i])); + assert((*iter == octree.children(octree.children(octree.root())[3])[i])); } iter++; - assert((*iter == octree.root()[4])); + assert((*iter == octree.children(octree.root())[4])); iter++; - assert((*iter == octree.root()[5])); + assert((*iter == octree.children(octree.root())[5])); iter++; - assert((*iter == octree.root()[6])); + assert((*iter == octree.children(octree.root())[6])); iter++; - assert((*iter == octree.root()[7])); + assert((*iter == octree.children(octree.root())[7])); for (int i = 0; i < 8; ++i) { iter++; - assert((*iter == octree.root()[7][i])); + assert((*iter == octree.children(octree.children(octree.root())[7])[i])); } return true;