ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
kdtreeflann.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include <ecvKDTreeFlann.h>
9 
10 #include "pybind/docstring.h"
13 
14 namespace cloudViewer {
15 namespace geometry {
16 
17 void pybind_kdtreeflann(py::module &m) {
18  // cloudViewer.geometry.KDTreeSearchParam
19  py::class_<geometry::KDTreeSearchParam> kdtreesearchparam(
20  m, "KDTreeSearchParam", "Base class for KDTree search parameters.");
21  kdtreesearchparam.def("get_search_type",
23  "Get the search type (KNN, Radius, Hybrid) for the "
24  "search parameter.");
25  docstring::ClassMethodDocInject(m, "KDTreeSearchParam", "get_search_type");
26 
27  // cloudViewer.geometry.KDTreeSearchParam.Type
28  py::native_enum<KDTreeSearchParam::SearchType>(
29  kdtreesearchparam, "Type", "enum.Enum",
30  "Enum class for Geometry types.")
31  .value("KNNSearch", KDTreeSearchParam::SearchType::Knn)
32  .value("RadiusSearch", KDTreeSearchParam::SearchType::Radius)
33  .value("HybridSearch", KDTreeSearchParam::SearchType::Hybrid)
34  .export_values()
35  .finalize();
36 
37  // cloudViewer.geometry.KDTreeSearchParamKNN
38  py::class_<geometry::KDTreeSearchParamKNN> kdtreesearchparam_knn(
39  m, "KDTreeSearchParamKNN", kdtreesearchparam,
40  "KDTree search parameters for pure KNN search.");
41  kdtreesearchparam_knn.def(py::init<int>(), "knn"_a = 30)
42  .def("__repr__",
43  [](const geometry::KDTreeSearchParamKNN &param) {
44  return std::string(
45  "geometry::KDTreeSearchParamKNN with knn "
46  "= ") +
47  std::to_string(param.knn_);
48  })
49  .def_readwrite("knn", &geometry::KDTreeSearchParamKNN::knn_,
50  "Number of the neighbors that will be searched.");
51 
52  // cloudViewer.geometry.KDTreeSearchParamRadius
53  py::class_<geometry::KDTreeSearchParamRadius> kdtreesearchparam_radius(
54  m, "KDTreeSearchParamRadius", kdtreesearchparam,
55  "KDTree search parameters for pure radius search.");
56  kdtreesearchparam_radius.def(py::init<double>(), "radius"_a)
57  .def("__repr__",
58  [](const geometry::KDTreeSearchParamRadius &param) {
59  return std::string(
60  "geometry::KDTreeSearchParamRadius with "
61  "radius = ") +
62  std::to_string(param.radius_);
63  })
64  .def_readwrite("radius",
66  "Search radius.");
67 
68  // cloudViewer.geometry.KDTreeSearchParamHybrid
69  py::class_<geometry::KDTreeSearchParamHybrid> kdtreesearchparam_hybrid(
70  m, "KDTreeSearchParamHybrid", kdtreesearchparam,
71  "KDTree search parameters for hybrid KNN and radius search.");
72  kdtreesearchparam_hybrid
73  .def(py::init<double, int>(), "radius"_a, "max_nn"_a)
74  .def("__repr__",
75  [](const geometry::KDTreeSearchParamHybrid &param) {
76  return std::string(
77  "geometry::KDTreeSearchParamHybrid with "
78  "radius = ") +
79  std::to_string(param.radius_) +
80  " and max_nn = " + std::to_string(param.max_nn_);
81  })
82  .def_readwrite("radius",
84  "Search radius.")
85  .def_readwrite(
87  "At maximum, ``max_nn`` neighbors will be searched.");
88 
89  // cloudViewer.geometry.KDTreeFlann
90  static const std::unordered_map<std::string, std::string>
91  map_kd_tree_flann_method_docs = {
92  {"query", "The input query point."},
93  {"radius", "Search radius."},
94  {"max_nn",
95  "At maximum, ``max_nn`` neighbors will be searched."},
96  {"knn", "``knn`` neighbors will be searched."},
97  {"feature", "Feature data."},
98  {"data", "Matrix data."}};
99  py::class_<KDTreeFlann, std::shared_ptr<KDTreeFlann>> kdtreeflann(
100  m, "KDTreeFlann", "KDTree with FLANN for nearest neighbor search.");
101  kdtreeflann.def(py::init<>())
102  .def(py::init<const Eigen::MatrixXd &>(), "data"_a)
103  .def("set_matrix_data", &KDTreeFlann::SetMatrixData,
104  "Sets the data for the KDTree from a matrix.", "data"_a)
105  .def(py::init<const ccHObject &>(), "geometry"_a)
106  .def("set_geometry", &KDTreeFlann::SetGeometry,
107  "Sets the data for the KDTree from geometry.", "geometry"_a)
108  .def(py::init<const utility::Feature &>(), "feature"_a)
109  .def("set_feature", &KDTreeFlann::SetFeature,
110  "Sets the data for the KDTree from the feature data.",
111  "feature"_a)
112  // Although these C++ style functions are fast by orders of
113  // magnitudes when similar queries are performed for a large number
114  // of times and memory management is involved, we prefer not to
115  // expose them in Python binding. Considering writing C++ functions
116  // if performance is an issue.
117  //.def("search_vector_3d_in_place",
118  //&KDTreeFlann::Search<Eigen::Vector3d>,
119  // "query"_a, "search_param"_a, "indices"_a, "distance2"_a)
120  //.def("search_knn_vector_3d_in_place",
121  // &KDTreeFlann::SearchKNN<Eigen::Vector3d>,
122  // "query"_a, "knn"_a, "indices"_a, "distance2"_a)
123  //.def("search_radius_vector_3d_in_place",
124  // &KDTreeFlann::SearchRadius<Eigen::Vector3d>, "query"_a,
125  // "radius"_a, "indices"_a, "distance2"_a)
126  //.def("search_hybrid_vector_3d_in_place",
127  // &KDTreeFlann::SearchHybrid<Eigen::Vector3d>, "query"_a,
128  // "radius"_a, "max_nn"_a, "indices"_a, "distance2"_a)
129  .def(
130  "search_vector_3d",
131  [](const geometry::KDTreeFlann &tree,
132  const Eigen::Vector3d &query,
133  const geometry::KDTreeSearchParam &param) {
134  std::vector<int> indices;
135  std::vector<double> distance2;
136  int k = tree.Search(query, param, indices, distance2);
137  if (k < 0)
138  throw std::runtime_error(
139  "search_vector_3d() error!");
140  return std::make_tuple(k, indices, distance2);
141  },
142  "query"_a, "search_param"_a)
143  .def(
144  "query_vector_3d",
145  [](const geometry::KDTreeFlann &tree,
146  const std::vector<Eigen::Vector3d> &queries,
147  const geometry::KDTreeSearchParam &param) {
148  std::vector<std::vector<int>> indices;
149  std::vector<std::vector<double>> distance2;
150  int k = tree.Query(queries, param, indices, distance2);
151  if (k < 0)
152  throw std::runtime_error(
153  "search_vector_3d() error!");
154  return std::make_tuple(k, indices, distance2);
155  },
156  "queries"_a, "search_param"_a)
157  .def(
158  "search_knn_vector_3d",
159  [](const geometry::KDTreeFlann &tree,
160  const Eigen::Vector3d &query, int knn) {
161  std::vector<int> indices;
162  std::vector<double> distance2;
163  int k = tree.SearchKNN(query, knn, indices, distance2);
164  if (k < 0)
165  throw std::runtime_error(
166  "search_knn_vector_3d() error!");
167  return std::make_tuple(k, indices, distance2);
168  },
169  "query"_a, "knn"_a)
170  .def(
171  "search_radius_vector_3d",
172  [](const geometry::KDTreeFlann &tree,
173  const Eigen::Vector3d &query, double radius) {
174  std::vector<int> indices;
175  std::vector<double> distance2;
176  int k = tree.SearchRadius(query, radius, indices,
177  distance2);
178  if (k < 0)
179  throw std::runtime_error(
180  "search_radius_vector_3d() error!");
181  return std::make_tuple(k, indices, distance2);
182  },
183  "query"_a, "radius"_a)
184  .def(
185  "search_hybrid_vector_3d",
186  [](const geometry::KDTreeFlann &tree,
187  const Eigen::Vector3d &query, double radius,
188  int max_nn) {
189  std::vector<int> indices;
190  std::vector<double> distance2;
191  int k = tree.SearchHybrid(query, radius, max_nn,
192  indices, distance2);
193  if (k < 0)
194  throw std::runtime_error(
195  "search_hybrid_vector_3d() error!");
196  return std::make_tuple(k, indices, distance2);
197  },
198  "query"_a, "radius"_a, "max_nn"_a)
199  .def(
200  "search_vector_xd",
201  [](const geometry::KDTreeFlann &tree,
202  const Eigen::VectorXd &query,
203  const geometry::KDTreeSearchParam &param) {
204  std::vector<int> indices;
205  std::vector<double> distance2;
206  int k = tree.Search(query, param, indices, distance2);
207  if (k < 0)
208  throw std::runtime_error(
209  "search_vector_xd() error!");
210  return std::make_tuple(k, indices, distance2);
211  },
212  "query"_a, "search_param"_a)
213 
214  .def(
215  "query_vector_xd",
216  [](const geometry::KDTreeFlann &tree,
217  const std::vector<Eigen::VectorXd> &queries,
218  const geometry::KDTreeSearchParam &param) {
219  std::vector<std::vector<int>> indices;
220  std::vector<std::vector<double>> distance2;
221  int k = tree.Query(queries, param, indices, distance2);
222  if (k < 0)
223  throw std::runtime_error(
224  "query_vector_xd() error!");
225  return std::make_tuple(k, indices, distance2);
226  },
227  "queries"_a, "search_param"_a)
228  .def(
229  "search_knn_vector_xd",
230  [](const geometry::KDTreeFlann &tree,
231  const Eigen::VectorXd &query, int knn) {
232  std::vector<int> indices;
233  std::vector<double> distance2;
234  int k = tree.SearchKNN(query, knn, indices, distance2);
235  if (k < 0)
236  throw std::runtime_error(
237  "search_knn_vector_xd() error!");
238  return std::make_tuple(k, indices, distance2);
239  },
240  "query"_a, "knn"_a)
241  .def(
242  "search_radius_vector_xd",
243  [](const geometry::KDTreeFlann &tree,
244  const Eigen::VectorXd &query, double radius) {
245  std::vector<int> indices;
246  std::vector<double> distance2;
247  int k = tree.SearchRadius(query, radius, indices,
248  distance2);
249  if (k < 0)
250  throw std::runtime_error(
251  "search_radius_vector_xd() error!");
252  return std::make_tuple(k, indices, distance2);
253  },
254  "query"_a, "radius"_a)
255  .def(
256  "search_hybrid_vector_xd",
257  [](const geometry::KDTreeFlann &tree,
258  const Eigen::VectorXd &query, double radius,
259  int max_nn) {
260  std::vector<int> indices;
261  std::vector<double> distance2;
262  int k = tree.SearchHybrid(query, radius, max_nn,
263  indices, distance2);
264  if (k < 0)
265  throw std::runtime_error(
266  "search_hybrid_vector_xd() error!");
267  return std::make_tuple(k, indices, distance2);
268  },
269  "query"_a, "radius"_a, "max_nn"_a);
270  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_hybrid_vector_3d",
271  map_kd_tree_flann_method_docs);
272  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_hybrid_vector_xd",
273  map_kd_tree_flann_method_docs);
274  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_knn_vector_3d",
275  map_kd_tree_flann_method_docs);
276  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_knn_vector_xd",
277  map_kd_tree_flann_method_docs);
278  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_radius_vector_3d",
279  map_kd_tree_flann_method_docs);
280  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_radius_vector_xd",
281  map_kd_tree_flann_method_docs);
282  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_vector_3d",
283  map_kd_tree_flann_method_docs);
284  docstring::ClassMethodDocInject(m, "KDTreeFlann", "search_vector_xd",
285  map_kd_tree_flann_method_docs);
286  docstring::ClassMethodDocInject(m, "KDTreeFlann", "set_feature",
287  map_kd_tree_flann_method_docs);
288  docstring::ClassMethodDocInject(m, "KDTreeFlann", "set_geometry",
289  map_kd_tree_flann_method_docs);
290  docstring::ClassMethodDocInject(m, "KDTreeFlann", "set_matrix_data",
291  map_kd_tree_flann_method_docs);
292 }
293 
294 } // namespace geometry
295 } // namespace cloudViewer
KDTree with FLANN for nearest neighbor search.
int SearchRadius(const T &query, double radius, std::vector< int > &indices, std::vector< double > &distance2) const
bool SetMatrixData(const Eigen::MatrixXd &data)
bool SetFeature(const utility::Feature &feature)
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
int Query(const std::vector< T > &queries, const KDTreeSearchParam &param, std::vector< std::vector< int >> &indices, std::vector< std::vector< double >> &distance2) const
int Search(const T &query, const KDTreeSearchParam &param, std::vector< int > &indices, std::vector< double > &distance2) const
bool SetGeometry(const ccHObject &geometry)
KDTree search parameters for hybrid KNN and radius search.
int max_nn_
At maximum, max_nn neighbors will be searched.
KDTree search parameters for pure KNN search.
int knn_
Number of the neighbors that will be searched.
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.
void ClassMethodDocInject(py::module &pybind_module, const std::string &class_name, const std::string &function_name, const std::unordered_map< std::string, std::string > &map_parameter_body_docs)
Definition: docstring.cpp:27
void pybind_kdtreeflann(py::module &m)
Definition: kdtreeflann.cpp:17
Generic file read and write utility for python interface.
std::string to_string(const T &n)
Definition: Common.h:20