tdtree_node.h

Back to Temporal kd-tree

pastel/geometry/tdtree/

// Description: Temporal kd-tree node
// Documentation: tdtree.txt

#ifndef PASTELGEOMETRY_TDTREE_NODE_H
#define PASTELGEOMETRY_TDTREE_NODE_H

#include "pastel/geometry/tdtree/tdtree_fwd.h"

#include <array>

namespace Pastel
{

    //! Temporal kd-tree node
    template <typename Settings>
    class TdTree_Fwd<Settings>::Node
    {
    public:
        //! Returns a child node.
        Node*& child(bool right)
        {
            return childSet_[right];
        }

        //! Returns a child node.
        const Node* child(bool right) const
        {
            return childSet_[right];
        }

        //! Returns the split-point.
        const ConstIterator& split() const
        {
            return split_;
        }

        //! Returns the split-axis.
        integer splitAxis() const
        {
            return splitAxis_;
        }

        //! Returns whether the node is an end-node.
        bool isEnd() const
        {
            // The end-node is the only node
            // which is the child of itself.
            return child(false) == this;
        }

        //! Returns whether the node is a leaf.
        bool leaf() const
        {
            // A node is a leaf if and only if
            // it is not the end-node and its
            // children are equal.
            return !isEnd() &&
                child(false) == child(true);
        }

        //! Returns the stored points.
        Entry_ConstRange entryRange() const
        {
            return Pastel::range(
                entrySet_.begin(), 
                entrySet_.end());
        }

        //! Returns the number of stored points.
        integer entries() const
        {
            return entrySet_.size();
        }

        integer points() const
        {
            return entries() - 1;
        }

        const Real& min() const
        {
            return min_;
        }

        const Real& max() const
        {
            return max_;
        }

        const Real& prevMin() const
        {
            return prevMin_;
        }

        const Real& prevMax() const
        {
            return prevMax_;
        }

    private:
        template <typename, template <typename> class>
        friend class TdTree;

        Node()
        : childSet_()
        , split_()
        , splitAxis_(0)
        , entrySet_()
        , min_(0)
        , max_(0)
        , prevMin_(0)
        , prevMax_(0)
        {
            child(false) = this;
            child(true) = this;
            entrySet_.emplace_back(Iterator());
        }

        explicit Node(
            const std::vector<Iterator>& iteratorSet)
        : childSet_()
        , split_()
        , splitAxis_(0)
        , entrySet_()
        , min_(0)
        , max_(0)
        , prevMin_(0)
        , prevMax_(0)
        {
            entrySet_.reserve(iteratorSet.size() + 1);
            RANGES_FOR(auto&& i, iteratorSet)
            {
                entrySet_.emplace_back(i);
            }
            entrySet_.emplace_back(Iterator());
        }

        void isolate(Node* end)
        {
            child(false) = end;
            child(true) = end;
        }

        Node(const Node&) = delete;
        Node(Node&&) = delete;
        Node& operator=(const Node&) = delete;

        //! The child-nodes.
        /*!
       The first (second) node contains the points that 
       are < (>=) the split point on the splitting axis.
       */
        std::array<Node*, 2> childSet_;

        //! The splitting position.
        /*!
       The splitting position is given by 
       locator(split_->point(), splitAxis).
       */
        Iterator split_;

        //! The splitting axis.
        /*!
       This is the index of the standard basis 
       vector to use for the normal of the
       splitting plane normal.
       */
        integer splitAxis_;

        //! The set of points.
        EntrySet entrySet_;

        //! Node bounds on the splitting axis of the parent.

        Real min_;
        Real max_;

        //! The previous node bounds on the splitting axis of the parent.
        /*!
       This information is important for the efficient 
       incremental computation of distance between the
       search point and the kd-tree nodes in the nearest 
       neighbor search algorithm.
       */
        Real prevMin_;
        Real prevMax_;
    };

}

#endif