VoxelGridStructure.cpp
Go to the documentation of this file.
1 #include "VoxelGridStructure.h"
2 
3 #include <VirtualRobot/math/Helpers.h>
4 
6 
7 namespace visionx::voxelgrid
8 {
9 
10  template <typename Derived>
13 
14  template <typename Derived>
15  static Derived
16  cwise(ScalarFunction<Derived> function, const Eigen::MatrixBase<Derived>& matrix)
17  {
18  Derived result = matrix;
19  for (typename Derived::Index i = 0; i < result.size(); ++i)
20  {
21  result(i) = function(result(i));
22  }
23  return result;
24  }
25 
26  const Eigen::IOFormat VoxelGridStructure::_iofVector = {5, 0, " ", " ", "", "", "[", "]"};
27  const Eigen::IOFormat VoxelGridStructure::_iofTimes = {5, 0, "", " x ", "", "", "", ""};
28 
30  {
31  }
32 
34  float voxelSize,
35  const Eigen::Vector3f& origin,
36  const Eigen::Quaternionf& orientation) :
37  VoxelGridStructure(Eigen::Vector3i::Constant(gridSize),
38  Eigen::Vector3f::Constant(voxelSize),
39  origin,
40  orientation)
41  {
42  }
43 
44  VoxelGridStructure::VoxelGridStructure(const Eigen::Vector3i& gridSize,
45  float voxelSize,
46  const Eigen::Vector3f& origin,
47  const Eigen::Quaternionf& orientation) :
48  VoxelGridStructure(gridSize, Eigen::Vector3f::Constant(voxelSize), origin, orientation)
49  {
50  }
51 
53  const Eigen::Vector3f& voxelSize,
54  const Eigen::Vector3f& origin,
55  const Eigen::Quaternionf& orientation) :
56  VoxelGridStructure(Eigen::Vector3i::Constant(gridSize), voxelSize, origin, orientation)
57  {
58  }
59 
60  VoxelGridStructure::VoxelGridStructure(const Eigen::Vector3i& gridSize,
61  const Eigen::Vector3f& voxelSize,
62  const Eigen::Vector3f& origin,
63  const Eigen::Quaternionf& orientation) :
64  _gridSize(gridSize), _voxelSize(voxelSize), _origin(origin), _orientation(orientation)
65  {
66  ARMARX_CHECK_NONNEGATIVE(voxelSize.minCoeff()) << "Voxel sizes must not be negative.";
67  ARMARX_CHECK_NONNEGATIVE(gridSize.minCoeff()) << "Grid sizes must not be negative.";
68  }
69 
70  Eigen::Vector3i
72  {
73  return _gridSize;
74  }
75 
76  void
78  {
79  setGridSize(Eigen::Vector3i::Constant(gridSize));
80  }
81 
82  void
83  VoxelGridStructure::setGridSize(const Eigen::Vector3i& gridSize)
84  {
85  _gridSize = gridSize;
86  }
87 
88  Eigen::Vector3f
90  {
91  return _voxelSize;
92  }
93 
94  void
96  {
97  setVoxelSize(Eigen::Vector3f::Constant(voxelSize));
98  }
99 
100  void
101  VoxelGridStructure::setVoxelSize(const Eigen::Vector3f& voxelSize)
102  {
103  _voxelSize = voxelSize;
104  }
105 
106  std::size_t
108  {
109  return static_cast<std::size_t>(_gridSize.prod());
110  }
111 
112  std::size_t
113  VoxelGridStructure::getFlatIndex(int x, int y, int z) const
114  {
115  return getFlatIndex(Eigen::Vector3i(x, y, z));
116  }
117 
118  std::size_t
119  VoxelGridStructure::getFlatIndex(const Eigen::Vector3i& indices) const
120  {
121  const Eigen::Vector3f _halfGridSizes = halfGridSize();
122 
124 
125  long index = static_cast<long>(
126  (indices.x() + _halfGridSizes.x()) * _gridSize.z() * _gridSize.y() // skips y*z
127  + (indices.y() + _halfGridSizes.y()) * _gridSize.z() // skips z
128  + (indices.z() + _halfGridSizes.z()));
129 
131  return static_cast<std::size_t>(index);
132  }
133 
134  std::size_t
135  VoxelGridStructure::getFlatIndex(const Eigen::Vector3f& point, bool local) const
136  {
137  return getFlatIndex(getGridIndex(point, local));
138  }
139 
140  Eigen::Vector3i
142  {
143  // FITS_SIZE triggers: comparison of unsigned expression >= 0 is always true [-Werror=type-limits]
144  //ARMARX_CHECK_FITS_SIZE(index, getNumVoxels());
146  int x = static_cast<int>(index / static_cast<std::size_t>(_gridSize.z() * _gridSize.y()));
147  int rest =
148  static_cast<int>(index % static_cast<std::size_t>(_gridSize.z() * _gridSize.y()));
149  int y = rest / _gridSize.z();
150  int z = rest % _gridSize.z();
151  return Eigen::Vector3i{x, y, z} + getGridIndexMin();
152  }
153 
154  Eigen::Vector3i
155  VoxelGridStructure::getGridIndex(const Eigen::Vector3f& point, bool local) const
156  {
157  Eigen::Vector3f pointLocal;
158  if (local)
159  {
160  pointLocal = point;
161  }
162  else
163  {
164  // pose = local -> global => inv_pose = global -> locals
165  pointLocal =
166  math::Helpers::TransformPosition(math::Helpers::InvertedPose(getPose()), point);
167  }
168 
169  Eigen::Vector3f scaled = (pointLocal.array() / _voxelSize.array()).matrix();
170 
171  return cwise<Eigen::Vector3f>(&std::roundf, scaled).template cast<int>();
172  }
173 
174  Eigen::Vector3i
176  {
177  // 3 -> 1.5 -> 1 -> -1
178  // 4 -> 2.0 -> 2 -> -2
179  // 5 -> 2.5 -> 2 -> -2
180  // 6 -> 3.0 -> 3 -> -3
181  return -cwise<Eigen::Vector3f>(&floorf, halfGridSize()).template cast<int>();
182  }
183 
184  Eigen::Vector3i
186  {
187  // 3 -> 1.5 -> 1.0 -> 1
188  // 4 -> 2.0 -> 1.5 -> 1
189  // 5 -> 2.5 -> 2.0 -> 2
190  // 6 -> 3.0 -> 2.5 -> 2
191  const Eigen::Vector3f half = halfGridSize().array() - 0.5f;
192  return cwise<Eigen::Vector3f>(&floorf, half).template cast<int>();
193  }
194 
195  Eigen::Vector3f
196  VoxelGridStructure::getVoxelCenter(std::size_t index, bool local) const
197  {
198  return getVoxelCenter(getGridIndex(index), local);
199  }
200 
201  Eigen::Vector3f
202  VoxelGridStructure::getVoxelCenter(int x, int y, int z, bool local) const
203  {
204  return getVoxelCenter({x, y, z}, local);
205  }
206 
207  Eigen::Vector3f
208  VoxelGridStructure::getVoxelCenter(const Eigen::Vector3i& indices, bool local) const
209  {
211  auto center = _voxelSize.array() * indices.array().cast<float>();
212  if (local)
213  {
214  return center;
215  }
216  else
217  {
218  return math::Helpers::TransformPosition(getPose(), center);
219  }
220  }
221 
222  Eigen::Vector3f
224  {
225  return _origin;
226  }
227 
228  void
229  VoxelGridStructure::setOrigin(const Eigen::Vector3f& origin)
230  {
231  _origin = origin;
232  }
233 
236  {
237  return _orientation;
238  }
239 
240  void
242  {
243  _orientation = orientation;
244  }
245 
246  Eigen::Vector3f
248  {
249  return _origin + getOriginToGridCenter(false);
250  }
251 
252  void
253  VoxelGridStructure::setCenter(const Eigen::Vector3f& center)
254  {
255  setOrigin(center - getOriginToGridCenter(false));
256  }
257 
260  {
261  return math::Helpers::Pose(_origin, _orientation);
262  }
263 
264  void
266  {
269  }
270 
273  {
274  return math::Helpers::Pose(getCenter(), _orientation);
275  }
276 
277  void
279  {
282  }
283 
284  Eigen::Vector3f
286  {
287  return getExtentOfCenters() + _voxelSize;
288  }
289 
290  Eigen::Vector3f
292  {
293  return _gridSize.cast<float>().array() * _voxelSize.array();
294  }
295 
298  {
300  bb.col(0) -= _voxelSize / 2;
301  bb.col(1) += _voxelSize / 2;
302  return bb;
303  }
304 
307  {
308  Eigen::Matrix32f bb;
309  bb.col(0) = getVoxelCenter(getGridIndexMin(), true);
310  bb.col(1) = getVoxelCenter(getGridIndexMax(), true);
311  return bb;
312  }
313 
314  bool
315  VoxelGridStructure::isInside(const Eigen::Vector3i& indices) const
316  {
317  const Eigen::Vector3i min = getGridIndexMin();
318  const Eigen::Vector3i max = getGridIndexMax();
319 
320  for (int i = 0; i < indices.size(); ++i)
321  {
322  if (!(min(i) <= indices(i) && indices(i) <= max(i)))
323  {
324  return false;
325  }
326  }
327  return true;
328  }
329 
330  bool
331  VoxelGridStructure::isInside(const Eigen::Vector3f& point, bool local) const
332  {
333  return isInside(getGridIndex(point, local));
334  }
335 
336  void
337  VoxelGridStructure::checkIsInside(const Eigen::Vector3i& indices) const
338  {
340  << "Indices must be inside voxel grid. "
341  << "\n- given: " << indices.format(_iofVector)
342  << "\n- allowed range: " << getGridIndexMin().format(_iofVector) << " .. "
343  << getGridIndexMax().format(_iofVector);
344  }
345 
346  bool
348  {
349  return _gridSize == rhs._gridSize && _voxelSize.isApprox(rhs._voxelSize) &&
350  _origin.isApprox(rhs._origin) && _orientation.isApprox(rhs._orientation);
351  }
352 
353  bool
355  {
356  return !(*this == rhs);
357  }
358 
359  Eigen::Vector3f
360  VoxelGridStructure::halfGridSize() const
361  {
362  return _gridSize.cast<float>() / 2;
363  }
364 
365  Eigen::Vector3f
366  VoxelGridStructure::getOriginToGridCenter(bool local) const
367  {
368  Eigen::Vector3f shift = shift.Zero();
369  for (Eigen::Vector3f::Index i = 0; i < shift.size(); ++i)
370  {
371  if (_gridSize(i) % 2 == 0)
372  {
373  shift(i) = -_voxelSize(i) / 2;
374  }
375  }
376  return local ? shift : (_orientation * shift);
377  }
378 
379  std::ostream&
380  operator<<(std::ostream& os, const VoxelGridStructure& rhs)
381  {
382  os << "Structure with " << rhs.getNumVoxels() << " voxels";
383  os << "\n- Origin: \t" << rhs._origin.format(rhs._iofVector);
384  os << "\n- Voxel size:\t" << rhs._voxelSize.format(rhs._iofTimes);
385  os << "\n- Grid size: \t" << rhs._gridSize.format(rhs._iofTimes);
386  os << "\n- Indices: \t" << rhs.getGridIndexMin().format(rhs._iofVector) << " .. "
387  << rhs.getGridIndexMax().format(rhs._iofVector);
388  os << "\n- Centers: \t"
389  << rhs.getVoxelCenter(rhs.getGridIndexMin()).format(rhs._iofVector) << " .. "
390  << rhs.getVoxelCenter(rhs.getGridIndexMax()).format(rhs._iofVector);
391 
392  return os;
393  }
394 
395 } // namespace visionx::voxelgrid
visionx::voxelgrid::VoxelGridStructure::getGridIndexMin
Eigen::Vector3i getGridIndexMin() const
Get the minimal (along each axis) grid index.
Definition: VoxelGridStructure.cpp:175
visionx::voxelgrid::VoxelGridStructure::getGridIndexMax
Eigen::Vector3i getGridIndexMax() const
Get the maximal (along each axis) grid index.
Definition: VoxelGridStructure.cpp:185
Eigen
Definition: Elements.h:32
ARMARX_CHECK_NONNEGATIVE
#define ARMARX_CHECK_NONNEGATIVE(number)
Check whether number is nonnegative (>= 0). If it is not, throw an ExpressionException with the expre...
Definition: ExpressionException.h:152
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:10
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
index
uint8_t index
Definition: EtherCATFrame.h:59
visionx::voxelgrid::VoxelGridStructure::getFlatIndex
std::size_t getFlatIndex(int x, int y, int z) const
Get the flat index for the given grid indices.
Definition: VoxelGridStructure.cpp:113
visionx::voxelgrid::VoxelGridStructure::getVoxelSize
Eigen::Vector3f getVoxelSize() const
Get the voxel size.
Definition: VoxelGridStructure.cpp:89
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
visionx::voxelgrid::VoxelGridStructure::setGridSize
void setGridSize(int gridSize)
Set the grid size for a cubic grid.
Definition: VoxelGridStructure.cpp:77
visionx::voxelgrid::VoxelGridStructure::VoxelGridStructure
VoxelGridStructure()
Construct an empty grid structure (0 voxels with size 1.0).
Definition: VoxelGridStructure.cpp:29
visionx::voxelgrid::VoxelGridStructure::getOrientation
Eigen::Quaternionf getOrientation() const
Get the grid orienation in the world frame.
Definition: VoxelGridStructure.cpp:235
VoxelGridStructure.h
ARMARX_CHECK_LESS
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
Definition: ExpressionException.h:102
visionx::voxelgrid::VoxelGridStructure::setPose
void setPose(const Eigen::Matrix4f &pose)
Get the grid pose in the world frame.
Definition: VoxelGridStructure.cpp:265
visionx::voxelgrid::operator<<
std::ostream & operator<<(std::ostream &os, const VoxelGrid< VT > &grid)
Definition: VoxelGrid.hpp:554
visionx::voxelgrid::VoxelGridStructure::getPose
Eigen::Matrix4f getPose() const
Get the grid pose in the world frame.
Definition: VoxelGridStructure.cpp:259
visionx::voxelgrid::VoxelGridStructure::getExtentOfCenters
Eigen::Vector3f getExtentOfCenters() const
Get extent of the grid along each axis (encompassing only voxel centers).
Definition: VoxelGridStructure.cpp:291
visionx::voxelgrid::VoxelGridStructure::getExtent
Eigen::Vector3f getExtent() const
Get extent of the grid along each axis (encompassing the whole voxels).
Definition: VoxelGridStructure.cpp:285
visionx::voxelgrid
Definition: exceptions.cpp:7
visionx::voxelgrid::VoxelGridStructure::getLocalBoundingBoxOfCenters
Eigen::Matrix32f getLocalBoundingBoxOfCenters() const
Get the local axis aligned bounding box of the voxel centers (minimal/maximal values in columns).
Definition: VoxelGridStructure.cpp:306
visionx::voxelgrid::VoxelGridStructure::isInside
bool isInside(const Eigen::Vector3i &indices) const
Indicate whether the given point is inside the voxel.
Definition: VoxelGridStructure.cpp:315
visionx::voxelgrid::VoxelGridStructure
Geometric structure of a 3D voxel grid.
Definition: VoxelGridStructure.h:94
visionx::voxelgrid::VoxelGridStructure::getGridSize
Eigen::Vector3i getGridSize() const
Get the grid size.
Definition: VoxelGridStructure.cpp:71
pcl::graph::indices
pcl::PointIndices::Ptr indices(const PCG &g)
Retrieve the indices of the points of the point cloud stored in a point cloud graph that actually bel...
Definition: point_cloud_graph.h:717
visionx::voxelgrid::VoxelGridStructure::setCenter
void setCenter(const Eigen::Vector3f &center)
Set the geometric center of the grid the world frame (which differs from the origin for even grid siz...
Definition: VoxelGridStructure.cpp:253
visionx::voxelgrid::VoxelGridStructure::setOrigin
void setOrigin(const Eigen::Vector3f &value)
Set the grid origin the world frame (center of voxel [0 0 0]).
Definition: VoxelGridStructure.cpp:229
visionx::voxelgrid::VoxelGridStructure::setOrientation
void setOrientation(const Eigen::Quaternionf &value)
Set the grid orienation in the world frame.
Definition: VoxelGridStructure.cpp:241
visionx::voxelgrid::VoxelGridStructure::getCenterPose
Eigen::Matrix4f getCenterPose() const
Get the grid pose positioned at the grid center in the world frame.
Definition: VoxelGridStructure.cpp:272
max
T max(T t1, T t2)
Definition: gdiam.h:51
visionx::voxelgrid::ScalarFunction
std::function< typename Eigen::MatrixBase< Derived >::Scalar(typename Eigen::MatrixBase< Derived >::Scalar)> ScalarFunction
Definition: VoxelGridStructure.cpp:12
visionx::voxelgrid::VoxelGridStructure::getVoxelCenter
Eigen::Vector3f getVoxelCenter(std::size_t index, bool local=false) const
Get the center of the voxel with the given indices.
Definition: VoxelGridStructure.cpp:196
visionx::voxelgrid::VoxelGridStructure::operator!=
bool operator!=(const VoxelGridStructure &rhs) const
Definition: VoxelGridStructure.cpp:354
ExpressionException.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
visionx::voxelgrid::VoxelGridStructure::getNumVoxels
std::size_t getNumVoxels() const
Get the number of voxels contained in the structure.
Definition: VoxelGridStructure.cpp:107
armarx::Quaternion< float, 0 >
Scalar
float Scalar
Definition: basic.h:15
visionx::voxelgrid::VoxelGridStructure::setVoxelSize
void setVoxelSize(float voxelSize)
Set the voxel size for cubic voxels.
Definition: VoxelGridStructure.cpp:95
visionx::voxelgrid::VoxelGridStructure::checkIsInside
void checkIsInside(const Eigen::Vector3i &indices) const
Assert that the given indices are valid grid indices.
Definition: VoxelGridStructure.cpp:337
Eigen::Matrix
Definition: EigenForwardDeclarations.h:27
visionx::voxelgrid::VoxelGridStructure::getCenter
Eigen::Vector3f getCenter() const
Get the geometric center of the grid the world frame (which differs from the origin for even grid siz...
Definition: VoxelGridStructure.cpp:247
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
min
T min(T t1, T t2)
Definition: gdiam.h:44
visionx::voxelgrid::VoxelGridStructure::getOrigin
Eigen::Vector3f getOrigin() const
Get the grid origin in the world frame (center of voxel [0 0 0]).
Definition: VoxelGridStructure.cpp:223
visionx::voxelgrid::VoxelGridStructure::getGridIndex
Eigen::Vector3i getGridIndex(size_t index) const
Get the voxel indices of the voxel with the given index.
Definition: VoxelGridStructure.cpp:141
visionx::voxelgrid::VoxelGridStructure::getLocalBoundingBox
Eigen::Matrix32f getLocalBoundingBox() const
Get the local axis aligned bounding box of the grid (minimal/maximal values in columns).
Definition: VoxelGridStructure.cpp:297
visionx::voxelgrid::VoxelGridStructure::operator==
bool operator==(const VoxelGridStructure &rhs) const
Indicates whether rhs is equal to *this.
Definition: VoxelGridStructure.cpp:347
visionx::voxelgrid::VoxelGridStructure::setCenterPose
void setCenterPose(const Eigen::Matrix4f &pose)
Set the grid pose so that the grid center is the position of the given pose under the given orientati...
Definition: VoxelGridStructure.cpp:278