Ponca  7d8ac87a7de01d881c9fde3c42e397b44bffb901
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
17{
18 template <typename Traits>
19 class KnnGraphBase;
20
28 template <typename Traits>
29 class KnnGraphRangeQuery : public RangeIndexQuery<typename Traits::IndexType, typename Traits::DataPoint::Scalar>
30 {
31 protected:
33 friend class KnnGraphRangeIterator<Traits>; // This type must be equal to KnnGraphRangeQuery::Iterator
34
35 public:
36 using DataPoint = typename Traits::DataPoint;
37 using IndexType = typename Traits::IndexType;
38 using Scalar = typename DataPoint::Scalar;
39 using VectorType = typename DataPoint::VectorType;
42
43 public:
44 inline KnnGraphRangeQuery(const KnnGraphBase<Traits>* graph, Scalar radius, int index)
45 : QueryType(radius, index), m_graph(graph), m_flag(), m_stack()
46 {
47 }
48
50 inline Self& operator()(int index, Scalar radius)
51 {
52 return QueryType::template operator()<Self>(index, radius);
53 }
54
56 inline Self& operator()(int index) { return QueryType::template operator()<Self>(index); }
57
59 inline Iterator begin()
60 {
61 QueryType::reset();
62 Iterator it(this);
63 this->initialize(it);
64 this->advance(it);
65 return it;
66 }
67
69 inline Iterator end() { return Iterator(this, static_cast<int>(m_graph->size())); }
70
71 protected:
72 inline void initialize(Iterator& iterator)
73 {
74 m_flag.clear();
75 m_flag.insert(QueryType::input());
76
77 PONCA_DEBUG_ASSERT(m_stack.empty());
78 m_stack.push(QueryType::input());
79
80 iterator.m_index = -1;
81 }
82
83 inline void advance(Iterator& iterator)
84 {
85 const auto& points = m_graph->m_kdTreePoints;
86 const auto& point = points[QueryType::input()].pos();
87
88 if (!(iterator != end()))
89 return;
90
91 if (m_stack.empty())
92 {
93 iterator = end();
94 }
95 else
96 {
97 int idx_current = m_stack.top();
98 m_stack.pop();
99
100 PONCA_DEBUG_ASSERT((point - points[idx_current].pos()).squaredNorm() < QueryType::squaredRadius());
101
102 iterator.m_index = idx_current;
103
104 for (int idx_nei : m_graph->kNearestNeighbors(idx_current))
105 {
106 PONCA_DEBUG_ASSERT(idx_nei >= 0);
107 Scalar d = (point - points[idx_nei].pos()).squaredNorm();
108 Scalar th = QueryType::descentDistanceThreshold();
109 if ((point - points[idx_nei].pos()).squaredNorm() < QueryType::descentDistanceThreshold() &&
110 m_flag.insert(idx_nei).second)
111 {
112 m_stack.push(idx_nei);
113 }
114 }
115 if (iterator.m_index == QueryType::input())
116 advance(iterator); // query is not included in returned set
117 }
118 }
119
120 protected:
121 const KnnGraphBase<Traits>* m_graph{nullptr};
122 std::set<int> m_flag;
123 std::stack<int> m_stack;
124 };
125
126} // namespace Ponca
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:318
Input iterator to read the KnnGraphRangeQuery object.
Extension of the Query class that allows to read the result of a range neighbor search on the KnnGrap...
Self & operator()(int index, Scalar radius)
Call the range neighbors query with new input and radius parameters.
Iterator begin()
Returns an iterator to the beginning of the range neighbors query.
Self & operator()(int index)
Call the range neighbors query with new input parameter.
std::stack< int > m_stack
hold ids (ids range from 0 to point cloud size)
std::set< int > m_flag
store visited ids
Iterator end()
Returns an iterator to the end of the range neighbors query.
Base Query class combining QueryInputIsIndex and QueryOutputIsRange.
Definition query.h:375
This Source Code Form is subject to the terms of the Mozilla Public License, v.