47 #ifndef _SUPER4PCS_ACCELERATORS_KDTREE_H 48 #define _SUPER4PCS_ACCELERATORS_KDTREE_H 50 #include "super4pcs/utils/disablewarnings.h" 51 #include "super4pcs/accelerators/bbox.h" 60 #define KD_MAX_DEPTH 32 63 #define KD_POINT_PER_CELL 64 140 template<
typename _Scalar,
typename _Index =
int >
183 template <
int _stackSize = 64>
191 inline const NodeList&
_getNodes (
void) {
return mNodes; }
192 inline const PointList&
_getPoints (
void) {
return mPoints; }
198 KdTree(
const PointList& points,
199 unsigned int nofPointsPerCell = KD_POINT_PER_CELL,
200 unsigned int maxDepth = KD_MAX_DEPTH );
204 unsigned int nofPointsPerCell = KD_POINT_PER_CELL,
205 unsigned int maxDepth = KD_MAX_DEPTH );
208 template <
class VectorDerived>
209 inline void add(
const VectorDerived &p ){
211 mPoints.push_back(p);
212 mIndices.push_back(mIndices.size());
216 inline void add(Scalar *position){
217 add(Eigen::Map< Eigen::Matrix<Scalar, 3, 1> >(position));
224 inline const AxisAlignedBoxType&
aabb()
const {
return mAABB; }
231 template<
int stackSize,
typename Container = std::vector<VectorType> >
234 Container& result)
const {
235 _doQueryDistIndicesWithFunctor(query, [&result,
this](
unsigned int i){
236 result.push_back(mPoints[i]);
243 template<
int stackSize,
typename IndexContainer = std::vector<Index> >
246 IndexContainer& result)
const {
247 _doQueryDistIndicesWithFunctor(query, [&result,
this](
unsigned int i){
248 result.push_back(mIndices[i]);
255 template<
int stackSize,
typename Functor>
259 _doQueryDistIndicesWithFunctor(query, [f,
this](
unsigned int i){
268 template<
int stackSize>
271 int currentId = -1)
const;
273 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
285 void createTree(
unsigned int nodeId,
289 unsigned int targetCellsize,
290 unsigned int targetMaxDepth);
296 template<
int stackSize,
typename Functor >
298 _doQueryDistIndicesWithFunctor(RangeQuery<stackSize>& query,
304 AxisAlignedBoxType mAABB;
307 unsigned int _nofPointsPerCell;
308 unsigned int _maxDepth;
318 template<
typename Scalar,
typename Index>
320 unsigned int nofPointsPerCell,
321 unsigned int maxDepth)
323 mIndices(points.
size()),
324 _nofPointsPerCell(nofPointsPerCell),
327 mAABB.extend(points.cbegin(), points.cend());
328 std::iota (mIndices.begin(), mIndices.end(), 0);
338 template<
typename Scalar,
typename Index>
340 unsigned int nofPointsPerCell,
341 unsigned int maxDepth)
342 : _nofPointsPerCell(nofPointsPerCell),
345 mPoints.reserve(size);
346 mIndices.reserve(size);
349 template<
typename Scalar,
typename Index>
354 mNodes.reserve(4*mPoints.size()/_nofPointsPerCell);
355 mNodes.emplace_back();
356 mNodes.back().leaf = 0;
358 std::cout <<
"create tree" << std::endl;
360 createTree(0, 0, mPoints.size(), 1, _nofPointsPerCell, _maxDepth);
362 std::cout <<
"create tree ... DONE (" << mPoints.size() <<
" points)" << std::endl;
366 template<
typename Scalar,
typename Index>
388 template<
typename Scalar,
typename Index>
389 template<
int stackSize>
392 RangeQuery<stackSize>& query,
396 Index cl_id = invalidIndex();
397 Scalar cl_dist = query.sqdist;
399 query.nodeStack[0].nodeId = 0;
400 query.nodeStack[0].sq = 0.f;
401 unsigned int count = 1;
407 QueryNode& qnode = query.nodeStack[count-1];
408 const KdNode& node = mNodes[qnode.nodeId];
410 if (qnode.sq < cl_dist)
415 const int end = node.start+node.size;
416 for (
int i=node.start ; i<end ; ++i){
417 const Scalar sqdist = (query.queryPoint - mPoints[i]).squaredNorm();
418 if (sqdist <= cl_dist && mIndices[i] != currentId){
427 const Scalar new_off = query.queryPoint[node.dim] - node.splitValue;
433 query.nodeStack[count].nodeId = node.firstChildId;
434 qnode.nodeId = node.firstChildId+1;
438 query.nodeStack[count].nodeId = node.firstChildId+1;
439 qnode.nodeId = node.firstChildId;
441 query.nodeStack[count].sq = qnode.sq;
442 qnode.sq = new_off*new_off;
462 template<
typename Scalar,
typename Index>
463 template<
int stackSize,
typename Functor >
466 RangeQuery<stackSize>& query,
469 query.nodeStack[0].nodeId = 0;
470 query.nodeStack[0].sq = 0.f;
471 unsigned int count = 1;
475 QueryNode& qnode = query.nodeStack[count-1];
476 const KdNode & node = mNodes[qnode.nodeId];
478 if (qnode.sq < query.sqdist)
483 unsigned int end = node.start+node.size;
484 for (
unsigned int i=node.start ; i<end ; ++i)
485 if ( (query.queryPoint - mPoints[i]).squaredNorm() < query.sqdist){
492 Scalar new_off = query.queryPoint[node.dim] - node.splitValue;
495 query.nodeStack[count].nodeId = node.firstChildId;
496 qnode.nodeId = node.firstChildId+1;
500 query.nodeStack[count].nodeId = node.firstChildId+1;
501 qnode.nodeId = node.firstChildId;
503 query.nodeStack[count].sq = qnode.sq;
504 qnode.sq = new_off*new_off;
516 template<
typename Scalar,
typename Index>
519 int l(start), r(end-1);
520 for ( ; l<r ; ++l, --r)
522 while (l < end && mPoints[l][dim] < splitValue)
524 while (r >= start && mPoints[r][dim] >= splitValue)
528 std::swap(mPoints[l],mPoints[r]);
529 std::swap(mIndices[l],mIndices[r]);
531 return (mPoints[l][dim] < splitValue ? l+1 : l);
554 template<
typename Scalar,
typename Index>
555 void KdTree<Scalar, Index>::createTree(
unsigned int nodeId,
unsigned int start,
unsigned int end,
unsigned int level,
unsigned int targetCellSize,
unsigned int targetMaxDepth)
558 KdNode& node = mNodes[nodeId];
561 for (
unsigned int i=start ; i<end ; ++i)
565 typename VectorType::Index dim;
576 if (std::isnan(diag.maxCoeff(&dim))){
577 std::cerr <<
"NaN values discovered in the tree, abort" << std::endl;
587 node.splitValue = aabb.center()(dim);
589 unsigned int midId = split(start, end, dim, node.splitValue);
591 node.firstChildId = mNodes.size();
604 unsigned int childId = mNodes[nodeId].firstChildId;
605 KdNode& child = mNodes[childId];
606 if (midId-start <= targetCellSize || level>=targetMaxDepth)
610 child.size = midId-start;
615 createTree(childId, start, midId, level+1, targetCellSize, targetMaxDepth);
621 unsigned int childId = mNodes[nodeId].firstChildId+1;
622 KdNode& child = mNodes[childId];
623 if (end-midId <= targetCellSize || level>=targetMaxDepth)
627 child.size = end-midId;
632 createTree(childId, midId, end, level+1, targetCellSize, targetMaxDepth);
std::vector< KdNode > NodeList
Definition: kdtree.h:168
const PointList & _getIndices(void)
Definition: kdtree.h:193
unsigned int firstChildId
Definition: kdtree.h:149
std::vector< VectorType > PointList
Definition: kdtree.h:169
Index doQueryRestrictedClosestIndex(RangeQuery< stackSize > &query, int currentId=-1) const
Finds the closest element index within the range [0:sqrt(sqdist)].
Definition: kdtree.h:391
Eigen::Matrix< Scalar, 3, 1 > VectorType
Definition: kdtree.h:165
Scalar sq
squared distance to the next node
Definition: kdtree.h:180
void doQueryDistProcessIndices(RangeQuery< stackSize > &query, Functor f) const
Performs distance query and return indices.
Definition: kdtree.h:257
void finalize()
Finalize the creation of the KdTree.
Definition: kdtree.h:351
const PointList & _getPoints(void)
Definition: kdtree.h:192
void extend(InputIt first, InputIt last)
Definition: bbox.h:75
void add(Scalar *position)
Definition: kdtree.h:216
std::vector< Index > IndexList
Definition: kdtree.h:170
unsigned int dim
Definition: kdtree.h:150
unsigned int start
Definition: kdtree.h:154
Scalar sqdist
Definition: kdtree.h:187
const AxisAlignedBoxType & aabb() const
Definition: kdtree.h:224
const NodeList & _getNodes(void)
Definition: kdtree.h:191
VectorType queryPoint
Definition: kdtree.h:186
element of the stack
Definition: kdtree.h:173
static constexpr Index invalidIndex()
Definition: kdtree.h:163
QueryNode()
Definition: kdtree.h:175
void add(const VectorDerived &p)
Add a new vertex in the KdTree.
Definition: kdtree.h:209
float splitValue
Definition: kdtree.h:148
void doQueryDist(RangeQuery< stackSize > &query, Container &result) const
Performs distance query and return vector coordinates.
Definition: kdtree.h:233
AABB3D< Scalar > AxisAlignedBoxType
Definition: kdtree.h:166
unsigned short size
Definition: kdtree.h:155
unsigned int leaf
Definition: kdtree.h:151
~KdTree()
Definition: kdtree.h:367
_Scalar Scalar
Definition: kdtree.h:160
void doQueryDistIndices(RangeQuery< stackSize > &query, IndexContainer &result) const
Performs distance query and return indices.
Definition: kdtree.h:245
_Index Index
Definition: kdtree.h:161
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:319
unsigned int nodeId
id of the next node
Definition: kdtree.h:178
QueryNode(unsigned int id)
Definition: kdtree.h:176