@@ -49,7 +49,7 @@ void FasterVoxelGridDownsampleFilter::set_voxel_size(
4949}
5050
5151ValidationResult FasterVoxelGridDownsampleFilter::filter (
52- const PointCloud2ConstPtr & input, PointCloud2 & output, const TransformInfo & transform_info )
52+ const PointCloud2ConstPtr & input, PointCloud2 & output)
5353{
5454 const int x_index = find_field_index (*input, " x" );
5555 const int y_index = find_field_index (*input, " y" );
@@ -67,7 +67,7 @@ ValidationResult FasterVoxelGridDownsampleFilter::filter(
6767 return {false , " The intensity field in the input point cloud is not of type UINT8." };
6868 }
6969
70- // Compute the minimum and maximum voxel coordinates
70+ // Compute the voxel-space bounds of all valid points.
7171 Eigen::Vector3i min_voxel, max_voxel;
7272 if (!get_min_max_voxel (input, min_voxel, max_voxel)) {
7373 output = *input;
@@ -77,10 +77,10 @@ ValidationResult FasterVoxelGridDownsampleFilter::filter(
7777 };
7878 }
7979
80- // Storage for mapping voxel coordinates to centroids
80+ // Accumulate one centroid per voxel.
8181 auto voxel_centroid_map = calc_centroids_each_voxel (input, max_voxel, min_voxel);
8282
83- // Initialize the output
83+ // Prepare output metadata and storage.
8484 output.row_step = voxel_centroid_map.size () * input->point_step ;
8585 output.data .resize (output.row_step );
8686 output.width = voxel_centroid_map.size ();
@@ -91,15 +91,15 @@ ValidationResult FasterVoxelGridDownsampleFilter::filter(
9191 output.point_step = input->point_step ;
9292 output.header = input->header ;
9393
94- // Copy the centroids to the output
95- copy_centroids_to_output (voxel_centroid_map, output, transform_info );
94+ // Serialize centroids into the output PointCloud2 buffer.
95+ copy_centroids_to_output (voxel_centroid_map, output);
9696 return {true , " " };
9797}
9898
9999bool FasterVoxelGridDownsampleFilter::get_min_max_voxel (
100100 const PointCloud2ConstPtr & input, Eigen::Vector3i & min_voxel, Eigen::Vector3i & max_voxel)
101101{
102- // Compute the minimum and maximum point coordinates
102+ // Scan all valid points and track XYZ min/max values.
103103 Eigen::Vector3f min_point, max_point;
104104 min_point.setConstant (FLT_MAX );
105105 max_point.setConstant (-FLT_MAX );
@@ -116,7 +116,7 @@ bool FasterVoxelGridDownsampleFilter::get_min_max_voxel(
116116 }
117117 }
118118
119- // Check that the voxel size is not too small, given the size of the data
119+ // Guard against integer overflow when flattening 3D voxel indices into a 1D id.
120120 if (
121121 ((static_cast <std::int64_t >((max_point[0 ] - min_point[0 ]) * inverse_voxel_size_[0 ]) + 1 ) *
122122 (static_cast <std::int64_t >((max_point[1 ] - min_point[1 ]) * inverse_voxel_size_[1 ]) + 1 ) *
@@ -125,7 +125,7 @@ bool FasterVoxelGridDownsampleFilter::get_min_max_voxel(
125125 return false ;
126126 }
127127
128- // Compute the minimum and maximum voxel coordinates
128+ // Convert point-space bounds to voxel-space bounds.
129129 min_voxel[0 ] = static_cast <int >(std::floor (min_point[0 ] * inverse_voxel_size_[0 ]));
130130 min_voxel[1 ] = static_cast <int >(std::floor (min_point[1 ] * inverse_voxel_size_[1 ]));
131131 min_voxel[2 ] = static_cast <int >(std::floor (min_point[2 ] * inverse_voxel_size_[2 ]));
@@ -142,9 +142,10 @@ FasterVoxelGridDownsampleFilter::calc_centroids_each_voxel(
142142 const Eigen::Vector3i & min_voxel)
143143{
144144 std::unordered_map<uint32_t , Centroid> voxel_centroid_map;
145- // Compute the number of divisions needed along all axis
145+ // Number of voxel bins along each axis within the bounding box.
146146 Eigen::Vector3i div_b = max_voxel - min_voxel + Eigen::Vector3i::Ones ();
147- // Set up the division multiplier
147+ // Strides for flattening voxel coordinates (i, j, k) into one key:
148+ // id = i * 1 + j * div_b[0] + k * (div_b[0] * div_b[1]).
148149 Eigen::Vector3i div_b_mul (1 , div_b[0 ], div_b[0 ] * div_b[1 ]);
149150
150151 sensor_msgs::PointCloud2ConstIterator<float > input_x (*input, " x" );
@@ -155,7 +156,7 @@ FasterVoxelGridDownsampleFilter::calc_centroids_each_voxel(
155156 const Eigen::Vector4f point (
156157 *input_x, *input_y, *input_z, static_cast <float >(*input_intensity));
157158 if (std::isfinite (point[0 ]) && std::isfinite (point[1 ]) && std::isfinite (point[2 ])) {
158- // Calculate the voxel index to which the point belongs
159+ // Compute voxel coordinates relative to the minimum voxel corner.
159160 int ijk0 = static_cast <int >(
160161 std::floor (point[0 ] * inverse_voxel_size_[0 ]) - static_cast <float >(min_voxel[0 ]));
161162 int ijk1 = static_cast <int >(
@@ -164,7 +165,7 @@ FasterVoxelGridDownsampleFilter::calc_centroids_each_voxel(
164165 std::floor (point[2 ] * inverse_voxel_size_[2 ]) - static_cast <float >(min_voxel[2 ]));
165166 uint32_t voxel_id = ijk0 * div_b_mul[0 ] + ijk1 * div_b_mul[1 ] + ijk2 * div_b_mul[2 ];
166167
167- // Add the point to the corresponding centroid
168+ // Start or update the centroid accumulator for this voxel.
168169 if (voxel_centroid_map.find (voxel_id) == voxel_centroid_map.end ()) {
169170 voxel_centroid_map[voxel_id] = Centroid (point[0 ], point[1 ], point[2 ], point[3 ]);
170171 } else {
@@ -177,8 +178,7 @@ FasterVoxelGridDownsampleFilter::calc_centroids_each_voxel(
177178}
178179
179180void FasterVoxelGridDownsampleFilter::copy_centroids_to_output (
180- const std::unordered_map<uint32_t , Centroid> & voxel_centroid_map, PointCloud2 & output,
181- const TransformInfo & transform_info) const
181+ const std::unordered_map<uint32_t , Centroid> & voxel_centroid_map, PointCloud2 & output) const
182182{
183183 sensor_msgs::PointCloud2Iterator<float > output_x (output, " x" );
184184 sensor_msgs::PointCloud2Iterator<float > output_y (output, " y" );
0 commit comments