#ifndef __octree_h #define __octree_h #include /**\brief An n-dimensional octree. Perhaps it should be named a tttntree (two-to-the n tree)? * * This templated class provides an n-dimensional binary tree, storing an * object whose type is specified by the first template parameter at each * node (whether or not that node is a leaf). * The second template parameter is an integer constant specifying the * dimension of the tree. * The final template parameter takes an allocator object just as the STL does. * * The tree itself stores the center and overall bounds of the root node; * the nodes themselves do not contain any information on the geometry. * If needed, it can be derived from an octree_path object referring to * the node or stored in the template class at each node for fast access. * This makes the class useful for storing abstract trees with minimal overhead * as well as trees embedded in a metric space. * * Access to entries in the tree is provided by octree_cursor and octree_iterator * objects, both of which inherit octree_path. * An octree_path stores a vector of integers describing a descent from the root * node to a particular child node of the octree. * Since each node of a \f$d\f$-dimensional tree has \f$2^d\f$ children, * the integers in the vector will all be in \f$\{0,\ldots,2^d-1\}\f$. * * The octree_cursor class provides a free-form way to visit nodes in the octree; * it does not behave like an iterator that guarantees each node will be visited once. * Instead, it provides a way to move up, down, and across the tree from any location. * This makes it useful for local queries that do not need to traverse the entire tree. * * The octree_iterator class simply traverses the tree in depth-first order * and can be configured to visit only leaf nodes or to include all nodes. */ template > class octree { public: typedef T_ value_type; typedef T_* pointer; typedef T_& reference; typedef const T_* const_pointer; typedef const T_& const_reference; typedef octree _self_type; typedef _self_type* _self_pointer; typedef octree_node* octree_node_pointer; typedef octree_node& octree_node_reference; typedef const octree_node* const_octree_node_pointer; typedef const octree_node& const_octree_node_reference; typedef typename std::vector::size_type size_type; typedef A_ allocator_type; // Ugly. But necessary according to young me. Old me says so. typedef octree_iterator iterator; typedef octree_iterator const_iterator; typedef octree_cursor cursor; typedef octree_cursor const_cursor; octree(const double* center, double size); octree(const double* center, double size, const value_type& root_node_value); virtual ~octree(); /** \brief Iterator based access. * * Iterators come in const and non-const versions as well as versions * that visit all nodes or just leaf nodes. By default, only leaf nodes * are visited. * * You may add or remove children while iterating with some caveats. * When adding children, any iterator currently referencing the node * to which children were added will reference the first child node * when incremented. Iterators confined to leaf nodes may reference * non-leaf nodes when refinement occurs between increments/decrements. * When removing children from node \a A, any iterators pointing to * grandchildren of \a A will become invalid. Iterators pointing to * children of \a A may not be dereferenced but may be incremented or * decremented safely. */ //@{ iterator begin(bool only_leaves = true) { return iterator(_M_root, _M_root, only_leaves); } iterator end(bool only_leaves = true) { return iterator(_M_root, nullptr, only_leaves); } const_iterator begin(bool only_leaves = true) const { return const_iterator(_M_root, _M_root, only_leaves); } const_iterator end(bool only_leaves = true) const { return const_iterator(_M_root, 0, only_leaves); } //@} octree_node_pointer root() { return this->_M_root; } size_t size(bool only_leaves = false); /** \brief Geometric information * Binary trees of dimension 2 or higher are often used to partition geometric objects into * subsets. In order to do this, the tree must have some geometric center and size. These are set * by the constructor but may be queried at any time. They may not be modified as that would * require a re-partitioning of the objects (typically stored at nodes or leaf-nodes). */ //@{ const double* center() const { return this->_M_center; } double size() const { return this->_M_size; } //@} protected: octree_node_pointer _M_root; double _M_center[d_]; double _M_size; }; #endif // __octree_h