22
33#include " math.h"
44
5+ #include < glm/gtc/type_ptr.hpp>
6+
57#include < chrono>
68#include < cstddef>
7- #include < inttypes.h>
89#include < iostream>
910#include < limits>
1011#include < vector>
@@ -14,14 +15,20 @@ namespace core
1415
1516ClosestPointQuery::ClosestPointQuery (const MeshPointCloud& mesh_point_cloud)
1617 : m_mesh_point_cloud(mesh_point_cloud)
18+ , m_tree_index(
19+ 3 ,
20+ mesh_point_cloud,
21+ nanoflann::KDTreeSingleIndexAdaptorParams (10 /* tree leaf max size */ ))
1722{
1823 // Start a timer to know how long it takes to build the query object.
1924 auto timer_start = std::chrono::high_resolution_clock::now ();
2025
26+ m_tree_index.buildIndex ();
27+
2128 auto timer_stop = std::chrono::high_resolution_clock::now ();
2229 auto process_time = std::chrono::duration_cast<std::chrono::milliseconds>(timer_stop - timer_start).count ();
2330
24- std::printf ( " Generated mesh query tree in % " PRId64 " ms." , process_time) ;
31+ std::cout << " Generated mesh query tree in " << process_time << " ms.\n " ;
2532}
2633
2734bool ClosestPointQuery::get_closest_point (
@@ -31,43 +38,38 @@ bool ClosestPointQuery::get_closest_point(
3138{
3239 assert (max_distance > 0 .0f );
3340
34- const std::size_t triangle_count = m_mesh_point_cloud.kdtree_get_point_count () / 3 ;
35-
36- // => Naive implementation.
37- // 1. Go through each triangle
38- // 2. Compute the closest point on a particular mesh
39- // 3. Keep the closest
40- float closest_distance2 = std::numeric_limits<float >::max ();
41- result = { 0 , 0 , 0 };
42- bool found = false ;
43-
44- for (std::size_t triangle_index = 0 ; triangle_index < triangle_count; ++triangle_index)
45- {
46- const glm::vec3& v1 = m_mesh_point_cloud.kdtree_get_pt (triangle_index * 3 );
47- const glm::vec3& v2 = m_mesh_point_cloud.kdtree_get_pt (triangle_index * 3 + 1 );
48- const glm::vec3& v3 = m_mesh_point_cloud.kdtree_get_pt (triangle_index * 3 + 2 );
49-
50- bool success = false ;
51- const glm::vec3 p = closest_point_in_triangle (
52- query_point,
53- v1,
54- v2,
55- v3);
56-
57- const float distance2_to_triangle = distance2 (p, query_point);
58-
59- if (distance2_to_triangle > max_distance)
60- continue ;
61-
62- if (distance2_to_triangle < closest_distance2)
63- {
64- closest_distance2 = distance2_to_triangle;
65- result = p;
66- found = true ;
67- }
68- }
69-
70- return found;
41+ static nanoflann::SearchParams search_params (
42+ 32 , // ignored param
43+ 0 .0f , // epsilon
44+ true ); // true means we want results to be sorted by squared dist
45+
46+ std::vector<std::size_t > ret_index (1 );
47+ std::vector<float > out_dist_sqr (1 );
48+ const std::size_t num_results =
49+ m_tree_index.knnSearch (
50+ glm::value_ptr (query_point),
51+ 1 , // We only want 1 result, the closest one.
52+ &ret_index[0 ],
53+ &out_dist_sqr[0 ]);
54+
55+ if (num_results == 0 )
56+ return false ;
57+
58+ glm::vec3 v1, v2, v3;
59+ m_mesh_point_cloud.get_triangle (ret_index[0 ], v1, v2, v3);
60+
61+ result = closest_point_in_triangle (
62+ query_point,
63+ v1,
64+ v2,
65+ v3);
66+
67+ const float distance2_to_triangle = distance2 (result, query_point);
68+
69+ if (distance2_to_triangle > max_distance)
70+ return false ;;
71+
72+ return true ;
7173}
7274
7375} // namespace core
0 commit comments