VoxelGrid.hpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
5 * Karlsruhe Institute of Technology (KIT), all rights reserved.
6 *
7 * ArmarX is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * ArmarX is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Rainer Kartmann (rainer dot kartmann at student dot kit dot edu)
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
24#pragma once
25
26#include <vector>
27
28#include <Eigen/Geometry>
29
30#include "VoxelGridStructure.h"
31#include "exceptions.h"
32
33namespace visionx::voxelgrid
34{
35
36 /**
37 * @brief A 3D grid of voxels of type _VoxelT.
38 *
39 * A `VoxelGrid` three-dimensional regular grid of cuboids, called voxels.
40 * Its geometric structure is defined by a `VoxelGridStructure`.
41 * In addition, it stores voxel data of type _VoxelT (one per voxel).
42 *
43 * This is a generic implementation made to hold hold arbitrary data.
44 * As such, there is no concept of "free/occupied" voxels".
45 *
46 * @see VoxelGridStructure
47 */
48 template <typename _VoxelT>
50 {
51 public:
52 /// The voxel type.
53 using VoxelT = _VoxelT;
54
55
56 public:
57 /// Construct a voxel grid with 0 voxels of size 1.0.
59
60 /// Construct a voxel grid with the given structure and voxels with given value.
61 VoxelGrid(const VoxelGridStructure& structure, const VoxelT& value = {});
62
63 /**
64 * @brief Construct a voxel grid with the given structure and data.
65 * The size of `voxelData` must match the grid size of `structure`.
66 * @throw error::InvalidVoxelDataSize If the size does not match.
67 */
68 VoxelGrid(const VoxelGridStructure& structure,
69 const std::vector<VoxelGrid::VoxelT>& voxelData);
70
71 /// Construct a voxel grid with the same structure as other.
72 template <typename OtherVoxelT>
74
75 /// Ordinary copy constructor for voxel grid with same VoxelT.
76 VoxelGrid(const VoxelGrid<VoxelT>& other) = default;
77
78 /// Reset the voxel data by `numVoxels()` voxels with given value.
79 void
80 reset(const VoxelT& value = {})
81 {
82 _voxels.assign(numVoxels(), value);
83 }
84
85 /// Get the voxel grid structure.
88 {
89 return _struct;
90 }
91
92 /// Set the voxel grid structure and reset voxel data.
93 void
95 {
96 this->_struct = structure;
97 reset();
98 }
99
100 /// Get the voxel with the given index. @see `operator[]`
101 VoxelT&
102 getVoxel(std::size_t index)
103 {
104 return _voxels.at(index);
105 }
106
107 const VoxelT&
108 getVoxel(std::size_t index) const
109 {
110 return _voxels.at(index);
111 }
112
113 /// Get the voxel with the given grid index. @see `operator[]`
114 VoxelT&
115 getVoxel(int x, int y, int z)
116 {
117 return getVoxel(getVoxelFlatIndex(x, y, z));
118 }
119
120 const VoxelT&
121 getVoxel(int x, int y, int z) const
122 {
123 return getVoxel(getVoxelFlatIndex(x, y, z));
124 }
125
126 /// Get the voxel with the given grid index. @see `operator[]`
127 VoxelT&
128 getVoxel(const Eigen::Vector3i& index)
129 {
131 }
132
133 const VoxelT&
134 getVoxel(const Eigen::Vector3i& index) const
135 {
137 }
138
139 /// Get the voxel closest to the given point.
140 /// @param local If false (default), the point is transformed to local coordinate system.
141 VoxelT&
142 getVoxel(const Eigen::Vector3f& point, bool local = false)
143 {
144 return getVoxel(getVoxelGridIndex(point, local));
145 }
146
147 const VoxelT&
148 getVoxel(const Eigen::Vector3f& point, bool local = false) const
149 {
150 return getVoxel(getVoxelGridIndex(point, local));
151 }
152
153 /// Get the voxels.
154 /// @note `VoxelGrid` provides begin()/end() pairs, so it can be iterated over directly.
155 const std::vector<VoxelT>&
156 getVoxels() const
157 {
158 return _voxels;
159 }
160
161 /// Set the voxels. (Size must match `numVoxels()`).
162 /// @throw error::InvalidVoxelDataSize If the size does not match.
163 void
164 setVoxels(const std::vector<VoxelT>& voxels)
165 {
166 if (voxels.size() != numVoxels())
167 {
168 throw error::InvalidVoxelDataSize(voxels.size(), numVoxels());
169 }
170 this->_voxels = voxels;
171 }
172
173 /// Get the number of voxels in the grid.
174 std::size_t
175 numVoxels() const
176 {
177 return getNumVoxels();
178 }
179
180 /// Get the number of voxels in the grid.
181 std::size_t
183 {
184 return _struct.getNumVoxels();
185 }
186
187 /// Get the grid size.
188 Eigen::Vector3i
190 {
191 return _struct.getGridSize();
192 }
193
194 /// Set the grid size for a cubic grid. Resets the grid data.
195 void
196 setGridSizes(float gridSizes)
197 {
198 _struct.setGridSize(gridSizes);
199 }
200
201 /// Set the grid size. This resets the grid data.
202 void
203 setGridSizes(const Eigen::Vector3i& gridSizes)
204 {
205 _struct.setGridSize(gridSizes);
206 reset();
207 }
208
209 /// Get the voxel size.
210 Eigen::Vector3f
212 {
213 return _struct.getVoxelSize();
214 }
215
216 /// Set the voxel size of cubic voxels. The grid data is not updated.
217 void
218 setVoxelSizes(float voxelSize)
219 {
220 _struct.setVoxelSize(voxelSize);
221 }
222
223 /// Set the voxel size. The grid data is not updated.
224 void
225 setVoxelSizes(const Eigen::Vector3f& voxelSizes)
226 {
227 _struct.setVoxelSize(voxelSizes);
228 }
229
230 /// Get the flat index of the voxel with given grid index.
231 std::size_t
232 getVoxelFlatIndex(int x, int y, int z) const
233 {
234 return _struct.getFlatIndex(x, y, z);
235 }
236
237 /// Get the flat index of the voxel with given grid index.
238 std::size_t
239 getVoxelFlatIndex(const Eigen::Vector3i& index) const
240 {
241 return _struct.getFlatIndex(index);
242 }
243
244 /// Get the flat index of the voxel closest to `point`.
245 std::size_t
246 getVoxelFlatIndex(const Eigen::Vector3f& point, bool local = false) const
247 {
248 return _struct.getFlatIndex(point, local);
249 }
250
251 /// Get the grid index of the voxel with the given flat index.
252 Eigen::Vector3i
254 {
255 return _struct.getGridIndex(index);
256 }
257
258 /// Get the grid index of the voxel closest to point.
259 /// @param local If false (default), the point is transformed to local coordinate system.
260 Eigen::Vector3i
261 getVoxelGridIndex(const Eigen::Vector3f& point, bool local = false) const
262 {
263 return _struct.getGridIndex(point, local);
264 }
265
266 /// Get the minimal (along each axis) voxel grid index.
267 Eigen::Vector3i
269 {
270 return _struct.getGridIndexMin();
271 }
272
273 /// Get the maximal (along each axis) voxel grid index.
274 Eigen::Vector3i
276 {
277 return _struct.getGridIndexMax();
278 }
279
280 /// Get the center of the voxel with the given index.
281 Eigen::Vector3f
282 getVoxelCenter(std::size_t index, bool local = false) const
283 {
284 return _struct.getVoxelCenter(index, local);
285 }
286
287 /// Get the center of the voxel with the given index.
288 Eigen::Vector3f
289 getVoxelCenter(int x, int y, int z, bool local = false) const
290 {
291 return _struct.getVoxelCenter(x, y, z, local);
292 }
293
294 /// Get the center of the voxel with the given index.
295 Eigen::Vector3f
296 getVoxelCenter(const Eigen::Vector3i& index, bool local = false) const
297 {
298 return _struct.getVoxelCenter(index, local);
299 }
300
301 /// Get the grid origin in the world frame (center of voxel [0 0 0]).
302 /// Note that this differs from the geometric center for even grid sizes.
303 /// @see getCenter()
304 Eigen::Vector3f
305 getOrigin() const
306 {
307 return _struct.getOrigin();
308 }
309
310 /// Set the grid origin the world frame (center of voxel [0 0 0]).
311 /// Note that this differs from the geometric center for even grid sizes.
312 /// @see setCenter()
313 void
314 setOrigin(const Eigen::Vector3f& value)
315 {
316 _struct.setOrigin(value);
317 }
318
319 /// Get the grid orienation in the world frame.
322 {
323 return _struct.getOrientation();
324 }
325
326 /// Set the grid orienation in the world frame.
327 void
329 {
330 _struct.setOrientation(value);
331 }
332
333 /**
334 * @brief Get the geometric center of the grid the world frame
335 * (which differs from the origin for even grid sizes).
336 */
337 Eigen::Vector3f
338 getCenter() const
339 {
340 return _struct.getCenter();
341 }
342
343 /**
344 * @brief Set the geometric center of the grid the world frame
345 * (which differs from the origin for even grid sizes).
346 *
347 * @note This computes the origin from the given center using the
348 * current orientation. If you want to set grid center and orientation,
349 * set the orientation first, or (equivalently), use `setCenterPose()`.
350 *
351 * @see setPoseGridCenter()
352 */
353 void
354 setCenter(const Eigen::Vector3f& value)
355 {
356 _struct.setCenter(value);
357 }
358
359 /// Get the grid pose in the world frame.
360 /// Note that this differs from the geometric center for even grid sizes.
361 /// @see getCenterPose()
362 Eigen::Matrix4f
363 getPose() const
364 {
365 return _struct.getPose();
366 }
367
368 /// Get the grid pose in the world frame.
369 /// Note that this differs from the geometric center for even grid sizes.
370 /// @see setCenterPose()
371 void
372 setPose(const Eigen::Matrix4f& value)
373 {
374 _struct.setPose(value);
375 }
376
377 /// Get the grid pose positioned at the grid center in the world frame.
378 Eigen::Matrix4f
380 {
381 return _struct.getCenterPose();
382 }
383
384 /// Set the grid pose so that the grid center is the position of the
385 /// given pose under the given orientation.
386 void
387 setCenterPose(const Eigen::Matrix4f& value)
388 {
389 _struct.setCenterPose(value);
390 }
391
392 /// Get extent of the grid along each axis (encompassing the whole voxels).
393 Eigen::Vector3f
395 {
396 return _struct.getExtent();
397 }
398
399 /// Get extent of the grid along each axis (encompassing only voxel centers).
400 Eigen::Vector3f
402 {
403 return _struct.getExtentOfCenters();
404 }
405
406 /// Get the local axis aligned bounding box of the grid (minimal/maximal values in columns).
409 {
410 return _struct.getLocalBoundingBox();
411 }
412
413 /// Get the local axis aligned bounding box of the voxel centers (minimal/maximal values in columns).
416 {
417 return _struct.getLocalBoundingBoxOfCenters();
418 }
419
420 /// Indicate whether the given point is inside the voxel.
421 bool
422 isInside(const Eigen::Vector3i& index) const
423 {
424 return _struct.isInside(index);
425 }
426
427 /// Indicate whether the given point is inside the voxel.
428 bool
429 isInside(const Eigen::Vector3f& point, bool local = false) const
430 {
431 return _struct.isInside(point, local);
432 }
433
434 /// Assert that the given index is a valid grid index.
435 void
436 checkIsInside(const Eigen::Vector3i& index) const
437 {
438 return _struct.checkIsInside(index);
439 }
440
441 /// Get the voxel with given flat index. @see `getVoxel(std::size_t)`
442 VoxelT&
443 operator[](std::size_t index)
444 {
445 return getVoxel(index);
446 }
447
448 const VoxelT&
449 operator[](std::size_t index) const
450 {
451 return getVoxel(index);
452 }
453
454 /// Get the voxel with given grid index. @see `getVoxel(const Eigen::Vector3i&)`
455 VoxelT&
456 operator[](const Eigen::Vector3i& index)
457 {
458 return getVoxel(index);
459 }
460
461 const VoxelT&
462 operator[](const Eigen::Vector3i& index) const
463 {
464 return getVoxel(index);
465 }
466
467 /// Get an iterator to the first voxel.
468 typename std::vector<VoxelT>::iterator
470 {
471 return _voxels.begin();
472 }
473
474 /// Get an iterator to the first voxel.
475 typename std::vector<VoxelT>::const_iterator
476 begin() const
477 {
478 return _voxels.begin();
479 }
480
481 /// Get an iterator to the first voxel.
482 typename std::vector<VoxelT>::const_iterator
483 cbegin() const
484 {
485 return _voxels.begin();
486 }
487
488 /// Get an iterator to the element following the last voxel.
489 typename std::vector<VoxelT>::iterator
491 {
492 return _voxels.end();
493 }
494
495 /// Get an iterator to the element following the last voxel.
496 typename std::vector<VoxelT>::const_iterator
497 end() const
498 {
499 return _voxels.end();
500 }
501
502 /// Get an iterator to the element following the last voxel.
503 typename std::vector<VoxelT>::const_iterator
504 cend() const
505 {
506 return _voxels.end();
507 }
508
509
510 /// Stream a human-readable description of the grid's structure.
511 template <class VoxelType>
512 friend std::ostream& operator<<(std::ostream& os, const VoxelGrid<VoxelType>& grid);
513
514
515 protected:
516 /// The geometric structure.
518
519 /// The voxel data.
520 std::vector<VoxelT> _voxels;
521 };
522
523 template <typename VT>
525 {
526 }
527
528 template <typename VT>
529 VoxelGrid<VT>::VoxelGrid(const VoxelGridStructure& structure, const VoxelT& value) :
530 VoxelGrid(structure, std::vector<VoxelT>(structure.getNumVoxels(), value))
531 {
532 }
533
534 template <typename VT>
536 const std::vector<VoxelGrid::VoxelT>& voxelData) :
537 _struct(structure)
538 {
539 if (voxelData.size() != structure.getNumVoxels())
540 {
541 throw error::InvalidVoxelDataSize(voxelData.size(), structure.getNumVoxels());
542 }
543 _voxels = voxelData;
544 }
545
546 template <typename VT>
547 template <typename OtherVoxelT>
551
552 template <typename VT>
553 std::ostream&
554 operator<<(std::ostream& os, const VoxelGrid<VT>& grid)
555 {
556 os << "VoxelGrid " << grid._struct;
557 return os;
558 }
559
560} // namespace visionx::voxelgrid
uint8_t index
Geometric structure of a 3D voxel grid.
std::size_t getNumVoxels() const
Get the number of voxels contained in the structure.
A 3D grid of voxels of type _VoxelT.
Definition VoxelGrid.hpp:50
VoxelGrid(const VoxelGrid< OtherVoxelT > &other)
Construct a voxel grid with the same structure as other.
std::size_t getNumVoxels() const
Get the number of voxels in the grid.
Eigen::Matrix4f getCenterPose() const
Get the grid pose positioned at the grid center in the world frame.
bool isInside(const Eigen::Vector3f &point, bool local=false) const
Indicate whether the given point is inside the voxel.
void setVoxelSizes(const Eigen::Vector3f &voxelSizes)
Set the voxel size. The grid data is not updated.
std::vector< VoxelT >::const_iterator begin() const
Get an iterator to the first voxel.
Eigen::Vector3f getOrigin() const
Get the grid origin in the world frame (center of voxel [0 0 0]).
VoxelGrid(const VoxelGridStructure &structure, const std::vector< VoxelGrid::VoxelT > &voxelData)
Construct a voxel grid with the given structure and data.
void setVoxelSizes(float voxelSize)
Set the voxel size of cubic voxels. The grid data is not updated.
Eigen::Vector3f getExtents() const
Get extent of the grid along each axis (encompassing the whole voxels).
std::size_t getVoxelFlatIndex(const Eigen::Vector3f &point, bool local=false) const
Get the flat index of the voxel closest to point.
Eigen::Matrix32f getLocalBoundingBox() const
Get the local axis aligned bounding box of the grid (minimal/maximal values in columns).
_VoxelT VoxelT
The voxel type.
Definition VoxelGrid.hpp:53
VoxelGridStructure getStructure() const
Get the voxel grid structure.
Definition VoxelGrid.hpp:87
void resetStructure(const VoxelGridStructure &structure)
Set the voxel grid structure and reset voxel data.
Definition VoxelGrid.hpp:94
std::size_t getVoxelFlatIndex(int x, int y, int z) const
Get the flat index of the voxel with given grid index.
void reset(const VoxelT &value={})
Reset the voxel data by numVoxels() voxels with given value.
Definition VoxelGrid.hpp:80
VoxelGrid(const VoxelGridStructure &structure, const VoxelT &value={})
Construct a voxel grid with the given structure and voxels with given value.
const VoxelT & getVoxel(const Eigen::Vector3i &index) const
VoxelT & getVoxel(const Eigen::Vector3i &index)
Get the voxel with the given grid index.
std::vector< VoxelT >::iterator end()
Get an iterator to the element following the last voxel.
Eigen::Vector3f getVoxelCenter(std::size_t index, bool local=false) const
Get the center of the voxel with the given index.
const VoxelT & operator[](std::size_t index) const
Eigen::Vector3f getCenter() const
Get the geometric center of the grid the world frame (which differs from the origin for even grid siz...
const VoxelT & getVoxel(int x, int y, int z) const
VoxelT & getVoxel(std::size_t index)
Get the voxel with the given index.
void setOrientation(const Eigen::Quaternionf &value)
Set the grid orienation in the world frame.
Eigen::Matrix32f getLocalBoundingBoxOfCenters() const
Get the local axis aligned bounding box of the voxel centers (minimal/maximal values in columns).
friend std::ostream & operator<<(std::ostream &os, const VoxelGrid< VoxelType > &grid)
Stream a human-readable description of the grid's structure.
Eigen::Vector3i getVoxelGridIndex(const Eigen::Vector3f &point, bool local=false) const
Get the grid index of the voxel closest to point.
void setOrigin(const Eigen::Vector3f &value)
Set the grid origin the world frame (center of voxel [0 0 0]).
void setGridSizes(const Eigen::Vector3i &gridSizes)
Set the grid size. This resets the grid data.
VoxelGrid()
Construct a voxel grid with 0 voxels of size 1.0.
const VoxelT & getVoxel(std::size_t index) const
std::vector< VoxelT >::const_iterator end() const
Get an iterator to the element following the last voxel.
const VoxelT & getVoxel(const Eigen::Vector3f &point, bool local=false) const
std::size_t getVoxelFlatIndex(const Eigen::Vector3i &index) const
Get the flat index of the voxel with given grid index.
void checkIsInside(const Eigen::Vector3i &index) const
Assert that the given index is a valid grid index.
std::size_t numVoxels() const
Get the number of voxels in the grid.
void setCenter(const Eigen::Vector3f &value)
Set the geometric center of the grid the world frame (which differs from the origin for even grid siz...
void setPose(const Eigen::Matrix4f &value)
Get the grid pose in the world frame.
Eigen::Vector3i getGridSizes() const
Get the grid size.
bool isInside(const Eigen::Vector3i &index) const
Indicate whether the given point is inside the voxel.
const VoxelT & operator[](const Eigen::Vector3i &index) const
const std::vector< VoxelT > & getVoxels() const
Get the voxels.
Eigen::Vector3f getVoxelSizes() const
Get the voxel size.
Eigen::Vector3f getExtentsOfCenters() const
Get extent of the grid along each axis (encompassing only voxel centers).
std::vector< VoxelT > _voxels
The voxel data.
VoxelT & operator[](const Eigen::Vector3i &index)
Get the voxel with given grid index.
Eigen::Vector3f getVoxelCenter(int x, int y, int z, bool local=false) const
Get the center of the voxel with the given index.
void setVoxels(const std::vector< VoxelT > &voxels)
Set the voxels.
VoxelGrid(const VoxelGrid< VoxelT > &other)=default
Ordinary copy constructor for voxel grid with same VoxelT.
VoxelT & operator[](std::size_t index)
Get the voxel with given flat index.
Eigen::Vector3f getVoxelCenter(const Eigen::Vector3i &index, bool local=false) const
Get the center of the voxel with the given index.
std::vector< VoxelT >::iterator begin()
Get an iterator to the first voxel.
void setGridSizes(float gridSizes)
Set the grid size for a cubic grid. Resets the grid data.
std::vector< VoxelT >::const_iterator cend() const
Get an iterator to the element following the last voxel.
Eigen::Vector3i getVoxelGridIndex(size_t index) const
Get the grid index of the voxel with the given flat index.
Eigen::Vector3i getVoxelGridIndexMin() const
Get the minimal (along each axis) voxel grid index.
void setCenterPose(const Eigen::Matrix4f &value)
Set the grid pose so that the grid center is the position of the given pose under the given orientati...
VoxelT & getVoxel(int x, int y, int z)
Get the voxel with the given grid index.
Eigen::Matrix4f getPose() const
Get the grid pose in the world frame.
VoxelT & getVoxel(const Eigen::Vector3f &point, bool local=false)
Get the voxel closest to the given point.
std::vector< VoxelT >::const_iterator cbegin() const
Get an iterator to the first voxel.
Eigen::Quaternionf getOrientation() const
Get the grid orienation in the world frame.
Eigen::Vector3i getVoxelGridIndexMax() const
Get the maximal (along each axis) voxel grid index.
Indicates that voxel data with an invalid number of voxels has been passed to a VoxelGrid.
Definition exceptions.h:27
Quaternion< float, 0 > Quaternionf
Matrix< float, 3, 2 > Matrix32f
A 3x2 matrix.
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::ostream & operator<<(std::ostream &os, const VoxelGrid< VT > &grid)
voxelgrid::VoxelGridStructure VoxelGridStructure