40
40
41
41
#include < pcl/search/search.h>
42
42
43
+ namespace pcl {
44
+ namespace search {
43
45
// /////////////////////////////////////////////////////////////////////////////////////////
44
46
template <typename PointT>
45
- pcl::search:: Search<PointT>::Search (const std::string& name, bool sorted)
47
+ Search<PointT>::Search (const std::string& name, bool sorted)
46
48
: input_ ()
47
49
, sorted_results_ (sorted)
48
50
, name_ (name)
@@ -51,28 +53,28 @@ pcl::search::Search<PointT>::Search (const std::string& name, bool sorted)
51
53
52
54
// /////////////////////////////////////////////////////////////////////////////////////////
53
55
template <typename PointT> const std::string&
54
- pcl::search:: Search<PointT>::getName () const
56
+ Search<PointT>::getName () const
55
57
{
56
58
return (name_);
57
59
}
58
60
59
61
// /////////////////////////////////////////////////////////////////////////////////////////
60
62
template <typename PointT> void
61
- pcl::search:: Search<PointT>::setSortedResults (bool sorted)
63
+ Search<PointT>::setSortedResults (bool sorted)
62
64
{
63
65
sorted_results_ = sorted;
64
66
}
65
67
66
68
// /////////////////////////////////////////////////////////////////////////////////////////
67
69
template <typename PointT> bool
68
- pcl::search:: Search<PointT>::getSortedResults ()
70
+ Search<PointT>::getSortedResults () const
69
71
{
70
72
return (sorted_results_);
71
73
}
72
74
73
75
// /////////////////////////////////////////////////////////////////////////////////////////
74
76
template <typename PointT> void
75
- pcl::search:: Search<PointT>::setInputCloud (
77
+ Search<PointT>::setInputCloud (
76
78
const PointCloudConstPtr& cloud, const IndicesConstPtr &indices)
77
79
{
78
80
input_ = cloud;
@@ -82,7 +84,7 @@ pcl::search::Search<PointT>::setInputCloud (
82
84
83
85
// /////////////////////////////////////////////////////////////////////////////////////////
84
86
template <typename PointT> int
85
- pcl::search:: Search<PointT>::nearestKSearch (
87
+ Search<PointT>::nearestKSearch (
86
88
const PointCloud &cloud, index_t index, int k,
87
89
Indices &k_indices, std::vector<float > &k_sqr_distances) const
88
90
{
@@ -92,7 +94,7 @@ pcl::search::Search<PointT>::nearestKSearch (
92
94
93
95
// /////////////////////////////////////////////////////////////////////////////////////////
94
96
template <typename PointT> int
95
- pcl::search:: Search<PointT>::nearestKSearch (
97
+ Search<PointT>::nearestKSearch (
96
98
index_t index, int k,
97
99
Indices &k_indices,
98
100
std::vector<float > &k_sqr_distances) const
@@ -110,7 +112,7 @@ pcl::search::Search<PointT>::nearestKSearch (
110
112
111
113
// /////////////////////////////////////////////////////////////////////////////////////////
112
114
template <typename PointT> void
113
- pcl::search:: Search<PointT>::nearestKSearch (
115
+ Search<PointT>::nearestKSearch (
114
116
const PointCloud& cloud, const Indices& indices,
115
117
int k, std::vector<Indices>& k_indices,
116
118
std::vector< std::vector<float > >& k_sqr_distances) const
@@ -133,7 +135,7 @@ pcl::search::Search<PointT>::nearestKSearch (
133
135
134
136
// /////////////////////////////////////////////////////////////////////////////////////////
135
137
template <typename PointT> int
136
- pcl::search:: Search<PointT>::radiusSearch (
138
+ Search<PointT>::radiusSearch (
137
139
const PointCloud &cloud, index_t index, double radius,
138
140
Indices &k_indices, std::vector<float > &k_sqr_distances,
139
141
unsigned int max_nn) const
@@ -144,7 +146,7 @@ pcl::search::Search<PointT>::radiusSearch (
144
146
145
147
// /////////////////////////////////////////////////////////////////////////////////////////
146
148
template <typename PointT> int
147
- pcl::search:: Search<PointT>::radiusSearch (
149
+ Search<PointT>::radiusSearch (
148
150
index_t index, double radius, Indices &k_indices,
149
151
std::vector<float > &k_sqr_distances, unsigned int max_nn ) const
150
152
{
@@ -159,7 +161,7 @@ pcl::search::Search<PointT>::radiusSearch (
159
161
160
162
// /////////////////////////////////////////////////////////////////////////////////////////
161
163
template <typename PointT> void
162
- pcl::search:: Search<PointT>::radiusSearch (
164
+ Search<PointT>::radiusSearch (
163
165
const PointCloud& cloud,
164
166
const Indices& indices,
165
167
double radius,
@@ -185,7 +187,7 @@ pcl::search::Search<PointT>::radiusSearch (
185
187
186
188
// /////////////////////////////////////////////////////////////////////////////////////////
187
189
template <typename PointT> void
188
- pcl::search:: Search<PointT>::sortResults (
190
+ Search<PointT>::sortResults (
189
191
Indices& indices, std::vector<float >& distances) const
190
192
{
191
193
Indices order (indices.size ());
@@ -205,6 +207,105 @@ pcl::search::Search<PointT>::sortResults (
205
207
sort (distances.begin (), distances.end ());
206
208
}
207
209
210
+ template <typename PointT>
211
+ std::size_t
212
+ Search<PointT>::makeNonTrivial(Indices& k_indices,
213
+ std::vector<float >& k_sqr_distances) const
214
+ {
215
+ assert (k_indices.size () == k_sqr_distances.size ());
216
+ if (k_indices.empty ()) {
217
+ return 0 ;
218
+ }
219
+
220
+ if (getSortedResults ()) {
221
+ std::size_t num_zero_elements = 0 ;
222
+ // distances are sorted, so if we encounter a non-zero, we can bail early
223
+ for (const auto & distance : k_sqr_distances) {
224
+ if (distance) {
225
+ break ;
226
+ }
227
+ ++num_zero_elements;
228
+ }
229
+ // We need to remove `num_zero_elements` initial elements
230
+ k_indices.erase (k_indices.begin (), k_indices.begin () + num_zero_elements);
231
+ k_sqr_distances.erase (k_sqr_distances.begin (),
232
+ k_sqr_distances.begin () + num_zero_elements);
233
+ }
234
+ else {
235
+ const auto zero_distance_it =
236
+ std::find (k_sqr_distances.begin (), k_sqr_distances.end (), 0 );
237
+ const auto zero_distance_idx =
238
+ std::distance (k_sqr_distances.begin (), zero_distance_it);
239
+ // From zero_distance_idx, we start removing elements
240
+ std::size_t last_good_idx = zero_distance_idx - 1 ;
241
+ for (std::size_t i = zero_distance_idx + 1 ; i < k_sqr_distances.size (); ++i) {
242
+ if (k_sqr_distances[i] == 0 ) {
243
+ continue ;
244
+ }
245
+ ++last_good_idx;
246
+ k_sqr_distances[last_good_idx] = k_sqr_distances[i];
247
+ k_indices[last_good_idx] = k_indices[i];
248
+ }
249
+ // We need to remove elements after `last_good_idx`
250
+ const auto new_end = last_good_idx + 1 ;
251
+ k_indices.erase (k_indices.begin () + new_end, k_indices.end ());
252
+ k_sqr_distances.erase (k_sqr_distances.begin () + new_end, k_sqr_distances.end ());
253
+ }
254
+ assert (k_indices.size () == k_sqr_distances.size ());
255
+ return k_indices.size ();
256
+ }
257
+
258
+ template <typename PointT>
259
+ std::size_t
260
+ Search<PointT>::makeNonTrivial(index_t index,
261
+ Indices& k_indices,
262
+ std::vector<float >& k_sqr_distances) const
263
+ {
264
+ assert (k_indices.size () == k_sqr_distances.size ());
265
+ if (k_indices.empty ()) {
266
+ return 0 ;
267
+ }
268
+
269
+ if (getSortedResults ()) {
270
+ std::size_t same_idx_elements = 0 ;
271
+ // distances are sorted, so if we encounter a non-zero, we can bail early
272
+ for (const auto & idx : k_indices) {
273
+ if (idx == index) {
274
+ break ;
275
+ }
276
+ ++same_idx_elements;
277
+ }
278
+ // We need to remove `same_idx_elements` initial elements
279
+ k_indices.erase (k_indices.begin (), k_indices.begin () + same_idx_elements);
280
+ k_sqr_distances.erase (k_sqr_distances.begin (),
281
+ k_sqr_distances.begin () + same_idx_elements);
282
+ }
283
+ else {
284
+ const auto same_idx_it =
285
+ std::find (k_indices.begin (), k_indices.end (), index);
286
+ const auto same_idx = std::distance (k_indices.begin (), same_idx_it);
287
+ // From same_idx, we start removing elements
288
+ std::size_t last_good_idx = same_idx - 1 ;
289
+ for (std::size_t i = same_idx + 1 ; i < k_indices.size (); ++i) {
290
+ if (k_indices[i] == index) {
291
+ continue ;
292
+ }
293
+ ++last_good_idx;
294
+ k_sqr_distances[last_good_idx] = k_sqr_distances[i];
295
+ k_indices[last_good_idx] = k_indices[i];
296
+ }
297
+ // We need to remove elements after `last_good_idx`
298
+ const auto new_end = last_good_idx + 1 ;
299
+ k_indices.erase (k_indices.begin () + new_end, k_indices.end ());
300
+ k_sqr_distances.erase (k_sqr_distances.begin () + new_end, k_sqr_distances.end ());
301
+ }
302
+
303
+ assert (k_indices.size () == k_sqr_distances.size ());
304
+ return k_indices.size ();
305
+ }
306
+ } // namespace search
307
+ } // namespace pcl
308
+
208
309
#define PCL_INSTANTIATE_Search (T ) template class PCL_EXPORTS pcl::search::Search<T>;
209
310
210
311
#endif // #ifndef _PCL_SEARCH_SEARCH_IMPL_HPP_
0 commit comments