From cc4d33de0e23aadcd3d4ccbd813a72184fbb38d4 Mon Sep 17 00:00:00 2001 From: Kunal Tyagi Date: Wed, 3 Jun 2020 14:36:00 +0900 Subject: [PATCH] Removing php files --- advanced/c_cache.php | 138 -- advanced/compiler_optimizations.php | 93 - advanced/distcc.php | 239 -- advanced/exceptions_guide.php | 159 -- advanced/how_to_write_a_tutorial.php | 144 -- advanced/html/c_cache.php | 152 -- advanced/html/compiler_optimizations.php | 107 - advanced/html/distcc.php | 253 -- advanced/html/exceptions_guide.php | 171 -- advanced/html/how_to_write_a_tutorial.php | 157 -- advanced/html/index.php | 220 -- advanced/html/minimal_example.php | 132 - advanced/html/pcl2.php | 250 -- advanced/html/pcl_reg_eval.php | 169 -- advanced/html/pcl_registration.php | 316 --- advanced/html/pcl_style_guide.php | 492 ---- advanced/html/roadmap.php | 78 - advanced/html/search.php | 105 - advanced/html/single_compile_unit.php | 125 - advanced/html/vertical_sse.php | 760 ------ advanced/index.php | 158 -- advanced/minimal_example.php | 120 - advanced/pcl2.php | 223 -- advanced/pcl_reg_eval.php | 133 -- advanced/pcl_registration.php | 312 --- advanced/pcl_style_guide.php | 448 ---- advanced/roadmap.php | 66 - advanced/search.php | 88 - advanced/single_compile_unit.php | 110 - advanced/vertical_sse.php | 753 ------ search-config.php | 22 - search-functions.php | 366 --- search-opensearch.php | 127 - search.php | 64 - search_config.php | 22 - search_functions.php | 366 --- search_opensearch.php | 127 - tutorials/adding_custom_ptype.php | 980 -------- tutorials/alignment_prerejective.php | 501 ---- tutorials/basic_structures.php | 156 -- tutorials/benchmark.php | 195 -- tutorials/benchmark_filters.php | 109 - tutorials/bspline_fitting.php | 825 ------- tutorials/building_pcl.php | 366 --- tutorials/cloud_viewer.php | 271 --- tutorials/cluster_extraction.php | 465 ---- .../compiling_pcl_dependencies_windows.php | 354 --- tutorials/compiling_pcl_macosx.php | 367 --- tutorials/compiling_pcl_posix.php | 254 -- tutorials/compiling_pcl_windows.php | 340 --- tutorials/compression.php | 556 ----- tutorials/concatenate_clouds.php | 409 ---- tutorials/concatenate_fields.php | 284 --- tutorials/concatenate_points.php | 282 --- .../conditional_euclidean_clustering.php | 483 ---- tutorials/conditional_removal.php | 276 --- tutorials/convex_hull_2d.php | 247 -- tutorials/correspondence_grouping.php | 1422 ----------- tutorials/cylinder_segmentation.php | 407 ---- tutorials/davidsdk.php | 175 -- tutorials/depth_sense_grabber.php | 145 -- tutorials/dinast_grabber.php | 313 --- tutorials/don_segmentation.php | 780 ------ tutorials/ensenso_cameras.php | 148 -- tutorials/extract_indices.php | 337 --- tutorials/fpfh_estimation.php | 256 -- tutorials/gasd_estimation.php | 243 -- tutorials/generate_local_doc.php | 131 - tutorials/global_hypothesis_verification.php | 1570 ------------ tutorials/gpu_install.php | 202 -- tutorials/gpu_people.php | 331 --- tutorials/greedy_projection.php | 364 --- .../ground_based_rgbd_people_detection.php | 546 ----- tutorials/hdl_grabber.php | 467 ---- tutorials/how_features_work.php | 358 --- tutorials/html/adding_custom_ptype.php | 985 -------- tutorials/html/alignment_prerejective.php | 513 ---- tutorials/html/basic_structures.php | 168 -- tutorials/html/benchmark.php | 206 -- tutorials/html/benchmark_filters.php | 121 - tutorials/html/bspline_fitting.php | 835 ------- tutorials/html/building_pcl.php | 378 --- tutorials/html/cloud_viewer.php | 283 --- tutorials/html/cluster_extraction.php | 481 ---- .../compiling_pcl_dependencies_windows.php | 389 --- tutorials/html/compiling_pcl_macosx.php | 392 --- tutorials/html/compiling_pcl_windows.php | 355 --- tutorials/html/compression.php | 568 ----- tutorials/html/concatenate_clouds.php | 421 ---- tutorials/html/concatenate_fields.php | 296 --- tutorials/html/concatenate_points.php | 294 --- .../html/conditional_euclidean_clustering.php | 493 ---- tutorials/html/conditional_removal.php | 284 --- tutorials/html/convex_hull_2d.php | 259 -- tutorials/html/correspondence_grouping.php | 1443 ----------- tutorials/html/cylinder_segmentation.php | 419 ---- tutorials/html/dinast_grabber.php | 325 --- tutorials/html/don_segmentation.php | 790 ------ tutorials/html/extract_indices.php | 349 --- tutorials/html/fpfh_estimation.php | 268 --- tutorials/html/gpu_install.php | 211 -- tutorials/html/gpu_people.php | 344 --- tutorials/html/greedy_projection.php | 376 --- .../ground_based_rgbd_people_detection.php | 553 ----- tutorials/html/hdl_grabber.php | 479 ---- tutorials/html/how_features_work.php | 397 --- tutorials/html/hull_2d.php | 321 --- tutorials/html/implicit_shape_model.php | 543 ----- tutorials/html/in_hand_scanner.php | 211 -- tutorials/html/index.php | 1698 ------------- tutorials/html/installing_homebrew.php | 128 - tutorials/html/interactive_icp.php | 797 ------ tutorials/html/iterative_closest_point.php | 316 --- tutorials/html/kdtree_search.php | 439 ---- tutorials/html/matrix_transform.php | 631 ----- tutorials/html/min_cut_segmentation.php | 342 --- tutorials/html/mobile_streaming.php | 621 ----- tutorials/html/moment_of_inertia.php | 465 ---- .../html/narf_descriptor_visualization.php | 633 ----- tutorials/html/narf_feature_extraction.php | 618 ----- tutorials/html/narf_keypoint_extraction.php | 567 ----- .../html/normal_distributions_transform.php | 469 ---- tutorials/html/normal_estimation.php | 310 --- ...ormal_estimation_using_integral_images.php | 202 -- tutorials/html/octree.php | 460 ---- tutorials/html/octree_change.php | 375 --- tutorials/html/openni_grabber.php | 413 ---- .../pairwise_incremental_registration.php | 1145 --------- tutorials/html/passthrough.php | 274 --- tutorials/html/pcd_file_format.php | 530 ---- tutorials/html/pcl_painter2D.php | 242 -- tutorials/html/pcl_plotter.php | 521 ---- tutorials/html/pcl_visualizer.php | 1323 ---------- tutorials/html/pfh_estimation.php | 284 --- tutorials/html/planar_segmentation.php | 377 --- .../progressive_morphological_filtering.php | 313 --- tutorials/html/project_inliers.php | 301 --- tutorials/html/qt_visualizer.php | 502 ---- tutorials/html/radius_outlier_removal.php | 263 -- tutorials/html/random_sample_consensus.php | 453 ---- .../html/range_image_border_extraction.php | 540 ----- tutorials/html/range_image_creation.php | 241 -- tutorials/html/range_image_visualization.php | 516 ---- tutorials/html/reading_pcd.php | 217 -- .../html/region_growing_rgb_segmentation.php | 284 --- .../html/region_growing_segmentation.php | 484 ---- tutorials/html/registration_api.php | 234 -- tutorials/html/remove_outliers.php | 359 --- tutorials/html/resampling.php | 252 -- tutorials/html/rops_feature.php | 361 --- tutorials/html/search.php | 105 - tutorials/html/statistical_outlier.php | 281 --- tutorials/html/supervoxel_clustering.php | 626 ----- tutorials/html/template_alignment.php | 1056 -------- tutorials/html/tracking.php | 804 ------- tutorials/html/using_kinfu_large_scale.php | 177 -- tutorials/html/using_pcl_pcl_config.php | 262 -- tutorials/html/using_pcl_with_eclipse.php | 177 -- tutorials/html/vfh_estimation.php | 218 -- tutorials/html/vfh_recognition.php | 1265 ---------- tutorials/html/voxel_grid.php | 225 -- tutorials/html/walkthrough.php | 1054 -------- tutorials/html/writing_new_classes.php | 2126 ----------------- tutorials/html/writing_pcd.php | 259 -- tutorials/hull_2d.php | 309 --- tutorials/implicit_shape_model.php | 512 ---- tutorials/in_hand_scanner.php | 207 -- tutorials/index.php | 1876 --------------- tutorials/installing_homebrew.php | 113 - tutorials/interactive_icp.php | 873 ------- tutorials/iterative_closest_point.php | 305 --- tutorials/kdtree_search.php | 426 ---- tutorials/matrix_transform.php | 620 ----- tutorials/min_cut_segmentation.php | 328 --- tutorials/mobile_streaming.php | 609 ----- tutorials/model_outlier_removal.php | 342 --- tutorials/moment_of_inertia.php | 343 --- tutorials/narf_descriptor_visualization.php | 619 ----- tutorials/narf_feature_extraction.php | 604 ----- tutorials/narf_keypoint_extraction.php | 553 ----- tutorials/normal_distributions_transform.php | 463 ---- tutorials/normal_estimation.php | 298 --- ...ormal_estimation_using_integral_images.php | 190 -- tutorials/octree.php | 448 ---- tutorials/octree_change.php | 363 --- tutorials/openni_grabber.php | 407 ---- .../pairwise_incremental_registration.php | 1133 --------- tutorials/passthrough.php | 262 -- tutorials/pcd_file_format.php | 515 ---- tutorials/pcl_painter2D.php | 230 -- tutorials/pcl_plotter.php | 509 ---- tutorials/pcl_visualizer.php | 1317 ---------- tutorials/pfh_estimation.php | 272 --- tutorials/planar_segmentation.php | 364 --- tutorials/posix_building_pcl.php | 258 -- .../progressive_morphological_filtering.php | 301 --- tutorials/project_inliers.php | 289 --- tutorials/qt_colorize_cloud.php | 548 ----- tutorials/qt_visualizer.php | 484 ---- tutorials/radius_outlier_removal.php | 251 -- tutorials/random_sample_consensus.php | 446 ---- tutorials/range_image_border_extraction.php | 526 ---- tutorials/range_image_creation.php | 229 -- tutorials/range_image_visualization.php | 500 ---- tutorials/reading_pcd.php | 205 -- tutorials/region_growing_rgb_segmentation.php | 280 --- tutorials/region_growing_segmentation.php | 468 ---- tutorials/registration_api.php | 222 -- tutorials/remove_outliers.php | 353 --- tutorials/resampling.php | 240 -- tutorials/rops_feature.php | 349 --- tutorials/search.php | 88 - tutorials/statistical_outlier.php | 269 --- tutorials/supervoxel_clustering.php | 618 ----- tutorials/template_alignment.php | 1053 -------- tutorials/tracking.php | 794 ------ tutorials/using_kinfu_large_scale.php | 165 -- tutorials/using_pcl_pcl_config.php | 250 -- tutorials/using_pcl_with_eclipse.php | 298 --- tutorials/vfh_estimation.php | 205 -- tutorials/vfh_recognition.php | 1241 ---------- tutorials/visualization.php | 253 -- tutorials/voxel_grid.php | 213 -- tutorials/walkthrough.php | 998 -------- tutorials/writing_new_classes.php | 2115 ---------------- tutorials/writing_pcd.php | 239 -- 226 files changed, 96723 deletions(-) delete mode 100644 advanced/c_cache.php delete mode 100644 advanced/compiler_optimizations.php delete mode 100644 advanced/distcc.php delete mode 100644 advanced/exceptions_guide.php delete mode 100644 advanced/how_to_write_a_tutorial.php delete mode 100644 advanced/html/c_cache.php delete mode 100644 advanced/html/compiler_optimizations.php delete mode 100644 advanced/html/distcc.php delete mode 100644 advanced/html/exceptions_guide.php delete mode 100644 advanced/html/how_to_write_a_tutorial.php delete mode 100644 advanced/html/index.php delete mode 100644 advanced/html/minimal_example.php delete mode 100644 advanced/html/pcl2.php delete mode 100644 advanced/html/pcl_reg_eval.php delete mode 100644 advanced/html/pcl_registration.php delete mode 100644 advanced/html/pcl_style_guide.php delete mode 100644 advanced/html/roadmap.php delete mode 100644 advanced/html/search.php delete mode 100644 advanced/html/single_compile_unit.php delete mode 100644 advanced/html/vertical_sse.php delete mode 100644 advanced/index.php delete mode 100644 advanced/minimal_example.php delete mode 100644 advanced/pcl2.php delete mode 100644 advanced/pcl_reg_eval.php delete mode 100644 advanced/pcl_registration.php delete mode 100644 advanced/pcl_style_guide.php delete mode 100644 advanced/roadmap.php delete mode 100644 advanced/search.php delete mode 100644 advanced/single_compile_unit.php delete mode 100644 advanced/vertical_sse.php delete mode 100644 search-config.php delete mode 100644 search-functions.php delete mode 100644 search-opensearch.php delete mode 100644 search.php delete mode 100644 search_config.php delete mode 100644 search_functions.php delete mode 100644 search_opensearch.php delete mode 100644 tutorials/adding_custom_ptype.php delete mode 100644 tutorials/alignment_prerejective.php delete mode 100644 tutorials/basic_structures.php delete mode 100644 tutorials/benchmark.php delete mode 100644 tutorials/benchmark_filters.php delete mode 100644 tutorials/bspline_fitting.php delete mode 100644 tutorials/building_pcl.php delete mode 100644 tutorials/cloud_viewer.php delete mode 100644 tutorials/cluster_extraction.php delete mode 100644 tutorials/compiling_pcl_dependencies_windows.php delete mode 100644 tutorials/compiling_pcl_macosx.php delete mode 100644 tutorials/compiling_pcl_posix.php delete mode 100644 tutorials/compiling_pcl_windows.php delete mode 100644 tutorials/compression.php delete mode 100644 tutorials/concatenate_clouds.php delete mode 100644 tutorials/concatenate_fields.php delete mode 100644 tutorials/concatenate_points.php delete mode 100644 tutorials/conditional_euclidean_clustering.php delete mode 100644 tutorials/conditional_removal.php delete mode 100644 tutorials/convex_hull_2d.php delete mode 100644 tutorials/correspondence_grouping.php delete mode 100644 tutorials/cylinder_segmentation.php delete mode 100644 tutorials/davidsdk.php delete mode 100644 tutorials/depth_sense_grabber.php delete mode 100644 tutorials/dinast_grabber.php delete mode 100644 tutorials/don_segmentation.php delete mode 100644 tutorials/ensenso_cameras.php delete mode 100644 tutorials/extract_indices.php delete mode 100644 tutorials/fpfh_estimation.php delete mode 100644 tutorials/gasd_estimation.php delete mode 100644 tutorials/generate_local_doc.php delete mode 100644 tutorials/global_hypothesis_verification.php delete mode 100644 tutorials/gpu_install.php delete mode 100644 tutorials/gpu_people.php delete mode 100644 tutorials/greedy_projection.php delete mode 100644 tutorials/ground_based_rgbd_people_detection.php delete mode 100644 tutorials/hdl_grabber.php delete mode 100644 tutorials/how_features_work.php delete mode 100644 tutorials/html/adding_custom_ptype.php delete mode 100644 tutorials/html/alignment_prerejective.php delete mode 100644 tutorials/html/basic_structures.php delete mode 100644 tutorials/html/benchmark.php delete mode 100644 tutorials/html/benchmark_filters.php delete mode 100644 tutorials/html/bspline_fitting.php delete mode 100644 tutorials/html/building_pcl.php delete mode 100644 tutorials/html/cloud_viewer.php delete mode 100644 tutorials/html/cluster_extraction.php delete mode 100644 tutorials/html/compiling_pcl_dependencies_windows.php delete mode 100644 tutorials/html/compiling_pcl_macosx.php delete mode 100644 tutorials/html/compiling_pcl_windows.php delete mode 100644 tutorials/html/compression.php delete mode 100644 tutorials/html/concatenate_clouds.php delete mode 100644 tutorials/html/concatenate_fields.php delete mode 100644 tutorials/html/concatenate_points.php delete mode 100644 tutorials/html/conditional_euclidean_clustering.php delete mode 100644 tutorials/html/conditional_removal.php delete mode 100644 tutorials/html/convex_hull_2d.php delete mode 100644 tutorials/html/correspondence_grouping.php delete mode 100644 tutorials/html/cylinder_segmentation.php delete mode 100644 tutorials/html/dinast_grabber.php delete mode 100644 tutorials/html/don_segmentation.php delete mode 100644 tutorials/html/extract_indices.php delete mode 100644 tutorials/html/fpfh_estimation.php delete mode 100644 tutorials/html/gpu_install.php delete mode 100644 tutorials/html/gpu_people.php delete mode 100644 tutorials/html/greedy_projection.php delete mode 100644 tutorials/html/ground_based_rgbd_people_detection.php delete mode 100644 tutorials/html/hdl_grabber.php delete mode 100644 tutorials/html/how_features_work.php delete mode 100644 tutorials/html/hull_2d.php delete mode 100644 tutorials/html/implicit_shape_model.php delete mode 100644 tutorials/html/in_hand_scanner.php delete mode 100644 tutorials/html/index.php delete mode 100644 tutorials/html/installing_homebrew.php delete mode 100644 tutorials/html/interactive_icp.php delete mode 100644 tutorials/html/iterative_closest_point.php delete mode 100644 tutorials/html/kdtree_search.php delete mode 100644 tutorials/html/matrix_transform.php delete mode 100644 tutorials/html/min_cut_segmentation.php delete mode 100644 tutorials/html/mobile_streaming.php delete mode 100644 tutorials/html/moment_of_inertia.php delete mode 100644 tutorials/html/narf_descriptor_visualization.php delete mode 100644 tutorials/html/narf_feature_extraction.php delete mode 100644 tutorials/html/narf_keypoint_extraction.php delete mode 100644 tutorials/html/normal_distributions_transform.php delete mode 100644 tutorials/html/normal_estimation.php delete mode 100644 tutorials/html/normal_estimation_using_integral_images.php delete mode 100644 tutorials/html/octree.php delete mode 100644 tutorials/html/octree_change.php delete mode 100644 tutorials/html/openni_grabber.php delete mode 100644 tutorials/html/pairwise_incremental_registration.php delete mode 100644 tutorials/html/passthrough.php delete mode 100644 tutorials/html/pcd_file_format.php delete mode 100644 tutorials/html/pcl_painter2D.php delete mode 100644 tutorials/html/pcl_plotter.php delete mode 100644 tutorials/html/pcl_visualizer.php delete mode 100644 tutorials/html/pfh_estimation.php delete mode 100644 tutorials/html/planar_segmentation.php delete mode 100644 tutorials/html/progressive_morphological_filtering.php delete mode 100644 tutorials/html/project_inliers.php delete mode 100644 tutorials/html/qt_visualizer.php delete mode 100644 tutorials/html/radius_outlier_removal.php delete mode 100644 tutorials/html/random_sample_consensus.php delete mode 100644 tutorials/html/range_image_border_extraction.php delete mode 100644 tutorials/html/range_image_creation.php delete mode 100644 tutorials/html/range_image_visualization.php delete mode 100644 tutorials/html/reading_pcd.php delete mode 100644 tutorials/html/region_growing_rgb_segmentation.php delete mode 100644 tutorials/html/region_growing_segmentation.php delete mode 100644 tutorials/html/registration_api.php delete mode 100644 tutorials/html/remove_outliers.php delete mode 100644 tutorials/html/resampling.php delete mode 100644 tutorials/html/rops_feature.php delete mode 100644 tutorials/html/search.php delete mode 100644 tutorials/html/statistical_outlier.php delete mode 100644 tutorials/html/supervoxel_clustering.php delete mode 100644 tutorials/html/template_alignment.php delete mode 100644 tutorials/html/tracking.php delete mode 100644 tutorials/html/using_kinfu_large_scale.php delete mode 100644 tutorials/html/using_pcl_pcl_config.php delete mode 100644 tutorials/html/using_pcl_with_eclipse.php delete mode 100644 tutorials/html/vfh_estimation.php delete mode 100644 tutorials/html/vfh_recognition.php delete mode 100644 tutorials/html/voxel_grid.php delete mode 100644 tutorials/html/walkthrough.php delete mode 100644 tutorials/html/writing_new_classes.php delete mode 100644 tutorials/html/writing_pcd.php delete mode 100644 tutorials/hull_2d.php delete mode 100644 tutorials/implicit_shape_model.php delete mode 100644 tutorials/in_hand_scanner.php delete mode 100644 tutorials/index.php delete mode 100644 tutorials/installing_homebrew.php delete mode 100644 tutorials/interactive_icp.php delete mode 100644 tutorials/iterative_closest_point.php delete mode 100644 tutorials/kdtree_search.php delete mode 100644 tutorials/matrix_transform.php delete mode 100644 tutorials/min_cut_segmentation.php delete mode 100644 tutorials/mobile_streaming.php delete mode 100644 tutorials/model_outlier_removal.php delete mode 100644 tutorials/moment_of_inertia.php delete mode 100644 tutorials/narf_descriptor_visualization.php delete mode 100644 tutorials/narf_feature_extraction.php delete mode 100644 tutorials/narf_keypoint_extraction.php delete mode 100644 tutorials/normal_distributions_transform.php delete mode 100644 tutorials/normal_estimation.php delete mode 100644 tutorials/normal_estimation_using_integral_images.php delete mode 100644 tutorials/octree.php delete mode 100644 tutorials/octree_change.php delete mode 100644 tutorials/openni_grabber.php delete mode 100644 tutorials/pairwise_incremental_registration.php delete mode 100644 tutorials/passthrough.php delete mode 100644 tutorials/pcd_file_format.php delete mode 100644 tutorials/pcl_painter2D.php delete mode 100644 tutorials/pcl_plotter.php delete mode 100644 tutorials/pcl_visualizer.php delete mode 100644 tutorials/pfh_estimation.php delete mode 100644 tutorials/planar_segmentation.php delete mode 100644 tutorials/posix_building_pcl.php delete mode 100644 tutorials/progressive_morphological_filtering.php delete mode 100644 tutorials/project_inliers.php delete mode 100644 tutorials/qt_colorize_cloud.php delete mode 100644 tutorials/qt_visualizer.php delete mode 100644 tutorials/radius_outlier_removal.php delete mode 100644 tutorials/random_sample_consensus.php delete mode 100644 tutorials/range_image_border_extraction.php delete mode 100644 tutorials/range_image_creation.php delete mode 100644 tutorials/range_image_visualization.php delete mode 100644 tutorials/reading_pcd.php delete mode 100644 tutorials/region_growing_rgb_segmentation.php delete mode 100644 tutorials/region_growing_segmentation.php delete mode 100644 tutorials/registration_api.php delete mode 100644 tutorials/remove_outliers.php delete mode 100644 tutorials/resampling.php delete mode 100644 tutorials/rops_feature.php delete mode 100644 tutorials/search.php delete mode 100644 tutorials/statistical_outlier.php delete mode 100644 tutorials/supervoxel_clustering.php delete mode 100644 tutorials/template_alignment.php delete mode 100644 tutorials/tracking.php delete mode 100644 tutorials/using_kinfu_large_scale.php delete mode 100644 tutorials/using_pcl_pcl_config.php delete mode 100644 tutorials/using_pcl_with_eclipse.php delete mode 100644 tutorials/vfh_estimation.php delete mode 100644 tutorials/vfh_recognition.php delete mode 100644 tutorials/visualization.php delete mode 100644 tutorials/voxel_grid.php delete mode 100644 tutorials/walkthrough.php delete mode 100644 tutorials/writing_new_classes.php delete mode 100644 tutorials/writing_pcd.php diff --git a/advanced/c_cache.php b/advanced/c_cache.php deleted file mode 100644 index 877154e64368..000000000000 --- a/advanced/c_cache.php +++ /dev/null @@ -1,138 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Using CCache to speed up compilation - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Using CCache to speed up compilation

