Ponca  aa50bfdf187919869239c5b44b748842569114c1
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
15template <typename Traits>
17{
18public:
19 using DataPoint = typename Traits::DataPoint;
20 using IndexType = typename Traits::IndexType;
21 using Scalar = typename DataPoint::Scalar;
22 using VectorType = typename DataPoint::VectorType;
23
24 explicit inline KdTreeQuery(const KdTreeBase<Traits>* kdtree) : m_kdtree( kdtree ), m_stack() {}
25
26protected:
28 inline void reset() {
29 m_stack.clear();
30 m_stack.push({0,0});
31 }
32
34 const KdTreeBase<Traits>* m_kdtree { nullptr };
37
39 template<typename LeafPreparationFunctor,
40 typename DescentDistanceThresholdFunctor,
41 typename SkipIndexFunctor,
42 typename ProcessNeighborFunctor>
43 bool search_internal(const VectorType& point,
44 LeafPreparationFunctor prepareLeafTraversal,
45 DescentDistanceThresholdFunctor descentDistanceThreshold,
46 SkipIndexFunctor skipFunctor,
47 ProcessNeighborFunctor processNeighborFunctor
48 )
49 {
50 const auto& nodes = m_kdtree->nodes();
51 const auto& points = m_kdtree->points();
52
53 if (nodes.empty() || points.empty() || m_kdtree->sample_count() == 0)
54 return false;
55
56 while(!m_stack.empty())
57 {
58 auto& qnode = m_stack.top();
59 const auto& node = nodes[qnode.index];
60
61 if(qnode.squared_distance < descentDistanceThreshold())
62 {
63 if(node.is_leaf())
64 {
65 m_stack.pop();
66 IndexType start = node.leaf_start();
67 IndexType end = node.leaf_start() + node.leaf_size();
68 prepareLeafTraversal(start, end);
69 for(IndexType i=start; i<end; ++i)
70 {
71 IndexType idx = m_kdtree->pointFromSample(i);
72 if(skipFunctor(idx)) continue;
73
74 Scalar d = (point - points[idx].pos()).squaredNorm();
75
76 if(d < descentDistanceThreshold())
77 {
78 if( processNeighborFunctor( idx, i, d )) return false;
79 }
80 }
81 }
82 else
83 {
84 // replace the stack top by the farthest and push the closest
85 Scalar newOff = point[node.inner_split_dim()] - node.inner_split_value();
86 m_stack.push();
87 if(newOff < 0)
88 {
89 m_stack.top().index = node.inner_first_child_id();
90 qnode.index = node.inner_first_child_id()+1;
91 }
92 else
93 {
94 m_stack.top().index = node.inner_first_child_id()+1;
95 qnode.index = node.inner_first_child_id();
96 }
97 m_stack.top().squared_distance = qnode.squared_distance;
98 qnode.squared_distance = newOff*newOff;
99 }
100 }
101 else
102 {
103 m_stack.pop();
104 }
105 }
106 return true;
107 }
108};
109} // namespace Ponca
[KdTreeSparse type definition]
Definition: kdTree.h:104
void reset()
Init stack for a new search.
Definition: kdTreeQuery.h:28
Stack< IndexSquaredDistance< IndexType, Scalar >, 2 *Traits::MAX_DEPTH > m_stack
[KdTreeQuery kdtree type]
Definition: kdTreeQuery.h:36
bool search_internal(const VectorType &point, LeafPreparationFunctor prepareLeafTraversal, DescentDistanceThresholdFunctor descentDistanceThreshold, SkipIndexFunctor skipFunctor, ProcessNeighborFunctor processNeighborFunctor)
Definition: kdTreeQuery.h:43
const KdTreeBase< Traits > * m_kdtree
[KdTreeQuery kdtree type]
Definition: kdTreeQuery.h:34
Stack with fixed-size storage.
Definition: stack.h:25
This Source Code Form is subject to the terms of the Mozilla Public License, v.