34 using Parent = BVH<_VertexArray, _ElementArray>;
35 using VertexArray =
typename Parent::VertexArray;
36 using ElementArray =
typename Parent::ElementArray;
37 using Scalar =
typename Parent::Scalar;
38 using Index =
typename Parent::Index;
39 using PointType =
typename Parent::PointType;
41 using KDTree = nanoflann::KDTreeEigenMatrixAdaptor<VertexArray>;
44 BVHType
get_bvh_type()
const override {
return BVHType::NANOFLANN; }
47 bool does_support_triangles()
const override {
return false; }
48 bool does_support_lines()
const override {
return false; }
50 void build(
const VertexArray&,
const ElementArray&)
override
55 void build(
const VertexArray& vertices)
override
57 m_vertices = vertices;
62 void build(VertexArray&& vertices)
64 m_vertices = std::move(vertices);
69 ClosestPoint query_closest_point(
const PointType& p)
const override
74 typename KDTree::IndexType out_idx[1];
76 auto num_valid_pts = m_tree->index_->knnSearch(p.data(), 1, out_idx, out_sq_dist);
78 if (num_valid_pts == 0) {
79 throw std::runtime_error(
"Nanoflann did not find any valid closest points.");
83 r.closest_point = m_vertices.row(out_idx[0]);
84 r.squared_distance = out_sq_dist[0];
90 std::vector<ClosestPoint> query_k_nearest_neighbours(
const PointType& p,
int k)
const override
93 std::vector<ClosestPoint> rs;
95 std::vector<typename KDTree::IndexType> out_idxs(k);
96 std::vector<Scalar> out_sq_dists(k);
98 m_tree->index_->knnSearch(p.data(), k, out_idxs.data(), out_sq_dists.data());
100 rs.resize(num_valid_pts);
101 for (
size_t i = 0; i < num_valid_pts; i++) {
103 rs[i].closest_point = m_vertices.row(out_idxs[i]);
104 rs[i].squared_distance = out_sq_dists[i];
111 std::vector<ClosestPoint> query_in_sphere_neighbours(
const PointType& p,
const Scalar radius)
115 std::vector<ClosestPoint> r;
117 std::vector<nanoflann::ResultItem<typename KDTree::IndexType, Scalar>> output;
118 nanoflann::SearchParameters params(
121 m_tree->index_->radiusSearch(p.data(), radius * radius, output, params);
123 r.reserve(output.size());
124 for (
const auto& entry : output) {
126 cp.closest_vertex_idx = (Index)entry.first;
127 cp.closest_point = m_vertices.row(cp.closest_vertex_idx);
128 cp.squared_distance = entry.second;
129 r.push_back(std::move(cp));
136 return Parent::default_batch_query_closest_point(query_pts);
143 constexpr int max_leaf = 10;
144 m_tree = std::make_unique<KDTree>(m_vertices.cols(), m_vertices, max_leaf);
145 m_tree->index_->buildIndex();
148 VertexArray m_vertices;
149 std::unique_ptr<KDTree> m_tree;
constexpr auto safe_cast(SourceType value) -> std::enable_if_t<!std::is_same< SourceType, TargetType >::value, TargetType >
Perform safe cast from SourceType to TargetType, where "safe" means:
Definition safe_cast.h:51