Ponca  82fc77e8c6294111c6f00670e92ec58a24e2ecf2
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 "abstractNeighborGraph.h"
10#include "Query/neighborGraphOneConnectedQuery.h"
11#include "Query/neighborGraphRangeQuery.h"
12
13#include "../KdTree/kdTree.h"
14#include "../../Common/Assert.h"
15
16namespace Ponca
17{
18
22 template <typename _Traits>
24 {
25 WRITE_NEIGHBOR_GRAPH_ALIASES
27
29 static constexpr int DefaultKInKnnGraph() { return 6; }
30
32 const int k{DefaultKInKnnGraph()};
33
34 PONCA_MULTIARCH inline KnnGraphBuffers() = default;
35 PONCA_MULTIARCH inline KnnGraphBuffers(PointContainerConstRef _points, const int _k = DefaultKInKnnGraph())
36 : Base(_points), k(_k)
37 {
38 }
39 PONCA_MULTIARCH inline KnnGraphBuffers(PointContainerConstRef _points, IndexContainerRef _indices,
40 const size_t _points_size, const size_t _indices_size, const int _k)
41 : Base(_points, _indices, _points_size, _indices_size), k(_k)
42 {
43 }
44 };
45
57 template <typename _Traits>
58 class StaticKnnGraphBase : public AbstractNeighborGraph<_Traits, KnnGraphBuffers,
59 NeighborGraphOneConnectedQuery<StaticKnnGraphBase<_Traits>>,
60 NeighborGraphRangeQuery<StaticKnnGraphBase<_Traits>>>
61 {
62 public:
63 WRITE_NEIGHBOR_GRAPH_ALIASES
64
68 friend class NeighborGraphRangeQuery<StaticKnnGraphBase<_Traits>>;
70 using Base =
73 using Buffers = typename Base::Buffers;
74
75 PONCA_MULTIARCH inline StaticKnnGraphBase<Traits>(Buffers& _bufs) : Base(_bufs) {}
76
77 protected:
78 PONCA_MULTIARCH inline StaticKnnGraphBase(PointContainerConstRef _points, const int _k)
79 : Base(Buffers(_points, _k))
80 {
81 }
82
83 // Accessors ---------------------------------------------------------------
84 public:
87 PONCA_MULTIARCH [[nodiscard]] inline int k(int /*index*/ = 0) const { return Base::buffers().k; }
89 PONCA_MULTIARCH [[nodiscard]] inline int beginId(int vId) const { return vId * k(); }
91 PONCA_MULTIARCH [[nodiscard]] inline int endId(int vId) const { return (vId + 1) * k(); }
92
95 PONCA_MULTIARCH [[nodiscard]] inline typename Base::OneConnectedIndexQuery kNearestNeighbors(int index) const
96 {
97 return Base::oneConnectedNeighbors(index);
98 }
99
102 PONCA_MULTIARCH [[nodiscard]] inline typename Base::OneConnectedIndexQuery kNearestNeighborsIndexQuery() const
103 {
105 }
106 };
107
108 template <typename _Traits>
109 class KnnGraphBase : public StaticKnnGraphBase<_Traits>
110 {
111 public:
112 WRITE_NEIGHBOR_GRAPH_ALIASES
113
114 private:
116 using Buffers = typename Base::Buffers;
117 // knnGraph ----------------------------------------------------------------
118 public:
127 template <typename KdTreeTraits>
128 PONCA_MULTIARCH_HOST inline KnnGraphBase(const KdTreeBase<KdTreeTraits>& _kdtree,
129 const int _k = Buffers::DefaultKInKnnGraph())
130 : Base(_kdtree.points(), std::min(_k, _kdtree.sampleCount() - 1))
131 {
133#define CHECK_TRAITS_TYPENAME_COMPAT(A, B) \
134 static_assert(std::is_same_v<A, B> || std::is_convertible_v<A, B> || std::is_convertible_v<B, A>, \
135 "KdTreeTraits::DataPoint is not equal to Traits::DataPoint");
136
137 static_assert(std::is_same_v<typename Traits::DataPoint, typename KdTreeTraits::DataPoint>,
138 "KdTreeTraits::DataPoint is not equal to Traits::DataPoint");
139
140 CHECK_TRAITS_TYPENAME_COMPAT(typename Traits::PointContainer, typename KdTreeTraits::PointContainer)
141 CHECK_TRAITS_TYPENAME_COMPAT(typename Traits::IndexContainer, typename KdTreeTraits::IndexContainer)
142
143#undef CHECK_TRAITS_TYPENAME_COMPAT
144
145 // We need to account for the entire point set, irrespectively of the sampling. This is because the kdtree
146 // (kNearestNeighbors) return ids of the entire point set, not it sub-sampled list of ids.
147 // \fixme Update API to properly handle kdtree subsampling
148 const int cloudSize = _kdtree.pointCount();
149 {
150 const int samplesSize = _kdtree.sampleCount();
151 PONCA_ASSERT(cloudSize == samplesSize);
152 }
153
155 Base::m_bufs.indices.resize(Base::m_bufs.indices_size, -1);
156
157#pragma omp parallel for shared(_kdtree, cloudSize) default(none)
158 for (int i = 0; i < cloudSize; ++i)
159 {
160 int j = 0;
161 for (auto n : _kdtree.kNearestNeighbors(typename KdTreeTraits::IndexType(i),
162 typename KdTreeTraits::IndexType(Base::m_bufs.k)))
163 {
164 Base::m_bufs.indices[i * Base::m_bufs.k + j] = n;
165 ++j;
166 }
167 }
168 }
169 };
170
179 template <typename DataPoint>
181
182} // namespace Ponca
183
184#undef WRITE_TRAITS
Base class for neighbor graphs.
OneConnectedIndexQuery oneConnectedNeighbors(int index=0) const
Provides a Query object to iterate over the vertices that are directly connected to the query point.
const Buffers & buffers() const
Get access to the internal buffer, for instance to prepare GPU binding.
KnnGraphBase(const KdTreeBase< KdTreeTraits > &_kdtree, const int _k=Buffers::DefaultKInKnnGraph())
Build a KnnGraph from a KdTreeDense.
Definition knnGraph.h:128
Extension of the Query class that allows to read the neighbors that are directly connected to the que...
Extension of the Query class that allows to read the result of a range neighbor search on the KnnGrap...
IndexType pointCount() const
Get the number of points.
Definition kdTree.h:219
KdTreeKNearestPointQuery< Traits > kNearestNeighbors(const VectorType &point, IndexType k) const
Computes a Query object to iterate over the k-nearest neighbors of a point. The returned object can b...
Definition kdTree.h:284
IndexType sampleCount() const
Get the number of indices.
Definition kdTree.h:216
Customizable base class for KnnGraph datastructure.
Definition knnGraph.h:61
typename Traits::PointContainerConstRef PointContainerConstRef
Container for DataPoint used inside the KdTree
Definition knnGraph.h:63
int beginId(int vId) const
Index of the beginning of the neighborhood range.
Definition knnGraph.h:89
typename Traits::IndexContainerRef IndexContainerRef
Ref type to index container.
Definition knnGraph.h:63
int endId(int vId) const
Index of the end of the neighborhood range.
Definition knnGraph.h:91
_Traits Traits
Alias to the Traits type
Definition knnGraph.h:63
int k(int=0) const
Number of neighbor per vertex for a given element (in the KnnGraph, all points have the same number o...
Definition knnGraph.h:87
Base::OneConnectedIndexQuery kNearestNeighborsIndexQuery() const
Convenience function that provides an empty k-nearest neighbors Query object.
Definition knnGraph.h:102
Base::OneConnectedIndexQuery kNearestNeighbors(int index) const
Convenience function that provides an empty k-nearest neighbors Query object.
Definition knnGraph.h:95
This Source Code Form is subject to the terms of the Mozilla Public License, v.
Definition concepts.h:11
Buffer class for StaticKnnGraphBase.
Definition knnGraph.h:24
typename Traits::PointContainerConstRef PointContainerConstRef
Container for DataPoint used inside the KdTree
Definition knnGraph.h:25
static constexpr int DefaultKInKnnGraph()
Helper constexpr defining the default number of neighbors in Knn graphs.
Definition knnGraph.h:29
const int k
Number of neighbors used to build the graph.
Definition knnGraph.h:32
Internal structure storing the buffers used by a neighbor graph.
size_t points_size
Number of points in the graph.
size_t indices_size
Number of connections in the graph.
IndexContainer indices
Buffer storing the indices associating the input points to the nodes.