33#include < set>
44#include < cstdint>
55#include < thread>
6+ #include < iostream>
67
78typedef struct thread_struct {
89 void * kd_tree;
@@ -15,6 +16,8 @@ typedef struct thread_struct {
1516 size_t end;
1617 double search_radius;
1718 bool small;
19+ bool option;
20+ size_t k;
1821} thread_args;
1922
2023template <typename scalar_t >
@@ -37,7 +40,7 @@ void thread_routine(thread_args* targs) {
3740 double search_radius = (double ) targs->search_radius ;
3841 size_t start = targs->start ;
3942 size_t end = targs->end ;
40-
43+ auto k = targs-> k ;
4144 for (size_t i = start; i < end; i++) {
4245
4346 std::vector<scalar_t > p0 = *(((*pcd_query).pts )[i]);
@@ -46,11 +49,23 @@ void thread_routine(thread_args* targs) {
4649 std::copy (p0.begin (), p0.end (), query_pt);
4750 (*matches)[i].reserve (*max_count);
4851 std::vector<std::pair<size_t , scalar_t > > ret_matches;
52+ std::vector<size_t >* knn_ret_matches = new std::vector<size_t >(k);
53+ std::vector<scalar_t >* knn_dist_matches = new std::vector<scalar_t >(k);
4954
5055 tree_m->lock ();
5156
52- const size_t nMatches = index->radiusSearch (query_pt, (scalar_t )(search_radius+eps), ret_matches, nanoflann::SearchParams ());
53-
57+ size_t nMatches;
58+ if (targs->option ){
59+ nMatches = index->radiusSearch (query_pt, (scalar_t )(search_radius+eps), ret_matches, nanoflann::SearchParams ());
60+ }
61+ else {
62+ nMatches = index->knnSearch (query_pt, k, &(*knn_ret_matches)[0 ],&(* knn_dist_matches)[0 ]);
63+ auto temp = new std::vector<std::pair<size_t , scalar_t > >((*knn_dist_matches).size ());
64+ for (size_t j = 0 ; j < (*knn_ret_matches).size (); j++){
65+ (*temp)[j] = std::make_pair ( (*knn_ret_matches)[j],(*knn_dist_matches)[j] );
66+ }
67+ ret_matches = *temp;
68+ }
5469 tree_m->unlock ();
5570
5671 (*matches)[i] = ret_matches;
@@ -67,7 +82,8 @@ void thread_routine(thread_args* targs) {
6782
6883template <typename scalar_t >
6984size_t nanoflann_neighbors (std::vector<scalar_t >& queries, std::vector<scalar_t >& supports,
70- std::vector<size_t >*& neighbors_indices, double radius, int dim, int64_t max_num, int64_t n_threads){
85+ std::vector<size_t >*& neighbors_indices, double radius, int dim,
86+ int64_t max_num, int64_t n_threads, int64_t k, int option){
7187
7288 const scalar_t search_radius = static_cast <scalar_t >(radius*radius);
7389
@@ -120,9 +136,21 @@ size_t nanoflann_neighbors(std::vector<scalar_t>& queries, std::vector<scalar_t>
120136
121137 (*list_matches)[i0].reserve (*max_count);
122138 std::vector<std::pair<size_t , scalar_t > > ret_matches;
139+ std::vector<size_t >* knn_ret_matches = new std::vector<size_t >(k);
140+ std::vector<scalar_t >* knn_dist_matches = new std::vector<scalar_t >(k);
123141
124- const size_t nMatches = index->radiusSearch (query_pt, (scalar_t )(search_radius+eps), ret_matches, search_params);
125-
142+ size_t nMatches;
143+ if (!!(option)){
144+ nMatches = index->radiusSearch (query_pt, (scalar_t )(search_radius+eps), ret_matches, search_params);
145+ }
146+ else {
147+ nMatches = index->knnSearch (query_pt, (size_t )k, &(*knn_ret_matches)[0 ],&(* knn_dist_matches)[0 ]);
148+ auto temp = new std::vector<std::pair<size_t , scalar_t > >((*knn_dist_matches).size ());
149+ for (size_t j = 0 ; j < (*knn_ret_matches).size (); j++){
150+ (*temp)[j] = std::make_pair ( (*knn_ret_matches)[j],(*knn_dist_matches)[j] );
151+ }
152+ ret_matches = *temp;
153+ }
126154 (*list_matches)[i0] = ret_matches;
127155 if (*max_count < nMatches) *max_count = nMatches;
128156 i0++;
@@ -171,6 +199,8 @@ size_t nanoflann_neighbors(std::vector<scalar_t>& queries, std::vector<scalar_t>
171199 else {
172200 targs->small = false ;
173201 }
202+ targs->option = !!(option);
203+ targs->k = k;
174204 std::thread* temp = new std::thread (thread_routine<scalar_t >, targs);
175205 tid[t] = temp;
176206 }
@@ -220,7 +250,7 @@ size_t batch_nanoflann_neighbors (std::vector<scalar_t>& queries,
220250 std::vector<long >& q_batches,
221251 std::vector<long >& s_batches,
222252 std::vector<size_t >*& neighbors_indices,
223- double radius, int dim, int64_t max_num){
253+ double radius, int dim, int64_t max_num, int64_t k, int option ){
224254
225255
226256 // indices
@@ -292,14 +322,22 @@ size_t batch_nanoflann_neighbors (std::vector<scalar_t>& queries,
292322 // Initial guess of neighbors size
293323 all_inds_dists[i0].reserve (max_count);
294324 // Find neighbors
295- size_t nMatches = index->radiusSearch (query_pt, r2+eps, all_inds_dists[i0], search_params);
296- // Update max count
297-
298- std::vector<std::pair<size_t , float > > indices_dists;
299- nanoflann::RadiusResultSet<float ,size_t > resultSet (r2, indices_dists);
300-
301- index->findNeighbors (resultSet, query_pt, search_params);
302325
326+ size_t nMatches;
327+ if (!!option) {
328+ nMatches = index->radiusSearch (query_pt, r2+eps, all_inds_dists[i0], search_params);
329+ // Update max count
330+ }
331+ else {
332+ std::vector<size_t >* knn_ret_matches = new std::vector<size_t >(k);
333+ std::vector<scalar_t >* knn_dist_matches = new std::vector<scalar_t >(k);
334+ nMatches = index->knnSearch (query_pt, (size_t )k, &(*knn_ret_matches)[0 ],&(*knn_dist_matches)[0 ]);
335+ auto temp = new std::vector<std::pair<size_t , scalar_t > >((*knn_dist_matches).size ());
336+ for (size_t j = 0 ; j < (*knn_ret_matches).size (); j++){
337+ (*temp)[j] = std::make_pair ( (*knn_ret_matches)[j],(*knn_dist_matches)[j] );
338+ }
339+ all_inds_dists[i0] = *temp;
340+ }
303341 if (nMatches > max_count)
304342 max_count = nMatches;
305343 // Increment query idx
0 commit comments