From 733f0504b0d66571fd535f22350f0822e72a4f06 Mon Sep 17 00:00:00 2001 From: Markus Vieth Date: Tue, 4 Aug 2026 11:37:06 +0200 Subject: [PATCH 1/2] Move further towards KdTreeNanoflann --- CMakeLists.txt | 17 +++--- features/CMakeLists.txt | 6 +- features/include/pcl/features/impl/cppf.hpp | 4 +- features/include/pcl/features/impl/ppf.hpp | 4 +- features/include/pcl/features/impl/ppfrgb.hpp | 4 +- filters/CMakeLists.txt | 6 +- keypoints/CMakeLists.txt | 4 +- people/CMakeLists.txt | 8 +-- .../ground_based_people_detection_app.h | 1 - recognition/CMakeLists.txt | 6 +- .../recognition/hv/hypotheses_verification.h | 8 +-- .../include/pcl/recognition/impl/hv/hv_go.hpp | 3 +- registration/CMakeLists.txt | 6 +- .../registration/correspondence_estimation.h | 19 ++++--- .../registration/correspondence_rejection.h | 12 ++-- .../correspondence_rejection_distance.h | 2 +- ...correspondence_rejection_median_distance.h | 2 +- .../correspondence_rejection_surface_normal.h | 2 +- .../correspondence_rejection_var_trimmed.h | 2 +- registration/include/pcl/registration/fricp.h | 1 - .../impl/correspondence_estimation.hpp | 57 +++++++++++++------ .../include/pcl/registration/impl/fricp.hpp | 14 ++--- .../include/pcl/registration/impl/ia_fpcs.hpp | 4 +- .../pcl/registration/impl/joint_icp.hpp | 4 -- .../pcl/registration/impl/registration.hpp | 19 +++++-- .../transformation_validation_euclidean.hpp | 8 ++- .../include/pcl/registration/joint_icp.h | 4 +- .../include/pcl/registration/registration.h | 13 ++--- .../transformation_validation_euclidean.h | 7 +-- search/CMakeLists.txt | 29 ++++++---- search/include/pcl/search/auto.h | 13 +++++ search/include/pcl/search/impl/auto.hpp | 44 ++++++++++++++ search/include/pcl/search/kdtree_nanoflann.h | 17 +++--- search/src/auto.cpp | 1 + segmentation/CMakeLists.txt | 4 +- surface/CMakeLists.txt | 6 +- test/people/CMakeLists.txt | 2 +- test/segmentation/CMakeLists.txt | 4 +- tools/CMakeLists.txt | 54 +++++++++--------- tracking/CMakeLists.txt | 6 +- visualization/CMakeLists.txt | 6 +- 41 files changed, 265 insertions(+), 168 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 168c3aba1ca..986a2edfff0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,13 +353,16 @@ if(NOT EIGEN3_FOUND AND Eigen3_FOUND) endif() # FLANN -find_package(FLANN 1.9.1) -if(NOT FLANN_FOUND) - message(WARNING "Flann was not found, so many PCL modules will not be built!") -else() - set(PCL_HAS_FLANN 1) - if(NOT (${FLANN_LIBRARY_TYPE} MATCHES ${PCL_FLANN_REQUIRED_TYPE}) AND NOT (${PCL_FLANN_REQUIRED_TYPE} MATCHES "DONTCARE")) - message(FATAL_ERROR "Flann was selected with ${PCL_FLANN_REQUIRED_TYPE} but found as ${FLANN_LIBRARY_TYPE}") +option(WITH_FLANN "Use FLANN library (if available)" TRUE) +if(WITH_FLANN) + find_package(FLANN 1.9.1) + if(NOT FLANN_FOUND) + message(WARNING "Flann was not found, so many PCL modules will not be built!") + else() + set(PCL_HAS_FLANN 1) + if(NOT (${FLANN_LIBRARY_TYPE} MATCHES ${PCL_FLANN_REQUIRED_TYPE}) AND NOT (${PCL_FLANN_REQUIRED_TYPE} MATCHES "DONTCARE")) + message(FATAL_ERROR "Flann was selected with ${PCL_FLANN_REQUIRED_TYPE} but found as ${FLANN_LIBRARY_TYPE}") + endif() endif() endif() diff --git a/features/CMakeLists.txt b/features/CMakeLists.txt index a2a04a42202..de45fefc500 100644 --- a/features/CMakeLists.txt +++ b/features/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME features) set(SUBSYS_DESC "Point cloud features library") -set(SUBSYS_DEPS common search kdtree octree filters 2d) +set(SUBSYS_DEPS common search octree filters 2d) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -167,7 +167,7 @@ endif() set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs}) -target_link_libraries("${LIB_NAME}" pcl_common pcl_2d pcl_search pcl_kdtree pcl_octree pcl_filters) +target_link_libraries("${LIB_NAME}" pcl_common pcl_2d pcl_search pcl_octree pcl_filters) PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS}) # Install headers PCL_ADD_INCLUDES("${SUBSYS_NAME}" "${SUBSYS_NAME}" ${incs}) diff --git a/features/include/pcl/features/impl/cppf.hpp b/features/include/pcl/features/impl/cppf.hpp index 94f9c3a61f3..0f006f8481f 100755 --- a/features/include/pcl/features/impl/cppf.hpp +++ b/features/include/pcl/features/impl/cppf.hpp @@ -42,7 +42,7 @@ #define PCL_FEATURES_IMPL_CPPF_H_ #include -#include // for KdTree +#include // for BruteForce ////////////////////////////////////////////////////////////////////////////////////////////// template @@ -51,7 +51,7 @@ pcl::CPPFEstimation::CPPFEstimation () { feature_name_ = "CPPFEstimation"; // Slight hack in order to pass the check for the presence of a search method in Feature::initCompute () - Feature::tree_.reset (new pcl::search::KdTree ()); + Feature::tree_.reset (new pcl::search::BruteForce ()); Feature::search_radius_ = 1.0f; } diff --git a/features/include/pcl/features/impl/ppf.hpp b/features/include/pcl/features/impl/ppf.hpp index 7fb8818a645..fbdf6a3dab6 100644 --- a/features/include/pcl/features/impl/ppf.hpp +++ b/features/include/pcl/features/impl/ppf.hpp @@ -43,7 +43,7 @@ #include #include #include // for computePairFeatures -#include // for KdTree +#include // for BruteForce ////////////////////////////////////////////////////////////////////////////////////////////// template @@ -52,7 +52,7 @@ pcl::PPFEstimation::PPFEstimation () { feature_name_ = "PPFEstimation"; // Slight hack in order to pass the check for the presence of a search method in Feature::initCompute () - Feature::tree_.reset (new pcl::search::KdTree ()); + Feature::tree_.reset (new pcl::search::BruteForce ()); Feature::search_radius_ = 1.0f; } diff --git a/features/include/pcl/features/impl/ppfrgb.hpp b/features/include/pcl/features/impl/ppfrgb.hpp index 193d54d6f56..dc4d9f720e9 100644 --- a/features/include/pcl/features/impl/ppfrgb.hpp +++ b/features/include/pcl/features/impl/ppfrgb.hpp @@ -40,7 +40,7 @@ #include #include -#include // for KdTree +#include // for BruteForce ////////////////////////////////////////////////////////////////////////////////////////////// template @@ -49,7 +49,7 @@ pcl::PPFRGBEstimation::PPFRGBEstimation () { feature_name_ = "PPFRGBEstimation"; // Slight hack in order to pass the check for the presence of a search method in Feature::initCompute () - Feature::tree_.reset (new pcl::search::KdTree ()); + Feature::tree_.reset (new pcl::search::BruteForce ()); Feature::search_radius_ = 1.0f; } diff --git a/filters/CMakeLists.txt b/filters/CMakeLists.txt index 2d62bd59433..9854b0f13d6 100644 --- a/filters/CMakeLists.txt +++ b/filters/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME filters) set(SUBSYS_DESC "Point cloud filters library") -set(SUBSYS_DEPS common sample_consensus search kdtree octree) +set(SUBSYS_DEPS common sample_consensus search octree) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -132,7 +132,7 @@ set(impl_incs set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs}) -target_link_libraries("${LIB_NAME}" pcl_common pcl_sample_consensus pcl_search pcl_kdtree pcl_octree) +target_link_libraries("${LIB_NAME}" pcl_common pcl_sample_consensus pcl_search pcl_octree) PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS}) # Install include files diff --git a/keypoints/CMakeLists.txt b/keypoints/CMakeLists.txt index 30419d7c6f4..348a78008d5 100644 --- a/keypoints/CMakeLists.txt +++ b/keypoints/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME keypoints) set(SUBSYS_DESC "Point cloud keypoints library") -set(SUBSYS_DEPS common search kdtree octree features filters) +set(SUBSYS_DEPS common search octree features filters) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") diff --git a/people/CMakeLists.txt b/people/CMakeLists.txt index f2b11e838e6..cce64535a20 100644 --- a/people/CMakeLists.txt +++ b/people/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME people) set(SUBSYS_DESC "Point cloud people library") -set(SUBSYS_DEPS common kdtree search sample_consensus filters io visualization geometry segmentation octree) +set(SUBSYS_DEPS common search sample_consensus filters io visualization geometry segmentation octree) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS}) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -34,7 +34,7 @@ set(srcs set(LIB_NAME "pcl_${SUBSYS_NAME}") 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) +target_link_libraries(${LIB_NAME} pcl_common pcl_filters 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 @@ -43,5 +43,5 @@ PCL_ADD_INCLUDES("${SUBSYS_NAME}" "${SUBSYS_NAME}/impl" ${impl_incs}) if(WITH_OPENNI) PCL_ADD_EXECUTABLE(pcl_ground_based_rgbd_people_detector COMPONENT ${SUBSYS_NAME} SOURCES apps/main_ground_based_people_detection.cpp BUNDLE) - target_link_libraries(pcl_ground_based_rgbd_people_detector pcl_common pcl_kdtree pcl_search pcl_sample_consensus pcl_filters pcl_io pcl_visualization pcl_segmentation pcl_people) + target_link_libraries(pcl_ground_based_rgbd_people_detector pcl_common pcl_search pcl_sample_consensus pcl_filters pcl_io pcl_visualization pcl_segmentation pcl_people) endif() diff --git a/people/include/pcl/people/ground_based_people_detection_app.h b/people/include/pcl/people/ground_based_people_detection_app.h index 40645a6c67c..a5ae1af2ec0 100644 --- a/people/include/pcl/people/ground_based_people_detection_app.h +++ b/people/include/pcl/people/ground_based_people_detection_app.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/recognition/CMakeLists.txt b/recognition/CMakeLists.txt index 0e1e7c011bd..2bfeb15b5b1 100644 --- a/recognition/CMakeLists.txt +++ b/recognition/CMakeLists.txt @@ -1,11 +1,11 @@ set(SUBSYS_NAME recognition) set(SUBSYS_DESC "Point cloud recognition library") -set(SUBSYS_DEPS common io search kdtree octree features filters registration sample_consensus ml) +set(SUBSYS_DEPS common io search octree features filters registration sample_consensus ml) set(DEFAULT ON) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ${DEFAULT} "${REASON}") -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS}) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -134,7 +134,7 @@ set(metslib_incs set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs} ${face_detection_incs} ${ransac_based_incs} ${ransac_based_impl_incs} ${hv_incs} ${hv_impl_incs} ${cg_incs} ${cg_impl_incs} ${metslib_incs}) -target_link_libraries("${LIB_NAME}" pcl_common pcl_kdtree pcl_octree pcl_search pcl_features pcl_registration pcl_sample_consensus pcl_filters pcl_ml pcl_io) +target_link_libraries("${LIB_NAME}" pcl_common pcl_octree pcl_search pcl_features pcl_registration pcl_sample_consensus pcl_filters pcl_ml pcl_io) 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}) diff --git a/recognition/include/pcl/recognition/hv/hypotheses_verification.h b/recognition/include/pcl/recognition/hv/hypotheses_verification.h index f6977ae9174..da58a83ef24 100644 --- a/recognition/include/pcl/recognition/hv/hypotheses_verification.h +++ b/recognition/include/pcl/recognition/hv/hypotheses_verification.h @@ -37,9 +37,10 @@ #pragma once #include +#include // for pcl::Normal #include "pcl/recognition/hv/occlusion_reasoning.h" #include "pcl/recognition/impl/hv/occlusion_reasoning.hpp" -#include +#include #include namespace pcl @@ -79,7 +80,7 @@ namespace pcl /* * \brief Scene tree of the downsampled cloud */ - typename pcl::search::KdTree::Ptr scene_downsampled_tree_; + typename pcl::search::Search::Ptr scene_downsampled_tree_; /* * \brief Vector of point clouds representing the 3D models after occlusion reasoning @@ -307,8 +308,7 @@ namespace pcl voxel_grid.filter (*scene_cloud_downsampled_); //initialize kdtree for search - scene_downsampled_tree_.reset (new pcl::search::KdTree); - scene_downsampled_tree_->setInputCloud(scene_cloud_downsampled_); + scene_downsampled_tree_.reset (pcl::search::autoSelectMethod(scene_cloud_downsampled_, true)); } void setOcclusionCloud (const typename pcl::PointCloud::Ptr & occ_cloud) diff --git a/recognition/include/pcl/recognition/impl/hv/hv_go.hpp b/recognition/include/pcl/recognition/impl/hv/hv_go.hpp index 976a53f8ad6..bb14ce56026 100644 --- a/recognition/include/pcl/recognition/impl/hv/hv_go.hpp +++ b/recognition/include/pcl/recognition/impl/hv/hv_go.hpp @@ -242,8 +242,7 @@ void pcl::GlobalHypothesesVerification::initialize() if (detect_clutter_) { //initialize kdtree for search - scene_downsampled_tree_.reset (new pcl::search::KdTree); - scene_downsampled_tree_->setInputCloud (scene_cloud_downsampled_); + scene_downsampled_tree_.reset (pcl::search::autoSelectMethod(scene_cloud_downsampled_, true, pcl::search::Purpose::radius_search)); std::vector clusters; double eps_angle_threshold = 0.2; diff --git a/registration/CMakeLists.txt b/registration/CMakeLists.txt index 437b77b016c..f56c75c7af8 100644 --- a/registration/CMakeLists.txt +++ b/registration/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME registration) set(SUBSYS_DESC "Point cloud registration library") -set(SUBSYS_DEPS common octree kdtree search sample_consensus features filters) +set(SUBSYS_DEPS common octree search sample_consensus features filters) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -168,7 +168,7 @@ set(srcs set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs}) -target_link_libraries("${LIB_NAME}" pcl_kdtree pcl_search pcl_sample_consensus pcl_features pcl_filters) +target_link_libraries("${LIB_NAME}" pcl_search pcl_sample_consensus pcl_features pcl_filters) 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}) diff --git a/registration/include/pcl/registration/correspondence_estimation.h b/registration/include/pcl/registration/correspondence_estimation.h index 6eb451dd2d7..f814648d47f 100644 --- a/registration/include/pcl/registration/correspondence_estimation.h +++ b/registration/include/pcl/registration/correspondence_estimation.h @@ -42,10 +42,11 @@ #include // for getFields #include -#include +#include #include #include #include +#include #include @@ -70,11 +71,11 @@ class CorrespondenceEstimationBase : public PCLBase { using PCLBase::indices_; using PCLBase::setIndices; - using KdTree = pcl::search::KdTree; + using KdTree = pcl::search::Search; using KdTreePtr = typename KdTree::Ptr; using KdTreeConstPtr = typename KdTree::ConstPtr; - using KdTreeReciprocal = pcl::search::KdTree; + using KdTreeReciprocal = pcl::search::Search; using KdTreeReciprocalPtr = typename KdTreeReciprocal::Ptr; using KdTreeReciprocalConstPtr = typename KdTreeReciprocal::ConstPtr; @@ -86,15 +87,14 @@ class CorrespondenceEstimationBase : public PCLBase { using PointCloudTargetPtr = typename PointCloudTarget::Ptr; using PointCloudTargetConstPtr = typename PointCloudTarget::ConstPtr; - using PointRepresentationConstPtr = typename KdTree::PointRepresentationConstPtr; + using PointRepresentationConstPtr = + typename PointRepresentation::ConstPtr; using PointRepresentationReciprocalConstPtr = - typename KdTreeReciprocal::PointRepresentationConstPtr; + typename PointRepresentation::ConstPtr; /** \brief Empty constructor. */ CorrespondenceEstimationBase() : corr_name_("CorrespondenceEstimationBase") - , tree_(new pcl::search::KdTree) - , tree_reciprocal_(new pcl::search::KdTree) , target_() , point_representation_() , input_transformed_() @@ -458,9 +458,10 @@ class CorrespondenceEstimation using PointCloudTargetPtr = typename PointCloudTarget::Ptr; using PointCloudTargetConstPtr = typename PointCloudTarget::ConstPtr; - using PointRepresentationConstPtr = typename KdTree::PointRepresentationConstPtr; + using PointRepresentationConstPtr = + typename PointRepresentation::ConstPtr; using PointRepresentationReciprocalConstPtr = - typename KdTreeReciprocal::PointRepresentationConstPtr; + typename PointRepresentation::ConstPtr; /** \brief Empty constructor. */ CorrespondenceEstimation() { corr_name_ = "CorrespondenceEstimation"; } diff --git a/registration/include/pcl/registration/correspondence_rejection.h b/registration/include/pcl/registration/correspondence_rejection.h index f68882ab665..0ceeee59a57 100644 --- a/registration/include/pcl/registration/correspondence_rejection.h +++ b/registration/include/pcl/registration/correspondence_rejection.h @@ -43,8 +43,10 @@ #include #include #include -#include +#include +#include #include +#include // for PointNormal namespace pcl { namespace registration { @@ -236,7 +238,7 @@ class DataContainer : public DataContainerInterface { using PointCloudPtr = typename PointCloud::Ptr; using PointCloudConstPtr = typename PointCloud::ConstPtr; - using KdTreePtr = typename pcl::search::KdTree::Ptr; + using KdTreePtr = typename pcl::search::Search::Ptr; using Normals = pcl::PointCloud; using NormalsPtr = typename Normals::Ptr; @@ -251,7 +253,6 @@ class DataContainer : public DataContainerInterface { , input_normals_() , input_normals_transformed_() , target_normals_() - , tree_(new pcl::search::KdTree) , class_name_("DataContainer") , needs_normals_(needs_normals) {} @@ -348,7 +349,10 @@ class DataContainer : public DataContainerInterface { getCorrespondenceScore(int index) override { if (target_cloud_updated_ && !force_no_recompute_) { - tree_->setInputCloud(target_); + if (!tree_ || !tree_->setInputCloud(target_)) + tree_.reset(pcl::search::autoSelectMethod( + target_, false, pcl::search::Purpose::one_knn_search)); + target_cloud_updated_ = false; } pcl::Indices indices(1); std::vector distances(1); diff --git a/registration/include/pcl/registration/correspondence_rejection_distance.h b/registration/include/pcl/registration/correspondence_rejection_distance.h index 358c1b4dd74..7d36c224651 100644 --- a/registration/include/pcl/registration/correspondence_rejection_distance.h +++ b/registration/include/pcl/registration/correspondence_rejection_distance.h @@ -171,7 +171,7 @@ class PCL_EXPORTS CorrespondenceRejectorDistance : public CorrespondenceRejector */ template inline void - setSearchMethodTarget(const typename pcl::search::KdTree::Ptr& tree, + setSearchMethodTarget(const typename pcl::search::Search::Ptr& tree, bool force_no_recompute = false) { static_pointer_cast>(data_container_) diff --git a/registration/include/pcl/registration/correspondence_rejection_median_distance.h b/registration/include/pcl/registration/correspondence_rejection_median_distance.h index bf5715dbc87..a71f674160d 100644 --- a/registration/include/pcl/registration/correspondence_rejection_median_distance.h +++ b/registration/include/pcl/registration/correspondence_rejection_median_distance.h @@ -157,7 +157,7 @@ class PCL_EXPORTS CorrespondenceRejectorMedianDistance : public CorrespondenceRe */ template inline void - setSearchMethodTarget(const typename pcl::search::KdTree::Ptr& tree, + setSearchMethodTarget(const typename pcl::search::Search::Ptr& tree, bool force_no_recompute = false) { static_pointer_cast>(data_container_) diff --git a/registration/include/pcl/registration/correspondence_rejection_surface_normal.h b/registration/include/pcl/registration/correspondence_rejection_surface_normal.h index d2795748e5f..5231841d6a8 100644 --- a/registration/include/pcl/registration/correspondence_rejection_surface_normal.h +++ b/registration/include/pcl/registration/correspondence_rejection_surface_normal.h @@ -167,7 +167,7 @@ class PCL_EXPORTS CorrespondenceRejectorSurfaceNormal : public CorrespondenceRej */ template inline void - setSearchMethodTarget(const typename pcl::search::KdTree::Ptr& tree, + setSearchMethodTarget(const typename pcl::search::Search::Ptr& tree, bool force_no_recompute = false) { static_pointer_cast>(data_container_) diff --git a/registration/include/pcl/registration/correspondence_rejection_var_trimmed.h b/registration/include/pcl/registration/correspondence_rejection_var_trimmed.h index 37485c9f6a1..0002225b839 100644 --- a/registration/include/pcl/registration/correspondence_rejection_var_trimmed.h +++ b/registration/include/pcl/registration/correspondence_rejection_var_trimmed.h @@ -161,7 +161,7 @@ class PCL_EXPORTS CorrespondenceRejectorVarTrimmed : public CorrespondenceReject */ template inline void - setSearchMethodTarget(const typename pcl::search::KdTree::Ptr& tree, + setSearchMethodTarget(const typename pcl::search::Search::Ptr& tree, bool force_no_recompute = false) { static_pointer_cast>(data_container_) diff --git a/registration/include/pcl/registration/fricp.h b/registration/include/pcl/registration/fricp.h index 6b0f8f4006c..b93d6ae145d 100644 --- a/registration/include/pcl/registration/fricp.h +++ b/registration/include/pcl/registration/fricp.h @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/registration/include/pcl/registration/impl/correspondence_estimation.hpp b/registration/include/pcl/registration/impl/correspondence_estimation.hpp index 4ab57213e0f..78daa9a8079 100644 --- a/registration/include/pcl/registration/impl/correspondence_estimation.hpp +++ b/registration/include/pcl/registration/impl/correspondence_estimation.hpp @@ -44,6 +44,7 @@ #include #include #include // for isXYZFinite +#include namespace pcl { @@ -61,11 +62,6 @@ CorrespondenceEstimationBase::setInputTarget( return; } target_ = cloud; - - // Set the internal point representation of choice - if (point_representation_) - tree_->setPointRepresentation(point_representation_); - target_cloud_updated_ = true; } @@ -82,10 +78,23 @@ CorrespondenceEstimationBase::initCompute() // Only update target kd-tree if a new target cloud was set if (target_cloud_updated_ && !force_no_recompute_) { // If the target indices have been given via setIndicesTarget - if (target_indices_) - tree_->setInputCloud(target_, target_indices_); - else - tree_->setInputCloud(target_); + if (point_representation_) { + tree_.reset(pcl::search::autoSelectMethod( + target_, + (target_indices_ ? target_indices_ : pcl::IndicesConstPtr()), + false, + pcl::search::Purpose::one_knn_search)); + } + else if (target_indices_) { + if (!tree_ || !tree_->setInputCloud(target_, target_indices_)) + tree_.reset(pcl::search::autoSelectMethod( + target_, target_indices_, false, pcl::search::Purpose::one_knn_search)); + } + else { + if (!tree_ || !tree_->setInputCloud(target_)) + tree_.reset(pcl::search::autoSelectMethod( + target_, false, pcl::search::Purpose::one_knn_search)); + } target_cloud_updated_ = false; } @@ -99,14 +108,28 @@ CorrespondenceEstimationBase::initComputeRecip { // Only update source kd-tree if a new target cloud was set if (source_cloud_updated_ && !force_no_recompute_reciprocal_) { - if (point_representation_reciprocal_) - tree_reciprocal_->setPointRepresentation(point_representation_reciprocal_); - // If the target indices have been given via setIndicesTarget - if (indices_) - tree_reciprocal_->setInputCloud(getInputSource(), getIndicesSource()); - else - tree_reciprocal_->setInputCloud(getInputSource()); - + if (point_representation_reciprocal_) { + tree_reciprocal_.reset(pcl::search::autoSelectMethod( + getInputSource(), + (indices_ ? getIndicesSource() : pcl::IndicesConstPtr()), + point_representation_reciprocal_, + true, + pcl::search::Purpose::one_knn_search)); + } + else if (indices_) { + if (!tree_reciprocal_ || + !tree_reciprocal_->setInputCloud(getInputSource(), getIndicesSource())) + tree_reciprocal_.reset(pcl::search::autoSelectMethod( + getInputSource(), + getIndicesSource(), + true, + pcl::search::Purpose::one_knn_search)); + } + else { + if (!tree_reciprocal_ || !tree_reciprocal_->setInputCloud(getInputSource())) + tree_reciprocal_.reset(pcl::search::autoSelectMethod( + getInputSource(), true, pcl::search::Purpose::one_knn_search)); + } source_cloud_updated_ = false; } diff --git a/registration/include/pcl/registration/impl/fricp.hpp b/registration/include/pcl/registration/impl/fricp.hpp index 6d377f20a71..14fec8ad6fb 100644 --- a/registration/include/pcl/registration/impl/fricp.hpp +++ b/registration/include/pcl/registration/impl/fricp.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -218,9 +219,8 @@ FastRobustIterativeClosestPoint:: (*target_centered)[i].z = static_cast(target_mat(2, i)); } - pcl::search::KdTree tree_data; - pcl::search::Search& tree = tree_data; - tree.setInputCloud(target_centered); + pcl::search::Search::Ptr tree( + pcl::search::autoSelectMethod(target_centered, true)); Matrix4d transform_centered = convertGuessToCentered(guess, source_mean, target_mean); Matrix4d svd_transform = transform_centered; @@ -231,7 +231,7 @@ FastRobustIterativeClosestPoint:: if (!updateCorrespondences(transform_centered, source_mat, target_mat, - tree, + *tree, matched_targets, residuals, this->correspondences_.get())) { @@ -250,7 +250,7 @@ FastRobustIterativeClosestPoint:: double nu_limit = 1.0; double nu_current = 1.0; if (use_welsch) { - const double neighbor_med = findKNearestMedian(*target_centered, tree_data, 7); + const double neighbor_med = findKNearestMedian(*target_centered, *tree, 7); std::vector residual_values(static_cast(residuals.size())); for (Eigen::Index i = 0; i < residuals.size(); ++i) residual_values[static_cast(i)] = std::sqrt(residuals(i)); @@ -287,7 +287,7 @@ FastRobustIterativeClosestPoint:: if (!updateCorrespondences(transform_centered, source_mat, target_mat, - tree, + *tree, matched_targets, residuals, this->correspondences_.get())) { @@ -329,7 +329,7 @@ FastRobustIterativeClosestPoint:: if (!updateCorrespondences(transform_centered, source_mat, target_mat, - tree, + *tree, matched_targets, residuals, this->correspondences_.get())) { diff --git a/registration/include/pcl/registration/impl/ia_fpcs.hpp b/registration/include/pcl/registration/impl/ia_fpcs.hpp index 0b01484e0c9..ff11971257a 100644 --- a/registration/include/pcl/registration/impl/ia_fpcs.hpp +++ b/registration/include/pcl/registration/impl/ia_fpcs.hpp @@ -269,7 +269,9 @@ pcl::registration::FPCSInitialAlignmentsetInputCloud(target_, target_indices_); + if (!tree_ || !tree_->setInputCloud(target_, target_indices_)) + tree_.reset(pcl::search::autoSelectMethod( + target_, target_indices_, false, pcl::search::Purpose::one_knn_search)); target_cloud_updated_ = false; } diff --git a/registration/include/pcl/registration/impl/joint_icp.hpp b/registration/include/pcl/registration/impl/joint_icp.hpp index b1ac2ceda1f..0eb1a0709a0 100644 --- a/registration/include/pcl/registration/impl/joint_icp.hpp +++ b/registration/include/pcl/registration/impl/joint_icp.hpp @@ -62,10 +62,6 @@ JointIterativeClosestPoint::computeTransformat correspondence_estimations_.resize(sources_.size()); for (std::size_t i = 0; i < sources_.size(); i++) { correspondence_estimations_[i] = correspondence_estimation_->clone(); - KdTreeReciprocalPtr src_tree(new KdTreeReciprocal); - KdTreePtr tgt_tree(new KdTree); - correspondence_estimations_[i]->setSearchMethodTarget(tgt_tree); - correspondence_estimations_[i]->setSearchMethodSource(src_tree); } } if (correspondence_estimations_.size() != sources_.size()) { diff --git a/registration/include/pcl/registration/impl/registration.hpp b/registration/include/pcl/registration/impl/registration.hpp index 59a9794bd05..05b18c427a6 100644 --- a/registration/include/pcl/registration/impl/registration.hpp +++ b/registration/include/pcl/registration/impl/registration.hpp @@ -82,7 +82,17 @@ Registration::initCompute() // Only update target kd-tree if a new target cloud was set if (target_cloud_updated_ && !force_no_recompute_) { - tree_->setInputCloud(target_); + if (point_representation_) { + tree_.reset(pcl::search::autoSelectMethod( + target_, + pcl::IndicesConstPtr(), + point_representation_, + false, + pcl::search::Purpose::one_knn_search)); + } + else if (!tree_ || !tree_->setInputCloud(target_)) + tree_.reset(pcl::search::autoSelectMethod( + target_, false, pcl::search::Purpose::one_knn_search)); target_cloud_updated_ = false; } @@ -111,7 +121,8 @@ Registration::initComputeReciprocal() } if (source_cloud_updated_ && !force_no_recompute_reciprocal_) { - tree_reciprocal_->setInputCloud(input_); + if (!tree_reciprocal_ || !tree_reciprocal_->setInputCloud(input_)) + tree_reciprocal_.reset(pcl::search::autoSelectMethod(input_, false)); source_cloud_updated_ = false; } return (true); @@ -201,10 +212,6 @@ Registration::align(PointCloudSource& output, for (std::size_t i = 0; i < indices_->size(); ++i) output[i] = (*input_)[(*indices_)[i]]; - // Set the internal point representation of choice unless otherwise noted - if (point_representation_ && !force_no_recompute_) - tree_->setPointRepresentation(point_representation_); - // Perform the actual transformation computation converged_ = false; final_transformation_ = transformation_ = previous_transformation_ = diff --git a/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp b/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp index 67b2c07f011..06c31f55e65 100644 --- a/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp +++ b/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp @@ -74,8 +74,12 @@ TransformationValidationEuclidean:: typename MyPointRepresentation::ConstPtr point_rep(new MyPointRepresentation); if (!force_no_recompute_) { - tree_->setPointRepresentation(point_rep); - tree_->setInputCloud(cloud_tgt); + tree_.reset(pcl::search::autoSelectMethod( + cloud_tgt, + pcl::IndicesConstPtr(), + point_rep, + false, + pcl::search::Purpose::one_knn_search)); } pcl::Indices nn_indices(1); diff --git a/registration/include/pcl/registration/joint_icp.h b/registration/include/pcl/registration/joint_icp.h index a6290c476ac..4f2d269e077 100644 --- a/registration/include/pcl/registration/joint_icp.h +++ b/registration/include/pcl/registration/joint_icp.h @@ -65,10 +65,10 @@ class JointIterativeClosestPoint using PointCloudTargetPtr = typename PointCloudTarget::Ptr; using PointCloudTargetConstPtr = typename PointCloudTarget::ConstPtr; - using KdTree = pcl::search::KdTree; + using KdTree = pcl::search::Search; using KdTreePtr = typename KdTree::Ptr; - using KdTreeReciprocal = pcl::search::KdTree; + using KdTreeReciprocal = pcl::search::Search; using KdTreeReciprocalPtr = typename KdTree::Ptr; using PointIndicesPtr = PointIndices::Ptr; diff --git a/registration/include/pcl/registration/registration.h b/registration/include/pcl/registration/registration.h index a137ef2dc63..2c299fd09ce 100644 --- a/registration/include/pcl/registration/registration.h +++ b/registration/include/pcl/registration/registration.h @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -67,10 +67,10 @@ class Registration : public PCLBase { using ConstPtr = shared_ptr>; using CorrespondenceRejectorPtr = pcl::registration::CorrespondenceRejector::Ptr; - using KdTree = pcl::search::KdTree; + using KdTree = pcl::search::Search; using KdTreePtr = typename KdTree::Ptr; - using KdTreeReciprocal = pcl::search::KdTree; + using KdTreeReciprocal = pcl::search::Search; using KdTreeReciprocalPtr = typename KdTreeReciprocal::Ptr; using PointCloudSource = pcl::PointCloud; @@ -81,7 +81,8 @@ class Registration : public PCLBase { using PointCloudTargetPtr = typename PointCloudTarget::Ptr; using PointCloudTargetConstPtr = typename PointCloudTarget::ConstPtr; - using PointRepresentationConstPtr = typename KdTree::PointRepresentationConstPtr; + using PointRepresentationConstPtr = + typename PointRepresentation::ConstPtr; using TransformationEstimation = typename pcl::registration:: TransformationEstimation; @@ -107,9 +108,7 @@ class Registration : public PCLBase { /** \brief Empty constructor. */ Registration() - : tree_(new KdTree) - , tree_reciprocal_(new KdTreeReciprocal) - , target_() + : target_() , final_transformation_(Matrix4::Identity()) , transformation_(Matrix4::Identity()) , previous_transformation_(Matrix4::Identity()) diff --git a/registration/include/pcl/registration/transformation_validation_euclidean.h b/registration/include/pcl/registration/transformation_validation_euclidean.h index db5b3179aa3..8913f980c24 100644 --- a/registration/include/pcl/registration/transformation_validation_euclidean.h +++ b/registration/include/pcl/registration/transformation_validation_euclidean.h @@ -41,7 +41,6 @@ #pragma once #include -#include #include #include #include @@ -80,10 +79,11 @@ class TransformationValidationEuclidean { using ConstPtr = shared_ptr>; - using KdTree = pcl::search::KdTree; + using KdTree = pcl::search::Search; using KdTreePtr = typename KdTree::Ptr; - using PointRepresentationConstPtr = typename KdTree::PointRepresentationConstPtr; + using PointRepresentationConstPtr = + typename PointRepresentation::ConstPtr; using PointCloudSourceConstPtr = typename TransformationValidation::max()) , threshold_(std::numeric_limits::quiet_NaN()) - , tree_(new pcl::search::KdTree) {} virtual ~TransformationValidationEuclidean() = default; diff --git a/search/CMakeLists.txt b/search/CMakeLists.txt index 87070ca0ecc..b9301b5b6fc 100644 --- a/search/CMakeLists.txt +++ b/search/CMakeLists.txt @@ -1,9 +1,17 @@ set(SUBSYS_NAME search) set(SUBSYS_DESC "Point cloud generic search library") set(SUBSYS_DEPS common kdtree octree) +set(SUBSYS_OPT_DEPS OpenMP) +set(SUBSYS_EXT_DEPS "") +if(FLANN_FOUND) + list(APPEND SUBSYS_EXT_DEPS flann) +else() + list(REMOVE_ITEM SUBSYS_DEPS kdtree) + list(APPEND SUBSYS_OPT_DEPS flann) +endif() PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP EXT_DEPS flann) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS ${SUBSYS_OPT_DEPS} EXT_DEPS ${SUBSYS_EXT_DEPS}) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -19,16 +27,9 @@ set(srcs src/octree.cpp ) -if(FLANN_FOUND) - list(APPEND srcs - src/kdtree.cpp - ) -endif() - set(incs "include/pcl/${SUBSYS_NAME}/auto.h" "include/pcl/${SUBSYS_NAME}/search.h" - "include/pcl/${SUBSYS_NAME}/kdtree.h" "include/pcl/${SUBSYS_NAME}/kdtree_nanoflann.h" "include/pcl/${SUBSYS_NAME}/brute_force.h" "include/pcl/${SUBSYS_NAME}/organized.h" @@ -40,18 +41,22 @@ set(incs set(impl_incs "include/pcl/${SUBSYS_NAME}/impl/auto.hpp" "include/pcl/${SUBSYS_NAME}/impl/search.hpp" - "include/pcl/${SUBSYS_NAME}/impl/kdtree.hpp" "include/pcl/${SUBSYS_NAME}/impl/flann_search.hpp" "include/pcl/${SUBSYS_NAME}/impl/brute_force.hpp" "include/pcl/${SUBSYS_NAME}/impl/organized.hpp" ) +if(FLANN_FOUND) + list(APPEND srcs src/kdtree.cpp) + list(APPEND incs "include/pcl/${SUBSYS_NAME}/kdtree.h") + list(APPEND impl_incs "include/pcl/${SUBSYS_NAME}/impl/kdtree.hpp") +endif() + set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs}) -target_link_libraries("${LIB_NAME}" pcl_common pcl_octree pcl_kdtree) +target_link_libraries("${LIB_NAME}" pcl_common pcl_octree) if(FLANN_FOUND) - target_link_libraries("${LIB_NAME}" FLANN::FLANN) - list(APPEND EXT_DEPS flann) + target_link_libraries("${LIB_NAME}" FLANN::FLANN pcl_kdtree) endif() PCL_MAKE_PKGCONFIG(${LIB_NAME} COMPONENT ${SUBSYS_NAME} DESC ${SUBSYS_DESC} PCL_DEPS ${SUBSYS_DEPS}) diff --git a/search/include/pcl/search/auto.h b/search/include/pcl/search/auto.h index 6cb9f679e1e..07dd5f417e0 100644 --- a/search/include/pcl/search/auto.h +++ b/search/include/pcl/search/auto.h @@ -13,6 +13,8 @@ #include namespace pcl { + template class PointRepresentation; + namespace search { enum class Purpose : std::uint32_t { undefined = 0, ///< Default value, for general-purpose search method @@ -42,6 +44,17 @@ namespace pcl { */ template pcl::search::Search * autoSelectMethod(const typename pcl::PointCloud::ConstPtr& cloud, const pcl::IndicesConstPtr& indices, bool sorted_results, Purpose purpose = Purpose::undefined); + + /** + * Automatically select the fastest search method for the given point cloud. Make sure to delete the returned object after use! + * \param[in] cloud Point cloud, this function will pass it to the search method via setInputCloud + * \param[in] indices Will be passed to the search method via setInputCloud, together with the point cloud + * \param[in] point_representation Determines which fields are used for searching + * \param[in] sorted_results Whether the search method should always return results sorted by distance (may be slower than unsorted) + * \param[in] purpose Optional, can be used to give more information about what this search method will be used for, to achieve optimal performance + */ + template + pcl::search::Search * autoSelectMethod(const typename pcl::PointCloud::ConstPtr& cloud, const pcl::IndicesConstPtr& indices, const pcl::shared_ptr>& point_representation, bool sorted_results, Purpose purpose = Purpose::undefined); } // namespace search } // namespace pcl diff --git a/search/include/pcl/search/impl/auto.hpp b/search/include/pcl/search/impl/auto.hpp index 3316f49ca1b..0f2d3e4fb15 100644 --- a/search/include/pcl/search/impl/auto.hpp +++ b/search/include/pcl/search/impl/auto.hpp @@ -10,10 +10,13 @@ #ifndef PCL_SEARCH_AUTO_IMPL_HPP_ #define PCL_SEARCH_AUTO_IMPL_HPP_ +#include #include // for ignore #include #include +#if PCL_HAS_FLANN #include +#endif #include #include #include @@ -64,6 +67,47 @@ pcl::search::Search * pcl::search::autoSelectMethod(const typename pcl:: return searcher; } +template +pcl::search::Search * pcl::search::autoSelectMethod(const typename pcl::PointCloud::ConstPtr& cloud, const pcl::IndicesConstPtr& indices, const pcl::shared_ptr >& point_representation, bool sorted_results, pcl::search::Purpose purpose) { +#if PCL_HAS_NANOFLANN + // we get the number of search dimensions from the given point_representation, but we can only get it a run-time. Often, this is the same as when DefaultPointRepresentation is used, in this case we use the fast option of KdTreeNanoflann with a static number of dimensions (second template parameter). Otherwise, we use a KdTreeNanoflann with a dynamic number of dimensions (-1 as template parameter, slightly slower). + if(point_representation->getNumberOfDimensions() == pcl::DefaultPointRepresentation::NR_DIMS) { + auto searcher = new pcl::search::KdTreeNanoflann::NR_DIMS> (sorted_results, (purpose == pcl::search::Purpose::one_knn_search ? 10 : 20)); + searcher->setPointRepresentation (point_representation); + if(searcher->setInputCloud (cloud, indices)) { + return searcher; + } + delete searcher; + } + { + auto searcher = new pcl::search::KdTreeNanoflann (sorted_results, (purpose == pcl::search::Purpose::one_knn_search ? 10 : 20)); + searcher->setPointRepresentation (point_representation); + if(searcher->setInputCloud (cloud, indices)) { + return searcher; + } + delete searcher; + } +#else + pcl::utils::ignore(purpose); +#endif + +#if PCL_HAS_FLANN + { + auto searcher = new pcl::search::KdTree (sorted_results); + searcher->setPointRepresentation (point_representation); + if(searcher->setInputCloud (cloud, indices)) { + return searcher; + } + delete searcher; + } +#endif + + PCL_ERROR("[pcl::search::autoSelectMethod] No suitable method found. Make sure you have nanoflann and/or FLANN installed.\n"); + return nullptr; +} + #define PCL_INSTANTIATE_AutoSelectMethod(T) template PCL_EXPORTS pcl::search::Search * pcl::search::autoSelectMethod(const typename pcl::PointCloud::ConstPtr& cloud, const pcl::IndicesConstPtr& indices, bool sorted_results, pcl::search::Purpose purpose); +#define PCL_INSTANTIATE_AutoSelectMethod2(T) template PCL_EXPORTS pcl::search::Search * pcl::search::autoSelectMethod(const typename pcl::PointCloud::ConstPtr& cloud, const pcl::IndicesConstPtr& indices, const pcl::shared_ptr >& point_representation, bool sorted_results, pcl::search::Purpose purpose); + #endif //#ifndef PCL_SEARCH_AUTO_IMPL_HPP_ diff --git a/search/include/pcl/search/kdtree_nanoflann.h b/search/include/pcl/search/kdtree_nanoflann.h index 6bd12dd8794..af83d880a03 100644 --- a/search/include/pcl/search/kdtree_nanoflann.h +++ b/search/include/pcl/search/kdtree_nanoflann.h @@ -12,7 +12,7 @@ #include #if PCL_HAS_NANOFLANN || defined(DOXYGEN_ONLY) -#include +#include #include #include @@ -183,7 +183,7 @@ template , Dim, pcl::index_t>> -class KdTreeNanoflann : public pcl::search::KdTree { +class KdTreeNanoflann : public pcl::search::Search { private: /** The special thing here is that indices and distances are stored in _two_ vectors, * not as a pair in _one_ vector. @@ -310,7 +310,7 @@ class KdTreeNanoflann : public pcl::search::KdTree { KdTreeNanoflann(bool sorted, std::size_t leaf_max_size, unsigned int n_thread_build = 1) - : pcl::search::KdTree("KdTreeNanoflann", sorted) + : pcl::search::Search("KdTreeNanoflann", sorted) , leaf_max_size_(leaf_max_size) , n_thread_build_(n_thread_build) {} @@ -333,7 +333,7 @@ class KdTreeNanoflann : public pcl::search::KdTree { * @param[in] point_representation the const shared pointer to a PointRepresentation */ void - setPointRepresentation(const PointRepresentationConstPtr& point_representation) override + setPointRepresentation(const PointRepresentationConstPtr& point_representation) { PCL_DEBUG("[KdTreeNanoflann::setPointRepresentation] " "KdTreeNanoflann::setPointRepresentation called, " @@ -356,7 +356,7 @@ class KdTreeNanoflann : public pcl::search::KdTree { /** @brief Get a pointer to the point representation used when converting points into * k-D vectors. */ inline PointRepresentationConstPtr - getPointRepresentation() const override + getPointRepresentation() const { return point_representation_; } @@ -375,7 +375,7 @@ class KdTreeNanoflann : public pcl::search::KdTree { * @param[in] eps precision (error bound) for nearest neighbors searches */ void - setEpsilon(float eps) override + setEpsilon(float eps) { eps_ = eps; } @@ -383,7 +383,7 @@ class KdTreeNanoflann : public pcl::search::KdTree { /** @brief Get the search epsilon precision (error bound) for nearest neighbors * searches. */ inline float - getEpsilon() const override + getEpsilon() const { return eps_; } @@ -759,9 +759,6 @@ class KdTreeNanoflann : public pcl::search::KdTree { }; } // namespace search } // namespace pcl -#ifdef PCL_NO_PRECOMPILE -#include -#endif #else //#warning "KdTreeNanoflann is not available" diff --git a/search/src/auto.cpp b/search/src/auto.cpp index 4b1380f20e2..80985a25a2c 100644 --- a/search/src/auto.cpp +++ b/search/src/auto.cpp @@ -13,5 +13,6 @@ #include #include PCL_INSTANTIATE(AutoSelectMethod, PCL_POINT_TYPES) +PCL_INSTANTIATE(AutoSelectMethod2, PCL_POINT_TYPES) #endif // PCL_NO_PRECOMPILE diff --git a/segmentation/CMakeLists.txt b/segmentation/CMakeLists.txt index 6eca4e5625c..8f75dadf255 100644 --- a/segmentation/CMakeLists.txt +++ b/segmentation/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME segmentation) set(SUBSYS_DESC "Point cloud segmentation library") -set(SUBSYS_DEPS common geometry search sample_consensus kdtree octree features filters ml) +set(SUBSYS_DEPS common geometry search sample_consensus octree features filters ml) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") diff --git a/surface/CMakeLists.txt b/surface/CMakeLists.txt index 7c5f7dd52b3..e3cdfebb943 100644 --- a/surface/CMakeLists.txt +++ b/surface/CMakeLists.txt @@ -1,10 +1,10 @@ set(SUBSYS_NAME surface) set(SUBSYS_DESC "Point cloud surface library") -set(SUBSYS_DEPS common search kdtree octree) +set(SUBSYS_DEPS common search octree) set(SUBSYS_EXT_DEPS "") PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS qhull vtk OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS qhull vtk OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -168,7 +168,7 @@ set(impl_incs set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs} ${VTK_SMOOTHING_INCLUDES} ${POISSON_INCLUDES} ${OPENNURBS_INCLUDES} ${ON_NURBS_INCLUDES}) -target_link_libraries("${LIB_NAME}" pcl_common pcl_search pcl_kdtree pcl_octree ${ON_NURBS_LIBRARIES}) +target_link_libraries("${LIB_NAME}" pcl_common pcl_search pcl_octree ${ON_NURBS_LIBRARIES}) if(VTK_FOUND) if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.0) diff --git a/test/people/CMakeLists.txt b/test/people/CMakeLists.txt index d920a36bf47..09382b61a60 100644 --- a/test/people/CMakeLists.txt +++ b/test/people/CMakeLists.txt @@ -12,5 +12,5 @@ endif() 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_segmentation pcl_people + LINK_WITH pcl_gtest pcl_common pcl_io 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") diff --git a/test/segmentation/CMakeLists.txt b/test/segmentation/CMakeLists.txt index 3041d136ca8..45467b72197 100644 --- a/test/segmentation/CMakeLists.txt +++ b/test/segmentation/CMakeLists.txt @@ -17,7 +17,7 @@ PCL_ADD_TEST(random_walker test_random_walker PCL_ADD_TEST(a_segmentation_test test_segmentation FILES test_segmentation.cpp - LINK_WITH pcl_gtest pcl_io pcl_segmentation pcl_features pcl_kdtree pcl_search pcl_common + LINK_WITH pcl_gtest pcl_io pcl_segmentation pcl_features pcl_search pcl_common ARGUMENTS "${PCL_SOURCE_DIR}/test/bun0.pcd" "${PCL_SOURCE_DIR}/test/car6.pcd" "${PCL_SOURCE_DIR}/test/colored_cloud.pcd") PCL_ADD_TEST(progressive_morphological_filter test_progressive_morphological_filter @@ -30,5 +30,5 @@ PCL_ADD_TEST(a_prism_test test_concave_prism PCL_ADD_TEST(test_non_linear test_non_linear FILES test_non_linear.cpp - LINK_WITH pcl_gtest pcl_common pcl_io pcl_sample_consensus pcl_segmentation pcl_kdtree pcl_search + LINK_WITH pcl_gtest pcl_common pcl_io pcl_sample_consensus pcl_segmentation pcl_search ARGUMENTS "${PCL_SOURCE_DIR}/test/noisy_slice_displaced.pcd") diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index dd1f34f9912..2803af67add 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -139,11 +139,11 @@ if(TARGET pcl_search) target_link_libraries(pcl_compute_hausdorff pcl_common pcl_io pcl_search) PCL_ADD_EXECUTABLE(pcl_compute_cloud_error COMPONENT ${SUBSYS_NAME} SOURCES compute_cloud_error.cpp) - target_link_libraries (pcl_compute_cloud_error pcl_common pcl_io pcl_kdtree pcl_search) + target_link_libraries (pcl_compute_cloud_error pcl_common pcl_io pcl_search) if(TARGET pcl_visualization) PCL_ADD_EXECUTABLE(pcl_viewer COMPONENT ${SUBSYS_NAME} SOURCES pcd_viewer.cpp BUNDLE) - target_link_libraries(pcl_viewer pcl_common pcl_io pcl_kdtree pcl_search pcl_visualization ) + target_link_libraries(pcl_viewer pcl_common pcl_io pcl_search pcl_visualization ) endif() endif() @@ -174,7 +174,7 @@ if(TARGET pcl_filters) if(TARGET pcl_segmentation) PCL_ADD_EXECUTABLE(pcl_cluster_extraction COMPONENT ${SUBSYS_NAME} SOURCES cluster_extraction.cpp) - target_link_libraries (pcl_cluster_extraction pcl_common pcl_io pcl_kdtree pcl_filters pcl_segmentation) + target_link_libraries (pcl_cluster_extraction pcl_common pcl_io pcl_filters pcl_segmentation) PCL_ADD_EXECUTABLE(pcl_progressive_morphological_filter COMPONENT ${SUBSYS_NAME} SOURCES progressive_morphological_filter.cpp) target_link_libraries(pcl_progressive_morphological_filter pcl_common pcl_io pcl_filters pcl_segmentation) @@ -190,19 +190,19 @@ if(TARGET pcl_filters) if(TARGET pcl_keypoints) PCL_ADD_EXECUTABLE(pcl_uniform_sampling COMPONENT ${SUBSYS_NAME} SOURCES uniform_sampling.cpp) - target_link_libraries (pcl_uniform_sampling pcl_common pcl_io pcl_kdtree pcl_filters pcl_keypoints) + target_link_libraries (pcl_uniform_sampling pcl_common pcl_io pcl_filters pcl_keypoints) endif() if(TARGET pcl_registration) if(TARGET pcl_visualization) PCL_ADD_EXECUTABLE(pcl_registration_visualizer COMPONENT ${SUBSYS_NAME} SOURCES registration_visualizer.cpp) - target_link_libraries(pcl_registration_visualizer pcl_common pcl_io pcl_kdtree pcl_filters pcl_registration pcl_visualization) + target_link_libraries(pcl_registration_visualizer pcl_common pcl_io pcl_filters pcl_registration pcl_visualization) endif() endif() if(TARGET pcl_visualization) PCL_ADD_EXECUTABLE(pcl_octree_viewer COMPONENT ${SUBSYS_NAME} SOURCES octree_viewer.cpp) - target_link_libraries(pcl_octree_viewer pcl_common pcl_io pcl_octree pcl_kdtree pcl_filters pcl_visualization) + target_link_libraries(pcl_octree_viewer pcl_common pcl_io pcl_octree pcl_filters pcl_visualization) PCL_ADD_EXECUTABLE(pcl_mesh2pcd COMPONENT ${SUBSYS_NAME} SOURCES mesh2pcd.cpp) target_link_libraries(pcl_mesh2pcd pcl_common pcl_io pcl_filters pcl_visualization) @@ -222,11 +222,13 @@ if(TARGET pcl_segmentation) PCL_ADD_EXECUTABLE(pcl_sac_segmentation_plane COMPONENT ${SUBSYS_NAME} SOURCES sac_segmentation_plane.cpp) target_link_libraries(pcl_sac_segmentation_plane pcl_common pcl_io pcl_sample_consensus pcl_segmentation) - PCL_ADD_EXECUTABLE(pcl_train_unary_classifier COMPONENT ${SUBSYS_NAME} SOURCES train_unary_classifier.cpp) - target_link_libraries (pcl_train_unary_classifier pcl_common pcl_io pcl_segmentation) + if(FLANN_FOUND) + PCL_ADD_EXECUTABLE(pcl_train_unary_classifier COMPONENT ${SUBSYS_NAME} SOURCES train_unary_classifier.cpp) + target_link_libraries (pcl_train_unary_classifier pcl_common pcl_io pcl_segmentation) - PCL_ADD_EXECUTABLE(pcl_unary_classifier_segment COMPONENT ${SUBSYS_NAME} SOURCES unary_classifier_segment.cpp) - target_link_libraries (pcl_unary_classifier_segment pcl_common pcl_io pcl_segmentation) + PCL_ADD_EXECUTABLE(pcl_unary_classifier_segment COMPONENT ${SUBSYS_NAME} SOURCES unary_classifier_segment.cpp) + target_link_libraries (pcl_unary_classifier_segment pcl_common pcl_io pcl_segmentation) + endif() PCL_ADD_EXECUTABLE(pcl_crf_segmentation COMPONENT ${SUBSYS_NAME} SOURCES crf_segmentation.cpp) target_link_libraries (pcl_crf_segmentation pcl_common pcl_io pcl_segmentation) @@ -244,22 +246,22 @@ endif() if(TARGET pcl_features) PCL_ADD_EXECUTABLE(pcl_normal_estimation COMPONENT ${SUBSYS_NAME} SOURCES normal_estimation.cpp) - target_link_libraries (pcl_normal_estimation pcl_common pcl_io pcl_kdtree pcl_features) + target_link_libraries (pcl_normal_estimation pcl_common pcl_io pcl_features) PCL_ADD_EXECUTABLE(pcl_boundary_estimation COMPONENT ${SUBSYS_NAME} SOURCES boundary_estimation.cpp) - target_link_libraries (pcl_boundary_estimation pcl_common pcl_io pcl_kdtree pcl_features) + target_link_libraries (pcl_boundary_estimation pcl_common pcl_io pcl_features) PCL_ADD_EXECUTABLE(pcl_fpfh_estimation COMPONENT ${SUBSYS_NAME} SOURCES fpfh_estimation.cpp) - target_link_libraries (pcl_fpfh_estimation pcl_common pcl_io pcl_kdtree pcl_features) + target_link_libraries (pcl_fpfh_estimation pcl_common pcl_io pcl_features) PCL_ADD_EXECUTABLE(pcl_vfh_estimation COMPONENT ${SUBSYS_NAME} SOURCES vfh_estimation.cpp) - target_link_libraries (pcl_vfh_estimation pcl_common pcl_io pcl_kdtree pcl_features) + target_link_libraries (pcl_vfh_estimation pcl_common pcl_io pcl_features) PCL_ADD_EXECUTABLE(pcl_spin_estimation COMPONENT ${SUBSYS_NAME} SOURCES spin_estimation.cpp) - target_link_libraries (pcl_spin_estimation pcl_common pcl_io pcl_kdtree pcl_features) + target_link_libraries (pcl_spin_estimation pcl_common pcl_io pcl_features) PCL_ADD_EXECUTABLE(pcl_extract_feature COMPONENT ${SUBSYS_NAME} SOURCES extract_feature.cpp) - target_link_libraries (pcl_extract_feature pcl_common pcl_io pcl_kdtree pcl_features) + target_link_libraries (pcl_extract_feature pcl_common pcl_io pcl_features) endif() if(TARGET pcl_surface) @@ -337,10 +339,10 @@ endif() if(TARGET pcl_visualization) PCL_ADD_EXECUTABLE(pcl_pcd_image_viewer COMPONENT ${SUBSYS_NAME} SOURCES image_viewer.cpp BUNDLE) - target_link_libraries(pcl_pcd_image_viewer pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_pcd_image_viewer pcl_common pcl_io pcl_visualization) PCL_ADD_EXECUTABLE(pcl_timed_trigger_test COMPONENT ${SUBSYS_NAME} SOURCES timed_trigger_test.cpp) - target_link_libraries(pcl_timed_trigger_test pcl_io pcl_common pcl_kdtree pcl_visualization) + target_link_libraries(pcl_timed_trigger_test pcl_io pcl_common pcl_visualization) PCL_ADD_EXECUTABLE(pcl_hdl_viewer_simple COMPONENT ${SUBSYS_NAME} SOURCES hdl_viewer_simple.cpp) target_link_libraries(pcl_hdl_viewer_simple pcl_io pcl_common pcl_visualization) @@ -353,30 +355,30 @@ if(TARGET pcl_visualization) target_link_libraries(pcl_openni_save_image pcl_common pcl_io pcl_visualization) 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) + target_link_libraries(pcl_pcd_grabber_viewer pcl_common pcl_io pcl_visualization) PCL_ADD_EXECUTABLE(pcl_image_grabber_saver COMPONENT ${SUBSYS_NAME} SOURCES image_grabber_saver.cpp BUNDLE) - target_link_libraries(pcl_image_grabber_saver pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_image_grabber_saver pcl_common pcl_io pcl_visualization) PCL_ADD_EXECUTABLE(pcl_image_grabber_viewer COMPONENT ${SUBSYS_NAME} SOURCES image_grabber_viewer.cpp BUNDLE) - target_link_libraries(pcl_image_grabber_viewer pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_image_grabber_viewer pcl_common pcl_io pcl_visualization) PCL_ADD_EXECUTABLE(pcl_openni_viewer_simple COMPONENT ${SUBSYS_NAME} SOURCES openni_viewer_simple.cpp) - target_link_libraries(pcl_openni_viewer_simple pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_openni_viewer_simple pcl_common pcl_io pcl_visualization) PCL_ADD_EXECUTABLE(pcl_oni_viewer COMPONENT ${SUBSYS_NAME} SOURCES oni_viewer_simple.cpp BUNDLE) - target_link_libraries(pcl_oni_viewer pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_oni_viewer pcl_common pcl_io pcl_visualization) PCL_ADD_EXECUTABLE(pcl_openni_viewer COMPONENT ${SUBSYS_NAME} SOURCES openni_viewer.cpp BUNDLE) - target_link_libraries(pcl_openni_viewer pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_openni_viewer pcl_common pcl_io 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_visualization) endif() if(WITH_OPENNI2) PCL_ADD_EXECUTABLE(pcl_openni2_viewer COMPONENT ${SUBSYS_NAME} SOURCES openni2_viewer.cpp BUNDLE) - target_link_libraries(pcl_openni2_viewer pcl_common pcl_io pcl_kdtree pcl_visualization) + target_link_libraries(pcl_openni2_viewer pcl_common pcl_io pcl_visualization) endif() if(WITH_ENSENSO) diff --git a/tracking/CMakeLists.txt b/tracking/CMakeLists.txt index cd1fb8777a8..bd30fea1e3f 100644 --- a/tracking/CMakeLists.txt +++ b/tracking/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME tracking) set(SUBSYS_DESC "Point cloud tracking library") -set(SUBSYS_DEPS common search kdtree filters octree) +set(SUBSYS_DEPS common search filters octree) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} OPT_DEPS OpenMP kdtree) PCL_ADD_DOC("${SUBSYS_NAME}") @@ -52,7 +52,7 @@ set(impl_incs set(LIB_NAME "pcl_${SUBSYS_NAME}") PCL_ADD_LIBRARY(${LIB_NAME} COMPONENT ${SUBSYS_NAME} SOURCES ${srcs} ${incs} ${impl_incs}) -target_link_libraries("${LIB_NAME}" pcl_common pcl_kdtree pcl_search pcl_filters pcl_octree) +target_link_libraries("${LIB_NAME}" pcl_common pcl_search pcl_filters pcl_octree) 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}) diff --git a/visualization/CMakeLists.txt b/visualization/CMakeLists.txt index 5259b8bc537..f8af1845e4a 100644 --- a/visualization/CMakeLists.txt +++ b/visualization/CMakeLists.txt @@ -1,9 +1,9 @@ set(SUBSYS_NAME visualization) set(SUBSYS_DESC "Point cloud visualization library") -set(SUBSYS_DEPS common io kdtree geometry search octree) +set(SUBSYS_DEPS common io geometry search octree) PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} EXT_DEPS vtk) +PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} EXT_DEPS vtk OPT_DEPS kdtree) if(ANDROID) message("VTK was found, but cannot be compiled for Android. Please use VES instead.") @@ -138,7 +138,7 @@ if(APPLE) target_link_libraries("${LIB_NAME}" "-framework Cocoa") endif() -target_link_libraries("${LIB_NAME}" pcl_common pcl_io pcl_kdtree pcl_geometry pcl_search ${OPENGL_LIBRARIES}) +target_link_libraries("${LIB_NAME}" pcl_common pcl_io pcl_geometry pcl_search ${OPENGL_LIBRARIES}) if(${VTK_VERSION} VERSION_GREATER_EQUAL 9.6 AND UNIX AND NOT ANDROID AND NOT APPLE AND NOT APPLE_IOS) find_package(X11 REQUIRED) From ff07499f0a35491bf854c4a5e04386805ed6f66a Mon Sep 17 00:00:00 2001 From: Markus Vieth Date: Tue, 1 Sep 2026 16:13:53 +0200 Subject: [PATCH 2/2] Address review --- .../include/pcl/recognition/impl/hv/hv_go.hpp | 1 + .../impl/correspondence_estimation.hpp | 7 ++++--- .../pcl/registration/impl/registration.hpp | 2 ++ .../impl/transformation_validation_euclidean.hpp | 7 +++++-- .../include/pcl/registration/joint_icp.h | 2 +- .../transformation_validation_euclidean.h | 6 +++--- search/include/pcl/search/impl/auto.hpp | 8 ++++++-- search/include/pcl/search/kdtree_nanoflann.h | 3 ++- test/registration/test_registration_api.cpp | 16 ++++++++++++++++ 9 files changed, 40 insertions(+), 12 deletions(-) diff --git a/recognition/include/pcl/recognition/impl/hv/hv_go.hpp b/recognition/include/pcl/recognition/impl/hv/hv_go.hpp index bb14ce56026..6cf7abd26ff 100644 --- a/recognition/include/pcl/recognition/impl/hv/hv_go.hpp +++ b/recognition/include/pcl/recognition/impl/hv/hv_go.hpp @@ -41,6 +41,7 @@ #include // for getMinMax3D #include #include +#include #include #include diff --git a/registration/include/pcl/registration/impl/correspondence_estimation.hpp b/registration/include/pcl/registration/impl/correspondence_estimation.hpp index 78daa9a8079..a327b30afb8 100644 --- a/registration/include/pcl/registration/impl/correspondence_estimation.hpp +++ b/registration/include/pcl/registration/impl/correspondence_estimation.hpp @@ -82,6 +82,7 @@ CorrespondenceEstimationBase::initCompute() tree_.reset(pcl::search::autoSelectMethod( target_, (target_indices_ ? target_indices_ : pcl::IndicesConstPtr()), + point_representation_, false, pcl::search::Purpose::one_knn_search)); } @@ -113,7 +114,7 @@ CorrespondenceEstimationBase::initComputeRecip getInputSource(), (indices_ ? getIndicesSource() : pcl::IndicesConstPtr()), point_representation_reciprocal_, - true, + false, pcl::search::Purpose::one_knn_search)); } else if (indices_) { @@ -122,13 +123,13 @@ CorrespondenceEstimationBase::initComputeRecip tree_reciprocal_.reset(pcl::search::autoSelectMethod( getInputSource(), getIndicesSource(), - true, + false, pcl::search::Purpose::one_knn_search)); } else { if (!tree_reciprocal_ || !tree_reciprocal_->setInputCloud(getInputSource())) tree_reciprocal_.reset(pcl::search::autoSelectMethod( - getInputSource(), true, pcl::search::Purpose::one_knn_search)); + getInputSource(), false, pcl::search::Purpose::one_knn_search)); } source_cloud_updated_ = false; } diff --git a/registration/include/pcl/registration/impl/registration.hpp b/registration/include/pcl/registration/impl/registration.hpp index 05b18c427a6..0a22aff85ae 100644 --- a/registration/include/pcl/registration/impl/registration.hpp +++ b/registration/include/pcl/registration/impl/registration.hpp @@ -40,6 +40,8 @@ #pragma once +#include + namespace pcl { template diff --git a/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp b/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp index 06c31f55e65..5583d2b7926 100644 --- a/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp +++ b/registration/include/pcl/registration/impl/transformation_validation_euclidean.hpp @@ -41,6 +41,8 @@ #ifndef PCL_REGISTRATION_TRANSFORMATION_VALIDATION_EUCLIDEAN_IMPL_H_ #define PCL_REGISTRATION_TRANSFORMATION_VALIDATION_EUCLIDEAN_IMPL_H_ +#include + namespace pcl { namespace registration { @@ -72,9 +74,10 @@ TransformationValidationEuclidean:: transformation_matrix(2, 2) * src.z + transformation_matrix(2, 3)); } + KdTreePtr tree; typename MyPointRepresentation::ConstPtr point_rep(new MyPointRepresentation); if (!force_no_recompute_) { - tree_.reset(pcl::search::autoSelectMethod( + tree.reset(pcl::search::autoSelectMethod( cloud_tgt, pcl::IndicesConstPtr(), point_rep, @@ -89,7 +92,7 @@ TransformationValidationEuclidean:: int nr = 0; for (const auto& point : input_transformed) { // Find its nearest neighbor in the target - tree_->nearestKSearch(point, 1, nn_indices, nn_dists); + tree->nearestKSearch(point, 1, nn_indices, nn_dists); // Deal with occlusions (incomplete targets) if (nn_dists[0] > max_range_) diff --git a/registration/include/pcl/registration/joint_icp.h b/registration/include/pcl/registration/joint_icp.h index 4f2d269e077..b8554117b68 100644 --- a/registration/include/pcl/registration/joint_icp.h +++ b/registration/include/pcl/registration/joint_icp.h @@ -69,7 +69,7 @@ class JointIterativeClosestPoint using KdTreePtr = typename KdTree::Ptr; using KdTreeReciprocal = pcl::search::Search; - using KdTreeReciprocalPtr = typename KdTree::Ptr; + using KdTreeReciprocalPtr = typename KdTreeReciprocal::Ptr; using PointIndicesPtr = PointIndices::Ptr; using PointIndicesConstPtr = PointIndices::ConstPtr; diff --git a/registration/include/pcl/registration/transformation_validation_euclidean.h b/registration/include/pcl/registration/transformation_validation_euclidean.h index 8913f980c24..dce4063c500 100644 --- a/registration/include/pcl/registration/transformation_validation_euclidean.h +++ b/registration/include/pcl/registration/transformation_validation_euclidean.h @@ -244,10 +244,10 @@ class TransformationValidationEuclidean { } /** \brief Empty destructor */ - virtual ~MyPointRepresentation() = default; + ~MyPointRepresentation() override = default; - virtual void - copyToFloatArray(const PointTarget& p, float* out) const + void + copyToFloatArray(const PointTarget& p, float* out) const override { out[0] = p.x; out[1] = p.y; diff --git a/search/include/pcl/search/impl/auto.hpp b/search/include/pcl/search/impl/auto.hpp index 0f2d3e4fb15..27d06d87d98 100644 --- a/search/include/pcl/search/impl/auto.hpp +++ b/search/include/pcl/search/impl/auto.hpp @@ -102,8 +102,12 @@ pcl::search::Search * pcl::search::autoSelectMethod(const typename pcl:: } #endif - PCL_ERROR("[pcl::search::autoSelectMethod] No suitable method found. Make sure you have nanoflann and/or FLANN installed.\n"); - return nullptr; + { + auto searcher = new pcl::search::BruteForce (sorted_results); + searcher->setPointRepresentation (point_representation); + searcher->setInputCloud (cloud, indices); + return searcher; + } } #define PCL_INSTANTIATE_AutoSelectMethod(T) template PCL_EXPORTS pcl::search::Search * pcl::search::autoSelectMethod(const typename pcl::PointCloud::ConstPtr& cloud, const pcl::IndicesConstPtr& indices, bool sorted_results, pcl::search::Purpose purpose); diff --git a/search/include/pcl/search/kdtree_nanoflann.h b/search/include/pcl/search/kdtree_nanoflann.h index af83d880a03..7f623d58530 100644 --- a/search/include/pcl/search/kdtree_nanoflann.h +++ b/search/include/pcl/search/kdtree_nanoflann.h @@ -350,7 +350,8 @@ class KdTreeNanoflann : public pcl::search::Search { return; } point_representation_ = point_representation; - setUpTree(); + if (input_) + setUpTree(); } /** @brief Get a pointer to the point representation used when converting points into diff --git a/test/registration/test_registration_api.cpp b/test/registration/test_registration_api.cpp index 7395afafa7f..3da0b1d0c33 100644 --- a/test/registration/test_registration_api.cpp +++ b/test/registration/test_registration_api.cpp @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -777,6 +778,21 @@ TEST (PCL, FastRobustIterativeClosestPoint) EXPECT_LT (reg_guess.getFitnessScore (), 5e-4); } +TEST (PCL, TransformationValidationEuclidean) +{ + CloudXYZConstPtr source (new CloudXYZ (cloud_source)); + CloudXYZConstPtr target (new CloudXYZ (cloud_target)); + Eigen::Matrix4f ground_truth_tform = Eigen::Matrix4f::Identity (); + ground_truth_tform.row (0) << 0.825336f, 0.000000f, -0.564642f, 0.037267f; + ground_truth_tform.row (1) << 0.000000f, 1.000000f, 0.000000f, 0.000000f; + ground_truth_tform.row (2) << 0.564642f, 0.000000f, 0.825336f, 0.038325f; + ground_truth_tform.row (3) << 0.000000f, 0.000000f, 0.000000f, 1.000000f; + pcl::registration::TransformationValidationEuclidean tve; + tve.setMaxRange (0.01); // 1cm + EXPECT_LT (tve.validateTransformation (source, target, ground_truth_tform), 1e-3); + ground_truth_tform (0, 3) = 10.0f; // Bad transformation + EXPECT_GT (tve.validateTransformation (source, target, ground_truth_tform), 1e-3); +} /* ---[ */ int