Ponca  7d8ac87a7de01d881c9fde3c42e397b44bffb901
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
13{
14 template <typename Traits>
15 class StaticKdTreeBase;
16
22 template <typename Traits>
24 {
25 public:
26 using DataPoint = typename Traits::DataPoint;
27 using IndexType = typename Traits::IndexType;
28 using Scalar = typename DataPoint::Scalar;
29 using VectorType = typename DataPoint::VectorType;
30
31 PONCA_MULTIARCH explicit inline KdTreeQuery(const StaticKdTreeBase<Traits>* kdtree)
33 {
34 }
35
36 protected:
38 PONCA_MULTIARCH inline void reset()
39 {
40 m_stack.clear();
41 m_stack.push({0, 0});
42 }
43
48
51 template <typename LeafPreparationFunctor, typename DescentDistanceThresholdFunctor, typename SkipIndexFunctor,
53 PONCA_MULTIARCH bool searchInternal(const VectorType& point, LeafPreparationFunctor prepareLeafTraversal,
54 DescentDistanceThresholdFunctor descentDistanceThreshold,
56 {
57 const auto& nodes = m_kdtree->nodes();
58 const auto& points = m_kdtree->points();
59
60 if (m_kdtree->nodeCount() == 0 || m_kdtree->pointCount() == 0 || m_kdtree->sampleCount() == 0)
61 return false;
62
63 while (!m_stack.empty())
64 {
65 auto& qnode = m_stack.top();
66 const auto& node = nodes[qnode.index];
67
68 if (qnode.squared_distance < descentDistanceThreshold())
69 {
70 if (node.is_leaf())
71 {
72 m_stack.pop();
73 IndexType start = node.leaf_start();
74 IndexType end = node.leaf_start() + node.leaf_size();
75 prepareLeafTraversal(start, end);
76 for (IndexType i = start; i < end; ++i)
77 {
78 IndexType idx = m_kdtree->pointFromSample(i);
79 if (skipFunctor(idx))
80 continue;
81
82 Scalar d = (point - points[idx].pos()).squaredNorm();
83
84 if (d < descentDistanceThreshold())
85 {
87 return false;
88 }
89 }
90 }
91 else
92 {
93 // replace the stack top by the farthest and push the closest
94 Scalar newOff = point[node.inner_split_dim()] - node.inner_split_value();
95 m_stack.push();
96 if (newOff < 0)
97 {
98 m_stack.top().index = node.inner_first_child_id();
99 qnode.index = node.inner_first_child_id() + 1;
100 }
101 else
102 {
103 m_stack.top().index = node.inner_first_child_id() + 1;
104 qnode.index = node.inner_first_child_id();
105 }
106 m_stack.top().squared_distance = qnode.squared_distance;
107 qnode.squared_distance = newOff * newOff;
108 }
109 }
110 else
111 {
112 m_stack.pop();
113 }
114 }
115 return true;
116 }
117 };
118} // namespace Ponca
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:318
Query object that provides a method to search neighbors on the KdTree depending on a distance thresho...
Definition kdTreeQuery.h:24
const StaticKdTreeBase< Traits > * m_kdtree
[KdTreeQuery kdtree type]
Definition kdTreeQuery.h:45
void reset()
Init stack for a new search.
Definition kdTreeQuery.h:38
Stack< IndexSquaredDistance< IndexType, Scalar >, 2 *Traits::MAX_DEPTH > m_stack
[KdTreeQuery kdtree type]
Definition kdTreeQuery.h:47
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:53
This Source Code Form is subject to the terms of the Mozilla Public License, v.