41 #include <pcl/common/common.h>
42 #include <pcl/common/point_tests.h>
43 #include <pcl/octree/impl/octree_base.hpp>
44 #include <pcl/types.h>
50 typename LeafContainerT,
51 typename BranchContainerT,
58 , resolution_(resolution)
63 if (resolution <= 0.0) {
65 "[pcl::octree::OctreePointCloud::OctreePointCloud] Resolution "
66 << resolution <<
" must be > 0!");
72 typename LeafContainerT,
73 typename BranchContainerT,
80 for (
const auto& index : *indices_) {
81 assert((index >= 0) && (static_cast<std::size_t>(index) < input_->size()));
85 this->addPointIdx(index);
90 for (
index_t i = 0; i < static_cast<index_t>(input_->size()); i++) {
100 template <
typename PointT,
101 typename LeafContainerT,
102 typename BranchContainerT,
108 this->addPointIdx(point_idx_arg);
110 indices_arg->push_back(point_idx_arg);
114 template <
typename PointT,
115 typename LeafContainerT,
116 typename BranchContainerT,
122 assert(cloud_arg == input_);
124 cloud_arg->push_back(point_arg);
126 this->addPointIdx(cloud_arg->size() - 1);
130 template <
typename PointT,
131 typename LeafContainerT,
132 typename BranchContainerT,
140 assert(cloud_arg == input_);
141 assert(indices_arg == indices_);
143 cloud_arg->push_back(point_arg);
145 this->addPointFromCloud(cloud_arg->size() - 1, indices_arg);
149 template <
typename PointT,
150 typename LeafContainerT,
151 typename BranchContainerT,
157 if (!isPointWithinBoundingBox(point_arg)) {
164 this->genOctreeKeyforPoint(point_arg, key);
167 return (this->existLeaf(key));
171 template <
typename PointT,
172 typename LeafContainerT,
173 typename BranchContainerT,
180 const PointT& point = (*this->input_)[point_idx_arg];
183 return (this->isVoxelOccupiedAtPoint(point));
187 template <
typename PointT,
188 typename LeafContainerT,
189 typename BranchContainerT,
194 const double point_y_arg,
195 const double point_z_arg)
const
199 point.x = point_x_arg;
200 point.y = point_y_arg;
201 point.z = point_z_arg;
204 return (this->isVoxelOccupiedAtPoint(point));
208 template <
typename PointT,
209 typename LeafContainerT,
210 typename BranchContainerT,
216 if (!isPointWithinBoundingBox(point_arg)) {
223 this->genOctreeKeyforPoint(point_arg, key);
225 this->removeLeaf(key);
229 template <
typename PointT,
230 typename LeafContainerT,
231 typename BranchContainerT,
238 const PointT& point = (*this->input_)[point_idx_arg];
241 this->deleteVoxelAtPoint(point);
245 template <
typename PointT,
246 typename LeafContainerT,
247 typename BranchContainerT,
254 key.
x = key.
y = key.
z = 0;
256 voxel_center_list_arg.clear();
258 return getOccupiedVoxelCentersRecursive(this->root_node_, key, voxel_center_list_arg);
262 template <
typename PointT,
263 typename LeafContainerT,
264 typename BranchContainerT,
269 const Eigen::Vector3f& end,
273 Eigen::Vector3f direction = end - origin;
274 float norm = direction.norm();
275 direction.normalize();
277 const float step_size =
static_cast<float>(resolution_) * precision;
279 const auto nsteps = std::max<std::size_t>(1, norm / step_size);
283 bool bkeyDefined =
false;
286 for (std::size_t i = 0; i < nsteps; ++i) {
287 Eigen::Vector3f p = origin + (direction * step_size *
static_cast<float>(i));
295 this->genOctreeKeyforPoint(octree_p, key);
298 if ((key == prev_key) && (bkeyDefined))
305 genLeafNodeCenterFromOctreeKey(key, center);
306 voxel_center_list.push_back(center);
314 this->genOctreeKeyforPoint(end_p, end_key);
315 if (!(end_key == prev_key)) {
317 genLeafNodeCenterFromOctreeKey(end_key, center);
318 voxel_center_list.push_back(center);
321 return (static_cast<uindex_t>(voxel_center_list.size()));
325 template <
typename PointT,
326 typename LeafContainerT,
327 typename BranchContainerT,
334 double minX, minY, minZ, maxX, maxY, maxZ;
340 if (this->leaf_count_ != 0) {
341 PCL_ERROR(
"[pcl::octree::OctreePointCloud::defineBoundingBox] Leaf count (%lu) "
349 float minValue = std::numeric_limits<float>::epsilon() * 512.0f;
355 maxX = max_pt.x + minValue;
356 maxY = max_pt.y + minValue;
357 maxZ = max_pt.z + minValue;
360 defineBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
364 template <
typename PointT,
365 typename LeafContainerT,
366 typename BranchContainerT,
371 const double min_y_arg,
372 const double min_z_arg,
373 const double max_x_arg,
374 const double max_y_arg,
375 const double max_z_arg)
378 if (this->leaf_count_ != 0) {
379 PCL_ERROR(
"[pcl::octree::OctreePointCloud::defineBoundingBox] Leaf count (%lu) "
385 min_x_ = std::min(min_x_arg, max_x_arg);
386 min_y_ = std::min(min_y_arg, max_y_arg);
387 min_z_ = std::min(min_z_arg, max_z_arg);
389 max_x_ = std::max(min_x_arg, max_x_arg);
390 max_y_ = std::max(min_y_arg, max_y_arg);
391 max_z_ = std::max(min_z_arg, max_z_arg);
396 bounding_box_defined_ =
true;
400 template <
typename PointT,
401 typename LeafContainerT,
402 typename BranchContainerT,
407 const double max_y_arg,
408 const double max_z_arg)
411 if (this->leaf_count_ != 0) {
412 PCL_ERROR(
"[pcl::octree::OctreePointCloud::defineBoundingBox] Leaf count (%lu) "
418 min_x_ = std::min(0.0, max_x_arg);
419 min_y_ = std::min(0.0, max_y_arg);
420 min_z_ = std::min(0.0, max_z_arg);
422 max_x_ = std::max(0.0, max_x_arg);
423 max_y_ = std::max(0.0, max_y_arg);
424 max_z_ = std::max(0.0, max_z_arg);
429 bounding_box_defined_ =
true;
433 template <
typename PointT,
434 typename LeafContainerT,
435 typename BranchContainerT,
442 if (this->leaf_count_ != 0) {
443 PCL_ERROR(
"[pcl::octree::OctreePointCloud::defineBoundingBox] Leaf count (%lu) "
449 min_x_ = std::min(0.0, cubeLen_arg);
450 min_y_ = std::min(0.0, cubeLen_arg);
451 min_z_ = std::min(0.0, cubeLen_arg);
453 max_x_ = std::max(0.0, cubeLen_arg);
454 max_y_ = std::max(0.0, cubeLen_arg);
455 max_z_ = std::max(0.0, cubeLen_arg);
460 bounding_box_defined_ =
true;
464 template <
typename PointT,
465 typename LeafContainerT,
466 typename BranchContainerT,
475 double& max_z_arg)
const
487 template <
typename PointT,
488 typename LeafContainerT,
489 typename BranchContainerT,
496 constexpr
float minValue = std::numeric_limits<float>::epsilon();
500 bool bLowerBoundViolationX = (point_arg.x < min_x_);
501 bool bLowerBoundViolationY = (point_arg.y < min_y_);
502 bool bLowerBoundViolationZ = (point_arg.z < min_z_);
504 bool bUpperBoundViolationX = (point_arg.x >= max_x_);
505 bool bUpperBoundViolationY = (point_arg.y >= max_y_);
506 bool bUpperBoundViolationZ = (point_arg.z >= max_z_);
509 if (bLowerBoundViolationX || bLowerBoundViolationY || bLowerBoundViolationZ ||
510 bUpperBoundViolationX || bUpperBoundViolationY || bUpperBoundViolationZ ||
511 (!bounding_box_defined_)) {
513 if (bounding_box_defined_) {
515 double octreeSideLen;
516 unsigned char child_idx;
520 child_idx =
static_cast<unsigned char>(((bLowerBoundViolationX) << 2) |
521 ((bLowerBoundViolationY) << 1) |
522 ((bLowerBoundViolationZ)));
527 this->branch_count_++;
529 this->setBranchChildPtr(*newRootBranch, child_idx, this->root_node_);
531 this->root_node_ = newRootBranch;
533 octreeSideLen =
static_cast<double>(1 << this->octree_depth_) * resolution_;
535 if (bLowerBoundViolationX)
536 min_x_ -= octreeSideLen;
538 if (bLowerBoundViolationY)
539 min_y_ -= octreeSideLen;
541 if (bLowerBoundViolationZ)
542 min_z_ -= octreeSideLen;
545 this->octree_depth_++;
546 this->setTreeDepth(this->octree_depth_);
550 static_cast<double>(1 << this->octree_depth_) * resolution_ - minValue;
553 max_x_ = min_x_ + octreeSideLen;
554 max_y_ = min_y_ + octreeSideLen;
555 max_z_ = min_z_ + octreeSideLen;
560 this->min_x_ = point_arg.x - this->resolution_ / 2;
561 this->min_y_ = point_arg.y - this->resolution_ / 2;
562 this->min_z_ = point_arg.z - this->resolution_ / 2;
564 this->max_x_ = point_arg.x + this->resolution_ / 2;
565 this->max_y_ = point_arg.y + this->resolution_ / 2;
566 this->max_z_ = point_arg.z + this->resolution_ / 2;
570 bounding_box_defined_ =
true;
580 template <
typename PointT,
581 typename LeafContainerT,
582 typename BranchContainerT,
588 unsigned char child_idx,
594 std::size_t leaf_obj_count = (*leaf_node)->getSize();
598 leafIndices.reserve(leaf_obj_count);
600 (*leaf_node)->getPointIndices(leafIndices);
603 this->deleteBranchChild(*parent_branch, child_idx);
607 BranchNode* childBranch = this->createBranchChild(*parent_branch, child_idx);
608 this->branch_count_++;
613 for (
const auto& leafIndex : leafIndices) {
615 const PointT& point_from_index = (*input_)[leafIndex];
617 genOctreeKeyforPoint(point_from_index, new_index_key);
621 this->createLeafRecursive(
622 new_index_key, depth_mask, childBranch, newLeaf, newBranchParent);
624 (*newLeaf)->addPointIndex(leafIndex);
630 template <
typename PointT,
631 typename LeafContainerT,
632 typename BranchContainerT,
640 assert(point_idx_arg < input_->size());
642 const PointT& point = (*input_)[point_idx_arg];
645 adoptBoundingBoxToPoint(point);
648 genOctreeKeyforPoint(point, key);
652 auto depth_mask = this->createLeafRecursive(
653 key, this->depth_mask_, this->root_node_, leaf_node, parent_branch_of_leaf_node);
655 if (this->dynamic_depth_enabled_ && depth_mask) {
657 std::size_t leaf_obj_count = (*leaf_node)->getSize();
659 while (leaf_obj_count >= max_objs_per_leaf_ && depth_mask) {
663 expandLeafNode(leaf_node, parent_branch_of_leaf_node, child_idx, depth_mask);
665 depth_mask = this->createLeafRecursive(key,
669 parent_branch_of_leaf_node);
670 leaf_obj_count = (*leaf_node)->getSize();
674 (*leaf_node)->addPointIndex(point_idx_arg);
678 template <
typename PointT,
679 typename LeafContainerT,
680 typename BranchContainerT,
687 assert(index_arg < input_->size());
688 return ((*this->input_)[index_arg]);
692 template <
typename PointT,
693 typename LeafContainerT,
694 typename BranchContainerT,
700 constexpr
float minValue = std::numeric_limits<float>::epsilon();
703 const auto max_key_x =
704 static_cast<uindex_t>(std::ceil((max_x_ - min_x_ - minValue) / resolution_));
705 const auto max_key_y =
706 static_cast<uindex_t>(std::ceil((max_y_ - min_y_ - minValue) / resolution_));
707 const auto max_key_z =
708 static_cast<uindex_t>(std::ceil((max_z_ - min_z_ - minValue) / resolution_));
711 const auto max_voxels =
712 std::max<uindex_t>(std::max(std::max(max_key_x, max_key_y), max_key_z), 2);
715 this->octree_depth_ = std::max<uindex_t>(
717 std::ceil(std::log2(max_voxels) - minValue)),
720 const auto octree_side_len =
721 static_cast<double>(1 << this->octree_depth_) * resolution_;
723 if (this->leaf_count_ == 0) {
724 double octree_oversize_x;
725 double octree_oversize_y;
726 double octree_oversize_z;
728 octree_oversize_x = (octree_side_len - (max_x_ - min_x_)) / 2.0;
729 octree_oversize_y = (octree_side_len - (max_y_ - min_y_)) / 2.0;
730 octree_oversize_z = (octree_side_len - (max_z_ - min_z_)) / 2.0;
732 assert(octree_oversize_x > -minValue);
733 assert(octree_oversize_y > -minValue);
734 assert(octree_oversize_z > -minValue);
736 if (octree_oversize_x > minValue) {
737 min_x_ -= octree_oversize_x;
738 max_x_ += octree_oversize_x;
740 if (octree_oversize_y > minValue) {
741 min_y_ -= octree_oversize_y;
742 max_y_ += octree_oversize_y;
744 if (octree_oversize_z > minValue) {
745 min_z_ -= octree_oversize_z;
746 max_z_ += octree_oversize_z;
750 max_x_ = min_x_ + octree_side_len;
751 max_y_ = min_y_ + octree_side_len;
752 max_z_ = min_z_ + octree_side_len;
756 this->setTreeDepth(this->octree_depth_);
760 template <
typename PointT,
761 typename LeafContainerT,
762 typename BranchContainerT,
769 key_arg.
x =
static_cast<uindex_t>((point_arg.x - this->min_x_) / this->resolution_);
770 key_arg.
y =
static_cast<uindex_t>((point_arg.y - this->min_y_) / this->resolution_);
771 key_arg.
z =
static_cast<uindex_t>((point_arg.z - this->min_z_) / this->resolution_);
773 assert(key_arg.
x <= this->max_key_.x);
774 assert(key_arg.
y <= this->max_key_.y);
775 assert(key_arg.
z <= this->max_key_.z);
779 template <
typename PointT,
780 typename LeafContainerT,
781 typename BranchContainerT,
786 const double point_y_arg,
787 const double point_z_arg,
792 temp_point.x =
static_cast<float>(point_x_arg);
793 temp_point.y =
static_cast<float>(point_y_arg);
794 temp_point.z =
static_cast<float>(point_z_arg);
797 genOctreeKeyforPoint(temp_point, key_arg);
801 template <
typename PointT,
802 typename LeafContainerT,
803 typename BranchContainerT,
809 const PointT temp_point = getPointByIndex(data_arg);
812 genOctreeKeyforPoint(temp_point, key_arg);
818 template <
typename PointT,
819 typename LeafContainerT,
820 typename BranchContainerT,
827 point.x =
static_cast<float>((
static_cast<double>(key.
x) + 0.5f) * this->resolution_ +
829 point.y =
static_cast<float>((
static_cast<double>(key.
y) + 0.5f) * this->resolution_ +
831 point.z =
static_cast<float>((
static_cast<double>(key.
z) + 0.5f) * this->resolution_ +
836 template <
typename PointT,
837 typename LeafContainerT,
838 typename BranchContainerT,
847 point_arg.x =
static_cast<float>(
848 (
static_cast<double>(key_arg.
x) + 0.5f) *
850 static_cast<double>(1 << (this->octree_depth_ - tree_depth_arg))) +
852 point_arg.y =
static_cast<float>(
853 (
static_cast<double>(key_arg.
y) + 0.5f) *
855 static_cast<double>(1 << (this->octree_depth_ - tree_depth_arg))) +
857 point_arg.z =
static_cast<float>(
858 (
static_cast<double>(key_arg.
z) + 0.5f) *
860 static_cast<double>(1 << (this->octree_depth_ - tree_depth_arg))) +
865 template <
typename PointT,
866 typename LeafContainerT,
867 typename BranchContainerT,
873 Eigen::Vector3f& min_pt,
874 Eigen::Vector3f& max_pt)
const
877 double voxel_side_len =
879 static_cast<double>(1 << (this->octree_depth_ - tree_depth_arg));
882 min_pt(0) =
static_cast<float>(
static_cast<double>(key_arg.
x) * voxel_side_len +
884 min_pt(1) =
static_cast<float>(
static_cast<double>(key_arg.
y) * voxel_side_len +
886 min_pt(2) =
static_cast<float>(
static_cast<double>(key_arg.
z) * voxel_side_len +
889 max_pt(0) =
static_cast<float>(
static_cast<double>(key_arg.
x + 1) * voxel_side_len +
891 max_pt(1) =
static_cast<float>(
static_cast<double>(key_arg.
y + 1) * voxel_side_len +
893 max_pt(2) =
static_cast<float>(
static_cast<double>(key_arg.
z + 1) * voxel_side_len +
898 template <
typename PointT,
899 typename LeafContainerT,
900 typename BranchContainerT,
909 side_len = this->resolution_ *
910 static_cast<double>(1 << (this->octree_depth_ - tree_depth_arg));
913 side_len *= side_len;
919 template <
typename PointT,
920 typename LeafContainerT,
921 typename BranchContainerT,
928 return (getVoxelSquaredSideLen(tree_depth_arg) * 3);
932 template <
typename PointT,
933 typename LeafContainerT,
934 typename BranchContainerT,
945 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
946 if (!this->branchHasChild(*node_arg, child_idx))
950 child_node = this->getBranchChildPtr(*node_arg, child_idx);
954 new_key.
x = (key_arg.
x << 1) | (!!(child_idx & (1 << 2)));
955 new_key.
y = (key_arg.
y << 1) | (!!(child_idx & (1 << 1)));
956 new_key.
z = (key_arg.
z << 1) | (!!(child_idx & (1 << 0)));
961 voxel_count += getOccupiedVoxelCentersRecursive(
962 static_cast<const BranchNode*>(child_node), new_key, voxel_center_list_arg);
968 genLeafNodeCenterFromOctreeKey(new_key, new_point);
969 voxel_center_list_arg.push_back(new_point);
978 return (voxel_count);
981 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataTVector(T) \
982 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
984 pcl::octree::OctreeContainerPointIndices, \
985 pcl::octree::OctreeContainerEmpty, \
986 pcl::octree::OctreeBase<pcl::octree::OctreeContainerPointIndices, \
987 pcl::octree::OctreeContainerEmpty>>;
988 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataTVector(T) \
989 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
991 pcl::octree::OctreeContainerPointIndices, \
992 pcl::octree::OctreeContainerEmpty, \
993 pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerPointIndices, \
994 pcl::octree::OctreeContainerEmpty>>;
996 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataT(T) \
997 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
999 pcl::octree::OctreeContainerPointIndex, \
1000 pcl::octree::OctreeContainerEmpty, \
1001 pcl::octree::OctreeBase<pcl::octree::OctreeContainerPointIndex, \
1002 pcl::octree::OctreeContainerEmpty>>;
1003 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataT(T) \
1004 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1006 pcl::octree::OctreeContainerPointIndex, \
1007 pcl::octree::OctreeContainerEmpty, \
1008 pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerPointIndex, \
1009 pcl::octree::OctreeContainerEmpty>>;
1011 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithEmptyLeaf(T) \
1012 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1014 pcl::octree::OctreeContainerEmpty, \
1015 pcl::octree::OctreeContainerEmpty, \
1016 pcl::octree::OctreeBase<pcl::octree::OctreeContainerEmpty, \
1017 pcl::octree::OctreeContainerEmpty>>;
1018 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithEmptyLeaf(T) \
1019 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1021 pcl::octree::OctreeContainerEmpty, \
1022 pcl::octree::OctreeContainerEmpty, \
1023 pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerEmpty, \
1024 pcl::octree::OctreeContainerEmpty>>;
uindex_t getOccupiedVoxelCenters(AlignedPointTVector &voxel_center_list_arg) const
Get a PointT vector of centers of all occupied voxels.
void genOctreeKeyforPoint(const PointT &point_arg, OctreeKey &key_arg) const
Generate octree key for voxel at a given point.
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
void genVoxelCenterFromOctreeKey(const OctreeKey &key_arg, uindex_t tree_depth_arg, PointT &point_arg) const
Generate a point at center of octree voxel at given tree level.
void addPointsFromInputCloud()
Add points from input point cloud to octree.
static const unsigned char maxDepth
typename OctreeT::BranchNode BranchNode
std::vector< PointT, Eigen::aligned_allocator< PointT >> AlignedPointTVector
typename PointCloud::ConstPtr PointCloudConstPtr
void addPointToCloud(const PointT &point_arg, PointCloudPtr cloud_arg)
Add point simultaneously to octree and input point cloud.
virtual node_type_t getNodeType() const =0
Pure virtual method for retrieving the type of octree node (branch or leaf)
void addPointFromCloud(uindex_t point_idx_arg, IndicesPtr indices_arg)
Add point at given index from input point cloud to octree.
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
double getVoxelSquaredDiameter() const
Calculates the squared diameter of a voxel at leaf depth.
OctreePointCloud(const double resolution_arg)
Octree pointcloud constructor.
void adoptBoundingBoxToPoint(const PointT &point_idx_arg)
Grow the bounding box/octree until point fits.
shared_ptr< Indices > IndicesPtr
uindex_t getApproxIntersectedVoxelCentersBySegment(const Eigen::Vector3f &origin, const Eigen::Vector3f &end, AlignedPointTVector &voxel_center_list, float precision=0.2)
Get a PointT vector of centers of voxels intersected by a line segment.
virtual bool genOctreeKeyForDataT(const index_t &data_arg, OctreeKey &key_arg) const
Virtual method for generating octree key for a given point index.
void defineBoundingBox()
Investigate dimensions of pointcloud data set and define corresponding bounding box for octree...
virtual void addPointIdx(uindex_t point_idx_arg)
Add point at index from input pointcloud dataset to octree.
void getBoundingBox(double &min_x_arg, double &min_y_arg, double &min_z_arg, double &max_x_arg, double &max_y_arg, double &max_z_arg) const
Get bounding box for octree.
typename PointCloud::Ptr PointCloudPtr
void getMinMax3D(const pcl::PointCloud< PointT > &cloud, PointT &min_pt, PointT &max_pt)
Get the minimum and maximum values on each of the 3 (x-y-z) dimensions in a given pointcloud...
void genLeafNodeCenterFromOctreeKey(const OctreeKey &key_arg, PointT &point_arg) const
Generate a point at center of leaf node voxel.
unsigned char getChildIdxWithDepthMask(uindex_t depthMask) const
get child node index using depthMask
void getKeyBitSize()
Define octree key setting and octree depth based on defined bounding box.
An exception thrown when init can not be performed should be used in all the PCLBase class inheritant...
IndicesAllocator<> Indices
Type used for indices in PCL.
bool isVoxelOccupiedAtPoint(const PointT &point_arg) const
Check if voxel at given point exist.
void genVoxelBoundsFromOctreeKey(const OctreeKey &key_arg, uindex_t tree_depth_arg, Eigen::Vector3f &min_pt, Eigen::Vector3f &max_pt) const
Generate bounds of an octree voxel using octree key and tree depth arguments.
void expandLeafNode(LeafNode *leaf_node, BranchNode *parent_branch, unsigned char child_idx, uindex_t depth_mask)
Add point at index from input pointcloud dataset to octree.
const PointT & getPointByIndex(uindex_t index_arg) const
Get point at index from input pointcloud dataset.
shared_ptr< const Indices > IndicesConstPtr
typename OctreeT::LeafNode LeafNode
double getVoxelSquaredSideLen() const
Calculates the squared voxel cube side length at leaf level.
A point structure representing Euclidean xyz coordinates, and the RGB color.
void deleteVoxelAtPoint(const PointT &point_arg)
Delete leaf node / voxel at given point.
detail::int_type_t< detail::index_type_size, false > uindex_t
Type used for an unsigned index in PCL.
Abstract octree node class
uindex_t getOccupiedVoxelCentersRecursive(const BranchNode *node_arg, const OctreeKey &key_arg, AlignedPointTVector &voxel_center_list_arg) const
Recursively search the tree for all leaf nodes and return a vector of voxel centers.