New upstream version 1.12.1+dfsg
authorJochen Sprickerhof <git@jochen.sprickerhof.de>
Fri, 24 Dec 2021 21:52:10 +0000 (22:52 +0100)
committerJochen Sprickerhof <git@jochen.sprickerhof.de>
Fri, 24 Dec 2021 21:52:10 +0000 (22:52 +0100)
153 files changed:
.ci/azure-pipelines/azure-pipelines.yaml
.ci/azure-pipelines/env.yml
.clang-format
.dev/docker/perception_pcl_ros/Dockerfile
.dev/docker/windows/Dockerfile
.dev/format.sh
.github/FUNDING.yml [new file with mode: 0644]
CHANGES.md
CMakeLists.txt
PCLConfig.cmake.in
README.md
apps/3d_rec_framework/include/pcl/apps/3d_rec_framework/pipeline/impl/global_nn_recognizer_cvfh.hpp
apps/3d_rec_framework/src/tools/local_recognition_mian_dataset.cpp
apps/CMakeLists.txt
apps/cloud_composer/CMakeLists.txt
apps/cloud_composer/ComposerTool.cmake
apps/in_hand_scanner/CMakeLists.txt
apps/include/pcl/apps/impl/dominant_plane_segmentation.hpp
apps/modeler/CMakeLists.txt
apps/point_cloud_editor/CMakeLists.txt
apps/point_cloud_editor/src/cloudEditorWidget.cpp
cmake/CudaComputeTargetFlags.cmake [deleted file]
cmake/Modules/FindFLANN.cmake
cmake/Modules/FindOpenMP.cmake [new file with mode: 0644]
cmake/Modules/FindOpenNI.cmake
cmake/Modules/FindOpenNI2.cmake
cmake/Modules/FindQhull.cmake [changed mode: 0644->0755]
cmake/Modules/Findlibusb.cmake
cmake/pcl_all_in_one_installer.cmake
cmake/pcl_cpack.cmake
cmake/pcl_find_avx.cmake
cmake/pcl_find_boost.cmake
cmake/pcl_find_cuda.cmake
cmake/pcl_find_libusb.cmake [new file with mode: 0644]
cmake/pcl_find_qt.cmake [new file with mode: 0644]
cmake/pcl_find_sse.cmake
cmake/pcl_find_vtk.cmake
cmake/pcl_options.cmake
cmake/pcl_pclconfig.cmake
cmake/pcl_targets.cmake
common/CMakeLists.txt
common/include/pcl/common/eigen.h
common/include/pcl/common/impl/centroid.hpp
common/include/pcl/conversions.h
common/src/feature_histogram.cpp
common/src/fft/kiss_fft.c
cuda/common/CMakeLists.txt
cuda/filters/include/pcl/cuda/filters/filter.h
cuda/filters/include/pcl/cuda/filters/voxel_grid.h
doc/advanced/content/conf.py
doc/requirements.txt
doc/tutorials/content/adding_custom_ptype.rst
doc/tutorials/content/conf.py
doc/tutorials/content/correspondence_grouping.rst
doc/tutorials/content/davidsdk.rst
doc/tutorials/content/index.rst
doc/tutorials/content/qt_colorize_cloud.rst
doc/tutorials/content/qt_visualizer.rst
doc/tutorials/content/rops_feature.rst
doc/tutorials/content/sources/qt_colorize_cloud/CMakeLists.txt
doc/tutorials/content/sources/qt_colorize_cloud/pclviewer.cpp
doc/tutorials/content/sources/qt_colorize_cloud/pclviewer.h
doc/tutorials/content/sources/qt_colorize_cloud/pclviewer.ui
doc/tutorials/content/sources/qt_visualizer/CMakeLists.txt
doc/tutorials/content/sources/qt_visualizer/pclviewer.cpp
doc/tutorials/content/sources/qt_visualizer/pclviewer.h
doc/tutorials/content/sources/qt_visualizer/pclviewer.ui
doc/tutorials/content/using_pcl_pcl_config.rst
doc/tutorials/content/writing_new_classes.rst
features/include/pcl/features/3dsc.h
features/include/pcl/features/impl/3dsc.hpp
filters/include/pcl/filters/crop_hull.h
filters/include/pcl/filters/impl/convolution.hpp
filters/include/pcl/filters/impl/crop_hull.hpp
filters/include/pcl/filters/impl/voxel_grid_covariance.hpp
filters/include/pcl/filters/normal_space.h
filters/include/pcl/filters/voxel_grid.h
filters/src/convolution.cpp
geometry/CMakeLists.txt
geometry/include/pcl/geometry/mesh_base.h
gpu/containers/CMakeLists.txt
gpu/containers/include/pcl/gpu/containers/device_memory.h
gpu/kinfu/CMakeLists.txt
gpu/kinfu/test/CMakeLists.txt [deleted file]
gpu/kinfu/tools/CMakeLists.txt
gpu/kinfu_large_scale/CMakeLists.txt
gpu/kinfu_large_scale/test/CMakeLists.txt [deleted file]
gpu/kinfu_large_scale/tools/CMakeLists.txt
gpu/people/CMakeLists.txt
gpu/people/src/organized_plane_detector.cpp
gpu/people/tools/CMakeLists.txt
gpu/segmentation/include/pcl/gpu/segmentation/gpu_extract_clusters.h
gpu/segmentation/include/pcl/gpu/segmentation/gpu_extract_labeled_clusters.h
gpu/segmentation/include/pcl/gpu/segmentation/gpu_seeded_hue_segmentation.h
gpu/segmentation/include/pcl/gpu/segmentation/impl/gpu_extract_clusters.hpp
gpu/segmentation/include/pcl/gpu/segmentation/impl/gpu_extract_labeled_clusters.hpp
gpu/segmentation/include/pcl/gpu/segmentation/impl/gpu_seeded_hue_segmentation.hpp
gpu/surface/CMakeLists.txt
io/CMakeLists.txt
io/include/pcl/compression/impl/organized_pointcloud_compression.hpp
io/include/pcl/io/impl/vtk_lib_io.hpp
io/include/pcl/io/real_sense_2_grabber.h
io/include/pcl/io/tim_grabber.h [new file with mode: 0644]
io/src/ply/ply_parser.cpp
io/src/ply_io.cpp
io/src/tim_grabber.cpp [new file with mode: 0644]
io/tools/CMakeLists.txt
kdtree/include/pcl/kdtree/kdtree_flann.h
keypoints/include/pcl/keypoints/impl/iss_3d.hpp
keypoints/include/pcl/keypoints/iss_3d.h
ml/src/svm.cpp
octree/include/pcl/octree/octree_iterator.h
outofcore/include/pcl/outofcore/visualization/common.h
pcl_config.h.in
people/CMakeLists.txt
registration/include/pcl/registration/gicp6d.h
registration/include/pcl/registration/ia_ransac.h
registration/include/pcl/registration/impl/ndt.hpp
registration/include/pcl/registration/impl/ppf_registration.hpp
sample_consensus/include/pcl/sample_consensus/impl/sac_model_cylinder.hpp
sample_consensus/include/pcl/sample_consensus/sac_model_registration.h
search/include/pcl/search/flann_search.h
surface/CMakeLists.txt
surface/include/pcl/surface/3rdparty/poisson4/multi_grid_octree_data.hpp
surface/include/pcl/surface/impl/mls.hpp
surface/include/pcl/surface/impl/organized_fast_mesh.hpp
surface/include/pcl/surface/impl/texture_mapping.hpp
surface/include/pcl/surface/mls.h
surface/include/pcl/surface/vtk_smoothing/vtk.h
surface/src/mls.cpp
test/common/CMakeLists.txt
test/common/test_pointcloud.cpp
test/features/test_normal_estimation.cpp
test/filters/test_crop_hull.cpp
test/filters/test_functor_filter.cpp
test/filters/test_sampling.cpp
test/geometry/CMakeLists.txt
test/io/CMakeLists.txt
test/io/test_ply_io.cpp
test/io/test_tim_grabber.cpp [new file with mode: 0644]
test/people/CMakeLists.txt
test/people/test_people_groundBasedPeopleDetectionApp.cpp
test/sample_consensus/test_sample_consensus_plane_models.cpp
test/sample_consensus/test_sample_consensus_quadric_models.cpp
test/search/test_flann_search.cpp
test/segmentation/CMakeLists.txt
tools/CMakeLists.txt
tools/tiff2pcd.cpp
visualization/CMakeLists.txt
visualization/include/pcl/visualization/impl/point_cloud_color_handlers.hpp
visualization/include/pcl/visualization/pcl_visualizer.h
visualization/src/common/io.cpp
visualization/src/pcl_plotter.cpp

index 281540424c31a6b21c6de66ab4230c8aa6a5d16f..196c3a759f4ccb7a3fad53d95c6281e508c10040 100644 (file)
@@ -78,9 +78,9 @@ stages:
             Catalina 10.15:
               VMIMAGE: 'macOS-10.15'
               OSX_VERSION: '10.15'
-            Mojave 10.14:
-              VMIMAGE: 'macOS-10.14'
-              OSX_VERSION: '10.14'
+            Big Sur 11:
+              VMIMAGE: 'macOS-11'
+              OSX_VERSION: '11'
         timeoutInMinutes: 0
         variables:
           BUILD_DIR: '$(Agent.WorkFolder)/build'
index 00ca0a80288c0f645e0c9542d933b96b09daf48e..b1697c2a1a498fc5a12c2c3dd491999a12c96649 100644 (file)
@@ -112,7 +112,7 @@ jobs:
         PLATFORM: x86
         TAG: winx86
         GENERATOR: "'Visual Studio 16 2019' -A Win32"
-        VCPKGCOMMIT: 2bc10eae2fb0b8c7c098325c4e9d82aa5d0329d9
+        VCPKGCOMMIT: 5568f110b509a9fd90711978a7cb76bae75bb092
       Winx64:
         PLATFORM: x64
         TAG: winx64
index 3e0ebf2ffeccace311fa81471aa280e40fa6ef57..3578d7f1cad5b568801b9501101ded75c95aa1a3 100644 (file)
@@ -62,7 +62,7 @@ IncludeCategories:
   - Regex:           '^<(OpenGL|(GL(UT)?/))'
     Priority:        450
 # Matches all std includes. Match them before any unknown include, so we can order them behind.
-  - Regex:           '^<[a-z]+>$'
+  - Regex:           '^<[a-z_]+>$'
     Priority:        900
 # Any unknown include
   - Regex:           '.*'
index 670bdc47459a178066e6b3dbe7d1d48a1374ae47..6d189fcbb2134da9f379a654b3b3426b4389b156 100644 (file)
@@ -35,6 +35,6 @@ COPY package.xml ${workspace}/src/pcl/
 RUN cd ${workspace} \
  && . "/opt/ros/${flavor}/setup.sh" \
  && catkin config --install --link-devel \
- && catkin build -j2 libpcl-all-dev --cmake-args -DWITH_OPENGL:BOOL=OFF \
+ && catkin build --no-status --verbose --summary -j2 libpcl-all-dev --cmake-args -DWITH_OPENGL:BOOL=OFF \
  && rm -fr build/libpcl-all-dev \
- && catkin build --start-with pcl_msgs
+ && catkin build --no-status --verbose --summary --start-with pcl_msgs
index 6901105debfc81e540286980104e4a479c51c262..610587b02832b7b0a06144ebe2519c45aa7379e9 100644 (file)
@@ -34,8 +34,10 @@ RUN wget $Env:CHANNEL_BASE_URL/vs_buildtools.exe -OutFile 'C:\TEMP\vs_buildtools
     -Wait -PassThru;                                                `
     del c:\temp\vs_buildtools.exe;                                  
 
-RUN iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'));        `
-    choco install cmake git --installargs 'ADD_CMAKE_TO_PATH=System' -y --no-progress
+# VCPKG requires update if Cmake version is > 3.20.5 see: https://github.com/microsoft/vcpkg-tool/pull/107
+RUN iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'));   `
+    choco install cmake --version=3.20.5 --installargs 'ADD_CMAKE_TO_PATH=System' -y --no-progress; `
+    choco install git -y --no-progress
 
 RUN git clone https://github.com/microsoft/vcpkg.git; cd vcpkg; git checkout $Env:VCPKGCOMMIT;
 
index dba2619055ef664f6e80632be02e0ac39a298b6d..1860d850761c76a0a8e9a09f680ec4940ac0a9dc 100755 (executable)
@@ -8,7 +8,7 @@
 
 format() {
     # don't use a directory with whitespace
-    local whitelist="apps/3d_rec_framework apps/include apps/modeler apps/src benchmarks 2d geometry ml octree simulation stereo tracking registration gpu/containers"
+    local whitelist="apps/3d_rec_framework apps/include apps/modeler apps/src benchmarks 2d geometry ml octree simulation stereo tracking registration gpu/containers gpu/segmentation"
 
     local PCL_DIR="${2}"
     local formatter="${1}"
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644 (file)
index 0000000..30ac450
--- /dev/null
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Reolace with a single Ko Fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: PointCloudLibrary
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
index 5fd55b71c175520c4f908662a047283e239e1606..375412caf8d0488424300488edc6d2e5b128530b 100644 (file)
@@ -1,5 +1,106 @@
 # ChangeList
 
+## = 1.12.1 (2021.12.21) =
+
+This minor release brings in a lot of enhancements in CMake thanks to @larshg and @SunBlack.
+Enjoy a lot of bug-fixes and improvements in IO and Filters.
+
+### Notable changes
+
+**New features** *added to PCL*
+
+* **[io]** Add a grabber for SICK 2D LiDAR: TiM [[#4429](https://github.com/PointCloudLibrary/pcl/pull/4429)]
+
+**Deprecation** *of public APIs, scheduled to be removed after two minor releases*
+
+* **[cuda][filters]** Add deprecation for filter getters with bool reference [[#4861](https://github.com/PointCloudLibrary/pcl/pull/4861)]
+* **[filters]** Fix keep_organized behavior in CropHull filter [[#4855](https://github.com/PointCloudLibrary/pcl/pull/4855)]
+
+**Behavior changes** *in classes, apps, or tools*
+
+* **[registration]** Fix typo in the hessian representation of NDT [[#4889](https://github.com/PointCloudLibrary/pcl/pull/4889)]
+* **[cmake]** Update PCLConfig.cmake.in to 3.10 for default policy.  [[#4996](https://github.com/PointCloudLibrary/pcl/pull/4996)]
+
+**ABI changes** *that are still API compatible*
+
+* **[ml]** Wrap QMatrix in namespace pcl to resolve linker conflict with Qt6 [[#4858](https://github.com/PointCloudLibrary/pcl/pull/4858)]
+
+### Changes grouped by module
+
+#### CMake:
+
+* Add AVX for Linux & macos [[#4698](https://github.com/PointCloudLibrary/pcl/pull/4698)]
+* Update cmake to 3.10 and add CUDA language support [[#4619](https://github.com/PointCloudLibrary/pcl/pull/4619)]
+* Fix CUDA Compute Capability version detection [[#4900](https://github.com/PointCloudLibrary/pcl/pull/4900)]
+* Update pcl_find_boost to allow compilation with Boost 1.77 and 1.78 [[#4972](https://github.com/PointCloudLibrary/pcl/pull/4972)] [[#5067](https://github.com/PointCloudLibrary/pcl/pull/5067)]
+* Allow boost to be found by config files. [[#4952](https://github.com/PointCloudLibrary/pcl/pull/4952)]
+* **[behavior change]** Update PCLConfig.cmake.in to 3.10 for default policy.  [[#4996](https://github.com/PointCloudLibrary/pcl/pull/4996)]
+* Allow PCL to have non-static dependencies for static builds and vice-versa [[#4390](https://github.com/PointCloudLibrary/pcl/pull/4390)]
+* Enhance finding of qhull [[#4923](https://github.com/PointCloudLibrary/pcl/pull/4923)]
+
+#### libpcl_common:
+
+* Fix: max_id size should be equal to histogram.size() - 1 [[#4934](https://github.com/PointCloudLibrary/pcl/pull/4934)]
+* Remove casts, use more auto and uindex_t in conversions.h [[#4935](https://github.com/PointCloudLibrary/pcl/pull/4935)]
+* Fix inaccurate covariance matrix computation [[#4983](https://github.com/PointCloudLibrary/pcl/pull/4983)]
+
+#### libpcl_cuda:
+
+* **[deprecation]** Add deprecation for filter getters with bool reference [[#4861](https://github.com/PointCloudLibrary/pcl/pull/4861)]
+
+#### libpcl_features:
+
+* Add `isNormalFinite` check in `ShapeContext3DEstimation` [[#4883](https://github.com/PointCloudLibrary/pcl/pull/4883)]
+
+#### libpcl_filters:
+
+* Clear the output indices in function `CropHull::applyFilters` [[#4851](https://github.com/PointCloudLibrary/pcl/pull/4851)]
+* Fix unresolved linking to Convolution [[#4845](https://github.com/PointCloudLibrary/pcl/pull/4845)]
+* **[deprecation]** Add deprecation for filter getters with bool reference [[#4861](https://github.com/PointCloudLibrary/pcl/pull/4861)]
+* NormalSpaceSampling filter: add constructor to specify `extract_removed_indices`  [[#4846](https://github.com/PointCloudLibrary/pcl/pull/4846)]
+* **[deprecation]** Fix keep_organized behavior in CropHull filter [[#4855](https://github.com/PointCloudLibrary/pcl/pull/4855)]
+* Added reserve function before storing points in PointCloud in VoxelGr… [[#4938](https://github.com/PointCloudLibrary/pcl/pull/4938)]
+
+#### libpcl_io:
+
+* Higher flexibility regarding which PLY files can be read [[#4963](https://github.com/PointCloudLibrary/pcl/pull/4963)]
+* **[new feature]** Add a grabber for SICK 2D LiDAR: TiM [[#4429](https://github.com/PointCloudLibrary/pcl/pull/4429)]
+
+#### libpcl_keypoints:
+
+* Bugfix: Number of OpenMP threads was not validated, ... [[#4863](https://github.com/PointCloudLibrary/pcl/pull/4863)]
+
+#### libpcl_ml:
+
+* **[ABI break]** Wrap QMatrix in namespace pcl to resolve linker conflict with Qt6 [[#4858](https://github.com/PointCloudLibrary/pcl/pull/4858)]
+
+#### libpcl_registration:
+
+* **[behavior change]** Fix typo in the hessian representation of NDT [[#4889](https://github.com/PointCloudLibrary/pcl/pull/4889)]
+* Fix discretization bug in PPFRegistration [[#4975](https://github.com/PointCloudLibrary/pcl/pull/4975)]
+
+#### libpcl_sample_consensus:
+
+* Fix SampleConsensusModelCylinder.projectPoints and verify with test [[#4881](https://github.com/PointCloudLibrary/pcl/pull/4881)]
+
+#### libpcl_search:
+
+* Add missing include of hpp file in flann_search.h [[#4848](https://github.com/PointCloudLibrary/pcl/pull/4848)]
+
+#### libpcl_surface:
+
+* Improve logging in `multi_grid_octree_data.hpp` [[#4844](https://github.com/PointCloudLibrary/pcl/pull/4844)]
+* Fix duplicate definition error in mls [[#5049](https://github.com/PointCloudLibrary/pcl/pull/5049)]
+
+#### libpcl_visualization:
+
+* Use pixel ratio to scale mouse events on HiDpi monitors [[#4411](https://github.com/PointCloudLibrary/pcl/pull/4411)]
+* Remove declaration of updateCamera [[#4921](https://github.com/PointCloudLibrary/pcl/pull/4921)]
+
+#### PCL Docs:
+
+* Require sphinx>=3 to fix errors on readthedocs [[#5037](https://github.com/PointCloudLibrary/pcl/pull/5037)]
+
 ## = 1.12.0 (2021.07.07) =
 
 PCL 1.12.0 enables custom index size and type, from `int16_t` to `uint64_t`, allowing
index 63b38df682e00885c8c7b7c77658bc3e99cf625b..1e61bfdb59993f9e5d40712f297dbf4415111e53 100644 (file)
@@ -1,5 +1,5 @@
 ### ---[ PCL global CMake
-cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
 
 if(POLICY CMP0074)
   # 1. Remove with 3.12.4.
@@ -11,13 +11,10 @@ endif()
 set(CMAKE_CXX_STANDARD 14 CACHE STRING "The target C++ standard. PCL requires C++14 or higher.")
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
-if(CMAKE_VERSION VERSION_LESS 3.8)
-  # CMake did not have cxx_std_14 compile feature prior to 3.8
-  # We use cxx_attribute_deprecated as a proxy because this feature is a part of c++14 standard
-  set(PCL_CXX_COMPILE_FEATURES cxx_attribute_deprecated)
-else()
-  set(PCL_CXX_COMPILE_FEATURES cxx_std_14)
-endif()
+set(PCL_CXX_COMPILE_FEATURES cxx_std_14)
+
+set(CMAKE_CUDA_STANDARD 14 CACHE STRING "The target CUDA/C++ standard. PCL requires CUDA/C++ 14 or higher.")
+set(CMAKE_CUDA_STANDARD_REQUIRED ON)
 
 set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "possible configurations" FORCE)
 
@@ -26,7 +23,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "")
   set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "build type default to RelWithDebInfo, set to Release to improve performance" FORCE)
 endif()
 
-project(PCL VERSION 1.12.0)
+project(PCL VERSION 1.12.1)
 string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
 
 ### ---[ Find universal dependencies
@@ -90,7 +87,7 @@ if(PCL_ENABLE_SSE AND "${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}"
   PCL_CHECK_FOR_SSE()
 endif()
 
-# check for AVX flags for windows
+# check for AVX flags
 if(PCL_ENABLE_AVX AND "${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
   include("${PCL_SOURCE_DIR}/cmake/pcl_find_avx.cmake")
   PCL_CHECK_FOR_AVX()
@@ -104,7 +101,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
     else()
       string(APPEND CMAKE_CXX_FLAGS " -Wabi")
     endif()
-    string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra -Wno-unknown-pragmas -fno-strict-aliasing -Wno-format-extra-args -Wno-sign-compare -Wno-invalid-offsetof -Wno-conversion ${SSE_FLAGS}")
+    string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra -Wno-unknown-pragmas -fno-strict-aliasing -Wno-format-extra-args -Wno-sign-compare -Wno-invalid-offsetof -Wno-conversion ${SSE_FLAGS} ${AVX_FLAGS}")
   endif()
 
   if(PCL_WARNINGS_ARE_ERRORS)
@@ -131,10 +128,8 @@ endif()
 if(CMAKE_COMPILER_IS_MSVC)
   add_definitions("-DBOOST_ALL_NO_LIB -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DNOMINMAX -DPCL_ONLY_CORE_POINT_TYPES ${SSE_DEFINITIONS}")
   
-  add_compile_options(/bigobj)
-  
   if("${CMAKE_CXX_FLAGS}" STREQUAL "${CMAKE_CXX_FLAGS_DEFAULT}")
-    string(APPEND CMAKE_CXX_FLAGS " /fp:precise /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355 ${SSE_FLAGS} ${AVX_FLAGS}")
+    string(APPEND CMAKE_CXX_FLAGS " /fp:precise /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355 ${SSE_FLAGS} ${AVX_FLAGS} /bigobj")
 
     # Add extra code generation/link optimizations
     if(CMAKE_MSVC_CODE_LINK_OPTIMIZATION AND (NOT BUILD_CUDA) AND (NOT BUILD_GPU))
@@ -142,6 +137,8 @@ if(CMAKE_COMPILER_IS_MSVC)
       string(APPEND CMAKE_SHARED_LINKER_FLAGS_RELEASE " /LTCG /OPT:REF")
       string(APPEND CMAKE_EXE_LINKER_FLAGS_RELEASE " /LTCG")
     else()
+      set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=/bigobj")
+      
       message("Global optimizations /GL has been turned off, as it doesn't work with nvcc/thrust")
     endif()
     # /MANIFEST:NO") # please, don't disable manifest generation, otherwise crash at start for vs2008
@@ -154,7 +151,7 @@ if(CMAKE_COMPILER_IS_MSVC)
     ProcessorCount(CPUCores)
     set(MSVC_MP ${CPUCores} CACHE STRING "Number of simultaneously running compilers (0 = automatic detection by MSVC). See documentation of /MP flag.")
     if (CMAKE_VERSION VERSION_LESS 3.11.0)
-      # Usage of COMPILE_LANGUAGE generator expression for MSVC in add_compile_options requires at least CMake 3.11, see https://gitlab.kitware.com/cmake/cmake/issues/17435     
+      # Usage of COMPILE_LANGUAGE generator expression for MSVC in add_compile_options requires at least CMake 3.11, see https://gitlab.kitware.com/cmake/cmake/issues/17435
       if(MSVC_MP EQUAL 0)
         # MSVC_MP is 0 in case the information cannot be determined by ProcessorCount => fallback
         string(APPEND CMAKE_C_FLAGS " /MP")
@@ -194,7 +191,7 @@ if(CMAKE_COMPILER_IS_CLANG)
     set(CMAKE_C_FLAGS "-Qunused-arguments")
   endif()
   if("${CMAKE_CXX_FLAGS}" STREQUAL "")
-    set(CMAKE_CXX_FLAGS "-ftemplate-depth=1024 -Qunused-arguments -Wno-invalid-offsetof ${SSE_FLAGS_STR}") # Unfortunately older Clang versions do not have this: -Wno-unnamed-type-template-args
+    set(CMAKE_CXX_FLAGS "-ftemplate-depth=1024 -Qunused-arguments -Wno-invalid-offsetof ${SSE_FLAGS} ${AVX_FLAGS}") # Unfortunately older Clang versions do not have this: -Wno-unnamed-type-template-args
     if(APPLE AND WITH_CUDA AND CUDA_FOUND)
       string(APPEND CMAKE_CXX_FLAGS " -stdlib=libstdc++")
     endif()
@@ -286,6 +283,8 @@ if(OpenMP_FOUND)
       set(OPENMP_DLL VCOMP140)
     elseif(MSVC_VERSION MATCHES "^192[0-9]$")
       set(OPENMP_DLL VCOMP140)
+    elseif(MSVC_VERSION MATCHES "^193[0-9]$")
+      set(OPENMP_DLL VCOMP140)
     endif()
     if(OPENMP_DLL)
       string(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG " /DELAYLOAD:${OPENMP_DLL}D.dll")
@@ -314,7 +313,7 @@ endif()
 # libusb
 option(WITH_LIBUSB "Build USB RGBD-Camera drivers" TRUE)
 if(WITH_LIBUSB)
-  find_package(libusb)
+  include("${PCL_SOURCE_DIR}/cmake/pcl_find_libusb.cmake")
 endif()
 
 # Dependencies for different grabbers
@@ -352,12 +351,9 @@ endif()
 # Qhull
 option(WITH_QHULL "Include convex-hull operations" TRUE)
 if(WITH_QHULL)
-  if(NOT PCL_SHARED_LIBS OR ((WIN32 AND NOT MINGW) AND NOT PCL_BUILD_WITH_QHULL_DYNAMIC_LINKING_WIN32))
-    set(QHULL_USE_STATIC ON)
-  endif()
   find_package(Qhull)
-  if(QHULL_FOUND)
-    include_directories(SYSTEM ${QHULL_INCLUDE_DIRS})
+  if(NOT (${QHULL_LIBRARY_TYPE} MATCHES ${PCL_QHULL_REQUIRED_TYPE}) AND NOT (${PCL_QHULL_REQUIRED_TYPE} MATCHES "DONTCARE"))
+    message(FATAL_ERROR "Qhull was selected with ${PCL_QHULL_REQUIRED_TYPE} but found as ${QHULL_LIBRARY_TYPE}")
   endif()
 endif()
 
@@ -380,29 +376,11 @@ if(WITH_VTK)
   endif()
 endif()
 
-#VTK can depend on Qt and search for its required version, so search after so we can overwrite Qt5_FOUND if the version we require is not found.
-option(WITH_QT "Build QT Front-End" TRUE)
+# VTK can depend on Qt and search for its required version, so search after so we can overwrite Qt5_FOUND/Qt6_FOUND if the version we require is not found.
+set(WITH_QT "AUTO" CACHE STRING "Build QT Front-End (AUTO|YES|QT6|QT5|NO)")
+set_property(CACHE WITH_QT PROPERTY STRINGS "AUTO" "YES" "QT6" "QT5" "NO")
 if(WITH_QT)
-  find_package(Qt5 5.9.5 COMPONENTS Concurrent OpenGL Widgets)
-  set(QT_DISABLE_PRECATED_BEFORE_VAL "0x050900")
-  
-  if(Qt5_FOUND)
-    message(STATUS "Qt5 version: ${Qt5_VERSION}")
-    set(QT5_FOUND ${Qt5_FOUND})
-    #Set Cmake Auto features to skip .hh files
-    if(POLICY CMP0100)
-      cmake_policy(SET CMP0100 OLD)
-    endif()
-    
-    get_property(core_def TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_DEFINITIONS)
-    list(APPEND core_def "QT_DISABLE_DEPRECATED_BEFORE=${QT_DISABLE_PRECATED_BEFORE_VAL}")
-    set_property(TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_DEFINITIONS ${core_def})
-
-  else()
-    message(STATUS "Qt5 is not found.")
-  endif()
-else()
-  set(Qt5_FOUND FALSE)
+  include("${PCL_SOURCE_DIR}/cmake/pcl_find_qt.cmake")
 endif()
 
 #Find PCAP
index a1283a81011df8a2a508690291170331ee3697d7..27ef980720115095adcfd4571eb38bc66aa6483c 100644 (file)
@@ -13,7 +13,7 @@
 #------------------------------------------------------------------------------------
 
 # Set default policy behavior similar to minimum requirement version
-cmake_policy(VERSION 3.5)
+cmake_policy(VERSION 3.10)
 
 # explicitly set policies we already support in newer cmake versions
 if(POLICY CMP0074)
@@ -93,19 +93,13 @@ macro(find_boost)
   elseif(NOT BOOST_INCLUDEDIR)
     set(BOOST_INCLUDEDIR "@Boost_INCLUDE_DIR@")
   endif()
-  # use static Boost in Windows
-  if(WIN32)
-    set(Boost_USE_STATIC_LIBS @Boost_USE_STATIC_LIBS@)
-    set(Boost_USE_STATIC @Boost_USE_STATIC@)
-    set(Boost_USE_MULTITHREAD @Boost_USE_MULTITHREAD@)
-  endif()
+  
   set(Boost_ADDITIONAL_VERSIONS
     "@Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@.@Boost_SUBMINOR_VERSION@" "@Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@"
-    "1.76.0" "1.76" "1.75.0" "1.75" 
+    "1.78.0" "1.78" "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" 
     "1.74.0" "1.74" "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70"
     "1.69.0" "1.69" "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65")
-  # Disable the config mode of find_package(Boost)
-  set(Boost_NO_BOOST_CMAKE ON)
+  
   find_package(Boost 1.65.0 ${QUIET_} COMPONENTS @PCLCONFIG_AVAILABLE_BOOST_MODULES@)
 
   set(BOOST_FOUND ${Boost_FOUND})
@@ -135,7 +129,7 @@ macro(find_qhull)
     get_filename_component(QHULL_ROOT "@QHULL_INCLUDE_DIRS@" PATH)
   endif()
 
-  set(QHULL_USE_STATIC @QHULL_USE_STATIC@)
+  set(PCL_QHULL_REQUIRED_TYPE @PCL_QHULL_REQUIRED_TYPE@)
   find_package(Qhull)
 endmacro()
 
@@ -233,7 +227,7 @@ macro(find_flann)
     set(FLANN_ROOT "@FLANN_ROOT@")
   endif()
 
-  set(FLANN_USE_STATIC @FLANN_USE_STATIC@)
+  set(PCL_FLANN_REQUIRED_TYPE @PCL_FLANN_REQUIRED_TYPE@)
   find_package(FLANN)
 endmacro()
 
@@ -311,13 +305,20 @@ macro(find_external_library _component _lib _is_optional)
   string(REGEX REPLACE "[.-]" "_" LIB ${LIB})
   if(${LIB}_FOUND)
     list(APPEND PCL_${COMPONENT}_INCLUDE_DIRS ${${LIB}_INCLUDE_DIRS})
-    if(${LIB}_USE_FILE)
+    
+    if(${LIB} MATCHES "VTK")
+      if(${${LIB}_VERSION_MAJOR} GREATER_EQUAL 9)
+        set(ISVTK9ORGREATER TRUE)
+      endif()
+    endif()
+    
+    if(${LIB}_USE_FILE AND NOT ISVTK9ORGREATER )
       include(${${LIB}_USE_FILE})
     else()
       list(APPEND PCL_${COMPONENT}_LIBRARY_DIRS "${${LIB}_LIBRARY_DIRS}")
     endif()
     if(${LIB}_LIBRARIES)
-      list(APPEND PCL_${COMPONENT}_LIBRARIES "${${LIB}_LIBRARIES}")
+      list(APPEND PCL_${COMPONENT}_LINK_LIBRARIES "${${LIB}_LIBRARIES}")
     endif()
     if(${LIB}_DEFINITIONS AND NOT ${LIB} STREQUAL "VTK")
       list(APPEND PCL_${COMPONENT}_DEFINITIONS ${${LIB}_DEFINITIONS})
@@ -419,10 +420,15 @@ set(PCL_INCLUDE_DIRS "${PCL_CONF_INCLUDE_DIR}")
 set(PCL_DEBUG_SUFFIX "@CMAKE_DEBUG_POSTFIX@")
 set(PCL_RELEASE_SUFFIX "@CMAKE_RELEASE_POSTFIX@")
 
+set(PCL_SHARED_LIBS "@PCL_SHARED_LIBS@")
+
 #set SSE flags used compiling PCL
 list(APPEND PCL_DEFINITIONS @PCLCONFIG_SSE_DEFINITIONS@)
 list(APPEND PCL_COMPILE_OPTIONS @PCLCONFIG_SSE_COMPILE_OPTIONS@)
 
+#set AVX flags used compiling PCL
+list(APPEND PCL_COMPILE_OPTIONS @PCLCONFIG_AVX_COMPILE_OPTIONS@)
+
 set(pcl_all_components @PCLCONFIG_AVAILABLE_COMPONENTS@)
 list(LENGTH pcl_all_components PCL_NB_COMPONENTS)
 
@@ -662,10 +668,14 @@ endif()
 pcl_remove_duplicate_libraries(PCL_COMPONENTS PCL_LIBRARIES)
 
 # Add 3rd party libraries, as user code might include our .HPP implementations
-list(APPEND PCL_LIBRARIES ${BOOST_LIBRARIES} ${QHULL_LIBRARIES} ${OPENNI_LIBRARIES} ${OPENNI2_LIBRARIES} ${ENSENSO_LIBRARIES} ${davidSDK_LIBRARIES} ${DSSDK_LIBRARIES} ${RSSDK_LIBRARIES} ${RSSDK2_LIBRARIES} ${VTK_LIBRARIES})
+list(APPEND PCL_LIBRARIES ${BOOST_LIBRARIES} ${OPENNI_LIBRARIES} ${OPENNI2_LIBRARIES} ${ENSENSO_LIBRARIES} ${davidSDK_LIBRARIES} ${DSSDK_LIBRARIES} ${RSSDK_LIBRARIES} ${RSSDK2_LIBRARIES} ${VTK_LIBRARIES})
 if (TARGET FLANN::FLANN)
   list(APPEND PCL_LIBRARIES FLANN::FLANN)
 endif()
 
+if(TARGET QHULL::QHULL)
+    list(APPEND PCL_LIBRARIES QHULL::QHULL)
+endif()
+
 find_package_handle_standard_args(PCL DEFAULT_MSG PCL_LIBRARIES PCL_INCLUDE_DIRS)
 mark_as_advanced(PCL_LIBRARIES PCL_INCLUDE_DIRS PCL_LIBRARY_DIRS)
index b8c83e4df7f3c7df8e3a807844480f900323c83e..a895f50afa66c9d4d03059f75e2a5d78559b0132 100644 (file)
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 [![Release][release-image]][releases]
 [![License][license-image]][license]
 
-[release-image]: https://img.shields.io/badge/release-1.12.0-green.svg?style=flat
+[release-image]: https://img.shields.io/badge/release-1.12.1-green.svg?style=flat
 [releases]: https://github.com/PointCloudLibrary/pcl/releases
 
 [license-image]: https://img.shields.io/badge/license-BSD-green.svg?style=flat
@@ -26,7 +26,7 @@ Continuous integration
 [ci-ubuntu-20.10]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/9?branchName=master&stageName=Build%20GCC&jobName=Ubuntu&configuration=Ubuntu%2020.10%20GCC&label=Ubuntu%2020.10%20GCC
 [ci-windows-x86]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/9?branchName=master&stageName=Build%20MSVC&jobName=Windows%20Build&configuration=Windows%20Build%20x86&label=Windows%20VS2019%20x86
 [ci-windows-x64]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/9?branchName=master&stageName=Build%20MSVC&jobName=Windows%20Build&configuration=Windows%20Build%20x64&label=Windows%20VS2019%20x64
-[ci-macos-10.14]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/9?branchName=master&stageName=Build%20Clang&jobName=macOS&configuration=macOS%20Mojave%2010.14&label=macOS%20Mojave%2010.14
+[ci-macos-11]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/9?branchName=master&stageName=Build%20Clang&jobName=macOS&configuration=macOS%20Big%20Sur%2011&label=macOS%20Big%20Sur%2011
 [ci-macos-10.15]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/9?branchName=master&stageName=Build%20Clang&jobName=macOS&configuration=macOS%20Catalina%2010.15&label=macOS%20Catalina%2010.15
 [ci-docs]: https://dev.azure.com/PointCloudLibrary/pcl/_apis/build/status/Documentation?branchName=master
 [ci-latest-docs]: https://dev.azure.com/PointCloudLibrary/pcl/_build/latest?definitionId=14&branchName=master
@@ -35,7 +35,7 @@ Build Platform           | Status
 ------------------------ | ------------------------------------------------------------------------------------------------- |
 Ubuntu                   | [![Status][ci-ubuntu-18.04]][ci-latest-build] <br> [![Status][ci-ubuntu-20.04]][ci-latest-build]                              <br> [![Status][ci-ubuntu-20.10]][ci-latest-build]                                                |
 Windows                  | [![Status][ci-windows-x86]][ci-latest-build]  <br> [![Status][ci-windows-x64]][ci-latest-build]   |
-macOS                    | [![Status][ci-macos-10.14]][ci-latest-build]  <br> [![Status][ci-macos-10.15]][ci-latest-build]   |
+macOS                    | [![Status][ci-macos-10.15]][ci-latest-build]  <br> [![Status][ci-macos-11]][ci-latest-build]   |
 Documentation            | [![Status][ci-docs]][ci-latest-docs] |
 
 Community
index b891d95ec3bc0a10ee7d8a636bc17aba6e8f00cf..b3ea5716e9d3f6443c7218589a7a294be12eaa3e 100644 (file)
@@ -270,14 +270,12 @@ pcl::rec_3d_framework::GlobalNNCVFHRecognizer<Distance, PointInT, FeatureT>::rec
                            indices,
                            distances);
             // gather NN-search results
-            double score = 0;
             for (std::size_t i = 0; i < (std::size_t)NN_; ++i) {
-              score = distances[0][i];
               index_score is;
               is.idx_models_ =
                   single_categories_pointers_to_models_[it->second]->at(indices[0][i]);
               is.idx_input_ = static_cast<int>(idx);
-              is.score_ = score;
+              is.score_ = distances[0][i];
               indices_scores.push_back(is);
             }
           }
index b742768072d311cec225e93a71735d8c2024cdc2..53891821d115d8ed041fb5d6d768105034dabc12 100644 (file)
@@ -283,7 +283,7 @@ main(int argc, char** argv)
   int detect_clutter = 1;
   int hv_method = 0;
   int use_hv = 1;
-  float thres_hyp_ = 0.2f;
+  float thres_hyp = 0.2f;
   float desc_radius = 0.04f;
 
   pcl::console::parse_argument(argc, argv, "-models_dir", path);
@@ -300,7 +300,8 @@ main(int argc, char** argv)
   pcl::console::parse_argument(argc, argv, "-detect_clutter", detect_clutter);
   pcl::console::parse_argument(argc, argv, "-hv_method", hv_method);
   pcl::console::parse_argument(argc, argv, "-use_hv", use_hv);
-  pcl::console::parse_argument(argc, argv, "-thres_hyp", thres_hyp_);
+  pcl::console::parse_argument(argc, argv, "-thres_hyp", thres_hyp);
+  pcl::console::parse_argument(argc, argv, "-desc_radius", desc_radius);
 
   if (mians_scenes.empty()) {
     PCL_ERROR("Set the directory containing mians scenes using the -mians_scenes_dir "
@@ -493,7 +494,7 @@ main(int argc, char** argv)
 
     local.setUseCache(static_cast<bool>(use_cache));
     local.initialize(static_cast<bool>(force_retrain));
-    local.setThresholdAcceptHyp(thres_hyp_);
+    local.setThresholdAcceptHyp(thres_hyp);
 
     uniform_keypoint_extractor->setSamplingDensity(0.005f);
     local.setICPIterations(icp_iterations);
index 722c7728886a96c4c7ee11110a4120628106c333..d352ab49bebbb714a5378945c1739de5985e582a 100644 (file)
@@ -1,7 +1,7 @@
 set(SUBSYS_NAME apps)
 set(SUBSYS_DESC "Application examples/samples that show how PCL works")
 set(SUBSYS_DEPS common geometry io filters sample_consensus segmentation visualization kdtree features surface octree registration keypoints tracking search recognition ml stereo 2d)
-set(SUBSYS_OPT_DEPS openni vtk Qt5)
+set(SUBSYS_OPT_DEPS openni vtk ${QTX})
 
 set(DEFAULT FALSE)
 set(REASON "Disabled by default")
@@ -64,25 +64,21 @@ if(VTK_FOUND)
   if(QHULL_FOUND)
     PCL_ADD_EXECUTABLE(pcl_pcd_select_object_plane COMPONENT ${SUBSYS_NAME} SOURCES src/pcd_select_object_plane.cpp)
     target_link_libraries(pcl_pcd_select_object_plane pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_features pcl_surface)
-    #TODO: Update when CMAKE 3.10 is available
-    if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
-      target_link_libraries(pcl_pcd_select_object_plane VTK::FiltersGeometry)
-    endif()
   endif()
 
   PCL_ADD_EXECUTABLE(pcl_pcd_organized_edge_detection COMPONENT ${SUBSYS_NAME} SOURCES src/pcd_organized_edge_detection.cpp)
   target_link_libraries(pcl_pcd_organized_edge_detection pcl_common pcl_io pcl_features pcl_visualization)
 
   PCL_ADD_EXECUTABLE(pcl_face_trainer COMPONENT ${SUBSYS_NAME} SOURCES src/face_detection/face_trainer.cpp)
-  target_link_libraries(pcl_face_trainer pcl_features pcl_recognition pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_sample_consensus pcl_surface pcl_keypoints pcl_ml pcl_search pcl_kdtree ${VTK_LIBRARIES})
+  target_link_libraries(pcl_face_trainer pcl_features pcl_recognition pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_sample_consensus pcl_surface pcl_keypoints pcl_ml pcl_search pcl_kdtree)
 
   PCL_ADD_EXECUTABLE(pcl_fs_face_detector COMPONENT ${SUBSYS_NAME} SOURCES src/face_detection//filesystem_face_detection.cpp BUNDLE)
-  target_link_libraries(pcl_fs_face_detector pcl_features pcl_recognition pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_sample_consensus pcl_surface pcl_keypoints pcl_ml pcl_search pcl_kdtree ${VTK_LIBRARIES})
+  target_link_libraries(pcl_fs_face_detector pcl_features pcl_recognition pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_sample_consensus pcl_surface pcl_keypoints pcl_ml pcl_search pcl_kdtree)
 
   PCL_ADD_EXECUTABLE(pcl_stereo_ground_segmentation COMPONENT ${SUBSYS_NAME} SOURCES src/stereo_ground_segmentation.cpp)
   target_link_libraries(pcl_stereo_ground_segmentation pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_features pcl_stereo)
 
-  if(Qt5_FOUND AND HAVE_QVTK)
+  if(QT_FOUND AND HAVE_QVTK)
     # Manual registration demo
     PCL_ADD_EXECUTABLE(pcl_manual_registration
       COMPONENT
@@ -93,11 +89,7 @@ if(VTK_FOUND)
       src/manual_registration/manual_registration.ui
       BUNDLE)
       
-    target_link_libraries(pcl_manual_registration pcl_common pcl_io pcl_visualization pcl_segmentation pcl_features pcl_surface Qt5::Widgets)
-    #TODO: Update when CMAKE 3.10 is available
-    if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
-      target_link_libraries(pcl_manual_registration VTK::GUISupportQt)
-    endif()
+    target_link_libraries(pcl_manual_registration pcl_common pcl_io pcl_visualization pcl_segmentation pcl_features pcl_surface ${QTX}::Widgets)
 
     PCL_ADD_EXECUTABLE(pcl_pcd_video_player
       COMPONENT
@@ -108,11 +100,7 @@ if(VTK_FOUND)
       src/pcd_video_player/pcd_video_player.ui
       BUNDLE)
     
-    target_link_libraries(pcl_pcd_video_player pcl_common pcl_io pcl_visualization pcl_segmentation pcl_features pcl_surface Qt5::Widgets)
-    #TODO: Update when CMAKE 3.10 is available
-    if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
-      target_link_libraries(pcl_pcd_video_player VTK::GUISupportQt)
-    endif()
+    target_link_libraries(pcl_pcd_video_player pcl_common pcl_io pcl_visualization pcl_segmentation pcl_features pcl_surface ${QTX}::Widgets)
   endif()
 
   if(WITH_OPENNI)
@@ -164,9 +152,9 @@ if(VTK_FOUND)
     target_link_libraries(pcl_openni_organized_edge_detection pcl_common pcl_io pcl_features pcl_visualization)
 
     PCL_ADD_EXECUTABLE(pcl_openni_face_detector COMPONENT ${SUBSYS_NAME} SOURCES src/face_detection//openni_face_detection.cpp src/face_detection//openni_frame_source.cpp BUNDLE)
-    target_link_libraries(pcl_openni_face_detector pcl_features pcl_recognition pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_sample_consensus pcl_surface pcl_keypoints pcl_ml pcl_search pcl_kdtree ${VTK_LIBRARIES})
+    target_link_libraries(pcl_openni_face_detector pcl_features pcl_recognition pcl_common pcl_io pcl_filters pcl_visualization pcl_segmentation pcl_sample_consensus pcl_surface pcl_keypoints pcl_ml pcl_search pcl_kdtree)
 
-    if(Qt5_FOUND AND HAVE_QVTK)
+    if(QT_FOUND AND HAVE_QVTK)
       # OpenNI Passthrough application demo
       PCL_ADD_EXECUTABLE(pcl_openni_passthrough
         COMPONENT
@@ -176,11 +164,7 @@ if(VTK_FOUND)
           src/openni_passthrough.cpp
           src/openni_passthrough.ui)
           
-      target_link_libraries(pcl_openni_passthrough pcl_common pcl_io pcl_filters pcl_visualization Qt5::Widgets)
-      #TODO: Update when CMAKE 3.10 is available
-      if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
-        target_link_libraries(pcl_openni_passthrough VTK::GUISupportQt)
-      endif()
+      target_link_libraries(pcl_openni_passthrough pcl_common pcl_io pcl_filters pcl_visualization ${QTX}::Widgets)
 
       list(APPEND CMAKE_AUTOUIC_SEARCH_PATHS "src")
 
@@ -194,11 +178,8 @@ if(VTK_FOUND)
           src/organized_segmentation_demo.cpp
           src/organized_segmentation_demo.ui
         BUNDLE)
-      target_link_libraries(pcl_organized_segmentation_demo pcl_common pcl_io pcl_visualization pcl_segmentation pcl_features pcl_surface Qt5::Widgets)
-      #TODO: Update when CMAKE 3.10 is available
-      if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
-        target_link_libraries(pcl_organized_segmentation_demo VTK::GUISupportQt)
-      endif()      
+      target_link_libraries(pcl_organized_segmentation_demo pcl_common pcl_io pcl_visualization pcl_segmentation pcl_features pcl_surface ${QTX}::Widgets)
+
     endif()
 
     if(QHULL_FOUND)
index 4b006ee254a4adf564dfe8afd41c3c985083db7c..c9223a9efbba84eca3eacde30344ae32782504af 100644 (file)
@@ -6,7 +6,7 @@
 set(SUBSUBSYS_NAME cloud_composer)
 set(SUBSUBSYS_DESC "Cloud Composer - Application for Manipulating Point Clouds")
 set(SUBSUBSYS_DEPS common io visualization filters apps)
-set(SUBSUBSYS_EXT_DEPS vtk Qt5)
+set(SUBSUBSYS_EXT_DEPS vtk ${QTX})
 
 # QVTK?
 if(NOT HAVE_QVTK)
@@ -75,12 +75,8 @@ set(PCL_LIB_TYPE STATIC)
 
 PCL_ADD_LIBRARY(pcl_cc_tool_interface COMPONENT ${SUBSUBSYS_NAME} SOURCES ${INTERFACE_HEADERS} ${INTERFACE_SOURCES})
 
-set(vtk_libs ${VTK_LIBRARIES})
-#TODO: Update when CMAKE 3.10 is available
-if (NOT (${VTK_VERSION} VERSION_LESS 9.0))
-  set(vtk_libs VTK::GUISupportQt)
-endif()
-target_link_libraries(pcl_cc_tool_interface pcl_common pcl_filters pcl_search pcl_visualization Qt5::Widgets ${vtk_libs})
+
+target_link_libraries(pcl_cc_tool_interface pcl_common pcl_filters pcl_search pcl_visualization ${QTX}::Widgets)
 
 set(PCL_LIB_TYPE ${PCL_LIB_TYPE_ORIGIN})
 
@@ -133,7 +129,7 @@ list(APPEND CMAKE_AUTOUIC_SEARCH_PATHS "src")
 
 set(EXE_NAME "pcl_${SUBSUBSYS_NAME}")
 PCL_ADD_EXECUTABLE(${EXE_NAME} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${uis} ${incs} ${srcs} ${resources} ${impl_incs})
-target_link_libraries("${EXE_NAME}" pcl_cc_tool_interface pcl_common pcl_io pcl_visualization pcl_filters Qt5::Widgets)
+target_link_libraries("${EXE_NAME}" pcl_cc_tool_interface pcl_common pcl_io pcl_visualization pcl_filters ${QTX}::Widgets)
 
 
 
index 5261da7650c736f5efeccea3836ea6600a6c6429..bf6d80b64da562a35556fae89fe862820654002f 100644 (file)
@@ -17,7 +17,7 @@ function(define_composer_tool TOOL_NAME TOOL_SOURCES TOOL_HEADERS DEPS)
   add_definitions(-DQT_PLUGIN)
   add_definitions(-DQT_SHARED)
 
-  target_link_libraries(${TOOL_TARGET} pcl_cc_tool_interface pcl_common pcl_io ${DEPS} Qt5::Widgets)
+  target_link_libraries(${TOOL_TARGET} pcl_cc_tool_interface pcl_common pcl_io ${DEPS} ${QTX}::Widgets)
 
   if(APPLE)
     set_target_properties(${TOOL_TARGET} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
index 35e9884f9a89c1ca53a855be4db94cad1d336f94..2096cbedcf357cbeeca687b8d41549fbd3b8b2cb 100644 (file)
@@ -2,7 +2,7 @@ set(SUBSUBSYS_NAME in_hand_scanner)
 set(SUBSUBSYS_DESC "In-hand scanner for small objects")
 set(SUBSUBSYS_DEPS     common     features     io     kdtree apps)
 set(SUBSUBSYS_LIBS pcl_common pcl_features pcl_io pcl_kdtree)
-set(SUBSUBSYS_EXT_DEPS Qt5 OpenGL OpenGL_GLU openni)
+set(SUBSUBSYS_EXT_DEPS ${QTX} OpenGL OpenGL_GLU openni)
 
 ################################################################################
 
@@ -91,7 +91,7 @@ PCL_ADD_EXECUTABLE(
     ${IMPL_INCS}
     ${UI}
   BUNDLE)
-target_link_libraries("${EXE_NAME}" ${SUBSUBSYS_LIBS} ${OPENGL_LIBRARIES} Qt5::Concurrent Qt5::Widgets Qt5::OpenGL)
+target_link_libraries("${EXE_NAME}" ${SUBSUBSYS_LIBS} ${OPENGL_LIBRARIES} ${QTX}::Concurrent ${QTX}::Widgets ${QTX}::OpenGL)
 
 pcl_add_includes("${SUBSUBSYS_NAME}" "${SUBSUBSYS_NAME}" ${INCS})
 pcl_add_includes("${SUBSUBSYS_NAME}" "${SUBSUBSYS_NAME}/impl" ${IMPL_INCS})
@@ -107,7 +107,7 @@ PCL_ADD_EXECUTABLE(
     ${OI_INCS}
   BUNDLE)
 
-target_link_libraries(pcl_offline_integration ${SUBSUBSYS_LIBS} ${OPENGL_LIBRARIES} Qt5::Concurrent Qt5::Widgets Qt5::OpenGL)
+target_link_libraries(pcl_offline_integration ${SUBSUBSYS_LIBS} ${OPENGL_LIBRARIES} ${QTX}::Concurrent ${QTX}::Widgets ${QTX}::OpenGL)
 
 # Add to the compound apps target
 list(APPEND PCL_APPS_ALL_TARGETS ${PCL_IN_HAND_SCANNER_ALL_TARGETS})
index 4a47568ea70bc1dd844185d0ef84f91b6e0364a9..549f893bcff06abc461b3226342fc9aecb626021 100644 (file)
@@ -310,7 +310,7 @@ pcl::apps::DominantPlaneSegmentation<PointType>::compute_fast(
 
   std::map<float, float> connected_labels;
   float c_intensity = 0.1f;
-  float intensity_incr = 0.1f;
+  const float intensity_incr = 0.1f;
 
   {
 
index c6b6c9789f93ec2cdc440d3f08fc7605db8d65a8..aa61605218babcef86496ac1d480bd370519ce71 100644 (file)
@@ -1,7 +1,7 @@
 set(SUBSUBSYS_NAME modeler)
 set(SUBSUBSYS_DESC "PCLModeler: PCL based reconstruction platform")
 set(SUBSUBSYS_DEPS common geometry io filters sample_consensus segmentation visualization kdtree features surface octree registration keypoints tracking search apps)
-set(SUBSUBSYS_EXT_DEPS vtk Qt5)
+set(SUBSUBSYS_EXT_DEPS vtk ${QTX})
 set(REASON "")
 
 # QVTK?
@@ -118,11 +118,7 @@ PCL_ADD_EXECUTABLE(
     ${incs}
     ${impl_incs})
 
-target_link_libraries("${EXE_NAME}" pcl_common pcl_io pcl_kdtree pcl_filters pcl_visualization pcl_segmentation pcl_surface pcl_features pcl_sample_consensus pcl_search Qt5::Widgets)
-#TODO: Update when CMAKE 3.10 is available
-if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
-  target_link_libraries("${EXE_NAME}" VTK::GUISupportQt)
-endif()
+target_link_libraries("${EXE_NAME}" pcl_common pcl_io pcl_kdtree pcl_filters pcl_visualization pcl_segmentation pcl_surface pcl_features pcl_sample_consensus pcl_search ${QTX}::Widgets)
 
 # Install include files
 PCL_ADD_INCLUDES("${SUBSUBSYS_NAME}" "${SUBSUBSYS_NAME}" ${incs})
index b09bd01f8a26a64cc88496813e0007acf6d242bf..e5321278920fe30db0b4d2c468837d8344e148b3 100644 (file)
@@ -1,7 +1,7 @@
 set(SUBSUBSYS_NAME point_cloud_editor)
 set(SUBSUBSYS_DESC "Point Cloud Editor - Simple editor for 3D point clouds")
 set(SUBSUBSYS_DEPS common filters io apps)
-set(SUBSUBSYS_EXT_DEPS vtk Qt5 OpenGL)
+set(SUBSUBSYS_EXT_DEPS vtk ${QTX} OpenGL)
 
 # Default to not building for now
 if(${DEFAULT} STREQUAL "TRUE")
@@ -86,7 +86,7 @@ PCL_ADD_EXECUTABLE(
     ${RSRC}
     ${INCS})
 
-target_link_libraries("${EXE_NAME}" Qt5::Widgets Qt5::OpenGL ${OPENGL_LIBRARIES} ${BOOST_LIBRARIES} pcl_common pcl_io pcl_filters)
+target_link_libraries("${EXE_NAME}" ${QTX}::Widgets ${QTX}::OpenGL ${OPENGL_LIBRARIES} ${BOOST_LIBRARIES} pcl_common pcl_io pcl_filters)
 
 PCL_ADD_INCLUDES("${SUBSUBSYS_NAME}" "${SUBSYS_NAME}/${SUBSUBSYS_NAME}" ${INCS})
 PCL_MAKE_PKGCONFIG(${EXE_NAME} COMPONENT ${SUBSUBSYS_NAME} DESC ${SUBSUBSYS_DESC})
index c3fcfa61766f52dd048ef3096e830b07b2285c6f..b9150f7bcfed46833ff6203d620c2777cfd85a50 100644 (file)
@@ -40,6 +40,8 @@
 #include <QFileDialog>
 #include <QMessageBox>
 #include <QMouseEvent>
+#include <QApplication>
+#include <QDesktopWidget>
 #include <qgl.h>
 
 #include <pcl/pcl_config.h>
@@ -101,7 +103,7 @@ void
 CloudEditorWidget::load ()
 {
   QString file_path = QFileDialog::getOpenFileName(this, tr("Open File"));
-    
+
   if (file_path.isEmpty())
     return;
 
@@ -129,7 +131,7 @@ CloudEditorWidget::save ()
   }
 
   QString file_path = QFileDialog::getSaveFileName(this,tr("Save point cloud"));
-  
+
   std::string file_path_std = file_path.toStdString();
   if ( (file_path_std.empty()) || (!cloud_ptr_) )
     return;
@@ -487,9 +489,10 @@ CloudEditorWidget::resizeGL (int width, int height)
 void
 CloudEditorWidget::mousePressEvent (QMouseEvent *event)
 {
+  auto ratio = this->devicePixelRatio();
   if (!tool_ptr_)
     return;
-  tool_ptr_ -> start(event -> x(), event -> y(),
+  tool_ptr_ -> start(event -> x()*ratio, event -> y()*ratio,
                      event -> modifiers(), event -> buttons());
   update();
 }
@@ -497,9 +500,10 @@ CloudEditorWidget::mousePressEvent (QMouseEvent *event)
 void
 CloudEditorWidget::mouseMoveEvent (QMouseEvent *event)
 {
+  auto ratio = this->devicePixelRatio();
   if (!tool_ptr_)
     return;
-  tool_ptr_ -> update(event -> x(), event -> y(),
+  tool_ptr_ -> update(event -> x()*ratio, event -> y()*ratio,
                       event -> modifiers(), event -> buttons());
   update();
 }
@@ -507,9 +511,10 @@ CloudEditorWidget::mouseMoveEvent (QMouseEvent *event)
 void
 CloudEditorWidget::mouseReleaseEvent (QMouseEvent *event)
 {
+  auto ratio = this->devicePixelRatio();
   if (!tool_ptr_)
     return;
-  tool_ptr_ -> end(event -> x(), event -> y(),
+  tool_ptr_ -> end(event -> x()*ratio, event -> y()*ratio,
                    event -> modifiers(), event -> button());
   update();
 }
@@ -528,7 +533,7 @@ CloudEditorWidget::keyPressEvent (QKeyEvent *event)
 
 void
 CloudEditorWidget::loadFilePCD(const std::string &filename)
-{   
+{
   PclCloudPtr pcl_cloud_ptr;
   Cloud3D tmp;
   if (pcl::io::loadPCDFile<Point3D>(filename, tmp) == -1)
@@ -597,7 +602,7 @@ CloudEditorWidget::swapRBValues ()
 
 void
 CloudEditorWidget::initKeyMap ()
-{   
+{
   key_map_[Qt::Key_1] = &CloudEditorWidget::colorByPure;
   key_map_[Qt::Key_2] = &CloudEditorWidget::colorByX;
   key_map_[Qt::Key_3] = &CloudEditorWidget::colorByY;
diff --git a/cmake/CudaComputeTargetFlags.cmake b/cmake/CudaComputeTargetFlags.cmake
deleted file mode 100644 (file)
index 928c664..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-#  Compute target flags macros by Anatoly Baksheev
-#
-#  Usage in CmakeLists.txt:
-#    include(CudaComputeTargetFlags.cmake)
-#    APPEND_TARGET_ARCH_FLAGS()
-
-#compute flags macros
-macro(CUDA_COMPUTE_TARGET_FLAGS arch_bin arch_ptx cuda_nvcc_target_flags)
-  string(REGEX REPLACE "\\." "" ARCH_BIN_WITHOUT_DOTS "${${arch_bin}}")
-  string(REGEX REPLACE "\\." "" ARCH_PTX_WITHOUT_DOTS "${${arch_ptx}}")
-
-  set(cuda_computer_target_flags_temp "")
-
-  # Tell NVCC to add binaries for the specified GPUs
-  string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_WITHOUT_DOTS}")
-  foreach(ARCH IN LISTS ARCH_LIST)
-    if(ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)")
-      # User explicitly specified PTX for the concrete BIN
-      set(cuda_computer_target_flags_temp ${cuda_computer_target_flags_temp} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
-    else()
-      # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
-      set(cuda_computer_target_flags_temp ${cuda_computer_target_flags_temp} -gencode arch=compute_${ARCH},code=sm_${ARCH})
-    endif()
-  endforeach()
-
-  # Tell NVCC to add PTX intermediate code for the specified architectures
-  string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_WITHOUT_DOTS}")
-  foreach(ARCH IN LISTS ARCH_LIST)
-    set(cuda_computer_target_flags_temp ${cuda_computer_target_flags_temp} -gencode arch=compute_${ARCH},code=compute_${ARCH})
-  endforeach()
-
-  set(${cuda_nvcc_target_flags} ${cuda_computer_target_flags_temp})
-endmacro()
-
-macro(APPEND_TARGET_ARCH_FLAGS)
-  set(cuda_nvcc_target_flags "")
-  CUDA_COMPUTE_TARGET_FLAGS(CUDA_ARCH_BIN CUDA_ARCH_PTX cuda_nvcc_target_flags)
-  if(cuda_nvcc_target_flags)
-    message(STATUS "CUDA NVCC target flags: ${cuda_nvcc_target_flags}")
-    list(APPEND CUDA_NVCC_FLAGS ${cuda_nvcc_target_flags})
-  endif()
-endmacro()
index a87f9c6177928d1b4beaafba257b11ec526cfeea..9b46b2256f7962f7772a9291007a0dcfc3dc3b9c 100644 (file)
@@ -51,7 +51,13 @@ if(flann_FOUND)
   add_library(FLANN::FLANN INTERFACE IMPORTED)
 
   if(TARGET flann::flann_cpp_s AND TARGET flann::flann_cpp)
-    if(PCL_FLANN_REQUIRED_TYPE MATCHES "DONTCARE")
+    if(PCL_FLANN_REQUIRED_TYPE MATCHES "SHARED")
+      set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp)
+      set(FLANN_LIBRARY_TYPE SHARED)
+    elseif(PCL_FLANN_REQUIRED_TYPE MATCHES "STATIC")
+      set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp_s)
+      set(FLANN_LIBRARY_TYPE STATIC)
+    else()
       if(PCL_SHARED_LIBS)
         set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp)
         set(FLANN_LIBRARY_TYPE SHARED)
@@ -59,12 +65,6 @@ if(flann_FOUND)
         set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp_s)
         set(FLANN_LIBRARY_TYPE STATIC)
       endif()
-    elseif(PCL_FLANN_REQUIRED_TYPE MATCHES "SHARED")
-      set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp)
-      set(FLANN_LIBRARY_TYPE SHARED)
-    else()
-      set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp_s)
-      set(FLANN_LIBRARY_TYPE STATIC)
     endif()
   elseif(TARGET flann::flann_cpp_s)
     set_property(TARGET FLANN::FLANN APPEND PROPERTY INTERFACE_LINK_LIBRARIES flann::flann_cpp_s)
@@ -161,7 +161,13 @@ find_library(FLANN_LIBRARY_DEBUG_STATIC
 )
 
 if(FLANN_LIBRARY_SHARED AND FLANN_LIBRARY_STATIC)
-  if(PCL_FLANN_REQUIRED_TYPE MATCHES "DONTCARE")
+  if(PCL_FLANN_REQUIRED_TYPE MATCHES "SHARED")
+    set(FLANN_LIBRARY_TYPE SHARED)
+    set(FLANN_LIBRARY ${FLANN_LIBRARY_SHARED})
+  elseif(PCL_FLANN_REQUIRED_TYPE MATCHES "STATIC")
+    set(FLANN_LIBRARY_TYPE STATIC)
+    set(FLANN_LIBRARY ${FLANN_LIBRARY_STATIC})
+  else()
     if(PCL_SHARED_LIBS)
       set(FLANN_LIBRARY_TYPE SHARED)
       set(FLANN_LIBRARY ${FLANN_LIBRARY_SHARED})
@@ -169,12 +175,6 @@ if(FLANN_LIBRARY_SHARED AND FLANN_LIBRARY_STATIC)
       set(FLANN_LIBRARY_TYPE STATIC)
       set(FLANN_LIBRARY ${FLANN_LIBRARY_STATIC})
     endif()
-  elseif(PCL_FLANN_REQUIRED_TYPE MATCHES "SHARED")
-    set(FLANN_LIBRARY_TYPE SHARED)
-    set(FLANN_LIBRARY ${FLANN_LIBRARY_SHARED})
-  else()
-    set(FLANN_LIBRARY_TYPE STATIC)
-    set(FLANN_LIBRARY ${FLANN_LIBRARY_STATIC})
   endif()
 elseif(FLANN_LIBRARY_STATIC)
   set(FLANN_LIBRARY_TYPE STATIC)
@@ -218,4 +218,5 @@ if(FLANN_FOUND)
     endif()
   endforeach()
   get_filename_component(FLANN_ROOT "${FLANN_INCLUDE_DIR}" PATH)
+  message(STATUS "FLANN found (include: ${FLANN_INCLUDE_DIR}, lib: ${FLANN_LIBRARY})")
 endif()
diff --git a/cmake/Modules/FindOpenMP.cmake b/cmake/Modules/FindOpenMP.cmake
new file mode 100644 (file)
index 0000000..cd17a17
--- /dev/null
@@ -0,0 +1,617 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+
+FindOpenMP is added to PCL local Cmake modules due to bug in earlier version.
+TODO: Can be removed when Cmake 3.11 is required.
+See https://gitlab.kitware.com/cmake/cmake/-/issues/20364
+
+FindOpenMP
+----------
+
+Finds Open Multi-Processing (OpenMP) support.
+
+This module can be used to detect OpenMP support in a compiler.  If
+the compiler supports OpenMP, the flags required to compile with
+OpenMP support are returned in variables for the different languages.
+The variables may be empty if the compiler does not need a special
+flag to support OpenMP.
+
+Variables
+^^^^^^^^^
+
+The module exposes the components ``C``, ``CXX``, and ``Fortran``.
+Each of these controls the various languages to search OpenMP support for.
+
+Depending on the enabled components the following variables will be set:
+
+``OpenMP_FOUND``
+  Variable indicating that OpenMP flags for all requested languages have been found.
+  If no components are specified, this is true if OpenMP settings for all enabled languages
+  were detected.
+``OpenMP_VERSION``
+  Minimal version of the OpenMP standard detected among the requested languages,
+  or all enabled languages if no components were specified.
+
+This module will set the following variables per language in your
+project, where ``<lang>`` is one of C, CXX, or Fortran:
+
+``OpenMP_<lang>_FOUND``
+  Variable indicating if OpenMP support for ``<lang>`` was detected.
+``OpenMP_<lang>_FLAGS``
+  OpenMP compiler flags for ``<lang>``, separated by spaces.
+``OpenMP_<lang>_INCLUDE_DIRS``
+  Directories that must be added to the header search path for ``<lang>``
+  when using OpenMP.
+
+For linking with OpenMP code written in ``<lang>``, the following
+variables are provided:
+
+``OpenMP_<lang>_LIB_NAMES``
+  :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
+``OpenMP_<libname>_LIBRARY``
+  Location of the individual libraries needed for OpenMP support in ``<lang>``.
+``OpenMP_<lang>_LIBRARIES``
+  A list of libraries needed to link with OpenMP code written in ``<lang>``.
+
+Additionally, the module provides :prop_tgt:`IMPORTED` targets:
+
+``OpenMP::OpenMP_<lang>``
+  Target for using OpenMP from ``<lang>``.
+
+Specifically for Fortran, the module sets the following variables:
+
+``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
+  Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
+``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
+  Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
+
+The module will also try to provide the OpenMP version variables:
+
+``OpenMP_<lang>_SPEC_DATE``
+  Date of the OpenMP specification implemented by the ``<lang>`` compiler.
+``OpenMP_<lang>_VERSION_MAJOR``
+  Major version of OpenMP implemented by the ``<lang>`` compiler.
+``OpenMP_<lang>_VERSION_MINOR``
+  Minor version of OpenMP implemented by the ``<lang>`` compiler.
+``OpenMP_<lang>_VERSION``
+  OpenMP version implemented by the ``<lang>`` compiler.
+
+The specification date is formatted as given in the OpenMP standard:
+``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
+the OpenMP specification implemented by the ``<lang>`` compiler.
+
+For some compilers, it may be necessary to add a header search path to find
+the relevant OpenMP headers.  This location may be language-specific.  Where
+this is needed, the module may attempt to find the location, but it can be
+provided directly by setting the ``OpenMP_<lang>_INCLUDE_DIR`` cache variable.
+Note that this variable is an _input_ control to the module.  Project code
+should use the ``OpenMP_<lang>_INCLUDE_DIRS`` _output_ variable if it needs
+to know what include directories are needed.
+#]=======================================================================]
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if IN_LIST
+
+function(_OPENMP_FLAG_CANDIDATES LANG)
+  if(NOT OpenMP_${LANG}_FLAG)
+    unset(OpenMP_FLAG_CANDIDATES)
+
+    set(OMP_FLAG_GNU "-fopenmp")
+    set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp")
+    set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
+    set(OMP_FLAG_HP "+Oopenmp")
+    if(WIN32)
+      set(OMP_FLAG_Intel "-Qopenmp")
+    elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
+           "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
+      set(OMP_FLAG_Intel "-openmp")
+    else()
+      set(OMP_FLAG_Intel "-qopenmp")
+    endif()
+    set(OMP_FLAG_MSVC "-openmp")
+    set(OMP_FLAG_PathScale "-openmp")
+    set(OMP_FLAG_NAG "-openmp")
+    set(OMP_FLAG_Absoft "-openmp")
+    set(OMP_FLAG_PGI "-mp")
+    set(OMP_FLAG_Flang "-fopenmp")
+    set(OMP_FLAG_SunPro "-xopenmp")
+    set(OMP_FLAG_XL "-qsmp=omp")
+    # Cray compiler activate OpenMP with -h omp, which is enabled by default.
+    set(OMP_FLAG_Cray " " "-h omp")
+
+    # If we know the correct flags, use those
+    if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
+      set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
+    # Fall back to reasonable default tries otherwise
+    else()
+      set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
+    endif()
+    set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
+  else()
+    set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+# sample openmp source code to test
+set(OpenMP_C_CXX_TEST_SOURCE
+"
+#include <omp.h>
+int main(void) {
+#ifdef _OPENMP
+  omp_get_max_threads();
+  return 0;
+#elif defined(__HIP_DEVICE_COMPILE__)
+  return 0;
+#else
+  breaks_on_purpose
+#endif
+}
+")
+
+# in Fortran, an implementation may provide an omp_lib.h header
+# or omp_lib module, or both (OpenMP standard, section 3.1)
+# Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
+# Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
+# while not actually enabling OpenMP, building code sequentially
+set(OpenMP_Fortran_TEST_SOURCE
+  "
+      program test
+      @OpenMP_Fortran_INCLUDE_LINE@
+  !$  integer :: n
+      n = omp_get_num_threads()
+      end program test
+  "
+)
+
+function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
+  set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
+  if("${LANG}" STREQUAL "C")
+    set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
+    file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
+  elseif("${LANG}" STREQUAL "CXX")
+    set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
+    file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
+  elseif("${LANG}" STREQUAL "Fortran")
+    set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
+    file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
+    configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
+  endif()
+  set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
+endfunction()
+
+include(CMakeParseImplicitLinkInfo)
+
+function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
+  _OPENMP_FLAG_CANDIDATES("${LANG}")
+  _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
+
+  unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
+  separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
+  foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
+    if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
+      list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
+    endif()
+  endforeach()
+
+  foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
+    set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
+    if(OpenMP_VERBOSE_COMPILE_OPTIONS)
+      string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
+    endif()
+    string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
+    try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
+      CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
+      LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
+      OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
+    )
+
+    if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
+      set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
+
+      if(CMAKE_${LANG}_VERBOSE_FLAG)
+        unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
+        unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
+        unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
+        unset(OpenMP_${LANG}_LOG_VAR)
+
+        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
+
+        cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
+          OpenMP_${LANG}_IMPLICIT_LIBRARIES
+          OpenMP_${LANG}_IMPLICIT_LINK_DIRS
+          OpenMP_${LANG}_IMPLICIT_FWK_DIRS
+          OpenMP_${LANG}_LOG_VAR
+          "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
+        )
+
+        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
+
+        unset(_OPENMP_LIB_NAMES)
+        foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
+          get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
+          get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
+          get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
+          string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
+          string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
+          if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
+            OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
+            OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
+            if(_OPENMP_IMPLICIT_LIB_DIR)
+              set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
+                "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
+            else()
+              find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
+                NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
+                DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
+                HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
+                CMAKE_FIND_ROOT_PATH_BOTH
+                NO_DEFAULT_PATH
+              )
+            endif()
+            mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
+            list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
+          endif()
+        endforeach()
+        set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
+      else()
+        # We do not know how to extract implicit OpenMP libraries for this compiler.
+        # Assume that it handles them automatically, e.g. the Intel Compiler on
+        # Windows should put the dependency in its object files.
+        set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
+      endif()
+      break()
+    elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
+      AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0")
+
+      # Check for separate OpenMP library on AppleClang 7+
+      find_library(OpenMP_libomp_LIBRARY
+        NAMES omp gomp iomp5
+        HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
+      )
+      mark_as_advanced(OpenMP_libomp_LIBRARY)
+
+      if(OpenMP_libomp_LIBRARY)
+        # Try without specifying include directory first. We only want to
+        # explicitly add a search path if the header can't be found on the
+        # default header search path already.
+        try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
+          CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
+          LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+          OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
+        )
+        if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
+          find_path(OpenMP_${LANG}_INCLUDE_DIR omp.h)
+          mark_as_advanced(OpenMP_${LANG}_INCLUDE_DIR)
+          set(OpenMP_${LANG}_INCLUDE_DIR "${OpenMP_${LANG}_INCLUDE_DIR}" PARENT_SCOPE)
+          if(OpenMP_${LANG}_INCLUDE_DIR)
+            try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
+              CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
+                          "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
+              LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+              OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
+            )
+          endif()
+        endif()
+        if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
+          set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
+          set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
+          break()
+        endif()
+      endif()
+    elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND WIN32)
+      # Check for separate OpenMP library for Clang on Windows
+      find_library(OpenMP_libomp_LIBRARY
+        NAMES libomp libgomp libiomp5
+        HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
+      )
+      mark_as_advanced(OpenMP_libomp_LIBRARY)
+      if(OpenMP_libomp_LIBRARY)
+        try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
+          CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
+          LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+          OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
+        )
+        if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
+          set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
+          set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
+          break()
+        endif()
+      endif()
+    else()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
+    endif()
+    set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
+    set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
+  endforeach()
+
+  unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
+endfunction()
+
+set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
+"
+#include <stdio.h>
+#include <omp.h>
+const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
+                            'P', '-', 'd', 'a', 't', 'e', '[',
+                            ('0' + ((_OPENMP/100000)%10)),
+                            ('0' + ((_OPENMP/10000)%10)),
+                            ('0' + ((_OPENMP/1000)%10)),
+                            ('0' + ((_OPENMP/100)%10)),
+                            ('0' + ((_OPENMP/10)%10)),
+                            ('0' + ((_OPENMP/1)%10)),
+                            ']', '\\0' };
+int main(void)
+{
+  puts(ompver_str);
+  return 0;
+}
+")
+
+set(OpenMP_Fortran_CHECK_VERSION_SOURCE
+"
+      program omp_ver
+      @OpenMP_Fortran_INCLUDE_LINE@
+      integer, parameter :: zero = ichar('0')
+      integer, parameter :: ompv = openmp_version
+      character, dimension(24), parameter :: ompver_str =&
+      (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
+         'd', 'a', 't', 'e', '[',&
+         char(zero + mod(ompv/100000, 10)),&
+         char(zero + mod(ompv/10000, 10)),&
+         char(zero + mod(ompv/1000, 10)),&
+         char(zero + mod(ompv/100, 10)),&
+         char(zero + mod(ompv/10, 10)),&
+         char(zero + mod(ompv/1, 10)), ']' /)
+      print *, ompver_str
+      end program omp_ver
+")
+
+function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
+  _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
+
+  unset(_includeDirFlags)
+  if(OpenMP_${LANG}_INCLUDE_DIR)
+    set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
+  endif()
+
+  set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
+  string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
+  try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
+              CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags}
+              COPY_FILE ${BIN_FILE}
+              OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT)
+
+  if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
+    file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
+    set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
+    if("${specstr}" MATCHES "${regex_spec_date}")
+      set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
+    endif()
+  else()
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Detecting ${LANG} OpenMP version failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
+  endif()
+endfunction()
+
+macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
+  set(OpenMP_SPEC_DATE_MAP
+    # Preview versions
+    "201611=5.0" # OpenMP 5.0 preview 1
+    # Combined versions, 2.5 onwards
+    "201811=5.0"
+    "201511=4.5"
+    "201307=4.0"
+    "201107=3.1"
+    "200805=3.0"
+    "200505=2.5"
+    # C/C++ version 2.0
+    "200203=2.0"
+    # Fortran version 2.0
+    "200011=2.0"
+    # Fortran version 1.1
+    "199911=1.1"
+    # C/C++ version 1.0 (there's no 1.1 for C/C++)
+    "199810=1.0"
+    # Fortran version 1.0
+    "199710=1.0"
+  )
+  if(MSVC)
+    list(APPEND OpenMP_SPEC_DATE_MAP "2019=2.0")
+  endif()
+
+  if(OpenMP_${LANG}_SPEC_DATE)
+    string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
+  else()
+    set(_version_match "")
+  endif()
+  if(NOT _version_match STREQUAL "")
+    set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
+    set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
+    set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
+  else()
+    unset(OpenMP_${LANG}_VERSION_MAJOR)
+    unset(OpenMP_${LANG}_VERSION_MINOR)
+    unset(OpenMP_${LANG}_VERSION)
+  endif()
+  unset(_version_match)
+  unset(OpenMP_SPEC_DATE_MAP)
+endmacro()
+
+foreach(LANG IN ITEMS C CXX)
+  if(CMAKE_${LANG}_COMPILER_LOADED)
+    if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
+      OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
+      _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
+      set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
+        CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE)
+      set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
+        CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE)
+      mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
+    endif()
+  endif()
+endforeach()
+
+if(CMAKE_Fortran_COMPILER_LOADED)
+  if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
+    OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
+    OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+    set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n      implicit none")
+    _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
+    if(OpenMP_Fortran_FLAGS_WORK)
+      set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
+    endif()
+
+    set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
+      CACHE STRING "Fortran compiler flags for OpenMP parallelization")
+    set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
+      CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
+    mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
+  endif()
+
+  if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
+    OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
+    OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
+    set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n      include 'omp_lib.h'")
+    _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
+    if(OpenMP_Fortran_FLAGS_WORK)
+      set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
+    endif()
+
+    set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
+      CACHE STRING "Fortran compiler flags for OpenMP parallelization")
+
+    set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
+      CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
+  endif()
+
+  if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+    set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n      implicit none")
+  else()
+    set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n      include 'omp_lib.h'")
+  endif()
+endif()
+
+if(NOT OpenMP_FIND_COMPONENTS)
+  set(OpenMP_FINDLIST C CXX Fortran)
+else()
+  set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
+endif()
+
+unset(_OpenMP_MIN_VERSION)
+
+include(FindPackageHandleStandardArgs)
+
+foreach(LANG IN LISTS OpenMP_FINDLIST)
+  if(CMAKE_${LANG}_COMPILER_LOADED)
+    if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
+      _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
+      set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
+        INTERNAL "${LANG} compiler's OpenMP specification date")
+    endif()
+    _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
+
+    set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
+    set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
+    set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
+    set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
+
+    set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
+    if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
+      set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
+    else()
+      foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
+        list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
+      endforeach()
+    endif()
+
+    if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.17")
+      find_package_handle_standard_args(OpenMP_${LANG}
+        NAME_MISMATCHED
+        REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
+        VERSION_VAR OpenMP_${LANG}_VERSION
+      )
+    else()
+      find_package_handle_standard_args(OpenMP_${LANG}
+        REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
+        VERSION_VAR OpenMP_${LANG}_VERSION
+      )
+    endif()
+
+    if(OpenMP_${LANG}_FOUND)
+      if(DEFINED OpenMP_${LANG}_VERSION)
+        if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
+          set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
+        endif()
+      endif()
+      set(OpenMP_${LANG}_LIBRARIES "")
+      foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
+        list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
+      endforeach()
+      if(OpenMP_${LANG}_INCLUDE_DIR)
+        set(OpenMP_${LANG}_INCLUDE_DIRS ${OpenMP_${LANG}_INCLUDE_DIR})
+      else()
+        set(OpenMP_${LANG}_INCLUDE_DIRS "")
+      endif()
+
+      if(NOT TARGET OpenMP::OpenMP_${LANG})
+        add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
+      endif()
+      if(OpenMP_${LANG}_FLAGS)
+        separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
+        set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
+          INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
+        unset(_OpenMP_${LANG}_OPTIONS)
+      endif()
+      if(OpenMP_${LANG}_INCLUDE_DIRS)
+        set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
+          INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${OpenMP_${LANG}_INCLUDE_DIRS}>")
+      endif()
+      if(OpenMP_${LANG}_LIBRARIES)
+        set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
+          INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
+      endif()
+    endif()
+  endif()
+endforeach()
+
+unset(_OpenMP_REQ_VARS)
+foreach(LANG IN ITEMS C CXX Fortran)
+  if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
+    list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
+  endif()
+endforeach()
+
+find_package_handle_standard_args(OpenMP
+    REQUIRED_VARS ${_OpenMP_REQ_VARS}
+    VERSION_VAR ${_OpenMP_MIN_VERSION}
+    HANDLE_COMPONENTS)
+
+set(OPENMP_FOUND ${OpenMP_FOUND})
+
+if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
+  if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+    set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
+  endif()
+  if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
+    set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
+  endif()
+endif()
+
+if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
+  message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
+endif()
+
+unset(OpenMP_C_CXX_TEST_SOURCE)
+unset(OpenMP_Fortran_TEST_SOURCE)
+unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
+unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
+unset(OpenMP_Fortran_INCLUDE_LINE)
+
+cmake_policy(POP)
index 249e89621bf3517e742ecd47c90ce8e1b253380e..e86ab40b2ab5d0f6f43cd9729cd66f12c185bc7c 100644 (file)
@@ -51,7 +51,7 @@ if(OPENNI_INCLUDE_DIR AND OPENNI_LIBRARY)
   mark_as_advanced(OPENNI_INCLUDE_DIRS)
 
   # Libraries
-  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+  if(NOT WIN32)
     find_package(libusb REQUIRED)
     set(OPENNI_LIBRARIES ${OPENNI_LIBRARY} libusb::libusb)
   else()
index 14ca206e40f2d217dc050126f84d4ac00a3cd5d3..5ab50743b4e0fcc535be171bda3101427960e9ef 100644 (file)
@@ -41,7 +41,7 @@ if(OPENNI2_INCLUDE_DIR AND OPENNI2_LIBRARY)
   mark_as_advanced(OPENNI2_INCLUDE_DIRS)
 
   # Libraries
-  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+  if(NOT WIN32)
     find_package(libusb REQUIRED)
     set(OPENNI2_LIBRARIES ${OPENNI2_LIBRARY} libusb::libusb)
   else()
old mode 100644 (file)
new mode 100755 (executable)
index f9f6284..5368c1d
@@ -1,35 +1,99 @@
-###############################################################################
-# Find QHULL
+#.rst:
+# FindQhull
+# --------
+#
+# Try to find QHULL library and headers. This module supports both old released versions
+# of QHULL â‰¤ 7.3.2 and newer development versions that ship with a modern config file,
+# but its limited to only the reentrant version of Qhull.
+#
+# PCL_QHULL_REQUIRED_TYPE can be used to select if you want static or shared libraries, but it defaults to "don't care".
+#
+# IMPORTED Targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the :prop_tgt:`IMPORTED` targets:
+#
+# ``QHULL::QHULL``
+#  Defined if the system has QHULL.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module sets the following variables:
+#
+# ::
+#
+#   QHULL_FOUND               True in case QHULL is found, otherwise false
+#
+# Example usage
+# ^^^^^^^^^^^^^
+#
+# ::
+#
+#     find_package(QHULL REQUIRED)
+#
+#     add_executable(foo foo.cc)
+#     target_link_libraries(foo QHULL::QHULL)
 #
-# This sets the following variables:
-# QHULL_FOUND - True if QHULL was found.
-# QHULL_INCLUDE_DIRS - Directories containing the QHULL include files.
-# QHULL_LIBRARIES - Libraries needed to use QHULL.
-# QHULL_DEFINITIONS - Compiler flags for QHULL.
-# If QHULL_USE_STATIC is specified then look for static libraries ONLY else
-# look for shared ones
 
-if(QHULL_USE_STATIC)
-  set(QHULL_RELEASE_NAME qhullstatic_r)
-  set(QHULL_DEBUG_NAME qhullstatic_rd)
-else()
-  set(QHULL_RELEASE_NAME qhull_r qhull)
-  set(QHULL_DEBUG_NAME qhull_rd qhull_d)
+# Skip if QHULL::QHULL is already defined
+if(TARGET QHULL::QHULL)
+  return()
+endif()
+
+# Try to locate QHull using modern cmake config (available on latest Qhull version).
+find_package(Qhull CONFIG QUIET)
+
+if(Qhull_FOUND)
+  unset(Qhull_FOUND)
+  set(QHULL_FOUND ON)
+  set(HAVE_QHULL ON)
+  
+  message(STATUS "Found Qhull version ${Qhull_VERSION}")
+  
+  # Create interface library that effectively becomes an alias for the appropriate (static/dynamic) imported QHULL target
+  add_library(QHULL::QHULL INTERFACE IMPORTED)
+  
+  if(TARGET Qhull::qhull_r AND TARGET Qhull::qhullstatic_r)
+    if(PCL_QHULL_REQUIRED_TYPE MATCHES "SHARED")
+      set_property(TARGET QHULL::QHULL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Qhull::qhull_r)
+      set(QHULL_LIBRARY_TYPE SHARED)
+    elseif(PCL_QHULL_REQUIRED_TYPE MATCHES "STATIC")
+      set_property(TARGET QHULL::QHULL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Qhull::qhullstatic_r)
+      set(QHULL_LIBRARY_TYPE STATIC)
+    else()
+      if(PCL_SHARED_LIBS)
+        set_property(TARGET QHULL::QHULL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Qhull::qhull_r)
+        set(QHULL_LIBRARY_TYPE SHARED)
+      else()
+        set_property(TARGET QHULL::QHULL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Qhull::qhullstatic_r)
+        set(QHULL_LIBRARY_TYPE STATIC)
+      endif()
+    endif()
+  elseif(TARGET Qhull::qhullstatic_r)
+    set_property(TARGET QHULL::QHULL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Qhull::qhullstatic_r)
+    set(QHULL_LIBRARY_TYPE STATIC)
+  else()
+    set_property(TARGET QHULL::QHULL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Qhull::qhull_r)
+    set(QHULL_LIBRARY_TYPE SHARED)  
+  endif()
+  
+  return()
 endif()
 
 find_file(QHULL_HEADER
-          NAMES libqhull/libqhull.h qhull.h
+          NAMES libqhull_r.h
           HINTS "${QHULL_ROOT}" "$ENV{QHULL_ROOT}" "${QHULL_INCLUDE_DIR}"
           PATHS "$ENV{PROGRAMFILES}/QHull" "$ENV{PROGRAMW6432}/QHull"
-          PATH_SUFFIXES qhull src/libqhull libqhull include)
+          PATH_SUFFIXES qhull_r src/libqhull_r libqhull_r include)
 
 set(QHULL_HEADER "${QHULL_HEADER}" CACHE INTERNAL "QHull header" FORCE )
 
 if(QHULL_HEADER)
   get_filename_component(qhull_header ${QHULL_HEADER} NAME_WE)
-  if("${qhull_header}" STREQUAL "qhull")
+  if("${qhull_header}" STREQUAL "qhull_r")
     get_filename_component(QHULL_INCLUDE_DIR ${QHULL_HEADER} PATH)
-  elseif("${qhull_header}" STREQUAL "libqhull")
+  elseif("${qhull_header}" STREQUAL "libqhull_r")
     get_filename_component(QHULL_INCLUDE_DIR ${QHULL_HEADER} PATH)
     get_filename_component(QHULL_INCLUDE_DIR ${QHULL_INCLUDE_DIR} PATH)
   endif()
@@ -37,54 +101,82 @@ else()
   set(QHULL_INCLUDE_DIR "QHULL_INCLUDE_DIR-NOTFOUND")
 endif()
 
-find_library(QHULL_LIBRARY
-             NAMES ${QHULL_RELEASE_NAME}
+find_library(QHULL_LIBRARY_SHARED
+             NAMES qhull_r qhull
              HINTS "${QHULL_ROOT}" "$ENV{QHULL_ROOT}"
              PATHS "$ENV{PROGRAMFILES}/QHull" "$ENV{PROGRAMW6432}/QHull"
              PATH_SUFFIXES project build bin lib)
 
-get_filename_component(QHULL_LIBRARY_NAME "${QHULL_LIBRARY}" NAME)
-
 find_library(QHULL_LIBRARY_DEBUG
-             NAMES ${QHULL_DEBUG_NAME} ${QHULL_RELEASE_NAME}
+             NAMES qhull_rd qhull_d
              HINTS "${QHULL_ROOT}" "$ENV{QHULL_ROOT}"
              PATHS "$ENV{PROGRAMFILES}/QHull" "$ENV{PROGRAMW6432}/QHull"
              PATH_SUFFIXES project build bin lib debug/lib)
 
-if(NOT QHULL_LIBRARY_DEBUG)
-  set(QHULL_LIBRARY_DEBUG ${QHULL_LIBRARY})
-endif()
-
-get_filename_component(QHULL_LIBRARY_DEBUG_NAME "${QHULL_LIBRARY_DEBUG}" NAME)
-
-if(QHULL_INCLUDE_DIR AND QHULL_LIBRARY)
-
-  # Include directories
-  set(QHULL_INCLUDE_DIRS ${QHULL_INCLUDE_DIR})
-  unset(QHULL_INCLUDE_DIR)
-  mark_as_advanced(QHULL_INCLUDE_DIRS)
+find_library(QHULL_LIBRARY_STATIC
+             NAMES qhullstatic_r
+             HINTS "${QHULL_ROOT}" "$ENV{QHULL_ROOT}"
+             PATHS "$ENV{PROGRAMFILES}/QHull" "$ENV{PROGRAMW6432}/QHull"
+             PATH_SUFFIXES project build bin lib)
 
-  # Libraries
-  set(QHULL_LIBRARIES optimized ${QHULL_LIBRARY} debug ${QHULL_LIBRARY_DEBUG})
-  unset(QHULL_LIBRARY)
-  unset(QHULL_LIBRARY_DEBUG)
-  mark_as_advanced(QHULL_LIBRARIES)
+find_library(QHULL_LIBRARY_DEBUG_STATIC
+             NAMES qhullstatic_rd
+             HINTS "${QHULL_ROOT}" "$ENV{QHULL_ROOT}"
+             PATHS "$ENV{PROGRAMFILES}/QHull" "$ENV{PROGRAMW6432}/QHull"
+             PATH_SUFFIXES project build bin lib debug/lib)
 
+if(QHULL_LIBRARY_SHARED AND QHULL_LIBRARY_STATIC)
+  if(PCL_QHULL_REQUIRED_TYPE MATCHES "SHARED")
+    set(QHULL_LIBRARY_TYPE SHARED)
+    set(QHULL_LIBRARY ${QHULL_LIBRARY_SHARED})
+  elseif(PCL_QHULL_REQUIRED_TYPE MATCHES "STATIC")
+    set(QHULL_LIBRARY_TYPE STATIC)
+    set(QHULL_LIBRARY ${QHULL_LIBRARY_STATIC})
+  else()
+    if(PCL_SHARED_LIBS)
+      set(QHULL_LIBRARY_TYPE SHARED)
+      set(QHULL_LIBRARY ${QHULL_LIBRARY_SHARED})
+    else()
+      set(QHULL_LIBRARY_TYPE STATIC)
+      set(QHULL_LIBRARY ${QHULL_LIBRARY_STATIC})
+    endif()
+  endif()
+elseif(QHULL_LIBRARY_STATIC)
+  set(QHULL_LIBRARY_TYPE STATIC)
+  set(QHULL_LIBRARY ${QHULL_LIBRARY_STATIC})
+elseif(QHULL_LIBRARY_SHARED)
+  set(QHULL_LIBRARY_TYPE SHARED)
+  set(QHULL_LIBRARY ${QHULL_LIBRARY_SHARED})
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Qhull
   FOUND_VAR QHULL_FOUND
-  REQUIRED_VARS QHULL_LIBRARIES QHULL_INCLUDE_DIRS
+  REQUIRED_VARS QHULL_LIBRARY QHULL_INCLUDE_DIR
 )
 
 if(QHULL_FOUND)
   set(HAVE_QHULL ON)
-  if(NOT QHULL_USE_STATIC)
-    add_definitions("-Dqh_QHpointer")
-    if(MSVC)
-      add_definitions("-Dqh_QHpointer_dllimport")
+  add_library(QHULL::QHULL ${QHULL_LIBRARY_TYPE} IMPORTED)
+  set_target_properties(QHULL::QHULL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${QHULL_INCLUDE_DIR}")
+  set_property(TARGET QHULL::QHULL APPEND PROPERTY IMPORTED_CONFIGURATIONS "RELEASE")
+  set_target_properties(QHULL::QHULL PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "CXX")
+  set_target_properties(QHULL::QHULL PROPERTIES INTERFACE_COMPILE_DEFINITIONS "qh_QHpointer")
+  if(MSVC)
+    set_target_properties(QHULL::QHULL PROPERTIES INTERFACE_COMPILE_DEFINITIONS "qh_QHpointer_dllimport")
+  endif()
+  if(WIN32 AND NOT (PCL_QHULL_REQUIRED_TYPE MATCHES "STATIC"))
+    set_target_properties(QHULL::QHULL PROPERTIES IMPORTED_IMPLIB_RELEASE "${QHULL_LIBRARY}")
+  else()
+    set_target_properties(QHULL::QHULL PROPERTIES IMPORTED_LOCATION_RELEASE "${QHULL_LIBRARY}")
+  endif()
+  if(QHULL_LIBRARY_DEBUG)
+    set_property(TARGET QHULL::QHULL APPEND PROPERTY IMPORTED_CONFIGURATIONS "DEBUG")
+    if(WIN32 AND NOT (PCL_QHULL_REQUIRED_TYPE MATCHES "STATIC"))
+      set_target_properties(QHULL::QHULL PROPERTIES IMPORTED_IMPLIB_DEBUG "${QHULL_LIBRARY_DEBUG}")
+    else()
+      set_target_properties(QHULL::QHULL PROPERTIES IMPORTED_LOCATION_DEBUG "${QHULL_LIBRARY_DEBUG}")
     endif()
   endif()
-  message(STATUS "QHULL found (include: ${QHULL_INCLUDE_DIRS}, lib: ${QHULL_LIBRARIES})")
+  message(STATUS "QHULL found (include: ${QHULL_INCLUDE_DIR}, lib: ${QHULL_LIBRARY})")
 endif()
index 90277400000dbc334045d0d0129ab6ec1b2b4c2e..aab8226901854122f92f40a0a813933628e46126 100644 (file)
@@ -66,7 +66,7 @@ find_package_handle_standard_args(libusb DEFAULT_MSG libusb_LIBRARIES libusb_INC
 
 mark_as_advanced(libusb_INCLUDE_DIRS libusb_LIBRARIES)
 
-if(LIBUSB_FOUND)
+if(libusb_FOUND)
   add_library(libusb::libusb UNKNOWN IMPORTED)
   set_target_properties(libusb::libusb PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${libusb_INCLUDE_DIR}")
   set_target_properties(libusb::libusb PROPERTIES IMPORTED_LOCATION "${libusb_LIBRARIES}")
index 9d006a358f9a8c7fc3a909323513ecd80e5135df..52309dc412b7b9fa4fb3b28a99b83c5dca83d659 100644 (file)
@@ -7,13 +7,16 @@ if(NOT BUILD_all_in_one_installer)
   return()
 endif()
 
-get_filename_component(BOOST_ROOT "${Boost_INCLUDE_DIR}" PATH)
-get_filename_component(BOOST_ROOT "${BOOST_ROOT}" PATH)
-get_filename_component(EIGEN_ROOT "${EIGEN_INCLUDE_DIRS}" PATH)
-get_filename_component(QHULL_ROOT "${QHULL_INCLUDE_DIRS}" PATH)
-get_filename_component(VTK_ROOT "${VTK_DIR}" PATH)
-get_filename_component(VTK_ROOT "${VTK_ROOT}" PATH)
-get_filename_component(VTK_ROOT "${VTK_ROOT}" PATH)
+# get root directory of each dependency libraries to be copied to PCL/3rdParty
+get_filename_component(BOOST_ROOT "${Boost_INCLUDE_DIR}" PATH)  # ../Boost/include/boost-x_x/ -> ../Boost/include/
+get_filename_component(BOOST_ROOT "${BOOST_ROOT}" PATH)         # ../Boost/include/           -> ../Boost/
+get_filename_component(EIGEN_ROOT "${EIGEN_INCLUDE_DIRS}" PATH) # ../Eigen3/include/          -> ../Eigen3/
+get_filename_component(QHULL_ROOT "${Qhull_DIR}" PATH)          # ../qhull/lib/cmake/Qhull/   -> ../qhull/lib/cmake
+get_filename_component(QHULL_ROOT "${QHULL_ROOT}" PATH)         # ../qhull/lib/cmake/         -> ../qhull/lib/
+get_filename_component(QHULL_ROOT "${QHULL_ROOT}" PATH)         # ../qhull/lib/               -> ../qhull/
+get_filename_component(VTK_ROOT "${VTK_DIR}" PATH)              # ../VTK/lib/cmake/vtk-x.x/   -> ../VTK/lib/cmake/
+get_filename_component(VTK_ROOT "${VTK_ROOT}" PATH)             # ../VTK/lib/cmake/           -> ../VTK/lib/
+get_filename_component(VTK_ROOT "${VTK_ROOT}" PATH)             # ../VTK/lib/                 -> ../VTK/
 
 set(PCL_3RDPARTY_COMPONENTS)
 foreach(dep Eigen Boost Qhull FLANN VTK)
index 5f036cd982538384037563687c15af4785ff321b..b00433b27841a679cc4620003d00640c262abcf4 100644 (file)
@@ -43,6 +43,8 @@ if(WIN32)
     string(APPEND CPACK_NSIS_PACKAGE_NAME "-msvc2017-${win_system_name}")
   elseif(MSVC_VERSION MATCHES "^192[0-9]$")
     string(APPEND CPACK_NSIS_PACKAGE_NAME "-msvc2019-${win_system_name}")
+  elseif(MSVC_VERSION MATCHES "^193[0-9]$")
+    string(APPEND CPACK_NSIS_PACKAGE_NAME "-msvc2022-${win_system_name}")
   else()
     string(APPEND CPACK_NSIS_PACKAGE_NAME "-${win_system_name}")
   endif()
index d3187ea70e4e9efb5fb416de2b13608beb83e54d..f760a16393e5637d82cbc86fab937ec4cc4efe2d 100644 (file)
@@ -5,6 +5,12 @@ function(PCL_CHECK_FOR_AVX)
 
   include(CheckCXXSourceRuns)
   
+  if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG)
+    # Setting -march & -mtune just as required flags for check_cxx_source_runs,
+    # and CMAKE_REQUIRED_FLAGS will be restored after test runs.
+    set(CMAKE_REQUIRED_FLAGS "-march=native -mtune=native")
+  endif()
+
   check_cxx_source_runs("    
     #include <immintrin.h>
     int main()
@@ -27,6 +33,18 @@ function(PCL_CHECK_FOR_AVX)
     HAVE_AVX)
   endif()
 
+  set(CMAKE_REQUIRED_FLAGS)
+
+# Setting the -mavx/-mavx2 defines __AVX(2)__, see here https://stackoverflow.com/a/28939692
+# and this allows the compiler to use the codes for AVX behind code guards.
+  if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG)
+    if(HAVE_AVX2)
+      set(AVX_FLAGS "-mavx2" PARENT_SCOPE)
+    elseif(HAVE_AVX)
+      set(AVX_FLAGS "-mavx" PARENT_SCOPE)
+    endif()
+  endif()
+
 # Setting the /arch defines __AVX(2)__, see here https://docs.microsoft.com/en-us/cpp/build/reference/arch-x64?view=msvc-160
 # AVX2 extends and includes AVX.
 # Setting these defines allows the compiler to use AVX instructions as well as code guarded with the defines.
index ae6b93355b384501b6113ee00e4d77d14d6d0c4a..862851b1c7dcb293e778aa938b21518d4e99e963 100644 (file)
@@ -14,13 +14,10 @@ else()
 endif()
 
 set(Boost_ADDITIONAL_VERSIONS
-  "1.76.0" "1.76" "1.75.0" "1.75" 
+  "1.78.0" "1.78" "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" 
   "1.74.0" "1.74" "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70"
   "1.69.0" "1.69" "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65")
 
-# Disable the config mode of find_package(Boost)
-set(Boost_NO_BOOST_CMAKE ON)
-
 # Optional boost modules
 find_package(Boost 1.65.0 QUIET COMPONENTS serialization mpi)
 if(Boost_SERIALIZATION_FOUND)
@@ -33,9 +30,4 @@ find_package(Boost 1.65.0 REQUIRED COMPONENTS ${BOOST_REQUIRED_MODULES})
 
 if(Boost_FOUND)
   set(BOOST_FOUND TRUE)
-  # Obtain diagnostic information about Boost's automatic linking outputted
-  # during compilation time.
-  add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
-  include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
-  link_directories(${Boost_LIBRARY_DIRS})
 endif()
index ab1810a15cb1d40a765abc24a5241c884f76a614..21aeac2e1dc0cf03d593c8437221b475b90c0647 100644 (file)
@@ -1,5 +1,4 @@
 # Find CUDA
-
 if(MSVC)
   # Setting this to true brakes Visual Studio builds.
   set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF CACHE BOOL "CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE")
@@ -10,46 +9,55 @@ find_package(CUDA 9.0)
 
 if(CUDA_FOUND)
   message(STATUS "Found CUDA Toolkit v${CUDA_VERSION_STRING}")
+  
+  enable_language(CUDA)
   set(HAVE_CUDA TRUE)
 
-  # CUDA_ARCH_BIN is a space separated list of versions to include in output so-file. So you can set CUDA_ARCH_BIN = 10 11 12 13 20
-  # Also user can specify virtual arch in parenthesis to limit instructions set,
-  # for example CUDA_ARCH_BIN = 11(11) 12(11) 13(11) 20(11) 21(11) -> forces using only sm_11 instructions.
-  # The CMake scripts interpret XX as XX (XX). This allows user to omit parenthesis.
-  # Arch 21 is an exceptional case since it doesn't have own sm_21 instructions set.
-  # So 21 = 21(21) is an invalid configuration and user has to explicitly force previous sm_20 instruction set via 21(20).
-  # CUDA_ARCH_BIN adds support of only listed GPUs. As alternative CMake scripts also parse 'CUDA_ARCH_PTX' variable,
-  # which is a list of intermediate PTX codes to include in final so-file. The PTX code can/will be JIT compiled for any current or future GPU.
-  # To add support of older GPU for kinfu, I would embed PTX 11 and 12 into so-file. GPU with sm_13 will run PTX 12 code (no difference for kinfu)
-
-  # Find a complete list for CUDA compute capabilities at http://developer.nvidia.com/cuda-gpus
-  
-  # For a list showing CUDA toolkit version support for compute capabilities see: https://en.wikipedia.org/wiki/CUDA
-  # or the nvidia release notes ie: 
-  # https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-general-new-features
-  # or
-  # https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#deprecated-features
-  
-  if(NOT ${CUDA_VERSION_STRING} VERSION_LESS "11.0")
-    set(__cuda_arch_bin "3.5 3.7 5.0 5.2 5.3 6.0 6.1 6.2 7.0 7.2 7.5 8.0 8.6")
-  elseif(NOT ${CUDA_VERSION_STRING} VERSION_LESS "10.0")
-    set(__cuda_arch_bin "3.0 3.2 3.5 3.7 5.0 5.2 5.3 6.0 6.1 6.2 7.0 7.2 7.5")
-  elseif(NOT ${CUDA_VERSION_STRING} VERSION_LESS "9.0")
-    set(__cuda_arch_bin "3.0 3.2 3.5 3.7 5.0 5.2 5.3 6.0 6.1 6.2 7.0 7.2")
+  if (CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+    if(${CUDA_VERSION_STRING} VERSION_GREATER_EQUAL "11.1")
+      execute_process(COMMAND ${CMAKE_CUDA_COMPILER} --list-gpu-code RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE OUTPUT_VAL)
+      if(EXIT_CODE EQUAL 0)
+        #Remove sm_
+        string(REPLACE "sm_" "" OUTPUT_VAL ${OUTPUT_VAL})
+        #Convert to list
+        string(REPLACE "\n" ";" __CUDA_ARCH_BIN ${OUTPUT_VAL})
+        #Remove last empty entry
+        list(REMOVE_AT __CUDA_ARCH_BIN -1)
+      else()
+        message(FATAL_ERROR "Failed to run NVCC to get list of GPU codes: ${EXIT_CODE}")
+      endif()
+    elseif(${CUDA_VERSION_STRING} VERSION_GREATER_EQUAL "11.0")
+      set(__CUDA_ARCH_BIN "35;37;50;52;53;60;61;62;70;72;75;80")
+    elseif(${CUDA_VERSION_STRING} VERSION_GREATER_EQUAL "10.0")
+      set(__CUDA_ARCH_BIN "30;32;35;37;50;52;53;60;61;62;70;72;75")
+    elseif(${CUDA_VERSION_STRING} VERSION_GREATER_EQUAL "9.1")
+      set(__CUDA_ARCH_BIN "30;32;35;37;50;52;53;60;61;62;70;72")
+    else()
+      set(__CUDA_ARCH_BIN "30;32;35;37;50;52;53;60;61;62;70")
+    endif()
+  else()
+    message(FATAL_ERROR "Unsupported CUDA compiler ${CMAKE_CUDA_COMPILER_ID}.")
   endif()
 
-  set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
-
-  set(CUDA_ARCH_PTX "" CACHE STRING "Specify 'virtual' PTX arch to build PTX intermediate code for. Example: 1.0 1.2 or 10 12")
-  #set(CUDA_ARCH_PTX "1.1 1.2" CACHE STRING "Specify 'virtual' PTX arch to build PTX intermediate code for. Example: 1.0 1.2 or 10 12")
-
-  # Guess this macros will be included in cmake distributive
-  include(${PCL_SOURCE_DIR}/cmake/CudaComputeTargetFlags.cmake)
-  APPEND_TARGET_ARCH_FLAGS()
-
-  # Prevent compilation issues between recent gcc versions and old CUDA versions
-  list(APPEND CUDA_NVCC_FLAGS "-D_FORCE_INLINES")
+  set(CUDA_ARCH_BIN ${__CUDA_ARCH_BIN} CACHE STRING "Specify 'real' GPU architectures to build binaries for")
   
-  # Allow calling a constexpr __host__ function from a __device__ function.
-  list(APPEND CUDA_NVCC_FLAGS "--expt-relaxed-constexpr")
+  if(POLICY CMP0104)
+    cmake_policy(SET CMP0104 NEW)
+    set(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH_BIN})
+    message(STATUS "CMAKE_CUDA_ARCHITECTURES: ${CMAKE_CUDA_ARCHITECTURES}")
+    
+    #Add empty project as its not required with newer CMake
+    add_library(pcl_cuda INTERFACE)
+  else()
+    # Generate SASS
+    set(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH_BIN})
+    # Generate PTX for last architecture
+    list(GET CUDA_ARCH_BIN -1 ver)
+    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -gencode arch=compute_${ver},code=compute_${ver}")
+    message(STATUS "CMAKE_CUDA_FLAGS: ${CMAKE_CUDA_FLAGS}")
+    
+    add_library(pcl_cuda INTERFACE)
+    target_include_directories(pcl_cuda INTERFACE ${CUDA_TOOLKIT_INCLUDE})
+    
+  endif ()
 endif()
diff --git a/cmake/pcl_find_libusb.cmake b/cmake/pcl_find_libusb.cmake
new file mode 100644 (file)
index 0000000..666594b
--- /dev/null
@@ -0,0 +1,34 @@
+#
+#pcl_find_libusb is used due to VCPKG making impossible to use local findXX modules.
+# and VCPKG findlibusb doesn't create the libusb targets.
+
+# Find and set libusb
+find_package(libusb)
+
+if(TARGET libusb::libusb)
+  #libusb target is found by the find_package script. 
+  #VCPKG skip PCLs findlibusb and sets its own variables which is handled below.
+  return()
+endif()
+
+#Handle VCPKG definitions
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(libusb DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIRS)
+
+mark_as_advanced(LIBUSB_INCLUDE_DIRS LIBUSB_LIBRARIES)
+
+if(libusb_FOUND)
+  add_library(libusb::libusb UNKNOWN IMPORTED)
+  if(${LIBUSB_INCLUDE_DIRS})
+    set_target_properties(libusb::libusb PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBUSB_INCLUDE_DIRS}")
+  endif()
+  if(EXISTS "${LIBUSB_LIBRARY}")
+    set_target_properties(libusb::libusb PROPERTIES IMPORTED_LOCATION ${LIBUSB_LIBRARY})
+  endif()
+  if(EXISTS "${LIBUSB_LIBRARY_DEBUG}")
+    set_target_properties(libusb::libusb PROPERTIES IMPORTED_LOCATION_DEBUG ${LIBUSB_LIBRARY_DEBUG})
+  endif()
+  if(EXISTS "${LIBUSB_LIBRARY_RELEASE}")
+    set_target_properties(libusb::libusb PROPERTIES IMPORTED_LOCATION_RELEASE ${LIBUSB_LIBRARY_RELEASE})
+  endif()
+endif()
diff --git a/cmake/pcl_find_qt.cmake b/cmake/pcl_find_qt.cmake
new file mode 100644 (file)
index 0000000..09192e3
--- /dev/null
@@ -0,0 +1,77 @@
+# This file is not processed if WITH_QT evaluates to a CMake false constant.
+#
+# First we convert WITH_QT to WITH_QT_STR with
+# - CMake true constants to string YES (except numbers unequal 1)
+# - Other values to upper case string
+#
+# Background: WITH_QT was previously boolean and we want to be backwards compatible.
+#
+# This if condition matches all CMake true constants (`${WITH_QT}`) except numbers other than 1 (`NOT (WITH_QT LESS 1 OR WITH_QT GREATER 1)`).
+#
+# This way we prevent things like -DWITH_QT=5 to be handled as YES instead of QT5.
+# Setting -DWITH_QT=5 will error and inform you to use -DWITH_QT=QT5 instead.
+# (This breaks backward compatibility, but hopefully no one will use values not equal to 1 if they want to express true.)
+#
+# Note: "NOT (WITH_QT LESS 1 OR WITH_QT GREATER 1)" is not the same as
+#       "WITH_QT EQUAL 1" because "LESS/GREATER/EQUAL" all pre-check if WITH_QT is a valid number.
+if(${WITH_QT} AND NOT (WITH_QT LESS 1 OR WITH_QT GREATER 1))
+  set(WITH_QT_STR "YES")
+else()
+  string(TOUPPER ${WITH_QT} WITH_QT_STR)
+endif()
+
+if(NOT WITH_QT_STR MATCHES "^(AUTO|YES|QT6|QT5)$")
+  message(FATAL_ERROR "Option WITH_QT must be one of AUTO|YES|QT6|QT5|NO but is '${WITH_QT}'")
+endif()
+
+if(WITH_QT_STR MATCHES "^(AUTO|YES|QT6)$")
+  find_package(Qt6 QUIET COMPONENTS Concurrent OpenGL Widgets)
+  set(QT6_FOUND ${Qt6_FOUND})
+  set(QT_FOUND ${QT6_FOUND})
+  if (QT6_FOUND)
+    set(QTX Qt6)
+  endif()
+endif()
+
+if(WITH_QT_STR MATCHES "^(AUTO|YES|QT5)$" AND NOT QT6_FOUND)
+  find_package(Qt5 5.9.5 QUIET COMPONENTS Concurrent OpenGL Widgets)
+  set(QT5_FOUND ${Qt5_FOUND})
+  set(QT_FOUND ${QT5_FOUND})
+  if(QT5_FOUND)
+    set(QTX Qt5)
+  endif()
+endif()
+
+if(NOT WITH_QT_STR MATCHES "^(AUTO)$" AND NOT QT_FOUND)
+  message(FATAL_ERROR "Can not find Qt required by WITH_QT=${WITH_QT}.")
+endif()
+
+if(NOT QT_FOUND)
+  message(STATUS "Qt is not found.")
+  return()
+endif()
+
+set(QT_VERSION ${${QTX}_VERSION})
+message(STATUS "Qt version: ${QT_VERSION}")
+
+set(QT_DISABLE_PRECATED_BEFORE_VAL "0x050900")
+
+#Set Cmake Auto features to skip .hh files
+if(POLICY CMP0100)
+  cmake_policy(SET CMP0100 OLD)
+endif()
+
+#If building CUDA required libraries
+#Change ${QTX}::Core fixed -fPIC flags to conditionally only CXX
+#TODO: To be removed when QT is >5.14.1
+if(BUILD_CUDA OR BUILD_GPU)
+  if(${QTX}Widgets_VERSION VERSION_LESS 5.14.1)
+    get_property(core_options TARGET ${QTX}::Core PROPERTY INTERFACE_COMPILE_OPTIONS)
+    string(REPLACE "-fPIC" "$<IF:$<COMPILE_LANGUAGE:CXX>,-fPIC,>"  new_core_options ${core_options})
+    set_property(TARGET ${QTX}::Core PROPERTY INTERFACE_COMPILE_OPTIONS ${new_core_options})
+  endif()
+endif()
+
+get_property(core_def TARGET ${QTX}::Core PROPERTY INTERFACE_COMPILE_DEFINITIONS)
+list(APPEND core_def "QT_DISABLE_DEPRECATED_BEFORE=${QT_DISABLE_PRECATED_BEFORE_VAL}")
+set_property(TARGET ${QTX}::Core PROPERTY INTERFACE_COMPILE_DEFINITIONS ${core_def})
index 541ec580b55b8125c871e22e595297143ba9c5d3..25d1522bee17cd7ad0402364bd919ccb5f3476f5 100644 (file)
@@ -4,17 +4,11 @@ function(PCL_CHECK_FOR_SSE)
   set(SSE_FLAGS)
   set(SSE_DEFINITIONS)
 
-  if(NOT CMAKE_CROSSCOMPILING)
+  if(PCL_ENABLE_MARCHNATIVE AND (NOT CMAKE_CROSSCOMPILING))
     # Test GCC/G++ and CLANG
     if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG)
       include(CheckCXXCompilerFlag)
       check_cxx_compiler_flag("-march=native" HAVE_MARCH)
-      if(HAVE_MARCH)
-          list(APPEND SSE_FLAGS "-march=native")
-      else()
-          list(APPEND SSE_FLAGS "-mtune=native")
-      endif()
-      message(STATUS "Using CPU native flags for SSE optimization: ${SSE_FLAGS}")
     endif()
   endif()
 
@@ -221,7 +215,16 @@ function(PCL_CHECK_FOR_SSE)
     else()
       # Setting -ffloat-store to alleviate 32bit vs 64bit discrepancies on non-SSE
       # platforms.
-      list(APPEND SSE_FLAGS "-ffloat-store")
+      string(APPEND SSE_FLAGS " -ffloat-store")
+    endif()
+    
+    if(PCL_ENABLE_MARCHNATIVE AND (NOT CMAKE_CROSSCOMPILING))
+      if(HAVE_MARCH)
+          string(APPEND SSE_FLAGS " -march=native")
+      else()
+          string(APPEND SSE_FLAGS " -mtune=native")
+      endif()
+      message(STATUS "Using CPU native flags for SSE optimization: ${SSE_FLAGS}")
     endif()
   elseif(MSVC AND NOT CMAKE_SIZEOF_VOID_P)
     if(SSE_LEVEL GREATER_EQUAL 2.0)
index d1037b4ea748a9a48a52c8ec8c5de4483d9e0013..918d887388ac15ef898c3fcc4247fca12ca88528 100644 (file)
@@ -52,6 +52,7 @@ set(NON_PREFIX_PCL_VTK_COMPONENTS
   FiltersSources
   ImagingCore
   ImagingSources
+  InteractionImage
   InteractionStyle
   InteractionWidgets
   IOCore
@@ -102,18 +103,18 @@ if (vtkMissingComponents)
   message(WARNING "Missing vtk modules: ${vtkMissingComponents}")
 endif()
 
-if("vtkGUISupportQt" IN_LIST VTK_MODULES_ENABLED AND "vtkRenderingQt" IN_LIST VTK_MODULES_ENABLED)
+if("vtkGUISupportQt" IN_LIST VTK_MODULES_ENABLED)
   set(HAVE_QVTK TRUE)
   #PCL_VTK_COMPONENTS is used in the PCLConfig.cmake to refind the required modules.
   #Pre vtk 9.0, all vtk libraries are linked into pcl_visualizer.
   #Subprojects can link against pcl_visualizer and directly use VTK-QT libraries.
-  list(APPEND PCL_VTK_COMPONENTS vtkRenderingQt vtkGUISupportQt)
+  list(APPEND PCL_VTK_COMPONENTS vtkGUISupportQt)
 elseif("GUISupportQt" IN_LIST VTK_AVAILABLE_COMPONENTS AND "RenderingQt" IN_LIST VTK_AVAILABLE_COMPONENTS)
   set(HAVE_QVTK TRUE)
   #PCL_VTK_COMPONENTS is used in the PCLConfig.cmake to refind the required modules.
   #Post vtk 9.0, only required libraries are linked against pcl_visualizer.
   #Subprojects need to manually link to VTK-QT libraries.
-  list(APPEND PCL_VTK_COMPONENTS RenderingQt GUISupportQt)
+  list(APPEND PCL_VTK_COMPONENTS GUISupportQt)
 else()
   unset(HAVE_QVTK)
 endif()
index 6570d75f166e97cbaa4aaf33ce2afc942e3086e5..e4ca977857ac4d5b001b9b56c4e083fe98ae6dfc 100644 (file)
@@ -1,20 +1,33 @@
 # Options for building PCL.
 
+# By default, PCL restricts the dependency search to only shared or only static libraries,
+# depending on whether PCL itself is built as a shared or static library.
+# This restriction is undesirable when a dependency is available
+# only as a shared library while building PCL as a static library, or vice versa.
+# In such cases, the user may prefer to use the found dependency anyway.
+# For example, the user may prefer to build PCL as a static library
+# using a shared OpenGL library provided by the system.
+# This option allows to override the restriction imposed by default.
+option(PCL_ALLOW_BOTH_SHARED_AND_STATIC_DEPENDENCIES, "Do not force PCL dependencies to be all shared or all static." OFF)
+
 # Build shared libraries by default.
 option(PCL_SHARED_LIBS "Build shared libraries." ON)
 if(PCL_SHARED_LIBS)
   set(PCL_LIB_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
   set(PCL_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
   set(PCL_LIB_TYPE "SHARED")
-#  set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
-  if(WIN32)
-    set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_IMPORT_LIBRARY_SUFFIX})
+  if(NOT PCL_ALLOW_BOTH_SHARED_AND_STATIC_DEPENDENCIES)
+    if(WIN32)
+      set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_IMPORT_LIBRARY_SUFFIX})
+    endif()
   endif()
 else()
   set(PCL_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
   set(PCL_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
   set(PCL_LIB_TYPE "STATIC")
-  set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+  if(NOT PCL_ALLOW_BOTH_SHARED_AND_STATIC_DEPENDENCIES)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+  endif()
 endif()
 mark_as_advanced(PCL_SHARED_LIBS)
 
@@ -23,14 +36,14 @@ option(PCL_BUILD_WITH_BOOST_DYNAMIC_LINKING_WIN32 "Build against a dynamically l
 mark_as_advanced(PCL_BUILD_WITH_BOOST_DYNAMIC_LINKING_WIN32)
 
 # Build with shared/static linking for FLANN (advanced users)
-set(PCL_FLANN_REQUIRED_TYPE "DONTCARE" CACHE STRING "Select build type to use (STATIC/SHARED).")
+set(PCL_FLANN_REQUIRED_TYPE "DONTCARE" CACHE STRING "Select build type to use STATIC or SHARED.")
 set_property(CACHE PCL_FLANN_REQUIRED_TYPE PROPERTY STRINGS DONTCARE SHARED STATIC)
-
-mark_as_advanced(PCL_BUILD_WITH_FLANN_DYNAMIC_LINKING_WIN32)
+mark_as_advanced(PCL_FLANN_REQUIRED_TYPE)
 
 # Build with dynamic linking for QHull (advanced users)
-option(PCL_BUILD_WITH_QHULL_DYNAMIC_LINKING_WIN32 "Build against a dynamically linked QHull on Win32 platforms." OFF)
-mark_as_advanced(PCL_BUILD_WITH_QHULL_DYNAMIC_LINKING_WIN32)
+set(PCL_QHULL_REQUIRED_TYPE "DONTCARE" CACHE STRING "Select build type to use STATIC or SHARED.")
+set_property(CACHE PCL_QHULL_REQUIRED_TYPE PROPERTY STRINGS DONTCARE SHARED STATIC)
+mark_as_advanced(PCL_QHULL_REQUIRED_TYPE)
 
 # Precompile for a minimal set of point types instead of all.
 option(PCL_ONLY_CORE_POINT_TYPES "Compile explicitly only for a small subset of point types (e.g., pcl::PointXYZ instead of PCL_XYZ_POINT_TYPES)." OFF)
@@ -44,10 +57,16 @@ mark_as_advanced(PCL_NO_PRECOMPILE)
 option(PCL_ENABLE_SSE "Enable or Disable SSE optimizations." ON)
 mark_as_advanced(PCL_ENABLE_SSE)
 
-if(WIN32)
-  # Enable or Disable the check for AVX optimizations
-  option(PCL_ENABLE_AVX "Enable or Disable AVX optimizations." ON)
-  mark_as_advanced(PCL_ENABLE_AVX)
+# Enable or Disable the check for AVX optimizations
+option(PCL_ENABLE_AVX "Enable or Disable AVX optimizations." ON)
+mark_as_advanced(PCL_ENABLE_AVX)
+
+if(UNIX)
+  # Enable or Disable the check for March Native optimizations
+  option(PCL_ENABLE_MARCHNATIVE "Enable or Disable march native optimizations." ON)
+  mark_as_advanced(PCL_ENABLE_MARCHNATIVE)
+else()
+  set(PCL_ENABLE_MARCHNATIVE FALSE)
 endif()
 
 # Allow the user to enable compiler cache
index 42880bc64565c65d6cf1bd7b9fc77fcc99ce2161..40e5ad80ba62258b6c172cf568907289816ccba4 100644 (file)
@@ -14,6 +14,7 @@ set(PCLCONFIG_EXTERNAL_DEPENDENCIES)
 set(PCLCONFIG_OPTIONAL_DEPENDENCIES)
 set(PCLCONFIG_SSE_DEFINITIONS "${SSE_DEFINITIONS}")
 set(PCLCONFIG_SSE_COMPILE_OPTIONS ${SSE_FLAGS})
+set(PCLCONFIG_AVX_COMPILE_OPTIONS ${AVX_FLAGS})
 
 foreach(_ss ${PCL_SUBSYSTEMS_MODULES})
   PCL_GET_SUBSYS_STATUS(_status ${_ss})
index 91f24041ff6f6748827322d6ea86025800b30ff7..ff79c207612eed6f4b92dc49d20f66a8d8aacc74 100644 (file)
@@ -223,8 +223,8 @@ function(PCL_ADD_LIBRARY _name)
   add_library(${_name} ${PCL_LIB_TYPE} ${ADD_LIBRARY_OPTION_SOURCES})
   PCL_ADD_VERSION_INFO(${_name})
   target_compile_features(${_name} PUBLIC ${PCL_CXX_COMPILE_FEATURES})
-  # must link explicitly against boost.
-  target_link_libraries(${_name} ${Boost_LIBRARIES} Threads::Threads)
+
+  target_link_libraries(${_name} Threads::Threads)
   if(TARGET OpenMP::OpenMP_CXX)
     target_link_libraries(${_name} OpenMP::OpenMP_CXX)
   endif()
@@ -251,6 +251,11 @@ function(PCL_ADD_LIBRARY _name)
           RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT pcl_${ADD_LIBRARY_OPTION_COMPONENT}
           LIBRARY DESTINATION ${LIB_INSTALL_DIR} COMPONENT pcl_${ADD_LIBRARY_OPTION_COMPONENT}
           ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT pcl_${ADD_LIBRARY_OPTION_COMPONENT})
+
+  # Copy PDB if available
+  if(MSVC AND PCL_SHARED_LIBS)
+    install(FILES $<TARGET_PDB_FILE:${_name}> DESTINATION ${BIN_INSTALL_DIR} OPTIONAL)
+  endif()
 endfunction()
 
 ###############################################################################
@@ -265,16 +270,14 @@ function(PCL_CUDA_ADD_LIBRARY _name)
   cmake_parse_arguments(ADD_LIBRARY_OPTION "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
   REMOVE_VTK_DEFINITIONS()
-  if(PCL_SHARED_LIBS)
-    # to overcome a limitation in cuda_add_library, we add manually PCLAPI_EXPORTS macro
-    cuda_add_library(${_name} ${PCL_LIB_TYPE} ${ADD_LIBRARY_OPTION_SOURCES} OPTIONS -DPCLAPI_EXPORTS)
-  else()
-    cuda_add_library(${_name} ${PCL_LIB_TYPE} ${ADD_LIBRARY_OPTION_SOURCES})
-  endif()
+
+  add_library(${_name} ${PCL_LIB_TYPE} ${ADD_LIBRARY_OPTION_SOURCES})
+
   PCL_ADD_VERSION_INFO(${_name})
 
-  # must link explicitly against boost.
-  target_link_libraries(${_name} ${Boost_LIBRARIES})
+  target_compile_options(${_name} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: ${GEN_CODE} --expt-relaxed-constexpr>)
+
+  target_include_directories(${_name} PRIVATE ${CUDA_TOOLKIT_INCLUDE})
 
   set_target_properties(${_name} PROPERTIES
     VERSION ${PCL_VERSION}
@@ -306,8 +309,8 @@ function(PCL_ADD_EXECUTABLE _name)
     add_executable(${_name} ${ADD_LIBRARY_OPTION_SOURCES})
   endif()
   PCL_ADD_VERSION_INFO(${_name})
-  # must link explicitly against boost.
-  target_link_libraries(${_name} ${Boost_LIBRARIES} Threads::Threads)
+  
+  target_link_libraries(${_name} Threads::Threads)
 
   if(WIN32 AND MSVC)
     set_target_properties(${_name} PROPERTIES DEBUG_OUTPUT_NAME ${_name}${CMAKE_DEBUG_POSTFIX}
@@ -346,11 +349,14 @@ function(PCL_CUDA_ADD_EXECUTABLE _name)
   cmake_parse_arguments(ADD_LIBRARY_OPTION "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
   REMOVE_VTK_DEFINITIONS()
-  cuda_add_executable(${_name} ${ADD_LIBRARY_OPTION_SOURCES})
+  
+  add_executable(${_name} ${ADD_LIBRARY_OPTION_SOURCES})
+  
   PCL_ADD_VERSION_INFO(${_name})
 
-  # must link explicitly against boost.
-  target_link_libraries(${_name} ${Boost_LIBRARIES})
+  target_compile_options(${_name} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: ${GEN_CODE} --expt-relaxed-constexpr>)
+  
+  target_include_directories(${_name} PRIVATE ${CUDA_TOOLKIT_INCLUDE})
 
   if(WIN32 AND MSVC)
     set_target_properties(${_name} PROPERTIES DEBUG_OUTPUT_NAME ${_name}${CMAKE_DEBUG_POSTFIX}
@@ -387,9 +393,6 @@ macro(PCL_ADD_TEST _name _exename)
 
   target_link_libraries(${_exename} Threads::Threads)
 
-  # must link explicitly against boost only on Windows
-  target_link_libraries(${_exename} ${Boost_LIBRARIES})
-
   #Only applies to MSVC
   if(MSVC)
     #Requires CMAKE version 3.13.0
@@ -506,7 +509,7 @@ endmacro()
 ###############################################################################
 # Make a pkg-config file for a library. Do not include general PCL stuff in the
 # arguments; they will be added automatically.
-# _name The library name. "pcl_" will be preprended to this.
+# _name The library name. Please prepend "pcl_" to ensure no conflicts in user systems
 # COMPONENT The part of PCL that this pkg-config file belongs to.
 # DESC Description of the library.
 # PCL_DEPS External dependencies to pcl libs, as a list. (will get mangled to external pkg-config name)
index cc5a4a504d117ecb4a6423a940d38e249aec0c5a..2ef82d370a85e56be09959981b9531444fcf3d26 100644 (file)
@@ -175,6 +175,8 @@ set(LIB_NAME "pcl_${SUBSYS_NAME}")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
 PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${kissfft_srcs} ${incs} ${common_incs} ${impl_incs} ${tools_incs} ${kissfft_incs} ${common_incs_impl} ${range_image_incs} ${range_image_incs_impl})
 
+target_link_libraries(${LIB_NAME} Boost::boost)
+
 if(MSVC AND NOT (MSVC_VERSION LESS 1915))
   # MSVC resolved a byte alignment issue in compiler version 15.9
   # We get this due to using Eigen objects and allocating those objects with make_shared
index 70339feed48e0de132e88875e5c82e369b2a2be8..15b079a19fa8c2452f80f2ddabe0407f47034a6b 100644 (file)
@@ -249,7 +249,7 @@ namespace pcl
                                                 const Eigen::Vector3f& origin, 
                                                 Eigen::Affine3f& transformation);
 
-  /** \brief Extract the Euler angles (XYZ-convention) from the given transformation
+  /** \brief Extract the Euler angles (intrinsic rotations, ZYX-convention) from the given transformation
     * \param[in] t the input transformation matrix
     * \param[in] roll the resulting roll angle
     * \param[in] pitch the resulting pitch angle
@@ -259,7 +259,7 @@ namespace pcl
   template <typename Scalar> void
   getEulerAngles (const Eigen::Transform<Scalar, 3, Eigen::Affine> &t, Scalar &roll, Scalar &pitch, Scalar &yaw);
 
-  /** Extract x,y,z and the Euler angles (XYZ-convention) from the given transformation
+  /** Extract x,y,z and the Euler angles (intrinsic rotations, ZYX-convention) from the given transformation
     * \param[in] t the input transformation matrix
     * \param[out] x the resulting x translation
     * \param[out] y the resulting y translation
@@ -274,7 +274,7 @@ namespace pcl
                                 Scalar &x, Scalar &y, Scalar &z,
                                 Scalar &roll, Scalar &pitch, Scalar &yaw);
 
-  /** \brief Create a transformation from the given translation and Euler angles (XYZ-convention)
+  /** \brief Create a transformation from the given translation and Euler angles (intrinsic rotations, ZYX-convention)
     * \param[in] x the input x translation
     * \param[in] y the input y translation
     * \param[in] z the input z translation
@@ -302,7 +302,7 @@ namespace pcl
     return (getTransformation<double> (x, y, z, roll, pitch, yaw, t));
   }
 
-  /** \brief Create a transformation from the given translation and Euler angles (XYZ-convention)
+  /** \brief Create a transformation from the given translation and Euler angles (intrinsic rotations, ZYX-convention)
     * \param[in] x the input x translation
     * \param[in] y the input y translation
     * \param[in] z the input z translation
index 7cf88a6766f83e2aa0244af08e0d318d6fdd848c..9f932b97ecff82e0e8ec545f310550f545822fcf 100644 (file)
@@ -486,8 +486,14 @@ computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
                                 Eigen::Matrix<Scalar, 3, 3> &covariance_matrix,
                                 Eigen::Matrix<Scalar, 4, 1> &centroid)
 {
+  // Shifted data/with estimate of mean. This gives very good accuracy and good performance.
   // create the buffer on the stack which is much faster than using cloud[indices[i]] and centroid as a buffer
   Eigen::Matrix<Scalar, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<Scalar, 1, 9, Eigen::RowMajor>::Zero ();
+  Eigen::Matrix<Scalar, 3, 1> K(0.0, 0.0, 0.0);
+  for(const auto& point: cloud)
+    if(isFinite(point)) {
+      K.x() = point.x; K.y() = point.y; K.z() = point.z; break;
+    }
   std::size_t point_count;
   if (cloud.is_dense)
   {
@@ -495,15 +501,16 @@ computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
     // For each point in the cloud
     for (const auto& point: cloud)
     {
-      accu [0] += point.x * point.x;
-      accu [1] += point.x * point.y;
-      accu [2] += point.x * point.z;
-      accu [3] += point.y * point.y; // 4
-      accu [4] += point.y * point.z; // 5
-      accu [5] += point.z * point.z; // 8
-      accu [6] += point.x;
-      accu [7] += point.y;
-      accu [8] += point.z;
+      Scalar x = point.x - K.x(), y = point.y - K.y(), z = point.z - K.z();
+      accu [0] += x * x;
+      accu [1] += x * y;
+      accu [2] += x * z;
+      accu [3] += y * y;
+      accu [4] += y * z;
+      accu [5] += z * z;
+      accu [6] += x;
+      accu [7] += y;
+      accu [8] += z;
     }
   }
   else
@@ -514,23 +521,23 @@ computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
       if (!isFinite (point))
         continue;
 
-      accu [0] += point.x * point.x;
-      accu [1] += point.x * point.y;
-      accu [2] += point.x * point.z;
-      accu [3] += point.y * point.y;
-      accu [4] += point.y * point.z;
-      accu [5] += point.z * point.z;
-      accu [6] += point.x;
-      accu [7] += point.y;
-      accu [8] += point.z;
+      Scalar x = point.x - K.x(), y = point.y - K.y(), z = point.z - K.z();
+      accu [0] += x * x;
+      accu [1] += x * y;
+      accu [2] += x * z;
+      accu [3] += y * y;
+      accu [4] += y * z;
+      accu [5] += z * z;
+      accu [6] += x;
+      accu [7] += y;
+      accu [8] += z;
       ++point_count;
     }
   }
-  accu /= static_cast<Scalar> (point_count);
   if (point_count != 0)
   {
-    //centroid.head<3> () = accu.tail<3> ();    -- does not compile with Clang 3.0
-    centroid[0] = accu[6]; centroid[1] = accu[7]; centroid[2] = accu[8];
+    accu /= static_cast<Scalar> (point_count);
+    centroid[0] = accu[6] + K.x(); centroid[1] = accu[7] + K.y(); centroid[2] = accu[8] + K.z();
     centroid[3] = 1;
     covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
     covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
@@ -552,24 +559,30 @@ computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
                                 Eigen::Matrix<Scalar, 3, 3> &covariance_matrix,
                                 Eigen::Matrix<Scalar, 4, 1> &centroid)
 {
+  // Shifted data/with estimate of mean. This gives very good accuracy and good performance.
   // create the buffer on the stack which is much faster than using cloud[indices[i]] and centroid as a buffer
   Eigen::Matrix<Scalar, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<Scalar, 1, 9, Eigen::RowMajor>::Zero ();
+  Eigen::Matrix<Scalar, 3, 1> K(0.0, 0.0, 0.0);
+  for(const auto& index : indices)
+    if(isFinite(cloud[index])) {
+      K.x() = cloud[index].x; K.y() = cloud[index].y; K.z() = cloud[index].z; break;
+    }
   std::size_t point_count;
   if (cloud.is_dense)
   {
     point_count = indices.size ();
     for (const auto &index : indices)
     {
-      //const PointT& point = cloud[*iIt];
-      accu [0] += cloud[index].x * cloud[index].x;
-      accu [1] += cloud[index].x * cloud[index].y;
-      accu [2] += cloud[index].x * cloud[index].z;
-      accu [3] += cloud[index].y * cloud[index].y;
-      accu [4] += cloud[index].y * cloud[index].z;
-      accu [5] += cloud[index].z * cloud[index].z;
-      accu [6] += cloud[index].x;
-      accu [7] += cloud[index].y;
-      accu [8] += cloud[index].z;
+      Scalar x = cloud[index].x - K.x(), y = cloud[index].y - K.y(), z = cloud[index].z - K.z();
+      accu [0] += x * x;
+      accu [1] += x * y;
+      accu [2] += x * z;
+      accu [3] += y * y;
+      accu [4] += y * z;
+      accu [5] += z * z;
+      accu [6] += x;
+      accu [7] += y;
+      accu [8] += z;
     }
   }
   else
@@ -581,34 +594,34 @@ computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
         continue;
 
       ++point_count;
-      accu [0] += cloud[index].x * cloud[index].x;
-      accu [1] += cloud[index].x * cloud[index].y;
-      accu [2] += cloud[index].x * cloud[index].z;
-      accu [3] += cloud[index].y * cloud[index].y; // 4
-      accu [4] += cloud[index].y * cloud[index].z; // 5
-      accu [5] += cloud[index].z * cloud[index].z; // 8
-      accu [6] += cloud[index].x;
-      accu [7] += cloud[index].y;
-      accu [8] += cloud[index].z;
+      Scalar x = cloud[index].x - K.x(), y = cloud[index].y - K.y(), z = cloud[index].z - K.z();
+      accu [0] += x * x;
+      accu [1] += x * y;
+      accu [2] += x * z;
+      accu [3] += y * y;
+      accu [4] += y * z;
+      accu [5] += z * z;
+      accu [6] += x;
+      accu [7] += y;
+      accu [8] += z;
     }
   }
 
-  accu /= static_cast<Scalar> (point_count);
-  //Eigen::Vector3f vec = accu.tail<3> ();
-  //centroid.head<3> () = vec;//= accu.tail<3> ();
-  //centroid.head<3> () = accu.tail<3> ();    -- does not compile with Clang 3.0
-  centroid[0] = accu[6]; centroid[1] = accu[7]; centroid[2] = accu[8];
-  centroid[3] = 1;
-  covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
-  covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
-  covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
-  covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
-  covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
-  covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
-  covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
-  covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
-  covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
-
+  if (point_count != 0)
+  {
+    accu /= static_cast<Scalar> (point_count);
+    centroid[0] = accu[6] + K.x(); centroid[1] = accu[7] + K.y(); centroid[2] = accu[8] + K.z();
+    centroid[3] = 1;
+    covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
+    covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
+    covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
+    covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
+    covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
+    covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
+    covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
+    covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
+    covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
+  }
   return (static_cast<unsigned int> (point_count));
 }
 
index 7933a09016bbaafb3e3b443da16afd4c477fd818..f60d78bb19fc614669d8b2043ade4a23ca284e25 100644 (file)
@@ -173,8 +173,7 @@ namespace pcl
     cloud.is_dense = msg.is_dense == 1;
 
     // Copy point data
-    std::uint32_t num_points = msg.width * msg.height;
-    cloud.resize (num_points);
+    cloud.resize (msg.width * msg.height);
     std::uint8_t* cloud_data = reinterpret_cast<std::uint8_t*>(&cloud[0]);
 
     // Check if we can copy adjacent points in a single memcpy.  We can do so if there
@@ -186,7 +185,7 @@ namespace pcl
         field_map[0].size == msg.point_step &&
         field_map[0].size == sizeof(PointT))
     {
-      std::uint32_t cloud_row_step = static_cast<std::uint32_t> (sizeof (PointT) * cloud.width);
+      const auto cloud_row_step = (sizeof (PointT) * cloud.width);
       const std::uint8_t* msg_data = &msg.data[0];
       // Should usually be able to copy all rows at once
       if (msg.row_step == cloud_row_step)
@@ -195,7 +194,7 @@ namespace pcl
       }
       else
       {
-        for (std::uint32_t i = 0; i < msg.height; ++i, cloud_data += cloud_row_step, msg_data += msg.row_step)
+        for (uindex_t i = 0; i < msg.height; ++i, cloud_data += cloud_row_step, msg_data += msg.row_step)
           memcpy (cloud_data, msg_data, cloud_row_step);
       }
 
@@ -203,10 +202,10 @@ namespace pcl
     else
     {
       // If not, memcpy each group of contiguous fields separately
-      for (index_t row = 0; row < msg.height; ++row)
+      for (uindex_t row = 0; row < msg.height; ++row)
       {
         const std::uint8_t* row_data = &msg.data[row * msg.row_step];
-        for (index_t col = 0; col < msg.width; ++col)
+        for (uindex_t col = 0; col < msg.width; ++col)
         {
           const std::uint8_t* msg_data = row_data + col * msg.point_step;
           for (const detail::FieldMapping& mapping : field_map)
@@ -265,7 +264,7 @@ namespace pcl
 
     msg.header     = cloud.header;
     msg.point_step = sizeof (PointT);
-    msg.row_step   = static_cast<std::uint32_t> (sizeof (PointT) * msg.width);
+    msg.row_step   = (sizeof (PointT) * msg.width);
     msg.is_dense   = cloud.is_dense;
     /// @todo msg.is_bigendian = ?;
   }
@@ -326,13 +325,13 @@ namespace pcl
       msg.height = cloud.height;
       msg.width = cloud.width;
     }
-    int rgb_offset = cloud.fields[rgb_index].offset;
-    int point_step = cloud.point_step;
+    auto rgb_offset = cloud.fields[rgb_index].offset;
+    const auto point_step = cloud.point_step;
 
     // pcl::image_encodings::BGR8;
     msg.header = cloud.header;
     msg.encoding = "bgr8";
-    msg.step = static_cast<std::uint32_t>(msg.width * sizeof (std::uint8_t) * 3);
+    msg.step = (msg.width * sizeof (std::uint8_t) * 3);
     msg.data.resize (msg.step * msg.height);
 
     for (std::size_t y = 0; y < cloud.height; y++)
index df9c7d410d20ff293683989e4a91476dbce83842..cad1d39f4f1c01030331d517f24f1dce598c7177 100644 (file)
@@ -136,7 +136,7 @@ pcl::FeatureHistogram::getMeanValue ()
                      0.25f * histogram_[histogram_.size () - 2] * 2.0f;
   if (last_value > max)
   {
-    max_idx = histogram_.size ();
+    max_idx = histogram_.size () - 1;
   }
 
   // Compute mean value.
index a996887d9496875050fd4c702aa9259ea86d1c98..a48514a04632cf6f2e50ddf8d29c138562d4a74a 100644 (file)
@@ -252,7 +252,7 @@ void kf_work(
     // top-level (not recursive)
     if (fstride==1 && p<=5)
     {
-        int k;
+        int k=0;
 
         // execute the p different work units in different threads
 // We cannot use OPENMP_LEGACY_CONST_DATA_SHARING_RULE here, because we cannot include
index b5775afe577e449558ff79802b270ebcf2a56161..e7a2ff2a8f45252bf6047f1ec14e1b8d7efebc6c 100644 (file)
@@ -29,10 +29,10 @@ set(common_incs
     )
 
 include_directories(./include)
-#set(LIB_NAME pcl_${SUBSYS_NAME})
+set(LIB_NAME "pcl_${SUBSYS_NAME}")
 set(EXT_DEPS CUDA)
-#PCL_MAKE_PKGCONFIG(${LIB_NAME} ${SUBSYS_NAME} "${SUBSYS_DESC}"
-#    "${SUBSYS_DEPS}" "${EXT_DEPS}" "" "" "")
+PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC "${SUBSYS_DESC}"
+    PCL_DEPS "${SUBSYS_DEPS}" EXT_DEPS "" HEADER_ONLY)
 
 # Install include files
 PCL_ADD_INCLUDES(${SUBSYS_NAME} "cuda" ${incs})
index 416fc88dd56b18e2bebfb675b8d159d5c8d444ec..cb63d76cf6c29ab8d37f3d054b9177df9babd256 100644 (file)
@@ -123,8 +123,14 @@ namespace pcl_cuda
         * returned (true) or inside (false). 
         * \param limit_negative the limit_negative flag
         */
+      PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
       inline void 
       getFilterLimitsNegative (bool &limit_negative) { limit_negative = filter_limit_negative_; }
+
+      /** \brief Get whether the data outside the interval (min/max) is to be
+        * returned (true) or inside (false). 
+        * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
+        */
       inline bool 
       getFilterLimitsNegative () { return (filter_limit_negative_); }
 
index 39c207bac17ea56bcd8b48dee2d4bd3c764a62e1..f54b3a195ad61d579028442fb39fcb8efa000ee4 100644 (file)
@@ -35,6 +35,8 @@
 
 #pragma once
 
+PCL_DEPRECATED_HEADER(1, 16, "The CUDA VoxelGrid filter does not work. Use the CPU VoxelGrid filter instead.")
+
 #include <pcl_cuda/filters/filter.h>
 #include <pcl_cuda/filters/passthrough.h>
 #include <thrust/count.h>
index 2753d7ee96d06318931a1851ffe9036aba70de60..5842a23a1fa64219750084a912a0b9076a9decc2 100644 (file)
@@ -4,7 +4,7 @@
 # -- General configuration -----------------------------------------------------
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.imgmath', 'sphinxcontrib.doxylink.doxylink']
+extensions = ['sphinx.ext.imgmath', 'sphinxcontrib.doxylink']
 
 # Add any paths that contain templates here, relative to this directory.
 # templates_path = ['_templates']
@@ -126,4 +126,4 @@ needs_sphinx = '1.0'
 file_insertion_enabled = True
 raw_enabled = True
 # Set up doxylink
-doxylink = {'pcl' : ('../../../build/doc/doxygen/pcl.tag', 'http://docs.pointclouds.org/trunk/')}
+doxylink = {'pcl' : ('../../../s/doc/doxygen/pcl.tag', 'https://pointclouds.org/documentation/')}
index 03f46b6958da0a8b158f90d12a110c102131f33c..bf23e751b29a6d1f2dfb4653c7bb96fc8cccab18 100644 (file)
@@ -1,2 +1,2 @@
-sphinx
+sphinx>=3
 sphinxcontrib-doxylink
index 7acb5cdc9a5e350abcbd64acf1f68653734997b1..530c2a94c65cb1afb4064b7c962a9704f1f74893 100644 (file)
@@ -830,12 +830,12 @@ data (SSE padded), together with a test float.
    #include <pcl/point_cloud.h>
    #include <pcl/io/pcd_io.h>
 
-   struct MyPointType
+   struct EIGEN_ALIGN16 MyPointType    // enforce SSE padding for correct memory alignment
    {
      PCL_ADD_POINT4D;                  // preferred way of adding a XYZ+padding
      float test;
      PCL_MAKE_ALIGNED_OPERATOR_NEW     // make sure our new allocators are aligned
-   } EIGEN_ALIGN16;                    // enforce SSE padding for correct memory alignment
+   };
 
    POINT_CLOUD_REGISTER_POINT_STRUCT (MyPointType,           // here we assume a XYZ + "test" (as fields)
                                       (float, x, x)
index 6eaf69bcdfd59f121baa7c60d976229d0218647a..413d95b8110f1e6ff18a8b3a90c0a86645147d03 100644 (file)
@@ -4,7 +4,7 @@
 # -- General configuration -----------------------------------------------------
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.imgmath', 'sphinxcontrib.doxylink.doxylink']
+extensions = ['sphinx.ext.imgmath', 'sphinxcontrib.doxylink']
 imgmath_dvipng_args = ['-gamma', '1.5', '-D', '110', '-bg', 'Transparent']
 
 # Add any paths that contain templates here, relative to this directory.
@@ -128,4 +128,4 @@ file_insertion_enabled = True
 raw_enabled = True
 
 # Set up doxylink
-doxylink = {'pcl' : ('../../../build/doc/doxygen/pcl.tag', 'http://docs.pointclouds.org/trunk/')}
+doxylink = {'pcl' : ('../../../s/doc/doxygen/pcl.tag', 'https://pointclouds.org/documentation/')}
index 5331cfe932a1afc5508bca8ba6568f3c35b45abb..67f436e2073651f092b3f3600adbd04620602e33 100644 (file)
@@ -10,7 +10,7 @@ For each cluster, representing a possible model instance in the scene, the Corre
 The code
 --------
 
-Before you begin, you should download the PCD dataset used in this tutorial from GitHub (`milk.pcd <https://github.com/PointCloudLibrary/pcl/blob/master/test/milk.pcd?raw=true>`_ and
+Before you begin, you should download the PCD dataset used in this tutorial from GitHub (`milk.pcd <https://github.com/PointCloudLibrary/data/blob/master/tutorials/correspondence_grouping/milk.pcd?raw=true>`_ and
 `milk_cartoon_all_small_clorox.pcd <https://github.com/PointCloudLibrary/pcl/blob/master/test/milk_cartoon_all_small_clorox.pcd?raw=true>`_) and put the files in a folder of your convenience.
 
 Also, copy and paste the following code into your editor and save it as ``correspondence_grouping.cpp`` (or download the source file :download:`here <./sources/correspondence_grouping/correspondence_grouping.cpp>`).
@@ -177,7 +177,7 @@ After you have created the executable, you can then launch it following this exa
   
 Or, alternatively, if you prefer specifying the radii in units of cloud resolution::
 
-  $ ./correspondence_grouping milk.pcd milk_cartoon_all_small_clorox.pcd milk.pcd milk_cartoon_all_small_clorox.pcd -r --model_ss 7.5 --scene_ss 20 --rf_rad 10 --descr_rad 15 --cg_size 10
+  $ ./correspondence_grouping milk.pcd milk_cartoon_all_small_clorox.pcd -r --model_ss 7.5 --scene_ss 20 --rf_rad 10 --descr_rad 15 --cg_size 10
   
 Remember to replace ``milk.pcd`` and ``milk_cartoon_all_small_clorox.pcd`` with model and scene filenames, in this exact order. If you want you can add other command line options as described at the beginning of this tutorial.
 
@@ -195,12 +195,14 @@ After a few seconds, you will see an output similar to::
     Instance 1:
       Correspondences belonging to this instance: 24
 
-          |  0.969 -0.120  0.217 |
-      R = |  0.117  0.993  0.026 |
-          | -0.218 -0.000  0.976 |
+          |  0.968 -0.148  0.201 |
+      R = | -0.146 -0.989 -0.023 |
+          |  0.202 -0.007 -0.979 |
 
-      t = < -0.159, 0.212, -0.042 >
+      t = < -0.171, -0.204, 0.043 >
          
+You may see warnings about invalid reference frames (this can happen if a keypoint does not have enough other points in its neighborhood). If these warnings are only displayed for few points and the results look good otherwise, you can ignore them, else you should try to adapt the parameters.
+
 The output window should look like this (depending on the command line options used):
 
 .. image:: images/correspondence_grouping/correspondence_grouping.jpg
index b28eae96ee42dd3789b368a860b08248828a00c0..3c621d27186719142599c9b3f856ad560d4e652b 100644 (file)
@@ -27,7 +27,7 @@ You need at least PCL 1.8.0 to be able to use the davidSDK. You need to make sur
 
 The default following values can be tweaked into CMake if you don't have a standard installation, for example:
 
-.. code-block:: cmake
+.. code-block::
 
   DAVIDSDK_ABI_DIR     /opt/davidsdk
 
index a922b33c8cf7a40a8f75f9ff41855835bdd47ab6..43795791aea91379ad376834dc8febee30a04b2d 100644 (file)
@@ -70,7 +70,7 @@ Basic Usage
   * :ref:`compiling_pcl_posix`
 
      =======  ======
-     |mi_11|  Title: **Compiling PCL from source on POSIX compliant systems**
+     |mi_12|  Title: **Compiling PCL from source on POSIX compliant systems**
 
               Author: *Victor Lamoine*
 
@@ -79,7 +79,7 @@ Basic Usage
               In this tutorial, we will explain how to compile PCL from sources on POSIX/Unix systems.
      =======  ======
 
-     .. |mi_11| image:: images/pcl_logo.png
+     .. |mi_12| image:: images/pcl_logo.png
                :height: 120px
 
   * :ref:`building_pcl`
index 1baccd42697bcedf9f11489fe1787eedf292cb87..8cbaf64c958aba6b520071c630309ec5cfdbbf76 100644 (file)
@@ -60,13 +60,13 @@ pclviewer.h
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.h
    :language: cpp
-   :lines: 41-56
+   :lines: 38-53
 
 These are the public slots triggered by the buttons in the UI.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.h
    :language: cpp
-   :lines: 58-85
+   :lines: 55-87
 
 These are the protected members of our class;
   * ``viewer_`` is the visualizer object
@@ -80,65 +80,65 @@ pclviewer.cpp
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 4-8
+   :lines: 8-12
 
 We initialize the members of our class to default values (note that theses values should match with the UI buttons ticked)
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 9-24
+   :lines: 13-28
 
 Here we initialize the UI, window title and generate a random point cloud (500 points), note we don't care about the color for now.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 26-31
+   :lines: 30-42
 
 Here we set up the QVTK window.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 33-46
+   :lines: 44-57
 
 At this point we connect SLOTS and their functions to ensure that each UI elements has an use.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 48-52
+   :lines: 59-65
 
 We call the coloring function, add the point cloud and refresh the QVTK viewer.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 60-98
+   :lines: 83-122
 
 This functions deals with opening files, it supports both ``pcd`` and ``ply`` files.
 The LUT computing will only work if the point cloud is dense (only finite values) so we remove NaN values from the point cloud if needed.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 100-127
+   :lines: 124-151
 
 | This functions deals with saving the displayed file, it supports both ``pcd`` and ``ply`` files.
 | As said before, if the user doesn't append an extension to the file name, ``ply`` will be automatically added.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 129-152
+   :lines: 153-177
 
 This function is called whenever one of the three radio buttons X,Y,Z are clicked, it determines which radio button is clicked and changes
 the ``filtering_axis_`` member accordingly.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 154-187
+   :lines: 179-213
 
 This function is called whenever one of the radio buttons in the color list is clicked, the ``color_mode_`` member is modified accordingly.
 We also call the coloring function and update the cloud / QVTK widget.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 189-209
+   :lines: 215-235
 
 | This is the core function of the application. We are going to color the cloud following a color scheme.
 The point cloud is going to be colored following one direction, we first need to know where it starts and where it ends 
@@ -147,13 +147,13 @@ The point cloud is going to be colored following one direction, we first need to
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 211-238
+   :lines: 237-264
 
 We then loop through the whole cloud to find the minimum and maximum values.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 239-244
+   :lines: 266-271
 
 Here we compute the scaling, RGB values are coded from 0 to 255 (as integers), we need to scale our distances so that the 
 minimum distance equals 0 (in RGB scale) and the maximum distance 255 (in RGB scale).
@@ -161,14 +161,14 @@ The ``if`` condition is here in case of a perfectly flat point cloud and avoids
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 246-260
+   :lines: 274-286
 
 We have computed how much we need to scale the distances to fit the RGB scale, we first need to round the ``double`` values to the closest ``integer``
 because colors are coded as integers.
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 262-270
+   :lines: 288-296
 
 This is where we apply the color level we have computed to the point cloud R,G,B values.
 You can do whatever you want here, the simplest option is to apply the 3 channels (R,G,B) to the ``value`` computed, this means that the 
@@ -176,7 +176,7 @@ minimum distance will translate into dark (black = 0,0,0) points and maximal dis
 
 .. literalinclude:: sources/qt_colorize_cloud/pclviewer.cpp
    :language: cpp
-   :lines: 271-305
+   :lines: 297-331
 
 These are examples of coloring schemes, if you are wondering how it works, simply plot the computed values into a spreadsheet software.
 
index 1fe2f19e466f9f9e506666cc02d6b51fbbafee06..08c2b75d187c4be69ccb8781640bd69c933b1e10 100644 (file)
@@ -101,7 +101,7 @@ pclviewer.h
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.h
    :language: cpp
-   :lines: 1-17
+   :lines: 1-14
 
 This file is the header for the class PCLViewer; we include ``QMainWindow`` because this class contains UI elements, we include the PCL headers we will 
 be using and the VTK header for the ``qvtkWidget``. We also define typedefs of the point types and point clouds, this improves readabily.
@@ -109,32 +109,32 @@ be using and the VTK header for the ``qvtkWidget``. We also define typedefs of t
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.h
    :language: cpp
-   :lines: 19-22
+   :lines: 16-19
 
 We declare the namespace ``Ui`` and the class PCLViewer inside it.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.h
    :language: cpp
-   :lines: 24-26
+   :lines: 21-23
 
 This is the definition of the PCLViewer class; the macro ``Q_OBJECT`` tells the compiler that this object contains UI elements;
 this imply that this file will be processed through `the Meta-Object Compiler (moc) <http://qt-project.org/doc/qt-4.8/moc.html>`_.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.h
    :language: cpp
-   :lines: 28-30
+   :lines: 25-27
 
 The constructor and destructor of the PCLViewer class.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.h
    :language: cpp
-   :lines: 32-49
+   :lines: 29-46
 
 These are the public slots; these functions will be linked with UI elements actions.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.h
    :language: cpp
-   :lines: 51-57
+   :lines: 48-57
 
 | A boost shared pointer to a PCLVisualier and a pointer to a point cloud are defined here.
 | The integers ``red``, ``green``, ``blue`` will help us store the value of the sliders.
@@ -144,7 +144,7 @@ pclviewer.cpp
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 1-14
+   :lines: 1-18
 
 We include the class header and the header for the UI object; note that this file is generated by the moc and it's path depend on 
 where you call cmake !
@@ -155,25 +155,23 @@ After that is the constructor implementation; we setup the ui and the window tit
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 16-31
+   :lines: 10-35
 
 | ``red`` ``green`` and ``blue`` protected members are initialized to their default values.
 | The cloud is filled with random points (in a cube) and accordingly to ``red`` ``green`` and ``blue`` colors.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 33-37
+   :lines: 37-49
 
 | Here we create a PCL Visualizer name ``viewer`` and we also specify that we don't want an interactor to be created.
 | We don't want an interactor to be created because our ``qvtkWidget`` is already an interactor and it's the one we want to use.
 | So the next step is to configure our newly created PCL Visualiser interactor to use the ``qvtkWidget``.
 
-The ``update()`` method of the ``qvtkWidget`` should be called each time you modify the PCL visualizer; if you don't call it you don't know if the 
-visualizer will be updated before the user try to pan/spin/zoom.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 39-51
+   :lines: 51-63
 
 Here we connect slots and signals, this links UI actions to functions. Here is a summary of what we have linked :
   * ``pushButton_random``:  
@@ -190,16 +188,16 @@ Here we connect slots and signals, this links UI actions to functions. Here is a
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 53-57
+   :lines: 65-69
 
 | This is the last part of our constructor; we add the point cloud to the visualizer, call the method ``pSliderValueChanged`` to change the point size to 2.
 
-We finally reset the camera within the PCL Visualizer not avoid the user having to zoom out and update the qvtkwidget to be 
+We finally reset the camera within the PCL Visualizer not avoid the user having to zoom out and refesh the view to be 
 sure the modifications will be displayed.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 59-74
+   :lines: 72-87
 
 | This is the public slot function member called when the push button "Random" is pressed.
 | The ``for`` loop iterates through the point cloud and changes point cloud color to a random number (between 0 and 255).
@@ -207,7 +205,7 @@ sure the modifications will be displayed.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 76-88
+   :lines: 89-101
 
 | This is the public slot function member called whenever the red, green or blue slider is released
 | The ``for`` loop iterates through the point cloud and changes point cloud color to ``red``, ``green`` and ``blue`` member values.
@@ -215,7 +213,7 @@ sure the modifications will be displayed.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 97-116
+   :lines: 120-139
 
 | These are the public slot function member called whenever the red, green or blue slider value is changed
 | These functions just changes the member value accordingly to the slider value.
@@ -223,7 +221,7 @@ sure the modifications will be displayed.
 
 .. literalinclude:: sources/qt_visualizer/pclviewer.cpp
    :language: cpp
-   :lines: 118-121
+   :lines: 141-144
 
 The destructor.
 
index c7048d73db866e1376120da10e3aec14b4934001..c31df8cede98a71b7ca677864eab1d05c1e8650d 100644 (file)
@@ -35,9 +35,9 @@ The code
 For this tutorial we will use the model from the Queen's Dataset. You can choose any other point cloud, but in order to make the
 code work you will need to use the triangulation algorithm in order to obtain polygons. You can find the proposed model here:
 
-  * `points <https://github.com/PointCloudLibrary/data/blob/master/tutorials/min_cut_segmentation_tutorial.pcd>`_ - contains the point cloud
-  * `indices - contains indices of the points for which RoPs must be computed
-  * `triangles - contains the polygons
+  * `points <https://github.com/PointCloudLibrary/pcl/blob/master/test/rops_cloud.pcd>`_ - contains the point cloud
+  * `indices <https://github.com/PointCloudLibrary/pcl/blob/master/test/rops_indices.txt>`_ - contains indices of the points for which RoPs must be computed
+  * `triangles <https://github.com/PointCloudLibrary/pcl/blob/master/test/rops_triangles.txt>`_ - contains the polygons
 
 Next what you need to do is to create a file ``rops_feature.cpp`` in any editor you prefer and copy the following code inside of it:
 
index 5ee1dc8125067ae8722c5b0afed879af92456b78..221da6fe07fa040f3c60af87dec70a490cbd0988 100644 (file)
@@ -11,7 +11,13 @@ set(CMAKE_AUTOUIC ON) # UI files
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 # Find the QtWidgets library
-find_package(Qt5 REQUIRED Widgets)
+find_package(Qt6 QUIET COMPONENTS Widgets)
+if (NOT Qt6_FOUND)
+  find_package(Qt5 COMPONENTS Widgets REQUIRED)
+  set(QTX Qt5)
+else()
+  set(QTX Qt6)
+endif()
 
 find_package(VTK REQUIRED)
 find_package(PCL 1.7.1 REQUIRED)
@@ -26,4 +32,4 @@ set(project_SOURCES main.cpp pclviewer.cpp)
 
 add_executable(${PROJECT_NAME} ${project_SOURCES})
 
-target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES} Qt5::Widgets)
+target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES} ${QTX}::Widgets)
index 2a22446b6452511ff84c621aec158481bf4c4a04..fe769046706691ee23fc13161822347d3e0dbdd3 100644 (file)
@@ -1,6 +1,10 @@
 #include "pclviewer.h"
 #include "ui_pclviewer.h"
 
+#if VTK_MAJOR_VERSION > 8
+#include <vtkGenericOpenGLRenderWindow.h>
+#endif
+
 PCLViewer::PCLViewer (QWidget *parent) :
     QMainWindow (parent),
     filtering_axis_ (1),  // = y
@@ -24,11 +28,18 @@ PCLViewer::PCLViewer (QWidget *parent) :
   }
 
   // Set up the QVTK window
-  viewer_.reset (new pcl::visualization::PCLVisualizer ("viewer", false));
-  viewer_->setBackgroundColor (0.1, 0.1, 0.1);
-  ui->qvtkWidget->SetRenderWindow (viewer_->getRenderWindow ());
-  viewer_->setupInteractor (ui->qvtkWidget->GetInteractor (), ui->qvtkWidget->GetRenderWindow ());
-  ui->qvtkWidget->update ();
+#if VTK_MAJOR_VERSION > 8
+  auto renderer = vtkSmartPointer<vtkRenderer>::New();
+  auto renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
+  renderWindow->AddRenderer(renderer);
+  viewer_.reset(new pcl::visualization::PCLVisualizer(renderer, renderWindow, "viewer", false));
+  ui->qvtkWidget->setRenderWindow(viewer_->getRenderWindow());
+  viewer_->setupInteractor(ui->qvtkWidget->interactor(), ui->qvtkWidget->renderWindow());
+#else
+  viewer_.reset(new pcl::visualization::PCLVisualizer("viewer", false));
+  ui->qvtkWidget->SetRenderWindow(viewer_->getRenderWindow());
+  viewer_->setupInteractor(ui->qvtkWidget->GetInteractor(), ui->qvtkWidget->GetRenderWindow());
+#endif
 
   // Connect "Load" and "Save" buttons and their functions
   connect (ui->pushButton_load, SIGNAL(clicked ()), this, SLOT(loadFileButtonPressed ()));
@@ -47,9 +58,11 @@ PCLViewer::PCLViewer (QWidget *parent) :
 
   // Color the randomly generated cloud
   colorCloudDistances ();
+  viewer_->setBackgroundColor (0.1, 0.1, 0.1);
   viewer_->addPointCloud (cloud_, "cloud");
   viewer_->resetCamera ();
-  ui->qvtkWidget->update ();
+
+  refreshView();
 }
 
 PCLViewer::~PCLViewer ()
@@ -57,6 +70,16 @@ PCLViewer::~PCLViewer ()
   delete ui;
 }
 
+void
+PCLViewer::refreshView()
+{
+#if VTK_MAJOR_VERSION > 8
+  ui->qvtkWidget->renderWindow()->Render();
+#else
+  ui->qvtkWidget->update();
+#endif
+}
+
 void
 PCLViewer::loadFileButtonPressed ()
 {
@@ -94,7 +117,8 @@ PCLViewer::loadFileButtonPressed ()
   colorCloudDistances ();
   viewer_->updatePointCloud (cloud_, "cloud");
   viewer_->resetCamera ();
-  ui->qvtkWidget->update ();
+
+  refreshView();
 }
 
 void
@@ -148,7 +172,8 @@ PCLViewer::axisChosen ()
 
   colorCloudDistances ();
   viewer_->updatePointCloud (cloud_, "cloud");
-  ui->qvtkWidget->update ();
+
+  refreshView();
 }
 
 void
@@ -183,7 +208,8 @@ PCLViewer::lookUpTableChosen ()
 
   colorCloudDistances ();
   viewer_->updatePointCloud (cloud_, "cloud");
-  ui->qvtkWidget->update ();
+
+  refreshView();
 }
 
 void
index 20fcd4d3012818fcc5defcc808a92c659394359d..f3b1f8b2814cae3988d00a61b2cb5393c62cd22e 100644 (file)
@@ -15,9 +15,6 @@
 // Boost
 #include <boost/math/special_functions/round.hpp>
 
-// Visualization Toolkit (VTK)
-#include <vtkRenderWindow.h>
-
 typedef pcl::PointXYZRGBA PointT;
 typedef pcl::PointCloud<PointT> PointCloudT;
 
@@ -56,6 +53,10 @@ class PCLViewer : public QMainWindow
     lookUpTableChosen ();
 
   protected:
+    /** @brief Rerender the view */
+    void
+    refreshView();
+    
     /** @brief The PCL visualizer object */
     pcl::visualization::PCLVisualizer::Ptr viewer_;
 
index a36d17af95dc59c6e42d3793adb677cd19b52bbc..3019bf87c42944acccd58a06e8284a31b08bf4eb 100644 (file)
      </layout>
     </item>
     <item>
-     <widget class="QVTKWidget" name="qvtkWidget" native="true">
+     <widget class="PCLQVTKWidget" name="qvtkWidget" native="true">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
         <horstretch>50</horstretch>
  </widget>
  <customwidgets>
   <customwidget>
-   <class>QVTKWidget</class>
-   <extends>QWidget</extends>
-   <header>QVTKWidget.h</header>
+   <class>PCLQVTKWidget</class>
+   <extends>QOpenGLWidget</extends>
+   <header location="global">pcl/visualization/qvtk_compatibility.h</header>
   </customwidget>
  </customwidgets>
  <tabstops>
index e4f3caa8c233ede451c1e1a79a01814317ae2820..96580a1911b515e56fc0db166d5ea36007990254 100644 (file)
@@ -11,7 +11,13 @@ set(CMAKE_AUTOUIC ON) # UI files
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 # Find the QtWidgets library
-find_package(Qt5 REQUIRED Widgets)
+find_package(Qt6 QUIET COMPONENTS Concurrent OpenGL Widgets)
+if (NOT Qt6_FOUND)
+  find_package(Qt5 COMPONENTS Concurrent OpenGL Widgets REQUIRED)
+  set(QTX Qt5)
+else()
+  set(QTX Qt6)
+endif()
 
 find_package(VTK REQUIRED)
 find_package(PCL 1.7.1 REQUIRED)
@@ -26,4 +32,4 @@ set(project_SOURCES main.cpp pclviewer.cpp)
 
 add_executable(${PROJECT_NAME} ${project_SOURCES})
 
-target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES} Qt5::Widgets)
+target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES} ${QTX}::Widgets)
index c2535b854150d08c38481aaa184b27a990183625..82a5fd2a9411a7d2a765bf0088c376e97e2b8b0f 100644 (file)
@@ -1,6 +1,10 @@
 #include "pclviewer.h"
 #include "ui_pclviewer.h"
 
+#if VTK_MAJOR_VERSION > 8
+#include <vtkGenericOpenGLRenderWindow.h>
+#endif
+
 PCLViewer::PCLViewer (QWidget *parent) :
   QMainWindow (parent),
   ui (new Ui::PCLViewer)
@@ -11,7 +15,7 @@ PCLViewer::PCLViewer (QWidget *parent) :
   // Setup the cloud pointer
   cloud.reset (new PointCloudT);
   // The number of points in the cloud
-  cloud->points.resize (200);
+  cloud->resize (200);
 
   // The default color
   red   = 128;
@@ -30,11 +34,19 @@ PCLViewer::PCLViewer (QWidget *parent) :
     point.b = blue;
   }
 
-  // Set up the QVTK window
-  viewer.reset (new pcl::visualization::PCLVisualizer ("viewer", false));
-  ui->qvtkWidget->SetRenderWindow (viewer->getRenderWindow ());
-  viewer->setupInteractor (ui->qvtkWidget->GetInteractor (), ui->qvtkWidget->GetRenderWindow ());
-  ui->qvtkWidget->update ();
+  // Set up the QVTK window  
+#if VTK_MAJOR_VERSION > 8
+  auto renderer = vtkSmartPointer<vtkRenderer>::New();
+  auto renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
+  renderWindow->AddRenderer(renderer);
+  viewer.reset(new pcl::visualization::PCLVisualizer(renderer, renderWindow, "viewer", false));
+  ui->qvtkWidget->setRenderWindow(viewer->getRenderWindow());
+  viewer->setupInteractor(ui->qvtkWidget->interactor(), ui->qvtkWidget->renderWindow());
+#else
+  viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
+  ui->qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
+  viewer->setupInteractor(ui->qvtkWidget->GetInteractor(), ui->qvtkWidget->GetRenderWindow());
+#endif
 
   // Connect "random" button and the function
   connect (ui->pushButton_random,  SIGNAL (clicked ()), this, SLOT (randomButtonPressed ()));
@@ -53,7 +65,8 @@ PCLViewer::PCLViewer (QWidget *parent) :
   viewer->addPointCloud (cloud, "cloud");
   pSliderValueChanged (2);
   viewer->resetCamera ();
-  ui->qvtkWidget->update ();
+  
+  refreshView();
 }
 
 void
@@ -70,7 +83,7 @@ PCLViewer::randomButtonPressed ()
   }
 
   viewer->updatePointCloud (cloud, "cloud");
-  ui->qvtkWidget->update ();
+  refreshView();
 }
 
 void
@@ -84,14 +97,24 @@ PCLViewer::RGBsliderReleased ()
     point.b = blue;
   }
   viewer->updatePointCloud (cloud, "cloud");
-  ui->qvtkWidget->update ();
+  refreshView();
 }
 
 void
 PCLViewer::pSliderValueChanged (int value)
 {
   viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, value, "cloud");
-  ui->qvtkWidget->update ();
+  refreshView();
+}
+
+void
+PCLViewer::refreshView()
+{
+#if VTK_MAJOR_VERSION > 8
+  ui->qvtkWidget->renderWindow()->Render();
+#else
+  ui->qvtkWidget->update();
+#endif
 }
 
 void
index 2c6ca6ec7ce4944c051d1887ee4a3d0d58b34c17..295e3d6cc1faefcf7532949587d447746039ea6f 100644 (file)
@@ -10,9 +10,6 @@
 #include <pcl/point_types.h>
 #include <pcl/visualization/pcl_visualizer.h>
 
-// Visualization Toolkit (VTK)
-#include <vtkRenderWindow.h>
-
 typedef pcl::PointXYZRGBA PointT;
 typedef pcl::PointCloud<PointT> PointCloudT;
 
@@ -49,6 +46,9 @@ public Q_SLOTS:
   blueSliderValueChanged (int value);
 
 protected:
+  void
+  refreshView();
+
   pcl::visualization::PCLVisualizer::Ptr viewer;
   PointCloudT::Ptr cloud;
 
@@ -58,5 +58,4 @@ protected:
 
 private:
   Ui::PCLViewer *ui;
-
 };
index 3f616085ee0d45eccc469635699736e52bf4ba7b..88393ce86d8176be868017ad4e234a92eb52a3a9 100644 (file)
@@ -26,7 +26,7 @@
    <string>PCLViewer</string>
   </property>
   <widget class="QWidget" name="centralwidget">
-   <widget class="QVTKWidget" name="qvtkWidget" native="true">
+   <widget class="PCLQVTKWidget" name="qvtkWidget" native="true">
     <property name="geometry">
      <rect>
       <x>300</x>
  </widget>
  <customwidgets>
   <customwidget>
-   <class>QVTKWidget</class>
-   <extends>QWidget</extends>
-   <header>QVTKWidget.h</header>
+   <class>PCLQVTKWidget</class>
+   <extends>QOpenGLWidget</extends>
+   <header location="global">pcl/visualization/qvtk_compatibility.h</header>
   </customwidget>
  </customwidgets>
  <resources/>
index d042ae616aa1eb2ff4afeb89a82e85ba68e99302..a138fd3c2f66d3f5f03bbfdc0058cab307a6246f 100644 (file)
@@ -205,4 +205,3 @@ before this one:
 .. code-block:: cmake
 
    find_package(PCL 1.3 REQUIRED COMPONENTS common io)
-     ...
index 4c53f0e72bb0a10c98602ac7a8cc77704414a01e..d823ddb84c0f55b2835758c6ac1890349d300dd1 100644 (file)
@@ -252,7 +252,7 @@ enable the build.
     set (srcs
          src/conditional_removal.cpp
          # ...
-         src/bilateral.cpp)
+         src/bilateral.cpp
          )
 
     # Find "set (incs", and add a new entry there, e.g.,
@@ -664,7 +664,7 @@ execution of the code, its value is still 0, we will print an error using the
 In the case of the search method, we can either do the same, or be clever and
 provide a default option for the user. The best default options are:
 
- * use an organized search method via :pcl:`pcl::OrganizedNeighbor<pcl::OrganizedNeighbor>` if the point cloud is organized;
+ * use an organized search method via :pcl:`pcl::search::OrganizedNeighbor<pcl::search::OrganizedNeighbor>` if the point cloud is organized;
  * use a general purpose kdtree via :pcl:`pcl::KdTreeFLANN<pcl::KdTreeFLANN>` if the point cloud is unorganized.
 
 .. code-block:: cpp
index 0d5bba72b3d273e1fc96b7081ae58a426e835268..bd795ee74b978480d33ad58cc6d5a27cc67a167f 100644 (file)
@@ -170,7 +170,7 @@ namespace pcl
       /** \brief Estimate a descriptor for a given point.
         * \param[in] index the index of the point to estimate a descriptor for
         * \param[in] normals a pointer to the set of normals
-        * \param[in] rf the reference frame
+        * \param[out] rf the reference frame
         * \param[out] desc the resultant estimated descriptor
         * \return true if the descriptor was computed successfully, false if there was an error
         * (e.g. the nearest neighbor didn't return any neighbors)
index 3a3a5c287ee30233c1915443cae778653b0cd9ad..d866e9e949117b5e73566ac11b6ce2178c3a3d95 100644 (file)
@@ -156,6 +156,12 @@ pcl::ShapeContext3DEstimation<PointInT, PointNT, PointOutT>::computePoint (
   Vector3fMapConst origin = (*input_)[(*indices_)[index]].getVector3fMap ();
   // Get origin normal
   // Use pre-computed normals
+  if (!pcl::isNormalFinite(normals[minIndex]))
+  {
+    std::fill (desc.begin (), desc.end (), std::numeric_limits<float>::quiet_NaN ());
+    std::fill (rf, rf + 9, 0.f);
+    return (false);
+  }
   normal = normals[minIndex].getNormalVector3fMap ();
 
   // Compute and store the RF direction
index 26c90654eb99afdada9e5f713b7054236f9eefa8..59ed4b5bcc9c6583fc1bd75b3c1647afb7a8cf0f 100644 (file)
@@ -53,7 +53,8 @@ namespace pcl
     using Filter<PointT>::filter_name_;
     using Filter<PointT>::indices_;
     using Filter<PointT>::input_;
-    
+    using Filter<PointT>::removed_indices_;
+
     using PointCloud = typename Filter<PointT>::PointCloud;
     using PointCloudPtr = typename PointCloud::Ptr;
     using PointCloudConstPtr = typename PointCloud::ConstPtr;
@@ -148,15 +149,6 @@ namespace pcl
         */
       Eigen::Vector3f
       getHullCloudRange ();
-      
-      /** \brief Apply the two-dimensional hull filter.
-        * All points are assumed to lie in the same plane as the 2D hull, an
-        * axis-aligned 2D coordinate system using the two dimensions specified
-        * (PlaneDim1, PlaneDim2) is used for calculations.
-        * \param[out] output The set of points that pass the 2D polygon filter.
-        */
-      template<unsigned PlaneDim1, unsigned PlaneDim2> void
-      applyFilter2D (PointCloud &output); 
 
       /** \brief Apply the two-dimensional hull filter.
         * All points are assumed to lie in the same plane as the 2D hull, an
@@ -168,17 +160,6 @@ namespace pcl
       template<unsigned PlaneDim1, unsigned PlaneDim2> void
       applyFilter2D (Indices &indices);
 
-       /** \brief Apply the three-dimensional hull filter.
-         * Polygon-ray crossings are used for three rays cast from each point
-         * being tested, and a  majority vote of the resulting
-         * polygon-crossings is used to decide  whether the point lies inside
-         * or outside the hull.
-         * \param[out] output The set of points that pass the 3D polygon hull
-         *                    filter.
-         */
-      void
-      applyFilter3D (PointCloud &output);
-
       /** \brief Apply the three-dimensional hull filter.
         *  Polygon-ray crossings are used for three rays cast from each point
         *  being tested, and a  majority vote of the resulting
index 6895312a48632f3dfe3db3ccb5b1a8f1dacc7532..3ee170e5ae64026a371504e9ea227c54dc596319 100644 (file)
@@ -557,6 +557,9 @@ Convolution<PointIn, PointOut>::convolve_cols_mirror (PointCloudOut& output)
   }
 }
 
+#define PCL_INSTANTIATE_Convolution(Tin, Tout)                                         \
+  template class PCL_EXPORTS Convolution<Tin, Tout>;
+
 } // namespace filters
 } // namespace pcl
 
index b63bc0ddda3f37d39a7b5bf389c80c7956be5d86..0fac898742de61a71f28a098b6f076eb6c812802 100644 (file)
 
 #include <pcl/filters/crop_hull.h>
 
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<typename PointT> void
+template<typename PointT>
+PCL_DEPRECATED(1, 13, "This is a trivial call to base class method")
+void
 pcl::CropHull<PointT>::applyFilter (PointCloud &output)
 {
-  if (dim_ == 2)
-  {
-    // in this case we are assuming all the points lie in the same plane as the
-    // 2D convex hull, so the choice of projection just changes the
-    // conditioning of the problem: choose to squash the XYZ component of the
-    // hull-points that has least variation - this will also give reasonable
-    // results if the points don't lie exactly in the same plane
-    const Eigen::Vector3f range = getHullCloudRange ();
-    if (range[0] <= range[1] && range[0] <= range[2])
-      applyFilter2D<1,2> (output);
-    else if (range[1] <= range[2] && range[1] <= range[0])
-      applyFilter2D<2,0> (output);
-    else
-      applyFilter2D<0,1> (output);
-  }
-  else
-  {
-    applyFilter3D (output);
-  }
+  FilterIndices<PointT>::applyFilter(output);
 }
 
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 template<typename PointT> void
 pcl::CropHull<PointT>::applyFilter (Indices &indices)
 {
+  indices.clear();
+  removed_indices_->clear();
+  indices.reserve(indices_->size());
+  removed_indices_->reserve(indices_->size());
   if (dim_ == 2)
   {
     // in this case we are assuming all the points lie in the same plane as the
@@ -119,7 +109,7 @@ pcl::CropHull<PointT>::getHullCloudRange ()
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 template<typename PointT> template<unsigned PlaneDim1, unsigned PlaneDim2> void 
-pcl::CropHull<PointT>::applyFilter2D (PointCloud &output)
+pcl::CropHull<PointT>::applyFilter2D (Indices &indices)
 {
   for (std::size_t index = 0; index < indices_->size (); index++)
   {
@@ -133,7 +123,7 @@ pcl::CropHull<PointT>::applyFilter2D (PointCloud &output)
          ))
       {
         if (crop_outside_)
-          output.push_back ((*input_)[(*indices_)[index]]);
+          indices.push_back ((*indices_)[index]);
         // once a point has tested +ve for being inside one polygon, we can
         // stop checking the others:
         break;
@@ -141,38 +131,17 @@ pcl::CropHull<PointT>::applyFilter2D (PointCloud &output)
     }
     // If we're removing points *inside* the hull, only remove points that
     // haven't been found inside any polygons
-    if (poly == hull_polygons_.size () && !crop_outside_)
-      output.push_back ((*input_)[(*indices_)[index]]);
-  }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<typename PointT> template<unsigned PlaneDim1, unsigned PlaneDim2> void 
-pcl::CropHull<PointT>::applyFilter2D (Indices &indices)
-{
-  // see comments in (PointCloud& output) overload
-  for (std::size_t index = 0; index < indices_->size (); index++)
-  {
-    std::size_t poly;
-    for (poly = 0; poly < hull_polygons_.size (); poly++)
-    {
-      if (isPointIn2DPolyWithVertIndices<PlaneDim1,PlaneDim2> (
-              (*input_)[(*indices_)[index]], hull_polygons_[poly], *hull_cloud_
-         ))
-      {
-        if (crop_outside_)      
-          indices.push_back ((*indices_)[index]);
-        break;
-      }
-    }
     if (poly == hull_polygons_.size () && !crop_outside_)
       indices.push_back ((*indices_)[index]);
+    if (indices.empty() || indices.back() != (*indices_)[index]) {
+      removed_indices_->push_back ((*indices_)[index]);
+    }
   }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 template<typename PointT> void 
-pcl::CropHull<PointT>::applyFilter3D (PointCloud &output)
+pcl::CropHull<PointT>::applyFilter3D (Indices &indices)
 {
   // This algorithm could definitely be sped up using kdtree/octree
   // information, if that is available!
@@ -186,33 +155,6 @@ pcl::CropHull<PointT>::applyFilter3D (PointCloud &output)
     // 'random' rays are arbitrary - basically anything that is less likely to
     // hit the edge between polygons than coordinate-axis aligned rays would
     // be.
-    std::size_t crossings[3] = {0,0,0};
-    Eigen::Vector3f rays[3] = 
-    {
-      Eigen::Vector3f (0.264882f,  0.688399f, 0.675237f),
-      Eigen::Vector3f (0.0145419f, 0.732901f, 0.68018f),
-      Eigen::Vector3f (0.856514f,  0.508771f, 0.0868081f)
-    };
-
-    for (std::size_t poly = 0; poly < hull_polygons_.size (); poly++)
-      for (std::size_t ray = 0; ray < 3; ray++)
-        crossings[ray] += rayTriangleIntersect
-          ((*input_)[(*indices_)[index]], rays[ray], hull_polygons_[poly], *hull_cloud_);
-
-    if (crop_outside_ && (crossings[0]&1) + (crossings[1]&1) + (crossings[2]&1) > 1)
-      output.push_back ((*input_)[(*indices_)[index]]);
-    else if (!crop_outside_)
-      output.push_back ((*input_)[(*indices_)[index]]);
-  }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<typename PointT> void 
-pcl::CropHull<PointT>::applyFilter3D (Indices &indices)
-{
-  // see comments in applyFilter3D (PointCloud& output)
-  for (std::size_t index = 0; index < indices_->size (); index++)
-  {
     std::size_t crossings[3] = {0,0,0};
     Eigen::Vector3f rays[3] = 
     {
@@ -230,6 +172,8 @@ pcl::CropHull<PointT>::applyFilter3D (Indices &indices)
       indices.push_back ((*indices_)[index]);
     else if (!crop_outside_)
       indices.push_back ((*indices_)[index]);
+    else
+      removed_indices_->push_back ((*indices_)[index]);
   }
 }
 
index 8b5a30df9fa80e3192a9549a0e99cb98e43cb945..55821a64fd6daf444210373304b2f3a051d0c9e8 100644 (file)
@@ -330,8 +330,9 @@ pcl::VoxelGridCovariance<PointT>::applyFilter (PointCloud &output)
       eigen_val = eigensolver.eigenvalues ().asDiagonal ();
       leaf.evecs_ = eigensolver.eigenvectors ();
 
-      if (eigen_val (0, 0) < 0 || eigen_val (1, 1) < 0 || eigen_val (2, 2) <= 0)
+      if (eigen_val (0, 0) < -Eigen::NumTraits<double>::dummy_precision () || eigen_val (1, 1) < -Eigen::NumTraits<double>::dummy_precision () || eigen_val (2, 2) <= 0)
       {
+        PCL_WARN ("[VoxelGridCovariance::applyFilter] Invalid eigen value! (%g, %g, %g)\n", eigen_val (0, 0), eigen_val (1, 1), eigen_val (2, 2));
         leaf.nr_points = -1;
         continue;
       }
@@ -456,6 +457,9 @@ pcl::VoxelGridCovariance<PointT>::getDisplayCloud (pcl::PointCloud<PointXYZ>& ce
   Eigen::Vector3d rand_point;
   Eigen::Vector3d dist_point;
 
+  cell_cloud.reserve (pnt_per_cell * std::count_if (leaves_.begin (), leaves_.end (),
+      [this] (auto& l) { return (l.second.nr_points >= min_points_per_voxel_); }));
+
   // Generate points for each occupied voxel with sufficient points.
   for (typename std::map<std::size_t, Leaf>::iterator it = leaves_.begin (); it != leaves_.end (); ++it)
   {
index b34021a2c0321604553589bdbaf9000b3742e3e5..03c05cc6fe5d2137ed541cd6c23c29868e9f54df 100644 (file)
@@ -70,8 +70,14 @@ namespace pcl
       using ConstPtr = shared_ptr<const NormalSpaceSampling<PointT, NormalT> >;
 
       /** \brief Empty constructor. */
-      NormalSpaceSampling ()
-        : sample_ (std::numeric_limits<unsigned int>::max ())
+      NormalSpaceSampling () : NormalSpaceSampling (false) {}
+
+      /** \brief Constructor.
+        * \param[in] extract_removed_indices Set to true if you want to be able to extract the indices of points being removed.
+        */
+      explicit NormalSpaceSampling (bool extract_removed_indices)
+        : FilterIndices<PointT> (extract_removed_indices)
+        , sample_ (std::numeric_limits<unsigned int>::max ())
         , seed_ (static_cast<unsigned int> (time (nullptr)))
         , binsx_ ()
         , binsy_ ()
index 72ee252f892b3dd4d74432c6f51df7b306c2fead..b5fa06f530a41928db279cd23b7f50e76214503a 100644 (file)
@@ -435,6 +435,7 @@ namespace pcl
       /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
         * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
         */
+      PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
       inline void
       getFilterLimitsNegative (bool &limit_negative) const
       {
@@ -592,10 +593,10 @@ namespace pcl
       inline void
       setMinimumPointsNumberPerVoxel (unsigned int min_points_per_voxel) { min_points_per_voxel_ = min_points_per_voxel; }
 
-         /** \brief Return the minimum number of points required for a voxel to be used.
-       */
-         inline unsigned int
-         getMinimumPointsNumberPerVoxel () const { return min_points_per_voxel_; }
+      /** \brief Return the minimum number of points required for a voxel to be used.
+        */
+      inline unsigned int
+      getMinimumPointsNumberPerVoxel () const { return min_points_per_voxel_; }
 
       /** \brief Set to true if leaf layout information needs to be saved for later access.
         * \param[in] save_leaf_layout the new value (true/false)
@@ -783,6 +784,7 @@ namespace pcl
       /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false).
         * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
         */
+      PCL_DEPRECATED(1, 16, "use bool getFilterLimitsNegative() instead")
       inline void
       getFilterLimitsNegative (bool &limit_negative) const
       {
index 41ffd02be9c9422575b68c8b87eb291e7beb73bd..7d35a463a0c41806bcd414fdf3f13a79ac04415b 100644 (file)
@@ -189,5 +189,17 @@ Convolution<pcl::RGB, pcl::RGB>::convolveOneColDense(int i, int j)
   result.b = static_cast<std::uint8_t>(b);
   return (result);
 }
+
+#ifndef PCL_NO_PRECOMPILE
+#include <pcl/impl/instantiate.hpp>
+#include <pcl/point_types.h>
+
+PCL_INSTANTIATE_PRODUCT(
+    Convolution, ((pcl::RGB))((pcl::RGB)))
+
+PCL_INSTANTIATE_PRODUCT(
+    Convolution, ((pcl::PointXYZRGB))((pcl::PointXYZRGB)))
+#endif // PCL_NO_PRECOMPILE
+
 } // namespace filters
 } // namespace pcl
index 350fa7619e7ff121f64dcdb85ed983feec015026..fc040b1ad7b4bded0d8b7b8a66520a1f2c0c06b2 100644 (file)
@@ -39,6 +39,11 @@ set(impl_incs
 
 set(LIB_NAME "pcl_${SUBSYS_NAME}")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
+
+add_library(${LIB_NAME} INTERFACE)
+target_include_directories(${LIB_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_link_libraries(${LIB_NAME} INTERFACE Boost::boost pcl_common)
+
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS} HEADER_ONLY)
 
 # Install include files
index 32223baa5526e7452bb1712f36d15fe0a32e3314..bff9d47eccc18ec56a07ef7e593b215aed712a2b 100644 (file)
@@ -49,7 +49,6 @@
 #include <pcl/point_cloud.h>
 
 #include <type_traits>
-
 #include <vector>
 
 ////////////////////////////////////////////////////////////////////////////////
index e94c1487307e76a9e6aa88fc1e5c7e4a2c526d3a..b0ff9474c1218156c4e828e08411dbfe7cc28adc 100644 (file)
@@ -26,6 +26,9 @@ set(LIB_NAME "pcl_${SUBSYS_NAME}")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" ${UTILS_INC})
 PCL_CUDA_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs})
 
+#Ensures that CUDA is added and the project can compile as it uses cuda calls.
+set_source_files_properties(src/device_memory.cpp PROPERTIES LANGUAGE CUDA)
+
 set(EXT_DEPS "")
 #set(EXT_DEPS CUDA)
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS} EXT_DEPS ${EXT_DEPS})
index c08339416d07896c399a8a06c69fad073dcb8a8a..e294c04fc97420cd805b6837db174a84b16af6e9 100644 (file)
@@ -111,7 +111,7 @@ public:
    * \param num_bytes number of bytes to upload
    * */
   bool
-  upload(const void* host_ptr,
+  upload(const void* host_ptr_arg,
          std::size_t device_begin_byte_offset,
          std::size_t num_bytes);
 
@@ -128,7 +128,7 @@ public:
    * \param num_bytes number of bytes to download
    * */
   bool
-  download(void* host_ptr,
+  download(void* host_ptr_arg,
            std::size_t device_begin_byte_offset,
            std::size_t num_bytes) const;
 
index 98aa3435c87bbf5615ef9298c975929d492afa7c..9b86018b83632b6952762cbe842c2fe16f9ee70f 100644 (file)
@@ -1,18 +1,8 @@
 set(SUBSYS_NAME gpu_kinfu)
 set(SUBSYS_PATH gpu/kinfu)
 set(SUBSYS_DESC "Kinect Fusion implementation")
-set(SUBSYS_DEPS common io gpu_containers geometry search visualization)
-
-set(build FALSE)
-
-# OpenNI found?
-if(NOT WITH_OPENNI)
-    set(DEFAULT FALSE)
-    set(REASON "OpenNI was not found or was disabled by the user.")
-else()
-    set(DEFAULT TRUE)
-    set(REASON)
-endif()
+set(SUBSYS_DEPS common io gpu_containers geometry search)
+set(DEFAULT TRUE)
 
 PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ${DEFAULT} "${REASON}")
 PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS})
@@ -23,8 +13,7 @@ if(NOT build)
   return()
 endif()
 
-REMOVE_VTK_DEFINITIONS()
-FILE(GLOB incs include/pcl/gpu/kinfu/*.h*)
+file(GLOB incs include/pcl/gpu/kinfu/*.h*)
 file(GLOB srcs src/*.cpp src/*.h*)
 file(GLOB cuda src/cuda/*.cu src/cuda/*.h*)
 
@@ -33,30 +22,17 @@ source_group("Source Files" FILES ${srcs})
 
 set(LIB_NAME "pcl_${SUBSYS_NAME}")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src")
-include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
-
-if(UNIX OR APPLE)
-  set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}  "-Xcompiler;-fPIC;")
-endif()
-
-if(NOT UNIX OR APPLE)
-  add_definitions(-DPCLAPI_EXPORTS)
-endif()
 
-set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--ftz=true;--prec-div=false;--prec-sqrt=false")
-CUDA_COMPILE(cuda_objs ${cuda})
+PCL_CUDA_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${cuda})
+target_link_libraries(${LIB_NAME} pcl_cuda pcl_gpu_containers)
 
-PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${cuda} ${cuda_objs})
-target_link_libraries("${LIB_NAME}" pcl_gpu_containers)
+target_compile_options(${LIB_NAME} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:--ftz=true;--prec-div=false;--prec-sqrt=false>)
 
-set(EXT_DEPS "")
-#set(EXT_DEPS CUDA)
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS} EXT_DEPS ${EXT_DEPS})
 
 # Install include files
 PCL_ADD_INCLUDES("${SUBSYS_NAME}" "${SUBSYS_PATH}" ${incs})
 
-if(BUILD_visualization)
-  add_subdirectory(test)
+if(BUILD_tools)
   add_subdirectory(tools)
 endif()
diff --git a/gpu/kinfu/test/CMakeLists.txt b/gpu/kinfu/test/CMakeLists.txt
deleted file mode 100644 (file)
index e69de29..0000000
index 691b4d875c6eb73f3debfb3f0baecc71dae2c597..a065da73234f2ffe2663c667176c4b59783ea769 100644 (file)
@@ -1,18 +1,22 @@
-if(NOT WITH_OPENNI)
+set(SUBSUBSYS_NAME tools)
+set(SUBSUBSYS_DESC "Kinfu tools")
+set(SUBSUBSYS_DEPS gpu_kinfu visualization)
+set(SUBSUBSYS_OPT_DEPS opencv)
+set(EXT_DEPS openni)
+set(DEFAULT TRUE)
+set(REASON "")
+
+PCL_SUBSUBSYS_OPTION(build ${SUBSYS_NAME} ${SUBSUBSYS_NAME} ${SUBSUBSYS_DESC} ${DEFAULT} ${REASON})
+PCL_SUBSUBSYS_DEPEND(build ${SUBSUBSYS_NAME} DEPS ${SUBSUBSYS_DEPS} OPT_DEPS ${SUBSUBSYS_OPT_DEPS} EXT_DEPS ${EXT_DEPS})
+
+if(NOT build)
   return()
 endif()
 
-if(NOT VTK_FOUND)
-  set(DEFAULT FALSE)
-  set(REASON "VTK was not found.")
-else()
-  set(DEFAULT TRUE)
-  set(REASON)
-  include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
-endif()
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
 
 file(GLOB hdrs "*.h*")
-include_directories(SYSTEM ${VTK_INCLUDE_DIRS} ${OPENNI_INCLUDE_DIRS})
+include_directories(SYSTEM ${OPENNI_INCLUDE_DIRS})
 
 ## KINECT FUSION
 set(the_target pcl_kinfu_app)
@@ -20,8 +24,8 @@ set(srcs kinfu_app.cpp capture.cpp evaluation.cpp)
 
 source_group("Source Files" FILES ${srcs})
 
-PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
-target_link_libraries("${the_target}" pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu)
+PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
+target_link_libraries(${the_target} pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu)
 
 if(OpenCV_FOUND)
   target_link_libraries("${the_target}" ${OpenCV_LIBS})
@@ -31,5 +35,5 @@ endif()
 set(the_target pcl_record_tsdfvolume)
 set(srcs record_tsdfvolume.cpp capture.cpp)
 
-PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs})
-target_link_libraries("${the_target}" pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu)
+PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${srcs} ${hdrs})
+target_link_libraries(${the_target} pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu)
index a39b660fc341c40999dd4dda16ce4b0ef64d9715..f0db371bfed820d82c2ce8c39b189009470c189e 100644 (file)
@@ -1,18 +1,8 @@
 set(SUBSYS_NAME gpu_kinfu_large_scale)
 set(SUBSYS_PATH gpu/kinfu_large_scale)
 set(SUBSYS_DESC "Kinect Fusion implementation, with volume shifting")
-set(SUBSYS_DEPS common visualization io gpu_containers gpu_utils geometry search octree filters kdtree features surface)
-
-set(build FALSE)
-
-# OpenNI found?
-if(NOT WITH_OPENNI)
-  set(DEFAULT FALSE)
-  set(REASON "OpenNI was not found or was disabled by the user.")
-else()
-  set(DEFAULT TRUE)
-  set(REASON)
-endif()
+set(SUBSYS_DEPS common io gpu_containers gpu_utils geometry search octree filters kdtree features surface)
+set(DEFAULT TRUE)
 
 PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ${DEFAULT} "${REASON}")
 PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS})
@@ -23,7 +13,6 @@ if(NOT build)
   return()
 endif()
 
-REMOVE_VTK_DEFINITIONS()
 file(GLOB incs include/pcl/gpu/kinfu_large_scale/*.h*)
 file(GLOB impl_incs include/pcl/gpu/kinfu_large_scale/impl/*.h*)
 file(GLOB srcs src/*.cpp src/*.h*)
@@ -33,28 +22,19 @@ source_group("Source Files\\cuda" FILES ${cuda})
 source_group("Source Files" FILES ${srcs})
 
 set(LIB_NAME "pcl_${SUBSYS_NAME}")
-include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src" ${CUDA_INCLUDE_DIRS})
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src")
 
-if(UNIX OR APPLE)
-  set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}  "-Xcompiler;-fPIC;")
-endif()
+PCL_CUDA_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs} ${cuda})
 
-if(NOT UNIX OR APPLE)
-  add_definitions(-DPCLAPI_EXPORTS)
-endif()
-
-set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--ftz=true;--prec-div=false;--prec-sqrt=false")
-CUDA_COMPILE(cuda_objs ${cuda})
+target_link_libraries(${LIB_NAME} pcl_cuda pcl_common pcl_io pcl_gpu_utils pcl_gpu_containers pcl_gpu_octree pcl_octree pcl_filters)
 
-PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs} ${cuda} ${cuda_objs})
-target_link_libraries("${LIB_NAME}" pcl_common pcl_io pcl_gpu_utils pcl_gpu_containers pcl_gpu_octree pcl_octree pcl_filters)
+target_compile_options(${LIB_NAME} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:--ftz=true;--prec-div=false;--prec-sqrt=false>)
 
-set(EXT_DEPS "")
-#set(EXT_DEPS CUDA)
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS} EXT_DEPS ${EXT_DEPS})
 
 # Install include files
 PCL_ADD_INCLUDES("${SUBSYS_NAME}" "${SUBSYS_PATH}" ${incs})
 
-add_subdirectory(test)
-add_subdirectory(tools)
+if(BUILD_tools)
+  add_subdirectory(tools)
+endif()
diff --git a/gpu/kinfu_large_scale/test/CMakeLists.txt b/gpu/kinfu_large_scale/test/CMakeLists.txt
deleted file mode 100644 (file)
index e69de29..0000000
index 65f63aa8b836148ce91d6bbcdba9aa3814200c14..c106476943b0d321292fe7e906d7fc71ed07ca5d 100644 (file)
@@ -1,15 +1,19 @@
-if((NOT WITH_OPENNI) AND (NOT WITH_OPENNI2))
+set(SUBSUBSYS_NAME tools)
+set(SUBSUBSYS_DESC "Kinfu large scale tools")
+set(SUBSUBSYS_DEPS gpu_kinfu_large_scale visualization)
+set(SUBSUBSYS_OPT_DEPS )
+set(EXT_DEPS openni openni2)
+set(DEFAULT TRUE)
+set(REASON "")
+
+PCL_SUBSUBSYS_OPTION(build ${SUBSYS_NAME} ${SUBSUBSYS_NAME} ${SUBSUBSYS_DESC} ${DEFAULT} ${REASON})
+PCL_SUBSUBSYS_DEPEND(build ${SUBSUBSYS_NAME} DEPS ${SUBSUBSYS_DEPS} OPT_DEPS ${SUBSUBSYS_OPT_DEPS} EXT_DEPS ${EXT_DEPS})
+
+if(NOT build)
   return()
 endif()
 
-if(NOT VTK_FOUND)
-  set(DEFAULT FALSE)
-  set(REASON "VTK was not found.")
-else()
-  set(DEFAULT TRUE)
-  set(REASON)
-  include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
-endif()
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
 
 file(GLOB hdrs "*.h*")
 include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
@@ -20,7 +24,7 @@ set(srcs standalone_texture_mapping.cpp)
 
 source_group("Source Files" FILES ${srcs})
 
-PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
+PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${srcs} BUNDLE)
 target_link_libraries("${the_target}" pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu_large_scale pcl_kdtree pcl_features pcl_surface)
 
 ## KINECT FUSION
@@ -29,19 +33,19 @@ set(srcs kinfuLS_app.cpp capture.cpp evaluation.cpp)
 
 source_group("Source Files" FILES ${srcs})
 
-PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
+PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
 target_link_libraries("${the_target}" pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu_large_scale pcl_octree)
 
 ## STANDALONE MARCHING CUBES
 set(the_target pcl_kinfu_largeScale_mesh_output)
 set(srcs process_kinfu_large_scale_output.cpp)
 
-PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
+PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
 target_link_libraries("${the_target}" pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu_large_scale pcl_filters)
 
 ## RECORD MAPS_RGB
 set(the_target pcl_record_kinect_maps_rgb)
 set(srcs record_maps_rgb.cpp)
 
-PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
+PCL_ADD_EXECUTABLE(${the_target} COMPONENT ${SUBSUBSYS_NAME} SOURCES ${srcs} ${hdrs} BUNDLE)
 target_link_libraries("${the_target}" pcl_common pcl_io ${OPENNI_LIBRARIES} pcl_visualization pcl_gpu_kinfu_large_scale pcl_filters)
index 38cb26c2a1f3b269549e77c517afa1a4ab6531d2..5f078daa3ee9e70d9791ef04bcb4c800885cef13 100644 (file)
@@ -14,8 +14,6 @@ if(NOT build)
   return()
 endif()
 
-REMOVE_VTK_DEFINITIONS()
-
 #find NPP
 unset(CUDA_npp_LIBRARY CACHE)
 find_cuda_helper_libs(nppc)
@@ -46,25 +44,15 @@ include_directories(
   "${CMAKE_CURRENT_SOURCE_DIR}/src/cuda/nvidia"
 )
 
-include_directories(SYSTEM
-  ${VTK_INCLUDE_DIRS}
-  ${OpenCV_INCLUDE_DIRS}
-  ${CUDA_INCLUDE_DIRS}
-)
+set(LIB_NAME "pcl_${SUBSYS_NAME}")
+
+PCL_CUDA_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} ${srcs_cuda})
+target_link_libraries(${LIB_NAME} pcl_cuda pcl_common pcl_search pcl_surface pcl_segmentation pcl_features pcl_sample_consensus pcl_gpu_utils pcl_gpu_containers "${CUDA_CUDART_LIBRARY}" ${CUDA_npp_LIBRARY})
 
 if(UNIX OR APPLE)
-  set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}  "-Xcompiler;-fPIC;")
+  target_compile_options(${LIB_NAME} INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:"-Xcompiler=-fPIC">)
 endif()
-if(NOT UNIX OR APPLE)
-  add_definitions(-DPCLAPI_EXPORTS)
-endif()
-
-CUDA_COMPILE(objs_cuda ${srcs_cuda} ${hdrs})
-
-set(LIB_NAME "pcl_${SUBSYS_NAME}")
 
-PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${hdrs} ${srcs_cuda} ${objs_cuda})
-target_link_libraries("${LIB_NAME}" pcl_common pcl_io pcl_search pcl_surface pcl_segmentation pcl_features pcl_sample_consensus pcl_gpu_utils pcl_gpu_containers "${CUDA_CUDART_LIBRARY}" ${CUDA_npp_LIBRARY})
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS})
 
 # install include files
index d7d21242cf1ab06e729b030bcd51246528db1995..30087cb039c6ccd32edd51330ca4baa089becb57 100644 (file)
 
 #include <pcl/console/print.h>
 
-#include <pcl/filters/voxel_grid.h>
-
-#include <pcl/features/integral_image_normal.h>
-
 #include <pcl/common/transforms.h>
 
 #include <pcl/segmentation/organized_multi_plane_segmentation.h>
index 83cf9b4b60f0e499617558db9066659239f1aebf..6cd7e7f9931c6b7859c7fa588217056e55ec5cc9 100644 (file)
@@ -14,18 +14,18 @@ set(the_target people_tracking)
 include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
 
 #PCL_ADD_EXECUTABLE(${the_target} "${SUBSYS_NAME}" people_tracking.cpp)
-#target_link_libraries("${the_target}" pcl_common pcl_filters pcl_kdtree pcl_segmentation pcl_kdtree pcl_gpu_people pcl_filters pcl_io pcl_visualization)
+#target_link_libraries("${the_target}" pcl_common pcl_kdtree pcl_gpu_people pcl_io pcl_visualization)
 
 if(HAVE_OPENNI)
   PCL_ADD_EXECUTABLE(pcl_people_app COMPONENT ${SUBSYS_NAME} SOURCES people_app.cpp)
-  target_link_libraries (pcl_people_app pcl_common pcl_filters pcl_kdtree pcl_segmentation pcl_kdtree pcl_gpu_people pcl_filters pcl_io pcl_visualization ${Boost_LIBRARIES})
+  target_link_libraries (pcl_people_app pcl_common pcl_gpu_people pcl_io pcl_visualization ${Boost_LIBRARIES})
 endif()
 
 PCL_ADD_EXECUTABLE(pcl_people_pcd_prob COMPONENT ${SUBSYS_NAME} SOURCES people_pcd_prob.cpp)
-target_link_libraries (pcl_people_pcd_prob pcl_common pcl_filters pcl_kdtree pcl_segmentation pcl_kdtree pcl_gpu_people pcl_filters pcl_io pcl_visualization ${Boost_LIBRARIES})
+target_link_libraries (pcl_people_pcd_prob pcl_common pcl_kdtree pcl_gpu_people pcl_io pcl_visualization)
 
 #PCL_ADD_EXECUTABLE(people_pcd_folder COMPONENT ${SUBSYS_NAME} SOURCES people_pcd_folder.cpp)
-#target_link_libraries (people_pcd_folder pcl_common pcl_filters pcl_kdtree pcl_segmentation pcl_kdtree pcl_gpu_people pcl_filters pcl_io pcl_visualization ${Boost_LIBRARIES})
+#target_link_libraries (people_pcd_folder pcl_common pcl_kdtree pcl_gpu_people pcl_io pcl_visualization)
 
 #PCL_ADD_EXECUTABLE(people_pcd_person COMPONENT ${SUBSYS_NAME} SOURCES people_pcd_person.cpp)
-#target_link_libraries (people_pcd_person pcl_common pcl_filters pcl_kdtree pcl_segmentation pcl_kdtree pcl_gpu_people pcl_filters pcl_io pcl_visualization)
+#target_link_libraries (people_pcd_person pcl_common pcl_kdtree pcl_gpu_people pcl_io pcl_visualization)
index 3738663ff4247b005fd477d5910888c8560313d9..94223cb0ca1150dfa5d37bfc6f7c3e0c53a7834e 100644 (file)
 
 #pragma once
 
-#include <pcl/point_types.h>
-#include <pcl/point_cloud.h>
+#include <pcl/gpu/containers/device_array.h>
+#include <pcl/gpu/octree/octree.hpp>
 #include <pcl/PointIndices.h>
 #include <pcl/pcl_macros.h>
-#include <pcl/gpu/octree/octree.hpp>
-#include <pcl/gpu/containers/device_array.h>
+#include <pcl/point_cloud.h>
+#include <pcl/point_types.h>
 
-namespace pcl
-{
-  namespace gpu
+namespace pcl {
+namespace gpu {
+template <typename PointT>
+void
+extractEuclideanClusters(const typename pcl::PointCloud<PointT>::Ptr& host_cloud_,
+                         const pcl::gpu::Octree::Ptr& tree,
+                         float tolerance,
+                         std::vector<PointIndices>& clusters,
+                         unsigned int min_pts_per_cluster,
+                         unsigned int max_pts_per_cluster);
+
+/** \brief @b EuclideanClusterExtraction represents a segmentation class for cluster
+ * extraction in an Euclidean sense, depending on pcl::gpu::octree
+ * \author Koen Buys, Radu Bogdan Rusu
+ * \ingroup segmentation
+ */
+template <typename PointT>
+class EuclideanClusterExtraction {
+public:
+  using PointCloudHost = pcl::PointCloud<PointT>;
+  using PointCloudHostPtr = typename PointCloudHost::Ptr;
+  using PointCloudHostConstPtr = typename PointCloudHost::ConstPtr;
+
+  using PointIndicesPtr = PointIndices::Ptr;
+  using PointIndicesConstPtr = PointIndices::ConstPtr;
+
+  using GPUTree = pcl::gpu::Octree;
+  using GPUTreePtr = pcl::gpu::Octree::Ptr;
+
+  using CloudDevice = pcl::gpu::Octree::PointCloud;
+
+  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /** \brief Empty constructor. */
+  EuclideanClusterExtraction() = default;
+
+  /** \brief the destructor */
+  /*        ~EuclideanClusterExtraction ()
+          {
+            tree_.clear();
+          };
+  */
+  /** \brief Provide a pointer to the search object.
+   * \param tree a pointer to the spatial search object.
+   */
+  inline void
+  setSearchMethod(GPUTreePtr& tree)
+  {
+    tree_ = tree;
+  }
+
+  /** \brief Get a pointer to the search method used.
+   *  @todo fix this for a generic search tree
+   */
+  inline GPUTreePtr
+  getSearchMethod()
+  {
+    return (tree_);
+  }
+
+  /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
+   * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean
+   * space
+   */
+  inline void
+  setClusterTolerance(double tolerance)
+  {
+    cluster_tolerance_ = tolerance;
+  }
+
+  /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space.
+   */
+  inline double
+  getClusterTolerance()
+  {
+    return (cluster_tolerance_);
+  }
+
+  /** \brief Set the minimum number of points that a cluster needs to contain in order
+   * to be considered valid.
+   * \param min_cluster_size the minimum cluster size
+   */
+  inline void
+  setMinClusterSize(int min_cluster_size)
+  {
+    min_pts_per_cluster_ = min_cluster_size;
+  }
+
+  /** \brief Get the minimum number of points that a cluster needs to contain in order
+   * to be considered valid. */
+  inline int
+  getMinClusterSize()
   {
-    template <typename PointT> void
-    extractEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr &host_cloud_,
-                              const pcl::gpu::Octree::Ptr               &tree,
-                              float                                     tolerance,
-                              std::vector<PointIndices>                 &clusters,
-                              unsigned int                              min_pts_per_cluster,
-                              unsigned int                              max_pts_per_cluster);
-
-   /** \brief @b EuclideanClusterExtraction represents a segmentation class for cluster extraction in an Euclidean sense, depending on pcl::gpu::octree
-    * \author Koen Buys, Radu Bogdan Rusu
-    * \ingroup segmentation
-    */
-    template <typename PointT>
-    class EuclideanClusterExtraction
-    {
-      public:
-        using PointCloudHost = pcl::PointCloud<PointT>;
-        using PointCloudHostPtr = typename PointCloudHost::Ptr;
-        using PointCloudHostConstPtr = typename PointCloudHost::ConstPtr;
-
-        using PointIndicesPtr = PointIndices::Ptr;
-        using PointIndicesConstPtr = PointIndices::ConstPtr;
-
-        using GPUTree = pcl::gpu::Octree;
-        using GPUTreePtr = pcl::gpu::Octree::Ptr;
-
-        using CloudDevice = pcl::gpu::Octree::PointCloud;
-
-        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-        /** \brief Empty constructor. */
-        EuclideanClusterExtraction () = default;
-
-        /** \brief the destructor */
-/*        ~EuclideanClusterExtraction ()
-        {
-          tree_.clear();
-        };
-*/
-        /** \brief Provide a pointer to the search object.
-          * \param tree a pointer to the spatial search object.
-          */
-        inline void setSearchMethod (GPUTreePtr &tree) { tree_ = tree; }
-
-        /** \brief Get a pointer to the search method used. 
-          *  @todo fix this for a generic search tree
-          */
-        inline GPUTreePtr getSearchMethod () { return (tree_); }
-
-        /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
-          * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean space
-          */
-        inline void setClusterTolerance (double tolerance) { cluster_tolerance_ = tolerance; }
-
-        /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space. */
-        inline double getClusterTolerance () { return (cluster_tolerance_); }
-
-        /** \brief Set the minimum number of points that a cluster needs to contain in order to be considered valid.
-          * \param min_cluster_size the minimum cluster size
-          */
-        inline void setMinClusterSize (int min_cluster_size) { min_pts_per_cluster_ = min_cluster_size; }
-
-        /** \brief Get the minimum number of points that a cluster needs to contain in order to be considered valid. */
-        inline int getMinClusterSize () { return (min_pts_per_cluster_); }
-
-        /** \brief Set the maximum number of points that a cluster needs to contain in order to be considered valid.
-          * \param max_cluster_size the maximum cluster size
-          */
-        inline void setMaxClusterSize (int max_cluster_size) { max_pts_per_cluster_ = max_cluster_size; }
-
-        /** \brief Get the maximum number of points that a cluster needs to contain in order to be considered valid. */
-        inline int getMaxClusterSize () { return (max_pts_per_cluster_); }
-
-        inline void setInput (CloudDevice input) {input_ = input;}
-
-        inline void setHostCloud (PointCloudHostPtr host_cloud) {host_cloud_ = host_cloud;}
-
-        /** \brief Cluster extraction in a PointCloud given by <setInputCloud (), setIndices ()>
-          * \param clusters the resultant point clusters
-          */
-        void extract (std::vector<pcl::PointIndices> &clusters);
-
-      protected:
-        /** \brief the input cloud on the GPU */
-        CloudDevice input_;
-
-        /** \brief the original cloud the Host */
-        PointCloudHostPtr host_cloud_;
-
-        /** \brief A pointer to the spatial search object. */
-        GPUTreePtr tree_;
-
-        /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
-        double cluster_tolerance_ {0};
-
-        /** \brief The minimum number of points that a cluster needs to contain in order to be considered valid (default = 1). */
-        int min_pts_per_cluster_ {1};
-
-        /** \brief The maximum number of points that a cluster needs to contain in order to be considered valid (default = MAXINT). */
-        int max_pts_per_cluster_ {std::numeric_limits<int>::max()};
-
-        /** \brief Class getName method. */
-        virtual std::string getClassName () const { return ("gpu::EuclideanClusterExtraction"); }
-    };
-    /** \brief Sort clusters method (for std::sort). 
-      * \ingroup segmentation
-      */
-    inline bool 
-      comparePointClusters (const pcl::PointIndices &a, const pcl::PointIndices &b)
-    {
-      return (a.indices.size () < b.indices.size ());
-    }
+    return (min_pts_per_cluster_);
   }
+
+  /** \brief Set the maximum number of points that a cluster needs to contain in order
+   * to be considered valid.
+   * \param max_cluster_size the maximum cluster size
+   */
+  inline void
+  setMaxClusterSize(int max_cluster_size)
+  {
+    max_pts_per_cluster_ = max_cluster_size;
+  }
+
+  /** \brief Get the maximum number of points that a cluster needs to contain in order
+   * to be considered valid. */
+  inline int
+  getMaxClusterSize()
+  {
+    return (max_pts_per_cluster_);
+  }
+
+  inline void
+  setInput(CloudDevice input)
+  {
+    input_ = input;
+  }
+
+  inline void
+  setHostCloud(PointCloudHostPtr host_cloud)
+  {
+    host_cloud_ = host_cloud;
+  }
+
+  /** \brief extract clusters of a PointCloud given by <setInputCloud(), setIndices()>
+   * \param clusters the resultant point clusters
+   */
+  void
+  extract(std::vector<pcl::PointIndices>& clusters);
+
+protected:
+  /** \brief the input cloud on the GPU */
+  CloudDevice input_;
+
+  /** \brief the original cloud the Host */
+  PointCloudHostPtr host_cloud_;
+
+  /** \brief A pointer to the spatial search object. */
+  GPUTreePtr tree_;
+
+  /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
+  double cluster_tolerance_{0};
+
+  /** \brief The minimum number of points that a cluster needs to contain in order to be
+   * considered valid (default = 1). */
+  int min_pts_per_cluster_{1};
+
+  /** \brief The maximum number of points that a cluster needs to contain in order to be
+   * considered valid (default = MAXINT). */
+  int max_pts_per_cluster_{std::numeric_limits<int>::max()};
+
+  /** \brief Class getName method. */
+  virtual std::string
+  getClassName() const
+  {
+    return ("gpu::EuclideanClusterExtraction");
+  }
+};
+/** \brief Sort clusters method (for std::sort).
+ * \ingroup segmentation
+ */
+inline bool
+comparePointClusters(const pcl::PointIndices& a, const pcl::PointIndices& b)
+{
+  return (a.indices.size() < b.indices.size());
 }
+} // namespace gpu
+} // namespace pcl
index 65fc71cc22f589ee307b921ade11e30708573f3b..17b791ecbe1802647d54f5832f42dce742822887 100644 (file)
 
 #pragma once
 
-#include <pcl/point_types.h>
-#include <pcl/point_cloud.h>
+#include <pcl/gpu/octree/octree.hpp>
 #include <pcl/PointIndices.h>
 #include <pcl/pcl_macros.h>
-#include <pcl/gpu/octree/octree.hpp>
+#include <pcl/point_cloud.h>
+#include <pcl/point_types.h>
 
-namespace pcl
-{
-  namespace gpu
+namespace pcl {
+namespace gpu {
+template <typename PointT>
+void
+extractLabeledEuclideanClusters(
+    const typename pcl::PointCloud<PointT>::Ptr& host_cloud_,
+    const pcl::gpu::Octree::Ptr& tree,
+    float tolerance,
+    std::vector<PointIndices>& clusters,
+    unsigned int min_pts_per_cluster,
+    unsigned int max_pts_per_cluster);
+
+/** \brief @b EuclideanLabeledClusterExtraction represents a segmentation class for
+ * cluster extraction in an Euclidean sense, depending on pcl::gpu::octree
+ * \author Koen Buys, Radu Bogdan Rusu
+ * \ingroup segmentation
+ */
+template <typename PointT>
+class EuclideanLabeledClusterExtraction {
+public:
+  using PointType = pcl::PointXYZ;
+  using PointCloudHost = pcl::PointCloud<PointT>;
+  using PointCloudHostPtr = typename PointCloudHost::Ptr;
+  using PointCloudHostConstPtr = typename PointCloudHost::ConstPtr;
+
+  using PointIndicesPtr = PointIndices::Ptr;
+  using PointIndicesConstPtr = PointIndices::ConstPtr;
+
+  using GPUTree = pcl::gpu::Octree;
+  using GPUTreePtr = pcl::gpu::Octree::Ptr;
+
+  using CloudDevice = pcl::gpu::Octree::PointCloud;
+
+  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /** \brief Empty constructor. */
+  EuclideanLabeledClusterExtraction() = default;
+
+  /** \brief Provide a pointer to the search object.
+   * \param tree a pointer to the spatial search object.
+   */
+  inline void
+  setSearchMethod(const GPUTreePtr& tree)
+  {
+    tree_ = tree;
+  }
+
+  /** \brief Get a pointer to the search method used.
+   *  @todo fix this for a generic search tree
+   */
+  inline GPUTreePtr
+  getSearchMethod()
+  {
+    return (tree_);
+  }
+
+  /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
+   * \param tolerance the spatial cluster tolerance measured by L2 distance
+   */
+  inline void
+  setClusterTolerance(double tolerance)
+  {
+    cluster_tolerance_ = tolerance;
+  }
+
+  /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space.
+   */
+  inline double
+  getClusterTolerance()
+  {
+    return (cluster_tolerance_);
+  }
+
+  /** \brief Set the minimum number of points that a cluster needs to contain in order
+   * to be considered valid.
+   * \param min_cluster_size the minimum cluster size
+   */
+  inline void
+  setMinClusterSize(int min_cluster_size)
+  {
+    min_pts_per_cluster_ = min_cluster_size;
+  }
+
+  /** \brief Get the minimum number of points that a cluster needs to contain in order
+   * to be considered valid. */
+  inline int
+  getMinClusterSize()
   {
-    template <typename PointT> void
-    extractLabeledEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr &host_cloud_,
-                                     const pcl::gpu::Octree::Ptr                 &tree,
-                                     float                                       tolerance,
-                                     std::vector<PointIndices>                   &clusters,
-                                     unsigned int                                min_pts_per_cluster, 
-                                     unsigned int                                max_pts_per_cluster);
-
-   /** \brief @b EuclideanLabeledClusterExtraction represents a segmentation class for cluster extraction in an Euclidean sense, depending on pcl::gpu::octree
-    * \author Koen Buys, Radu Bogdan Rusu
-    * \ingroup segmentation
-    */
-    template <typename PointT>
-    class EuclideanLabeledClusterExtraction
-    {
-      public:
-        using PointType = pcl::PointXYZ;
-        using PointCloudHost = pcl::PointCloud<PointT>;
-        using PointCloudHostPtr = typename PointCloudHost::Ptr;
-        using PointCloudHostConstPtr = typename PointCloudHost::ConstPtr;
-
-        using PointIndicesPtr = PointIndices::Ptr;
-        using PointIndicesConstPtr = PointIndices::ConstPtr;
-
-        using GPUTree = pcl::gpu::Octree;
-        using GPUTreePtr = pcl::gpu::Octree::Ptr;
-
-        using CloudDevice = pcl::gpu::Octree::PointCloud;
-
-        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-        /** \brief Empty constructor. */
-        EuclideanLabeledClusterExtraction () = default;
-
-        /** \brief Provide a pointer to the search object.
-          * \param tree a pointer to the spatial search object.
-          */
-        inline void setSearchMethod (const GPUTreePtr &tree) { tree_ = tree; }
-
-        /** \brief Get a pointer to the search method used. 
-          *  @todo fix this for a generic search tree
-          */
-        inline GPUTreePtr getSearchMethod () { return (tree_); }
-
-        /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
-          * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean space
-          */
-        inline void setClusterTolerance (double tolerance) { cluster_tolerance_ = tolerance; }
-
-        /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space. */
-        inline double getClusterTolerance () { return (cluster_tolerance_); }
-
-        /** \brief Set the minimum number of points that a cluster needs to contain in order to be considered valid.
-          * \param min_cluster_size the minimum cluster size
-          */
-        inline void setMinClusterSize (int min_cluster_size) { min_pts_per_cluster_ = min_cluster_size; }
-
-        /** \brief Get the minimum number of points that a cluster needs to contain in order to be considered valid. */
-        inline int getMinClusterSize () { return (min_pts_per_cluster_); }
-
-        /** \brief Set the maximum number of points that a cluster needs to contain in order to be considered valid.
-          * \param max_cluster_size the maximum cluster size
-          */
-        inline void setMaxClusterSize (int max_cluster_size) { max_pts_per_cluster_ = max_cluster_size; }
-
-        /** \brief Get the maximum number of points that a cluster needs to contain in order to be considered valid. */
-        inline int getMaxClusterSize () { return (max_pts_per_cluster_); }
-
-        inline void setInput (CloudDevice input) {input_ = input;}
-
-        inline void setHostCloud (PointCloudHostPtr host_cloud) {host_cloud_ = host_cloud;}
-
-        /** \brief Cluster extraction in a PointCloud given by <setInputCloud (), setIndices ()>
-          * \param clusters the resultant point clusters
-          */
-        void extract (std::vector<PointIndices> &clusters);
-
-      protected:
-        /** \brief the input cloud on the GPU */
-        CloudDevice input_;
-
-        /** \brief the original cloud the Host */
-        PointCloudHostPtr host_cloud_;
-
-        /** \brief A pointer to the spatial search object. */
-        GPUTreePtr tree_;
-
-        /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
-        double cluster_tolerance_ {0};
-
-        /** \brief The minimum number of points that a cluster needs to contain in order to be considered valid (default = 1). */
-        int min_pts_per_cluster_ {1};
-
-        /** \brief The maximum number of points that a cluster needs to contain in order to be considered valid (default = MAXINT). */
-        int max_pts_per_cluster_ {std::numeric_limits<int>::max()};
-
-        /** \brief Class getName method. */
-        virtual std::string getClassName () const { return ("gpu::EuclideanLabeledClusterExtraction"); }
-    };
-    /** \brief Sort clusters method (for std::sort). 
-      * \ingroup segmentation
-      */
-    inline bool 
-      compareLabeledPointClusters (const pcl::PointIndices &a, const pcl::PointIndices &b)
-    {
-      return (a.indices.size () < b.indices.size ());
-    }
+    return (min_pts_per_cluster_);
   }
+
+  /** \brief Set the maximum number of points that a cluster needs to contain in order
+   * to be considered valid.
+   * \param max_cluster_size the maximum cluster size
+   */
+  inline void
+  setMaxClusterSize(int max_cluster_size)
+  {
+    max_pts_per_cluster_ = max_cluster_size;
+  }
+
+  /** \brief Get the maximum number of points that a cluster needs to contain in order
+   * to be considered valid. */
+  inline int
+  getMaxClusterSize()
+  {
+    return (max_pts_per_cluster_);
+  }
+
+  inline void
+  setInput(CloudDevice input)
+  {
+    input_ = input;
+  }
+
+  inline void
+  setHostCloud(PointCloudHostPtr host_cloud)
+  {
+    host_cloud_ = host_cloud;
+  }
+
+  /** \brief extract clusters of a PointCloud given by <setInputCloud(), setIndices()>
+   * \param clusters the resultant point clusters
+   */
+  void
+  extract(std::vector<PointIndices>& clusters);
+
+protected:
+  /** \brief the input cloud on the GPU */
+  CloudDevice input_;
+
+  /** \brief the original cloud the Host */
+  PointCloudHostPtr host_cloud_;
+
+  /** \brief A pointer to the spatial search object. */
+  GPUTreePtr tree_;
+
+  /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
+  double cluster_tolerance_{0};
+
+  /** \brief The minimum number of points that a cluster needs to contain in order to be
+   * considered valid (default = 1). */
+  int min_pts_per_cluster_{1};
+
+  /** \brief The maximum number of points that a cluster needs to contain in order to be
+   * considered valid (default = MAXINT). */
+  int max_pts_per_cluster_{std::numeric_limits<int>::max()};
+
+  /** \brief Class getName method. */
+  virtual std::string
+  getClassName() const
+  {
+    return ("gpu::EuclideanLabeledClusterExtraction");
+  }
+};
+/** \brief Sort clusters method (for std::sort).
+ * \ingroup segmentation
+ */
+inline bool
+compareLabeledPointClusters(const pcl::PointIndices& a, const pcl::PointIndices& b)
+{
+  return (a.indices.size() < b.indices.size());
 }
+} // namespace gpu
+} // namespace pcl
index b6c974dfae3e0abbb929d4fdc55466024f1840be..afa34b2363f671fcbb2417f26ed48a811b76fa0c 100644 (file)
 
 #pragma once
 
-#include <pcl/point_types.h>
-#include <pcl/point_cloud.h>
 #include <pcl/PointIndices.h>
 #include <pcl/pcl_macros.h>
+#include <pcl/point_cloud.h>
+#include <pcl/point_types.h>
 
-namespace pcl
-{
-  namespace gpu
+namespace pcl {
+namespace gpu {
+void
+seededHueSegmentation(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr& host_cloud_,
+                      const pcl::gpu::Octree::Ptr& tree,
+                      float tolerance,
+                      PointIndices& clusters_in,
+                      PointIndices& clusters_out,
+                      float delta_hue = 0.0);
+
+class SeededHueSegmentation {
+public:
+  using PointType = pcl::PointXYZ;
+  using PointCloudHost = pcl::PointCloud<pcl::PointXYZ>;
+  using PointCloudHostPtr = PointCloudHost::Ptr;
+  using PointCloudHostConstPtr = PointCloudHost::ConstPtr;
+
+  using PointIndicesPtr = PointIndices::Ptr;
+  using PointIndicesConstPtr = PointIndices::ConstPtr;
+
+  using GPUTree = pcl::gpu::Octree;
+  using GPUTreePtr = pcl::gpu::Octree::Ptr;
+
+  using CloudDevice = pcl::gpu::Octree::PointCloud;
+
+  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /** \brief Empty constructor. */
+  SeededHueSegmentation() = default;
+
+  /** \brief Provide a pointer to the search object.
+   * \param tree a pointer to the spatial search object.
+   */
+  inline void
+  setSearchMethod(const GPUTreePtr& tree)
   {
-    void
-    seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud_,
-                           const pcl::gpu::Octree::Ptr                   &tree,
-                           float                                         tolerance,
-                           PointIndices                                  &clusters_in,
-                           PointIndices                                  &clusters_out,
-                           float                                         delta_hue = 0.0);
-
-    class SeededHueSegmentation
-    {
-      public:
-        using PointType = pcl::PointXYZ;
-        using PointCloudHost = pcl::PointCloud<pcl::PointXYZ>;
-        using PointCloudHostPtr = PointCloudHost::Ptr;
-        using PointCloudHostConstPtr = PointCloudHost::ConstPtr;
-
-        using PointIndicesPtr = PointIndices::Ptr;
-        using PointIndicesConstPtr = PointIndices::ConstPtr;
-
-        using GPUTree = pcl::gpu::Octree;
-        using GPUTreePtr = pcl::gpu::Octree::Ptr;
-
-        using CloudDevice = pcl::gpu::Octree::PointCloud;
-
-        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-        /** \brief Empty constructor. */
-        SeededHueSegmentation () = default;
-
-        /** \brief Provide a pointer to the search object.
-          * \param tree a pointer to the spatial search object.
-          */
-        inline void setSearchMethod (const GPUTreePtr &tree) { tree_ = tree; }
-
-        /** \brief Get a pointer to the search method used. 
-          *  @todo fix this for a generic search tree
-          */
-        inline GPUTreePtr getSearchMethod () { return (tree_); }
-
-        /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
-          * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean space
-          */
-        inline void setClusterTolerance (double tolerance) { cluster_tolerance_ = tolerance; }
-
-        /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space. */
-        inline double getClusterTolerance () { return (cluster_tolerance_); }
-
-        inline void setInput (CloudDevice input) {input_ = input;}
-
-        inline void setHostCloud (PointCloudHostPtr host_cloud) {host_cloud_ = host_cloud;}
-
-        /** \brief Set the tollerance on the hue
-          * \param[in] delta_hue the new delta hue
-          */
-        inline void 
-        setDeltaHue (float delta_hue) { delta_hue_ = delta_hue; }
-
-        /** \brief Get the tolerance on the hue */
-        inline float 
-        getDeltaHue () { return (delta_hue_); }
-
-        /** \brief Cluster extraction in a PointCloud given by <setInputCloud (), setIndices ()>
-          * \param indices_in
-          * \param indices_out
-          */
-        void segment (PointIndices &indices_in, PointIndices &indices_out);
-
-      protected:
-        /** \brief the input cloud on the GPU */
-        CloudDevice input_;
-
-        /** \brief the original cloud the Host */
-        PointCloudHostPtr host_cloud_;
-
-        /** \brief A pointer to the spatial search object. */
-        GPUTreePtr tree_;
-
-        /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
-        double cluster_tolerance_ {0};
-
-        /** \brief The allowed difference on the hue*/
-        float delta_hue_ {0.0};
-
-        /** \brief Class getName method. */
-        virtual std::string getClassName () const { return ("gpu::SeededHueSegmentation"); }
-    };
-    /** \brief Sort clusters method (for std::sort). 
-      * \ingroup segmentation
-      */
-    inline bool 
-      comparePointClusters (const pcl::PointIndices &a, const pcl::PointIndices &b)
-    {
-      return (a.indices.size () < b.indices.size ());
-    }
+    tree_ = tree;
   }
+
+  /** \brief Get a pointer to the search method used.
+   *  @todo fix this for a generic search tree
+   */
+  inline GPUTreePtr
+  getSearchMethod()
+  {
+    return (tree_);
+  }
+
+  /** \brief Set the spatial cluster tolerance as a measure in the L2 Euclidean space
+   * \param tolerance the spatial cluster tolerance as a measure in the L2 Euclidean
+   * space
+   */
+  inline void
+  setClusterTolerance(double tolerance)
+  {
+    cluster_tolerance_ = tolerance;
+  }
+
+  /** \brief Get the spatial cluster tolerance as a measure in the L2 Euclidean space.
+   */
+  inline double
+  getClusterTolerance()
+  {
+    return (cluster_tolerance_);
+  }
+
+  inline void
+  setInput(CloudDevice input)
+  {
+    input_ = input;
+  }
+
+  inline void
+  setHostCloud(PointCloudHostPtr host_cloud)
+  {
+    host_cloud_ = host_cloud;
+  }
+
+  /** \brief Set the tollerance on the hue
+   * \param[in] delta_hue the new delta hue
+   */
+  inline void
+  setDeltaHue(float delta_hue)
+  {
+    delta_hue_ = delta_hue;
+  }
+
+  /** \brief Get the tolerance on the hue */
+  inline float
+  getDeltaHue()
+  {
+    return (delta_hue_);
+  }
+
+  /** \brief extract clusters of a PointCloud given by <setInputCloud(), setIndices()>
+   * \param indices_in
+   * \param indices_out
+   */
+  void
+  segment(PointIndices& indices_in, PointIndices& indices_out);
+
+protected:
+  /** \brief the input cloud on the GPU */
+  CloudDevice input_;
+
+  /** \brief the original cloud the Host */
+  PointCloudHostPtr host_cloud_;
+
+  /** \brief A pointer to the spatial search object. */
+  GPUTreePtr tree_;
+
+  /** \brief The spatial cluster tolerance as a measure in the L2 Euclidean space. */
+  double cluster_tolerance_{0};
+
+  /** \brief The allowed difference on the hue*/
+  float delta_hue_{0.0};
+
+  /** \brief Class getName method. */
+  virtual std::string
+  getClassName() const
+  {
+    return ("gpu::SeededHueSegmentation");
+  }
+};
+/** \brief Sort clusters method (for std::sort).
+ * \ingroup segmentation
+ */
+inline bool
+comparePointClusters(const pcl::PointIndices& a, const pcl::PointIndices& b)
+{
+  return (a.indices.size() < b.indices.size());
 }
+} // namespace gpu
+} // namespace pcl
index c654ddc53c809715f8cb31495658e9085f838f66..d5c0371aac9633031ed1d1991818fda421d7fb56 100644 (file)
@@ -52,23 +52,25 @@ economical_download(const pcl::gpu::NeighborIndices& source_indices,
 } // namespace detail
 } // namespace pcl
 
-template <typename PointT> void
-pcl::gpu::extractEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr  &host_cloud_,
-                                    const pcl::gpu::Octree::Ptr                &tree,
-                                    float                                      tolerance,
-                                    std::vector<PointIndices>                  &clusters,
-                                    unsigned int                               min_pts_per_cluster,
-                                    unsigned int                               max_pts_per_cluster)
+template <typename PointT>
+void
+pcl::gpu::extractEuclideanClusters(
+    const typename pcl::PointCloud<PointT>::Ptr& host_cloud_,
+    const pcl::gpu::Octree::Ptr& tree,
+    float tolerance,
+    std::vector<PointIndices>& clusters,
+    unsigned int min_pts_per_cluster,
+    unsigned int max_pts_per_cluster)
 {
 
   // Create a bool vector of processed point indices, and initialize it to false
   // cloud is a DeviceArray<PointType>
   PCL_DEBUG("[pcl::gpu::extractEuclideanClusters]\n");
-  std::vector<bool> processed (host_cloud_->size (), false);
+  std::vector<bool> processed(host_cloud_->size(), false);
 
   int max_answers;
 
-  if(max_pts_per_cluster > host_cloud_->size())
+  if (max_pts_per_cluster > host_cloud_->size())
     max_answers = host_cloud_->size();
   else
     max_answers = max_pts_per_cluster;
@@ -83,8 +85,7 @@ pcl::gpu::extractEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr
   // Host buffer for results
   pcl::Indices sizes, data, cpu_tmp;
   // Process all points in the cloud
-  for (std::size_t i = 0; i < host_cloud_->size (); ++i)
-  {
+  for (std::size_t i = 0; i < host_cloud_->size(); ++i) {
     // if we already processed this point continue with the next one
     if (processed[i])
       continue;
@@ -101,27 +102,26 @@ pcl::gpu::extractEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr
     pcl::copyPoint((*host_cloud_)[i], p);
 
     // Push the starting point in the vector
-    queries_host.push_back (p);
+    queries_host.push_back(p);
     // Clear vector
     r.indices.clear();
     // Push the starting point in
     r.indices.push_back(i);
 
-    unsigned int found_points = queries_host.size ();
+    unsigned int found_points = queries_host.size();
     unsigned int previous_found_points = 0;
 
     pcl::gpu::NeighborIndices result_device;
 
     // once the area stop growing, stop also iterating.
-    do
-    {
+    do {
       data.clear();
       // if the number of queries is not high enough implement search on Host here
-      if(queries_host.size () <= 10) ///@todo: adjust this to a variable number settable with method
+      if (queries_host.size() <=
+          10) ///@todo: adjust this to a variable number settable with method
       {
         PCL_DEBUG(" CPU: ");
-        for(std::size_t p = 0; p < queries_host.size (); p++)
-        {
+        for (std::size_t p = 0; p < queries_host.size(); p++) {
           // Execute the radiusSearch on the host
           cpu_tmp.clear();
           tree->radiusSearchHost(queries_host[p], tolerance, cpu_tmp, max_answers);
@@ -129,12 +129,12 @@ pcl::gpu::extractEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr
         }
       }
       // If number of queries is high enough do it here
-      else
-      {
+      else {
         PCL_DEBUG(" GPU: ");
         sizes.clear();
         // Copy buffer
-        queries_device = DeviceArray<PointXYZ>(queries_device_buffer.ptr(),queries_host.size());
+        queries_device =
+            DeviceArray<PointXYZ>(queries_device_buffer.ptr(), queries_host.size());
         // Move queries to GPU
         queries_device.upload(queries_host);
         // Execute search
@@ -148,69 +148,84 @@ pcl::gpu::extractEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr
       // Clear queries list
       queries_host.clear();
 
-      if(data.size () == 1)
+      if (data.size() == 1)
         continue;
 
       // Process the results
-      for(auto idx : data)
-      {  
-        if(processed[idx])
+      for (auto idx : data) {
+        if (processed[idx])
           continue;
         processed[idx] = true;
         PointXYZ p;
         pcl::copyPoint((*host_cloud_)[idx], p);
-        queries_host.push_back (p);
+        queries_host.push_back(p);
         found_points++;
         r.indices.push_back(idx);
       }
-      PCL_DEBUG(" data.size: %i, foundpoints: %i, previous: %i", data.size() ,
-              found_points, previous_found_points);
-      PCL_DEBUG(" new points: %i, next queries size: %i\n", found_points - previous_found_points,
-             queries_host.size());
-    }
-    while (previous_found_points < found_points);
+      PCL_DEBUG(" data.size: %i, foundpoints: %i, previous: %i",
+                data.size(),
+                found_points,
+                previous_found_points);
+      PCL_DEBUG(" new points: %i, next queries size: %i\n",
+                found_points - previous_found_points,
+                queries_host.size());
+    } while (previous_found_points < found_points);
     // If this queue is satisfactory, add to the clusters
-    if (found_points >= min_pts_per_cluster && found_points <= max_pts_per_cluster)
-    {
-      std::sort (r.indices.begin (), r.indices.end ());
+    if (found_points >= min_pts_per_cluster && found_points <= max_pts_per_cluster) {
+      std::sort(r.indices.begin(), r.indices.end());
       // @todo: check if the following is actually still needed
-      //r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()), r.indices.end ());
+      // r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()),
+      // r.indices.end ());
 
       r.header = host_cloud_->header;
-      clusters.push_back (r);   // We could avoid a copy by working directly in the vector
+      clusters.push_back(r); // We could avoid a copy by working directly in the vector
     }
   }
 }
 
-template <typename PointT> void
-pcl::gpu::EuclideanClusterExtraction<PointT>::extract (std::vector<pcl::PointIndices> &clusters)
+template <typename PointT>
+void
+pcl::gpu::EuclideanClusterExtraction<PointT>::extract(
+    std::vector<pcl::PointIndices>& clusters)
 {
-/*
-  // Initialize the GPU search tree
-  if (!tree_)
-  {
-    tree_.reset (new pcl::gpu::Octree());
-    ///@todo what do we do if input isn't a PointXYZ cloud?
-    tree_.setCloud(input_);
-  }
-*/
-  if (!tree_->isBuilt())
-  {
+  /*
+    // Initialize the GPU search tree
+    if (!tree_)
+    {
+      tree_.reset (new pcl::gpu::Octree());
+      ///@todo what do we do if input isn't a PointXYZ cloud?
+      tree_.setCloud(input_);
+    }
+  */
+  if (!tree_->isBuilt()) {
     tree_->build();
   }
-/*
-  if(tree_->cloud_.size() != host_cloud.size ())
-  {
-    PCL_ERROR("[pcl::gpu::EuclideanClusterExtraction] size of host cloud and device cloud don't match!\n");
-    return;
-  }
-*/
+  /*
+    if(tree_->cloud_.size() != host_cloud.size ())
+    {
+      PCL_ERROR("[pcl::gpu::EuclideanClusterExtraction] size of host cloud and device
+    cloud don't match!\n"); return;
+    }
+  */
   // Extract the actual clusters
-  extractEuclideanClusters<PointT> (host_cloud_, tree_, cluster_tolerance_, clusters, min_pts_per_cluster_, max_pts_per_cluster_);
+  extractEuclideanClusters<PointT>(host_cloud_,
+                                   tree_,
+                                   cluster_tolerance_,
+                                   clusters,
+                                   min_pts_per_cluster_,
+                                   max_pts_per_cluster_);
   PCL_DEBUG("INFO: end of extractEuclideanClusters\n");
   // Sort the clusters based on their size (largest one first)
-  //std::sort (clusters.rbegin (), clusters.rend (), comparePointClusters);
+  // std::sort (clusters.rbegin (), clusters.rend (), comparePointClusters);
 }
 
-#define PCL_INSTANTIATE_extractEuclideanClusters(T) template void PCL_EXPORTS pcl::gpu::extractEuclideanClusters<T> (const typename pcl::PointCloud<T>::Ptr  &, const pcl::gpu::Octree::Ptr &,float, std::vector<PointIndices> &, unsigned int, unsigned int);
-#define PCL_INSTANTIATE_EuclideanClusterExtraction(T) template class PCL_EXPORTS pcl::gpu::EuclideanClusterExtraction<T>;
+#define PCL_INSTANTIATE_extractEuclideanClusters(T)                                    \
+  template void PCL_EXPORTS pcl::gpu::extractEuclideanClusters<T>(                     \
+      const typename pcl::PointCloud<T>::Ptr&,                                         \
+      const pcl::gpu::Octree::Ptr&,                                                    \
+      float,                                                                           \
+      std::vector<PointIndices>&,                                                      \
+      unsigned int,                                                                    \
+      unsigned int);
+#define PCL_INSTANTIATE_EuclideanClusterExtraction(T)                                  \
+  template class PCL_EXPORTS pcl::gpu::EuclideanClusterExtraction<T>;
index af518d9949276019f680a23521a032bcd43c11d8..21d701f360c367c05e42bae81d04490404879499 100644 (file)
 
 #include <pcl/gpu/segmentation/gpu_extract_labeled_clusters.h>
 
-template <typename PointT> void
-pcl::gpu::extractLabeledEuclideanClusters (const typename pcl::PointCloud<PointT>::Ptr  &host_cloud_,
-                                           const pcl::gpu::Octree::Ptr                  &tree,
-                                           float                                        tolerance,
-                                           std::vector<PointIndices>                    &clusters,
-                                           unsigned int                                 min_pts_per_cluster,
-                                           unsigned int                                 max_pts_per_cluster)
+template <typename PointT>
+void
+pcl::gpu::extractLabeledEuclideanClusters(
+    const typename pcl::PointCloud<PointT>::Ptr& host_cloud_,
+    const pcl::gpu::Octree::Ptr& tree,
+    float tolerance,
+    std::vector<PointIndices>& clusters,
+    unsigned int min_pts_per_cluster,
+    unsigned int max_pts_per_cluster)
 {
 
   // Create a bool vector of processed point indices, and initialize it to false
   // cloud is a DeviceArray<PointType>
-  std::vector<bool> processed (host_cloud_->size (), false);
+  std::vector<bool> processed(host_cloud_->size(), false);
 
   int max_answers;
 
-  if(max_pts_per_cluster > host_cloud_->size ())
-    max_answers = static_cast<int> (host_cloud_->size ());
+  if (max_pts_per_cluster > host_cloud_->size())
+    max_answers = static_cast<int>(host_cloud_->size());
   else
     max_answers = max_pts_per_cluster;
 
@@ -64,8 +66,7 @@ pcl::gpu::extractLabeledEuclideanClusters (const typename pcl::PointCloud<PointT
   pcl::PointIndices r;
 
   // Process all points in the cloud
-  for (std::size_t i = 0; i < host_cloud_->size (); ++i)
-  {
+  for (std::size_t i = 0; i < host_cloud_->size(); ++i) {
     // if we already processed this point continue with the next one
     if (processed[i])
       continue;
@@ -80,23 +81,24 @@ pcl::gpu::extractLabeledEuclideanClusters (const typename pcl::PointCloud<PointT
     // Buffer in a new PointXYZ type
     PointT t = (*host_cloud_)[i];
     PointXYZ p;
-    p.x = t.x; p.y = t.y; p.z = t.z;
+    p.x = t.x;
+    p.y = t.y;
+    p.z = t.z;
 
     // Push the starting point in the vector
-    queries_host.push_back (p);
+    queries_host.push_back(p);
     // Clear vector
-    r.indices.clear ();
+    r.indices.clear();
     // Push the starting point in
-    r.indices.push_back (static_cast<int> (i));
+    r.indices.push_back(static_cast<int>(i));
 
-    unsigned int found_points = static_cast<unsigned int> (queries_host.size ());
+    unsigned int found_points = static_cast<unsigned int>(queries_host.size());
     unsigned int previous_found_points = 0;
 
     pcl::gpu::NeighborIndices result_device;
 
     // once the area stop growing, stop also iterating.
-    while (previous_found_points < found_points)
-    {
+    while (previous_found_points < found_points) {
       // Move queries to GPU
       queries_device.upload(queries_host);
       // Execute search
@@ -109,23 +111,23 @@ pcl::gpu::extractLabeledEuclideanClusters (const typename pcl::PointCloud<PointT
       std::vector<int> sizes, data;
 
       // Copy results from GPU to Host
-      result_device.sizes.download (sizes);
-      result_device.data.download (data);
-
-      for(std::size_t qp = 0; qp < sizes.size (); qp++)
-      {
-        for(int qp_r = 0; qp_r < sizes[qp]; qp_r++)
-        {
-          if(processed[data[qp_r + qp * max_answers]])
+      result_device.sizes.download(sizes);
+      result_device.data.download(data);
+
+      for (std::size_t qp = 0; qp < sizes.size(); qp++) {
+        for (int qp_r = 0; qp_r < sizes[qp]; qp_r++) {
+          if (processed[data[qp_r + qp * max_answers]])
             continue;
           // Only add if label matches the original label
-          if((*host_cloud_)[i].label == (*host_cloud_)[data[qp_r + qp * max_answers]].label)
-          {
+          if ((*host_cloud_)[i].label ==
+              (*host_cloud_)[data[qp_r + qp * max_answers]].label) {
             processed[data[qp_r + qp * max_answers]] = true;
             PointT t_l = (*host_cloud_)[data[qp_r + qp * max_answers]];
             PointXYZ p_l;
-            p_l.x = t_l.x; p_l.y = t_l.y; p_l.z = t_l.z;
-            queries_host.push_back (p_l);
+            p_l.x = t_l.x;
+            p_l.y = t_l.y;
+            p_l.z = t_l.z;
+            queries_host.push_back(p_l);
             found_points++;
             r.indices.push_back(data[qp_r + qp * max_answers]);
           }
@@ -133,45 +135,58 @@ pcl::gpu::extractLabeledEuclideanClusters (const typename pcl::PointCloud<PointT
       }
     }
     // If this queue is satisfactory, add to the clusters
-    if (found_points >= min_pts_per_cluster && found_points <= max_pts_per_cluster)
-    {
-      std::sort (r.indices.begin (), r.indices.end ());
+    if (found_points >= min_pts_per_cluster && found_points <= max_pts_per_cluster) {
+      std::sort(r.indices.begin(), r.indices.end());
       // @todo: check if the following is actually still needed
-      //r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()), r.indices.end ());
+      // r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()),
+      // r.indices.end ());
 
       r.header = host_cloud_->header;
-      clusters.push_back (r);   // We could avoid a copy by working directly in the vector
+      clusters.push_back(r); // We could avoid a copy by working directly in the vector
     }
   }
 }
 
-template <typename PointT> void 
-pcl::gpu::EuclideanLabeledClusterExtraction<PointT>::extract (std::vector<PointIndices> &clusters)
+template <typename PointT>
+void
+pcl::gpu::EuclideanLabeledClusterExtraction<PointT>::extract(
+    std::vector<PointIndices>& clusters)
 {
   // Initialize the GPU search tree
-  if (!tree_)
-  {
-    tree_.reset (new pcl::gpu::Octree());
+  if (!tree_) {
+    tree_.reset(new pcl::gpu::Octree());
     ///@todo what do we do if input isn't a PointXYZ cloud?
     tree_->setCloud(input_);
   }
-  if (!tree_->isBuilt())
-  {
+  if (!tree_->isBuilt()) {
     tree_->build();
   }
-/*
-  if(tree_->cloud_.size() != host_cloud.size ())
-  {
-    PCL_ERROR("[pcl::gpu::EuclideanClusterExtraction] size of host cloud and device cloud don't match!\n");
-    return;
-  }
-*/
+  /*
+    if(tree_->cloud_.size() != host_cloud.size ())
+    {
+      PCL_ERROR("[pcl::gpu::EuclideanClusterExtraction] size of host cloud and device
+    cloud don't match!\n"); return;
+    }
+  */
   // Extract the actual clusters
-  extractLabeledEuclideanClusters<PointT> (host_cloud_, tree_, cluster_tolerance_, clusters, min_pts_per_cluster_, max_pts_per_cluster_);
+  extractLabeledEuclideanClusters<PointT>(host_cloud_,
+                                          tree_,
+                                          cluster_tolerance_,
+                                          clusters,
+                                          min_pts_per_cluster_,
+                                          max_pts_per_cluster_);
 
   // Sort the clusters based on their size (largest one first)
-  std::sort (clusters.rbegin (), clusters.rend (), compareLabeledPointClusters);
+  std::sort(clusters.rbegin(), clusters.rend(), compareLabeledPointClusters);
 }
 
-#define PCL_INSTANTIATE_extractLabeledEuclideanClusters(T) template void PCL_EXPORTS pcl::gpu::extractLabeledEuclideanClusters<T> (const typename pcl::PointCloud<T>::Ptr  &, const pcl::gpu::Octree::Ptr &,float, std::vector<PointIndices> &, unsigned int, unsigned int);
-#define PCL_INSTANTIATE_EuclideanLabeledClusterExtraction(T) template class PCL_EXPORTS pcl::gpu::EuclideanLabeledClusterExtraction<T>;
+#define PCL_INSTANTIATE_extractLabeledEuclideanClusters(T)                             \
+  template void PCL_EXPORTS pcl::gpu::extractLabeledEuclideanClusters<T>(              \
+      const typename pcl::PointCloud<T>::Ptr&,                                         \
+      const pcl::gpu::Octree::Ptr&,                                                    \
+      float,                                                                           \
+      std::vector<PointIndices>&,                                                      \
+      unsigned int,                                                                    \
+      unsigned int);
+#define PCL_INSTANTIATE_EuclideanLabeledClusterExtraction(T)                           \
+  template class PCL_EXPORTS pcl::gpu::EuclideanLabeledClusterExtraction<T>;
index d46a1a96ccebb5d82777d617d701c9b5c6927822..b1f2594c2b4d10ce58d60c553ffcefd5b3d42f8f 100644 (file)
 
 //////////////////////////////////////////////////////////////////////////////////////////////
 void
-seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud_,
-                       const pcl::gpu::Octree::Ptr                   &tree,
-                       float                                         tolerance,
-                       PointIndices                                  &indices_in,
-                       PointIndices                                  &indices_out,
-                       float                                         delta_hue)
+seededHueSegmentation(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr& host_cloud_,
+                      const pcl::gpu::Octree::Ptr& tree,
+                      float tolerance,
+                      PointIndices& indices_in,
+                      PointIndices& indices_out,
+                      float delta_hue)
 {
 
   // Create a bool vector of processed point indices, and initialize it to false
   // cloud is a DeviceArray<PointType>
-  std::vector<bool> processed (host_cloud_->size (), false);
+  std::vector<bool> processed(host_cloud_->size(), false);
 
   const auto max_answers = host_cloud_->size();
 
   // Process all points in the indices vector
-  for (std::size_t k = 0; k < indices_in.indices.size (); ++k)
-  {
+  for (std::size_t k = 0; k < indices_in.indices.size(); ++k) {
     int i = indices_in.indices[k];
     // if we already processed this point continue with the next one
     if (processed[i])
@@ -67,7 +66,7 @@ seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud
     // now we will process this point
     processed[i] = true;
 
-    PointXYZRGB  p;
+    PointXYZRGB p;
     p = (*host_cloud_)[i];
     PointXYZHSV h;
     PointXYZRGBtoXYZHSV(p, h);
@@ -77,9 +76,9 @@ seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud
     // Create the query queue on the host
     pcl::PointCloud<pcl::PointXYZ>::VectorType queries_host;
     // Push the starting point in the vector
-    queries_host.push_back ((*host_cloud_)[i]);
+    queries_host.push_back((*host_cloud_)[i]);
 
-    unsigned int found_points = queries_host.size ();
+    unsigned int found_points = queries_host.size();
     unsigned int previous_found_points = 0;
 
     pcl::gpu::NeighborIndices result_device;
@@ -88,8 +87,7 @@ seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud
     std::vector<int> sizes, data;
 
     // once the area stop growing, stop also iterating.
-    while (previous_found_points < found_points)
-    {
+    while (previous_found_points < found_points) {
       // Move queries to GPU
       queries_device.upload(queries_host);
       // Execute search
@@ -99,37 +97,33 @@ seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud
       previous_found_points = found_points;
 
       // Clear the Host vectors
-      sizes.clear (); data.clear ();
+      sizes.clear();
+      data.clear();
 
       // Copy results from GPU to Host
-      result_device.sizes.download (sizes);
-      result_device.data.download (data);
-
-      for(std::size_t qp = 0; qp < sizes.size (); qp++)
-      {
-        for(int qp_r = 0; qp_r < sizes[qp]; qp_r++)
-        {
-          if(processed[data[qp_r + qp * max_answers]])
+      result_device.sizes.download(sizes);
+      result_device.data.download(data);
+
+      for (std::size_t qp = 0; qp < sizes.size(); qp++) {
+        for (int qp_r = 0; qp_r < sizes[qp]; qp_r++) {
+          if (processed[data[qp_r + qp * max_answers]])
             continue;
 
-          PointXYZRGB  p_l;
+          PointXYZRGB p_l;
           p_l = (*host_cloud_)[data[qp_r + qp * max_answers]];
           PointXYZHSV h_l;
           PointXYZRGBtoXYZHSV(p_l, h_l);
 
-          if (std::abs(h_l.h - h.h) < delta_hue)
-          {
+          if (std::abs(h_l.h - h.h) < delta_hue) {
             processed[data[qp_r + qp * max_answers]] = true;
-            queries_host.push_back ((*host_cloud_)[data[qp_r + qp * max_answers]]);
+            queries_host.push_back((*host_cloud_)[data[qp_r + qp * max_answers]]);
             found_points++;
           }
         }
       }
     }
-    for(std::size_t qp = 0; qp < sizes.size (); qp++)
-    {
-      for(int qp_r = 0; qp_r < sizes[qp]; qp_r++)
-      {
+    for (std::size_t qp = 0; qp < sizes.size(); qp++) {
+      for (int qp_r = 0; qp_r < sizes[qp]; qp_r++) {
         indices_out.indices.push_back(data[qp_r + qp * max_answers]);
       }
     }
@@ -137,29 +131,29 @@ seededHueSegmentation (const pcl::PointCloud<pcl::PointXYZRGB>::Ptr  &host_cloud
   // @todo: do we need to sort here and remove double points?
 }
 
-void 
-pcl::gpu::SeededHueSegmentation::segment (PointIndices &indices_in, PointIndices &indices_out)
+void
+pcl::gpu::SeededHueSegmentation::segment(PointIndices& indices_in,
+                                         PointIndices& indices_out)
 {
   // Initialize the GPU search tree
-  if (!tree_)
-  {
-    tree_.reset (new pcl::gpu::Octree());
+  if (!tree_) {
+    tree_.reset(new pcl::gpu::Octree());
     ///@todo what do we do if input isn't a PointXYZ cloud?
     tree_->setCloud(input_);
   }
-  if (!tree_->isBuild())
-  {
+  if (!tree_->isBuild()) {
     tree_->build();
   }
-/*
-  if(tree_->cloud_.size() != host_cloud.size ())
-  {
-    PCL_ERROR("[pcl::gpu::SeededHueSegmentation] size of host cloud and device cloud don't match!\n");
-    return;
-  }
-*/
+  /*
+    if(tree_->cloud_.size() != host_cloud.size ())
+    {
+      PCL_ERROR("[pcl::gpu::SeededHueSegmentation] size of host cloud and device cloud
+    don't match!\n"); return;
+    }
+  */
   // Extract the actual clusters
-  seededHueSegmentation (host_cloud_, tree_, cluster_tolerance_, indices_in, indices_out, delta_hue_);
+  seededHueSegmentation(
+      host_cloud_, tree_, cluster_tolerance_, indices_in, indices_out, delta_hue_);
 }
 
-#endif //PCL_GPU_SEGMENTATION_IMPL_SEEDED_HUE_SEGMENTATION_H_
+#endif // PCL_GPU_SEGMENTATION_IMPL_SEEDED_HUE_SEGMENTATION_H_
index ef12475408270ddc8324a48957b063fe44c45af4..c53b225560441308cef5013edba4c0f72e328df0 100644 (file)
@@ -1,7 +1,7 @@
 set(SUBSYS_NAME gpu_surface)
 set(SUBSYS_PATH gpu/surface)
 set(SUBSYS_DESC "Surface algorithms with GPU")
-set(SUBSYS_DEPS common gpu_containers gpu_utils visualization geometry)
+set(SUBSYS_DEPS common gpu_containers gpu_utils geometry)
 
 set(build FALSE)
 PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" OFF)
@@ -25,13 +25,10 @@ source_group("Source Files\\cuda" FILES ${cuda})
 
 list(APPEND srcs ${utils} ${cuda})
 
-
-include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
-
 set(LIB_NAME "pcl_${SUBSYS_NAME}")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src" "${CMAKE_CURRENT_SOURCE_DIR}/src/cuda")
 PCL_CUDA_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs})
-target_link_libraries("${LIB_NAME}" pcl_gpu_containers pcl_visualization)
+target_link_libraries("${LIB_NAME}" pcl_gpu_containers)
 
 set(EXT_DEPS "")
 #set(EXT_DEPS CUDA)
index ab918424e07a9f30104c06caac5c92912b36f996..163639b0252958188c25f7d9089574b589826ceb 100644 (file)
@@ -1,13 +1,14 @@
 set(SUBSYS_NAME io)
 set(SUBSYS_DESC "Point cloud IO library")
 set(SUBSYS_DEPS common octree)
+set(SUBSYS_EXT_DEPS boost eigen)
 
 set(build TRUE)
 PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON)
 if(WIN32)
-  PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS} OPT_DEPS openni openni2 ensenso davidSDK dssdk rssdk rssdk2 pcap png vtk)
+  PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS} OPT_DEPS openni openni2 ensenso davidSDK dssdk rssdk rssdk2 pcap png vtk EXT_DEPS ${SUBSYS_EXT_DEPS})
 else()
-  PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS} OPT_DEPS openni openni2 ensenso davidSDK dssdk pcap png vtk libusb)
+  PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS} OPT_DEPS openni openni2 ensenso davidSDK dssdk pcap png vtk libusb EXT_DEPS ${SUBSYS_EXT_DEPS})
 endif()
 
 PCL_ADD_DOC("${SUBSYS_NAME}")
@@ -190,7 +191,7 @@ if(VTK_FOUND AND NOT ANDROID)
     src/vtk_lib_io.cpp
     src/png_io.cpp
   )
-  set(VTK_IO_TARGET_LINK_LIBRARIES vtkCommon vtkWidgets vtkIO vtkImaging vtkHybrid vtkGraphics vtkRendering vtkFiltering vtkVolumeRendering)
+
   # Indicates that we can rely on VTK to be present
   set(VTK_DEFINES -DPCL_BUILT_WITH_VTK)
 endif()
@@ -210,6 +211,7 @@ if(MINGW)
 endif()
 PCL_ADD_INCLUDES("${SUBSYS_NAME}" "${SUBSYS_NAME}/ply" ${PLY_INCLUDES})
 target_include_directories(pcl_io_ply PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_link_libraries(pcl_io_ply Boost::boost)
 
 set(srcs
   src/debayer.cpp
@@ -229,6 +231,7 @@ set(srcs
   src/robot_eye_grabber.cpp
   src/auto_io.cpp
   src/io_exception.cpp
+  src/tim_grabber.cpp
   ${VTK_IO_SOURCE}
   ${OPENNI_GRABBER_SOURCES}
   ${OPENNI2_GRABBER_SOURCES}
@@ -280,6 +283,7 @@ set(incs
   "include/pcl/${SUBSYS_NAME}/robot_eye_grabber.h"
   "include/pcl/${SUBSYS_NAME}/point_cloud_image_extractors.h"
   "include/pcl/${SUBSYS_NAME}/io_exception.h"
+  "include/pcl/${SUBSYS_NAME}/tim_grabber.h"
   ${VTK_IO_INCLUDES}
   ${OPENNI_GRABBER_INCLUDES}
   ${OPENNI2_GRABBER_INCLUDES}
@@ -338,16 +342,26 @@ PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${c
 
 target_include_directories(${LIB_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
 
-target_link_libraries("${LIB_NAME}" pcl_common pcl_io_ply)
+target_link_libraries("${LIB_NAME}" Boost::boost Boost::filesystem Boost::iostreams pcl_common pcl_io_ply)
+
 if(VTK_FOUND)
-  if(${VTK_VERSION} VERSION_LESS 9.0)
-    link_directories(${VTK_LINK_DIRECTORIES})
-    target_link_libraries("${LIB_NAME}" ${VTK_LIBRARIES})
-  else()
+  if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
     target_link_libraries("${LIB_NAME}" 
                           VTK::IOImage
                           VTK::IOGeometry
                           VTK::IOPLY)
+  else()
+    link_directories(${VTK_LINK_DIRECTORIES})
+    target_link_libraries("${LIB_NAME}"
+                          vtkIOImage
+                          vtkIOGeometry
+                          vtkIOMPIImage
+                          vtkIOMPIParallel
+                          vtkIOPLY
+                          )
+    if(${VTK_VERSION} VERSION_GREATER_EQUAL 7.0 AND ${VTK_VERSION} VERSION_LESS 8.0)
+      target_link_libraries("${LIB_NAME}" vtkFiltersParallelDIY2)
+    endif()
   endif()
 endif()
 
@@ -401,7 +415,7 @@ if(PCAP_FOUND)
   target_link_libraries("${LIB_NAME}" ${PCAP_LIBRARIES})
 endif()
 
-set(EXT_DEPS eigen3)
+set(EXT_DEPS boost eigen3)
 
 if(WITH_OPENNI)
   list(APPEND EXT_DEPS libopenni)
index c2160796c9475b86e3dfcbe736d5846fa338d334..a77e1e7e5c2bcde031bf0572f974342a2ee764c1 100644 (file)
@@ -288,8 +288,6 @@ namespace pcl
       std::uint32_t compressedColorSize;
 
       // PNG decoded parameters
-      std::size_t png_width = 0;
-      std::size_t png_height = 0;
       unsigned int png_channels = 1;
 
       // sync to frame header
@@ -328,6 +326,9 @@ namespace pcl
         compressedColor.resize (compressedColorSize);
         compressedDataIn_arg.read (reinterpret_cast<char*> (&compressedColor[0]), compressedColorSize * sizeof(std::uint8_t));
 
+        std::size_t png_width = 0;
+        std::size_t png_height = 0;
+
         // decode PNG compressed disparity data
         decodePNGToImage (compressedDisparity, disparityData, png_width, png_height, png_channels);
 
index 035cae3878926d8fbb4a5b6ebc5b249c6f346aea..477ed686f899eb1f44a91a58d3904eb74827c6b2 100644 (file)
@@ -190,9 +190,9 @@ pcl::io::vtkStructuredGridToPointCloud (vtkStructuredGrid* const structured_grid
       {
         int queryPoint[3] = {i, j, 0};
         vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
-        double coordinate[3];
         if (structured_grid->IsPointVisible (pointId))
         {
+          double coordinate[3];
           structured_grid->GetPoint (pointId, coordinate);
           pcl::setFieldValue<PointT, float> (cloud (i, j), x_idx, coordinate[0]);
           pcl::setFieldValue<PointT, float> (cloud (i, j), y_idx, coordinate[1]);
@@ -228,9 +228,9 @@ pcl::io::vtkStructuredGridToPointCloud (vtkStructuredGrid* const structured_grid
       {
         int queryPoint[3] = {i, j, 0};
         vtkIdType pointId = vtkStructuredData::ComputePointId (dimensions, queryPoint);
-        float normal[3];
         if (structured_grid->IsPointVisible (pointId))
         {
+          float normal[3];
           normals->GetTupleValue (i, normal);
           pcl::setFieldValue<PointT, float> (cloud (i, j), normal_x_idx, normal[0]);
           pcl::setFieldValue<PointT, float> (cloud (i, j), normal_y_idx, normal[1]);
index 6a1a5e6e8447f870326154bb2ae13be1220a203d..9d5b23adf309d4f78468be23db77ade113c70aa5 100644 (file)
@@ -61,6 +61,7 @@ namespace pcl
   public:
     /** \brief Constructor
     * \param[in] file_name_or_serial_number used for either loading bag file or specific device by serial number
+    * \param[in] repeat_playback whether to repeat playback when reading from file
     */
     RealSense2Grabber ( const std::string& file_name_or_serial_number = "", const bool repeat_playback = true );
 
diff --git a/io/include/pcl/io/tim_grabber.h b/io/include/pcl/io/tim_grabber.h
new file mode 100644 (file)
index 0000000..d0cd96a
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *  Point Cloud Library (PCL) - www.pointclouds.org
+ *  Copyright (c) 2020-, Open Perception
+ *  Copyright (c) 2020, ysuzuki19
+ *
+ *  All rights reserved
+ */
+
+#pragma once
+
+#include <pcl/pcl_exports.h>
+#include <pcl/console/print.h>
+#include <pcl/common/time.h>
+#include <pcl/io/grabber.h>
+#include <pcl/point_types.h>
+#include <pcl/point_cloud.h>
+#include <boost/asio.hpp>
+#include <boost/thread.hpp>
+#include <vector>
+#include <string>
+#include <thread>
+
+namespace pcl
+{
+
+//// note: Protcol named CoLaA (used by SICK) has some information.
+////       In this Grabber, only the amount_of_data is used, so other information is truncated.
+////       Details of the protocol can be found at the following URL.
+
+//// pp.87~89 (table)
+
+//// https://cdn.sickcn.com/media/docs/7/27/927/technical_information_telegram_listing_ranging_sensors_lms1xx_lms5xx_tim2xx_tim5xx_tim7xx_lms1000_mrs1000_mrs6000_nav310_ld_oem15xx_ld_lrs36xx_lms4000_en_im0045927.pdf
+
+
+//// By this PDF, the header contains the following information in order
+
+/////////////////////////////////////////////////////
+//// command type
+//// command
+//// version number
+//// device number
+//// serial number (2 value)
+//// device status
+//// Telegram counter
+//// Scan counter
+//// Time since start up
+//// Time of transmission
+//// Status of digital inputs (2 value)
+//// Status of digital outputs (2 value)
+//// Reserved
+//// scan frequency
+//// measurement frequency
+//// Amount of encoder
+//// Amount of 16 bit channels
+//// Content
+//// Scale factor according to IEEE754
+//// Scale factor offset according to IEEE754
+//// Start angle
+//// Size of single angular step
+//// Amount of data
+//// distance_1
+//// distance_2
+//// distance_3
+//// ...
+//// distance_n
+/////////////////////////////////////////////////////
+
+
+class PCL_EXPORTS TimGrabber : public Grabber
+{
+  public:
+    using sig_cb_sick_tim_scan_point_cloud_xyz = void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&);
+
+    TimGrabber ();
+    TimGrabber (const boost::asio::ip::address& ipAddress, const std::uint16_t port);
+    ~TimGrabber () noexcept;
+
+    void
+    start () override;
+
+    void
+    stop () override;
+
+    std::string
+    getName () const override;
+
+    bool
+    isRunning () const override;
+
+  protected:
+    pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_xyz_ptr_;
+    boost::signals2::signal<sig_cb_sick_tim_scan_point_cloud_xyz>* point_cloud_xyz_signal_;
+
+    void
+    publishSignal ();
+
+    //// parse received packet
+    //// used by GTEST
+    void
+    processTimPacket (std::string const& packet);
+
+    //// check size of lookup tables
+    //// rebuild if lookup tables have different size
+    void
+    updateLookupTables ();
+
+    //// convert std::vector (distance) to pcl::PointCloud
+    //// used by GTEST
+    void
+    toPointClouds ();
+
+  private:
+    constexpr static float angle_start_ = - 1.0 * M_PI / 4.0;
+    constexpr static float angle_range_ = 2.0 * M_PI * 3.0 / 4.0;
+
+    //// lookup tables for calculaing 2d-coordinate
+    //// reset lookup tables if amount of received data is different
+    std::vector<float> cos_dynamic_lookup_table_;
+    std::vector<float> sin_dynamic_lookup_table_;
+
+    std::array<char, 4000> received_packet_;
+    std::size_t length_;
+    std::istringstream iss_;
+
+    std::size_t amount_of_data_ = 811;
+    std::vector<float> distances_;
+
+    boost::asio::ip::tcp::endpoint tcp_endpoint_;
+    boost::asio::io_service tim_io_service_;
+    boost::asio::ip::tcp::socket tim_socket_;
+    //// wait time for receiving data (on the order of milliseconds)
+    unsigned int wait_time_milliseconds_ = 0;
+
+    pcl::EventFrequency frequency_;
+    mutable boost::mutex frequency_mutex_;
+
+    std::thread grabber_thread_;
+    bool is_running_ = false;
+
+    void
+    initialize ();
+
+    float
+    getFramesPerSecond () const override;
+
+    void
+    buildLookupTables ();
+
+    //// check received packet is valid
+    bool
+    isValidPacket () const;
+
+    //// receive packet (named CoLaA; SICK sensors Communication Language)
+    void
+    receiveTimPacket ();
+
+    void
+    parsePacketHeader (std::string const& header);
+    void
+    parsePacketBody (std::string const& body);
+
+    void
+    processGrabbing ();
+};
+}
index 8c19b03b667433b489d85ff9103425503c955201..28f7c485366cb724c6c7c91b9c9c782ab65c10fd 100644 (file)
@@ -113,6 +113,11 @@ bool pcl::io::ply::ply_parser::parse (const std::string& filename)
       std::string format_string, version;
       char space_format_format_string, space_format_string_version;
       stringstream >> space_format_format_string >> std::ws >> format_string >> space_format_string_version >> std::ws >> version;
+      if (!stringstream.eof ())
+      {
+        stringstream >> std::ws;
+        warning_callback_ (line_number_, "parse warning: trailing whitespaces in the header");
+      }
       if (!stringstream ||
           !stringstream.eof () ||
           !isspace (space_format_format_string) ||
@@ -158,6 +163,11 @@ bool pcl::io::ply::ply_parser::parse (const std::string& filename)
       std::size_t count;
       char space_element_name, space_name_count;
       stringstream >> space_element_name >> std::ws >> name >> space_name_count >> std::ws >> count;
+      if (!stringstream.eof ())
+      {
+        stringstream >> std::ws;
+        warning_callback_ (line_number_, "parse warning: trailing whitespaces in the header");
+      }
       if (!stringstream ||
           !stringstream.eof () ||
           !isspace (space_element_name) ||
@@ -359,7 +369,10 @@ bool pcl::io::ply::ply_parser::parse (const std::string& filename)
             return false;
           }
         }
-        else if ((size_type_string == type_traits<uint32>::name ()) || (size_type_string == type_traits<uint32>::old_name ()))
+        // It is safe to use size_type = uint32 here even if it is actually int32, because the size/number of list entries is never negative,
+        // uint32 and int32 have the same width, and all allowed (non-negative) values have the same binary encoding in int32 and uint32.
+        else if ((size_type_string == type_traits<uint32>::name ()) || (size_type_string == type_traits<uint32>::old_name ()) ||
+                 (size_type_string == type_traits< int32>::name ()) || (size_type_string == type_traits< int32>::old_name ()))
         {
           using size_type = uint32;
           if ((scalar_type_string == type_traits<int8>::name ()) || (scalar_type_string == type_traits<int8>::old_name ()))
index 5c0dfe1cc1e46df316036fcba4bcaf5ea8dac1d0..48c0c648f7aafac39ab7f3bc7434d3f81cddfc89 100644 (file)
@@ -306,52 +306,26 @@ namespace pcl
     vertex_offset_before_ += static_cast<int> (sizeof (ContentType));
   }
 
-  template <>
-  std::tuple<std::function<void (pcl::io::ply::uint8)>, std::function<void (pcl::io::ply::int32)>, std::function<void ()> >
+  template <typename SizeType, typename ContentType>
+  std::tuple<std::function<void (SizeType)>, std::function<void (ContentType)>, std::function<void ()> >
   pcl::PLYReader::listPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name)
   {
     if ((element_name == "range_grid") && (property_name == "vertex_indices" || property_name == "vertex_index"))
     {
-      return std::tuple<std::function<void (pcl::io::ply::uint8)>, std::function<void (pcl::io::ply::int32)>, std::function<void ()> > (
-        [this] (pcl::io::ply::uint8 size) { rangeGridVertexIndicesBeginCallback (size); },
-        [this] (pcl::io::ply::int32 vertex_index) { rangeGridVertexIndicesElementCallback (vertex_index); },
+      return std::tuple<std::function<void (SizeType)>, std::function<void (ContentType)>, std::function<void ()> > (
+        [this] (SizeType size) { rangeGridVertexIndicesBeginCallback (size); },
+        [this] (ContentType vertex_index) { rangeGridVertexIndicesElementCallback (vertex_index); },
         [this] { rangeGridVertexIndicesEndCallback (); }
       );
     }
     if ((element_name == "face") && (property_name == "vertex_indices" || property_name == "vertex_index") && polygons_)
     {
-      return std::tuple<std::function<void (pcl::io::ply::uint8)>, std::function<void (pcl::io::ply::int32)>, std::function<void ()> > (
-        [this] (pcl::io::ply::uint8 size) { faceVertexIndicesBeginCallback (size); },
-        [this] (pcl::io::ply::int32 vertex_index) { faceVertexIndicesElementCallback (vertex_index); },
+      return std::tuple<std::function<void (SizeType)>, std::function<void (ContentType)>, std::function<void ()> > (
+        [this] (SizeType size) { faceVertexIndicesBeginCallback (size); },
+        [this] (ContentType vertex_index) { faceVertexIndicesElementCallback (vertex_index); },
         [this] { faceVertexIndicesEndCallback (); }
       );
     }
-    if (element_name == "vertex")
-    {
-      cloud_->fields.emplace_back();
-      pcl::PCLPointField &current_field = cloud_->fields.back ();
-      current_field.name = property_name;
-      current_field.offset = cloud_->point_step;
-      current_field.datatype = pcl::traits::asEnum<pcl::io::ply::int32>::value;
-      current_field.count = 1u; // value will be updated once first vertex is read
-      if (sizeof (pcl::io::ply::int32) + cloud_->point_step < std::numeric_limits<std::uint32_t>::max ())
-          cloud_->point_step += static_cast<std::uint32_t> (sizeof (pcl::io::ply::int32));
-      else
-        cloud_->point_step = static_cast<std::uint32_t> (std::numeric_limits<std::uint32_t>::max ());
-      do_resize_ = true;
-      return std::tuple<std::function<void (pcl::io::ply::uint8)>, std::function<void (pcl::io::ply::int32)>, std::function<void ()> > (
-        std::bind (&pcl::PLYReader::vertexListPropertyBeginCallback<pcl::io::ply::uint8>, this, property_name, std::placeholders::_1),
-        [this] (pcl::io::ply::int32 value) { vertexListPropertyContentCallback<pcl::io::ply::int32> (value); },
-        [this] { vertexListPropertyEndCallback (); }
-      );
-    }
-    return {};
-  }
-
-  template <typename SizeType, typename ContentType>
-  std::tuple<std::function<void (SizeType)>, std::function<void (ContentType)>, std::function<void ()> >
-  pcl::PLYReader::listPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name)
-  {
     if (element_name == "vertex")
     {
       cloud_->fields.emplace_back();
@@ -371,6 +345,7 @@ namespace pcl
         [this] { vertexListPropertyEndCallback (); }
       );
     }
+    PCL_WARN("[pcl::PLYReader::listPropertyDefinitionCallback] no fitting callbacks. element_name=%s, property_name=%s\n", element_name.c_str(), property_name.c_str());
     return {};
   }
 }
diff --git a/io/src/tim_grabber.cpp b/io/src/tim_grabber.cpp
new file mode 100644 (file)
index 0000000..38a3265
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *  Point Cloud Library (PCL) - www.pointclouds.org
+ *  Copyright (c) 2020-, Open Perception
+ *  Copyright (c) 2020, ysuzuki19
+ *
+ *  All rights reserved
+ */
+
+#include <pcl/io/tim_grabber.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+pcl::TimGrabber::TimGrabber () :
+    tim_socket_ (tim_io_service_)
+{
+  initialize ();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+pcl::TimGrabber::TimGrabber (const boost::asio::ip::address& ipAddress,
+                             const std::uint16_t port) :
+    tcp_endpoint_ (ipAddress, port),
+    tim_socket_ (tim_io_service_)
+{
+  initialize ();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+pcl::TimGrabber::~TimGrabber () noexcept
+{
+  stop ();
+
+  disconnect_all_slots<sig_cb_sick_tim_scan_point_cloud_xyz> ();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::initialize ()
+{
+  buildLookupTables ();
+
+  point_cloud_xyz_signal_ = createSignal<sig_cb_sick_tim_scan_point_cloud_xyz> ();
+
+  point_cloud_xyz_ptr_.reset (new pcl::PointCloud<pcl::PointXYZ>);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+float
+pcl::TimGrabber::getFramesPerSecond () const
+{
+  boost::mutex::scoped_lock lock (frequency_mutex_);
+  return (frequency_.getFrequency ());
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::buildLookupTables () {
+  const float angle_step = angle_range_ / static_cast<float> (amount_of_data_);
+  float angle = angle_start_;
+
+  cos_dynamic_lookup_table_.reserve (amount_of_data_);
+  cos_dynamic_lookup_table_.clear ();
+  sin_dynamic_lookup_table_.reserve (amount_of_data_);
+  sin_dynamic_lookup_table_.clear ();
+
+  for (std::size_t i = 0; i < amount_of_data_; i++, angle += angle_step)
+  {
+    cos_dynamic_lookup_table_.push_back (std::cos (angle));
+    sin_dynamic_lookup_table_.push_back (std::sin (angle));
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::updateLookupTables () {
+  //// note: cos, sin are the same size
+  if (cos_dynamic_lookup_table_.size () != amount_of_data_)
+    buildLookupTables ();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+bool
+pcl::TimGrabber::isValidPacket () const {
+  return received_packet_.data ()[length_-1] == '\03';
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::receiveTimPacket ()
+{
+  if (!tim_socket_.is_open ())
+    return;
+
+  tim_socket_.send (boost::asio::buffer ("\x02sRN LMDscandata 1\x03\0"));
+
+  std::this_thread::sleep_for (std::chrono::milliseconds (wait_time_milliseconds_));
+
+  length_ = tim_socket_.receive (boost::asio::buffer (received_packet_));
+
+  if (!isValidPacket ()) {
+    //// Countup wait_time
+    //// Because fit wait_time to network latency
+    wait_time_milliseconds_++;
+
+    //// Clear invalid packet in socket
+    while (!isValidPacket ())
+      length_ = tim_socket_.receive (boost::asio::buffer (received_packet_));
+
+    //// If received packet is invalid, recurse
+    receiveTimPacket ();
+  }
+}
+
+void
+pcl::TimGrabber::parsePacketHeader (std::string const& header) {
+  //// note:  Please following part, if you want to use other information in the header.
+  //std::size_t pos = header.find (' ');
+  //for (int i=0; i<24; ++i)
+    //pos = header.find (' ', pos+1);
+
+  std::size_t pos = header.rfind (' ');
+  amount_of_data_ = std::stoi (header.substr (pos+1), nullptr, 16);
+}
+
+void
+pcl::TimGrabber::parsePacketBody (std::string const& body) {
+  iss_.clear ();
+  iss_.str (body);
+  iss_.setf (std::ios::hex, std::ios::basefield);
+  int d;
+  for (auto& distance : distances_) {
+    iss_ >> d;
+    distance = d / 1000.0;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::processTimPacket (std::string const& packet)
+{
+  std::size_t header_body_splitter = packet.find (' ');
+  for (int i=0; i<25; ++i)
+    header_body_splitter = packet.find (' ', header_body_splitter + 1);
+
+  //// packet contains header and body.
+  //// header has 26 spaces, the rest is body
+  std::string header (packet.substr (0, header_body_splitter));
+  std::string body   (packet.substr (header_body_splitter + 1));
+
+  parsePacketHeader (header);
+
+  distances_.resize (amount_of_data_);
+
+  parsePacketBody (body);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::toPointClouds () {
+  point_cloud_xyz_ptr_->resize (distances_.size ());
+  for (std::size_t i=0; i<distances_.size (); ++i) {
+    point_cloud_xyz_ptr_->points[i].x = distances_[i] * cos_dynamic_lookup_table_[i];
+    point_cloud_xyz_ptr_->points[i].y = distances_[i] * sin_dynamic_lookup_table_[i];
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::publishSignal ()
+{
+  point_cloud_xyz_signal_->operator () (point_cloud_xyz_ptr_);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::start ()
+{
+  if (isRunning ())
+    return;
+
+  is_running_ = true;
+
+  try {
+    boost::asio::ip::tcp::resolver resolver (tim_io_service_);
+    tcp_endpoint_ = *resolver.resolve (tcp_endpoint_);
+    tim_socket_.connect (tcp_endpoint_);
+  }
+  catch (std::exception& e)
+  {
+    PCL_ERROR ("[pcl::TimGrabber::start] Unable to bind to socket! %s\n", e.what ());
+    return;
+  }
+  grabber_thread_ = std::thread (&TimGrabber::processGrabbing, this);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::stop ()
+{
+  if (is_running_) {
+    is_running_ = false;
+    grabber_thread_.join ();
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+bool
+pcl::TimGrabber::isRunning () const
+{
+  return is_running_;
+}
+
+std::string
+pcl::TimGrabber::getName () const
+{
+  return (std::string ("Sick Tim Grabber"));
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void
+pcl::TimGrabber::processGrabbing ()
+{
+  while (is_running_)
+  {
+    frequency_mutex_.lock ();
+    frequency_.event ();
+    frequency_mutex_.unlock ();
+
+    receiveTimPacket ();
+    processTimPacket (received_packet_.data ());
+
+    updateLookupTables ();
+    toPointClouds ();
+
+    publishSignal ();
+  }
+}
index 651bb00daa5e775d5aa7ea16c4f512c27e786a32..818da1d99c8939e24228bbb022d8af736881db97 100644 (file)
@@ -9,7 +9,7 @@ if(WITH_OPENNI)
 
 
   PCL_ADD_EXECUTABLE(pcl_openni_pcd_recorder COMPONENT ${SUBSYS_NAME} SOURCES openni_pcd_recorder.cpp)
-  target_link_libraries(pcl_openni_pcd_recorder pcl_common pcl_io)
+  target_link_libraries(pcl_openni_pcd_recorder pcl_common pcl_io Boost::date_time)
 endif()
 
 PCL_ADD_EXECUTABLE(pcl_pcd_convert_NaN_nan COMPONENT ${SUBSYS_NAME} SOURCES pcd_convert_NaN_nan.cpp)
index a20ed99833e03a305c05a1bbd1852b9166495590..e41b96c7a295206b2d5a0d8fb6b7b7a7fd7ab79c 100644 (file)
@@ -73,7 +73,7 @@ using NotCompatWithFlann = std::enable_if_t<!compat_with_flann<IndexT>::value, b
  * @brief Comaptibility template function to allow use of various types of indices with
  * FLANN
  * @details Template is used for all params to not constrain any FLANN side capability
- * @param[in|out] index A index searcher, of type ::flann::Index<Dist> or similar, where
+ * @param[in,out] index A index searcher, of type ::flann::Index<Dist> or similar, where
  * Dist is a template for computing distance between 2 points
  * @param[in] query A ::flann::Matrix<float> or compatible matrix representation of the
  * query point
@@ -99,14 +99,14 @@ radius_search(const FlannIndex& index,
  * @brief Comaptibility template function to allow use of various types of indices with
  * FLANN
  * @details Template is used for all params to not constrain any FLANN side capability
- * @param[in|out] index A index searcher, of type ::flann::Index<Dist> or similar, where
+ * @param[in,out] index A index searcher, of type ::flann::Index<Dist> or similar, where
  * Dist is a template for computing distance between 2 points
  * @param[in] query A ::flann::Matrix<float> or compatible matrix representation of the
  * query point
  * @param[out] indices Neighboring k indices found
  * @param[out] dists Computed distance matrix
- * @param[in] radius Threshold for consideration
- * @param[in] params Any parameters to pass to the radius_search call
+ * @param[in] k Number of neighbors to search for
+ * @param[in] params Any parameters to pass to the knn_search call
  */
 template <class FlannIndex,
           class Query,
index 550c6e30b3c96c50ecd8cc27593ef68c4b74338c..23f331235f41593be018b05c3273e8ff4133f9e6 100644 (file)
@@ -101,6 +101,20 @@ pcl::ISSKeypoint3D<PointInT, PointOutT, NormalT>::setNormals (const PointCloudNC
   normals_ = normals;
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////////
+template<typename PointInT, typename PointOutT, typename NormalT> void
+pcl::ISSKeypoint3D<PointInT, PointOutT, NormalT>::setNumberOfThreads (unsigned int nr_threads)
+{
+  if (nr_threads == 0)
+#ifdef _OPENMP
+    threads_ = omp_get_num_procs();
+#else
+    threads_ = 1;
+#endif
+  else
+    threads_ = nr_threads;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////
 template<typename PointInT, typename PointOutT, typename NormalT> bool*
 pcl::ISSKeypoint3D<PointInT, PointOutT, NormalT>::getBoundaryPoints (PointCloudIn &input, double border_radius, float angle_threshold)
index d8ef0c9445e9bb8d118531c5697f2f850eefd49c..13884b71d45c6cd6b5fa1d981db5036f33c1cbe8 100644 (file)
@@ -125,6 +125,7 @@ namespace pcl
       {
         name_ = "ISSKeypoint3D";
         search_radius_ = salient_radius_;
+        setNumberOfThreads(threads_); // Reset number of threads with the member's initialization value to apply input validation.
       }
 
       /** \brief Destructor. */
@@ -197,8 +198,8 @@ namespace pcl
       /** \brief Initialize the scheduler and set the number of threads to use.
         * \param[in] nr_threads the number of hardware threads to use (0 sets the value back to automatic)
         */
-      inline void
-      setNumberOfThreads (unsigned int nr_threads = 0) { threads_ = nr_threads; }
+      void
+      setNumberOfThreads (unsigned int nr_threads = 0);
 
     protected:
 
index ea39425485194464ecf7447c91d6feab0e3a16bc..9b7e0127139fbf4edc7865d60b9cdb9ede0afa23 100644 (file)
@@ -293,6 +293,7 @@ Cache::swap_index(int i, int j)
 // the member function get_Q is for getting one column from the Q Matrix
 //
 
+namespace pcl {
 class QMatrix {
 
 public:
@@ -304,8 +305,9 @@ public:
   swap_index(int i, int j) const = 0;
   virtual ~QMatrix() {}
 };
+} // namespace pcl
 
-class Kernel : public QMatrix {
+class Kernel : public pcl::QMatrix {
 
 public:
   Kernel(int l, svm_node* const* x, const svm_parameter& param);
@@ -534,7 +536,7 @@ public:
 
   void
   Solve(int l,
-        const QMatrix& Q,
+        const pcl::QMatrix& Q,
         const double* p_,
         const schar* y_,
         double* alpha_,
@@ -551,7 +553,7 @@ protected:
   enum { LOWER_BOUND, UPPER_BOUND, FREE };
   char* alpha_status; // LOWER_BOUND, UPPER_BOUND, FREE
   double* alpha;
-  const QMatrix* Q;
+  const pcl::QMatrix* Q;
   const double* QD;
   double eps;
   double Cp, Cn;
@@ -668,7 +670,7 @@ Solver::reconstruct_gradient()
 
 void
 Solver::Solve(int l,
-              const QMatrix& Q,
+              const pcl::QMatrix& Q,
               const double* p_,
               const schar* y_,
               double* alpha_,
@@ -1177,7 +1179,7 @@ public:
 
   void
   Solve(int l,
-        const QMatrix& Q,
+        const pcl::QMatrix& Q,
         const double* p,
         const schar* y,
         double* alpha,
index 2c1a848d33f69cc21338cabacb32c4746c9c9283..3cccce47f0b947a3dd1fba5d8c5a327f799f4b85 100644 (file)
@@ -96,7 +96,6 @@ public:
   /** \brief Constructor.
    * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its
    * root node.
-   * \param[in] max_depth_arg Depth limitation during traversal
    */
   OctreeIteratorBase(OctreeT* octree_arg) : OctreeIteratorBase(octree_arg, 0u) {}
 
index e8b36e85baa24e0b551b9c43bab076e03973688c..170fba6d65af09094829c7012ec48bd06e783c81 100644 (file)
@@ -1,6 +1,10 @@
 #pragma once
 
 // VTK
+#include <vtkVersion.h>
+#if VTK_MAJOR_VERSION == 9 && VTK_MINOR_VERSION == 0
+#include <limits> // This must be included before vtkPolyData.h
+#endif
 #include <vtkPolyData.h>
 #include <vtkSmartPointer.h>
 
index e41128d2dc5ec9b7e2a2a979bc8591b20b182963..4395043129a96ba3bde7e769721351053c7e72db 100644 (file)
 // SSE macros
 #cmakedefine HAVE_POSIX_MEMALIGN
 #cmakedefine HAVE_MM_MALLOC
-#cmakedefine HAVE_SSE4_2_EXTENSIONS
-#cmakedefine HAVE_SSE4_1_EXTENSIONS
-#cmakedefine HAVE_SSSE3_EXTENSIONS
-#cmakedefine HAVE_SSE3_EXTENSIONS
-#cmakedefine HAVE_SSE2_EXTENSIONS
-#cmakedefine HAVE_SSE_EXTENSIONS
 
 #cmakedefine HAVE_PNG
 
index 66cfede8969afb30a59831a7f4d685592d89f7fd..17ab8a95c44fc10fa822090ae2f6e26d20563115 100644 (file)
@@ -44,7 +44,10 @@ set(srcs
 
 set(LIB_NAME "pcl_${SUBSYS_NAME}")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
+
 PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs})
+target_link_libraries(${LIB_NAME} pcl_common pcl_filters pcl_kdtree pcl_sample_consensus pcl_segmentation pcl_visualization)
+
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS})
 # Install include files
 PCL_ADD_INCLUDES("${SUBSYS_NAME}" "${SUBSYS_NAME}" ${incs})
index 2718344bd4abb8834bb2ddb8ad9b8f0d4d80b847..60ba38f09a43882125e4c22cbb48662d1bbae1bd 100644 (file)
@@ -85,7 +85,7 @@ public:
   /** \brief Provide a pointer to the input target
    * (e.g., the point cloud that we want to align the input source to)
    *
-   * \param[in] cloud the input point cloud target
+   * \param[in] target the input point cloud target
    */
   void
   setInputTarget(const PointCloudTargetConstPtr& target) override;
index 828f3225ac15a19080dccfddf0b3c3b9150f671c..408b5e433ffd5a56922e2858c5e7bf27bec62618 100644 (file)
@@ -103,8 +103,8 @@ public:
 
   public:
     HuberPenalty(float threshold) : threshold_(threshold) {}
-    virtual float
-    operator()(float e) const
+    float
+    operator()(float e) const override
     {
       if (e <= threshold_)
         return (0.5 * e * e);
index c6d65c753beca299521ab3013fa9cd6d75f2d66e..3d7e34a3a97d1d9dd41dd4c5fd91262d20e9c8ab 100644 (file)
@@ -154,7 +154,7 @@ NormalDistributionsTransform<PointSource, PointTarget>::computeTransformation(
       update_visualizer_(output, pcl::Indices(), *target_, pcl::Indices());
 
     const double cos_angle =
-        0.5 * transformation_.template block<3, 3>(0, 0).trace() - 1;
+        0.5 * (transformation_.template block<3, 3>(0, 0).trace() - 1);
     const double translation_sqr =
         transformation_.template block<3, 1>(0, 3).squaredNorm();
 
@@ -286,13 +286,14 @@ NormalDistributionsTransform<PointSource, PointTarget>::computeAngleDerivatives(
     angular_hessian_.row(3).noalias() =
         Eigen::Vector4d((sx * cy * cz), (-sx * cy * sz), (sx * sy), 0.0f); // b3
 
+    // The sign of 'sx * sz' in c2 is incorrect in the thesis, and is fixed here.
     angular_hessian_.row(4).noalias() = Eigen::Vector4d(
         (-sx * cz - cx * sy * sz), (sx * sz - cx * sy * cz), 0, 0.0f); // c2
     angular_hessian_.row(5).noalias() = Eigen::Vector4d(
         (cx * cz - sx * sy * sz), (-sx * sy * cz - cx * sz), 0, 0.0f); // c3
 
     angular_hessian_.row(6).noalias() =
-        Eigen::Vector4d((-cy * cz), (cy * sz), (sy), 0.0f); // d1
+        Eigen::Vector4d((-cy * cz), (cy * sz), (-sy), 0.0f); // d1
     angular_hessian_.row(7).noalias() =
         Eigen::Vector4d((-sx * sy * cz), (sx * sy * sz), (sx * cy), 0.0f); // d2
     angular_hessian_.row(8).noalias() =
index 42c42545f73ce79628360ffae0fa575c18d4bdf3..3286e2bc880fb43c91606369d9a15fd22b22265e 100644 (file)
@@ -154,9 +154,14 @@ pcl::PPFRegistration<PointSource, PointTarget>::computeTransformation(
             float alpha =
                 search_method_->alpha_m_[model_reference_index][model_point_index] -
                 alpha_s;
-            unsigned int alpha_discretized = static_cast<unsigned int>(
-                std::floor(alpha) +
-                std::floor(M_PI / search_method_->getAngleDiscretizationStep()));
+            if (alpha < -M_PI) {
+              alpha += (2 * M_PI);
+            }
+            else if (alpha > M_PI) {
+              alpha -= (2 * M_PI);
+            }
+            unsigned int alpha_discretized = static_cast<unsigned int>(std::floor(
+                (alpha + M_PI) / search_method_->getAngleDiscretizationStep()));
             accumulator_array[model_reference_index][alpha_discretized]++;
           }
         }
@@ -200,10 +205,9 @@ pcl::PPFRegistration<PointSource, PointTarget>::computeTransformation(
         rotation_mg);
     Eigen::Affine3f max_transform =
         transform_sg.inverse() *
-        Eigen::AngleAxisf((static_cast<float>(max_votes_j) -
-                           std::floor(static_cast<float>(M_PI) /
-                                      search_method_->getAngleDiscretizationStep())) *
-                              search_method_->getAngleDiscretizationStep(),
+        Eigen::AngleAxisf((static_cast<float>(max_votes_j + 0.5) *
+                               search_method_->getAngleDiscretizationStep() -
+                           M_PI),
                           Eigen::Vector3f::UnitX()) *
         transform_mg;
 
index d21e1a691c64f935d3a5f2254cabf4b52c50fa44..1a338671a344ddfe282f58da891bd4f90a2b5211 100644 (file)
@@ -358,6 +358,7 @@ pcl::SampleConsensusModelCylinder<PointT, PointNT>::projectPoints (
       pp.matrix () = line_pt + k * line_dir;
 
       Eigen::Vector4f dir = p - pp;
+      dir[3] = 0.0f;
       dir.normalize ();
 
       // Calculate the projection of the point onto the cylinder
@@ -388,6 +389,7 @@ pcl::SampleConsensusModelCylinder<PointT, PointNT>::projectPoints (
       pp.matrix () = line_pt + k * line_dir;
 
       Eigen::Vector4f dir = p - pp;
+      dir[3] = 0.0f;
       dir.normalize ();
 
       // Calculate the projection of the point onto the cylinder
index 43c15c91facc6029a7d543ad9ff0e73d449a803b..2ff196e3b1b82d5902d3ed0a41fb8c17867bf4d7 100644 (file)
@@ -234,9 +234,12 @@ namespace pcl
       {
         // Compute the principal directions via PCA
         Eigen::Vector4f xyz_centroid;
-        Eigen::Matrix3f covariance_matrix = Eigen::Matrix3f::Zero ();
+        Eigen::Matrix3f covariance_matrix;
 
-        computeMeanAndCovarianceMatrix (*cloud, covariance_matrix, xyz_centroid);
+        if (computeMeanAndCovarianceMatrix (*cloud, covariance_matrix, xyz_centroid) == 0) {
+          PCL_ERROR ("[pcl::SampleConsensusModelRegistration::computeSampleDistanceThreshold] No valid points in cloud!\n");
+          return;
+        }
 
         // Check if the covariance matrix is finite or not.
         for (int i = 0; i < 3; ++i)
@@ -265,7 +268,10 @@ namespace pcl
         // Compute the principal directions via PCA
         Eigen::Vector4f xyz_centroid;
         Eigen::Matrix3f covariance_matrix;
-        computeMeanAndCovarianceMatrix (*cloud, indices, covariance_matrix, xyz_centroid);
+        if (computeMeanAndCovarianceMatrix (*cloud, indices, covariance_matrix, xyz_centroid) == 0) {
+          PCL_ERROR ("[pcl::SampleConsensusModelRegistration::computeSampleDistanceThreshold] No valid points given by cloud and indices!\n");
+          return;
+        }
 
         // Check if the covariance matrix is finite or not.
         for (int i = 0; i < 3; ++i)
index 80b448c47ba104a6408306ad4106281f65052906..8bafec1ddbe550e8b299137a602afbc84ad5f1a8 100644 (file)
@@ -367,4 +367,7 @@ namespace pcl
   }
 }
 
+// There is no cpp file containing template instantiations of FlannSearch
+#include <pcl/search/impl/flann_search.hpp>
+
 #define PCL_INSTANTIATE_FlannSearch(T) template class PCL_EXPORTS pcl::search::FlannSearch<T>;
index d8a8566ea3bae4b74c2fa58d7378665f638391bd..cfff3714a6be89f07e463834c37b4110f0164b9d 100644 (file)
@@ -174,20 +174,26 @@ PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${i
 target_link_libraries("${LIB_NAME}" pcl_common pcl_search pcl_kdtree pcl_octree ${ON_NURBS_LIBRARIES})
 
 if(VTK_FOUND)
-  if(${VTK_VERSION} VERSION_LESS 9.0)
+  if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
+    target_link_libraries("${LIB_NAME}"
+                          VTK::CommonDataModel
+                          VTK::CommonExecutionModel
+                          VTK::FiltersModeling
+                          VTK::FiltersCore)
+  else()
     include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
     link_directories(${VTK_LIBRARY_DIRS})
-    target_link_libraries("${LIB_NAME}" ${VTK_LIBRARIES})
-  else()
-    target_link_libraries("${LIB_NAME}" VTK::CommonDataModel
-                                        VTK::CommonExecutionModel
-                                        VTK::FiltersModeling
-                                        VTK::FiltersCore)
+    target_link_libraries("${LIB_NAME}"
+                          vtkCommonCore
+                          vtkCommonDataModel
+                          vtkCommonExecutionModel
+                          vtkFiltersModeling
+                          vtkFiltersCore)
   endif()
 endif()
 
 if(QHULL_FOUND)
-  target_link_libraries("${LIB_NAME}" ${QHULL_LIBRARIES})
+  target_link_libraries("${LIB_NAME}" QHULL::QHULL)
 endif()
 
 PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS})
index 10f494768545d49821d61abcf6f5c4c9af3386b4..187eba0e5cac94a4d280da14fbf35c10e2d29a59 100644 (file)
@@ -2373,7 +2373,7 @@ namespace pcl
                 (*vertexCount)[key1].second--;
                 (*vertexCount)[key2].second++;
               }
-              else fprintf( stderr , "Bad Edge 1: %d %d\n" , ri1.key , ri2.key );
+              else fprintf( stderr , "Bad Edge 1: %lld %lld\n" , ri1.key , ri2.key );
       }
     }
 
@@ -3550,13 +3550,13 @@ namespace pcl
                 {
                   int r1 = MarchingCubes::HasEdgeRoots( node->nodeData.mcIndex , isoTri[j*3+k] );
                   int r2 = MarchingCubes::HasEdgeRoots( node->nodeData.mcIndex , isoTri[j*3+((k+1)%3)] );
-                  fprintf( stderr , "Bad Edge 2: %d %d\t%d %d\n" , ri1.key , ri2.key , r1 , r2 );
+                  fprintf( stderr , "Bad Edge 2: %lld %lld\t%d %d\n" , ri1.key , ri2.key , r1 , r2 );
                 }
         }
       }
       for( int i=0 ; i<int(edges.size()) ; i++ )
       {
-        if( vertexCount.count( edges[i].first.key )==0 ) printf( "Could not find vertex: %lld\n" , edges[i].first );
+        if( vertexCount.count( edges[i].first.key )==0 ) printf( "Could not find vertex: %lld\n" , edges[i].first.key );
         else if( vertexCount[ edges[i].first.key ].second )
         {
           RootInfo ri;
@@ -3576,7 +3576,7 @@ namespace pcl
           }
         }
 
-        if( vertexCount.count( edges[i].second.key )==0 ) printf( "Could not find vertex: %lld\n" , edges[i].second );
+        if( vertexCount.count( edges[i].second.key )==0 ) printf( "Could not find vertex: %lld\n" , edges[i].second.key );
         else if( vertexCount[edges[i].second.key].second )
         {
           RootInfo ri;
index 7f78a106e99fb239c939fe6094c97958162e8876..5551e51a61dbb41b8f5b8f4dc769b2285c0e3075 100644 (file)
@@ -533,38 +533,6 @@ pcl::MLSResult::getPolynomialPartialDerivative (const double u, const double v)
   return (d);
 }
 
-Eigen::Vector2f
-pcl::MLSResult::calculatePrincipalCurvatures (const double u, const double v) const
-{
-  Eigen::Vector2f k (1e-5, 1e-5);
-
-  // Note: this use the Monge Patch to derive the Gaussian curvature and Mean Curvature found here http://mathworld.wolfram.com/MongePatch.html
-  // Then:
-  //      k1 = H + sqrt(H^2 - K)
-  //      k2 = H - sqrt(H^2 - K)
-  if (order > 1 && c_vec.size () >= (order + 1) * (order + 2) / 2 && std::isfinite (c_vec[0]))
-  {
-    const PolynomialPartialDerivative d = getPolynomialPartialDerivative (u, v);
-    const double Z = 1 + d.z_u * d.z_u + d.z_v * d.z_v;
-    const double Zlen = std::sqrt (Z);
-    const double K = (d.z_uu * d.z_vv - d.z_uv * d.z_uv) / (Z * Z);
-    const double H = ((1.0 + d.z_v * d.z_v) * d.z_uu - 2.0 * d.z_u * d.z_v * d.z_uv + (1.0 + d.z_u * d.z_u) * d.z_vv) / (2.0 * Zlen * Zlen * Zlen);
-    const double disc2 = H * H - K;
-    assert (disc2 >= 0.0);
-    const double disc = std::sqrt (disc2);
-    k[0] = H + disc;
-    k[1] = H - disc;
-
-    if (std::abs (k[0]) > std::abs (k[1])) std::swap (k[0], k[1]);
-  }
-  else
-  {
-    PCL_ERROR ("No Polynomial fit data, unable to calculate the principal curvatures!\n");
-  }
-
-  return (k);
-}
-
 pcl::MLSResult::MLSProjectionResults
 pcl::MLSResult::projectPointOrthogonalToPolynomialSurface (const double u, const double v, const double w) const
 {
index c9331b4c3e367611dfe7e721b32471ef286655e9..1b99b91836672fae7fbaa2a06d0423ec6fe83b4e 100644 (file)
@@ -212,7 +212,7 @@ pcl::OrganizedFastMesh<PointInT>::makeAdaptiveCutMesh (std::vector<pcl::Vertices
   int last_column = input_->width - triangle_pixel_size_columns_;
   int last_row = input_->height - triangle_pixel_size_rows_;
 
-  int i = 0, index_down = 0, index_right = 0, index_down_right = 0, idx = 0;
+  int idx = 0;
   int y_big_incr = triangle_pixel_size_rows_ * input_->width,
       x_big_incr = y_big_incr + triangle_pixel_size_columns_;
   // Reserve enough space
@@ -222,10 +222,10 @@ pcl::OrganizedFastMesh<PointInT>::makeAdaptiveCutMesh (std::vector<pcl::Vertices
   for (int y = 0; y < last_row; y += triangle_pixel_size_rows_)
   {
     // Initialize a new row
-    i = y * input_->width;
-    index_right = i + triangle_pixel_size_columns_;
-    index_down = i + y_big_incr;
-    index_down_right = i + x_big_incr;
+    int i = y * input_->width;
+    int index_right = i + triangle_pixel_size_columns_;
+    int index_down = i + y_big_incr;
+    int index_down_right = i + x_big_incr;
 
     // Go over the columns
     for (int x = 0; x < last_column; x += triangle_pixel_size_columns_,
index 34077edf9cb453c48636e113711165b9055c9a9b..6ce1afeda851c17bddbda3414584d9fe310e94e4 100644 (file)
@@ -164,12 +164,10 @@ pcl::TextureMapping<PointInT>::mapTexture2Mesh (pcl::TextureMesh &tex_mesh)
     // processing for each face
     for (std::size_t i = 0; i < tex_mesh.tex_polygons[m].size (); ++i)
     {
-      std::size_t idx;
-
       // get facet information
       for (std::size_t j = 0; j < tex_mesh.tex_polygons[m][i].vertices.size (); ++j)
       {
-        idx = tex_mesh.tex_polygons[m][i].vertices[j];
+        std::size_t idx = tex_mesh.tex_polygons[m][i].vertices[j];
         memcpy (&x, &tex_mesh.cloud.data[idx * point_size + tex_mesh.cloud.fields[0].offset], sizeof(float));
         memcpy (&y, &tex_mesh.cloud.data[idx * point_size + tex_mesh.cloud.fields[1].offset], sizeof(float));
         memcpy (&z, &tex_mesh.cloud.data[idx * point_size + tex_mesh.cloud.fields[2].offset], sizeof(float));
index 1af7a8dd80c71c8ae0b415118540cc5a161ba6af..15b45a832465d00e7b5fe6751cca8b454ed3a37a 100644 (file)
@@ -147,7 +147,7 @@ namespace pcl
     /** \brief Calculate the principal curvatures using the polynomial surface.
       * \param[in] u The u-coordinate of the point in local MLS frame.
       * \param[in] v The v-coordinate of the point in local MLS frame.
-      * \return The principal curvature [k1, k2] at the provided ub coordinates.
+      * \return The principal curvature [k1, k2] at the provided uv coordinates.
       * \note If an error occurs then 1e-5 is returned.
       */
     PCL_DEPRECATED(1, 15, "use calculatePrincipalCurvatures() instead")
@@ -206,7 +206,8 @@ namespace pcl
     inline MLSProjectionResults
     projectQueryPoint (ProjectionMethod method, int required_neighbors = 0) const;
 
-    /** \brief Smooth a given point and its neighborghood using Moving Least Squares.
+    /** \brief Smooth a given point and its neighborhood using Moving Least Squares.
+      * \param[in] cloud the input cloud, used together with index and nn_indices
       * \param[in] index the index of the query point in the input cloud
       * \param[in] nn_indices the set of nearest neighbors indices for pt
       * \param[in] search_radius the search radius used to find nearest neighbors for pt
index a86f10cfb85d854e635d5a06881150aad85d7f16..3dfa3bef5c395e1a6ef3405891da103090c01ec1 100644 (file)
@@ -43,5 +43,9 @@
 #  pragma GCC system_header 
 #endif
 
+#include <vtkVersion.h>
+#if VTK_MAJOR_VERSION == 9 && VTK_MINOR_VERSION == 0
+#include <limits> // This must be included before vtkPolyData.h
+#endif
 #include <vtkPolyData.h>
 #include <vtkSmartPointer.h>
index e380af5ff6ef61d33cfd25b8e7a20d3af7ac43ba..ba2fd655300517321e7e02e41f15c8ef1d77c9ed 100644 (file)
 #include <pcl/surface/mls.h>
 #include <pcl/surface/impl/mls.hpp>
 
+Eigen::Vector2f
+pcl::MLSResult::calculatePrincipalCurvatures (const double u, const double v) const
+{
+  Eigen::Vector2f k (1e-5, 1e-5);
+
+  // Note: this use the Monge Patch to derive the Gaussian curvature and Mean Curvature found here http://mathworld.wolfram.com/MongePatch.html
+  // Then:
+  //      k1 = H + sqrt(H^2 - K)
+  //      k2 = H - sqrt(H^2 - K)
+  if (order > 1 && c_vec.size () >= (order + 1) * (order + 2) / 2 && std::isfinite (c_vec[0]))
+  {
+    const PolynomialPartialDerivative d = getPolynomialPartialDerivative (u, v);
+    const double Z = 1 + d.z_u * d.z_u + d.z_v * d.z_v;
+    const double Zlen = std::sqrt (Z);
+    const double K = (d.z_uu * d.z_vv - d.z_uv * d.z_uv) / (Z * Z);
+    const double H = ((1.0 + d.z_v * d.z_v) * d.z_uu - 2.0 * d.z_u * d.z_v * d.z_uv + (1.0 + d.z_u * d.z_u) * d.z_vv) / (2.0 * Zlen * Zlen * Zlen);
+    const double disc2 = H * H - K;
+    assert (disc2 >= 0.0);
+    const double disc = std::sqrt (disc2);
+    k[0] = H + disc;
+    k[1] = H - disc;
+
+    if (std::abs (k[0]) > std::abs (k[1])) std::swap (k[0], k[1]);
+  }
+  else
+  {
+    PCL_ERROR ("No Polynomial fit data, unable to calculate the principal curvatures!\n");
+  }
+
+  return (k);
+}
+
 #ifndef PCL_NO_PRECOMPILE
 #include <pcl/point_types.h>
 #include <pcl/impl/instantiate.hpp>
index b6872cdfd77b278de8b8236fb50153c43d8fe724..4611b493494789aabd2698d43b4ab50a6f0816e5 100644 (file)
@@ -15,7 +15,7 @@ endif()
 # Args: name, executable_name
 PCL_ADD_TEST(common_test_wrappers test_wrappers FILES test_wrappers.cpp LINK_WITH pcl_gtest pcl_common)
 PCL_ADD_TEST(common_test_macros test_macros FILES test_macros.cpp LINK_WITH pcl_gtest pcl_common)
-PCL_ADD_TEST(common_vector_average test_vector_average FILES test_vector_average.cpp LINK_WITH pcl_gtest)
+PCL_ADD_TEST(common_vector_average test_vector_average FILES test_vector_average.cpp LINK_WITH pcl_gtest pcl_common)
 PCL_ADD_TEST(common_common test_common FILES test_common.cpp LINK_WITH pcl_gtest pcl_common)
 PCL_ADD_TEST(common_pointcloud test_pointcloud FILES test_pointcloud.cpp LINK_WITH pcl_gtest pcl_common)
 PCL_ADD_TEST(common_parse test_parse FILES test_parse.cpp LINK_WITH pcl_gtest pcl_common)
index 2e43620bfa895e9a4592a2c34321284694484b9b..b7a461ef7a959ffc2fb0ab4aaddbae0e05d64c84 100644 (file)
@@ -16,6 +16,7 @@ using namespace pcl;
 
 //////////////////////////////////////////////
 struct pointCloudTest : public testing::Test {
+  PCL_MAKE_ALIGNED_OPERATOR_NEW
   protected:
     PointCloud<PointXYZ> cloud;
 };
index 29fbbc9e7be02a52d8fd883de301bfcb3d3bf938..5211a2c1988ad98bd7d2e682016aea30041c24f2 100644 (file)
@@ -182,6 +182,137 @@ TEST (PCL, NormalEstimation)
   EXPECT_EQ (normals->size (), indices.size ());
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST (PCL, TranslatedNormalEstimation)
+{
+  Eigen::Vector4f plane_parameters;
+  float curvature;
+
+  NormalEstimation<PointXYZ, Normal> n;
+
+  PointCloud<PointXYZ> translatedCloud(cloud);
+  for(size_t i = 0; i < translatedCloud.size(); ++i) {
+    translatedCloud[i].x += 100;
+    translatedCloud[i].y += 100;
+    translatedCloud[i].z += 100;
+  }
+
+  // computePointNormal (indices, Vector)
+  computePointNormal (translatedCloud, indices, plane_parameters, curvature);
+  EXPECT_NEAR (std::abs (plane_parameters[0]), 0.035592, 1e-4);
+  EXPECT_NEAR (std::abs (plane_parameters[1]), 0.369596, 1e-4);
+  EXPECT_NEAR (std::abs (plane_parameters[2]), 0.928511, 1e-4);
+// The points have moved so the location (not orientation is expected to change)
+//  EXPECT_NEAR (std::abs (plane_parameters[3]), 0.0622552, 1e-4);
+  EXPECT_NEAR (curvature, 0.0693136, 1e-4);
+
+  float nx, ny, nz;
+  // computePointNormal (indices)
+  n.computePointNormal (translatedCloud, indices, nx, ny, nz, curvature);
+  EXPECT_NEAR (std::abs (nx), 0.035592, 1e-4);
+  EXPECT_NEAR (std::abs (ny), 0.369596, 1e-4);
+  EXPECT_NEAR (std::abs (nz), 0.928511, 1e-4);
+  EXPECT_NEAR (curvature, 0.0693136, 1e-4);
+
+  // computePointNormal (Vector)
+  computePointNormal (translatedCloud, plane_parameters, curvature);
+  EXPECT_NEAR (plane_parameters[0],  0.035592,  1e-4);
+  EXPECT_NEAR (plane_parameters[1],  0.369596,  1e-4);
+  EXPECT_NEAR (plane_parameters[2],  0.928511,  1e-4);
+// The points have moved so the location (not orientation is expected to change)
+//  EXPECT_NEAR (plane_parameters[3], -0.0622552, 1e-4);
+  EXPECT_NEAR (curvature,            0.0693136, 1e-4);
+
+  // flipNormalTowardsViewpoint (Vector)
+  flipNormalTowardsViewpoint (translatedCloud.points[0], 0, 0, 0, plane_parameters);
+  EXPECT_NEAR (plane_parameters[0], -0.035592,  1e-4);
+  EXPECT_NEAR (plane_parameters[1], -0.369596,  1e-4);
+  EXPECT_NEAR (plane_parameters[2], -0.928511,  1e-4);
+// The points have moved so the location (not orientation is expected to change)
+//  EXPECT_NEAR (plane_parameters[3],  0.0799743, 1e-4);
+
+  // flipNormalTowardsViewpoint
+  flipNormalTowardsViewpoint (translatedCloud.points[0], 0, 0, 0, nx, ny, nz);
+  EXPECT_NEAR (nx, -0.035592, 1e-4);
+  EXPECT_NEAR (ny, -0.369596, 1e-4);
+  EXPECT_NEAR (nz, -0.928511, 1e-4);
+
+  // Object
+  PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
+
+  // set parameters
+  PointCloud<PointXYZ>::Ptr cloudptr = translatedCloud.makeShared ();
+  n.setInputCloud (cloudptr);
+  EXPECT_EQ (n.getInputCloud (), cloudptr);
+  pcl::IndicesPtr indicesptr (new pcl::Indices (indices));
+  n.setIndices (indicesptr);
+  EXPECT_EQ (n.getIndices (), indicesptr);
+  n.setSearchMethod (tree);
+  EXPECT_EQ (n.getSearchMethod (), tree);
+  n.setKSearch (static_cast<int> (indices.size ()));
+
+  // estimate
+  n.compute (*normals);
+  EXPECT_EQ (normals->size (), indices.size ());
+
+  for (const auto &point : normals->points)
+  {
+    EXPECT_NEAR (point.normal[0], -0.035592, 1e-4);
+    EXPECT_NEAR (point.normal[1], -0.369596, 1e-4);
+    EXPECT_NEAR (point.normal[2], -0.928511, 1e-4);
+    EXPECT_NEAR (point.curvature, 0.0693136, 1e-4);
+  }
+
+  PointCloud<PointXYZ>::Ptr surfaceptr = cloudptr;
+  n.setSearchSurface (surfaceptr);
+  EXPECT_EQ (n.getSearchSurface (), surfaceptr);
+
+  // Additional test for searchForNeigbhors
+  surfaceptr.reset (new PointCloud<PointXYZ>);
+  *surfaceptr = *cloudptr;
+  surfaceptr->points.resize (640 * 480);
+  surfaceptr->width = 640;
+  surfaceptr->height = 480;
+  EXPECT_EQ (surfaceptr->size (), surfaceptr->width * surfaceptr->height);
+  n.setSearchSurface (surfaceptr);
+  tree.reset ();
+  n.setSearchMethod (tree);
+
+  // estimate
+  n.compute (*normals);
+  EXPECT_EQ (normals->size (), indices.size ());
+}
+
+TEST (NormalEstimation, FarFromOrigin)
+{ // Test if estimated normals are the same if the cloud is moved far away from the origin
+  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne1;
+  ne1.setInputCloud(cloud.makeShared());
+  ne1.setKSearch(15);
+  pcl::PointCloud<pcl::Normal> normals1;
+  ne1.compute(normals1);
+
+  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_translated(new pcl::PointCloud<pcl::PointXYZ>(cloud));
+  for(auto& point : (*cloud_translated)) {
+    point.x += 123.0;
+    point.y += -45.0;
+    point.z +=  98.0;
+  }
+  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne2;
+  ne2.setInputCloud(cloud_translated);
+  ne2.setKSearch(15);
+  ne2.setViewPoint(123.0, -45.0, 98.0); // Has to be set so that normals are oriented/flipped the same way
+  pcl::PointCloud<pcl::Normal> normals2;
+  ne2.compute(normals2);
+
+  ASSERT_EQ(normals1.size(), normals2.size());
+  for(std::size_t i=0; i<normals1.size(); ++i) {
+    EXPECT_NEAR(std::abs(normals1[i].getNormalVector3fMap().dot(normals2[i].getNormalVector3fMap())), 1.0, 1e-6);
+    EXPECT_NEAR(normals1[i].normal_x, normals2[i].normal_x, 5e-4);
+    EXPECT_NEAR(normals1[i].normal_y, normals2[i].normal_y, 5e-4);
+    EXPECT_NEAR(normals1[i].normal_z, normals2[i].normal_z, 5e-4);
+  }
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // There was an issue where the vectors for the indices and the
 // distances of the neighbor search weren't initialized correctly
index d46838a3baff326c33d8c7feffabf2d01f283235..9d010522745a71f4e4d292babc40b1b892b5a001 100644 (file)
@@ -101,6 +101,7 @@ class PCLCropHullTestFixture : public ::testing::Test
       baseOffsetList_.emplace_back(10, 1, 5);
       baseOffsetList_.emplace_back(10, 5, 1);
     }
+  PCL_MAKE_ALIGNED_OPERATOR_NEW
   protected:
 
     void
@@ -307,6 +308,27 @@ TYPED_TEST (PCLCropHullTestFixture, simple_test)
       crop_hull_filter.setInputCloud(test_data.input_cloud_);
       pcl::Indices filtered_indices;
       crop_hull_filter.filter(filtered_indices);
+      ASSERT_EQ(test_data.inside_indices_.size(), filtered_indices.size());
+      pcl::test::EXPECT_EQ_VECTORS(test_data.inside_indices_, filtered_indices);
+    }
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// checking that the result is independent of the original state of the output_indices
+TYPED_TEST (PCLCropHullTestFixture, non_empty_output_indices)
+{
+  for (auto & entry : this->data_)
+  {
+    auto & crop_hull_filter = entry.first;
+    for (TestData const & test_data : entry.second)
+    {
+      crop_hull_filter.setInputCloud(test_data.input_cloud_);
+      // the size of indices array does not matter. only that it is not empty
+      pcl::Indices filtered_indices(42);
+      crop_hull_filter.filter(filtered_indices);
+      ASSERT_EQ(test_data.inside_indices_.size(), filtered_indices.size());
       pcl::test::EXPECT_EQ_VECTORS(test_data.inside_indices_, filtered_indices);
     }
   }
@@ -335,6 +357,31 @@ TYPED_TEST (PCLCropHullTestFixture, test_cloud_filtering)
 }
 
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TYPED_TEST (PCLCropHullTestFixture, test_keep_organized)
+{
+  for (auto & entry : this->data_)
+  {
+    auto & crop_hull_filter = entry.first;
+    crop_hull_filter.setKeepOrganized(true);
+    crop_hull_filter.setUserFilterValue(-10.);
+    const pcl::PointXYZ defaultPoint(-10., -10., -10.);
+    for (TestData const & test_data : entry.second)
+    {
+      crop_hull_filter.setInputCloud(test_data.input_cloud_);
+      pcl::PointCloud<pcl::PointXYZ> filteredCloud;
+      crop_hull_filter.filter(filteredCloud);
+      ASSERT_EQ (test_data.input_cloud_->size(), filteredCloud.size());
+      for (size_t i = 0; i < test_data.input_cloud_->size(); ++i)
+      {
+        pcl::PointXYZ expectedPoint = test_data.inside_mask_[i] ? test_data.input_cloud_->at(i) : defaultPoint;
+        ASSERT_XYZ_NEAR(expectedPoint, filteredCloud[i], 1e-5);
+      }
+    }
+  }
+}
+
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // this test will pass only for 2d case //
 template <class T>
index e4a119071577720e8409a1c2946ccb6a15be29dc..f3e878183ff59689983527392b5804c4cd1cbe19 100644 (file)
@@ -52,6 +52,7 @@ struct FunctorFilterRandom : public testing::TestWithParam<std::uint32_t> {
 
   shared_ptr<PointCloud<PointXYZ>> cloud;
   PointCloud<PointXYZ> out_cloud, negative_cloud, positive_cloud;
+  PCL_MAKE_ALIGNED_OPERATOR_NEW
 };
 
 TEST_P(FunctorFilterRandom, functioning)
@@ -172,6 +173,7 @@ struct FunctorFilterFunctionObject : public ::testing::Test {
     cloud.resize(2);
   }
   PointCloud<PointXYZ> cloud;
+  PCL_MAKE_ALIGNED_OPERATOR_NEW
 };
 TYPED_TEST_SUITE_P(FunctorFilterFunctionObject);
 
index d7e107016837bc3de0c2b006d05dd968595bb63c..5863778784e36ab34d45f955ec0b9b252646d016 100644 (file)
@@ -86,16 +86,16 @@ TEST (CovarianceSampling, Filters)
   covariance_sampling.setNumberOfSamples (static_cast<unsigned int> (cloud_turtle_normals->size ()) / 8);
   double cond_num_turtle = covariance_sampling.computeConditionNumber ();
 
-  // Conditioning number should be loosely close to the expected number. Adopting 10% of the reference value
-  EXPECT_NEAR (cond_num_turtle, 20661.7663, 2e4);
+  // Conditioning number should be loosely close to the expected number
+  EXPECT_NEAR (cond_num_turtle, 102982728.6578, 2e4);
 
   IndicesPtr turtle_indices (new pcl::Indices ());
   covariance_sampling.filter (*turtle_indices);
   covariance_sampling.setIndices (turtle_indices);
   double cond_num_turtle_sampled = covariance_sampling.computeConditionNumber ();
 
-  // Conditioning number should be loosely close to the expected number. Adopting 10% of the reference value
-  EXPECT_NEAR (cond_num_turtle_sampled, 5795.5057, 5e3);
+  // Conditioning number should be loosely close to the expected number
+  EXPECT_NEAR (cond_num_turtle_sampled, 15697094.2996, 5e3);
 
   // Ensure it respects the requested sampling size
   EXPECT_EQ (static_cast<unsigned int> (cloud_turtle_normals->size ()) / 8, turtle_indices->size ());
index c0520e942a01659625270127b42de24c48cb77f2..02bc1ed8ce10566a420f1bc8319f0f05dbe19e5d 100644 (file)
@@ -13,45 +13,45 @@ endif()
 
 PCL_ADD_TEST(geometry_iterator test_iterator
              FILES test_iterator.cpp
-             LINK_WITH pcl_gtest pcl_common)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_mesh_circulators test_mesh_circulators
              FILES test_mesh_circulators.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_mesh_conversion test_mesh_conversion
              FILES test_mesh_conversion.cpp
-             LINK_WITH pcl_gtest pcl_common)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_mesh_data test_mesh_data
              FILES test_mesh_data.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_mesh_get_boundary test_mesh_get_boundary
              FILES test_mesh_get_boundary.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_mesh_indices test_mesh_indices
              FILES test_mesh_indices.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 add_definitions(-DPCL_TEST_GEOMETRY_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}")
 PCL_ADD_TEST(geometry_mesh_io test_mesh_io
              FILES test_mesh_io.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_mesh test_mesh
              FILES test_mesh.cpp test_mesh_common_functions.h
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_polygon_mesh test_polygon_mesh
              FILES test_polygon_mesh.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_quad_mesh test_quad_mesh
              FILES test_quad_mesh.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
 
 PCL_ADD_TEST(geometry_triangle_mesh test_triangle_mesh
              FILES test_triangle_mesh.cpp
-             LINK_WITH pcl_gtest)
+             LINK_WITH pcl_gtest pcl_geometry)
index 303ce71159a8d11412502bfe22427118edd73ef8..dc706be8ac451edb8f3781cc7ecc11183f104f07 100644 (file)
@@ -54,3 +54,8 @@ PCL_ADD_TEST(io_octree_compression test_octree_compression
         FILES test_octree_compression.cpp
         LINK_WITH pcl_gtest pcl_common pcl_io pcl_octree
         ARGUMENTS "${PCL_SOURCE_DIR}/test/milk_color.pcd")
+
+PCL_ADD_TEST (io_tim_grabber test_tim_grabber
+              FILES test_tim_grabber.cpp
+              LINK_WITH pcl_gtest pcl_io
+              ARGUMENTS "${PCL_SOURCE_DIR}/test/io/tim_sequences")
index f743f31faa1d9b52134ac7a39d4a9f9dab1a1741..abd340974b6a872018aa473217c49645fe61fd00 100644 (file)
@@ -34,6 +34,7 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  *
  */
+#include <pcl/common/io.h>
 #include <pcl/io/ply_io.h>
 #include <pcl/conversions.h>
 #include <pcl/PolygonMesh.h>
@@ -532,6 +533,84 @@ TEST_F (PLYTest, CommentAtTheEnd)
   ASSERT_FALSE (cloud.empty());
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F (PLYTest, EmptyCloud)
+{
+  // create file
+  std::ofstream fs;
+  fs.open (mesh_file_ply_.c_str ());
+  fs << "ply\n"
+        "format ascii 1.0\n"
+        "element vertex 0\n"
+        "property float x\n"
+        "property float y\n"
+        "property float z\n"
+        "end_header\n";
+  fs.close ();
+
+  // Set up cloud
+  pcl::PointCloud<pcl::PointXYZ> cloud;
+
+  // check if loading is ok
+  const int res = pcl::io::loadPLYFile (PLYTest::mesh_file_ply_, cloud);
+  ASSERT_EQ (res, 0);
+
+  ASSERT_TRUE (cloud.empty());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F (PLYTest, Float64Cloud)
+{
+  pcl::PointCloud<pcl::PointXYZ> cloud;
+  cloud.push_back(pcl::PointXYZ(4.23, 0.42, 1.61));
+  cloud.push_back(pcl::PointXYZ(-1.61, 4.32, 3.13));
+
+  // create file
+  std::ofstream fs;
+  fs.open (mesh_file_ply_.c_str ());
+  fs << "ply\n"
+        "format ascii 1.0\n"
+        "element vertex 2\n"
+        "property float64 x\n"
+        "property float64 y\n"
+        "property float64 z\n"
+        "end_header\n"
+        << cloud[0].x << " " << cloud[0].y << " " << cloud[0].z << "\n"
+        << cloud[1].x << " " << cloud[1].y << " " << cloud[1].z << "\n"
+        ;
+  fs.close ();
+
+  pcl::PCLPointCloud2 cloud2;
+  const int res = pcl::io::loadPLYFile (PLYTest::mesh_file_ply_, cloud2);
+  ASSERT_EQ (res, 0);
+
+  ASSERT_EQ (cloud2.height*cloud2.width, cloud.size());
+  for (auto & field : cloud2.fields) {
+    ASSERT_EQ (field.datatype, pcl::PCLPointField::FLOAT64);
+  }
+  for (size_t pointIdx = 0; pointIdx < cloud.size(); ++pointIdx)
+  {
+    unsigned char const * ptr = &cloud2.data[0] + pointIdx*cloud2.point_step;
+    double xValue, yValue, zValue;
+    memcpy(
+        reinterpret_cast<char*>(&xValue),
+        ptr + cloud2.fields.at(getFieldIndex(cloud2, "x")).offset,
+        8);
+    memcpy(
+        reinterpret_cast<char*>(&yValue),
+        ptr + cloud2.fields.at(getFieldIndex(cloud2, "y")).offset,
+        8);
+    memcpy(
+        reinterpret_cast<char*>(&zValue),
+        ptr + cloud2.fields.at(getFieldIndex(cloud2, "z")).offset,
+        8);
+
+    EXPECT_FLOAT_EQ(cloud[pointIdx].x, xValue);
+    EXPECT_FLOAT_EQ(cloud[pointIdx].y, yValue);
+    EXPECT_FLOAT_EQ(cloud[pointIdx].z, zValue);
+  }
+}
+
 /* ---[ */
 int
 main (int argc, char** argv)
diff --git a/test/io/test_tim_grabber.cpp b/test/io/test_tim_grabber.cpp
new file mode 100644 (file)
index 0000000..8897af5
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *  Point Cloud Library (PCL) - www.pointclouds.org
+ *  Copyright (c) 2020-, Open Perception
+ *  Copyright (c) 2020, ysuzuki19
+ *
+ *  All rights reserved
+ */
+
+#include <pcl/test/gtest.h>
+#include <pcl/point_types.h>
+#include <pcl/io/pcd_io.h>
+#include <pcl/io/tim_grabber.h>
+
+#include <string>
+#include <random>
+
+using PointT = pcl::PointXYZ;
+using CloudT = pcl::PointCloud<PointT>;
+
+struct TestableTimGrabber : public pcl::TimGrabber {
+  using TimGrabber::TimGrabber;
+  using TimGrabber::point_cloud_xyz_ptr_;
+  using TimGrabber::processTimPacket;
+  using TimGrabber::updateLookupTables;
+  using TimGrabber::toPointClouds;
+};
+
+class TimGrabberTest : public ::testing::Test {
+  protected:
+    TimGrabberTest () = default;
+    ~TimGrabberTest () override {}
+
+    std::vector<std::string> packets_;
+    std::vector<CloudT> correct_clouds_;
+    TestableTimGrabber grabber_;
+
+    virtual void SetUp () override {
+      constexpr float angle_start = - 1.0 * M_PI / 4.0;
+      constexpr float angle_range = 2.0 * M_PI * 3.0 / 4.0;
+
+      std::default_random_engine generator;
+      std::uniform_int_distribution<int> i_distribution (0, 1000);
+      std::uniform_real_distribution<float> f_distribution (0.0, 20.0);
+
+      CloudT cloud;
+
+      for (int i=0; i<1000; ++i) {
+        const size_t amount_of_data = i_distribution (generator);
+
+        cloud.reserve (amount_of_data);
+        cloud.clear ();
+
+        std::ostringstream ss;
+        ss << std::hex;
+        ss << " " << amount_of_data;
+
+        float angle = angle_start;
+        const float angle_step = angle_range / amount_of_data;
+
+        for (size_t i=0; i<amount_of_data; ++i, angle += angle_step) {
+          float distance = f_distribution (generator);
+          cloud.emplace_back (distance * std::cos (angle), distance * std::sin (angle), 0.0);
+          ss << " " << static_cast<int>(distance * 1000);
+        }
+        correct_clouds_.push_back (cloud);
+
+        std::string header_sample = "sRA LMDscandata 1 1 1291B11 0 0 AED5 AED7 FDB36397 FDB3779F 0 0 1 0 0 5DC A2 0 1 DIST1 3F800000 00000000 FFF92230 D05";
+        std::string packet = header_sample + ss.str ();
+        packets_.push_back (packet);
+      }
+    }
+};
+
+TEST_F (TimGrabberTest, Test1)
+{
+  CloudT::ConstPtr answer_cloud = grabber_.point_cloud_xyz_ptr_;
+
+  for (std::size_t i=0; i<packets_.size (); ++i) {
+    std::string packet = packets_.at(i);
+
+    grabber_.processTimPacket (packet);
+    grabber_.updateLookupTables ();
+    grabber_.toPointClouds ();
+
+    ASSERT_EQ (correct_clouds_.at(i).size (), answer_cloud->size ());
+
+    for (std::size_t j = 0; j < correct_clouds_.at(i).size (); j++) {
+      PointT const& correct_point = correct_clouds_.at(i).at(j);
+      PointT const& answer_point = answer_cloud->at(j);
+      EXPECT_NEAR (correct_point.x, answer_point.x, 1.0e-3);
+      EXPECT_NEAR (correct_point.y, answer_point.y, 1.0e-3);
+      EXPECT_NEAR (correct_point.z, answer_point.z, 1.0e-3);
+    }
+  }
+}
+
+/* ---[ */
+int
+main (int argc, char** argv)
+{
+  ::testing::InitGoogleTest (&argc, argv);
+  return (RUN_ALL_TESTS ());
+}
+/* ]--- */
index e9c4268700a4a8e6456718da0f4b3a105fdefc7f..a96a8e391b1ffb4e43ffa24fc445c006ca734ec6 100644 (file)
@@ -15,5 +15,5 @@ endif()
 include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
 PCL_ADD_TEST(a_people_detection_test test_people_detection
              FILES test_people_groundBasedPeopleDetectionApp.cpp
-             LINK_WITH pcl_gtest pcl_common pcl_io pcl_kdtree pcl_search pcl_features pcl_sample_consensus pcl_filters pcl_io pcl_segmentation pcl_people
+             LINK_WITH pcl_gtest pcl_common pcl_io pcl_kdtree pcl_search pcl_features pcl_sample_consensus pcl_filters pcl_segmentation pcl_people
              ARGUMENTS "${PCL_SOURCE_DIR}/people/data/trainedLinearSVMForPeopleDetectionWithHOG.yaml" "${PCL_SOURCE_DIR}/test/five_people.pcd")
index 8df64db7175d3f923da1921dea601e7c40daf506..9627421dbe8fc418b3b2987eafc55f0a288cd24d 100644 (file)
@@ -48,7 +48,6 @@
 #include <pcl/test/gtest.h>
 #include <pcl/io/pcd_io.h>
 #include <pcl/point_types.h>
-#include <pcl/visualization/pcl_visualizer.h>
 #include <pcl/sample_consensus/sac_model_plane.h>
 #include <pcl/people/ground_based_people_detection_app.h>
 
index 6f9ede77046eb8654d587708798ca6eb5c53f0cd..48a0011794fbc5cf7926028d2d241630cd792457 100644 (file)
@@ -447,6 +447,30 @@ TEST (SampleConsensusModelNormalPlane, SIMD_countWithinDistance) // Test if all
   }
 }
 
+TEST (SampleConsensusModelPlane, OptimizeFarFromOrigin)
+{ // Test if the model can successfully optimize a plane that is far from the origin
+  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
+  Eigen::Vector3d x(-0.435197968, 0.598251061, -0.672828654);
+  Eigen::Vector3d y(-0.547340139, 0.417556627,  0.725303548);
+  Eigen::Vector3d z( 0.714857680, 0.683916759,  0.145727023); // This is the normal of the plane
+  Eigen::Vector3d center(7380.86467, -8350.60056617, 4324.22814107);
+  for(double i=-0.5; i<0.5; i+=0.01)
+    for(double j=-0.5; j<0.5; j+=0.01) {
+      Eigen::Vector3d p = center + i*x + j*y;
+      cloud->emplace_back(p[0], p[1], p[2]);
+    }
+  pcl::SampleConsensusModelPlane<pcl::PointXYZ> model(cloud, true);
+  pcl::Indices inliers;
+  for(std::size_t i=0; i<cloud->size(); ++i) inliers.push_back(i);
+  Eigen::VectorXf coeffs(4); // Doesn't have to be initialized, the function doesn't use them
+  Eigen::VectorXf optimized_coeffs(4);
+  model.optimizeModelCoefficients(inliers, coeffs, optimized_coeffs);
+  EXPECT_NEAR(optimized_coeffs[0], z[0], 5e-6);
+  EXPECT_NEAR(optimized_coeffs[1], z[1], 5e-6);
+  EXPECT_NEAR(optimized_coeffs[2], z[2], 5e-6);
+  EXPECT_NEAR(optimized_coeffs[3], -z.dot(center), 5e-2);
+}
+
 int
 main (int argc, char** argv)
 {
index c98f02f46cffd3a85686697b8af8f9e60f0a876c..b08232be4afc731c219385063cd658e3d66ff87e 100644 (file)
@@ -37,6 +37,7 @@
  */
 
 #include <pcl/test/gtest.h>
+#include <pcl/pcl_tests.h> // for EXPECT_XYZ_NEAR
 
 #include <pcl/sample_consensus/ransac.h>
 #include <pcl/sample_consensus/sac_model_sphere.h>
@@ -650,6 +651,51 @@ TEST (SampleConsensusModelCircle3D, RANSAC)
   EXPECT_NEAR ( 0.0, coeff_refined[6], 1e-3);
 }
 
+TEST (SampleConsensusModelCylinder, projectPoints)
+{
+  Eigen::VectorXf model_coefficients(7);
+  model_coefficients << -0.59, 0.85, -0.80, 0.22, -0.70, 0.68, 0.18;
+
+  pcl::PointCloud<pcl::PointXYZ>::Ptr input(new pcl::PointCloud<pcl::PointXYZ>);
+  input->emplace_back(-0.616358,  0.713315, -0.885120); // inlier, dist from axis=0.16
+  input->emplace_back( 0.595892,  0.455094,  0.025545); // outlier, not projected
+  input->emplace_back(-0.952749,  1.450040, -1.305640); // inlier, dist from axis=0.19
+  input->emplace_back(-0.644947,  1.421240, -1.421170); // inlier, dist from axis=0.14
+  input->emplace_back(-0.242308, -0.561036, -0.365535); // outlier, not projected
+  input->emplace_back(-0.502111,  0.694671, -0.878344); // inlier, dist from axis=0.18
+  input->emplace_back(-0.664129,  0.557583, -0.750060); // inlier, dist from axis=0.21
+  input->emplace_back(-0.033891,  0.624537, -0.606994); // outlier, not projected
+
+  pcl::SampleConsensusModelCylinder<pcl::PointXYZ, pcl::Normal> model(input);
+  // not necessary to set normals for model here because projectPoints does not use them
+  pcl::Indices inliers = {0, 2, 3, 5, 6};
+
+  pcl::PointCloud<pcl::PointXYZ> projected_truth;
+  projected_truth.emplace_back(-0.620532, 0.699027, -0.898478);
+  projected_truth.emplace_back(-0.943418, 1.449510, -1.309200);
+  projected_truth.emplace_back(-0.608243, 1.417710, -1.436680);
+  projected_truth.emplace_back(-0.502111, 0.694671, -0.878344);
+  projected_truth.emplace_back(-0.646557, 0.577140, -0.735612);
+
+  pcl::PointCloud<pcl::PointXYZ> projected_points;
+  model.projectPoints(inliers, model_coefficients, projected_points, false);
+  EXPECT_EQ(projected_points.size(), 5);
+  for(int i=0; i<5; ++i)
+    EXPECT_XYZ_NEAR(projected_points[i], projected_truth[i], 1e-5);
+
+  pcl::PointCloud<pcl::PointXYZ> projected_points_all;
+  model.projectPoints(inliers, model_coefficients, projected_points_all, true);
+  EXPECT_EQ(projected_points_all.size(), 8);
+  EXPECT_XYZ_NEAR(projected_points_all[0], projected_truth[0], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[1],        (*input)[1], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[2], projected_truth[1], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[3], projected_truth[2], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[4],        (*input)[4], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[5], projected_truth[3], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[6], projected_truth[4], 1e-5);
+  EXPECT_XYZ_NEAR(projected_points_all[7],        (*input)[7], 1e-5);
+}
+
 int
 main (int argc, char** argv)
 {
index 8d1786c023b0e93f2fb1847c7c32669b9a692fc0..9911a98191bf6a2c4e28f996a8df30c33889d7aa 100644 (file)
@@ -42,7 +42,7 @@
 #include <pcl/common/distances.h>
 #include <pcl/common/time.h>
 #include <pcl/search/kdtree.h> // for pcl::search::KdTree
-#include <pcl/search/impl/flann_search.hpp>
+#include <pcl/search/flann_search.h> // for pcl::search::FlannSearch
 #include <pcl/point_cloud.h>
 #include <pcl/point_types.h>
 
index 53dabcab3c2d0928982d31dc037bc2777bfb9a1b..a4d9b27db7499fc5c9c14b51d6bc105396098241 100644 (file)
@@ -14,7 +14,7 @@ endif()
 
 PCL_ADD_TEST(random_walker test_random_walker
              FILES test_random_walker.cpp
-             LINK_WITH pcl_gtest
+             LINK_WITH pcl_gtest pcl_segmentation
              ARGUMENTS "${PCL_SOURCE_DIR}/test/segmentation/data")
 
 PCL_ADD_TEST(a_segmentation_test test_segmentation
index 5bfe6e94cbc5959bcb211a4282fce72f6c3c735e..3b0890849bacc3181a22774b49688020995b0c28 100644 (file)
@@ -1,7 +1,7 @@
 set(SUBSYS_NAME tools)
 set(SUBSYS_DESC "Useful PCL-based command line tools")
 set(SUBSYS_DEPS common io filters sample_consensus segmentation search kdtree features surface octree registration recognition geometry keypoints ml)
-set(SUBSYS_OPT_DEPS visualization)
+set(SUBSYS_OPT_DEPS vtk visualization)
 set(DEFAULT ON)
 set(REASON "")
 
@@ -200,8 +200,8 @@ else()
 
   PCL_ADD_EXECUTABLE(pcl_obj2pcd COMPONENT ${SUBSYS_NAME} SOURCES obj2pcd.cpp)
   target_link_libraries(pcl_obj2pcd pcl_common pcl_io)
-  #TODO: Update when CMAKE 3.10 is available
-  if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
+
+  if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
     target_link_libraries(pcl_obj2pcd VTK::FiltersCore)
   endif()
 
@@ -210,8 +210,8 @@ else()
 
   PCL_ADD_EXECUTABLE(pcl_vtk2pcd COMPONENT ${SUBSYS_NAME} SOURCES vtk2pcd.cpp)
   target_link_libraries(pcl_vtk2pcd pcl_common pcl_io)
-  #TODO: Update when CMAKE 3.10 is available
-  if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
+
+  if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
     target_link_libraries(pcl_vtk2pcd VTK::FiltersCore)
   endif()
 
@@ -244,13 +244,13 @@ else()
     target_link_libraries(pcl_octree_viewer pcl_common pcl_io pcl_octree pcl_visualization pcl_kdtree pcl_filters)
 
     PCL_ADD_EXECUTABLE(pcl_mesh2pcd COMPONENT ${SUBSYS_NAME} SOURCES mesh2pcd.cpp)
-    target_link_libraries(pcl_mesh2pcd pcl_common pcl_io pcl_visualization pcl_filters ${VTK_LIBRARIES})
+    target_link_libraries(pcl_mesh2pcd pcl_common pcl_io pcl_visualization pcl_filters)
 
     PCL_ADD_EXECUTABLE(pcl_mesh_sampling COMPONENT ${SUBSYS_NAME} SOURCES mesh_sampling.cpp)
-    target_link_libraries(pcl_mesh_sampling pcl_common pcl_io pcl_visualization pcl_filters ${VTK_LIBRARIES})
+    target_link_libraries(pcl_mesh_sampling pcl_common pcl_io pcl_visualization pcl_filters)
 
     PCL_ADD_EXECUTABLE(pcl_virtual_scanner COMPONENT ${SUBSYS_NAME} SOURCES virtual_scanner.cpp)
-    target_link_libraries(pcl_virtual_scanner pcl_common pcl_io pcl_filters pcl_visualization ${VTK_LIBRARIES})
+    target_link_libraries(pcl_virtual_scanner pcl_common pcl_io pcl_filters pcl_visualization)
 
     PCL_ADD_EXECUTABLE(pcl_voxel_grid_occlusion_estimation COMPONENT ${SUBSYS_NAME} SOURCES voxel_grid_occlusion_estimation.cpp)
     target_link_libraries (pcl_voxel_grid_occlusion_estimation pcl_common pcl_io pcl_filters pcl_visualization)
@@ -272,7 +272,7 @@ else()
 
     if(WITH_OPENNI)
       PCL_ADD_EXECUTABLE(pcl_openni_save_image COMPONENT ${SUBSYS_NAME} SOURCES openni_save_image.cpp)
-      target_link_libraries(pcl_openni_save_image pcl_common pcl_io pcl_visualization)
+      target_link_libraries(pcl_openni_save_image pcl_common pcl_io pcl_visualization Boost::date_time)
 
       PCL_ADD_EXECUTABLE(pcl_pcd_grabber_viewer COMPONENT ${SUBSYS_NAME} SOURCES pcd_grabber_viewer.cpp BUNDLE)
       target_link_libraries(pcl_pcd_grabber_viewer pcl_common pcl_io pcl_kdtree pcl_visualization)
@@ -293,7 +293,7 @@ else()
       target_link_libraries(pcl_openni_viewer pcl_common pcl_io pcl_kdtree pcl_visualization)
 
       PCL_ADD_EXECUTABLE(pcl_openni_image COMPONENT ${SUBSYS_NAME} SOURCES openni_image.cpp BUNDLE)
-      target_link_libraries(pcl_openni_image pcl_common pcl_io pcl_kdtree pcl_visualization)
+      target_link_libraries(pcl_openni_image pcl_common pcl_io pcl_kdtree pcl_visualization Boost::date_time)
     endif()
 
     if(WITH_OPENNI2)
index 8602f859c51a85f4097797adc7c004394b692d71..d92eddab4693dbf289af6fc4149cdd73e2c5acbe 100644 (file)
 
 #include <vtkImageData.h> // for vtkImageData
 #include <vtkSmartPointer.h>
-#include <vtkImageViewer2.h>
 #include <vtkTIFFReader.h>
-#include <vtkRenderWindow.h>
-#include <vtkRenderWindowInteractor.h>
-#include <vtkRenderer.h>
 
 using namespace pcl;
 
index e676a202599e29fadf728d38ce791bec5b778224..d5ea61953864d62526e3a58c6fc77f1f8d5725d0 100644 (file)
@@ -141,7 +141,7 @@ if(VTK_RENDERING_BACKEND_OPENGL_VERSION VERSION_LESS 2)
   )
 endif()
 
-if(NOT (${VTK_VERSION} VERSION_LESS 9.0))
+if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
   if(NOT (";${VTK_AVAILABLE_COMPONENTS};" MATCHES ";RenderingContextOpenGL2;"))
     
     list(REMOVE_ITEM incs
@@ -166,10 +166,7 @@ endif()
 
 target_link_libraries("${LIB_NAME}" pcl_common pcl_io pcl_kdtree ${OPENGL_LIBRARIES})
 
-if(${VTK_VERSION} VERSION_LESS 9.0)
-  target_include_directories("${LIB_NAME}" SYSTEM PUBLIC ${VTK_INCLUDE_DIRS})
-  target_link_libraries("${LIB_NAME}" ${VTK_LIBRARIES})
-else()
+if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
   #Some libs are referenced through depending on IO
   target_link_libraries("${LIB_NAME}"
                         VTK::ChartsCore
@@ -193,9 +190,49 @@ else()
                         VTK::RenderingOpenGL2
                         VTK::ViewsContext2D)
                         
-  if(";${VTK_AVAILABLE_COMPONENTS};" MATCHES ";RenderingContextOpenGL2;")
+  if("RenderingContextOpenGL2" IN_LIST VTK_AVAILABLE_COMPONENTS)
     target_link_libraries("${LIB_NAME}" VTK::RenderingContextOpenGL2)
   endif()
+else()
+  target_include_directories("${LIB_NAME}" SYSTEM PUBLIC ${VTK_INCLUDE_DIRS})
+  target_link_libraries("${LIB_NAME}"
+                        vtkChartsCore
+                        vtkFiltersExtraction
+                        vtkFiltersGeometry
+                        vtkFiltersModeling
+                        vtkImagingCore
+                        vtkImagingSources
+                        vtkInteractionStyle
+                        vtkRenderingAnnotation
+                        vtkRenderingContext2D
+                        vtkRenderingContext${VTK_RENDERING_BACKEND}
+                        vtkRenderingFreeType
+                        vtkRenderingLOD
+                        vtkRendering${VTK_RENDERING_BACKEND}
+                        vtkViewsContext2D)
+  if(${VTK_VERSION} VERSION_LESS 7.0)
+    target_link_libraries("${LIB_NAME}" vtkRenderingVolume${VTK_RENDERING_BACKEND})    
+  endif()
+  if(${VTK_VERSION} VERSION_GREATER_EQUAL 7.0 AND ${VTK_VERSION} VERSION_LESS 9.0)
+    target_link_libraries("${LIB_NAME}" vtkRenderingGL2PS${VTK_RENDERING_BACKEND})
+  endif()
+  
+  # These two libraries are present and required in ubuntu 18.04 VTK 6, but not present in later versions of ubuntu using VTK 6.
+  # They are also present on later versions of VTK on later versions of ubuntu.
+  if("vtkRenderingFreeTypeFontConfig" IN_LIST VTK_MODULES_ENABLED)
+    target_link_libraries("${LIB_NAME}" vtkRenderingFreeTypeFontConfig)
+  endif()
+  if("vtkRenderingMatplotlib" IN_LIST VTK_MODULES_ENABLED)
+    target_link_libraries("${LIB_NAME}" vtkRenderingMatplotlib)
+  endif()
+endif()
+
+if(HAVE_QVTK)
+  if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0)
+    target_link_libraries("${LIB_NAME}" VTK::GUISupportQt)
+  else()
+    target_link_libraries("${LIB_NAME}" vtkGUISupportQt)
+  endif()
 endif()
 
 set(EXT_DEPS "")
index a91317ce5e1d1707c07d60b85db1050f553bc66b..efad1e9a69646c4c1d8ec944288a12b8256ed33f 100644 (file)
@@ -157,7 +157,6 @@ PointCloudColorHandlerRGBField<PointT>::getColor () const
   scalars->SetNumberOfTuples (nr_points);
   unsigned char* colors = scalars->GetPointer (0);
 
-  int j = 0;
   // If XYZ present, check if the points are invalid
   int x_idx = -1;
   for (std::size_t d = 0; d < fields_.size (); ++d)
@@ -167,6 +166,7 @@ PointCloudColorHandlerRGBField<PointT>::getColor () const
   pcl::RGB rgb;
   if (x_idx != -1)
   {
+    int j = 0;
     // Color every point
     for (vtkIdType cp = 0; cp < nr_points; ++cp)
     {
index c847ac9ac4aa492cad71dfb25c2a42d4a43ff533..f6db237ab066d59afcb028f7cd56c83a25e08e0f 100644 (file)
@@ -1808,8 +1808,9 @@ namespace pcl
         getCameraFile () const;
 
         /** \brief Update camera parameters and render. */
-        void
-        updateCamera ();
+        PCL_DEPRECATED(1,15,"updateCamera will be removed, as it does nothing.")
+        inline void
+        updateCamera () {};
 
         /** \brief Reset camera parameters and render. */
         void
index 5ec44eb3184eefd39af71d6ebf23f603484e5e63..baf2b3bee93bf401d8b7d9ad19982a3f087fc88c 100644 (file)
@@ -37,6 +37,9 @@
  */
 
 #include <vtkVersion.h>
+#if VTK_MAJOR_VERSION == 9 && VTK_MINOR_VERSION == 0
+#include <limits> // This must be included before vtkPolyData.h
+#endif
 #include <vtkPolyData.h>
 #include <vtkCleanPolyData.h>
 #include <vtkSmartPointer.h>
index e9c0fe959fb060ad183efc967e5e19943a43d892..29e3dd0b03e3feeba7ef4ad5f278c59a2bd46e38 100644 (file)
  */
 
 #include <vtkVersion.h>
+#if VTK_MAJOR_VERSION == 9 && VTK_MINOR_VERSION == 0
+#include <limits> // This must be included before vtkDoubleArray.h
+#endif
+#include <vtkDoubleArray.h>
 #include <vtkSmartPointer.h>
 #include <vtkRenderWindowInteractor.h>
 #include <vtkRenderWindow.h>
@@ -47,7 +51,6 @@
 #include <vtkContextScene.h>
 #include <vtkAxis.h>
 #include <vtkPlot.h>
-#include <vtkDoubleArray.h>
 #include <vtkTable.h>
 
 #include <fstream>