// 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