Reputation: 11
I have several sets of points and I want to quickly compute distances to these sets. In the case of only one set I have been successfully using nanoflann for the task. But when trying to define a vector of KDTree
I get an error. This is a minimal example:
#include <string>
#include <nanoflann.hpp>
using std::string;
using std::vector;
template <typename T=double>
struct Point {
T x;
T y;
T z;
};
template <typename T>
struct PointCloud{
vector<Point<double>> points;
inline size_t kdtree_get_point_count() const {
return points.size();
}
inline double kdtree_get_pt(const size_t idx, int dim) const {
switch(dim) {
case 0:
return points[idx].x;
case 1:
return points[idx].y;
case 2:
return points[idx].z;
default:
return static_cast<T>(0.0);
}
}
template <class BBOX>
bool kdtree_get_bbox(BBOX& /* bb */) const {
return false;
}
};
using KDTree = nanoflann::KDTreeSingleIndexAdaptor<
nanoflann::L2_Simple_Adaptor<double, PointCloud<double>>,
PointCloud<double>, 3>;
int main() {
vector<Point<double>> points1 {{0.0, 0.0, 0.0}, {0.0, 1.0, 1.0}, {1.0, 0.0, -1.0}};
vector<Point<double>> points2 {{0.3, 0.4, 0.0}, {0.0, 1.0, 1.0}, {1.0, 0.0, -1.0}};
vector<Point<double>> points3 {{0.0, 0.8, 0.9}, {0.3, 1.0, 1.1}, {1.9, 0.3, -1.0}};
vector<vector<Point<double>>> points_sets {points1, points2, points3};
vector<KDTree> kdtrees;
nanoflann::KDTreeSingleIndexAdaptorParams params{10};
for(int index {0}; index < 3; index++) {
PointCloud<double> pc {};
pc.points = points_sets[index];
KDTree kdtree(3, pc, params);
kdtrees.push_back(kdtree);
kdtrees.back().buildIndex();
}
}
and I get this error message:
In file included from /usr/include/x86_64-linux-gnu/c++/11/bits/c++allocator.h:33,
from /usr/include/c++/11/bits/allocator.h:46,
from /usr/include/c++/11/string:41,
from src/main.cpp:1:
/usr/include/c++/11/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>; _Args = {const nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double>, double, unsigned int>, PointCloud<double>, 3, unsigned int>&}; _Tp = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>]’:
/usr/include/c++/11/bits/alloc_traits.h:516:17: required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>; _Args = {const nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double>, double, unsigned int>, PointCloud<double>, 3, unsigned int>&}; _Tp = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3> >]’
/usr/include/c++/11/bits/stl_vector.h:1192:30: required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>; _Alloc = std::allocator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3> >; std::vector<_Tp, _Alloc>::value_type = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>]’
src/main.cpp:55:26: required from here
/usr/include/c++/11/ext/new_allocator.h:162:11: error: use of deleted function ‘nanoflann::KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, AccessorType>::KDTreeSingleIndexAdaptor(const nanoflann::KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, AccessorType>&) [with Distance = nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >; DatasetAdaptor = PointCloud<double>; int DIM = 3; AccessorType = unsigned int]’
162 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/main.cpp:2:
/usr/include/nanoflann.hpp:1284:5: note: declared here
1284 | KDTreeSingleIndexAdaptor(const KDTreeSingleIndexAdaptor<
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/vector:66,
from /usr/include/c++/11/functional:62,
from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
from /usr/include/c++/11/algorithm:74,
from /usr/include/nanoflann.hpp:47,
from src/main.cpp:2:
/usr/include/c++/11/bits/stl_uninitialized.h: In instantiation of ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>*>; _ForwardIterator = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>*]’:
/usr/include/c++/11/bits/stl_uninitialized.h:333:37: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>*>; _ForwardIterator = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>*; _Tp = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>]’
/usr/include/c++/11/bits/stl_uninitialized.h:355:2: required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>*; _ForwardIterator = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>*; _Allocator = std::allocator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3> >]’
/usr/include/c++/11/bits/vector.tcc:474:3: required from ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double>, double, unsigned int>, PointCloud<double>, 3, unsigned int>&}; _Tp = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>; _Alloc = std::allocator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3> >; std::vector<_Tp, _Alloc>::iterator = std::vector<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3> >::iterator]’
/usr/include/c++/11/bits/stl_vector.h:1198:21: required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>; _Alloc = std::allocator<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3> >; std::vector<_Tp, _Alloc>::value_type = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PointCloud<double> >, PointCloud<double>, 3>]’
src/main.cpp:55:26: required from here
/usr/include/c++/11/bits/stl_uninitialized.h:138:72: error: static assertion failed: result type must be constructible from value type of input range
138 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
| ^~~~~
/usr/include/c++/11/bits/stl_uninitialized.h:138:72: note: ‘std::integral_constant<bool, false>::value’ evaluates to false
I think the problem is that the KDTree
have the copy constructor deleted, so I tried using emplace_back()
instead of push_back with the same parameters I would use to make a single KDTree
but that doesn't work either.
Upvotes: 1
Views: 101