39#ifndef PCL_FILTERS_IMPL_VOXEL_GRID_OCCLUSION_ESTIMATION_H_
40#define PCL_FILTERS_IMPL_VOXEL_GRID_OCCLUSION_ESTIMATION_H_
42#include <pcl/filters/voxel_grid_occlusion_estimation.h>
45template <
typename Po
intT>
void
69 PCL_WARN (
"[VoxelGridOcclusionEstimation::initializeVoxelGrid] The voxel containing the sensor origin (%g, %g, %g) is marked as occupied. We will instead assume that it is free, to be able to perform the occlusion estimation.\n",
sensor_origin_.x(),
sensor_origin_.y(),
sensor_origin_.z());
75template <
typename Po
intT>
int
77 const Eigen::Vector3i& in_target_voxel)
81 PCL_ERROR (
"Voxel grid not initialized; call initializeVoxelGrid () first! \n");
88 direction.normalize ();
95 PCL_ERROR (
"The ray does not intersect with the bounding box \n");
106template <
typename Po
intT>
int
108 std::vector<Eigen::Vector3i, Eigen::aligned_allocator<Eigen::Vector3i> >& out_ray,
109 const Eigen::Vector3i& in_target_voxel)
113 PCL_ERROR (
"Voxel grid not initialized; call initializeVoxelGrid () first! \n");
120 direction.normalize ();
127 PCL_ERROR (
"The ray does not intersect with the bounding box \n");
138template <
typename Po
intT>
int
143 PCL_ERROR (
"Voxel grid not initialized; call initializeVoxelGrid () first! \n");
149 occluded_voxels.reserve (reserve_size);
156 Eigen::Vector3i ijk (ii, jj, kk);
164 direction.normalize ();
174 occluded_voxels.push_back (ijk);
181template <
typename Po
intT>
float
183 const Eigen::Vector4f& direction)
185 float tmin, tmax, tymin, tymax, tzmin, tzmax;
187 if (direction[0] >= 0)
189 tmin = (
b_min_[0] - origin[0]) / direction[0];
190 tmax = (
b_max_[0] - origin[0]) / direction[0];
194 tmin = (
b_max_[0] - origin[0]) / direction[0];
195 tmax = (
b_min_[0] - origin[0]) / direction[0];
198 if (direction[1] >= 0)
200 tymin = (
b_min_[1] - origin[1]) / direction[1];
201 tymax = (
b_max_[1] - origin[1]) / direction[1];
205 tymin = (
b_max_[1] - origin[1]) / direction[1];
206 tymax = (
b_min_[1] - origin[1]) / direction[1];
209 if ((tmin > tymax) || (tymin > tmax))
211 PCL_ERROR (
"no intersection with the bounding box \n");
221 if (direction[2] >= 0)
223 tzmin = (
b_min_[2] - origin[2]) / direction[2];
224 tzmax = (
b_max_[2] - origin[2]) / direction[2];
228 tzmin = (
b_max_[2] - origin[2]) / direction[2];
229 tzmax = (
b_min_[2] - origin[2]) / direction[2];
232 if ((tmin > tzmax) || (tzmin > tmax))
234 PCL_ERROR (
"no intersection with the bounding box \n");
243 return std::max<float>(tmin, 0.0f);
247template <
typename Po
intT>
int
249 const Eigen::Vector4f& origin,
250 const Eigen::Vector4f& direction,
255 Eigen::Vector4f start = origin + (t_min > 0.0f ? (t_min + std::numeric_limits<float>::epsilon()) : t_min) * direction;
261 int step_x, step_y, step_z;
266 if (direction[0] >= 0)
276 if (direction[1] >= 0)
286 if (direction[2] >= 0)
297 float t_max_x = t_min + (voxel_max[0] - start[0]) / direction[0];
298 float t_max_y = t_min + (voxel_max[1] - start[1]) / direction[1];
299 float t_max_z = t_min + (voxel_max[2] - start[2]) / direction[2];
301 float t_delta_x =
leaf_size_[0] /
static_cast<float> (std::abs (direction[0]));
302 float t_delta_y =
leaf_size_[1] /
static_cast<float> (std::abs (direction[1]));
303 float t_delta_z =
leaf_size_[2] /
static_cast<float> (std::abs (direction[2]));
305 while ( (ijk[0] <
max_b_[0]+1) && (ijk[0] >=
min_b_[0]) &&
310 if (ijk[0] == target_voxel[0] && ijk[1] == target_voxel[1] && ijk[2] == target_voxel[2])
320 if(t_max_x <= t_max_y && t_max_x <= t_max_z)
322 t_max_x += t_delta_x;
325 else if(t_max_y <= t_max_z && t_max_y <= t_max_x)
327 t_max_y += t_delta_y;
332 t_max_z += t_delta_z;
340template <
typename Po
intT>
int
342 const Eigen::Vector3i& target_voxel,
343 const Eigen::Vector4f& origin,
344 const Eigen::Vector4f& direction,
348 int reserve_size =
div_b_.maxCoeff () *
div_b_.maxCoeff ();
349 out_ray.reserve (reserve_size);
353 Eigen::Vector4f start = origin + (t_min > 0.0f ? (t_min + std::numeric_limits<float>::epsilon()) : t_min) * direction;
359 int step_x, step_y, step_z;
364 if (direction[0] >= 0)
374 if (direction[1] >= 0)
384 if (direction[2] >= 0)
395 float t_max_x = t_min + (voxel_max[0] - start[0]) / direction[0];
396 float t_max_y = t_min + (voxel_max[1] - start[1]) / direction[1];
397 float t_max_z = t_min + (voxel_max[2] - start[2]) / direction[2];
399 float t_delta_x =
leaf_size_[0] /
static_cast<float> (std::abs (direction[0]));
400 float t_delta_y =
leaf_size_[1] /
static_cast<float> (std::abs (direction[1]));
401 float t_delta_z =
leaf_size_[2] /
static_cast<float> (std::abs (direction[2]));
406 while ( (ijk[0] <
max_b_[0]+1) && (ijk[0] >=
min_b_[0]) &&
411 out_ray.push_back (ijk);
414 if (ijk[0] == target_voxel[0] && ijk[1] == target_voxel[1] && ijk[2] == target_voxel[2])
423 if(t_max_x <= t_max_y && t_max_x <= t_max_z)
425 t_max_x += t_delta_x;
428 else if(t_max_y <= t_max_z && t_max_y <= t_max_x)
430 t_max_y += t_delta_y;
435 t_max_z += t_delta_z;
443#define PCL_INSTANTIATE_VoxelGridOcclusionEstimation(T) template class PCL_EXPORTS pcl::VoxelGridOcclusionEstimation<T>;
void filter(PointCloud &output)
Calls the filtering method and returns the filtered dataset in output.
Eigen::Vector3i getGridCoordinates(float x, float y, float z) const
Returns the corresponding (i,j,k) coordinates in the grid of point (x,y,z).
std::vector< int > leaf_layout_
The leaf layout information for fast access to cells relative to current position.
Eigen::Vector4i divb_mul_
int getCentroidIndexAt(const Eigen::Vector3i &ijk) const
Returns the index in the downsampled cloud corresponding to a given set of coordinates.
Eigen::Vector4i min_b_
The minimum and maximum bin coordinates, the number of divisions, and the division multiplier.
Eigen::Vector4f leaf_size_
The size of a leaf.
void initializeVoxelGrid()
Initialize the voxel grid, needs to be called first Builts the voxel grid and computes additional val...
int occlusionEstimationAll(std::vector< Eigen::Vector3i, Eigen::aligned_allocator< Eigen::Vector3i > > &occluded_voxels)
Computes the voxel coordinates (i, j, k) of all occluded voxels in the voxel grid.
Eigen::Quaternionf sensor_orientation_
float rayBoxIntersection(const Eigen::Vector4f &origin, const Eigen::Vector4f &direction)
Returns the scaling value (tmin) were the ray intersects with the voxel grid bounding box.
int rayTraversal(const Eigen::Vector3i &target_voxel, const Eigen::Vector4f &origin, const Eigen::Vector4f &direction, const float t_min)
Returns the state of the target voxel (0 = visible, 1 = occupied) using a ray traversal algorithm.
PointCloud filtered_cloud_
Eigen::Vector4f sensor_origin_
int occlusionEstimation(int &out_state, const Eigen::Vector3i &in_target_voxel)
Computes the state (free = 0, occluded = 1) of the voxel after utilizing a ray traversal algorithm to...
Eigen::Vector4f getCentroidCoordinate(const Eigen::Vector3i &ijk)
Returns the corresponding centroid (x,y,z) coordinates in the grid of voxel (i,j,k).