EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
EBGeometry_PointCloud.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Robert Marskar <robert.marskar@sintef.no>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
11#ifndef EBGEOMETRY_POINTCLOUD_HPP
12#define EBGEOMETRY_POINTCLOUD_HPP
13
14// Std includes
15#include <cstddef>
16#include <cstdint>
17#include <vector>
18
19// Our includes
20#include "EBGeometry_GPU.hpp"
21#include "EBGeometry_Macros.hpp"
22#include "EBGeometry_Math.hpp"
23#include "EBGeometry_Vec.hpp"
24
25namespace EBGeometry {
26
34namespace PointCloud {
35
41inline constexpr uint32_t InvalidIndex = Math::Limits<uint32_t>::max();
42
51template <class T>
52struct Hit
53{
54 uint32_t index = InvalidIndex;
56
61 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
62 bool
63 valid() const noexcept
64 {
65 return index != InvalidIndex;
66 }
67};
68
77template <class T>
78class KBest
79{
80public:
88 KBest(Hit<T>* a_out, const std::size_t a_k, const uint32_t a_exclude = InvalidIndex) noexcept
89 : m_out(a_out), m_k(a_k), m_exclude(a_exclude)
90 {
91 EBGEOMETRY_EXPECT(a_out != nullptr);
92 EBGEOMETRY_EXPECT(a_k > 0);
93 }
94
103 void
104 insert(const T a_distanceSquared, const uint32_t a_index) noexcept
105 {
106 if (a_distanceSquared >= m_bound || a_index == m_exclude) {
107 return;
108 }
109
110 std::size_t slot = (m_found < m_k) ? m_found++ : (m_k - 1);
111
112 for (; slot > 0 && m_out[slot - 1].distanceSquared > a_distanceSquared; slot--) {
113 m_out[slot] = m_out[slot - 1];
114 }
115
116 m_out[slot] = Hit<T>{a_index, a_distanceSquared};
117
118 if (m_found == m_k) {
119 m_bound = m_out[m_k - 1].distanceSquared;
120 }
121 }
122
129 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
130 T
131 bound() const noexcept
132 {
133 return m_bound;
134 }
135
140 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
141 std::size_t
142 found() const noexcept
143 {
144 return m_found;
145 }
146
147private:
148 Hit<T>* m_out;
149 std::size_t m_k;
150 uint32_t m_exclude;
151 std::size_t m_found = 0;
152 T m_bound = Math::Limits<T>::max();
153};
154
170template <class T>
172inline std::size_t
174 const uint32_t a_numPoints,
175 const Vec3T<T>& a_query,
176 const std::size_t a_k,
177 Hit<T>* a_out,
178 const uint32_t a_exclude = InvalidIndex) noexcept
179{
180 EBGEOMETRY_EXPECT(a_positions != nullptr || a_numPoints == 0);
181
182 KBest<T> best(a_out, a_k, a_exclude);
183
184 for (uint32_t i = 0; i < a_numPoints; i++) {
185 best.insert((a_positions[i] - a_query).length2(), i);
186 }
187
188 return best.found();
189}
190
202template <class T>
203[[nodiscard]] EBGEOMETRY_HOST_DEVICE
204inline Hit<T>
206 const uint32_t a_numPoints,
207 const Vec3T<T>& a_query,
208 const uint32_t a_exclude = InvalidIndex) noexcept
209{
210 Hit<T> hit;
211
212 closestPointsBruteForce(a_positions, a_numPoints, a_query, 1, &hit, a_exclude);
213
214 return hit;
215}
216
217} // namespace PointCloud
218
219} // namespace EBGeometry
220
221#endif
GPU portability layer: host/device decoration macros and backend detection.
#define EBGEOMETRY_HOST_DEVICE
Mark a function as callable from both host and device code (no-op on host compilers).
Definition EBGeometry_GPU.hpp:80
Utility macros for EBGeometry.
#define EBGEOMETRY_EXPECT(cond)
Runtime precondition assertion for EBGeometry.
Definition EBGeometry_Macros.hpp:155
Scalar helpers and numeric limits that compile for both host and device.
Declaration of 2D and 3D point/vector classes with templated precision, and free functions on them.
The k nearest points seen so far, kept sorted in a caller-supplied buffer.
Definition EBGeometry_PointCloud.hpp:79
std::size_t found() const noexcept
Number of candidates held, at most k.
Definition EBGeometry_PointCloud.hpp:142
void insert(const T a_distanceSquared, const uint32_t a_index) noexcept
Offer one candidate.
Definition EBGeometry_PointCloud.hpp:104
KBest(Hit< T > *a_out, const std::size_t a_k, const uint32_t a_exclude=InvalidIndex) noexcept
Start an empty set.
Definition EBGeometry_PointCloud.hpp:88
T bound() const noexcept
The squared distance a candidate must beat to be inserted.
Definition EBGeometry_PointCloud.hpp:131
Three-dimensional vector class with arithmetic operators.
Definition EBGeometry_Vec.hpp:258
std::size_t closestPointsBruteForce(const Vec3T< T > *a_positions, const uint32_t a_numPoints, const Vec3T< T > &a_query, const std::size_t a_k, Hit< T > *a_out, const uint32_t a_exclude=InvalidIndex) noexcept
The a_k points of a cloud nearest to a query point, by a full scan.
Definition EBGeometry_PointCloud.hpp:173
Hit< T > closestPointBruteForce(const Vec3T< T > *a_positions, const uint32_t a_numPoints, const Vec3T< T > &a_query, const uint32_t a_exclude=InvalidIndex) noexcept
The point of a cloud nearest to a query point, by a full scan.
Definition EBGeometry_PointCloud.hpp:205
constexpr uint32_t InvalidIndex
The cloud index of "no point": a miss, or a result slot a query could not fill.
Definition EBGeometry_PointCloud.hpp:41
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_Affine.hpp:26
Numeric limits, with the meanings of the std::numeric_limits members of the same names.
Definition EBGeometry_Math.hpp:91
One query result: the cloud index of a matched point and its squared distance.
Definition EBGeometry_PointCloud.hpp:53
T distanceSquared
Squared distance from the query to it.
Definition EBGeometry_PointCloud.hpp:55
bool valid() const noexcept
Whether this is a match rather than a miss.
Definition EBGeometry_PointCloud.hpp:63
uint32_t index
Cloud index of the matched point.
Definition EBGeometry_PointCloud.hpp:54