12 #include <nanoflann.hpp>
22 template <
class MatrixType,
int DIM,
class Distance,
bool row_major>
23 struct KDTreeEigenMatrixAdaptor;
58 bool SetMatrixData(
const Eigen::MatrixXd &
data);
62 bool SetGeometry(
const ccHObject &geometry);
71 std::vector<int> &indices,
72 std::vector<double> &distance2)
const {
75 return SearchKNN(query,
94 int Query(
const std::vector<T> &queries,
96 std::vector<std::vector<int>> &indices,
97 std::vector<std::vector<double>> &distance2)
const {
99 indices.resize(queries.size());
100 distance2.resize(queries.size());
104 #pragma omp parallel for schedule(static)
106 for (
int idx = 0; idx < int(queries.size()); ++idx) {
107 int k = Search(queries[idx], param, indices[idx], distance2[idx]);
120 template <
typename T>
123 std::vector<int> &indices,
124 std::vector<double> &distance2)
const {
128 if (data_.empty() || dataset_size_ <= 0 ||
129 size_t(query.rows()) != dimension_ || knn < 0) {
133 distance2.resize(knn);
134 std::vector<Eigen::Index> indices_eigen(knn);
135 int k = nanoflann_index_->index_->knnSearch(
136 query.data(), knn, indices_eigen.data(), distance2.data());
139 std::copy_n(indices_eigen.begin(), k, indices.begin());
143 template <
typename T>
146 std::vector<int> &indices,
147 std::vector<double> &distance2)
const {
152 if (data_.empty() || dataset_size_ <= 0 ||
153 size_t(query.rows()) != dimension_) {
156 std::vector<nanoflann::ResultItem<Eigen::Index, double>> indices_dists;
157 int k = nanoflann_index_->index_->radiusSearch(
158 query.data(), radius * radius, indices_dists,
159 nanoflann::SearchParameters(0.0));
162 for (
int i = 0; i < k; ++i) {
163 indices[i] = indices_dists[i].first;
164 distance2[i] = indices_dists[i].second;
169 template <
typename T>
173 std::vector<int> &indices,
174 std::vector<double> &distance2)
const {
179 if (data_.empty() || dataset_size_ <= 0 ||
180 size_t(query.rows()) != dimension_ || max_nn < 0) {
183 distance2.resize(max_nn);
184 std::vector<Eigen::Index> indices_eigen(max_nn);
185 int k = nanoflann_index_->index_->knnSearch(
186 query.data(), max_nn, indices_eigen.data(), distance2.data());
189 std::lower_bound(distance2.begin(), distance2.begin() + k,
193 std::copy_n(indices_eigen.begin(), k, indices.begin());
202 bool SetRawData(
const Eigen::Map<const Eigen::MatrixXd> &
data);
205 using KDTree_t = nanoflann::KDTreeEigenMatrixAdaptor<
206 Eigen::Map<const Eigen::MatrixXd>,
208 nanoflann::metric_L2,
214 size_t dimension_ = 0;
215 size_t dataset_size_ = 0;
Hierarchical CLOUDVIEWER Object.
KDTree with FLANN for nearest neighbor search.
int SearchRadius(const T &query, double radius, std::vector< int > &indices, std::vector< double > &distance2) const
KDTreeFlann(const KDTreeFlann &)=delete
int SearchKNN(const T &query, int knn, std::vector< int > &indices, std::vector< double > &distance2) const
int SearchHybrid(const T &query, double radius, int max_nn, std::vector< int > &indices, std::vector< double > &distance2) const
std::unique_ptr< KDTree_t > nanoflann_index_
int Query(const std::vector< T > &queries, const KDTreeSearchParam ¶m, std::vector< std::vector< int >> &indices, std::vector< std::vector< double >> &distance2) const
std::unique_ptr< Eigen::Map< const Eigen::MatrixXd > > data_interface_
KDTreeFlann & operator=(const KDTreeFlann &)=delete
int Search(const T &query, const KDTreeSearchParam ¶m, std::vector< int > &indices, std::vector< double > &distance2) const
std::vector< double > data_
nanoflann::KDTreeEigenMatrixAdaptor< Eigen::Map< const Eigen::MatrixXd >, -1, nanoflann::metric_L2, false > KDTree_t
KDTree search parameters for hybrid KNN and radius search.
KDTree search parameters for pure KNN search.
KDTree search parameters for pure radius search.
Base class for KDTree search parameters.
SearchType GetSearchType() const
Get the search type (KNN, Radius, Hybrid) for the search parameter.
Class to store featrues for registration.
static double distance(T *pot1, T *pot2)
Generic file read and write utility for python interface.