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
59 m_vertices = vertices;
61 constexpr int max_leaf = 10;
62 m_tree = std::make_unique<KDTree>(m_vertices.cols(), m_vertices, max_leaf);
63 m_tree->index_->buildIndex();
67 ClosestPoint query_closest_point(
const PointType& p)
const override
72 typename KDTree::IndexType out_idx[1];
74 auto num_valid_pts = m_tree->index_->knnSearch(p.data(), 1, out_idx, out_sq_dist);
76 if (num_valid_pts == 0) {
77 throw std::runtime_error(
"Nanoflann did not find any valid closest points.");
81 r.closest_point = m_vertices.row(out_idx[0]);
82 r.squared_distance = out_sq_dist[0];
88 std::vector<ClosestPoint> query_k_nearest_neighbours(
const PointType& p,
int k)
const override
91 std::vector<ClosestPoint> rs;
93 std::vector<typename KDTree::IndexType> out_idxs(k);
94 std::vector<Scalar> out_sq_dists(k);
96 m_tree->index_->knnSearch(p.data(), k, out_idxs.data(), out_sq_dists.data());
98 rs.resize(num_valid_pts);
99 for (
size_t i = 0; i < num_valid_pts; i++) {
101 rs[i].closest_point = m_vertices.row(out_idxs[i]);
102 rs[i].squared_distance = out_sq_dists[i];
109 std::vector<ClosestPoint> query_in_sphere_neighbours(
const PointType& p,
const Scalar radius)
113 std::vector<ClosestPoint> r;
115 std::vector<nanoflann::ResultItem<typename KDTree::IndexType, Scalar>> output;
116 nanoflann::SearchParameters params(
119 m_tree->index_->radiusSearch(p.data(), radius * radius, output, params);
121 r.reserve(output.size());
122 for (
const auto& entry : output) {
124 cp.closest_vertex_idx = (Index)entry.first;
125 cp.closest_point = m_vertices.row(cp.closest_vertex_idx);
126 cp.squared_distance = entry.second;
127 r.push_back(std::move(cp));
134 return Parent::default_batch_query_closest_point(query_pts);
139 VertexArray m_vertices;
140 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