30 using Parent = BVH<_VertexArray, _ElementArray>;
31 using VertexArray =
typename Parent::VertexArray;
32 using ElementArray =
typename Parent::ElementArray;
33 using Scalar =
typename Parent::Scalar;
34 using Index =
typename Parent::Index;
35 using PointType =
typename Parent::PointType;
37 using KDTree = nanoflann::KDTreeEigenMatrixAdaptor<VertexArray>;
40 BVHType
get_bvh_type()
const override {
return BVHType::NANOFLANN; }
43 bool does_support_triangles()
const override {
return false; }
44 bool does_support_lines()
const override {
return false; }
46 void build(
const VertexArray&,
const ElementArray&)
override
51 void build(
const VertexArray& vertices)
override
55 m_vertices = vertices;
57 constexpr int max_leaf = 10;
58 m_tree = std::make_unique<KDTree>(m_vertices.cols(), m_vertices, max_leaf);
59 m_tree->index_->buildIndex();
63 ClosestPoint query_closest_point(
const PointType& p)
const override
68 typename KDTree::IndexType out_idx[1];
70 auto num_valid_pts = m_tree->index_->knnSearch(p.data(), 1, out_idx, out_sq_dist);
72 if (num_valid_pts == 0) {
73 throw std::runtime_error(
"Nanoflann did not find any valid closest points.");
77 r.closest_point = m_vertices.row(out_idx[0]);
78 r.squared_distance = out_sq_dist[0];
84 std::vector<ClosestPoint> query_k_nearest_neighbours(
const PointType& p,
int k)
const override
87 std::vector<ClosestPoint> rs;
89 std::vector<typename KDTree::IndexType> out_idxs(k);
90 std::vector<Scalar> out_sq_dists(k);
92 m_tree->index_->knnSearch(p.data(), k, out_idxs.data(), out_sq_dists.data());
94 rs.resize(num_valid_pts);
95 for (
size_t i = 0; i < num_valid_pts; i++) {
97 rs[i].closest_point = m_vertices.row(out_idxs[i]);
98 rs[i].squared_distance = out_sq_dists[i];
105 std::vector<ClosestPoint> query_in_sphere_neighbours(
const PointType& p,
const Scalar radius)
109 std::vector<ClosestPoint> r;
111 std::vector<nanoflann::ResultItem<typename KDTree::IndexType, Scalar>> output;
112 nanoflann::SearchParameters params(
115 m_tree->index_->radiusSearch(p.data(), radius * radius, output, params);
117 r.reserve(output.size());
118 for (
const auto& entry : output) {
120 cp.closest_vertex_idx = (Index)entry.first;
121 cp.closest_point = m_vertices.row(cp.closest_vertex_idx);
122 cp.squared_distance = entry.second;
123 r.push_back(std::move(cp));
130 return Parent::default_batch_query_closest_point(query_pts);
135 VertexArray m_vertices;
136 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:50