Ponca  aa50bfdf187919869239c5b44b748842569114c1
Point Cloud Analysis library
Loading...
Searching...
No Matches
knnGraphRangeQuery.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 "../../query.h"
10#include "../Iterator/knnGraphRangeIterator.h"
11
12#include <vector>
13#include <stack>
14#include <set>
15
16namespace Ponca {
17template <typename Traits> class KnnGraphBase;
18
19template <typename Traits>
20class KnnGraphRangeQuery : public RangeIndexQuery<typename Traits::IndexType, typename Traits::DataPoint::Scalar>
21{
22protected:
24 friend class KnnGraphRangeIterator<Traits>; // This type must be equal to KnnGraphRangeQuery::Iterator
25
26public:
27 using DataPoint = typename Traits::DataPoint;
28 using IndexType = typename Traits::IndexType;
29 using Scalar = typename DataPoint::Scalar;
30 using VectorType = typename DataPoint::VectorType;
32
33public:
34 inline KnnGraphRangeQuery(const KnnGraphBase<Traits>* graph, Scalar radius, int index):
35 QueryType(radius, index),
36 m_graph(graph),
37 m_flag(),
38 m_stack() {}
39
40public:
41 inline Iterator begin(){
42 Iterator it(this);
43 this->initialize(it);
44 this->advance(it);
45 return it;
46 }
47
48 inline Iterator end(){
49 return Iterator(this, m_graph->size());
50 }
51
52protected:
53 inline void initialize(Iterator& iterator){
54 m_flag.clear();
55 m_flag.insert(QueryType::input());
56
57 PONCA_DEBUG_ASSERT(m_stack.empty());
58 m_stack.push(QueryType::input());
59
60 iterator.m_index = -1;
61 }
62
63 inline void advance(Iterator& iterator){
64 const auto& points = m_graph->m_kdTreePoints;
65 const auto& point = points[QueryType::input()].pos();
66
67 if(! (iterator != end())) return;
68
69 if(m_stack.empty())
70 {
71 iterator = end();
72 }
73 else
74 {
75 int idx_current = m_stack.top();
76 m_stack.pop();
77
78 PONCA_DEBUG_ASSERT((point - points[idx_current].pos()).squaredNorm() < QueryType::squared_radius());
79
80 iterator.m_index = idx_current;
81
82 for(int idx_nei : m_graph->k_nearest_neighbors(idx_current))
83 {
84 PONCA_DEBUG_ASSERT(idx_nei>=0);
85 Scalar d = (point - points[idx_nei].pos()).squaredNorm();
87 if((point - points[idx_nei].pos()).squaredNorm() < QueryType::descentDistanceThreshold() && m_flag.insert(idx_nei).second)
88 {
89 m_stack.push(idx_nei);
90 }
91 }
92 if (iterator.m_index == QueryType::input()) advance(iterator); // query is not included in returned set
93 }
94 }
95
96protected:
97 const KnnGraphBase<Traits>* m_graph {nullptr};
98 std::set<int> m_flag;
99 std::stack<int> m_stack;
100};
101
102} // namespace Ponca
Customizable base class for KnnGraph datastructure.
Definition: knnGraph.h:45
std::stack< int > m_stack
hold ids (ids range from 0 to point cloud size)
std::set< int > m_flag
store visited ids
Scalar descentDistanceThreshold() const
Distance threshold used during tree descent to select nodes to explore.
Definition: query.h:138
Base Query class combining QueryInputIsIndex and QueryOutputIsRange.
Definition: query.h:205
This Source Code Form is subject to the terms of the Mozilla Public License, v.