-

CCache is nothing more than a cache for your -compiler. ccache is usually very easy to install. Here’s an example for Ubuntu -systems:

-
sudo apt-get install ccache
-
-
-

ccache will cache previous compilations, detect when the same compilation -is being done again, and reuse its cache instead of recompiling the source code -again. This can speed up your compilation by many orders of magnitude, -especially in those situations where your file timestamps change, and make -is triggering a recompile.

-

To enable ccache, simply add ‘/usr/lib/ccache’ to the beginning of your PATH. -This directory contains symlinks to ccache, and ccache is smart enough to -look at the name of the calling executable to determine which real executable -to run. I.e. there is a symlink from ‘/usr/lib/ccache/g++’ to just ‘ccache’, -but it actually runs the equivalent of ‘ccache g++’.

-
-
-

Using colorgcc to colorize output

-

colorgcc is a colorizer for the output -of GCC, and allows you to better interpret the compiler warnings/errors.

-

To enable both colorgcc and ccache, perform the following steps:

-

Install colorgcc on an Ubuntu system with

-
sudo apt-get install colorgcc
-
-
-

To enable colorgcc, perform the following steps:

-
cp /etc/colorgcc/colorgccrc $HOME/.colorgccrc
-
-
-
    -
  • edit the $HOME/.colorgccrc file, search for the following lines:

  • -
-
g++: /usr/bin/g++
-gcc: /usr/bin/gcc
-c++: /usr/bin/g++
-cc:  /usr/bin/gcc
-g77: /usr/bin/g77
-f77: /usr/bin/g77
-gcj: /usr/bin/gcj
-
-
-

and replace them with:

-
g++: ccache /usr/bin/g++
-gcc: ccache /usr/bin/gcc
-c++: ccache /usr/bin/g++
-cc:  ccache /usr/bin/gcc
-g77: ccache /usr/bin/g77
-f77: ccache /usr/bin/g77
-gcj: ccache /usr/bin/gcj
-
-
-
    -
  • create a $HOME/bin or $HOME/sbin directory, and create the following softlinks in it

  • -
-
ln -s /usr/bin/colorgcc c++
-ln -s /usr/bin/colorgcc cc
-ln -s /usr/bin/colorgcc g++
-ln -s /usr/bin/colorgcc gcc
-
-
-

make sure that $HOME/bin or $HOME/sbin is the first directory in your $PATH, e.g.:

-
export PATH=$HOME/bin:$PATH
-
-
-

or:

-
export PATH=$HOME/sbin:$PATH
-
-
-

depending on where you stored the colorgcc softlinks, so that when -cc/gcc/g++/c++ is invoked the freshly created softlinks get activated first and -not the global /usr/bin/{cc,gcc,g++,c++}.

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/compiler_optimizations.php b/advanced/compiler_optimizations.php deleted file mode 100644 index 3f7672c6971b..000000000000 --- a/advanced/compiler_optimizations.php +++ /dev/null @@ -1,93 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Compiler optimizations - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Compiler optimizations

-

Using excessive compiler optimizations can really hurt your compile-time -performance, and there’s a question whether you really need these optimizations -everytime you recompile to prototype something new, or whether you can live -with a less optimal binary for testing things. Obviously once your tests -succeed and you want to deploy your project, you can simply re-enable the -compiler optimizations. Here’s a few tests that we did a while back with -pcl_ros:

-
-j1, RelWithDebInfo + O3 : 3m20.376s -j1, RelWithDebInfo : 2m48.064s
--j1, Debug : 2m0.452s
--j2, Debug : 1m8.151s
--j4, Debug : 0m42.846s
-
-
-

In general, we got used to enable all compiler optimizations possible. In PCL -pre-0.4, this is how the CMakeLists.txt file looked like:

-
add_definitions(-Wall -O3 -DNDEBUG -pipe -ffast-math -funroll-loops -ftree-vectorize -fomit-frame-pointer -pipe -mfpmath=sse -mmmx -msse -mtune=core2 -march=core2 -msse2 -msse3 -mssse3 -msse4)
-#add_definitions(-momit-leaf-frame-pointer -fomit-frame-pointer -floop-block -ftree-loop-distribution -ftree-loop-linear -floop-interchange -floop-strip-mine -fgcse-lm -fgcse-sm -fsched-spec-load)
-add_definitions (-Wall -O3 -Winvalid-pch -pipe -funroll-loops -fno-strict-aliasing)
-
-
-

Obviously, not all those flags were enabled by default, but we were definitely -playing around with them, and sometimes committing them to the repository, -which led to increase compilation times for some of the projects that needed to -precompile/use PCL.

-

In general there is no good rule of thumb here, but we decided to disable these -excessive optimizations by default, and rely on CMake’s RelWithDebInfo by -default. You should do the same too when you prototype.

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/distcc.php b/advanced/distcc.php deleted file mode 100644 index e420ff7d43a2..000000000000 --- a/advanced/distcc.php +++ /dev/null @@ -1,239 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Using DistCC to speed up compilation - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Using DistCC to speed up compilation

-

distcc is a program to distribute builds of C, C++, -Objective C or Objective C++ code across several machines on a network. -distcc should always generate the same results as a local build, is simple to -install and use, and is usually much faster than a local compile.

-

distcc does not require all machines to share a filesystem, have synchronized -clocks, or to have the same libraries or header files installed. They can even -have different processors or operating systems, if cross-compilers are -installed.

-

distcc is usually very easy to install – just follow the installation -instructions on its web page. Here’s an example for Ubuntu systems:

-
sudo apt-get install distcc
-
-
-

In each distributed build environment, there are usually two different roles:

-
-
    -
  • server

    -

    Here, we call the server, the actual workstation/computer that is running -a distcc daemon, and will perform the compilation. To run a distcc -daemon on an Ubuntu system for example, you need to start the daemon, -usually with something along the lines of:

    -
    /etc/init.d/distcc start
    -
    -
    -

    Once started, you should notice a few distcc processes idle-ing:

    -
    $ ps axw | grep distcc
    -...
    -30042 ?        SN     0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
    -30043 ?        SN     0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
    -30044 ?        SN     0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
    -
    -
    -

    Let’s assume for the sake of this example, that we have two machines, -wgsc11 and wgsc12, with distcc installed and running as a server -daemon. These are the machines that we would like use to speed up the -compilation of the PCL source tree.

    -
  • -
  • client

    -

    Here by client we refer to the workstation/computer that contains the source -code to be compiled, in our case, where the PCL source code tree resides.

    -

    The first thing that we need to do is tell cmake to use distcc instead -of the default compiler. The easiest way to do this is to invoke cmake -with pre-flags, like:

    -
    [pcl] $ mkdir build && cd build
    -[pcl/build] $ CC="distcc gcc" CXX="distcc g++" cmake ..
    -
    -
    -

    Sometimes compiling on systems supporting different SSE extensions will lead -to problems. Setting PCL_ENABLE_SSE to false will solve this, like:

    -
    [pcl/build] $ CC="distcc gcc" CXX="distcc g++" cmake -DPCL_ENABLE_SSE:BOOL=FALSE ../pcl
    -
    -
    -

    The output of CC="distcc gcc" CXX="distcc g++" cmake .. will generate -something like this. Please note that this is just an example and that the -messages might vary depending on your operating system and the way your -library dependencies were compiled/installed:

    -
    -- The C compiler identification is GNU
    --- The CXX compiler identification is GNU
    --- Check for working C compiler: /usr/bin/distcc
    --- Check for working C compiler: /usr/bin/distcc -- works
    --- Detecting C compiler ABI info
    --- Detecting C compiler ABI info - done
    --- Check for working CXX compiler: /usr/bin/distcc
    --- Check for working CXX compiler: /usr/bin/distcc -- works
    --- Detecting CXX compiler ABI info
    --- Detecting CXX compiler ABI info - done
    --- Performing Test HAVE_SSE3_EXTENSIONS
    --- Performing Test HAVE_SSE3_EXTENSIONS - Success
    --- Performing Test HAVE_SSE2_EXTENSIONS
    --- Performing Test HAVE_SSE2_EXTENSIONS - Success
    --- Performing Test HAVE_SSE_EXTENSIONS
    --- Performing Test HAVE_SSE_EXTENSIONS - Success
    --- Found SSE3 extensions, using flags: -msse3 -mfpmath=sse
    --- Boost version: 1.42.0
    --- Found the following Boost libraries:
    ---   system
    ---   filesystem
    ---   thread
    ---   date_time
    ---   iostreams
    --- checking for module 'eigen3'
    ---   found eigen3, version 3.0.0
    --- Found Eigen: /usr/include/eigen3
    --- Eigen found (include: /usr/include/eigen3)
    --- checking for module 'flann'
    ---   found flann, version 1.6.8
    --- Found Flann: /usr/lib64/libflann_cpp_s.a
    --- FLANN found (include: /usr/include, lib: optimized;/usr/lib64/libflann_cpp_s.a;debug;/usr/lib64/libflann_cpp.so)
    --- checking for module 'cminpack'
    ---   found cminpack, version 1.0.90
    --- Found CMinpack: /usr/lib64/libcminpack.so
    --- CMinPack found (include: /usr/include/cminpack-1, libs: optimized;/usr/lib64/libcminpack.so;debug;/usr/lib64/libcminpack.so)
    --- Try OpenMP C flag = [-fopenmp]
    --- Performing Test OpenMP_FLAG_DETECTED
    --- Performing Test OpenMP_FLAG_DETECTED - Success
    --- Try OpenMP CXX flag = [-fopenmp]
    --- Performing Test OpenMP_FLAG_DETECTED
    --- Performing Test OpenMP_FLAG_DETECTED - Success
    --- Found OpenMP: -fopenmp
    --- Found OpenNI: /usr/lib/libOpenNI.so
    --- OpenNI found (include: /usr/include/openni, lib: /usr/lib/libOpenNI.so)
    --- ROS_ROOT /opt/ros/diamondback/ros
    --- Found ROS; USE_ROS is OFF
    --- Found GTest: /usr/lib/libgtest.so
    --- Tests will be built
    --- Found Qhull: /usr/lib/libqhull.so
    --- QHULL found (include: /usr/include/qhull, lib: optimized;/usr/lib/libqhull.so;debug;/usr/lib/libqhull.so)
    --- VTK found (include: /usr/include/vtk-5.4;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/lib/openmpi/include;/usr/lib/openmpi/include/openmpi;/usr/include/tcl8.5;/usr/include/python2.6;/usr/include/tcl8.5;/usr/lib/jvm/default-java/include;/usr/lib/jvm/default-java/include;/usr/lib/jvm/default-java/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include/libxml2;/usr/include;/usr/include/freetype2, lib: /usr/lib/vtk-5.4)
    --- Found Doxygen: /usr/bin/doxygen
    --- Found CPack generators: DEB
    --- The following subsystems will be built:
    ---   common
    ---   octree
    ---   io
    ---   kdtree
    ---   range_image
    ---   features
    ---   sample_consensus
    ---   keypoints
    ---   filters
    ---   registration
    ---   segmentation
    ---   surface
    ---   visualization
    ---   global_tests
    --- The following subsystems will not be built:
    --- Configuring done
    --- Generating done
    --- Build files have been written to: /work/PCL/pcl/trunk/build
    -
    -
    -
  • -
-
-

The important lines are:

-
-- Check for working C compiler: /usr/bin/distcc
--- Check for working C compiler: /usr/bin/distcc -- works
--- Detecting C compiler ABI info
--- Detecting C compiler ABI info - done
--- Check for working CXX compiler: /usr/bin/distcc
--- Check for working CXX compiler: /usr/bin/distcc -- works
-
-
-

The next step is to tell distcc which hosts it should use. Here we can -decide whether we want to use the local workstation for compilation too, or -just the machines running a distcc daemon (wgsc11 and wgsc12 in our -example). The easiest way to pass this information to distcc is via -environment variables. For example:

-
export DISTCC_HOSTS='localhost wgsc11 wgsc12'
-
-
-

will tell distcc to use the local machine, as well as both the distcc -servers, while:

-
export DISTCC_HOSTS='wgsc11 wgsc12'
-
-
-

will only use the wgsc11 and wgsc12 machines.

-

Finally, the last step is to increase the number of parallel compile units we should use. For example:

-
[pcl/build] $ make -j32
-
-
-

will start 32 processes and distribute them equally on the two distcc machines.

-
-
-

The following plot shows an example of multiple make -jX invocations, for X -ranging from 1 to 13. As it can be seen, the overall compile time is -drastically reduced by using distcc, in this case with the CPU on the client -machine almost idleing while the wgsc11 and wgsc12 machines do most of the -work. The reason why the plot “saturates” is due to conditional dependencies in -the compilation process, where certain libraries or binaries require others to -be compiled first.

-_images/distcc_plot.png -

For more information on how to configure distcc please visit http://distcc.org.

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/exceptions_guide.php b/advanced/exceptions_guide.php deleted file mode 100644 index 4a11c5a4a8e2..000000000000 --- a/advanced/exceptions_guide.php +++ /dev/null @@ -1,159 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Exceptions in PCL - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Exceptions in PCL

-

There have been a multitude of discussions in the past regarding exceptions in -PCL (see http://www.pcl-developers.org/to-throw-or-not-to-throw-td4828759.html -for an example). Herein, we discuss the major points with respect to writing -and using exceptions.

-
-

Adding a new Exception

-

Any new exception should inherit from the :pcl:`PCLException <pcl::PCLException>` class in -pcl/exceptions.h

-
/** \class MyException
-  * \brief An exception that is thrown when I want it.
-  */
-
-class PCL_EXPORTS MyException : public PCLException
-{
-  public:
-    MyException (const std::string& error_description,
-                 const char* file_name = NULL,
-                 const char* function_name = NULL,
-                 unsigned line_number = 0)
-      : pcl::PCLException (error_description, file_name, function_name, line_number) { }
-};
-
-
-
-
-

Using Exceptions

-

For ease of use we provide this macro

-
#define PCL_THROW_EXCEPTION (ExceptionName, message)
-{
-  std::ostringstream s;
-  s << message;
-  throw ExceptionName (s.str (), __FILE__, BOOST_CURRENT_FUNCTION, __LINE__);
-}
-
-
-

Then in your code, add:

-
if (my_requirements != the_parameters_used_)
-  PCL_THROW_EXCEPTION (MyException, "my requirements are not met " << the_parameters_used);
-
-
-

This will set the file name and the line number thanks to the macro definition. -Take care of the message: it is the most important part of the exception. You -can profit of the std::ostringstream used in the macro, so you can append -variable names to variable values and so on to make it really explicit. Also -something really important is when the method you are writing can throw an -exception, please add this to the the function documentation:

-
/** Function that does cool stuff
-  * \param nb number of points
-  * \throws MyException
-  */
-void
-myFunction (int nb);
-
-
-

This will be parsed by Doxygen and made available in the generated API -documentation so the person that would use your function knows that they have -to deal with an exception called MyException.

-
-
-

Exceptions handling

-

To properly handle exceptions you need to use the trycatch block.

-
// Here we call myFunction which can throw MyException
-try
-{
-  myObject.myFunction (some_number);
-  // You can put more exceptions throwing instruction within same try block
-}
-// We catch only MyException to be very specific
-catch (pcl::MyException& e)
-{
-  // Code to deal with the exception maybe changing myObject.the_parameters_used_
-}
-
-// Here we catch any exception
-#if 0
-catch (exception& e)
-{
-  // Code to deal with the exception maybe changing myObject.the_parameters_used_
-}
-#endif
-
-
-

Exceptions handling is really context dependent so there is no general -rule that can be applied but here are some of the most used guidelines:

-
-
    -
  • exit with some error if the exception is critical

  • -
  • modify the parameters for the function that threw the exception and recall it again

  • -
  • throw an exception with a meaningful message saying that you encountred an exception

  • -
  • continue (really bad)

  • -
-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/how_to_write_a_tutorial.php b/advanced/how_to_write_a_tutorial.php deleted file mode 100644 index 2b2e65f8b9d6..000000000000 --- a/advanced/how_to_write_a_tutorial.php +++ /dev/null @@ -1,144 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - How to write a good tutorial - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

How to write a good tutorial

-

No matter how many tutorials we create and upload at -www.pointclouds.org/documentation/tutorials, there are never going to be -enough. :) As our code base and user base are growing, so is the demand for -detailed explanations or step-by-step/how-to documentation increasing. This -short guide will help you understand how you can contribute documentation -and help improve the project.

-

The Point Cloud Library (PCL) documentation infrastructure has two distinct -parts:

-

1. API documentation – we are using -Doxygen to automatically generate the best -possible API documentation, directly from our source files;

-

2. Tutorials and HowTo documents -– we are using Restructured Text -via Sphinx to transform simple reST files into -beautiful HTML documents.

-

Both documentation sources are stored in our Source repository and the web pages are generated -hourly by our server via crontab jobs.

-

In the next two sections we will address both of the above, and present a small -example for each. We’ll begin with the easiest of the two: adding a new -tutorial.

-
-
-

Creating a new tutorial

-

As already mentioned, we make use of Sphinx to generate HTML files from reST -(restructured text) documents. If you want to add a new tutorial, we suggest -you read the following resources:

-
-
-
-

Once you understand how reST works, look over our current set of tutorials for -examples at https://github.com/PointCloudLibrary/pcl/tree/master/doc/tutorials/content.

-

To add a new tutorial, simply create a new file, and send it to us together -with the images/videos that you want included in the tutorial. The best way to -do this is to login to https://github.com/PointCloudLibrary/pcl and send it as -a pull request.

-
-
-

Improving the API documentation

-

Providing a good API documentation is not easy – as finding a balance between -the amount of information that you present for each function, versus keeping it -clean and simple is ermmm, a challenge in itself. Differently said, it’s hard -to know what sort of people will look at the API: hardcore developers or first -time users.

-

Our solution is to document the API as best as possible, but leave certain more -complex details such as application examples for the tutorials. However, while -this is a nice goal, it’s very improbable that our documentation is perfect.

-

To help us improve the API documentation, all that you need to do is simply -check out the source code of PCL (we recommend trunk if you’re going to start -editing the sources), like:

-
git clone https://github.com/PointCloudLibrary/pcl
-
-
-

Then, edit the file containing the function/class that you want to improve the -documentation for, say common/include/pcl/point_cloud.h, and go to the -element that you want to improve. Let’s take points for example:

-
/** \brief The point data. */
-std::vector<PointT, Eigen::aligned_allocator<PointT> > points;
-
-
-

What you have to modify is the Doxygen-style comment starting with /** and -ending with */. See http://www.doxygen.org for more information.

-

To send us the modification, please send a pull request through Github.

-
-
-

Testing the modified API documentation

-

