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