47 #ifndef _OPENGR_ACCELERATORS_KDTREE_H 48 #define _OPENGR_ACCELERATORS_KDTREE_H 50 #include "gr/utils/disablewarnings.h" 53 #include <Eigen/Geometry> 61 #define KD_MAX_DEPTH 32
64 #define KD_POINT_PER_CELL 64
72 template<
typename _Scalar,
typename _Index =
int >
81 unsigned int firstChildId:24;
115 template <
int _stackSize = 64>
135 KdTree(
unsigned int size = 0,
140 template <
class VectorDerived>
141 inline void add(
const VectorDerived &p ){
143 mPoints.push_back(p);
144 mIndices.push_back(mIndices.size());
149 add(Eigen::Map< Eigen::Matrix<Scalar, 3, 1> >(position));
166 Container& result)
const {
167 _doQueryDistIndicesWithFunctor(query, [&result,
this](
unsigned int i){
168 result.push_back(mPoints[i]);
175 template<
int stackSize,
typename IndexContainer =
std::
vector<
Index> >
178 IndexContainer& result)
const {
179 _doQueryDistIndicesWithFunctor(query, [&result,
this](
unsigned int i){
180 result.push_back(mIndices[i]);
187 template<
int stackSize,
typename Functor>
191 _doQueryDistIndicesWithFunctor(query, [f,
this](
unsigned int i){
200 template<
int stackSize>
203 int currentId = -1)
const;
205 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
215 unsigned int split(
int start,
int end,
unsigned int dim,
Scalar splitValue);
221 unsigned int targetCellsize,
222 unsigned int targetMaxDepth);
228 template<
int stackSize,
typename Functor >
250 template<
typename Scalar,
typename Index>
252 unsigned int nofPointsPerCell,
253 unsigned int maxDepth)
259 mAABB.extend(points.cbegin(), points.cend());
260 std::iota (mIndices.begin(), mIndices.end(), 0);
270 template<
typename Scalar,
typename Index>
272 unsigned int nofPointsPerCell,
273 unsigned int maxDepth)
277 mPoints.reserve(size);
278 mIndices.reserve(size);
281 template<
typename Scalar,
typename Index>
286 mNodes.reserve(4*mPoints.size()/_nofPointsPerCell);
287 mNodes.emplace_back();
288 mNodes.back().leaf = 0;
290 std::cout <<
"create tree" << std::endl;
292 createTree(0, 0, mPoints.size(), 1, _nofPointsPerCell, _maxDepth);
294 std::cout <<
"create tree ... DONE (" << mPoints.size() <<
" points)" << std::endl;
298 template<
typename Scalar,
typename Index>
321 template<
int stackSize>
322 std::pair<Index, Scalar>
328 Index cl_id = invalidIndex();
329 Scalar cl_dist = query.sqdist;
331 query.nodeStack[0].nodeId = 0;
332 query.nodeStack[0].sq = 0.f;
333 unsigned int count = 1;
339 QueryNode& qnode = query.nodeStack[count-1];
342 if (qnode.sq < cl_dist)
347 const int end = node.start+node.size;
348 for (
int i=node.start ; i<end ; ++i){
349 const Scalar sqdist = (query.queryPoint -
mPoints[i]).squaredNorm();
350 if (sqdist <= cl_dist &&
mIndices[i] != currentId){
359 const Scalar new_off = query.queryPoint[node.dim] - node.splitValue;
365 query.nodeStack[count].nodeId = node.firstChildId;
366 qnode.nodeId = node.firstChildId+1;
370 query.nodeStack[count].nodeId = node.firstChildId+1;
371 qnode.nodeId = node.firstChildId;
373 query.nodeStack[count].sq = qnode.sq;
374 qnode.sq = new_off*new_off;
384 return std::make_pair(cl_id, cl_dist);
395 template<
int stackSize,
typename Functor >
401 query.nodeStack[0].nodeId = 0;
402 query.nodeStack[0].sq = 0.f;
403 unsigned int count = 1;
407 QueryNode& qnode = query.nodeStack[count-1];
410 if (qnode.sq < query.sqdist)
415 unsigned int end = node.start+node.size;
416 for (
unsigned int i=node.start ; i<end ; ++i)
417 if ( (query.queryPoint -
mPoints[i]).squaredNorm() < query.sqdist){
424 Scalar new_off = query.queryPoint[node.dim] - node.splitValue;
427 query.nodeStack[count].nodeId = node.firstChildId;
428 qnode.nodeId = node.firstChildId+1;
432 query.nodeStack[count].nodeId = node.firstChildId+1;
433 qnode.nodeId = node.firstChildId;
435 query.nodeStack[count].sq = qnode.sq;
436 qnode.sq = new_off*new_off;
448 template<
typename Scalar,
typename Index>
449 unsigned int KdTree<Scalar, Index>::
split(
int start,
int end,
unsigned int dim,
Scalar splitValue)
451 int l(start), r(end-1);
452 for ( ; l<r ; ++l, --r)
454 while (l < end &&
mPoints[l][dim] < splitValue)
456 while (r >= start &&
mPoints[r][dim] >= splitValue)
463 return (
mPoints[l][dim] < splitValue ? l+1 : l);
486 template<
typename Scalar,
typename Index>
487 void KdTree<Scalar, Index>::
createTree(
unsigned int nodeId,
unsigned int start,
unsigned int end,
unsigned int level,
unsigned int targetCellSize,
unsigned int targetMaxDepth)
493 for (
unsigned int i=start ; i<end ; ++i)
496 VectorType diag = aabb.diagonal();
497 typename VectorType::
Index dim;
508 if (std::isnan(diag.maxCoeff(&dim))){
509 std::cerr <<
"NaN values discovered in the tree, abort" << std::endl;
519 node.splitValue = aabb.center()(dim);
521 unsigned int midId =
split(start
, end
, dim
, node.splitValue
);
523 node.firstChildId = mNodes.size();
536 unsigned int childId =
mNodes[nodeId].firstChildId;
538 if (midId-start <= targetCellSize || level>=targetMaxDepth)
542 child.size = midId-start;
553 unsigned int childId =
mNodes[nodeId].firstChildId+1;
555 if (end-midId <= targetCellSize || level>=targetMaxDepth)
559 child.size = end-midId;
std::vector< VectorType > PointList
Definition: kdtree.h:101
Scalar sqdist
Definition: kdtree.h:119
Scalar sq
squared distance to the next node
Definition: kdtree.h:112
unsigned int _maxDepth
Definition: kdtree.h:240
void add(const VectorDerived &p)
Add a new vertex in the KdTree.
Definition: kdtree.h:141
IndexList mIndices
Definition: kdtree.h:235
#define KD_MAX_DEPTH
Definition: kdtree.h:61
NodeList mNodes
Definition: kdtree.h:237
const PointList & _getPoints(void)
Definition: kdtree.h:124
PointList mPoints
Definition: kdtree.h:234
void finalize()
Finalize the creation of the KdTree.
Definition: kdtree.h:283
void _doQueryDistIndicesWithFunctor(RangeQuery< stackSize > &query, Functor f) const
Performs distance query and pass the internal id to a functor.
Definition: kdtree.h:397
~KdTree()
Definition: kdtree.h:299
Eigen::AlignedBox< _Scalar, 3 > AxisAlignedBoxType
Definition: kdtree.h:98
void add(Scalar *position)
Definition: kdtree.h:148
void doQueryDistIndices(RangeQuery< stackSize > &query, IndexContainer &result) const
Performs distance query and return indices.
Definition: kdtree.h:177
const AxisAlignedBoxType & aabb() const
Definition: kdtree.h:156
void doQueryDistProcessIndices(RangeQuery< stackSize > &query, Functor f) const
Performs distance query and return indices.
Definition: kdtree.h:189
#define KD_POINT_PER_CELL
Definition: kdtree.h:64
QueryNode(unsigned int id)
Definition: kdtree.h:108
void createTree(unsigned int nodeId, unsigned int start, unsigned int end, unsigned int level, unsigned int targetCellsize, unsigned int targetMaxDepth)
Recursively builds the kdtree.
Definition: kdtree.h:487
KdTree(const PointList &points, unsigned int nofPointsPerCell=KD_POINT_PER_CELL, unsigned int maxDepth=KD_MAX_DEPTH)
Create the Kd-Tree using memory copy.
Definition: kdtree.h:251
std::vector< Index > IndexList
Definition: kdtree.h:102
const NodeList & _getNodes(void)
Definition: kdtree.h:123
CongruentSetExplorationBase< Traits, PointType, TransformVisitor, PairFilteringFunctor, OptExts... >::Scalar ComputeTransformation(const InputRange1 &P, const InputRange2 &Q, Eigen::Ref< typename CongruentSetExplorationBase< Traits, PointType, TransformVisitor, PairFilteringFunctor, OptExts... >::MatrixType > transformation, const Sampler< PointType > &sampler, TransformVisitor &v)
Definition: congruentSetExplorationBase.hpp:61
_Scalar Scalar
Definition: kdtree.h:92
element of the stack
Definition: kdtree.h:105
VectorType queryPoint
Definition: kdtree.h:118
_Index Index
Definition: kdtree.h:93
KdTree(unsigned int size=0, unsigned int nofPointsPerCell=KD_POINT_PER_CELL, unsigned int maxDepth=KD_MAX_DEPTH)
Create a void KdTree.
Definition: kdtree.h:271
void doQueryDist(RangeQuery< stackSize > &query, Container &result) const
Performs distance query and return vector coordinates.
Definition: kdtree.h:165
std::vector< KdNode > NodeList
Definition: kdtree.h:100
QueryNode()
Definition: kdtree.h:107
std::pair< Index, Scalar > doQueryRestrictedClosestIndex(RangeQuery< stackSize > &query, int currentId=-1) const
Finds the closest element index within the range [0:sqrt(sqdist)].
Definition: kdtree.h:323
unsigned int split(int start, int end, unsigned int dim, Scalar splitValue)
Used to build the tree: split the subset [start..end[ according to dim and splitValue, and returns the index of the first element of the second subset.
Definition: kdtree.h:449
unsigned int nodeId
id of the next node
Definition: kdtree.h:110
AxisAlignedBoxType mAABB
Definition: kdtree.h:236
static constexpr Index invalidIndex()
Definition: kdtree.h:95
unsigned int _nofPointsPerCell
Definition: kdtree.h:239
const PointList & _getIndices(void)
Definition: kdtree.h:125
QueryNode nodeStack[_stackSize]
Definition: kdtree.h:120