Ponca  aa50bfdf187919869239c5b44b748842569114c1
Point Cloud Analysis library
Loading...
Searching...
No Matches
kdTreeTraits.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
8#pragma once
9
10#include "../../Common/Macro.h"
11
12#include <cstddef>
13
14#include <Eigen/Geometry>
15
16namespace Ponca {
17#ifndef PARSED_WITH_DOXYGEN
18namespace internal
19{
20 constexpr int clz(unsigned int value)
21 {
22#if PONCA_HAS_BUILTIN_CLZ
23 return __builtin_clz(value);
24#else
25 if (value == 0)
26 {
27 return 0;
28 }
29
30 unsigned int msb_mask = 1 << (sizeof(unsigned int)*8 - 1);
31 int count = 0;
32 for (; (value & msb_mask) == 0; value <<= 1, ++count)
33 {
34 }
35 return count;
36#endif
37 }
38}
39#endif
40
41template <typename NodeIndex, typename Scalar, int DIM>
43{
44private:
45 enum
46 {
47 // The minimum bit width required to store the split dimension.
48 //
49 // Equal to the index of DIM's most significant bit (starting at 1), e.g.:
50 // With DIM = 4,
51 // -------------
52 // DIM = 0b | 1 | 0 | 0 |
53 // -------------
54 // Bit index = #3 #2 #1
55 //
56 // The MSB has an index of 3, so we store the dimension on 3 bits.
57 DIM_BITS = sizeof(unsigned int)*8 - internal::clz((unsigned int)DIM),
58 };
59
60 // The node stores bitfields as unsigned indices.
61 using UIndex = typename std::make_unsigned<NodeIndex>::type;
62
63public:
64 enum
65 {
69 INDEX_BITS = sizeof(UIndex)*8 - DIM_BITS,
70 };
71
72 Scalar split_value{0};
73 UIndex first_child_id : INDEX_BITS;
74 UIndex split_dim : DIM_BITS;
75};
76
77template <typename Index, typename Size>
79{
80 Index start{0};
81 Size size{0};
82};
83
105template <typename Index, typename NodeIndex, typename DataPoint,
106 typename LeafSize = Index,
108 typename _LeafNodeType = KdTreeDefaultLeafNode<Index, LeafSize>>
110{
111private:
112 using Scalar = typename DataPoint::Scalar;
113 using InnerType = _InnerNodeType;
114 using LeafType = _LeafNodeType;
115
116public:
117 enum : std::size_t
118 {
123 MAX_COUNT = std::size_t(2) << InnerType::INDEX_BITS,
124 };
125
132 using AabbType = Eigen::AlignedBox<Scalar, DataPoint::Dim>;
133
134 [[nodiscard]] bool is_leaf() const { return m_is_leaf; }
135 void set_is_leaf(bool is_leaf) { m_is_leaf = is_leaf; }
136
149 void configure_range(Index start, Index size, const AabbType &aabb)
150 {
151 if (m_is_leaf)
152 {
153 data.m_leaf.start = start;
154 data.m_leaf.size = (LeafSize)size;
155 }
156 }
157
167 void configure_inner(Scalar split_value, Index first_child_id, Index split_dim)
168 {
169 if (!m_is_leaf)
170 {
171 data.m_inner.split_value = split_value;
172 data.m_inner.first_child_id = first_child_id;
173 data.m_inner.split_dim = split_dim;
174 }
175 }
176
181 [[nodiscard]] Index leaf_start() const { return data.m_leaf.start; }
182
186 [[nodiscard]] LeafSize leaf_size() const { return data.m_leaf.size; }
187
191 [[nodiscard]] Scalar inner_split_value() const { return data.m_inner.split_value; }
192
196 [[nodiscard]] int inner_split_dim() const { return (int)data.m_inner.split_dim; }
197
205 [[nodiscard]] Index inner_first_child_id() const { return (Index)data.m_inner.first_child_id; }
206
207protected:
208 [[nodiscard]] inline LeafType& getAsLeaf() { return data.m_leaf; }
209 [[nodiscard]] inline InnerType& getAsInner() { return data.m_inner; }
210 [[nodiscard]] inline const LeafType& getAsLeaf() const { return data.m_leaf; }
211 [[nodiscard]] inline const InnerType& getAsInner() const { return data.m_inner; }
212
213private:
214 bool m_is_leaf{true};
215 union Data
216 {
217 // We need an explicit constructor here, see https://stackoverflow.com/a/70428826
218 constexpr Data() : m_leaf() {}
219 // Needed to satisfy MoveInsertable requirement https://en.cppreference.com/w/cpp/named_req/MoveInsertable
220 constexpr Data(const Data&d) : m_leaf(d.m_leaf) {}
221
222 ~Data() {}
223 LeafType m_leaf;
224 InnerType m_inner;
225 };
226 Data data;
227};
228
229template <typename Index, typename NodeIndex, typename DataPoint,
230 typename LeafSize = Index>
231struct KdTreeDefaultNode : public KdTreeCustomizableNode<Index, NodeIndex, DataPoint, LeafSize,
232 KdTreeDefaultInnerNode<NodeIndex, typename DataPoint::Scalar, DataPoint::Dim>,
233 KdTreeDefaultLeafNode<Index, LeafSize>> {
234 using Base = KdTreeCustomizableNode<Index, NodeIndex, DataPoint, LeafSize,
237};
238
246template <typename _DataPoint,
247 template <typename /*Index*/,
248 typename /*NodeIndex*/,
249 typename /*DataPoint*/,
250 typename /*LeafSize*/> typename _NodeType = KdTreeDefaultNode>
252{
253 enum
254 {
259 };
260
270 using DataPoint = _DataPoint;
271 using IndexType = int;
272 using LeafSizeType = unsigned short;
273
274 // Containers
275 using PointContainer = std::vector<DataPoint>;
276 using IndexContainer = std::vector<IndexType>;
277
278 // Nodes
279 using NodeIndexType = std::size_t;
280 using NodeType = _NodeType<IndexType, NodeIndexType, DataPoint, LeafSizeType>;
281 using NodeContainer = std::vector<NodeType>;
282};
283} // namespace Ponca
The node type used by default by the kd-tree.
Definition: kdTreeTraits.h:110
Scalar inner_split_value() const
The position of the AABB split of the inner node.
Definition: kdTreeTraits.h:191
Index leaf_start() const
The start index of the range of the leaf node in the sample index array.
Definition: kdTreeTraits.h:181
Eigen::AlignedBox< Scalar, DataPoint::Dim > AabbType
The type used to store node bounding boxes.
Definition: kdTreeTraits.h:132
void configure_range(Index start, Index size, const AabbType &aabb)
Configures the range of the node in the sample index array of the kd-tree.
Definition: kdTreeTraits.h:149
void configure_inner(Scalar split_value, Index first_child_id, Index split_dim)
Configures the inner node information.
Definition: kdTreeTraits.h:167
int inner_split_dim() const
Which axis the split of the AABB of the inner node was done on.
Definition: kdTreeTraits.h:196
@ MAX_COUNT
The maximum number of nodes that a kd-tree can have when using this node type.
Definition: kdTreeTraits.h:123
LeafSize leaf_size() const
The size of the range of the leaf node in the sample index array.
Definition: kdTreeTraits.h:186
Index inner_first_child_id() const
The index of the first child of the node in the node array of the kd-tree.
Definition: kdTreeTraits.h:205
This Source Code Form is subject to the terms of the Mozilla Public License, v.
@ INDEX_BITS
The bit width used to store the first child index.
Definition: kdTreeTraits.h:69
The default traits type used by the kd-tree.
Definition: kdTreeTraits.h:252
@ MAX_DEPTH
A compile-time constant specifying the maximum depth of the kd-tree.
Definition: kdTreeTraits.h:258
_DataPoint DataPoint
The type used to store point data.
Definition: kdTreeTraits.h:270