small_gicp
flat_container.hpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright 2024 Kenji Koide
2 // SPDX-License-Identifier: MIT
3 #pragma once
4 
5 #include <queue>
6 #include <Eigen/Core>
7 #include <Eigen/Geometry>
11 
12 namespace small_gicp {
13 
20 template <bool HasNormals = false, bool HasCovs = false>
21 struct FlatContainer {
22 public:
24  struct Setting {
25  double min_sq_dist_in_cell = 0.1 * 0.1;
26  size_t max_num_points_in_cell = 10;
27  };
28 
30  FlatContainer() { points.reserve(5); }
31 
33  size_t size() const { return points.size(); }
34 
42  template <typename PointCloud>
43  void add(const Setting& setting, const Eigen::Vector4d& transformed_pt, const PointCloud& points, size_t i, const Eigen::Isometry3d& T) {
44  if (
45  this->points.size() >= setting.max_num_points_in_cell || //
46  std::any_of(this->points.begin(), this->points.end(), [&](const auto& pt) { return (pt - transformed_pt).squaredNorm() < setting.min_sq_dist_in_cell; }) //
47  ) {
48  return;
49  }
50 
51  this->points.emplace_back(transformed_pt);
52  if constexpr (HasNormals) {
53  this->normals.emplace_back(T.matrix() * traits::normal(points, i));
54  }
55  if constexpr (HasCovs) {
56  this->covs.emplace_back(T.matrix() * traits::cov(points, i) * T.matrix().transpose());
57  }
58  }
59 
61  void finalize() {}
62 
68  size_t nearest_neighbor_search(const Eigen::Vector4d& pt, size_t* k_index, double* k_sq_dist) const {
69  if (points.empty()) {
70  return 0;
71  }
72 
73  KnnResult<1> result(k_index, k_sq_dist);
74  knn_search(pt, result);
75  return result.num_found();
76  }
77 
84  size_t knn_search(const Eigen::Vector4d& pt, int k, size_t* k_indices, double* k_sq_dists) const {
85  if (points.empty()) {
86  return 0;
87  }
88 
89  KnnResult<-1> result(k_indices, k_sq_dists, k);
90  knn_search(pt, result);
91  return result.num_found();
92  }
93 
100  template <typename Result>
101  void knn_search(const Eigen::Vector4d& pt, Result& result) const {
102  if (points.empty()) {
103  return;
104  }
105 
106  for (size_t i = 0; i < points.size(); i++) {
107  const double sq_dist = (points[i] - pt).squaredNorm();
108  result.push(i, sq_dist);
109  }
110  }
111 
112 public:
113  struct Empty {};
114 
115  std::vector<Eigen::Vector4d> points;
116  std::conditional_t<HasNormals, std::vector<Eigen::Vector4d>, Empty> normals;
117  std::conditional_t<HasCovs, std::vector<Eigen::Matrix4d>, Empty> covs;
118 };
119 
128 
129 namespace traits {
130 
131 template <bool HasNormals, bool HasCovs>
132 struct Traits<FlatContainer<HasNormals, HasCovs>> {
133  static size_t size(const FlatContainer<HasNormals, HasCovs>& container) { return container.size(); }
134  static bool has_points(const FlatContainer<HasNormals, HasCovs>& container) { return container.size(); }
135  static bool has_normals(const FlatContainer<HasNormals, HasCovs>& container) { return HasNormals && container.size(); }
136  static bool has_covs(const FlatContainer<HasNormals, HasCovs>& container) { return HasCovs && container.size(); }
137 
138  static const Eigen::Vector4d& point(const FlatContainer<HasNormals, HasCovs>& container, size_t i) { return container.points[i]; }
139  static const Eigen::Vector4d& normal(const FlatContainer<HasNormals, HasCovs>& container, size_t i) { return container.normals[i]; }
140  static const Eigen::Matrix4d& cov(const FlatContainer<HasNormals, HasCovs>& container, size_t i) { return container.covs[i]; }
141 
142  static size_t nearest_neighbor_search(const FlatContainer<HasNormals, HasCovs>& container, const Eigen::Vector4d& pt, size_t* k_index, double* k_sq_dist) {
143  return container.nearest_neighbor_search(pt, k_index, k_sq_dist);
144  }
145 
146  static size_t knn_search(const FlatContainer<HasNormals, HasCovs>& container, const Eigen::Vector4d& pt, size_t k, size_t* k_index, double* k_sq_dist) {
147  return container.knn_search(pt, k, k_index, k_sq_dist);
148  }
149 
150  template <typename Result>
151  static void knn_search(const FlatContainer<HasNormals, HasCovs>& container, const Eigen::Vector4d& pt, Result& result) {
152  container.knn_search(pt, result);
153  }
154 };
155 
156 } // namespace traits
157 
158 } // namespace small_gicp
auto cov(const T &points, size_t i)
Get i-th covariance. Only the top-left 3x3 matrix is filled, and the bottom row and the right col mus...
Definition: traits.hpp:52
auto normal(const T &points, size_t i)
Get i-th normal. 4D vector is used to take advantage of SIMD intrinsics. The last element must be fil...
Definition: traits.hpp:46
Definition: flat_container.hpp:12
Definition: flat_container.hpp:113
FlatContainer setting.
Definition: flat_container.hpp:24
size_t max_num_points_in_cell
Maximum number of points in a cell.
Definition: flat_container.hpp:26
double min_sq_dist_in_cell
Minimum squared distance between points in a cell.
Definition: flat_container.hpp:25
Point container with a flat vector.
Definition: flat_container.hpp:21
std::vector< Eigen::Vector4d > points
Points.
Definition: flat_container.hpp:115
size_t nearest_neighbor_search(const Eigen::Vector4d &pt, size_t *k_index, double *k_sq_dist) const
Find the nearest neighbor.
Definition: flat_container.hpp:68
std::conditional_t< HasNormals, std::vector< Eigen::Vector4d >, Empty > normals
Normals (Empty if HasNormals is false)
Definition: flat_container.hpp:116
size_t size() const
Number of points.
Definition: flat_container.hpp:33
void add(const Setting &setting, const Eigen::Vector4d &transformed_pt, const PointCloud &points, size_t i, const Eigen::Isometry3d &T)
Add a point to the container. If there is a point that is too close to the input point,...
Definition: flat_container.hpp:43
void finalize()
Finalize the container (Nothing to do for FlatContainer).
Definition: flat_container.hpp:61
FlatContainer()
Constructor.
Definition: flat_container.hpp:30
size_t knn_search(const Eigen::Vector4d &pt, int k, size_t *k_indices, double *k_sq_dists) const
Find k nearest neighbors.
Definition: flat_container.hpp:84
void knn_search(const Eigen::Vector4d &pt, Result &result) const
Find k nearest neighbors.
Definition: flat_container.hpp:101
std::conditional_t< HasCovs, std::vector< Eigen::Matrix4d >, Empty > covs
Covariances (Empty if HasCovs is false)
Definition: flat_container.hpp:117
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
Point cloud.
Definition: point_cloud.hpp:15
size_t size() const
Number of points.
Definition: point_cloud.hpp:37
static bool has_normals(const FlatContainer< HasNormals, HasCovs > &container)
Definition: flat_container.hpp:135
static bool has_covs(const FlatContainer< HasNormals, HasCovs > &container)
Definition: flat_container.hpp:136
static size_t knn_search(const FlatContainer< HasNormals, HasCovs > &container, const Eigen::Vector4d &pt, size_t k, size_t *k_index, double *k_sq_dist)
Definition: flat_container.hpp:146
static size_t size(const FlatContainer< HasNormals, HasCovs > &container)
Definition: flat_container.hpp:133
static void knn_search(const FlatContainer< HasNormals, HasCovs > &container, const Eigen::Vector4d &pt, Result &result)
Definition: flat_container.hpp:151
static const Eigen::Vector4d & point(const FlatContainer< HasNormals, HasCovs > &container, size_t i)
Definition: flat_container.hpp:138
static const Eigen::Vector4d & normal(const FlatContainer< HasNormals, HasCovs > &container, size_t i)
Definition: flat_container.hpp:139
static size_t nearest_neighbor_search(const FlatContainer< HasNormals, HasCovs > &container, const Eigen::Vector4d &pt, size_t *k_index, double *k_sq_dist)
Definition: flat_container.hpp:142
static bool has_points(const FlatContainer< HasNormals, HasCovs > &container)
Definition: flat_container.hpp:134
static const Eigen::Matrix4d & cov(const FlatContainer< HasNormals, HasCovs > &container, size_t i)
Definition: flat_container.hpp:140
Definition: traits.hpp:13