@@ -138,24 +138,31 @@ CropBoxFilter::CropBoxFilter(const rclcpp::NodeOptions & node_options)
138138
139139void CropBoxFilter::filter_pointcloud (const PointCloud2ConstPtr & cloud, PointCloud2 & output)
140140{
141- int x_offset = cloud->fields [pcl::getFieldIndex (*cloud, " x" )].offset ;
142- int y_offset = cloud->fields [pcl::getFieldIndex (*cloud, " y" )].offset ;
143- int z_offset = cloud->fields [pcl::getFieldIndex (*cloud, " z" )].offset ;
144-
141+ // set up minimum output metadata required for creating iterators
142+ output.fields = cloud->fields ;
143+ output.point_step = cloud->point_step ;
145144 output.data .resize (cloud->data .size ());
146- size_t output_size = 0 ;
147145
146+ // create output iterators for writing transformed coordinates
147+ sensor_msgs::PointCloud2Iterator<float > output_x (output, " x" );
148+ sensor_msgs::PointCloud2Iterator<float > output_y (output, " y" );
149+ sensor_msgs::PointCloud2Iterator<float > output_z (output, " z" );
150+
151+ size_t output_size = 0 ;
148152 int skipped_count = 0 ;
149153
150- // pointcloud processing loop
151- for (size_t global_offset = 0 ; global_offset + cloud->point_step <= cloud->data .size ();
152- global_offset += cloud->point_step ) {
153- // extract point data from point cloud data buffer
154- Eigen::Vector4f point;
154+ // create input iterators for reading coordinates
155+ sensor_msgs::PointCloud2ConstIterator<float > iter_x (*cloud, " x" );
156+ sensor_msgs::PointCloud2ConstIterator<float > iter_y (*cloud, " y" );
157+ sensor_msgs::PointCloud2ConstIterator<float > iter_z (*cloud, " z" );
155158
156- std::memcpy (&point[0 ], &cloud->data [global_offset + x_offset], sizeof (float ));
157- std::memcpy (&point[1 ], &cloud->data [global_offset + y_offset], sizeof (float ));
158- std::memcpy (&point[2 ], &cloud->data [global_offset + z_offset], sizeof (float ));
159+ for (size_t point_index = 0 ; iter_x != iter_x.end ();
160+ ++iter_x, ++iter_y, ++iter_z, ++point_index) {
161+ // extract point data using iterators
162+ Eigen::Vector4f point;
163+ point[0 ] = *iter_x;
164+ point[1 ] = *iter_y;
165+ point[2 ] = *iter_z;
159166 point[3 ] = 1 ;
160167
161168 if (!std::isfinite (point[0 ]) || !std::isfinite (point[1 ]) || !std::isfinite (point[2 ])) {
@@ -176,24 +183,26 @@ void CropBoxFilter::filter_pointcloud(const PointCloud2ConstPtr & cloud, PointCl
176183 point_preprocessed[1 ] > param_.min_y && point_preprocessed[1 ] < param_.max_y &&
177184 point_preprocessed[0 ] > param_.min_x && point_preprocessed[0 ] < param_.max_x ;
178185 if ((!param_.negative && point_is_inside) || (param_.negative && !point_is_inside)) {
179- // apply post-transform if needed
180- if (need_postprocess_transform_) {
181- Eigen::Vector4f point_postprocessed = eigen_transform_postprocess_ * point_preprocessed;
182-
183- memcpy (&output.data [output_size], &cloud->data [global_offset], cloud->point_step );
186+ const size_t global_offset = point_index * cloud->point_step ;
184187
185- std::memcpy (&output.data [output_size + x_offset], &point_postprocessed[0 ], sizeof (float ));
186- std::memcpy (&output.data [output_size + y_offset], &point_postprocessed[1 ], sizeof (float ));
187- std::memcpy (&output.data [output_size + z_offset], &point_postprocessed[2 ], sizeof (float ));
188- } else {
189- memcpy (&output.data [output_size], &cloud->data [global_offset], cloud->point_step );
188+ // copy all fields from input to output
189+ memcpy (&output.data [output_size], &cloud->data [global_offset], cloud->point_step );
190190
191- if (need_preprocess_transform_) {
192- std::memcpy (&output.data [output_size + x_offset], &point_preprocessed[0 ], sizeof (float ));
193- std::memcpy (&output.data [output_size + y_offset], &point_preprocessed[1 ], sizeof (float ));
194- std::memcpy (&output.data [output_size + z_offset], &point_preprocessed[2 ], sizeof (float ));
195- }
191+ // overwrite x, y, z with transformed coordinates using output iterators
192+ if (need_postprocess_transform_) {
193+ Eigen::Vector4f point_postprocessed = eigen_transform_postprocess_ * point_preprocessed;
194+ *output_x = point_postprocessed[0 ];
195+ *output_y = point_postprocessed[1 ];
196+ *output_z = point_postprocessed[2 ];
197+ } else if (need_preprocess_transform_) {
198+ *output_x = point_preprocessed[0 ];
199+ *output_y = point_preprocessed[1 ];
200+ *output_z = point_preprocessed[2 ];
196201 }
202+
203+ ++output_x;
204+ ++output_y;
205+ ++output_z;
197206 output_size += cloud->point_step ;
198207 }
199208 }
@@ -212,9 +221,7 @@ void CropBoxFilter::filter_pointcloud(const PointCloud2ConstPtr & cloud, PointCl
212221 output.header .stamp = cloud->header .stamp ;
213222
214223 output.height = 1 ;
215- output.fields = cloud->fields ;
216224 output.is_bigendian = cloud->is_bigendian ;
217- output.point_step = cloud->point_step ;
218225 output.is_dense = cloud->is_dense ;
219226 output.width = static_cast <uint32_t >(output.data .size () / output.height / output.point_step );
220227 output.row_step = static_cast <uint32_t >(output.data .size () / output.height );
0 commit comments