/************************************************************ * * Copyright (c) 2021, University of California, Los Angeles * * Authors: Kenny J. Chen, Brett T. Lopez * Contact: kennyjchen@ucla.edu, btlopez@ucla.edu * ***********************************************************/ /*********************************************************************** * Software License Agreement (BSD License) * * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. * Copyright 2011-2021 Jose Luis Blanco (joseluisblancoc@gmail.com). * All rights reserved. * * THE BSD LICENSE * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *************************************************************************/ #ifndef NANO_KDTREE_KDTREE_FLANN_H_ #define NANO_KDTREE_KDTREE_FLANN_H_ #include #include #include #include #include "nano_gicp/impl/nanoflann_impl.hpp" namespace nanoflann { template class KdTreeFLANN { public: typedef typename pcl::PointCloud PointCloud; typedef typename pcl::PointCloud::Ptr PointCloudPtr; typedef typename pcl::PointCloud::ConstPtr PointCloudConstPtr; typedef boost::shared_ptr> Ptr; typedef boost::shared_ptr> ConstPtr; typedef boost::shared_ptr> IndicesPtr; typedef boost::shared_ptr> IndicesConstPtr; KdTreeFLANN (bool sorted = false); KdTreeFLANN (const KdTreeFLANN &k); void setEpsilon (float eps); void setSortedResults (bool sorted); inline Ptr makeShared () { return Ptr (new KdTreeFLANN (*this)); } void setInputCloud (const PointCloudConstPtr &cloud, const IndicesConstPtr &indices = IndicesConstPtr ()); inline PointCloudConstPtr getInputCloud() const { return _adaptor.pcl; } int nearestKSearch (const PointT &point, int k, std::vector &k_indices, std::vector &k_sqr_distances) const; int radiusSearch (const PointT &point, double radius, std::vector &k_indices, std::vector &k_sqr_distances) const; protected: nanoflann::SearchParams _params; struct PointCloud_Adaptor { inline size_t kdtree_get_point_count() const; inline float kdtree_get_pt(const size_t idx, int dim) const; template bool kdtree_get_bbox(BBOX&) const { return false; } PointCloudConstPtr pcl; IndicesConstPtr indices; }; typedef nanoflann::KDTreeSingleIndexAdaptor< nanoflann::SO3_Adaptor , PointCloud_Adaptor, 3, int> KDTreeFlann_PCL_SO3; PointCloud_Adaptor _adaptor; KDTreeFlann_PCL_SO3 _kdtree; }; //---------- Definitions --------------------- template inline KdTreeFLANN::KdTreeFLANN(bool sorted): _kdtree(3,_adaptor, KDTreeSingleIndexAdaptorParams(100)) { _params.sorted = sorted; } template inline void KdTreeFLANN::setEpsilon(float eps) { _params.eps = eps; } template inline void KdTreeFLANN::setSortedResults(bool sorted) { _params.sorted = sorted; } template inline void KdTreeFLANN::setInputCloud(const KdTreeFLANN::PointCloudConstPtr &cloud, const IndicesConstPtr &indices) { _adaptor.pcl = cloud; _adaptor.indices = indices; _kdtree.buildIndex(); } template inline int KdTreeFLANN::nearestKSearch(const PointT &point, int num_closest, std::vector &k_indices, std::vector &k_sqr_distances) const { k_indices.resize(num_closest); k_sqr_distances.resize(num_closest); nanoflann::KNNResultSet resultSet(num_closest); resultSet.init( k_indices.data(), k_sqr_distances.data()); _kdtree.findNeighbors(resultSet, point.data, nanoflann::SearchParams() ); return resultSet.size(); } template inline int KdTreeFLANN::radiusSearch(const PointT &point, double radius, std::vector &k_indices, std::vector &k_sqr_distances) const { static std::vector > indices_dist; indices_dist.reserve( 128 ); RadiusResultSet resultSet(radius, indices_dist); const size_t nFound = _kdtree.findNeighbors(resultSet, point.data, _params); if (_params.sorted) std::sort(indices_dist.begin(), indices_dist.end(), IndexDist_Sorter() ); k_indices.resize(nFound); k_sqr_distances.resize(nFound); for(int i=0; i inline size_t KdTreeFLANN::PointCloud_Adaptor::kdtree_get_point_count() const { if( indices ) return indices->size(); if( pcl) return pcl->points.size(); return 0; } template inline float KdTreeFLANN::PointCloud_Adaptor::kdtree_get_pt(const size_t idx, int dim) const{ const PointT& p = ( indices ) ? pcl->points[(*indices)[idx]] : pcl->points[idx]; if (dim==0) return p.x; else if (dim==1) return p.y; else if (dim==2) return p.z; else return 0.0; } } #endif