Ponca  7df32c91629c89b89840c4d7917cb272433f2d2b
Point Cloud Analysis library
Loading...
Searching...
No Matches
knnGraph.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 "./knnGraphTraits.h"
10
11#include "Query/knnGraphKNearestQuery.h"
12#include "Query/knnGraphRangeQuery.h"
13
14#include "../KdTree/kdTree.h"
15#include "../../Common/Assert.h"
16
17#include <memory>
18
19namespace Ponca
20{
21
22 template <typename Traits>
23 class KnnGraphBase;
24
33 template <typename DataPoint>
35
47 template <typename Traits>
49 {
50 public:
51#define WRITE_TRAITS \
52 using DataPoint = typename Traits::DataPoint; \
53 using Scalar = typename DataPoint::Scalar; \
54 using VectorType = typename DataPoint::VectorType; \
55 using IndexType = typename Traits::IndexType; \
56 using PointContainer = typename Traits::PointContainer; \
57 using IndexContainer = typename Traits::IndexContainer;
58 WRITE_TRAITS
59
62 friend class KnnGraphKNearestQuery<Traits>;
64 friend class KnnGraphRangeQuery<Traits>;
67 protected:
68 PONCA_MULTIARCH inline const IndexType* getIndexPtr() const { return Traits::getIndexRawPtr(m_bufs.indices); }
69 PONCA_MULTIARCH inline IndexType* getIndexPtr() { return Traits::getIndexRawPtr(m_bufs.indices); }
70
71 public:
73 struct Buffers
74 {
77
78 size_t points_size{0};
79 size_t indices_size{0};
80 int k{0};
81
82 PONCA_MULTIARCH inline Buffers() = default;
83 PONCA_MULTIARCH inline Buffers(PointContainer _points, const int _k) : points(_points), k(_k) {}
84
85 PONCA_MULTIARCH inline Buffers(PointContainer _points, typename Traits::IndexContainerRef _indices,
86 const size_t _points_size, const size_t _indices_size, const int _k)
87 : points(_points), indices(_indices), points_size(_points_size), indices_size(_indices_size), k(_k)
88 {
89 }
90 };
91
92 protected:
93 PONCA_MULTIARCH inline StaticKnnGraphBase(PointContainer _points, const int _k) : m_bufs(_points, _k) {}
94
95 public:
105 PONCA_MULTIARCH inline StaticKnnGraphBase(Buffers& _bufs) : m_bufs(_bufs) {}
106
107 // Query -------------------------------------------------------------------
108 public:
118 PONCA_MULTIARCH inline KNearestIndexQuery kNearestNeighbors(int index) const
119 {
120 return KNearestIndexQuery(this, index);
121 }
122
131 PONCA_MULTIARCH inline RangeIndexQuery rangeNeighbors(int index, Scalar r) const
132 {
133 return RangeIndexQuery(this, r, index);
134 }
135
148 PONCA_MULTIARCH inline KNearestIndexQuery kNearestNeighborsIndexQuery() const
149 {
150 return KNearestIndexQuery(this, 0);
151 }
152
162 PONCA_MULTIARCH inline RangeIndexQuery rangeNeighborsIndexQuery() const { return RangeIndexQuery(this, 0, 0); }
163
164 // Accessors ---------------------------------------------------------------
165 public:
167 PONCA_MULTIARCH [[nodiscard]] inline int k() const { return m_bufs.k; }
169 PONCA_MULTIARCH [[nodiscard]] inline size_t size() const
170 {
171 return m_bufs.indices_size / static_cast<size_t>(m_bufs.k);
172 }
174 PONCA_MULTIARCH [[nodiscard]] inline IndexType sampleCount() const { return (IndexType)m_bufs.indices_size; }
176 PONCA_MULTIARCH [[nodiscard]] inline IndexType pointCount() const { return (IndexType)m_bufs.points_size; }
178 PONCA_MULTIARCH [[nodiscard]] inline PointContainer points() const { return m_bufs.points; };
180 PONCA_MULTIARCH [[nodiscard]] inline IndexContainer samples() const { return m_bufs.indices; };
182 PONCA_MULTIARCH [[nodiscard]] inline const Buffers& buffers() const { return m_bufs; }
183
184 // Data --------------------------------------------------------------------
185 protected: // for friends relations
187 };
188
189 template <typename Traits>
190 class KnnGraphBase : public StaticKnnGraphBase<Traits>
191 {
192 public:
193 WRITE_TRAITS
194 private:
196 using Buffers = typename StaticKnnGraphBase<Traits>::Buffers;
197 // knnGraph ----------------------------------------------------------------
198 public:
207 template <typename KdTreeTraits>
208 PONCA_MULTIARCH_HOST inline KnnGraphBase(const KdTreeBase<KdTreeTraits>& _kdtree, const int _k = 6)
209 : Base(_kdtree.points(), std::min(_k, _kdtree.sampleCount() - 1))
210 {
211 Base::m_bufs.points_size = _kdtree.pointCount();
212#define CHECK_TRAITS_TYPENAME_COMPAT(A, B) \
213 static_assert(std::is_same_v<A, B> || std::is_convertible_v<A, B> || std::is_convertible_v<B, A>, \
214 "KdTreeTraits::DataPoint is not equal to Traits::DataPoint");
215
216 static_assert(std::is_same_v<typename Traits::DataPoint, typename KdTreeTraits::DataPoint>,
217 "KdTreeTraits::DataPoint is not equal to Traits::DataPoint");
218
219 CHECK_TRAITS_TYPENAME_COMPAT(typename Traits::PointContainer, typename KdTreeTraits::PointContainer)
220 CHECK_TRAITS_TYPENAME_COMPAT(typename Traits::IndexContainer, typename KdTreeTraits::IndexContainer)
221
222#undef CHECK_TRAITS_TYPENAME_COMPAT
223
224 // We need to account for the entire point set, irrespectively of the sampling. This is because the kdtree
225 // (kNearestNeighbors) return ids of the entire point set, not it sub-sampled list of ids.
226 // \fixme Update API to properly handle kdtree subsampling
227 const int cloudSize = _kdtree.pointCount();
228 {
229 const int samplesSize = _kdtree.sampleCount();
230 PONCA_ASSERT(cloudSize == samplesSize);
231 }
232
233 Base::m_bufs.indices_size = cloudSize * Base::m_bufs.k;
234 Base::m_bufs.indices.resize(Base::m_bufs.indices_size, -1);
235
236#pragma omp parallel for shared(_kdtree, cloudSize) default(none)
237 for (int i = 0; i < cloudSize; ++i)
238 {
239 int j = 0;
240 for (auto n : _kdtree.kNearestNeighbors(typename KdTreeTraits::IndexType(i),
241 typename KdTreeTraits::IndexType(Base::m_bufs.k)))
242 {
243 Base::m_bufs.indices[i * Base::m_bufs.k + j] = n;
244 ++j;
245 }
246 }
247 }
248 };
249
250} // namespace Ponca
251
252#undef WRITE_TRAITS
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:257
KnnGraphBase(const KdTreeBase< KdTreeTraits > &_kdtree, const int _k=6)
Build a KnnGraph from a KdTreeDense.
Definition knnGraph.h:208
Extension of the Query class that allows to read the result of a k-nearest neighbors search on the Kn...
Extension of the Query class that allows to read the result of a range neighbor search on the KnnGrap...
Customizable base class for KnnGraph datastructure.
Definition knnGraph.h:49
StaticKnnGraphBase(Buffers &_bufs)
Constructor that allows the use of prebuilt KnnGraph containers.
Definition knnGraph.h:105
typename Traits::IndexContainer IndexContainer
Container for indices used inside the KdTree
Definition knnGraph.h:58
KNearestIndexQuery kNearestNeighborsIndexQuery() const
Convenience function that provides a k-nearest neighbors Query object.
Definition knnGraph.h:148
IndexContainer samples() const
Get the internal index container.
Definition knnGraph.h:180
typename DataPoint::Scalar Scalar
Scalar given by user via DataPoint
Definition knnGraph.h:58
size_t size() const
Number of vertices in the neighborhood graph.
Definition knnGraph.h:169
RangeIndexQuery rangeNeighborsIndexQuery() const
Convenience function that provides an empty range neighbors Query object.
Definition knnGraph.h:162
IndexType sampleCount() const
Get the number of indices.
Definition knnGraph.h:174
typename Traits::PointContainer PointContainer
Container for DataPoint used inside the KdTree
Definition knnGraph.h:58
typename Traits::IndexType IndexType
Type used to index points into the PointContainer.
Definition knnGraph.h:58
KNearestIndexQuery kNearestNeighbors(int index) const
Computes a Query object to iterate over the k-nearest neighbors of a point.
Definition knnGraph.h:118
const Buffers & buffers() const
Get access to the internal buffer, for instance to prepare GPU binding.
Definition knnGraph.h:182
RangeIndexQuery rangeNeighbors(int index, Scalar r) const
Computes a Query object to iterate over the neighbors that are inside a given radius.
Definition knnGraph.h:131
Buffers m_bufs
Buffers used to store the KnnGraph.
Definition knnGraph.h:186
PointContainer points() const
Get the internal point container.
Definition knnGraph.h:178
IndexType pointCount() const
Get the number of points.
Definition knnGraph.h:176
int k() const
Number of neighbor per vertex.
Definition knnGraph.h:167
This Source Code Form is subject to the terms of the Mozilla Public License, v.
Definition bitset.h:17
Internal structure storing all the buffers used by the KdTree.
Definition knnGraph.h:74
PointContainer points
Buffer storing the input points (read only)
Definition knnGraph.h:75
IndexContainer indices
Buffer storing the indices associating the input points to the nodes.
Definition knnGraph.h:76