@@ -41,7 +41,7 @@ struct IncrementalVoxelMap {
41
41
42
42
// / @brief Constructor.
43
43
// / @param leaf_size Voxel size
44
- explicit IncrementalVoxelMap (double leaf_size) : inv_leaf_size(1.0 / leaf_size), lru_horizon(100 ), lru_clear_cycle(10 ), lru_counter(0 ) {}
44
+ explicit IncrementalVoxelMap (double leaf_size) : inv_leaf_size(1.0 / leaf_size), lru_horizon(100 ), lru_clear_cycle(10 ), lru_counter(0 ) { set_search_offsets ( 1 ); }
45
45
46
46
// / @brief Number of points in the voxelmap.
47
47
size_t size () const { return flat_voxels.size (); }
@@ -95,18 +95,24 @@ struct IncrementalVoxelMap {
95
95
// / @param sq_dist Squared distance to the nearest neighbor
96
96
// / @return Number of found points (0 or 1)
97
97
size_t nearest_neighbor_search (const Eigen::Vector4d& pt, size_t * index, double * sq_dist) const {
98
- const Eigen::Vector3i coord = fast_floor (pt * inv_leaf_size).template head <3 >();
99
- const auto found = voxels.find (coord);
100
- if (found == voxels.end ()) {
101
- return 0 ;
102
- }
98
+ const Eigen::Vector3i center = fast_floor (pt * inv_leaf_size).template head <3 >();
99
+ size_t voxel_index = 0 ;
100
+ const auto index_transform = [&](size_t i) { return calc_index (voxel_index, i); };
101
+ KnnResult<1 , decltype (index_transform)> result (index , sq_dist, -1 , index_transform);
102
+
103
+ for (const auto & offset : search_offsets) {
104
+ const Eigen::Vector3i coord = center + offset;
105
+ const auto found = voxels.find (coord);
106
+ if (found == voxels.end ()) {
107
+ continue ;
108
+ }
103
109
104
- const size_t voxel_index = found->second ;
105
- const auto & voxel = flat_voxels[voxel_index]->second ;
110
+ voxel_index = found->second ;
111
+ const auto & voxel = flat_voxels[voxel_index]->second ;
112
+
113
+ traits::Traits<VoxelContents>::knn_search (voxel, pt, result);
114
+ }
106
115
107
- const auto index_transform = [=](size_t i) { return calc_index (voxel_index, i); };
108
- KnnResult<1 , decltype (index_transform)> result (index , sq_dist, -1 , index_transform);
109
- traits::Traits<VoxelContents>::knn_search (voxel, pt, result);
110
116
return result.num_found ();
111
117
}
112
118
@@ -117,18 +123,25 @@ struct IncrementalVoxelMap {
117
123
// / @param k_sq_dists Squared distances to nearest neighbors
118
124
// / @return Number of found points
119
125
size_t knn_search (const Eigen::Vector4d& pt, size_t k, size_t * k_indices, double * k_sq_dists) const {
120
- const Eigen::Vector3i coord = fast_floor (pt * inv_leaf_size).template head <3 >();
121
- const auto found = voxels.find (coord);
122
- if (found == voxels.end ()) {
123
- return 0 ;
124
- }
126
+ const Eigen::Vector3i center = fast_floor (pt * inv_leaf_size).template head <3 >();
125
127
126
- const size_t voxel_index = found->second ;
127
- const auto & voxel = flat_voxels[voxel_index]->second ;
128
-
129
- const auto index_transform = [=](size_t i) { return calc_index (voxel_index, i); };
128
+ size_t voxel_index = 0 ;
129
+ const auto index_transform = [&](size_t i) { return calc_index (voxel_index, i); };
130
130
KnnResult<-1 , decltype (index_transform)> result (k_indices, k_sq_dists, k, index_transform);
131
- traits::Traits<VoxelContents>::knn_search (voxel, pt, result);
131
+
132
+ for (const auto & offset : search_offsets) {
133
+ const Eigen::Vector3i coord = center + offset;
134
+ const auto found = voxels.find (coord);
135
+ if (found == voxels.end ()) {
136
+ continue ;
137
+ }
138
+
139
+ voxel_index = found->second ;
140
+ const auto & voxel = flat_voxels[voxel_index]->second ;
141
+
142
+ traits::Traits<VoxelContents>::knn_search (voxel, pt, result);
143
+ }
144
+
132
145
return result.num_found ();
133
146
}
134
147
@@ -137,6 +150,38 @@ struct IncrementalVoxelMap {
137
150
inline size_t voxel_id (const size_t i) const { return i >> point_id_bits; } // /< Extract the point ID from a global index.
138
151
inline size_t point_id (const size_t i) const { return i & ((1ull << point_id_bits) - 1 ); } // /< Extract the voxel ID from a global index.
139
152
153
+ // / @brief Set the pattern of the search offsets. (Must be 1, 7, or 27)
154
+ void set_search_offsets (int num_offsets) {
155
+ switch (num_offsets) {
156
+ default :
157
+ std::cerr << " warning: unsupported search_offsets=" << num_offsets << " (supported values: 1, 7, 27)" << std::endl;
158
+ std::cerr << " : using default search_offsets=1" << std::endl;
159
+ [[fallthrough]];
160
+ case 1 :
161
+ search_offsets = {Eigen::Vector3i (0 , 0 , 0 )};
162
+ break ;
163
+ case 7 :
164
+ search_offsets = {
165
+ Eigen::Vector3i (0 , 0 , 0 ),
166
+ Eigen::Vector3i (1 , 0 , 0 ),
167
+ Eigen::Vector3i (0 , 1 , 0 ),
168
+ Eigen::Vector3i (0 , 0 , 1 ),
169
+ Eigen::Vector3i (-1 , 0 , 0 ),
170
+ Eigen::Vector3i (0 , -1 , 0 ),
171
+ Eigen::Vector3i (0 , 0 , -1 )};
172
+ break ;
173
+ case 27 :
174
+ for (int i = -1 ; i <= 1 ; i++) {
175
+ for (int j = -1 ; j <= 1 ; j++) {
176
+ for (int k = -1 ; k <= 1 ; k++) {
177
+ search_offsets.emplace_back (i, j, k);
178
+ }
179
+ }
180
+ }
181
+ break ;
182
+ }
183
+ }
184
+
140
185
public:
141
186
static_assert (sizeof (size_t ) == 8 , " size_t must be 64-bit" );
142
187
static constexpr int point_id_bits = 32 ; // /< Use the first 32 bits for point id
@@ -147,6 +192,8 @@ struct IncrementalVoxelMap {
147
192
size_t lru_clear_cycle; // /< LRU clear cycle. Voxel deletion is performed every lru_clear_cycle steps.
148
193
size_t lru_counter; // /< LRU counter. Incremented every step.
149
194
195
+ std::vector<Eigen::Vector3i> search_offsets; // /< Voxel search offsets.
196
+
150
197
typename VoxelContents::Setting voxel_setting; // /< Voxel setting.
151
198
std::vector<std::shared_ptr<std::pair<VoxelInfo, VoxelContents>>> flat_voxels; // /< Voxel contents.
152
199
std::unordered_map<Eigen::Vector3i, size_t , XORVector3iHash> voxels; // /< Voxel index map.
0 commit comments