neighbors.cpp 2.61 KB
Newer Older
Alexander Liao's avatar
Alexander Liao committed
1

2
// 3D Version https://github.com/HuguesTHOMAS/KPConv
Alexander Liao's avatar
Alexander Liao committed
3
4
5
6
7
8
9
10
11
12
13
14
15

#include "neighbors.h"

template<typename scalar_t>
int nanoflann_neighbors(vector<scalar_t>& queries, vector<scalar_t>& supports,
			vector<long>& neighbors_indices, float radius, int dim, int max_num){

	// Initiate variables
	// ******************

	const scalar_t search_radius = static_cast<scalar_t>(radius*radius);

	// Counting vector
16
	size_t max_count = 1;
Alexander Liao's avatar
Alexander Liao committed
17
18
19
20
21
22
23
24
25
26
27
28

	// Nanoflann related variables
	// ***************************

	// CLoud variable
	PointCloud<scalar_t> pcd;
	pcd.set(supports, dim);
	//Cloud query
	PointCloud<scalar_t> pcd_query;
	pcd_query.set(queries, dim);

	// Tree parameters
29
	nanoflann::KDTreeSingleIndexAdaptorParams tree_params(15 /* max leaf */);
Alexander Liao's avatar
Alexander Liao committed
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

	// KDTree type definition
	typedef nanoflann::KDTreeSingleIndexAdaptor< nanoflann::L2_Adaptor<scalar_t, PointCloud<scalar_t> > , PointCloud<scalar_t>> my_kd_tree_t;

	// Pointer to trees
	my_kd_tree_t* index;
	index = new my_kd_tree_t(dim, pcd, tree_params);
	index->buildIndex();
	// Search neigbors indices
	// ***********************

	// Search params
	nanoflann::SearchParams search_params;
	search_params.sorted = true;
	std::vector< std::vector<std::pair<size_t, scalar_t> > > list_matches(pcd_query.pts.size());

	float eps = 0.00001;

48
49
50
	// indices
	size_t i0 = 0;

Alexander Liao's avatar
Alexander Liao committed
51
52
53
	for (auto& p0 : pcd_query.pts){

		// Find neighbors
Alexander Liao's avatar
Alexander Liao committed
54
		scalar_t* query_pt = new scalar_t[dim];
Alexander Liao's avatar
Alexander Liao committed
55
56
57
58
59
60
61
62
		std::copy(p0.begin(), p0.end(), query_pt); 

		//for(int i=0; i < p0.size(); i++)
		//std::cout << query_pt[i] << '\n';

		list_matches[i0].reserve(max_count);
		std::vector<std::pair<size_t, scalar_t> > ret_matches;

Alexander Liao's avatar
Alexander Liao committed
63
		const size_t nMatches = index->radiusSearch(query_pt, search_radius+eps, ret_matches, search_params);
Alexander Liao's avatar
Alexander Liao committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
		list_matches[i0] = ret_matches;
		if(max_count < nMatches) max_count = nMatches;
		i0++;


		// Get worst (furthest) point, without sorting:
		
		// cout << "\n neighbors: " << nMatches << "\n";

		// Get worst (furthest) point, without sorting:
		// for(int i=0; i < ret_matches.size(); i++)
		// std::cout << ret_matches.at(i) << '\n';

	}
	// Reserve the memory
	if(max_num > 0) {
		max_count = max_num;
	}
	
83
	size_t size = 0; // total number of edges
Alexander Liao's avatar
Alexander Liao committed
84
85
86
87
88
89
	for (auto& inds : list_matches){
		if(inds.size() <= max_count)
			size += inds.size();
		else
			size += max_count;
	}
90

Alexander Liao's avatar
Alexander Liao committed
91
	neighbors_indices.resize(size*2);
92
93
	size_t i1 = 0; // index of the query points
	size_t u = 0; // curent index of the neighbors_indices
Alexander Liao's avatar
Alexander Liao committed
94
	for (auto& inds : list_matches){
95
		for (size_t j = 0; j < max_count; j++){
Alexander Liao's avatar
Alexander Liao committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
			if(j < inds.size()){
				neighbors_indices[u] = inds[j].first;
				neighbors_indices[u + 1] = i1;
				u += 2;
			}
		}
		i1++;
	}

	return max_count;




110
}