If you want to test it locally on your machine, make sure you have Doxygen -installed, and go into the build system (here we assume that you followed the -source installation instructions from -http://www.pointclouds.org/downloads) and run:

-
make doc
-
-
-

This will create a set of html files containing the API documentation for PCL, -in build/html/

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/c_cache.php b/advanced/html/c_cache.php deleted file mode 100644 index 8ef14cb1fe98..000000000000 --- a/advanced/html/c_cache.php +++ /dev/null @@ -1,152 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Using CCache to speed up compilation - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Using CCache to speed up compilation

-

CCache is nothing more than a cache for your -compiler. ccache is usually very easy to install. Here’s an example for Ubuntu -systems:

-
sudo apt-get install ccache
-
-
-

ccache will cache previous compilations, detect when the same compilation -is being done again, and reuse its cache instead of recompiling the source code -again. This can speed up your compilation by many orders of magnitude, -especially in those situations where your file timestamps change, and make -is triggering a recompile.

-

To enable ccache, simply add ‘/usr/lib/ccache’ to the beginning of your PATH. -This directory contains symlinks to ccache, and ccache is smart enough to -look at the name of the calling executable to determine which real executable -to run. I.e. there is a symlink from ‘/usr/lib/ccache/g++’ to just ‘ccache’, -but it actually runs the equivalent of ‘ccache g++’.

-
-
-

Using colorgcc to colorize output

-

`colorgcc<https://github.com/johannes/colorgcc>`_ is a colorizer for the output -of GCC, and allows you to better interpret the compiler warnings/errors.

-

To enable both colorgcc and ccache, perform the following steps:

-

Install colorgcc on an Ubuntu system with

-
sudo apt-get install colorgcc
-
-
-

To enable colorgcc, perform the following steps:

-
cp /etc/colorgcc/colorgccrc $HOME/.colorgccrc
-
-
-
    -
  • edit the $HOME/.colorgccrc file, search for the following lines:
  • -
-
g++: /usr/bin/g++
-gcc: /usr/bin/gcc
-c++: /usr/bin/g++
-cc:  /usr/bin/gcc
-g77: /usr/bin/g77
-f77: /usr/bin/g77
-gcj: /usr/bin/gcj
-
-
-

and replace them with:

-
g++: ccache /usr/bin/g++
-gcc: ccache /usr/bin/gcc
-c++: ccache /usr/bin/g++
-cc:  ccache /usr/bin/gcc
-g77: ccache /usr/bin/g77
-f77: ccache /usr/bin/g77
-gcj: ccache /usr/bin/gcj
-
-
-
    -
  • create a $HOME/bin or $HOME/sbin directory, and create the following softlinks in it
  • -
-
ln -s /usr/bin/colorgcc c++
-ln -s /usr/bin/colorgcc cc
-ln -s /usr/bin/colorgcc g++
-ln -s /usr/bin/colorgcc gcc
-
-
-

make sure that $HOME/bin or $HOME/sbin is the first directory in your $PATH, e.g.:

-
export PATH=$HOME/bin:$PATH
-
-
-

or:

-
export PATH=$HOME/sbin:$PATH
-
-
-

depending on where you stored the colorgcc softlinks, so that when -cc/gcc/g++/c++ is invoked the freshly created softlinks get activated first and -not the global /usr/bin/{cc,gcc,g++,c++}.

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/compiler_optimizations.php b/advanced/html/compiler_optimizations.php deleted file mode 100644 index 7af3dbc5ea67..000000000000 --- a/advanced/html/compiler_optimizations.php +++ /dev/null @@ -1,107 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Compiler optimizations - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Compiler optimizations

-

Using excessive compiler optimizations can really hurt your compile-time -performance, and there’s a question whether you really need these optimizations -everytime you recompile to prototype something new, or whether you can live -with a less optimal binary for testing things. Obviously once your tests -succeed and you want to deploy your project, you can simply re-enable the -compiler optimizations. Here’s a few tests that we did a while back with -pcl_ros:

-
-j1, RelWithDebInfo + O3 : 3m20.376s -j1, RelWithDebInfo : 2m48.064s
--j1, Debug : 2m0.452s
--j2, Debug : 1m8.151s
--j4, Debug : 0m42.846s
-
-
-

In general, we got used to enable all compiler optimizations possible. In PCL -pre-0.4, this is how the CMakeLists.txt file looked like:

-
add_definitions(-Wall -O3 -DNDEBUG -pipe -ffast-math -funroll-loops -ftree-vectorize -fomit-frame-pointer -pipe -mfpmath=sse -mmmx -msse -mtune=core2 -march=core2 -msse2 -msse3 -mssse3 -msse4)
-#add_definitions(-momit-leaf-frame-pointer -fomit-frame-pointer -floop-block -ftree-loop-distribution -ftree-loop-linear -floop-interchange -floop-strip-mine -fgcse-lm -fgcse-sm -fsched-spec-load)
-add_definitions (-Wall -O3 -Winvalid-pch -pipe -funroll-loops -fno-strict-aliasing)
-
-
-

Obviously, not all those flags were enabled by default, but we were definitely -playing around with them, and sometimes committing them to the repository, -which led to increase compilation times for some of the projects that needed to -precompile/use PCL.

-

In general there is no good rule of thumb here, but we decided to disable these -excessive optimizations by default, and rely on CMake’s RelWithDebInfo by -default. You should do the same too when you prototype.

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/distcc.php b/advanced/html/distcc.php deleted file mode 100644 index a218e8dd8773..000000000000 --- a/advanced/html/distcc.php +++ /dev/null @@ -1,253 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Using DistCC to speed up compilation - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Using DistCC to speed up compilation

-

distcc is a program to distribute builds of C, C++, -Objective C or Objective C++ code across several machines on a network. -distcc should always generate the same results as a local build, is simple to -install and use, and is usually much faster than a local compile.

-

distcc does not require all machines to share a filesystem, have synchronized -clocks, or to have the same libraries or header files installed. They can even -have different processors or operating systems, if cross-compilers are -installed.

-

distcc is usually very easy to install – just follow the installation -instructions on its web page. Here’s an example for Ubuntu systems:

-
sudo apt-get install distcc
-
-
-

In each distributed build environment, there are usually two different roles:

-
-
    -
  • server

    -

    Here, we call the server, the actual workstation/computer that is running -a distcc daemon, and will perform the compilation. To run a distcc -daemon on an Ubuntu system for example, you need to start the daemon, -usually with something along the lines of:

    -
    /etc/init.d/distcc start
    -
    -
    -

    Once started, you should notice a few distcc processes idle-ing:

    -
    $ ps axw | grep distcc
    -...
    -30042 ?        SN     0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
    -30043 ?        SN     0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
    -30044 ?        SN     0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
    -
    -
    -

    Let’s assume for the sake of this example, that we have two machines, -wgsc11 and wgsc12, with distcc installed and running as a server -daemon. These are the machines that we would like use to speed up the -compilation of the PCL source tree.

    -
  • -
  • client

    -

    Here by client we refer to the workstation/computer that contains the source -code to be compiled, in our case, where the PCL source code tree resides.

    -

    The first thing that we need to do is tell cmake to use distcc instead -of the default compiler. The easiest way to do this is to invoke cmake -with pre-flags, like:

    -
    [pcl] $ mkdir build && cd build
    -[pcl/build] $ CC="distcc gcc" CXX="distcc g++" cmake ..
    -
    -
    -

    Sometimes compiling on systems supporting different SSE extensions will lead -to problems. Setting PCL_ENABLE_SSE to false will solve this, like:

    -
    [pcl/build] $ CC="distcc gcc" CXX="distcc g++" cmake -DPCL_ENABLE_SSE:BOOL=FALSE ../pcl
    -
    -
    -

    The output of CC="distcc gcc" CXX="distcc g++" cmake .. will generate -something like this. Please note that this is just an example and that the -messages might vary depending on your operating system and the way your -library dependencies were compiled/installed:

    -
    -- The C compiler identification is GNU
    --- The CXX compiler identification is GNU
    --- Check for working C compiler: /usr/bin/distcc
    --- Check for working C compiler: /usr/bin/distcc -- works
    --- Detecting C compiler ABI info
    --- Detecting C compiler ABI info - done
    --- Check for working CXX compiler: /usr/bin/distcc
    --- Check for working CXX compiler: /usr/bin/distcc -- works
    --- Detecting CXX compiler ABI info
    --- Detecting CXX compiler ABI info - done
    --- Performing Test HAVE_SSE3_EXTENSIONS
    --- Performing Test HAVE_SSE3_EXTENSIONS - Success
    --- Performing Test HAVE_SSE2_EXTENSIONS
    --- Performing Test HAVE_SSE2_EXTENSIONS - Success
    --- Performing Test HAVE_SSE_EXTENSIONS
    --- Performing Test HAVE_SSE_EXTENSIONS - Success
    --- Found SSE3 extensions, using flags: -msse3 -mfpmath=sse
    --- Boost version: 1.42.0
    --- Found the following Boost libraries:
    ---   system
    ---   filesystem
    ---   thread
    ---   date_time
    ---   iostreams
    --- checking for module 'eigen3'
    ---   found eigen3, version 3.0.0
    --- Found Eigen: /usr/include/eigen3
    --- Eigen found (include: /usr/include/eigen3)
    --- checking for module 'flann'
    ---   found flann, version 1.6.8
    --- Found Flann: /usr/lib64/libflann_cpp_s.a
    --- FLANN found (include: /usr/include, lib: optimized;/usr/lib64/libflann_cpp_s.a;debug;/usr/lib64/libflann_cpp.so)
    --- checking for module 'cminpack'
    ---   found cminpack, version 1.0.90
    --- Found CMinpack: /usr/lib64/libcminpack.so
    --- CMinPack found (include: /usr/include/cminpack-1, libs: optimized;/usr/lib64/libcminpack.so;debug;/usr/lib64/libcminpack.so)
    --- Try OpenMP C flag = [-fopenmp]
    --- Performing Test OpenMP_FLAG_DETECTED
    --- Performing Test OpenMP_FLAG_DETECTED - Success
    --- Try OpenMP CXX flag = [-fopenmp]
    --- Performing Test OpenMP_FLAG_DETECTED
    --- Performing Test OpenMP_FLAG_DETECTED - Success
    --- Found OpenMP: -fopenmp
    --- Found OpenNI: /usr/lib/libOpenNI.so
    --- OpenNI found (include: /usr/include/openni, lib: /usr/lib/libOpenNI.so)
    --- ROS_ROOT /opt/ros/diamondback/ros
    --- Found ROS; USE_ROS is OFF
    --- Found GTest: /usr/lib/libgtest.so
    --- Tests will be built
    --- Found Qhull: /usr/lib/libqhull.so
    --- QHULL found (include: /usr/include/qhull, lib: optimized;/usr/lib/libqhull.so;debug;/usr/lib/libqhull.so)
    --- VTK found (include: /usr/include/vtk-5.4;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/lib/openmpi/include;/usr/lib/openmpi/include/openmpi;/usr/include/tcl8.5;/usr/include/python2.6;/usr/include/tcl8.5;/usr/lib/jvm/default-java/include;/usr/lib/jvm/default-java/include;/usr/lib/jvm/default-java/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include;/usr/include/libxml2;/usr/include;/usr/include/freetype2, lib: /usr/lib/vtk-5.4)
    --- Found Doxygen: /usr/bin/doxygen
    --- Found CPack generators: DEB
    --- The following subsystems will be built:
    ---   common
    ---   octree
    ---   io
    ---   kdtree
    ---   range_image
    ---   features
    ---   sample_consensus
    ---   keypoints
    ---   filters
    ---   registration
    ---   segmentation
    ---   surface
    ---   visualization
    ---   global_tests
    --- The following subsystems will not be built:
    --- Configuring done
    --- Generating done
    --- Build files have been written to: /work/PCL/pcl/trunk/build
    -
    -
    -
  • -
-
-

The important lines are:

-
-- Check for working C compiler: /usr/bin/distcc
--- Check for working C compiler: /usr/bin/distcc -- works
--- Detecting C compiler ABI info
--- Detecting C compiler ABI info - done
--- Check for working CXX compiler: /usr/bin/distcc
--- Check for working CXX compiler: /usr/bin/distcc -- works
-
-
-

The next step is to tell distcc which hosts it should use. Here we can -decide whether we want to use the local workstation for compilation too, or -just the machines running a distcc daemon (wgsc11 and wgsc12 in our -example). The easiest way to pass this information to distcc is via -environment variables. For example:

-
export DISTCC_HOSTS='localhost wgsc11 wgsc12'
-
-
-

will tell distcc to use the local machine, as well as both the distcc -servers, while:

-
export DISTCC_HOSTS='wgsc11 wgsc12'
-
-
-

will only use the wgsc11 and wgsc12 machines.

-

Finally, the last step is to increase the number of parallel compile units we should use. For example:

-
[pcl/build] $ make -j32
-
-
-

will start 32 processes and distribute them equally on the two distcc machines.

-
-
-

The following plot shows an example of multiple make -jX invocations, for X -ranging from 1 to 13. As it can be seen, the overall compile time is -drastically reduced by using distcc, in this case with the CPU on the client -machine almost idleing while the wgsc11 and wgsc12 machines do most of the -work. The reason why the plot “saturates” is due to conditional dependencies in -the compilation process, where certain libraries or binaries require others to -be compiled first.

-_images/distcc_plot.png -

For more information on how to configure distcc please visit http://distcc.org.

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/exceptions_guide.php b/advanced/html/exceptions_guide.php deleted file mode 100644 index 99632943e304..000000000000 --- a/advanced/html/exceptions_guide.php +++ /dev/null @@ -1,171 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Exceptions in PCL - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Exceptions in PCL

-

There have been a multitude of discussions in the past regarding exceptions in -PCL (see http://www.pcl-developers.org/to-throw-or-not-to-throw-td4828759.html -for an example). Herein, we discuss the major points with respect to writing -and using exceptions.

-
-

Adding a new Exception

-

Any new exception should inherit from the PCLException class in -pcl/exceptions.h

-
/** \class MyException
-  * \brief An exception that is thrown when I want it.
-  */
-
-class PCL_EXPORTS MyException : public PCLException
-{
-  public:
-    MyException (const std::string& error_description,
-                 const std::string& file_name = "",
-                 const std::string& function_name = "",
-                 unsigned line_number = 0) throw ()
-      : pcl::PCLException (error_description, file_name, function_name, line_number) { }
-};
-
-
-
-
-

Using Exceptions

-

For ease of use we provide this macro

-
#define PCL_THROW_EXCEPTION (ExceptionName, message)
-{
-  std::ostringstream s;
-  s << message;
-  throw ExceptionName (s.str (), __FILE__, "", __LINE__);
-}
-
-
-

Then in your code, add:

-
if (my_requirements != the_parameters_used_)
-  PCL_THROW_EXCEPTION (MyException, "my requirements are not met " << the_parameters_used);
-
-
-

This will set the file name and the line number thanks to the macro definition. -Take care of the message: it is the most important part of the exception. You -can profit of the std::ostringstream used in the macro, so you can append -variable names to variable values and so on to make it really explicit. Also -something really important is when the method you are writing can throw an -exception, please add this to the the function documentation:

-
/** Function that does cool stuff
-  * \param nb number of points
-  * \throws MyException
-  */
-void
-myFunction (int nb);
-
-
-

This will be parsed by Doxygen and made available in the generated API -documentation so the person that would use your function knows that they have -to deal with an exception called MyException.

-
-
-

Exceptions handling

-

To properly handle exceptions you need to use the try... catch block.

-
// Here we call myFunction which can throw MyException
-try
-{
-  myObject.myFunction (some_number);
-  // You can put more exceptions throwing instruction within same try block
-}
-// We catch only MyException to be very specific
-catch (pcl::MyException& e)
-{
-  // Code to deal with the exception maybe changing myObject.the_parameters_used_
-}
-
-// Here we catch any exception
-#if 0
-catch (exception& e)
-{
-  // Code to deal with the exception maybe changing myObject.the_parameters_used_
-}
-#endif
-
-
-

Exceptions handling is really context dependent so there is no general -rule that can be applied but here are some of the most used guidelines:

-
-
    -
  • exit with some error if the exception is critical
  • -
  • modify the parameters for the function that threw the exception and recall it again
  • -
  • throw an exception with a meaningful message saying that you encountred an exception
  • -
  • continue (really bad)
  • -
-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/how_to_write_a_tutorial.php b/advanced/html/how_to_write_a_tutorial.php deleted file mode 100644 index ad8feab56056..000000000000 --- a/advanced/html/how_to_write_a_tutorial.php +++ /dev/null @@ -1,157 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - How to write a good tutorial - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

How to write a good tutorial

-

No matter how many tutorials we create and upload at -www.pointclouds.org/documentation/tutorials, there are never going to be -enough. :) As our code base and user base are growing, so is the demand for -detailed explanations or step-by-step/how-to documentation increasing. This -short guide will help you understand how you can contribute documentation -and help improve the project.

-

The Point Cloud Library (PCL) documentation infrastructure has two distinct -parts:

-

1. API documentation – we are using -Doxygen to automatically generate the best -possible API documentation, directly from our source files;

-

2. Tutorials and HowTo documents -– we are using Restructured Text -via Sphinx to transform simple reST files into -beautiful HTML documents.

-

Both documentation sources are stored in our Source repository and the web pages are generated -hourly by our server via crontab jobs.

-

In the next two sections we will address both of the above, and present a small -example for each. We’ll begin with the easiest of the two: adding a new -tutorial.

-
-
-

Creating a new tutorial

-

As already mentioned, we make use of Sphinx to generate HTML files from reST -(restructured text) documents. If you want to add a new tutorial, we suggest -you read the following resources:

-
-
-
-

Once you understand how reST works, look over our current set of tutorials for -examples at https://github.com/PointCloudLibrary/pcl/tree/master/doc/tutorials/content.

-

To add a new tutorial, simply create a new file, and send it to us together -with the images/videos that you want included in the tutorial. The best way to -do this is to login to https://github.com/PointCloudLibrary/pcl and send it as -a pull request.

-
-
-

Improving the API documentation

-

Providing a good API documentation is not easy – as finding a balance between -the amount of information that you present for each function, versus keeping it -clean and simple is ermmm, a challenge in itself. Differently said, it’s hard -to know what sort of people will look at the API: hardcore developers or first -time users.

-

Our solution is to document the API as best as possible, but leave certain more -complex details such as application examples for the tutorials. However, while -this is a nice goal, it’s very improbable that our documentation is perfect.

-

To help us improve the API documentation, all that you need to do is simply -check out the source code of PCL (we recommend trunk if you’re going to start -editing the sources), like:

-
git clone https://github.com/PointCloudLibrary/pcl
-
-
-

Then, edit the file containing the function/class that you want to improve the -documentation for, say common/include/pcl/point_cloud.h, and go to the -element that you want to improve. Let’s take points for example:

-
/** \brief The point data. */
-std::vector<PointT, Eigen::aligned_allocator<PointT> > points;
-
-
-

What you have to modify is the Doxygen-style comment starting with /** and -ending with */. See http://www.doxygen.org for more information.

-

To send us the modification, please send a pull request through Github.

-
-
-

Testing the modified API documentation

-

If you want to test it locally on your machine, make sure you have Doxygen -installed, and go into the build system (here we assume that you followed the -source installation instructions from -http://www.pointclouds.org/downloads) and run:

-
make doc
-
-
-

This will create a set of html files containing the API documentation for PCL, -in build/html/

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/index.php b/advanced/html/index.php deleted file mode 100644 index 2a5dec55b403..000000000000 --- a/advanced/html/index.php +++ /dev/null @@ -1,220 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Compiling PCL - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-
    -
-
-

The following presents a set of advanced topics regarding PCL.

-
-

Compiling PCL

-

PCL uses modern C++ template programming in order to achieve maximum generality -and reusability of its components. Due to intricate details of the current -generation of C++ compilers however, the usage of templated code introduces -additional compile-time delays. We present a series of tricks that, if used -appropriately, will save you a lot of headaches and will speed up the -compilation of your project.

-
    -
  • Using CCache to speed up compilation

    -

    CCache is a compiler cache. It speeds up recompilation by caching previous -compilations and detecting when the same compilation is being done again. -Supported languages are C, C++, Objective-C and Objective-C++.

    -_images/ccache.png -
  • -
  • Using DistCC to speed up compilation

    -

    distcc is a program to distribute builds of C, C++, Objective C or -Objective C++ code across several machines on a network. distcc should always -generate the same results as a local build, is simple to install and use, and -is usually much faster than a local compile.

    -_images/distcc.png -
  • -
  • Compiler optimizations

    -

    Depending on what compiler optimizations you use, your code might behave -differently, both at compile time and at run time.

    -_images/optimize.png -
  • -
  • Single compilation units

    -

    In certain cases, it’s better to concatenate source files into single -compilation units to speed up compiling.

    -_images/unitybuild.jpg -
  • -
-
-
-

Developing PCL code

-

To make our lives easier, and to be able to read and integrate code from each -other without causing ourselves headaches, we assembled a set of rules for PCL -development that everyone should follow:

-
-

Rules

-
    -
  • if you make important commits, please _add the commit log_ or something similar _to -the changelist page_ -(https://github.com/PointCloudLibrary/pcl/blob/master/CHANGES.md);
  • -
  • if you change anything in an existing algorithm, _make sure that there are -unit tests_ for it and _make sure that they pass before you commit_ the code;
  • -
  • if you add a new algorithm or method, please _document the code in a similar -manner to the existing PCL code_ (or better!), and _add some minimal unit -tests_ before you commit it;
  • -
  • method definitions go into (include/.h), templated implementations go into -(include/impl/.hpp), non-templated implementations go into (src/.cpp), and -unit tests go in (test/.cpp);
  • -
  • last but not least, please _respect the same naming and indentation -guidelines_ as you see in the PCL C++ Programming Style Guide.
  • -
-
- -
-
-

Commiting changes to the git master

-

In order to oversee the commit messages more easier and that the changelist looks homogenous please keep the following format:

-

“* <fixed|bugfix|changed|new> X in @<classname>@ (#<bug number>)”

-
-
-

Improving the PCL documentation

-
    -
  • How to write a good tutorial

    -

    In case you want to contribute/help PCL by improving the existing -documentation and tutorials/examples, please read our short guide on how to -start.

    -
  • -
-
- - - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/minimal_example.php b/advanced/html/minimal_example.php deleted file mode 100644 index 71f20d1cf7db..000000000000 --- a/advanced/html/minimal_example.php +++ /dev/null @@ -1,132 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - How to build a minimal example - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

How to build a minimal example

-

First of all make a backup of your current state or start a new project for the -minimal example. Than there are basically two ways: strip down your program or -start from scratch.

-
-

Method 1: Strip down your program

-

This method has the advantage that you start with your actual problem and you -can test all the time if you are on the right track. First make sure that the -program actually compiles without the problematic code by commenting it. Then -start removing unneeded code until the bare minimum and make sure that it’s -still showing the error by compiling it with and without the problematic line -(make sure it still emits the same error message).

-
-
-

Method 2: Start from scratch

-

If your program is to big to strip it down, it’s maybe easier to start from -scratch by building a small project that only includes the problematic code. -Again make sure that it actually compiles without the erroneous code and emits -the same error with it.

-
-
-
-

How to deal with input data (e.g. point clouds)

-

If you fear that your problem is connected to the input data (either if you -have a problem with pcl/io or the error depends on the input data) you should -include the input with your minimal example. If the file is to big and a -stripped down version doesn’t work, you should upload it somewhere and only -provide a link to the data. If you can’t include the data or don’t know a way -to provide it, add a remark to your mail and we will contact you to find a -solution.

-

If the input data is not so important it is best to generate fake data:

-
1
-2
pcl::PointCloud<pcl::PointCloudXYZ> cloud;
-cloud.insert (cloud.end (), PointXYZ (1, 1, 1));
-
-
-
-
-

I’m linking against other libraries, what to do?

-

Normally other libraries should not interfere, so try to build a minimal -example using PCL (and it’s dependencies) first. If your problems is gone -without the other library please make sure that it’s not actually a problem -with one of the other libraries and add a comment in your minimal example.

-
-
-

Final Make

-

Please put only one error into the minimal example as well as include all -necessary files to build it.

-
- - - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/pcl2.php b/advanced/html/pcl2.php deleted file mode 100644 index ce8cafc053f7..000000000000 --- a/advanced/html/pcl2.php +++ /dev/null @@ -1,250 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - PCL 2.x API consideration guide - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

PCL 2.x API consideration guide

-

With the PCL 1.x API locked and a few releases already underway, it’s time to -consider what the next generation of libraries should look like. This document -discusses a series of changes to the current API, from base classes to higher -level algorithms.

-
-

Major changes

-
-

1.1 pcl::PointCloud

-

The PointCloud class represents the base class in PCL -for holding nD (n dimensional) data.

-
-
The 1.x API includes the following data members:
-
    -
  • PCLHeader (coming from ROS)
      -
    • uint32_t seq - a sequence number
    • -
    • uint64_t stamp - a timestamp associated with the time when the data was acquired
    • -
    • std::string frame_id - a TF frame ID
    • -
    -
  • -
  • std::vector<T> points - a std C++ vector of T data. T can be a structure of any of the types defined in point_types.h.
  • -
  • uint32_t width - the width (for organized datasets) of the data. Set to the number of points for unorganized data.
  • -
  • uint32_t height - the height (for organized datasets) of the data. Set to 1 for unorganized data.
  • -
  • bool is_dense - true if the data contains only valid numbers (e.g., no NaN or -/+Inf, etc). False otherwise.
  • -
  • Eigen::Vector4f sensor_origin_ - the origin (pose) of the acquisition sensor in the current data coordinate system.
  • -
  • Eigen::Quaternionf sensor_orientation_ - the origin (orientation) of hte acquisition sensor in the current data coordinate system.
  • -
-
-
-

Proposals for the 2.x API:

-
-
    -
  • drop templating on point types, thus making PointCloud template free

    -
  • -
  • drop the PCLHeader structure, or consolidate all the above information (width, height, is_dense, sensor_origin, sensor_orientation) into a single struct

    -
  • -
  • make sure we can access a slice of the data as a 2D image, thus allowing fast 2D displaying, [u, v] operations, etc

    -
  • -
  • make sure we can access a slice of the data as a subpoint cloud: only certain points are chosen from the main point cloud

    -
  • -
  • implement channels (of a single type!) as data holders, e.g.:

    -
      -
    • cloud[“xyz”] => gets all 3D x,y,z data
    • -
    • cloud[“normals”] => gets all surface normal data
    • -
    • etc
    • -
    -
  • -
  • internals should be hidden : only accessors (begin, end ...) are public, this facilitating the change of the underlying structure

    -
  • -
  • Capability to construct point cloud types containing the necessary channels -at runtime. This will be particularly useful for run-time configuration of -input sensors and for reading point clouds from files, which may contain a -variety of point cloud layouts not known until the file is opened.

    -
  • -
  • Complete traits system to identify what data/channels a cloud stores at -runtime, facilitating decision making in software that uses PCL. (e.g. -generic component wrappers.)

    -
  • -
  • Stream-based IO sub-system to allow developers to load a stream of point -clouds and “play” them through their algorithm(s), as well as easily capture -a stream of point clouds (e.g. from a Kinect). Perhaps based on -Boost::Iostreams.

    -
  • -
  • Given the experience on libpointmatcher, -we (François Pomerleau and Stéphane Magnenat) propose the following data structures:

    -
    cloud = map<space_identifier, space>
    -space = tuple<type, components_identifiers, data_matrix>
    -components_identifiers = vector<component_identifier>
    -data_matrix = Eigen matrix
    -space_identifier = string with standardised naming (pos, normals, color, etc.)
    -component_identifier = string with standardised naming (x, y, r, g, b, etc.)
    -type = type of space, underlying scalar type + distance definition (float with euclidean 2-norm distance, float representing gaussians with Mahalanobis distance, binary with manhattan distance, float with euclidean infinity norm distance, etc.)
    -
    -
    -
    -
    For instance, a simple point + color scenario could be::
    -

    cloud = { “pos” => pos_space, “color” => color_space } -pos_space = ( “float with euclidean 2-norm distance”, { “x”, “y”, “z” }, [[(0.3,0,1.3) , ... , (1.2,3.1,2)], ... , [(1,0.3,1) , ... , (2,0,3.5)] ) -color_space = ( “uint8 with rgb distance”, { “r”, “g”, “b” }, [[(0,255,0), ... , (128,255,32)] ... [(12,54,31) ... (255,0,192)]] )

    -
    -
    -
  • -
-
-
-
-

1.2 PointTypes

-
-
    -
  1. Eigen::Vector4f or Eigen::Vector3f ??
  2. -
  3. Large points cause significant perfomance penalty for GPU. Let’s assume that point sizes up to 16 bytes are suitable. This is some compromise between SOA and AOS. Structures like pcl::Normal (size = 32) is not desirable. SOA is better in this case.
  4. -
-
-
-
-

1.3 GPU support

-
-
    -
  1. Containers for GPU memory. pcl::gpu::DeviceMemory/DeviceMemory2D/DeviceArray<T>/DeviceArray2D<T> (Thrust containers are incinvinient).

    -
    -
      -
    • DeviceArray2D<T> is container for organized point cloud data (supports row alignment)
    • -
    -
    -
  2. -
  3. PointCloud Channels for GPU memory. Say, with “_gpu” postfix.

    -
    -
      -
    • cloud[“xyz_gpu”] => gets channel with 3D x,y,z data allocated on GPU.
    • -
    • GPU functions (ex. gpu::computeNormals) create new channel in cloud (ex. “normals_gpu”) and write there. Users can preallocate the channel and data inside it in order to save time on allocations.
    • -
    • Users must manually invoke uploading/downloading data to/from GPU. This provides better understanding how much each operation costs.
    • -
    -
    -
  4. -
  5. Two layers in GPU part: host layer(nvcc-independent interface) and device(for advanced use, for sharing code compiled by nvcc):

    -
    -
      -
    • namespace pcl::cuda (can depend on CUDA headers) or pcl::gpu (completely independent from CUDA, OpenCL support in future?).
    • -
    • namespace pcl::device for device layer, only headers.
    • -
    -
    -
  6. -
  7. Async operation support???

    -
  8. -
-
-
-
-

1.4 Keypoints and features

-
-
    -
  1. The name Feature is a bit misleading, since it has tons of meanings. Alternatives are Descriptor or FeatureDescription.

    -
  2. -
  3. In the feature description, there is no need in separate FeatureFromNormals class and setNormals() method, since all the required channels are contained in one input. We still need separate setSearchSurface() though.

    -
  4. -
  5. There exist different types of keypoints (corners, blobs, regions), so keypoint detector might return some meta-information besides the keypoint locations (scale, orientation etc.). Some channels of that meta-information are required by some descriptors. There are options how to deliver that information from keypoints to descriptor, but it should be easy to pass it if a user doesn’t change anything. This interface should be uniform to allow for switching implementations and automated benchmarking. Still one might want to set, say, custom orientations, different from what detector returned.

    -
    -

    to be continued...

    -
    -
  6. -
-
-
-
-

1.5 Data slices

-

Anything involving a slice of data should use size_t for indices and not int. E.g the indices of the inliers in RANSAC, the focused points in RANSAC ...

-
-
-

1.6 RANSAC

-
-
    -
  • Renaming the functions and internal variables: everything should be named with _src and _tgt: we have confusing names like indices_ and indices_tgt_ (and no indices_src_), setInputCloud and setInputTarget (duuh, everything is an input, it should be setTarget, setSource), in the code, a sample is named: selection, model_ and samples. getModelCoefficients is confusing with getModel (this one should be getBestSample).
  • -
  • no const-correctness all over, it’s pretty scary: all the get should be const, selectWithinDistance and so on too.
  • -
  • the getModel, getInliers function should not force you to fill a vector: you should just return a const reference to the internal vector: that could allow you to save a useless copy
  • -
  • some private members should be made protected in the sub sac models (like sac_model_registration) so that we can inherit from them.
  • -
  • the SampleConsensusModel should be independent from point clouds so that we can create our own model for whatever library. Then, the one used in the specialize models (like sac_model_registration and so on) should inherit from it and have constructors based on PointClouds like now. Maybe we should name those PclSampleConsensusModel or something (or have SampleConsensusModelBase and keep the naming for SampleConsensusModel).
  • -
-
-
-
-
-

Minor changes

-
- -
- - - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/pcl_reg_eval.php b/advanced/html/pcl_reg_eval.php deleted file mode 100644 index 91a6a0240b3f..000000000000 --- a/advanced/html/pcl_reg_eval.php +++ /dev/null @@ -1,169 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Evaluating pcl/registration - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Evaluating pcl/registration

-

This is a collection of ideas on how to build an evaluation framework of pcl/registration.

-
-

Data generation

-
    -
  • synthetic data
  • -
  • real word data (how to get ground truth?)
  • -
-
-
    -
  • Kinect
  • -
  • PR2 laser scanner
  • -
  • SICK laser data
  • -
  • small range 3D scanner
  • -
  • mid range 3D scanner (Faro)
  • -
  • high end 3D scanner (Riegl, Velodyne)
  • -
-
-
    -
  • Point Types
  • -
-
-
    -
  • 2D(?)
  • -
  • 3D
  • -
  • RGB
  • -
-
-
    -
  • dynamics
  • -
-
-
    -
  • static scans
  • -
  • scanning while driving (e.g. robots)
  • -
-
-
    -
  • size
  • -
-
-
    -
  • room
  • -
  • building
  • -
  • outdoor (street)
  • -
-
-
-
-

Architecture

-
    -
  • some lib for polygonal data
  • -
  • modeling different sensors
  • -
  • modeling noise
  • -
  • add a trajectory file
  • -
  • output a pile of .pcd files
  • -
  • integrate command line tools from PCL grandfather
  • -
-
-
-

Evaluating different algorithms

-
-

ICP

-
    -
  • how does the algorithm cope with outliers
  • -
  • how are the point pairs evaluated:
  • -
-
-
    -
  • does it use normal or RGB information
  • -
  • does it weight the pairs differently
  • -
  • which kind of point pairs are used:
  • -
-
-
    -
  • one-to-one
  • -
  • one-to-many
  • -
  • many-to-many
  • -
-
-
-
-
-
-

Similar Projects

- -
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/pcl_registration.php b/advanced/html/pcl_registration.php deleted file mode 100644 index 76a33621e515..000000000000 --- a/advanced/html/pcl_registration.php +++ /dev/null @@ -1,316 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - PCL/registration - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

PCL/registration

-
-

Participants

-
    -
  • Michael Dixon
  • -
  • Radu Rusu
  • -
  • Nicola Fioraio
  • -
  • Jochen Sprickerhof
  • -
-
-
-

Existing Frameworks

-
    -
  • SLAM6D
  • -
  • Toro
  • -
  • Hogman
  • -
  • G2O
  • -
  • MegaSLAM/MegaICP
  • -
-
-
-

Mission

-

Provide a common interface/architecture for all of these and future SLAM ideas.

-
-
-

Ideas

-
    -
  • Separate algorithms from data structures.
  • -
  • strip down everything to it’s basics and define an interface.
  • -
  • modify data structure in algorithms (you can copy them before if you need to).
  • -
  • point clouds are not transformed, only the translation and rotation is updated.
  • -
-
-
-

Data structures

-
-

Note

-

These ideas are independent of actual data structures in the PCL for now. We can see later how to integrate them best.

-
-
-

Pose

-
struct Pose
-{
-  Eigen::Vector3 translation;
-  Eigen::Quaternion rotation;
-}
-
-
-
-
-

PointCloud

-
typedef vector<vector <float> > Points;
-
-
-
-
-

PosedPointCloud

-
typedef pair<Pose*, PointCloud*> PosedPointCloud;
-
-
-

PointCloud* can be 0.

-
-
-

Graph

-

This should hold the SLAM graph. I would propose to use Boost::Graph for it, as it allows us to access a lot of algorithms.

-
-
-

CovarianceMatrix

-
typedef Eigen::Matrix4f CovarianceMatrix;
-
-
-
-
-

Measurement

-
struct Measurement
-{
-  Pose pose;
-  CovarianceMatrix covariance;
-}
-
-
-

Idea: change the CovarianceMatrix into a function pointer.

-
-
-
-

Interfaces

-
-

GlobalRegistration

-
class GlobalRegistration
-{
-  public:
-    /**
-      * \param history how many poses should be cached (0 means all)
-      */
-    GlobalRegistration (int history = 0) : history_(history) {}
-
-    /**
-      * \param pc a new point cloud for GlobalRegistration
-      * \param pose the initial pose of the pc, could be 0 (unknown)
-      */
-    void addPointCloud (PointCloud &pc, Pose &pose = 0)
-    {
-      new_clouds_.push_back (make_pair (pc, pose));
-    }
-
-    /**
-      * returns the current estimate of the transformation from point cloud from to point cloud to
-        throws an exception if the transformation is unknown
-      */
-    Pose getTF (PointCloud &from, PointCloud &to);
-
-    /**
-      * run the optimization process
-      * \param lod the level of detail (optional). Roughly how long it should run (TODO: better name/parametrization?)
-      */
-    virtual void compute (int lod = 0) {}
-
-  private:
-    int history_;
-    map<PointCloud*, Pose*> poses_;
-    PosedPointCloud new_clouds_;
-};
-
-
-

This will be the base class interface for every SLAM algorithm. At any point you can add point clouds and they will be processed. -The poses can be either in a global or in a local coordinate system (meaning that they are incremental regarding the last one). -Idea: Do we need the compute? Could it be included into the addPointCloud or getTF?

-
-
-

GraphOptimizer

-
class GraphOptimizer
-{
-  public:
-    virtual void optimize (Graph &gr) = 0;
-}
-
-
-
-
-

LoopDetection

-
class LoopDetection
-{
-  public:
-    virtual ~LoopDetection () {}
-    virtual list<pair<PointCloud*, PointCloud*> > detectLoop(list<PosedPointCloud*> poses, list<PosedPointCloud*> query) {} = 0;
-}
-
-
-
-
-

GraphHandler

-
class GraphHandler
-{
-  void addPose (Graph &gr, PointCloud &pc);
-  void addConstraint (Graph &gr, PointCloud &from, PointCloud &to, Pose &pose);
-}
-
-
-
-
-
-

Example Implementations

-
-

PairwiseGlobalRegistration

-
class PairwiseGlobalRegistration : public GlobalRegistration
-{
-  public:
-    PairwiseGlobalRegistration(Registration &reg) : reg_(reg) {}
-    virtual void compute (int lod = 0) {}
-    {
-      list<PosedPointCloud >::iterator cloud_it;
-      for (cloud_it = new_clouds_.begin(); cloud_it != new_clouds_.end(); cloud_it++)
-      {
-        if(!old_) {
-          old = *cloud_it;
-          continue;
-        }
-        reg_.align(old_, *cloud_it, transformation);
-        poses[*cloud_it] = transformation;
-        old_ = *cloud_it;
-      }
-      new_clouds_.clear();
-    }
-
-  private:
-    Registration &reg_;
-    PointCloud &old_;
-}
-
-
-
-
-

DistanceLoopDetection

-
class DistanceLoopDetection : LoopDetection
-{
-  public:
-    virtual list<pair<PointCloud*, PointCloud*> > detectLoop(list<PosedPointCloud*> poses, list<PosedPointCloud*> query)
-    {
-      //I want a map reduce here ;)
-      list<PosedPointCloud >::iterator poses_it;
-      for (poses_it = poses.begin(); poses_it != poses.end(); poses_it++)
-      {
-        list<PosedPointCloud >::iterator query_it;
-        for (query_it = query.begin(); query_it != query.end(); query_it++)
-        {
-          if (dist (*poses_it, *query_it) < min_dist_)
-          {
-            //..
-          }
-      }
-
-    }
-
-}
-
-
-
-
-

ELCH

-
class ELCH : public GlobalRegistration
-{
-  public:
-    ELCH(GlobalRegistration &initial_optimizer = PairwiseGlobalRegistration(), LoopDetection &loop_detection, GraphOptimizer &loop_optimizer, GraphOptimizer &graph_optimizer = LUM())
-}
-
-
-
-
-

LUM

-
class ELCH : public GlobalRegistration
-{
-  public:
-    ELCH(GlobalRegistration &initial_optimizer = PairwiseGlobalRegistration(), LoopDetection &loop_detection, GraphOptimizer &loop_optimizer, GraphOptimizer &graph_optimizer)
-}
-
-
-

Lu and Milios style scan matching (as in SLAM6D)

-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/pcl_style_guide.php b/advanced/html/pcl_style_guide.php deleted file mode 100644 index 3d0ba9ea4259..000000000000 --- a/advanced/html/pcl_style_guide.php +++ /dev/null @@ -1,492 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - PCL C++ Programming Style Guide - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

PCL C++ Programming Style Guide

-

To make sure that all code in PCL is coherent and easily understood by other -developers and users, we follow a set of strict rules that everyone should -adopt. These rules are not to be broken unless there is a very good reason to -do so. Changes to these rules are always possible, but the person proposing and -changing a rule will have the unfortunate task to go and apply the rule change -to all the existing code.

- -
-

1. Naming

-
-

1.1. Files

-

All files should be under_scored.

-
    -
  • Header files have the extension .h
  • -
  • Templated implementation files have the extension .hpp
  • -
  • Source files have the extension .cpp
  • -
-
-
-

1.2. Directories

-

All directories and subdirectories should be under_scored.

-
    -
  • Header files should go under include/
  • -
  • Templated implementation files should go under include/impl/
  • -
  • Source files should go under src/
  • -
-
-
-

1.3. Includes

-

Include statements are made with “quotes” only if the file is in the -same directory, in any other case the include statement is made with -<chevron_brackets>, e.g.:

-
-
#include <pcl/module_name/file_name.h>
-#incluce <pcl/module_name/impl/file_name.hpp>
-
-
-
-
-
-

1.4. Defines & Macros

-

Macros should all be ALL_CAPITALS_AND_UNDERSCORED. Defines for header type -files also need a trailing underscore. Their naming should be mapped from their -include name: pcl/filters/bilateral.h becomes PCL_FILTERS_BILATERAL_H_. -The #ifndef and #define lines should be placed just past the BSD license. -The #endif goes all the way at the bottom and needs to have the define name in -its comment, e.g:

-
-
// the license
-
-#ifndef PCL_MODULE_NAME_IMPL_FILE_NAME_HPP_
-#define PCL_MODULE_NAME_IMPL_FILE_NAME_HPP_
-
-// the code
-
-#endif // PCL_MODULE_NAME_IMPL_FILE_NAME_HPP_
-
-
-
-
-
-

1.5. Namespaces

-

Namespaces should be under_scored, e.g.:

-
-
namespace pcl_io
-{
-  ...
-}
-
-
-
-
-
-

1.6. Classes / Structs

-

Class names (and other type names) should be CamelCased. -Exception: if the class name contains a short acronym, the acronym itself -should be all capitals. Class and struct names are preferably nouns: -PFHEstimation instead of EstimatePFH.

-

Correct examples:

-
-
class ExampleClass;
-class PFHEstimation;
-
-
-
-
-
-

1.7. Functions / Methods

-

Functions and class method names should be camelCased, and arguments are -under_scored. Function and method names are preferably verbs, and the name -should make clear what it does: checkForErrors() instead of errorCheck(), -dumpDataToFile() instead of dataFile().

-

Correct usage:

-
-
int
-applyExample (int example_arg);
-
-
-
-
-
-

1.8. Variables

-

Variable names should be under_scored.

-
-
int my_variable;
-
-
-
-
-

1.8.1. Iterators

-

Iterator variables should indicate what they’re iterating over, e.g.:

-
-
std::list<int> pid_list;
-std::list<int>::iterator pid_it;
-
-
-
-
-
-

1.8.2. Constants

-

Constants should be ALL_CAPITALS, e.g.:

-
-
const static int MY_CONSTANT = 1000;
-
-
-
-
-
-

1.8.3. Member variables

-

Variables that are members of a class are under_scored_, with a trailing -underscore added, e.g.:

-
-
int example_int_;
-
-
-
-
-
-
-

1.9. Return statements

-

Return statements should have their values in parentheses, e.g.:

-
-
int
-main ()
-{
-  return (0);
-}
-
-
-
-
-

-
-
-
-
-

2. Indentation and Formatting

-

The standard indentation for each block in PCL is 2 spaces. Under no -circumstances, tabs or other spacing measures should be used. PCL uses a -variant of the GNU style formatting.

-
-

2.1. Namespaces

-

In a header file, the contets of a namespace should be indented, e.g.:

-
namespace pcl
-{
-  class Foo
-  {
-    ...
-  };
-}
-
-
-

In an implementation file, the namespace must be added to each individual -method or function definition, e.g.:

-
void
-pcl::Foo::bar ()
-{
-  ...
-}
-
-
-
-
-

2.2. Classes

-

The template parameters of a class should be declared on a different line, -e.g.:

-
template <typename T>
-class Foo
-{
-  ...
-}
-
-
-
-
-

2.3. Functions / Methods

-

The return type of each function declaration must be placed on a different -line, e.g.:

-
void
-bar ();
-
-
-

Same for the implementation/definition, e.g.:

-
void
-bar ()
-{
-  ...
-}
-
-
-

or

-
void
-Foo::bar ()
-{
-  ...
-}
-
-
-

or

-
template <typename T> void
-Foo<T>::bar ()
-{
-  ...
-}
-
-
-
-
-

2.4. Braces

-

Braces, both open and close, go on their own lines, e.g.:

-
if (a < b)
-{
-  ...
-}
-else
-{
-  ...
-}
-
-
-

Braces can be omitted if the enclosed block is a single-line statement, e.g.:

-
if (a < b)
-  x = 2 * a;
-
-
-
-
-

2.5. Spacing

-

We’ll say it again: the standard indentation for each block in PCL is 2 -spaces. We also include a space before the bracketed list of arguments to a -function/method, e.g.:

-
int
-exampleMethod (int example_arg);
-
-
-

If multiple namespaces are declared within header files, always use 2 -spaces to indent them, e.g.:

-
namespace foo
-{
-  namespace bar
-  {
-     void
-     method (int my_var);
-   }
-}
-
-
-

Class and struct members are indented by 2 spaces. Access qualifiers (public, private and protected) are put at the -indentation level of the class body and members affected by these qualifiers are indented by one more level, i.e. 2 spaces. E.g.:

-
namespace foo
-{
-  class Bar
-  {
-    int i;
-    public:
-      int j;
-    protected:
-      void
-      baz ();
-  }
-}
-
-
-
-
-

2.6. Automatic code formatting

-

The following set of rules can be automatically used by various different IDEs, -editors, etc.

-
-

2.6.1. Emacs

-

You can use the following PCL C/C++ style file, -download it to some known location and then:

-
    -
  • open .emacs
  • -
  • add the following before any C/C++ custom hooks
  • -
-
(load-file "/location/to/pcl-c-style.el")
-(add-hook 'c-mode-common-hook 'pcl-set-c-style)
-
-
-
-
-

2.6.2. Uncrustify

-

You can find a semi-finished config for Uncrustify here

-
-
-

2.6.3 Eclipse

-
-
You can find a PCL code style file for Eclipse on GitHub.
-
To add the new formatting style go to: Windows > Preferences > C/C++ > Code Style > Formatter
-
-
-
To format portion of codes, select the code and press Ctrl + Shift + F.
-
If you want to format the whole code in your project go to the tree and right click on the project: Source > Format.
-
-

Note that the Eclipse formatter style is configured to wrap all arguments in a function, feel free to re-arange the arguments if you feel the need; for example, -this improves readability:

-
int
-displayPoint (float x, float y, float z,
-              float r, float g, float b
-             );
-
-
-

This eclipse formatter fails to add a space before brackets when using PCL macros:

-
PCL_ERROR("Text\n");
-
-
-

should be

-
PCL_ERROR ("Text\n");
-
-
-
-

Note

-

This style sheet is not perfect, please mention errors on the user mailing list and feel free to patch!

-
-
-
-
-
-

3. Structuring

-
-

3.1. Classes and API

-

For most classes in PCL, it is preferred that the interface (all public -members) does not contain variables and only two types of methods:

-
    -
  • The first method type is the get/set type that allows to manipulate the -parameters and input data used by the class.
  • -
  • The second type of methods is actually performing the class functionality -and produces output, e.g. compute, filter, segment.
  • -
-
-
-

3.2. Passing arguments

-

For get/set type methods the following rules apply:

-
    -
  • If large amounts of data needs to be set (usually the case with input data -in PCL) it is preferred to pass a boost shared pointer instead of the actual -data.
  • -
  • Getters always need to pass exactly the same types as their repsective setters -and vice versa.
  • -
  • For getters, if only one argument needs to be passed this will be done via -the return keyword. If two or more arguments need to be passed they will -all be passed by reference instead.
  • -
-

For the compute, filter, segment, etc. type methods the following rules apply:

-
    -
  • The output arguments are preferably non-pointer type, regardless of data -size.
  • -
  • The output arguments will always be passed by reference.
  • -
-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/roadmap.php b/advanced/html/roadmap.php deleted file mode 100644 index ec9ad7a49c0a..000000000000 --- a/advanced/html/roadmap.php +++ /dev/null @@ -1,78 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Point Cloud Library (PCL) public roadmap - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Point Cloud Library (PCL) public roadmap

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/search.php b/advanced/html/search.php deleted file mode 100644 index 4309a78376c4..000000000000 --- a/advanced/html/search.php +++ /dev/null @@ -1,105 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Search - - - - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - - -
-
-
- -

Search

-
- -

- Please activate JavaScript to enable the search - functionality. -

-
-

- From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing fewer words won't appear in the result list. -

-
- - - -
- -
- -
- -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/single_compile_unit.php b/advanced/html/single_compile_unit.php deleted file mode 100644 index 8e2a40f128ac..000000000000 --- a/advanced/html/single_compile_unit.php +++ /dev/null @@ -1,125 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Single compilation units - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Single compilation units

-

Even before reading [1], we noticed a great speed up in compile time for all -PCL libraries if instead of compiling N object files and linking them together, -we compile only one, and include all the sources of the N files in this main -source. If you peek at an older version of PCL, you might notice things along -the lines of:

-
1
-2
-3
-4
-5
-6
 // Include the implementations instead of compiling them separately to speed up compile time
- #include "extract_indices.cpp"
- #include "passthrough.cpp"
- #include "project_inliers.cpp"
- #include "statistical_outlier_removal.cpp"
- #include "voxel_grid.cpp"
-
-
-

and in CMakeLists.txt:

-
1
-2
-3
-4
-5
-6
-7
-8
-9
 rosbuild_add_library (pcl_ros_filters
-                       src/pcl_ros/filters/filter.cpp
-                       # Compilation is much faster if we include all the following CPP files in filters.cpp
-                       #src/pcl_ros/filters/passthrough.cpp
-                       #src/pcl_ros/filters/project_inliers.cpp
-                       #src/pcl_ros/filters/extract_indices.cpp
-                       #src/pcl_ros/filters/statistical_outlier_removal.cpp
-                       #src/pcl_ros/filters/voxel_grid.cpp
-                      )
-
-
-

For more information on how/why this works, see [1].

- - - - - -
[1](1, 2) http://gamesfromwithin.com/physical-structure-and-c-part-2-build-times
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/html/vertical_sse.php b/advanced/html/vertical_sse.php deleted file mode 100644 index 02d35c552313..000000000000 --- a/advanced/html/vertical_sse.php +++ /dev/null @@ -1,760 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - - Vertical SSE for PCL2.0 - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -
-

Vertical SSE for PCL2.0

- -
-

Representing point data

-

In PCL currently, points are stored with their fields interleaved. For the -simplest PointXYZ type, this looks like:

-
XYZ_XYZ_XYZ_XYZ_ ...
-
-
-

where _ denotes an extra padding float so that each point is 16-byte -aligned. Operating on XYZ_ data efficiently often requires the use of -horizontal SSE instructions, which perform computations using multiple -elements of the same SSE register.

-

This representation is also known as Array-of-Structures (AoS). PointXYZ -is defined as a struct, and all fields for an individual point are stored -together in memory.

-

Instead a vertical representation, aka Structure-of-Arrays (SoA), can be -used:

-
XXXXXXXX ...
-YYYYYYYY ...
-ZZZZZZZZ ...
-
-
-

This layout fits traditional vertical SSE processing better. Most arithmetic -SSE instructions are binary operations on corresponding elements of two SSE -registers.

-
-
-

Why does PCL use AoS?

-

PCL’s use of AoS, normally non-optimal, does have its logic. In PCL, frequently -we wish to process only some (indexed / valid) subset of a point cloud. Besides -dense processing of all points, we then have two other cases.

-
-

Indexed subsets

-

PCL operators routinely provide a setIndices() method, ordering them to use only certain points -identified by index. With the AoS representation, each individual point can be -used in an SSE register via a simple aligned load. Indexed access therefore -does not much complicate an SSE-optimized implementation.

-

Vertical SSE (in the dense case) processes four adjacent points simultaneously, -and indexed access breaks the adjacency requirement. Instead of an aligned -load, the implementation must “gather” the data for the next four indexed -points (spread out in memory).

-
-
-

Organized point clouds

-

PCL permits point clouds with missing data. For imager-based 3D sensors, this -allows point clouds to retain their 2D structure, making it trivial to identify -nearby points. Invalid points have each field set to NaN, so that it is clear -when invalid data is accidentally used in a computation.

-

Handling invalid points in PCL (with AoS) is again rather simple. For each -point, check if X is NaN; if so, ignore it.

-

The SoA situation is much more complicated. Since we operate on four points at -a time, we have to check if any of the four points are invalid. If so, it -becomes very tricky to use SSE at all without destroying our result. Masking -tricks are possible, but imply some overhead over the simple dense code.

-
-
-
-

Horizontal or vertical?

-

Both representations have pros and cons.

-

Horizontal

-
    -
  • Pros
      -
    • More intuitive, easier to write code for
    • -
    • Handling indexed subsets is simple - can still use aligned loads
    • -
    • Handling NaNs also simple
    • -
    -
  • -
  • Cons
      -
    • Clearly slower at dense processing
    • -
    • Waste space and computation on padding elements
    • -
    -
  • -
-

Vertical

-
    -
  • Pros
      -
    • Clearly faster at dense processing
    • -
    • No wasted space - only 3/4 as many loads required
    • -
    • No wasted computation
    • -
    • May have less loop overhead, since you process 4 points per iteration -instead of 1
    • -
    -
  • -
  • Cons
      -
    • Less intuitive
    • -
    • Indexed subsets require gathering data for non-adjacent points
    • -
    • Handling NaNs is complicated
    • -
    -
  • -
-
-
-

Data structures

-

For benchmarking, we define two very simple point cloud representations:

-
// Array-of-Structures
-struct AOS
-{
-  float x;
-  float y;
-  float z;
-  float h;
-};
-
-// Structure-of-Arrays
-struct SOA
-{
-  float* x;
-  float* y;
-  float* z;
-  size_t size;
-};
-
-
-
-
-

Computations considered

-

We benchmark two basic operations:

-
    -
  • Compute the dot product of every point in a cloud with a given point
  • -
  • Compute the centroid of a point cloud
  • -
-

For both operations, we implemented several versions covering the space of:

-
    -
  • Horizontal (AoS) or vertical (SoA)
  • -
  • Dense or indexed
  • -
  • SSE instruction set
  • -
-

Representative examples are listed below.

-
-

Dot product

-

Vertical (SoA), SSE2-optimized:

-
void dotSSE2 (const SOA& vectors, const AOS& vector,
-              float* result, unsigned long size)
-{
-  float x = vector.x, y = vector.y, z = vector.z;
-
-  // Broadcast X, Y, Z of constant vector into 3 SSE registers
-  __m128 vX  = _mm_set_ps1(x);
-  __m128 vY  = _mm_set_ps1(y);
-  __m128 vZ  = _mm_set_ps1(z);
-  __m128 X, Y, Z;
-
-  unsigned i = 0;
-  for ( ; i < size - 3; i += 4)
-  {
-    // Load data for next 4 points
-    X = _mm_load_ps (vectors.x + i);
-    Y = _mm_load_ps (vectors.y + i);
-    Z = _mm_load_ps (vectors.z + i);
-
-    // Compute X*X'+Y*Y'+Z*Z' for each point
-    X = _mm_mul_ps (X, vX);
-    Y = _mm_mul_ps (Y, vY);
-    Z = _mm_mul_ps (Z, vZ);
-    X = _mm_add_ps (X, Y);
-    X = _mm_add_ps (X, Z);
-
-    // Store results
-    _mm_store_ps(result + i, X);
-  }
-
-  // Handle any leftovers at the end
-  for ( ; i < size; ++i)
-  {
-    result[i] = vectors.x[i]*x + vectors.y[i]*y + vectors.z[i]*z;
-  }
-}
-
-
-

Horizontal (AoS), SSE4.1-optimized (with horizontal DPPS instruction):

-
void dotSSE4_1 (const AOS* vectors, const AOS& vector,
-                float* result, unsigned long size)
-{
-  // Load constant vector into an SSE register
-  __m128 vec = _mm_load_ps ((const float*) &vector);
-  __m128 XYZH;
-
-  // Set mask to ignore the padding elements
-  const int mask = 123;
-  for (unsigned i = 0; i < size; ++i)
-  {
-    // Load next point
-    XYZH = _mm_load_ps ((const float*)(vectors + i));
-
-    // Dot product from SSE4.1
-    XYZH = _mm_dp_ps (XYZH, vec, mask);
-
-    // Store single result (the bottom register element)
-    _mm_store_ss (&(result [i]), XYZH);
-  }
-}
-
-
-
-
-

Centroid

-

Vertical (SoA), SSE2-optimized:

-
void centroidSSE2 (const SOA& vectors, AOS& result, size_t size)
-{
-  __m128 X_sum = _mm_setzero_ps();
-  __m128 Y_sum = _mm_setzero_ps();
-  __m128 Z_sum = _mm_setzero_ps();
-  __m128 X, Y, Z;
-
-  size_t i = 0;
-  for ( ; i < size - 3; i += 4)
-  {
-    // Load next 4 points
-    X = _mm_load_ps (vectors.x + i);
-    Y = _mm_load_ps (vectors.y + i);
-    Z = _mm_load_ps (vectors.z + i);
-
-    // Accumulate 4 sums in each dimension
-    X_sum = _mm_add_ps(X_sum, X);
-    Y_sum = _mm_add_ps(Y_sum, Y);
-    Z_sum = _mm_add_ps(Z_sum, Z);
-  }
-
-  // Horizontal adds (HADD from SSE3 could help slightly)
-  float* pX = reinterpret_cast<float*>(&X_sum);
-  float* pY = reinterpret_cast<float*>(&Y_sum);
-  float* pZ = reinterpret_cast<float*>(&Z_sum);
-  result.x = pX[0] + pX[1] + pX[2] + pX[3];
-  result.y = pY[0] + pY[1] + pY[2] + pY[3];
-  result.z = pZ[0] + pZ[1] + pZ[2] + pZ[3];
-
-  // Leftover points
-  for ( ; i < size; ++i)
-  {
-    result.x += vectors.x[i];
-    result.y += vectors.y[i];
-    result.z += vectors.z[i];
-  }
-
-  // Average
-  float inv_size = 1.0f / size;
-  result.x *= inv_size;
-  result.y *= inv_size;
-  result.z *= inv_size;
-}
-
-
-

Horizontal (AoS), SSE2-optimized:

-
void centroidSSE2 (const AOS* vectors, AOS& result, size_t size)
-{
-  __m128 sum = _mm_setzero_ps();
-
-  for (unsigned i = 0; i < size; ++i)
-  {
-    __m128 XYZH = _mm_load_ps ((const float*)(vectors + i));
-    sum = _mm_add_ps(sum, XYZH);
-  }
-  _mm_store_ps((float*)&result, sum);
-
-  float inv_size = 1.0f / size;
-  result.x *= inv_size;
-  result.y *= inv_size;
-  result.z *= inv_size;
-}
-
-
-
-
-

Indexed

-

When using point indices, the vertical implementation can no longer use aligned -loads. Instead it’s best to use the _mm_set_ps intrinsic to gather the next -four points.

-

Vertical (SoA) dot product, SSE2-optimized:

-
void dotIndexedSSE2 (const SOA& vectors, const AOS& vector,
-                     const int* indices, float* result, unsigned long size)
-{
-  float x = vector.x, y = vector.y, z = vector.z;
-
-  __m128 vX  = _mm_set_ps1(x);
-  __m128 vY  = _mm_set_ps1(y);
-  __m128 vZ  = _mm_set_ps1(z);
-  __m128 X, Y, Z;
-
-  unsigned i = 0;
-  for ( ; i < size - 3; i += 4)
-  {
-    int i0 = indices[i + 0];
-    int i1 = indices[i + 1];
-    int i2 = indices[i + 2];
-    int i3 = indices[i + 3];
-
-    // Gather next four indexed points
-    X = _mm_set_ps(vectors.x[i3], vectors.x[i2], vectors.x[i1], vectors.x[i0]);
-    Y = _mm_set_ps(vectors.y[i3], vectors.y[i2], vectors.y[i1], vectors.y[i0]);
-    Z = _mm_set_ps(vectors.z[i3], vectors.z[i2], vectors.z[i1], vectors.z[i0]);
-
-    // Computation
-    X = _mm_mul_ps (X, vX);
-    Y = _mm_mul_ps (Y, vY);
-    Z = _mm_mul_ps (Z, vZ);
-    X = _mm_add_ps (X, Y);
-    X = _mm_add_ps (X, Z);
-
-    // Store result
-    _mm_store_ps(result + i, X);
-  }
-
-  for ( ; i < size; ++i)
-  {
-    int idx = indices[i];
-    result[i] = vectors.x[idx]*x + vectors.y[idx]*x + vectors.z[idx]*z;
-  }
-}
-
-
-
-
-
-

Benchmarks (random data)

-

The test point cloud is randomly generated, 640x480, dense. Each operation is -repeated 1000 times.

-

For indexed tests, the indices list every 4th point. More random index patterns -would change execution time by affecting caching and prefetching, but I’d -expect such effects to be similar for horizontal and vertical code.

-

“Scalar” code uses no vector instructions, otherwise the instruction set is -listed. A trailing u# means the code was unrolled by factor #.

-
-

Dot product

-
-

Dense

-
Horizontal (AOS)
-  Scalar:   0.621674 seconds
-  SSE2:     0.756300 seconds
-  SSE4.1:   0.532441 seconds
-  SSE4.1u4: 0.476841 seconds
-Vertical (SOA)
-  Scalar:   0.519625 seconds
-  SSE2:     0.215499 seconds
-
-
-

The vertical SSE2 code is the clear winner, more than twice as fast as -horizontal code even with the special horizontal dot product from SSE4.1.

-

On the first i7 I used, horizontal SSE4.1 was actually the slowest -implementation. Unrolling it x4 helped significantly, although it was still -much worse than vertical SSE2. I attributed this to the very high latency of -the DPPS instruction; it takes 11 cycles before the result can be stored. -Unrolling helps hide the latency by providing more computation to do during -that time. I don’t know why the results from my office i7 (shown above) are so -different.

-
-
-

Indexed

-
Horizontal (AOS)
-  Scalar:   0.271768 seconds
-  SSE2:     0.276114 seconds
-  SSE4.1:   0.259613 seconds
-Vertical (SOA)
-  Scalar:   0.193394 seconds
-  SSE2:     0.177262 seconds
-
-
-

SSE optimization actually gives meager benefits in both the horizontal and -vertical cases. However vertical SSE2 is still the winner.

-
-
-
-

Centroid

-

The story for centroid is similar; vertical SSE2 is fastest, significantly so -for dense data.

-
-

Dense

-
Horizontal (AOS)
-  Scalar:  0.628597 seconds
-  SSE2:    0.326645 seconds
-  SSE2u2:  0.247539 seconds
-  SSE2u4:  0.236474 seconds
-Vertical (SOA)
-  Scalar:  0.711040 seconds
-  SSE2:    0.149806 seconds
-
-
-
-
-

Indexed

-
Horizontal (AOS)
-  Scalar:  0.256237 seconds
-  SSE2:    0.195724 seconds
-Vertical (SOA)
-  Scalar:  0.194030 seconds
-  SSE2:    0.166639 seconds
-
-
-
-
-
-
-

Vertical SSE for organized point clouds

-

We still need a way to effectively use vertical SSE for organized point clouds -(containing NaNs). A promising approach is to compute a run-length encoding -(RLE) of the valid points as a preprocessing step. The data structure is very -simple:

-
struct RlePair
-{
-  size_t good;
-  size_t skip;
-};
-typedef std::vector<RlePair> RLE;
-
-
-

The RLE counts the length of alternating runs of valid and invalid points. Once -computed, it allows us to process only valid points without explicitly checking -each one for NaNs. In fact, operations become O(#valid points) instead of -O(#total points), which can itself be a win if many points are invalid.

-

In real scenes, valid points are clustered together (into objects), so valid -(and invalid) runs should be lengthy on average. A long run of valid points can -be split into <4 beginning points, <4 final points, and a run of aligned, valid -point data which can be safely processed with vertical SSE.

-
-
-

Abstracting point iteration

-

We are still left with three distinct cases for processing point clouds, -requiring different methods of iterating over point data:

-
    -
  • Dense (no NaNs)
  • -
  • Indexed
  • -
  • Organized (contains NaNs)
  • -
-

Writing and maintaining three copies of each PCL algorithm is a huge burden. -The RLE for organized data in particular imposes a relatively complicated -iteration method. Ideally we should be able to write the computational core of -an algorithm only once, and have it work efficiently in each of the three cases.

-

Currently PCL does not meet this goal. In fact, core algorithms tend to have -four near-identical implementations:

-
    -
  • Dense
  • -
  • Dense indexed
  • -
  • Organized
  • -
  • Organized indexed
  • -
-

I think it’s unnecessary to distinguish between “dense indexed” and “organized -indexed”, if we require that indices point to valid data.

-
-

Writing algorithms as computational kernels

-

As an experiment, I rewrote the vertical centroid as a kernel class. This -implements only the computation, without worrying about the memory layout of -the whole cloud:

-
struct CentroidKernel
-{
-  // State
-  float x_sum, y_sum, z_sum;
-  __m128 X_sum, Y_sum, Z_sum;
-  size_t count;
-  AOS result;
-
-  void init()
-  {
-    // Initialization
-    x_sum = y_sum = z_sum = 0.0f;
-    X_sum = _mm_setzero_ps();
-    Y_sum = _mm_setzero_ps();
-    Z_sum = _mm_setzero_ps();
-    count = 0;
-  }
-
-  // Scalar operator
-  inline void operator() (float x, float y, float z)
-  {
-    x_sum += x;
-    y_sum += y;
-    z_sum += z;
-    ++count;
-  }
-
-  // SIMD operator
-  inline void operator() (__m128 X, __m128 Y, __m128 Z)
-  {
-    X_sum = _mm_add_ps(X_sum, X);
-    Y_sum = _mm_add_ps(Y_sum, Y);
-    Z_sum = _mm_add_ps(Z_sum, Z);
-    count += 4;
-  }
-
-  void reduce()
-  {
-    float* pX = reinterpret_cast<float*>(&X_sum);
-    float* pY = reinterpret_cast<float*>(&Y_sum);
-    float* pZ = reinterpret_cast<float*>(&Z_sum);
-    result.x = pX[0] + pX[1] + pX[2] + pX[3] + x_sum;
-    result.y = pY[0] + pY[1] + pY[2] + pY[3] + y_sum;
-    result.z = pZ[0] + pZ[1] + pZ[2] + pZ[3] + z_sum;
-
-    float inv_count = 1.0f / count;
-    result.x *= inv_count;
-    result.y *= inv_count;
-    result.z *= inv_count;
-  }
-};
-
-
-
-
-

Kernel applicators

-

We can then define applicator functions that apply a kernel to a particular -case of point cloud. The dense version simply uses aligned loads:

-
template <typename Kernel>
-void applyDense (Kernel& kernel, const SOA& pts)
-{
-  kernel.init();
-
-  size_t i = 0;
-  for ( ; i < pts.size - 3; i += 4)
-  {
-    __m128 X = _mm_load_ps (pts.x + i);
-    __m128 Y = _mm_load_ps (pts.y + i);
-    __m128 Z = _mm_load_ps (pts.z + i);
-
-    kernel(X, Y, Z);
-  }
-  for ( ; i < pts.size; ++i)
-  {
-    kernel(pts.x[i], pts.y[i], pts.z[i]);
-  }
-
-  kernel.reduce();
-}
-
-
-

The indexed version performs the necessary data gathering:

-
template <typename Kernel>
-void applySparse (Kernel& kernel, const SOA& pts,
-                  const std::vector<int>& indices)
-{
-  kernel.init();
-
-  size_t i = 0;
-  for ( ; i < indices.size() - 3; i += 4)
-  {
-    int i0 = indices[i + 0];
-    int i1 = indices[i + 1];
-    int i2 = indices[i + 2];
-    int i3 = indices[i + 3];
-
-    // Gather next four indexed points
-    __m128 X = _mm_set_ps(pts.x[i3], pts.x[i2], pts.x[i1], pts.x[i0]);
-    __m128 Y = _mm_set_ps(pts.y[i3], pts.y[i2], pts.y[i1], pts.y[i0]);
-    __m128 Z = _mm_set_ps(pts.z[i3], pts.z[i2], pts.z[i1], pts.z[i0]);
-
-    kernel(X, Y, Z);
-  }
-  for ( ; i < indices.size(); ++i)
-  {
-    int idx = indices[i];
-    kernel(pts.x[idx], pts.y[idx], pts.z[idx]);
-  }
-
-  kernel.reduce();
-}
-
-
-

The organized version is most complicated, and uses the RLE to vectorize as -much of the computation as possible:

-
template <typename Kernel>
-void applyOrganized (Kernel& kernel, const SOA& pts, const RLE& rle)
-{
-  kernel.init();
-
-  size_t i = 0;
-  for (RLE::const_iterator rle_it = rle.begin(); rle_it != rle.end(); ++rle_it)
-  {
-    // Process current stretch of good pixels
-    size_t good = rle_it->good;
-    size_t skip = rle_it->skip;
-    size_t good_end = i + good;
-
-    // Any unaligned points at start
-    size_t unaligned_end = std::min( (i + 3) & ~3, good_end );
-    for ( ; i < unaligned_end; ++i)
-      kernel(pts.x[i], pts.y[i], pts.z[i]);
-    // Aligned SIMD point data
-    for ( ; i + 4 <= good_end; i += 4)
-    {
-      __m128 X = _mm_load_ps (pts.x + i);
-      __m128 Y = _mm_load_ps (pts.y + i);
-      __m128 Z = _mm_load_ps (pts.z + i);
-
-      kernel(X, Y, Z);
-    }
-    // <4 remaining points
-    for ( ; i < good_end; ++i)
-      kernel(pts.x[i], pts.y[i], pts.z[i]);
-
-    // Skip the following stretch of NaNs
-    i += skip;
-  }
-
-  kernel.reduce();
-}
-
-
-

The kernel + applicator combinations for the dense and indexed cases were added -to the centroid benchmark for random point data, and show identical performance -to the hand-written vertical SSE2 code.

-

The above code is written with simplicity in mind. The biggest improvement -would be to combine the scalar and SSE operator() (...) functions; this -could possibly be achieved by using Eigen::Array as an SSE backend (similar -to how Eigen::Matrix maps are currently used), something like:

-
// N can be 1 or 4
-template <int N>
-void operator() (const Eigen::Array<float, N, 1>& x,
-                 const Eigen::Array<float, N, 1>& y,
-                 const Eigen::Array<float, N, 1>& z);
-
-
-
-
-
-

Benchmarks (real point clouds)

-

Finally, we compare CentroidKernel + applicator to -pcl::compute3DCentroid() for several real organized (and one dense) point -clouds.

-

The point clouds used are:

- -

capture0001.pcd (organized, 640x480, 57553 NaNs):

-
PCL:    0.926901 seconds
-
-RLE:    0.348173 seconds
-Kernel: 0.174194 seconds
-
-
-

capture0002.pcd (organized, 640x480, 57269 NaNs):

-
PCL:    0.931111 seconds
-
-RLE:    0.345437 seconds
-Kernel: 0.171373 seconds
-
-
-

Even if you include the RLE computation time (which could be amortized over -several operations, and perhaps optimized) in the total, the vertical kernel -beats the current PCL implementation. Discounting RLE, it’s more than 5x faster.

-

table_scene_mug_stereo_textured.pcd (organized, 640x480, 97920 NaNs):

-
PCL:    3.36001 seconds
-
-RLE:    0.379737 seconds
-Kernel: 0.183159 seconds
-
-
-

The very poor performance of PCL on the mug scene is a mystery to me. Perhaps -the larger number of NaNs has an effect?

-

table_scene_lms400.pcd (dense, 460400 pts):

-
PCL:    0.678805 seconds
-
-RLE:    N/A
-Kernel: 0.242546 seconds
-
-
-
-
-

Conclusions

-

For the simple operations considered here, vertical SSE is a huge win. In the -best case, this suggests that much of PCL could get at least a 3x speedup by -switching to the more SSE-friendly memory layout.

-

Vertical SSE presents some complications in usage and implementation for PCL, -but good solutions (RLE, kernel abstraction) are possible.

-

Looking at instruction sets, vertical SSE is especially advantageous both on -older and very new processors. On older processors, because it makes excellent -use of SSE2 instructions, whereas horizontal SSE may require horizontal -instructions (introduced in SSE3 and later) for good performance. On new -processors, because the latest AVX extensions expand SSE register to 256 bits, -allowing 8 floating point operations at a time instead of 4. The vertical SSE -techniques shown here trivially extend to AVX, and future instruction sets will -likely expand SSE registers even further. The upcoming AVX2 extensions add -dedicated gather instructions, which should improve performance with indices.

-
-
-

Remaining questions

-

Are there PCL algorithms that aren’t easily implementable in the proposed -kernel style?

-

How to handle nearest neighbor searches? These may be hard to vectorize.

-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/index.php b/advanced/index.php deleted file mode 100644 index 2eb33ca33a04..000000000000 --- a/advanced/index.php +++ /dev/null @@ -1,158 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Compiling PCL - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-
-

The following presents a set of advanced topics regarding PCL.

-
-

Compiling PCL

-

PCL uses modern C++ template programming in order to achieve maximum generality -and reusability of its components. Due to intricate details of the current -generation of C++ compilers however, the usage of templated code introduces -additional compile-time delays. We present a series of tricks that, if used -appropriately, will save you a lot of headaches and will speed up the -compilation of your project.

-
    -
  • Using CCache to speed up compilation

    -

    CCache is a compiler cache. It speeds up recompilation by caching previous -compilations and detecting when the same compilation is being done again. -Supported languages are C, C++, Objective-C and Objective-C++.

    -_images/ccache.png -
  • -
  • Using DistCC to speed up compilation

    -

    distcc is a program to distribute builds of C, C++, Objective C or -Objective C++ code across several machines on a network. distcc should always -generate the same results as a local build, is simple to install and use, and -is usually much faster than a local compile.

    -_images/distcc.png -
  • -
  • Compiler optimizations

    -

    Depending on what compiler optimizations you use, your code might behave -differently, both at compile time and at run time.

    -_images/optimize.png -
  • -
  • Single compilation units

    -

    In certain cases, it’s better to concatenate source files into single -compilation units to speed up compiling.

    -_images/unitybuild.jpg -
  • -
-
-
-

Developing PCL code

-

To make our lives easier, and to be able to read and integrate code from each -other without causing ourselves headaches, we assembled a set of rules for PCL -development that everyone should follow:

-
-

Rules

-
    -
  • if you make important commits, please _add the commit log_ or something similar _to -the changelist page_ -(https://github.com/PointCloudLibrary/pcl/blob/master/CHANGES.md);

  • -
  • if you change anything in an existing algorithm, _make sure that there are -unit tests_ for it and _make sure that they pass before you commit_ the code;

  • -
  • if you add a new algorithm or method, please _document the code in a similar -manner to the existing PCL code_ (or better!), and _add some minimal unit -tests_ before you commit it;

  • -
  • method definitions go into (include/.h), templated implementations go into -(include/impl/.hpp), non-templated implementations go into (src/.cpp), and -unit tests go in (test/.cpp);

  • -
  • last but not least, please _respect the same naming and indentation -guidelines_ as you see in the PCL C++ Programming Style Guide.

  • -
-
- -
-
-

Committing changes to the git master

-

In order to oversee the commit messages more easier and that the changelist looks homogenous please keep the following format:

-

“* <fixed|bugfix|changed|new> X in @<classname>@ (#<bug number>)”

-
-
-

Improving the PCL documentation

-
    -
  • How to write a good tutorial

    -

    In case you want to contribute/help PCL by improving the existing -documentation and tutorials/examples, please read our short guide on how to -start.

    -
  • -
-
-
-

How to build a minimal example

- -
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/minimal_example.php b/advanced/minimal_example.php deleted file mode 100644 index 1a24115a4023..000000000000 --- a/advanced/minimal_example.php +++ /dev/null @@ -1,120 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - How to build a minimal example - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

How to build a minimal example

-

First of all make a backup of your current state or start a new project for the -minimal example. Than there are basically two ways: strip down your program or -start from scratch.

-
-

Method 1: Strip down your program

-

This method has the advantage that you start with your actual problem and you -can test all the time if you are on the right track. First make sure that the -program actually compiles without the problematic code by commenting it. Then -start removing unneeded code until the bare minimum and make sure that it’s -still showing the error by compiling it with and without the problematic line -(make sure it still emits the same error message).

-
-
-

Method 2: Start from scratch

-

If your program is to big to strip it down, it’s maybe easier to start from -scratch by building a small project that only includes the problematic code. -Again make sure that it actually compiles without the erroneous code and emits -the same error with it.

-
-
-
-

How to deal with input data (e.g. point clouds)

-

If you fear that your problem is connected to the input data (either if you -have a problem with pcl/io or the error depends on the input data) you should -include the input with your minimal example. If the file is to big and a -stripped down version doesn’t work, you should upload it somewhere and only -provide a link to the data. If you can’t include the data or don’t know a way -to provide it, add a remark to your mail and we will contact you to find a -solution.

-

If the input data is not so important it is best to generate fake data:

-
1
-2
pcl::PointCloud<pcl::PointCloudXYZ> cloud;
-cloud.insert (cloud.end (), PointXYZ (1, 1, 1));
-
-
-
-
-

I’m linking against other libraries, what to do?

-

Normally other libraries should not interfere, so try to build a minimal -example using PCL (and it’s dependencies) first. If your problems is gone -without the other library please make sure that it’s not actually a problem -with one of the other libraries and add a comment in your minimal example.

-
-
-

Final Make

-

Please put only one error into the minimal example as well as include all -necessary files to build it.

-
- - - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/pcl2.php b/advanced/pcl2.php deleted file mode 100644 index c8a9d7493882..000000000000 --- a/advanced/pcl2.php +++ /dev/null @@ -1,223 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - PCL 2.x API consideration guide - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

PCL 2.x API consideration guide

-

With the PCL 1.x API locked and a few releases already underway, it’s time to -consider what the next generation of libraries should look like. This document -discusses a series of changes to the current API, from base classes to higher -level algorithms.

-
-

Major changes

-
-

1.1 pcl::PointCloud

-

The :pcl:`PointCloud <pcl::PointCloud>` class represents the base class in PCL -for holding nD (n dimensional) data.

-
-
The 1.x API includes the following data members:
-
-
-

Proposals for the 2.x API:

-
-
    -
  • drop templating on point types, thus making :pcl:`PointCloud <pcl::PointCloud>` template free

  • -
  • drop the :pcl:`PCLHeader <pcl::PCLHeader>` structure, or consolidate all the above information (width, height, is_dense, sensor_origin, sensor_orientation) into a single struct

  • -
  • make sure we can access a slice of the data as a 2D image, thus allowing fast 2D displaying, [u, v] operations, etc

  • -
  • make sure we can access a slice of the data as a subpoint cloud: only certain points are chosen from the main point cloud

  • -
  • implement channels (of a single type!) as data holders, e.g.: -* cloud[“xyz”] => gets all 3D x,y,z data -* cloud[“normals”] => gets all surface normal data -* etc

  • -
  • internals should be hidden : only accessors (begin, end …) are public, this facilitating the change of the underlying structure

  • -
  • Capability to construct point cloud types containing the necessary channels -at runtime. This will be particularly useful for run-time configuration of -input sensors and for reading point clouds from files, which may contain a -variety of point cloud layouts not known until the file is opened.

  • -
  • Complete traits system to identify what data/channels a cloud stores at -runtime, facilitating decision making in software that uses PCL. (e.g. -generic component wrappers.)

  • -
  • Stream-based IO sub-system to allow developers to load a stream of point -clouds and “play” them through their algorithm(s), as well as easily capture -a stream of point clouds (e.g. from a Kinect). Perhaps based on -Boost::Iostreams.

  • -
  • Given the experience on libpointmatcher, -we (François Pomerleau and Stéphane Magnenat) propose the following data structures:

    -
    cloud = map<space_identifier, space>
    -space = tuple<type, components_identifiers, data_matrix>
    -components_identifiers = vector<component_identifier>
    -data_matrix = Eigen matrix
    -space_identifier = string with standardised naming (pos, normals, color, etc.)
    -component_identifier = string with standardised naming (x, y, r, g, b, etc.)
    -type = type of space, underlying scalar type + distance definition (float with euclidean 2-norm distance, float representing gaussians with Mahalanobis distance, binary with manhattan distance, float with euclidean infinity norm distance, etc.)
    -
    -
    -
    -
    For instance, a simple point + color scenario could be::

    cloud = { “pos” => pos_space, “color” => color_space } -pos_space = ( “float with euclidean 2-norm distance”, { “x”, “y”, “z” }, [[(0.3,0,1.3) , … , (1.2,3.1,2)], … , [(1,0.3,1) , … , (2,0,3.5)] ) -color_space = ( “uint8 with rgb distance”, { “r”, “g”, “b” }, [[(0,255,0), … , (128,255,32)] … [(12,54,31) … (255,0,192)]] )

    -
    -
    -
  • -
-
-
-
-

1.2 PointTypes

-
-
    -
  1. Eigen::Vector4f or Eigen::Vector3f ??

  2. -
  3. Large points cause significant performance penalty for GPU. Let’s assume that point sizes up to 16 bytes are suitable. This is some compromise between SOA and AOS. Structures like pcl::Normal (size = 32) is not desirable. SOA is better in this case.

  4. -
-
-
-
-

1.3 GPU support

-
-
    -
  1. Containers for GPU memory. pcl::gpu::DeviceMemory/DeviceMemory2D/DeviceArray<T>/DeviceArray2D<T> (Thrust containers are incinvinient).

    -
    -
      -
    • DeviceArray2D<T> is container for organized point cloud data (supports row alignment)

    • -
    -
    -
  2. -
  3. PointCloud Channels for GPU memory. Say, with “_gpu” postfix.

    -
    -
      -
    • cloud[“xyz_gpu”] => gets channel with 3D x,y,z data allocated on GPU.

    • -
    • GPU functions (ex. gpu::computeNormals) create new channel in cloud (ex. “normals_gpu”) and write there. Users can preallocate the channel and data inside it in order to save time on allocations.

    • -
    • Users must manually invoke uploading/downloading data to/from GPU. This provides better understanding how much each operation costs.

    • -
    -
    -
  4. -
  5. Two layers in GPU part: host layer(nvcc-independent interface) and device(for advanced use, for sharing code compiled by nvcc):

    -
    -
      -
    • namespace pcl::cuda (can depend on CUDA headers) or pcl::gpu (completely independent from CUDA, OpenCL support in future?).

    • -
    • namespace pcl::device for device layer, only headers.

    • -
    -
    -
  6. -
  7. Async operation support???

  8. -
-
-
-
-

1.4 Keypoints and features

-
-
    -
  1. The name Feature is a bit misleading, since it has tons of meanings. Alternatives are Descriptor or FeatureDescription.

  2. -
  3. In the feature description, there is no need in separate FeatureFromNormals class and setNormals() method, since all the required channels are contained in one input. We still need separate setSearchSurface() though.

  4. -
  5. There exist different types of keypoints (corners, blobs, regions), so keypoint detector might return some meta-information besides the keypoint locations (scale, orientation etc.). Some channels of that meta-information are required by some descriptors. There are options how to deliver that information from keypoints to descriptor, but it should be easy to pass it if a user doesn’t change anything. This interface should be uniform to allow for switching implementations and automated benchmarking. Still one might want to set, say, custom orientations, different from what detector returned.

    -
    -

    to be continued…

    -
    -
  6. -
-
-
-
-

1.5 Data slices

-

Anything involving a slice of data should use std::size_t for indices and not int. E.g the indices of the inliers in RANSAC, the focused points in RANSAC …

-
-
-

1.6 RANSAC

-
-
    -
  • Renaming the functions and internal variables: everything should be named with _src and _tgt: we have confusing names like indices_ and indices_tgt_ (and no indices_src_), setInputCloud and setInputTarget (duuh, everything is an input, it should be setTarget, setSource), in the code, a sample is named: selection, model_ and samples. getModelCoefficients is confusing with getModel (this one should be getBestSample).

  • -
  • no const-correctness all over, it’s pretty scary: all the get should be const, selectWithinDistance and so on too.

  • -
  • the getModel, getInliers function should not force you to fill a vector: you should just return a const reference to the internal vector: that could allow you to save a useless copy

  • -
  • some private members should be made protected in the sub sac models (like sac_model_registration) so that we can inherit from them.

  • -
  • the SampleConsensusModel should be independent from point clouds so that we can create our own model for whatever library. Then, the one used in the specialize models (like sac_model_registration and so on) should inherit from it and have constructors based on PointClouds like now. Maybe we should name those PclSampleConsensusModel or something (or have SampleConsensusModelBase and keep the naming for SampleConsensusModel).

  • -
-
-
-
-
-

Minor changes

-
- -
- - - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/pcl_reg_eval.php b/advanced/pcl_reg_eval.php deleted file mode 100644 index 5fe3371ee868..000000000000 --- a/advanced/pcl_reg_eval.php +++ /dev/null @@ -1,133 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Evaluating pcl/registration - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Evaluating pcl/registration

-

This is a collection of ideas on how to build an evaluation framework of pcl/registration.

-
-

Data generation

-
    -
  • synthetic data

  • -
  • real word data (how to get ground truth?) -- Kinect -- PR2 laser scanner -- SICK laser data -- small range 3D scanner -- mid range 3D scanner (Faro) -- high end 3D scanner (Riegl, Velodyne)

  • -
  • Point Types -- 2D(?) -- 3D -- RGB

  • -
  • dynamics -- static scans -- scanning while driving (e.g. robots)

  • -
  • size -- room -- building -- outdoor (street)

  • -
-
-
-

Architecture

-
    -
  • some lib for polygonal data

  • -
  • modeling different sensors

  • -
  • modeling noise

  • -
  • add a trajectory file

  • -
  • output a pile of .pcd files

  • -
  • integrate command line tools from PCL grandfather

  • -
-
-
-

Evaluating different algorithms

-
-

ICP

-
    -
  • how does the algorithm cope with outliers

  • -
  • how are the point pairs evaluated:

    -
      -
    • does it use normal or RGB information

    • -
    • does it weight the pairs differently

    • -
    • which kind of point pairs are used:

      -
        -
      • one-to-one

      • -
      • one-to-many

      • -
      • many-to-many

      • -
      -
    • -
    -
  • -
-
-
-
-

Similar Projects

- -
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/pcl_registration.php b/advanced/pcl_registration.php deleted file mode 100644 index 1f73d3a28cda..000000000000 --- a/advanced/pcl_registration.php +++ /dev/null @@ -1,312 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - PCL/registration - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

PCL/registration

-
-

Participants

-
    -
  • Michael Dixon

  • -
  • Radu Rusu

  • -
  • Nicola Fioraio

  • -
  • Jochen Sprickerhof

  • -
-
-
-

Existing Frameworks

-
    -
  • SLAM6D

  • -
  • Toro

  • -
  • Hogman

  • -
  • G2O

  • -
  • MegaSLAM/MegaICP

  • -
-
-
-

Mission

-

Provide a common interface/architecture for all of these and future SLAM ideas.

-
-
-

Ideas

-
    -
  • Separate algorithms from data structures.

  • -
  • strip down everything to it’s basics and define an interface.

  • -
  • modify data structure in algorithms (you can copy them before if you need to).

  • -
  • point clouds are not transformed, only the translation and rotation is updated.

  • -
-
-
-

Data structures

-
-

Note

-

These ideas are independent of actual data structures in the PCL for now. We can see later how to integrate them best.

-
-
-

Pose

-
struct Pose
-{
-  Eigen::Vector3 translation;
-  Eigen::Quaternion rotation;
-}
-
-
-
-
-

PointCloud

-
typedef vector<vector <float> > Points;
-
-
-
-
-

PosedPointCloud

-
typedef pair<Pose*, PointCloud*> PosedPointCloud;
-
-
-

PointCloud* can be 0.

-
-
-

Graph

-

This should hold the SLAM graph. I would propose to use Boost::Graph for it, as it allows us to access a lot of algorithms.

-
-

Note

-

define abstract structure.

-
-
-
-

CovarianceMatrix

-
typedef Eigen::Matrix4f CovarianceMatrix;
-
-
-
-
-

Measurement

-
struct Measurement
-{
-  Pose pose;
-  CovarianceMatrix covariance;
-}
-
-
-

Idea: change the CovarianceMatrix into a function pointer.

-
-
-
-

Interfaces

-
-

GlobalRegistration

-
class GlobalRegistration
-{
-  public:
-    /**
-      * \param history how many poses should be cached (0 means all)
-      */
-    GlobalRegistration (int history = 0) : history_(history) {}
-
-    /**
-      * \param pc a new point cloud for GlobalRegistration
-      * \param pose the initial pose of the pc, could be 0 (unknown)
-      */
-    void addPointCloud (PointCloud &pc, Pose &pose = 0)
-    {
-      new_clouds_.push_back (make_pair (pc, pose));
-    }
-
-    /**
-      * returns the current estimate of the transformation from point cloud from to point cloud to
-        throws an exception if the transformation is unknown
-      */
-    Pose getTF (PointCloud &from, PointCloud &to);
-
-    /**
-      * run the optimization process
-      * \param lod the level of detail (optional). Roughly how long it should run (TODO: better name/parametrization?)
-      */
-    virtual void compute (int lod = 0) {}
-
-  private:
-    int history_;
-    map<PointCloud*, Pose*> poses_;
-    PosedPointCloud new_clouds_;
-};
-
-
-

This will be the base class interface for every SLAM algorithm. At any point you can add point clouds and they will be processed. -The poses can be either in a global or in a local coordinate system (meaning that they are incremental regarding the last one). -Idea: Do we need the compute? Could it be included into the addPointCloud or getTF?

-
-
-

GraphOptimizer

-
class GraphOptimizer
-{
-  public:
-    virtual void optimize (Graph &gr) = 0;
-}
-
-
-
-
-

LoopDetection

-
class LoopDetection
-{
-  public:
-    virtual ~LoopDetection () {}
-    virtual list<pair<PointCloud*, PointCloud*> > detectLoop(list<PosedPointCloud*> poses, list<PosedPointCloud*> query) {} = 0;
-}
-
-
-
-
-

GraphHandler

-
class GraphHandler
-{
-  void addPose (Graph &gr, PointCloud &pc);
-  void addConstraint (Graph &gr, PointCloud &from, PointCloud &to, Pose &pose);
-}
-
-
-
-

Note

-

I’m not sure about this one.

-
-
-
-
-

Example Implementations

-
-

PairwiseGlobalRegistration

-
class PairwiseGlobalRegistration : public GlobalRegistration
-{
-  public:
-    PairwiseGlobalRegistration(Registration &reg) : reg_(reg) {}
-    virtual void compute (int lod = 0) {}
-    {
-      list<PosedPointCloud >::iterator cloud_it;
-      for (cloud_it = new_clouds_.begin(); cloud_it != new_clouds_.end(); cloud_it++)
-      {
-        if(!old_) {
-          old = *cloud_it;
-          continue;
-        }
-        reg_.align(old_, *cloud_it, transformation);
-        poses[*cloud_it] = transformation;
-        old_ = *cloud_it;
-      }
-      new_clouds_.clear();
-    }
-
-  private:
-    Registration &reg_;
-    PointCloud &old_;
-}
-
-
-
-
-

DistanceLoopDetection

-
class DistanceLoopDetection : LoopDetection
-{
-  public:
-    virtual list<pair<PointCloud*, PointCloud*> > detectLoop(list<PosedPointCloud*> poses, list<PosedPointCloud*> query)
-    {
-      //I want a map reduce here ;)
-      list<PosedPointCloud >::iterator poses_it;
-      for (poses_it = poses.begin(); poses_it != poses.end(); poses_it++)
-      {
-        list<PosedPointCloud >::iterator query_it;
-        for (query_it = query.begin(); query_it != query.end(); query_it++)
-        {
-          if (dist (*poses_it, *query_it) < min_dist_)
-          {
-            //..
-          }
-      }
-
-    }
-
-}
-
-
-
-
-

ELCH

-
class ELCH : public GlobalRegistration
-{
-  public:
-    ELCH(GlobalRegistration &initial_optimizer = PairwiseGlobalRegistration(), LoopDetection &loop_detection, GraphOptimizer &loop_optimizer, GraphOptimizer &graph_optimizer = LUM())
-}
-
-
-
-
-

LUM

-
class ELCH : public GlobalRegistration
-{
-  public:
-    ELCH(GlobalRegistration &initial_optimizer = PairwiseGlobalRegistration(), LoopDetection &loop_detection, GraphOptimizer &loop_optimizer, GraphOptimizer &graph_optimizer)
-}
-
-
-

Lu and Milios style scan matching (as in SLAM6D)

-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/pcl_style_guide.php b/advanced/pcl_style_guide.php deleted file mode 100644 index e61f514edcb6..000000000000 --- a/advanced/pcl_style_guide.php +++ /dev/null @@ -1,448 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - PCL C++ Programming Style Guide - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

PCL C++ Programming Style Guide

-

To make sure that all code in PCL is coherent and easily understood by other -developers and users, we follow a set of strict rules that everyone should -adopt. These rules are not to be broken unless there is a very good reason to -do so. Changes to these rules are always possible, but the person proposing and -changing a rule will have the unfortunate task to go and apply the rule change -to all the existing code.

- -
-

1. Naming

-
-

1.1. Files

-

All files should be under_scored.

-
    -
  • Header files have the extension .h

  • -
  • Templated implementation files have the extension .hpp

  • -
  • Source files have the extension .cpp

  • -
-
-
-

1.2. Directories

-

All directories and subdirectories should be under_scored.

-
    -
  • Header files should go under include/

  • -
  • Templated implementation files should go under include/impl/

  • -
  • Source files should go under src/

  • -
-
-
-

1.3. Includes

-

Include statements are made with “quotes” only if the file is in the -same directory, in any other case the include statement is made with -<chevron_brackets>, e.g.:

-
-
#include <pcl/module_name/file_name.h>
-#incluce <pcl/module_name/impl/file_name.hpp>
-
-
-
-
-
-

1.4. Defines & Macros

-

Macros should all be ALL_CAPITALS_AND_UNDERSCORED.

-

Include guards are not implemented with defines, instead #pragma once should be used.

-
-
// the license
-
-#pragma once
-
-// the code
-
-
-
-
-
-

1.5. Namespaces

-

Namespaces should be under_scored, e.g.:

-
-
namespace pcl_io
-{
-  ...
-}
-
-
-
-
-
-

1.6. Classes / Structs

-

Class names (and other type names) should be CamelCased. -Exception: if the class name contains a short acronym, the acronym itself -should be all capitals. Class and struct names are preferably nouns: -PFHEstimation instead of EstimatePFH.

-

Correct examples:

-
-
class ExampleClass;
-class PFHEstimation;
-
-
-
-
-
-

1.7. Functions / Methods

-

Functions and class method names should be camelCased, and arguments are -under_scored. Function and method names are preferably verbs, and the name -should make clear what it does: checkForErrors() instead of errorCheck(), -dumpDataToFile() instead of dataFile().

-

Correct usage:

-
-
int
-applyExample (int example_arg);
-
-
-
-
-
-

1.8. Variables

-

Variable names should be under_scored.

-
-
int my_variable;
-
-
-
-
-

1.8.1. Iterators

-

Iterator variables should indicate what they’re iterating over, e.g.:

-
-
std::list<int> pid_list;
-std::list<int>::iterator pid_it;
-
-
-
-
-
-

1.8.2. Constants

-

Constants should be ALL_CAPITALS, e.g.:

-
-
const static int MY_CONSTANT = 1000;
-
-
-
-
-
-

1.8.3. Member variables

-

Variables that are members of a class are under_scored_, with a trailing -underscore added, e.g.:

-
-
int example_int_;
-
-
-
-
-
-
-

1.9. Return statements

-

Return statements should have their values in parentheses, e.g.:

-
-
int
-main ()
-{
-  return (0);
-}
-
-
-
-
-

-
-
-
-
-

2. Indentation and Formatting

-

The standard indentation for each block in PCL is 2 spaces. Under no -circumstances, tabs or other spacing measures should be used. PCL uses a -variant of the GNU style formatting.

-
-

2.1. Namespaces

-

In both header and implementation files, namespaces are to be explicitly -declared, and their contents should not be indented, like clang-format -enforces in the Formatting CI job, e.g.:

-
namespace pcl
-{
-
-class Foo
-{
-  ...
-};
-
-}
-
-
-
-
-

2.2. Classes

-

The template parameters of a class should be declared on a different line, -e.g.:

-
template <typename T>
-class Foo
-{
-  ...
-}
-
-
-
-
-

2.3. Functions / Methods

-

The return type of each function declaration must be placed on a different -line, e.g.:

-
void
-bar ();
-
-
-

Same for the implementation/definition, e.g.:

-
void
-bar ()
-{
-  ...
-}
-
-
-

or

-
void
-Foo::bar ()
-{
-  ...
-}
-
-
-

or

-
template <typename T> void
-Foo<T>::bar ()
-{
-  ...
-}
-
-
-
-
-

2.4. Braces

-

Braces, both open and close, go on their own lines, e.g.:

-
if (a < b)
-{
-  ...
-}
-else
-{
-  ...
-}
-
-
-

Braces can be omitted if the enclosed block is a single-line statement, e.g.:

-
if (a < b)
-  x = 2 * a;
-
-
-
-
-

2.5. Spacing

-

We’ll say it again: the standard indentation for each block in PCL is 2 -spaces. We also include a space before the bracketed list of arguments to a -function/method, e.g.:

-
int
-exampleMethod (int example_arg);
-
-
-

Class and struct members are indented by 2 spaces. Access qualifiers (public, private and protected) are put at the -indentation level of the class body and members affected by these qualifiers are indented by one more level, i.e. 2 spaces. E.g.:

-
namespace foo
-{
-
-class Bar
-{
-  int i;
-  public:
-    int j;
-  protected:
-    void
-    baz ();
-};
-}
-
-
-
-
-

2.6. Automatic code formatting

-

We currently use clang-format-10 as the tool for auto-formatting our C++ code. -Please note that different versions of clang-format can result in slightly different outputs.

-

The style rules mentioned in this document are enforced via PCL’s .clang-format file. -The style files which were previously distributed should now be considered deprecated.

-

For the integration of clang-format with various text editors and IDE’s, refer to this page.

-

Details about the style options used can be found here.

-
-

2.6.1. Script usage

-

PCL also creates a build target ‘format’ to format the whitelisted directories using clang-format.

-

Command line usage:

-
$ make format
-
-
-
-
-
-
-

3. Structuring

-
-

3.1. Classes and API

-

For most classes in PCL, it is preferred that the interface (all public -members) does not contain variables and only two types of methods:

-
    -
  • The first method type is the get/set type that allows to manipulate the -parameters and input data used by the class.

  • -
  • The second type of methods is actually performing the class functionality -and produces output, e.g. compute, filter, segment.

  • -
-
-
-

3.2. Passing arguments

-

For get/set type methods the following rules apply:

-
    -
  • If large amounts of data needs to be set (usually the case with input data -in PCL) it is preferred to pass a boost shared pointer instead of the actual -data.

  • -
  • Getters always need to pass exactly the same types as their repsective setters -and vice versa.

  • -
  • For getters, if only one argument needs to be passed this will be done via -the return keyword. If two or more arguments need to be passed they will -all be passed by reference instead.

  • -
-

For the compute, filter, segment, etc. type methods the following rules apply:

-
    -
  • The output arguments are preferably non-pointer type, regardless of data -size.

  • -
  • The output arguments will always be passed by reference.

  • -
-
-
-

3.3. Object declaration

-
-

3.3.1 Use of auto

-
    -
  • For Iterators auto must be used as much as possible

  • -
  • In all the other cases auto can be used at the author’s discretion

  • -
  • Use const auto references by default in range loops. Drop the const if the item needs to be modified.

  • -
-
-
-

3.3.2 Type qualifiers of variables

-
    -
  • Declare variables const when they don’t need to be modified.

  • -
  • Use const references whenever you don’t need a copy of the variable.

  • -
  • Use of unsigned variables if the value is sure to not go negative by -use and by definition of the variable

  • -
-
-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/roadmap.php b/advanced/roadmap.php deleted file mode 100644 index 8b6e6606d902..000000000000 --- a/advanced/roadmap.php +++ /dev/null @@ -1,66 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Point Cloud Library (PCL) public roadmap - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Point Cloud Library (PCL) public roadmap

-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/search.php b/advanced/search.php deleted file mode 100644 index 4c09ef0ed450..000000000000 --- a/advanced/search.php +++ /dev/null @@ -1,88 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Search - - - - - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - - -
-
-
- -

Search

-
- -

- Please activate JavaScript to enable the search - functionality. -

-
-

- Searching for multiple words only shows matches that contain - all words. -

-
- - - -
- -
- -
- -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/single_compile_unit.php b/advanced/single_compile_unit.php deleted file mode 100644 index 1bfd95d9ebd8..000000000000 --- a/advanced/single_compile_unit.php +++ /dev/null @@ -1,110 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Single compilation units - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Single compilation units

-

Even before reading 1, we noticed a great speed up in compile time for all -PCL libraries if instead of compiling N object files and linking them together, -we compile only one, and include all the sources of the N files in this main -source. If you peek at an older version of PCL, you might notice things along -the lines of:

-
1
-2
-3
-4
-5
-6
 // Include the implementations instead of compiling them separately to speed up compile time
- #include "extract_indices.cpp"
- #include "passthrough.cpp"
- #include "project_inliers.cpp"
- #include "statistical_outlier_removal.cpp"
- #include "voxel_grid.cpp"
-
-
-

and in CMakeLists.txt:

-
1
-2
-3
-4
-5
-6
-7
-8
-9
 rosbuild_add_library (pcl_ros_filters
-                       src/pcl_ros/filters/filter.cpp
-                       # Compilation is much faster if we include all the following CPP files in filters.cpp
-                       #src/pcl_ros/filters/passthrough.cpp
-                       #src/pcl_ros/filters/project_inliers.cpp
-                       #src/pcl_ros/filters/extract_indices.cpp
-                       #src/pcl_ros/filters/statistical_outlier_removal.cpp
-                       #src/pcl_ros/filters/voxel_grid.cpp
-                      )
-
-
-

For more information on how/why this works, see 1.

-
-
1(1,2)
-

http://gamesfromwithin.com/physical-structure-and-c-part-2-build-times

-
-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/advanced/vertical_sse.php b/advanced/vertical_sse.php deleted file mode 100644 index e5beca1f0c58..000000000000 --- a/advanced/vertical_sse.php +++ /dev/null @@ -1,753 +0,0 @@ - - - -Documentation - Point Cloud Library (PCL) - - - - - - - - Vertical SSE for PCL2.0 - - - - - - - - -initialize('web'); - -$snip = $modx->runSnippet("getSiteNavigation", array('id'=>5, 'phLevels'=>'sitenav.level0,sitenav.level1', 'showPageNav'=>'n')); -$chunkOutput = $modx->getChunk("site-header", array('sitenav'=>$snip)); -$bodytag = str_replace("[[+showSubmenus:notempty=`", "", $chunkOutput); -$bodytag = str_replace("`]]", "", $bodytag); -echo $bodytag; -echo "\n"; -?> -
-

Documentation

- -
-
- - - -
-
-
- -
-

Vertical SSE for PCL2.0

- -
-

Representing point data

-

In PCL currently, points are stored with their fields interleaved. For the -simplest :pcl:`PointXYZ <pcl::PointXYZ>` type, this looks like:

-
XYZ_XYZ_XYZ_XYZ_ ...
-
-
-

where _ denotes an extra padding float so that each point is 16-byte -aligned. Operating on XYZ_ data efficiently often requires the use of -horizontal SSE instructions, which perform computations using multiple -elements of the same SSE register.

-

This representation is also known as Array-of-Structures (AoS). PointXYZ -is defined as a struct, and all fields for an individual point are stored -together in memory.

-

Instead a vertical representation, aka Structure-of-Arrays (SoA), can be -used:

-
XXXXXXXX ...
-YYYYYYYY ...
-ZZZZZZZZ ...
-
-
-

This layout fits traditional vertical SSE processing better. Most arithmetic -SSE instructions are binary operations on corresponding elements of two SSE -registers.

-
-
-

Why does PCL use AoS?

-

PCL’s use of AoS, normally non-optimal, does have its logic. In PCL, frequently -we wish to process only some (indexed / valid) subset of a point cloud. Besides -dense processing of all points, we then have two other cases.

-
-

Indexed subsets

-

PCL operators routinely provide a :pcl:`setIndices() -<pcl::PCLBase::setIndices>` method, ordering them to use only certain points -identified by index. With the AoS representation, each individual point can be -used in an SSE register via a simple aligned load. Indexed access therefore -does not much complicate an SSE-optimized implementation.

-

Vertical SSE (in the dense case) processes four adjacent points simultaneously, -and indexed access breaks the adjacency requirement. Instead of an aligned -load, the implementation must “gather” the data for the next four indexed -points (spread out in memory).

-
-
-

Organized point clouds

-

PCL permits point clouds with missing data. For imager-based 3D sensors, this -allows point clouds to retain their 2D structure, making it trivial to identify -nearby points. Invalid points have each field set to NaN, so that it is clear -when invalid data is accidentally used in a computation.

-

Handling invalid points in PCL (with AoS) is again rather simple. For each -point, check if X is NaN; if so, ignore it.

-

The SoA situation is much more complicated. Since we operate on four points at -a time, we have to check if any of the four points are invalid. If so, it -becomes very tricky to use SSE at all without destroying our result. Masking -tricks are possible, but imply some overhead over the simple dense code.

-
-
-
-

Horizontal or vertical?

-

Both representations have pros and cons.

-

Horizontal

-
    -
  • Pros

    -
      -
    • More intuitive, easier to write code for

    • -
    • Handling indexed subsets is simple - can still use aligned loads

    • -
    • Handling NaNs also simple

    • -
    -
  • -
  • Cons

    -
      -
    • Clearly slower at dense processing

    • -
    • Waste space and computation on padding elements

    • -
    -
  • -
-

Vertical

-
    -
  • Pros

    -
      -
    • Clearly faster at dense processing

    • -
    • No wasted space - only 3/4 as many loads required

    • -
    • No wasted computation

    • -
    • May have less loop overhead, since you process 4 points per iteration -instead of 1

    • -
    -
  • -
  • Cons

    -
      -
    • Less intuitive

    • -
    • Indexed subsets require gathering data for non-adjacent points

    • -
    • Handling NaNs is complicated

    • -
    -
  • -
-
-
-

Data structures

-

For benchmarking, we define two very simple point cloud representations:

-
// Array-of-Structures
-struct AOS
-{
-  float x;
-  float y;
-  float z;
-  float h;
-};
-
-// Structure-of-Arrays
-struct SOA
-{
-  float* x;
-  float* y;
-  float* z;
-  std::size_t size;
-};
-
-
-
-
-

Computations considered

-

We benchmark two basic operations:

-
    -
  • Compute the dot product of every point in a cloud with a given point

  • -
  • Compute the centroid of a point cloud

  • -
-

For both operations, we implemented several versions covering the space of:

-
    -
  • Horizontal (AoS) or vertical (SoA)

  • -
  • Dense or indexed

  • -
  • SSE instruction set

  • -
-

Representative examples are listed below.

-
-

Dot product

-

Vertical (SoA), SSE2-optimized:

-
void dotSSE2 (const SOA& vectors, const AOS& vector,
-              float* result, unsigned long size)
-{
-  float x = vector.x, y = vector.y, z = vector.z;
-
-  // Broadcast X, Y, Z of constant vector into 3 SSE registers
-  __m128 vX  = _mm_set_ps1(x);
-  __m128 vY  = _mm_set_ps1(y);
-  __m128 vZ  = _mm_set_ps1(z);
-  __m128 X, Y, Z;
-
-  unsigned i = 0;
-  for ( ; i < size - 3; i += 4)
-  {
-    // Load data for next 4 points
-    X = _mm_load_ps (vectors.x + i);
-    Y = _mm_load_ps (vectors.y + i);
-    Z = _mm_load_ps (vectors.z + i);
-
-    // Compute X*X'+Y*Y'+Z*Z' for each point
-    X = _mm_mul_ps (X, vX);
-    Y = _mm_mul_ps (Y, vY);
-    Z = _mm_mul_ps (Z, vZ);
-    X = _mm_add_ps (X, Y);
-    X = _mm_add_ps (X, Z);
-
-    // Store results
-    _mm_store_ps(result + i, X);
-  }
-
-  // Handle any leftovers at the end
-  for ( ; i < size; ++i)
-  {
-    result[i] = vectors.x[i]*x + vectors.y[i]*y + vectors.z[i]*z;
-  }
-}
-
-
-

Horizontal (AoS), SSE4.1-optimized (with horizontal DPPS instruction):

-
void dotSSE4_1 (const AOS* vectors, const AOS& vector,
-                float* result, unsigned long size)
-{
-  // Load constant vector into an SSE register
-  __m128 vec = _mm_load_ps ((const float*) &vector);
-  __m128 XYZH;
-
-  // Set mask to ignore the padding elements
-  const int mask = 123;
-  for (unsigned i = 0; i < size; ++i)
-  {
-    // Load next point
-    XYZH = _mm_load_ps ((const float*)(vectors + i));
-
-    // Dot product from SSE4.1
-    XYZH = _mm_dp_ps (XYZH, vec, mask);
-
-    // Store single result (the bottom register element)
-    _mm_store_ss (&(result [i]), XYZH);
-  }
-}
-
-
-
-
-

Centroid

-

Vertical (SoA), SSE2-optimized:

-
void centroidSSE2 (const SOA& vectors, AOS& result, std::size_t size)
-{
-  __m128 X_sum = _mm_setzero_ps();
-  __m128 Y_sum = _mm_setzero_ps();
-  __m128 Z_sum = _mm_setzero_ps();
-  __m128 X, Y, Z;
-
-  std::size_t i = 0;
-  for ( ; i < size - 3; i += 4)
-  {
-    // Load next 4 points
-    X = _mm_load_ps (vectors.x + i);
-    Y = _mm_load_ps (vectors.y + i);
-    Z = _mm_load_ps (vectors.z + i);
-
-    // Accumulate 4 sums in each dimension
-    X_sum = _mm_add_ps(X_sum, X);
-    Y_sum = _mm_add_ps(Y_sum, Y);
-    Z_sum = _mm_add_ps(Z_sum, Z);
-  }
-
-  // Horizontal adds (HADD from SSE3 could help slightly)
-  float* pX = reinterpret_cast<float*>(&X_sum);
-  float* pY = reinterpret_cast<float*>(&Y_sum);
-  float* pZ = reinterpret_cast<float*>(&Z_sum);
-  result.x = pX[0] + pX[1] + pX[2] + pX[3];
-  result.y = pY[0] + pY[1] + pY[2] + pY[3];
-  result.z = pZ[0] + pZ[1] + pZ[2] + pZ[3];
-
-  // Leftover points
-  for ( ; i < size; ++i)
-  {
-    result.x += vectors.x[i];
-    result.y += vectors.y[i];
-    result.z += vectors.z[i];
-  }
-
-  // Average
-  float inv_size = 1.0f / size;
-  result.x *= inv_size;
-  result.y *= inv_size;
-  result.z *= inv_size;
-}
-
-
-

Horizontal (AoS), SSE2-optimized:

-
void centroidSSE2 (const AOS* vectors, AOS& result, std::size_t size)
-{
-  __m128 sum = _mm_setzero_ps();
-
-  for (unsigned i = 0; i < size; ++i)
-  {
-    __m128 XYZH = _mm_load_ps ((const float*)(vectors + i));
-    sum = _mm_add_ps(sum, XYZH);
-  }
-  _mm_store_ps((float*)&result, sum);
-
-  float inv_size = 1.0f / size;
-  result.x *= inv_size;
-  result.y *= inv_size;
-  result.z *= inv_size;
-}
-
-
-
-
-

Indexed

-

When using point indices, the vertical implementation can no longer use aligned -loads. Instead it’s best to use the _mm_set_ps intrinsic to gather the next -four points.

-

Vertical (SoA) dot product, SSE2-optimized:

-
void dotIndexedSSE2 (const SOA& vectors, const AOS& vector,
-                     const int* indices, float* result, unsigned long size)
-{
-  float x = vector.x, y = vector.y, z = vector.z;
-
-  __m128 vX  = _mm_set_ps1(x);
-  __m128 vY  = _mm_set_ps1(y);
-  __m128 vZ  = _mm_set_ps1(z);
-  __m128 X, Y, Z;
-
-  unsigned i = 0;
-  for ( ; i < size - 3; i += 4)
-  {
-    int i0 = indices[i + 0];
-    int i1 = indices[i + 1];
-    int i2 = indices[i + 2];
-    int i3 = indices[i + 3];
-
-    // Gather next four indexed points
-    X = _mm_set_ps(vectors.x[i3], vectors.x[i2], vectors.x[i1], vectors.x[i0]);
-    Y = _mm_set_ps(vectors.y[i3], vectors.y[i2], vectors.y[i1], vectors.y[i0]);
-    Z = _mm_set_ps(vectors.z[i3], vectors.z[i2], vectors.z[i1], vectors.z[i0]);
-
-    // Computation
-    X = _mm_mul_ps (X, vX);
-    Y = _mm_mul_ps (Y, vY);
-    Z = _mm_mul_ps (Z, vZ);
-    X = _mm_add_ps (X, Y);
-    X = _mm_add_ps (X, Z);
-
-    // Store result
-    _mm_store_ps(result + i, X);
-  }
-
-  for ( ; i < size; ++i)
-  {
-    int idx = indices[i];
-    result[i] = vectors.x[idx]*x + vectors.y[idx]*x + vectors.z[idx]*z;
-  }
-}
-
-
-
-
-
-

Benchmarks (random data)

-

The test point cloud is randomly generated, 640x480, dense. Each operation is -repeated 1000 times.

-

For indexed tests, the indices list every 4th point. More random index patterns -would change execution time by affecting caching and prefetching, but I’d -expect such effects to be similar for horizontal and vertical code.

-

“Scalar” code uses no vector instructions, otherwise the instruction set is -listed. A trailing u# means the code was unrolled by factor #.

-
-

Dot product

-
-

Dense

-
Horizontal (AOS)
-  Scalar:   0.621674 seconds
-  SSE2:     0.756300 seconds
-  SSE4.1:   0.532441 seconds
-  SSE4.1u4: 0.476841 seconds
-Vertical (SOA)
-  Scalar:   0.519625 seconds
-  SSE2:     0.215499 seconds
-
-
-

The vertical SSE2 code is the clear winner, more than twice as fast as -horizontal code even with the special horizontal dot product from SSE4.1.

-

On the first i7 I used, horizontal SSE4.1 was actually the slowest -implementation. Unrolling it x4 helped significantly, although it was still -much worse than vertical SSE2. I attributed this to the very high latency of -the DPPS instruction; it takes 11 cycles before the result can be stored. -Unrolling helps hide the latency by providing more computation to do during -that time. I don’t know why the results from my office i7 (shown above) are so -different.

-
-
-

Indexed

-
Horizontal (AOS)
-  Scalar:   0.271768 seconds
-  SSE2:     0.276114 seconds
-  SSE4.1:   0.259613 seconds
-Vertical (SOA)
-  Scalar:   0.193394 seconds
-  SSE2:     0.177262 seconds
-
-
-

SSE optimization actually gives meager benefits in both the horizontal and -vertical cases. However vertical SSE2 is still the winner.

-
-
-
-

Centroid

-

The story for centroid is similar; vertical SSE2 is fastest, significantly so -for dense data.

-
-

Dense

-
Horizontal (AOS)
-  Scalar:  0.628597 seconds
-  SSE2:    0.326645 seconds
-  SSE2u2:  0.247539 seconds
-  SSE2u4:  0.236474 seconds
-Vertical (SOA)
-  Scalar:  0.711040 seconds
-  SSE2:    0.149806 seconds
-
-
-
-
-

Indexed

-
Horizontal (AOS)
-  Scalar:  0.256237 seconds
-  SSE2:    0.195724 seconds
-Vertical (SOA)
-  Scalar:  0.194030 seconds
-  SSE2:    0.166639 seconds
-
-
-
-
-
-
-

Vertical SSE for organized point clouds

-

We still need a way to effectively use vertical SSE for organized point clouds -(containing NaNs). A promising approach is to compute a run-length encoding -(RLE) of the valid points as a preprocessing step. The data structure is very -simple:

-
struct RlePair
-{
-  std::size_t good;
-  std::size_t skip;
-};
-typedef std::vector<RlePair> RLE;
-
-
-

The RLE counts the length of alternating runs of valid and invalid points. Once -computed, it allows us to process only valid points without explicitly checking -each one for NaNs. In fact, operations become O(#valid points) instead of -O(#total points), which can itself be a win if many points are invalid.

-

In real scenes, valid points are clustered together (into objects), so valid -(and invalid) runs should be lengthy on average. A long run of valid points can -be split into <4 beginning points, <4 final points, and a run of aligned, valid -point data which can be safely processed with vertical SSE.

-
-
-

Abstracting point iteration

-

We are still left with three distinct cases for processing point clouds, -requiring different methods of iterating over point data:

-
    -
  • Dense (no NaNs)

  • -
  • Indexed

  • -
  • Organized (contains NaNs)

  • -
-

Writing and maintaining three copies of each PCL algorithm is a huge burden. -The RLE for organized data in particular imposes a relatively complicated -iteration method. Ideally we should be able to write the computational core of -an algorithm only once, and have it work efficiently in each of the three cases.

-

Currently PCL does not meet this goal. In fact, core algorithms tend to have -four near-identical implementations:

-
    -
  • Dense

  • -
  • Dense indexed

  • -
  • Organized

  • -
  • Organized indexed

  • -
-

I think it’s unnecessary to distinguish between “dense indexed” and “organized -indexed”, if we require that indices point to valid data.

-
-

Writing algorithms as computational kernels

-

As an experiment, I rewrote the vertical centroid as a kernel class. This -implements only the computation, without worrying about the memory layout of -the whole cloud:

-
struct CentroidKernel
-{
-  // State
-  float x_sum, y_sum, z_sum;
-  __m128 X_sum, Y_sum, Z_sum;
-  std::size_t count;
-  AOS result;
-
-  void init()
-  {
-    // Initialization
-    x_sum = y_sum = z_sum = 0.0f;
-    X_sum = _mm_setzero_ps();
-    Y_sum = _mm_setzero_ps();
-    Z_sum = _mm_setzero_ps();
-    count = 0;
-  }
-
-  // Scalar operator
-  inline void operator() (float x, float y, float z)
-  {
-    x_sum += x;
-    y_sum += y;
-    z_sum += z;
-    ++count;
-  }
-
-  // SIMD operator
-  inline void operator() (__m128 X, __m128 Y, __m128 Z)
-  {
-    X_sum = _mm_add_ps(X_sum, X);
-    Y_sum = _mm_add_ps(Y_sum, Y);
-    Z_sum = _mm_add_ps(Z_sum, Z);
-    count += 4;
-  }
-
-  void reduce()
-  {
-    float* pX = reinterpret_cast<float*>(&X_sum);
-    float* pY = reinterpret_cast<float*>(&Y_sum);
-    float* pZ = reinterpret_cast<float*>(&Z_sum);
-    result.x = pX[0] + pX[1] + pX[2] + pX[3] + x_sum;
-    result.y = pY[0] + pY[1] + pY[2] + pY[3] + y_sum;
-    result.z = pZ[0] + pZ[1] + pZ[2] + pZ[3] + z_sum;
-
-    float inv_count = 1.0f / count;
-    result.x *= inv_count;
-    result.y *= inv_count;
-    result.z *= inv_count;
-  }
-};
-
-
-
-
-

Kernel applicators

-

We can then define applicator functions that apply a kernel to a particular -case of point cloud. The dense version simply uses aligned loads:

-
template <typename Kernel>
-void applyDense (Kernel& kernel, const SOA& pts)
-{
-  kernel.init();
-
-  std::size_t i = 0;
-  for ( ; i < pts.size - 3; i += 4)
-  {
-    __m128 X = _mm_load_ps (pts.x + i);
-    __m128 Y = _mm_load_ps (pts.y + i);
-    __m128 Z = _mm_load_ps (pts.z + i);
-
-    kernel(X, Y, Z);
-  }
-  for ( ; i < pts.size; ++i)
-  {
-    kernel(pts.x[i], pts.y[i], pts.z[i]);
-  }
-
-  kernel.reduce();
-}
-
-
-

The indexed version performs the necessary data gathering:

-
template <typename Kernel>
-void applySparse (Kernel& kernel, const SOA& pts,
-                  const std::vector<int>& indices)
-{
-  kernel.init();
-
-  std::size_t i = 0;
-  for ( ; i < indices.size() - 3; i += 4)
-  {
-    int i0 = indices[i + 0];
-    int i1 = indices[i + 1];
-    int i2 = indices[i + 2];
-    int i3 = indices[i + 3];
-
-    // Gather next four indexed points
-    __m128 X = _mm_set_ps(pts.x[i3], pts.x[i2], pts.x[i1], pts.x[i0]);
-    __m128 Y = _mm_set_ps(pts.y[i3], pts.y[i2], pts.y[i1], pts.y[i0]);
-    __m128 Z = _mm_set_ps(pts.z[i3], pts.z[i2], pts.z[i1], pts.z[i0]);
-
-    kernel(X, Y, Z);
-  }
-  for ( ; i < indices.size(); ++i)
-  {
-    int idx = indices[i];
-    kernel(pts.x[idx], pts.y[idx], pts.z[idx]);
-  }
-
-  kernel.reduce();
-}
-
-
-

The organized version is most complicated, and uses the RLE to vectorize as -much of the computation as possible:

-
template <typename Kernel>
-void applyOrganized (Kernel& kernel, const SOA& pts, const RLE& rle)
-{
-  kernel.init();
-
-  std::size_t i = 0;
-  for (RLE::const_iterator rle_it = rle.begin(); rle_it != rle.end(); ++rle_it)
-  {
-    // Process current stretch of good pixels
-    std::size_t good = rle_it->good;
-    std::size_t skip = rle_it->skip;
-    std::size_t good_end = i + good;
-
-    // Any unaligned points at start
-    std::size_t unaligned_end = std::min( (i + 3) & ~3, good_end );
-    for ( ; i < unaligned_end; ++i)
-      kernel(pts.x[i], pts.y[i], pts.z[i]);
-    // Aligned SIMD point data
-    for ( ; i + 4 <= good_end; i += 4)
-    {
-      __m128 X = _mm_load_ps (pts.x + i);
-      __m128 Y = _mm_load_ps (pts.y + i);
-      __m128 Z = _mm_load_ps (pts.z + i);
-
-      kernel(X, Y, Z);
-    }
-    // <4 remaining points
-    for ( ; i < good_end; ++i)
-      kernel(pts.x[i], pts.y[i], pts.z[i]);
-
-    // Skip the following stretch of NaNs
-    i += skip;
-  }
-
-  kernel.reduce();
-}
-
-
-

The kernel + applicator combinations for the dense and indexed cases were added -to the centroid benchmark for random point data, and show identical performance -to the hand-written vertical SSE2 code.

-

The above code is written with simplicity in mind. The biggest improvement -would be to combine the scalar and SSE operator() (...) functions; this -could possibly be achieved by using Eigen::Array as an SSE backend (similar -to how Eigen::Matrix maps are currently used), something like:

-
// N can be 1 or 4
-template <int N>
-void operator() (const Eigen::Array<float, N, 1>& x,
-                 const Eigen::Array<float, N, 1>& y,
-                 const Eigen::Array<float, N, 1>& z);
-
-
-
-
-
-

Benchmarks (real point clouds)

-

Finally, we compare CentroidKernel + applicator to -pcl::compute3DCentroid() for several real organized (and one dense) point -clouds.

-

The point clouds used are:

- -

capture0001.pcd (organized, 640x480, 57553 NaNs):

-
PCL:    0.926901 seconds
-
-RLE:    0.348173 seconds
-Kernel: 0.174194 seconds
-
-
-

capture0002.pcd (organized, 640x480, 57269 NaNs):

-
PCL:    0.931111 seconds
-
-RLE:    0.345437 seconds
-Kernel: 0.171373 seconds
-
-
-

Even if you include the RLE computation time (which could be amortized over -several operations, and perhaps optimized) in the total, the vertical kernel -beats the current PCL implementation. Discounting RLE, it’s more than 5x faster.

-

table_scene_mug_stereo_textured.pcd (organized, 640x480, 97920 NaNs):

-
PCL:    3.36001 seconds
-
-RLE:    0.379737 seconds
-Kernel: 0.183159 seconds
-
-
-

The very poor performance of PCL on the mug scene is a mystery to me. Perhaps -the larger number of NaNs has an effect?

-

table_scene_lms400.pcd (dense, 460400 pts):

-
PCL:    0.678805 seconds
-
-RLE:    N/A
-Kernel: 0.242546 seconds
-
-
-
-
-

Conclusions

-

For the simple operations considered here, vertical SSE is a huge win. In the -best case, this suggests that much of PCL could get at least a 3x speedup by -switching to the more SSE-friendly memory layout.

-

Vertical SSE presents some complications in usage and implementation for PCL, -but good solutions (RLE, kernel abstraction) are possible.

-

Looking at instruction sets, vertical SSE is especially advantageous both on -older and very new processors. On older processors, because it makes excellent -use of SSE2 instructions, whereas horizontal SSE may require horizontal -instructions (introduced in SSE3 and later) for good performance. On new -processors, because the latest AVX extensions expand SSE register to 256 bits, -allowing 8 floating point operations at a time instead of 4. The vertical SSE -techniques shown here trivially extend to AVX, and future instruction sets will -likely expand SSE registers even further. The upcoming AVX2 extensions add -dedicated gather instructions, which should improve performance with indices.

-
-
-

Remaining questions

-

Are there PCL algorithms that aren’t easily implementable in the proposed -kernel style?

-

How to handle nearest neighbor searches? These may be hard to vectorize.

-
-
- - -
-
-
-
-
- -getChunk("site-footer"); -echo $chunkOutput; -?> - - - \ No newline at end of file diff --git a/search-config.php b/search-config.php deleted file mode 100644 index a4739ed45640..000000000000 --- a/search-config.php +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/search-functions.php b/search-functions.php deleted file mode 100644 index 5ad2e5d740e2..000000000000 --- a/search-functions.php +++ /dev/null @@ -1,366 +0,0 @@ - diff --git a/search-opensearch.php b/search-opensearch.php deleted file mode 100644 index 3b59516db8bc..000000000000 --- a/search-opensearch.php +++ /dev/null @@ -1,127 +0,0 @@ - diff --git a/search.php b/search.php deleted file mode 100644 index 23e2e25c08d4..000000000000 --- a/search.php +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - -Point Cloud Library (PCL): Search - - - - - - - - - - -
-
- - - - - - -
-
Point Cloud Library (PCL) -  1.8.1-dev -
-
-
- - - -