3 #include <VirtualRobot/math/Helpers.h>
10 template <
typename Derived>
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));
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)
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"