53 static constexpr
NodeIndexType INVALID_NODE = std::numeric_limits<NodeIndexType>::max();
56 template <
typename Projection>
79 template <
typename KdTree,
typename Po
intCloud>
82 std::iota(kdtree.indices.begin(), kdtree.indices.end(), 0);
84 size_t node_count = 0;
86 kdtree.root =
create_node(kdtree, node_count, points, kdtree.indices.begin(), kdtree.indices.begin(), kdtree.indices.end());
87 kdtree.nodes.resize(node_count);
95 template <
typename Po
intCloud,
typename KdTree,
typename IndexConstIterator>
98 const size_t N = std::distance(first, last);
100 auto& node = kdtree.nodes[node_index];
105 node.node_type.lr.first = std::distance(global_first, first);
106 node.node_type.lr.last = std::distance(global_first, last);
112 using Projection =
typename KdTree::Projection;
114 const auto median_itr = first + N / 2;
115 std::nth_element(first, median_itr, last, [&](
size_t i,
size_t j) {
return proj(
traits::point(points, i)) < proj(
traits::point(points, j)); });
118 node.node_type.sub.proj = proj;
119 node.node_type.sub.thresh = proj(
traits::point(points, *median_itr));
122 node.left =
create_node(kdtree, node_count, points, global_first, first, median_itr);
123 node.right =
create_node(kdtree, node_count, points, global_first, median_itr, last);
136 template <
typename Po
intCloud,
typename Projection_ = AxisAlignedProjection>
145 template <
typename Builder = KdTreeBuilder>
148 std::cerr <<
"warning: Empty point cloud" << std::endl;
152 builder.build_tree(*
this,
points);
162 return knn_search<1>(query, k_indices, k_sq_dists, setting);
173 KnnResult<-1> result(k_indices, k_sq_dists, k);
193 template <
typename Result>
195 const auto& node =
nodes[node_index];
198 if (node.left == INVALID_NODE) {
200 for (
size_t i = node.node_type.lr.first; i < node.node_type.lr.last; i++) {
202 result.push(
indices[i], sq_dist);
207 const double val = node.node_type.sub.proj(query);
208 const double diff = val - node.node_type.sub.thresh;
209 const double cut_sq_dist = diff * diff;
215 best_child = node.left;
216 other_child = node.right;
218 best_child = node.right;
219 other_child = node.left;
223 if (!
knn_search(query, best_child, result, setting)) {
228 if (result.worst_distance() > cut_sq_dist) {
229 return knn_search(query, other_child, result, setting);
244 template <
typename Po
intCloud,
typename Projection = AxisAlignedProjection>
247 using Ptr = std::shared_ptr<KdTree<PointCloud, Projection>>;
248 using ConstPtr = std::shared_ptr<const KdTree<PointCloud, Projection>>;
250 template <
typename Builder = KdTreeBuilder>
262 return kdtree.nearest_neighbor_search(query, k_indices, k_sq_dists, setting);
273 return kdtree.knn_search(query, k, k_indices, k_sq_dists, setting);
277 const std::shared_ptr<const PointCloud>
points;
283 template <
typename Po
intCloud,
typename Projection>
294 template <
typename Po
intCloud,
typename Projection>
size_t size(const T &points)
Get the number of points.
Definition: traits.hpp:16
auto point(const T &points, size_t i)
Get i-th point. 4D vector is used to take advantage of SIMD intrinsics. The last element must be fill...
Definition: traits.hpp:40
Definition: flat_container.hpp:12
std::uint32_t NodeIndexType
Definition: kdtree.hpp:52
Single thread Kd-tree builder.
Definition: kdtree.hpp:74
NodeIndexType create_node(KdTree &kdtree, size_t &node_count, const PointCloud &points, IndexConstIterator global_first, IndexConstIterator first, IndexConstIterator last) const
Create a Kd-tree node from the given point indices.
Definition: kdtree.hpp:96
int max_leaf_size
Maximum number of points in a leaf node.
Definition: kdtree.hpp:129
ProjectionSetting projection_setting
Projection setting.
Definition: kdtree.hpp:130
void build_tree(KdTree &kdtree, const PointCloud &points) const
Build KdTree.
Definition: kdtree.hpp:80
KdTree node.
Definition: kdtree.hpp:57
union small_gicp::KdTreeNode::@0 node_type
NodeIndexType right
Right child node index.
Definition: kdtree.hpp:70
Projection proj
Projection axis.
Definition: kdtree.hpp:64
NodeIndexType first
First point index in the leaf node.
Definition: kdtree.hpp:60
NodeIndexType last
Last point index in the leaf node.
Definition: kdtree.hpp:61
double thresh
Threshold value.
Definition: kdtree.hpp:65
struct small_gicp::KdTreeNode::@0::Leaf lr
Leaf node.
NodeIndexType left
Left child node index.
Definition: kdtree.hpp:69
struct small_gicp::KdTreeNode::@0::NonLeaf sub
Non-leaf node.
"Safe" KdTree that holds the ownership of the input points.
Definition: kdtree.hpp:245
const std::shared_ptr< const PointCloud > points
Points.
Definition: kdtree.hpp:277
const UnsafeKdTree< PointCloud, Projection > kdtree
KdTree.
Definition: kdtree.hpp:278
size_t knn_search(const Eigen::Vector4d &query, size_t k, size_t *k_indices, double *k_sq_dists, const KnnSetting &setting=KnnSetting()) const
Find k-nearest neighbors. This method uses dynamic memory allocation.
Definition: kdtree.hpp:272
std::shared_ptr< const KdTree< PointCloud, Projection > > ConstPtr
Definition: kdtree.hpp:248
std::shared_ptr< KdTree< PointCloud, Projection > > Ptr
Definition: kdtree.hpp:247
KdTree(std::shared_ptr< const PointCloud > points, const Builder &builder=Builder())
Definition: kdtree.hpp:251
size_t nearest_neighbor_search(const Eigen::Vector4d &query, size_t *k_indices, double *k_sq_dists, const KnnSetting &setting=KnnSetting()) const
Find k-nearest neighbors. This method uses dynamic memory allocation.
Definition: kdtree.hpp:261
K-nearest neighbor search result container.
Definition: knn_result.hpp:33
size_t num_found() const
Number of found neighbors.
Definition: knn_result.hpp:73
K-nearest neighbor search setting.
Definition: knn_result.hpp:13
bool fulfilled(const Result &result) const
Check if the result satisfies the early termination condition.
Definition: knn_result.hpp:17
Point cloud.
Definition: point_cloud.hpp:15
Parameters to control the projection axis search.
Definition: projection.hpp:12
"Unsafe" KdTree.
Definition: kdtree.hpp:137
UnsafeKdTree(const PointCloud &points, const Builder &builder=KdTreeBuilder())
Constructor.
Definition: kdtree.hpp:146
NodeIndexType root
Root node index (should be zero)
Definition: kdtree.hpp:239
std::vector< size_t > indices
Point indices refered by nodes.
Definition: kdtree.hpp:237
Projection_ Projection
Definition: kdtree.hpp:139
const PointCloud & points
Input points.
Definition: kdtree.hpp:236
size_t knn_search(const Eigen::Vector4d &query, size_t *k_indices, double *k_sq_dists, const KnnSetting &setting=KnnSetting()) const
Find k-nearest neighbors. This method uses fixed and static memory allocation. Might be faster for sm...
Definition: kdtree.hpp:185
size_t nearest_neighbor_search(const Eigen::Vector4d &query, size_t *k_indices, double *k_sq_dists, const KnnSetting &setting=KnnSetting()) const
Find the nearest neighbor.
Definition: kdtree.hpp:161
std::vector< Node > nodes
Kd-tree nodes.
Definition: kdtree.hpp:240
size_t knn_search(const Eigen::Vector4d &query, int k, size_t *k_indices, double *k_sq_dists, const KnnSetting &setting=KnnSetting()) const
Find k-nearest neighbors. This method uses dynamic memory allocation.
Definition: kdtree.hpp:172
static size_t knn_search(const KdTree< PointCloud, Projection > &tree, const Eigen::Vector4d &point, size_t k, size_t *k_indices, double *k_sq_dists)
Definition: kdtree.hpp:300
static size_t nearest_neighbor_search(const KdTree< PointCloud, Projection > &tree, const Eigen::Vector4d &point, size_t *k_indices, double *k_sq_dists)
Definition: kdtree.hpp:296
static size_t nearest_neighbor_search(const UnsafeKdTree< PointCloud, Projection > &tree, const Eigen::Vector4d &point, size_t *k_indices, double *k_sq_dists)
Definition: kdtree.hpp:285
static size_t knn_search(const UnsafeKdTree< PointCloud, Projection > &tree, const Eigen::Vector4d &point, size_t k, size_t *k_indices, double *k_sq_dists)
Definition: kdtree.hpp:289
Definition: traits.hpp:13