Ponca  84886bac0b52a686e88046a375da13f12f2b87d2
Point Cloud Analysis library
Loading...
Searching...
No Matches
kdTreeQuery.h
1/*
2 This Source Code Form is subject to the terms of the Mozilla Public
3 License, v. 2.0. If a copy of the MPL was not distributed with this
4 file, You can obtain one at http://mozilla.org/MPL/2.0/.
5*/
6
7#pragma once
8
9#include "../../indexSquaredDistance.h"
10#include "../../../Common/Containers/stack.h"
11
12namespace Ponca {
13template <typename Traits> class KdTreeBase;
14
20template <typename Traits>
22{
23public:
24 using DataPoint = typename Traits::DataPoint;
25 using IndexType = typename Traits::IndexType;
26 using Scalar = typename DataPoint::Scalar;
27 using VectorType = typename DataPoint::VectorType;
28
29 explicit inline KdTreeQuery(const KdTreeBase<Traits>* kdtree) : m_kdtree( kdtree ), m_stack() {}
30
31protected:
33 inline void reset() {
34 m_stack.clear();
35 m_stack.push({0,0});
36 }
37
39 const KdTreeBase<Traits>* m_kdtree { nullptr };
42
45 template<typename LeafPreparationFunctor,
46 typename DescentDistanceThresholdFunctor,
47 typename SkipIndexFunctor,
48 typename ProcessNeighborFunctor>
49 bool searchInternal(const VectorType& point,
50 LeafPreparationFunctor prepareLeafTraversal,
51 DescentDistanceThresholdFunctor descentDistanceThreshold,
52 SkipIndexFunctor skipFunctor,
53 ProcessNeighborFunctor processNeighborFunctor
54 )
55 {
56 const auto& nodes = m_kdtree->nodes();
57 const auto& points = m_kdtree->points();
58
59 if (nodes.empty() || points.empty() || m_kdtree->sample_count() == 0)
60 return false;
61
62 while(!m_stack.empty())
63 {
64 auto& qnode = m_stack.top();
65 const auto& node = nodes[qnode.index];
66
67 if(qnode.squared_distance < descentDistanceThreshold())
68 {
69 if(node.is_leaf())
70 {
71 m_stack.pop();
72 IndexType start = node.leaf_start();
73 IndexType end = node.leaf_start() + node.leaf_size();
74 prepareLeafTraversal(start, end);
75 for(IndexType i=start; i<end; ++i)
76 {
77 IndexType idx = m_kdtree->pointFromSample(i);
78 if(skipFunctor(idx)) continue;
79
80 Scalar d = (point - points[idx].pos()).squaredNorm();
81
82 if(d < descentDistanceThreshold())
83 {
84 if( processNeighborFunctor( idx, i, d )) return false;
85 }
86 }
87 }
88 else
89 {
90 // replace the stack top by the farthest and push the closest
91 Scalar newOff = point[node.inner_split_dim()] - node.inner_split_value();
92 m_stack.push();
93 if(newOff < 0)
94 {
95 m_stack.top().index = node.inner_first_child_id();
96 qnode.index = node.inner_first_child_id()+1;
97 }
98 else
99 {
100 m_stack.top().index = node.inner_first_child_id()+1;
101 qnode.index = node.inner_first_child_id();
102 }
103 m_stack.top().squared_distance = qnode.squared_distance;
104 qnode.squared_distance = newOff*newOff;
105 }
106 }
107 else
108 {
109 m_stack.pop();
110 }
111 }
112 return true;
113 }
114};
115} // namespace Ponca
[KdTreeSparse type definition]
Definition kdTree.h:104
Query object that provides a method to search neighbors on the KdTree depending on a distance thresho...
Definition kdTreeQuery.h:22
void reset()
Init stack for a new search.
Definition kdTreeQuery.h:33
Stack< IndexSquaredDistance< IndexType, Scalar >, 2 *Traits::MAX_DEPTH > m_stack
[KdTreeQuery kdtree type]
Definition kdTreeQuery.h:41
bool searchInternal(const VectorType &point, LeafPreparationFunctor prepareLeafTraversal, DescentDistanceThresholdFunctor descentDistanceThreshold, SkipIndexFunctor skipFunctor, ProcessNeighborFunctor processNeighborFunctor)
Search internally the neighbors of a point using the kdtree.
Definition kdTreeQuery.h:49
const KdTreeBase< Traits > * m_kdtree
[KdTreeQuery kdtree type]
Definition kdTreeQuery.h:39
Stack with fixed-size storage.
Definition stack.h:25
This Source Code Form is subject to the terms of the Mozilla Public License, v.