3#include <VirtualRobot/math/Helpers.h>
10 template <
typename Derived>
11 using ScalarFunction = std::function<typename Eigen::MatrixBase<Derived>::Scalar(
12 typename Eigen::MatrixBase<Derived>::Scalar)>;
14 template <
typename Derived>
18 Derived result = matrix;
19 for (
typename Derived::Index i = 0; i < result.size(); ++i)
21 result(i) = function(result(i));
26 const Eigen::IOFormat VoxelGridStructure::_iofVector = {5, 0,
" ",
" ",
"",
"",
"[",
"]"};
27 const Eigen::IOFormat VoxelGridStructure::_iofTimes = {5, 0,
"",
" x ",
"",
"",
"",
""};
35 const Eigen::Vector3f& origin,
38 Eigen::Vector3f::Constant(voxelSize),
46 const Eigen::Vector3f& origin,
53 const Eigen::Vector3f& voxelSize,
54 const Eigen::Vector3f& origin,
61 const Eigen::Vector3f& voxelSize,
62 const Eigen::Vector3f& origin,
64 _gridSize(gridSize), _voxelSize(voxelSize), _origin(origin), _orientation(orientation)
103 _voxelSize = voxelSize;
109 return static_cast<std::size_t
>(_gridSize.prod());
121 const Eigen::Vector3f _halfGridSizes = halfGridSize();
125 long index =
static_cast<long>(
126 (indices.x() + _halfGridSizes.x()) * _gridSize.z() * _gridSize.y()
127 + (indices.y() + _halfGridSizes.y()) * _gridSize.z()
128 + (indices.z() + _halfGridSizes.z()));
131 return static_cast<std::size_t
>(
index);
146 int x =
static_cast<int>(
index /
static_cast<std::size_t
>(_gridSize.z() * _gridSize.y()));
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();
157 Eigen::Vector3f pointLocal;
166 math::Helpers::TransformPosition(math::Helpers::InvertedPose(
getPose()), point);
169 Eigen::Vector3f scaled = (pointLocal.array() / _voxelSize.array()).matrix();
171 return cwise<Eigen::Vector3f>(&std::roundf, scaled).template cast<int>();
181 return -cwise<Eigen::Vector3f>(&floorf, halfGridSize()).template cast<int>();
191 const Eigen::Vector3f half = halfGridSize().array() - 0.5f;
192 return cwise<Eigen::Vector3f>(&floorf, half).template cast<int>();
211 auto center = _voxelSize.array() * indices.array().cast<
float>();
218 return math::Helpers::TransformPosition(
getPose(), center);
243 _orientation = orientation;
249 return _origin + getOriginToGridCenter(
false);
255 setOrigin(center - getOriginToGridCenter(
false));
261 return math::Helpers::Pose(_origin, _orientation);
267 setOrigin(math::Helpers::Position(pose));
274 return math::Helpers::Pose(
getCenter(), _orientation);
281 setCenter(math::Helpers::Position(pose));
293 return _gridSize.cast<
float>().array() * _voxelSize.array();
300 bb.col(0) -= _voxelSize / 2;
301 bb.col(1) += _voxelSize / 2;
320 for (
int i = 0; i < indices.size(); ++i)
322 if (!(
min(i) <= indices(i) && indices(i) <=
max(i)))
340 <<
"Indices must be inside voxel grid. "
341 <<
"\n- given: " << indices.format(_iofVector)
342 <<
"\n- allowed range: " <<
getGridIndexMin().format(_iofVector) <<
" .. "
349 return _gridSize == rhs._gridSize && _voxelSize.isApprox(rhs._voxelSize) &&
350 _origin.isApprox(rhs._origin) && _orientation.isApprox(rhs._orientation);
356 return !(*
this == rhs);
360 VoxelGridStructure::halfGridSize()
const
362 return _gridSize.cast<
float>() / 2;
366 VoxelGridStructure::getOriginToGridCenter(
bool local)
const
368 Eigen::Vector3f shift = shift.Zero();
369 for (Eigen::Vector3f::Index i = 0; i < shift.size(); ++i)
371 if (_gridSize(i) % 2 == 0)
373 shift(i) = -_voxelSize(i) / 2;
376 return local ? shift : (_orientation * shift);
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) <<
" .. "
388 os <<
"\n- Centers: \t"
std::size_t getNumVoxels() const
Get the number of voxels contained in the structure.
Eigen::Matrix4f getCenterPose() const
Get the grid pose positioned at the grid center in the world frame.
Eigen::Vector3f getOrigin() const
Get the grid origin in the world frame (center of voxel [0 0 0]).
bool operator!=(const VoxelGridStructure &rhs) const
Eigen::Matrix32f getLocalBoundingBox() const
Get the local axis aligned bounding box of the grid (minimal/maximal values in columns).
std::size_t getFlatIndex(int x, int y, int z) const
Get the flat index for the given grid indices.
void setVoxelSize(float voxelSize)
Set the voxel size for cubic voxels.
Eigen::Vector3f getVoxelCenter(std::size_t index, bool local=false) const
Get the center of the voxel with the given indices.
Eigen::Vector3f getCenter() const
Get the geometric center of the grid the world frame (which differs from the origin for even grid siz...
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).
void setOrigin(const Eigen::Vector3f &value)
Set the grid origin the world frame (center of voxel [0 0 0]).
Eigen::Vector3i getGridSize() const
Get the grid size.
Eigen::Vector3i getGridIndex(size_t index) const
Get the voxel indices of the voxel with the given index.
void setCenter(const Eigen::Vector3f ¢er)
Set the geometric center of the grid the world frame (which differs from the origin for even grid siz...
Eigen::Vector3f getVoxelSize() const
Get the voxel size.
Eigen::Vector3f getExtent() const
Get extent of the grid along each axis (encompassing the whole voxels).
bool operator==(const VoxelGridStructure &rhs) const
Indicates whether rhs is equal to *this.
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...
VoxelGridStructure()
Construct an empty grid structure (0 voxels with size 1.0).
bool isInside(const Eigen::Vector3i &indices) const
Indicate whether the given point is inside the voxel.
void checkIsInside(const Eigen::Vector3i &indices) const
Assert that the given indices are valid grid indices.
void setPose(const Eigen::Matrix4f &pose)
Get the grid pose in the world frame.
Eigen::Vector3f getExtentOfCenters() const
Get extent of the grid along each axis (encompassing only voxel centers).
Eigen::Matrix4f getPose() const
Get the grid pose in the world frame.
void setGridSize(int gridSize)
Set the grid size for a cubic grid.
Eigen::Vector3i getGridIndexMax() const
Get the maximal (along each axis) grid index.
Eigen::Vector3i getGridIndexMin() const
Get the minimal (along each axis) grid index.
Eigen::Quaternionf getOrientation() const
Get the grid orienation in the world frame.
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#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...
#define ARMARX_CHECK_NONNEGATIVE(number)
Check whether number is nonnegative (>= 0).
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)
std::function< typename Eigen::MatrixBase< Derived >::Scalar( typename Eigen::MatrixBase< Derived >::Scalar)> ScalarFunction