30 #ifndef MCL_3DL_CHUNKED_KDTREE_H 31 #define MCL_3DL_CHUNKED_KDTREE_H 33 #include <pcl/point_types.h> 34 #include <pcl/kdtree/kdtree.h> 35 #include <pcl/kdtree/kdtree_flann.h> 38 #include <unordered_map> 43 template <
typename POINT_TYPE>
47 using Ptr = std::shared_ptr<ChunkedKdtree>;
52 using Ptr = std::shared_ptr<ChunkId>;
60 return x_ == a.
x_ && y_ == a.
y_ && z_ == a.
z_;
72 return (
id.x_) ^ (
id.y_ << 11) ^ (
id.z_ << 22);
74 ChunkId(
const int& x,
const int& y,
const int& z)
89 const float chunk_length = 20.0,
90 const float max_search_radius = 1.0,
91 const bool keep_clouds =
false)
106 chunk.second.kdtree_->setEpsilon(
epsilon_);
115 chunk.second.kdtree_->setPointRepresentation(
point_rep_);
119 const typename pcl::PointCloud<POINT_TYPE>::ConstPtr cloud)
126 for (
auto& p : *cloud)
129 clouds[chunk_id].push_back(p);
130 ids[chunk_id].push_back(i);
153 if (x_bound && y_bound && z_bound)
156 clouds[id].push_back(p);
157 ids[id].push_back(i);
159 if (x_bound && y_bound)
162 clouds[id].push_back(p);
163 ids[id].push_back(i);
165 if (y_bound && z_bound)
168 clouds[id].push_back(p);
169 ids[id].push_back(i);
171 if (z_bound && x_bound)
174 clouds[id].push_back(p);
175 ids[id].push_back(i);
180 clouds[id].push_back(p);
181 ids[id].push_back(i);
186 clouds[id].push_back(p);
187 ids[id].push_back(i);
192 clouds[id].push_back(p);
193 ids[id].push_back(i);
197 for (
auto& cloud : clouds)
203 auto cloud_ptr = cloud.second.makeShared();
204 chunks_[cloud.first].kdtree_->setInputCloud(cloud_ptr);
206 chunks_[cloud.first].cloud_ = cloud_ptr;
207 chunks_[cloud.first].original_ids_ = ids[cloud.first];
213 std::vector<int>&
id,
214 std::vector<float>& dist_sq,
218 throw std::runtime_error(
"ChunkedKdtree: radius must be <chunk_length");
224 const auto ret =
chunks_[chunk_id].kdtree_->radiusSearch(p, radius,
id, dist_sq, num);
227 i =
chunks_[chunk_id].original_ids_[i];
238 return typename pcl::KdTreeFLANN<POINT_TYPE>::Ptr();
248 return typename pcl::PointCloud<POINT_TYPE>::Ptr();
262 typename pcl::KdTreeFLANN<POINT_TYPE>::Ptr
kdtree_;
264 typename pcl::PointCloud<POINT_TYPE>::Ptr
cloud_;
267 : kdtree_(new
pcl::KdTreeFLANN<POINT_TYPE>)
281 using ChunkMap = std::unordered_map<ChunkId, Chunk, ChunkId>;
288 #endif // MCL_3DL_CHUNKED_KDTREE_H std::vector< size_t > original_ids_
pcl::PointCloud< POINT_TYPE >::Ptr getChunkCloud(const ChunkId &c)
const float chunk_length_
std::shared_ptr< ChunkedKdtree > Ptr
pcl::PointCloud< POINT_TYPE >::Ptr getChunkCloud(const POINT_TYPE p)
pcl::KdTreeFLANN< POINT_TYPE >::Ptr getChunkKdtree(const POINT_TYPE p)
sensor_msgs::PointCloud2 PointCloud
std::unordered_map< ChunkId, typename pcl::PointCloud< mcl_3dl::PointXYZIL >, ChunkId > ChunkCloud
pcl::KdTreeFLANN< POINT_TYPE >::Ptr kdtree_
ChunkedKdtree(const float chunk_length=20.0, const float max_search_radius=1.0, const bool keep_clouds=false)
ChunkId getChunkId(const POINT_TYPE p) const
constexpr bool operator!=(const ChunkId &a) const
int radiusSearch(const POINT_TYPE &p, const float &radius, std::vector< int > &id, std::vector< float > &dist_sq, const size_t &num)
std::unordered_map< ChunkId, Chunk, ChunkId > ChunkMap
std::shared_ptr< ChunkId > Ptr
const float max_search_radius_
void setPointRepresentation(boost::shared_ptr< pcl::PointRepresentation< POINT_TYPE >> point_rep)
void setInputCloud(const typename pcl::PointCloud< POINT_TYPE >::ConstPtr cloud)
constexpr ChunkId operator+(const ChunkId &a) const
boost::shared_ptr< pcl::PointRepresentation< POINT_TYPE > > point_rep_
std::unordered_map< ChunkId, std::vector< size_t >, ChunkId > ChunkOriginalIds
const float pos_to_chunk_
pcl::PointCloud< POINT_TYPE >::Ptr cloud_
pcl::KdTreeFLANN< POINT_TYPE >::Ptr getChunkKdtree(const ChunkId &c)
constexpr bool operator==(const ChunkId &a) const
size_t operator()(const ChunkId &id) const
ChunkId(const int &x, const int &y, const int &z)
void setEpsilon(const float epsilon)