Skip to content

Commit 3a9c694

Browse files
committed
Simplify data_ and data_interface_ in KDTreeFlann.
KDTreeFlann::SetRawData had some confusion around data, data_, and data_interface_. As a result, the data from the parameter was copied to the member std::vector, but the interface (which takes an Eigen::Map) used the data passed as an argument to the method. As a result, the searches risked to be run on a dangling pointer, instead of the intended internal storage. However, rather than adjusting the pointer for Eigen::Map, I preferred simplifying the code, and copy the argument to an Eigen::MatrixXd.
1 parent 80ae047 commit 3a9c694

File tree

2 files changed

+8
-23
lines changed

2 files changed

+8
-23
lines changed

cpp/open3d/geometry/KDTreeFlann.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ int KDTreeFlann::SearchKNN(const T &query,
9797
// This is optimized code for heavily repeated search.
9898
// Other flann::Index::knnSearch() implementations lose performance due to
9999
// memory allocation/deallocation.
100-
if (data_.empty() || dataset_size_ <= 0 ||
101-
size_t(query.rows()) != dimension_ || knn < 0) {
100+
if (data_.size() == 0 || query.rows() != data_.rows() || knn < 0) {
102101
return -1;
103102
}
104103
indices.resize(knn);
@@ -121,8 +120,7 @@ int KDTreeFlann::SearchRadius(const T &query,
121120
// Since max_nn is not given, we let flann to do its own memory management.
122121
// Other flann::Index::radiusSearch() implementations lose performance due
123122
// to memory management and CPU caching.
124-
if (data_.empty() || dataset_size_ <= 0 ||
125-
size_t(query.rows()) != dimension_) {
123+
if (data_.size() == 0 || query.rows() != data_.rows()) {
126124
return -1;
127125
}
128126
std::vector<nanoflann::ResultItem<Eigen::Index, double>> indices_dists;
@@ -148,8 +146,7 @@ int KDTreeFlann::SearchHybrid(const T &query,
148146
// It is also the recommended setting for search.
149147
// Other flann::Index::radiusSearch() implementations lose performance due
150148
// to memory allocation/deallocation.
151-
if (data_.empty() || dataset_size_ <= 0 ||
152-
size_t(query.rows()) != dimension_ || max_nn < 0) {
149+
if (data_.size() == 0 || query.rows() != data_.rows() || max_nn < 0) {
153150
return -1;
154151
}
155152
distance2.resize(max_nn);
@@ -166,18 +163,12 @@ int KDTreeFlann::SearchHybrid(const T &query,
166163
}
167164

168165
bool KDTreeFlann::SetRawData(const Eigen::Map<const Eigen::MatrixXd> &data) {
169-
dimension_ = data.rows();
170-
dataset_size_ = data.cols();
171-
if (dimension_ == 0 || dataset_size_ == 0) {
166+
if (data.size() == 0) {
172167
utility::LogWarning("[KDTreeFlann::SetRawData] Failed due to no data.");
173168
return false;
174169
}
175-
data_.resize(dataset_size_ * dimension_);
176-
memcpy(data_.data(), data.data(),
177-
dataset_size_ * dimension_ * sizeof(double));
178-
data_interface_.reset(new Eigen::Map<const Eigen::MatrixXd>(data));
179-
nanoflann_index_.reset(
180-
new KDTree_t(dimension_, std::cref(*data_interface_), 15));
170+
data_ = data;
171+
nanoflann_index_ = std::make_unique<KDTree_t>(data_.rows(), data_, 15);
181172
nanoflann_index_->index_->buildIndex();
182173
return true;
183174
}

cpp/open3d/geometry/KDTreeFlann.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,10 @@ class KDTreeFlann {
9898

9999
protected:
100100
using KDTree_t = nanoflann::KDTreeEigenMatrixAdaptor<
101-
Eigen::Map<const Eigen::MatrixXd>,
102-
-1,
103-
nanoflann::metric_L2,
104-
false>;
101+
const Eigen::MatrixXd, -1, nanoflann::metric_L2, false>;
105102

106-
std::vector<double> data_;
107-
std::unique_ptr<Eigen::Map<const Eigen::MatrixXd>> data_interface_;
103+
Eigen::MatrixXd data_;
108104
std::unique_ptr<KDTree_t> nanoflann_index_;
109-
size_t dimension_ = 0;
110-
size_t dataset_size_ = 0;
111105
};
112106

113107
} // namespace geometry

0 commit comments

Comments
 (0)