42#include <pcl/common/point_tests.h>
43#include <pcl/octree/impl/octree_base.hpp>
49template <
typename PointT,
50 typename LeafContainerT,
51 typename BranchContainerT,
69 assert(resolution > 0.0f);
73template <
typename PointT,
74 typename LeafContainerT,
75 typename BranchContainerT,
83 assert((index >= 0) && (
static_cast<std::size_t
>(index) <
input_->size()));
92 for (
index_t i = 0; i < static_cast<index_t>(input_->size()); i++) {
102template <
typename PointT,
103 typename LeafContainerT,
104 typename BranchContainerT,
112 indices_arg->push_back(point_idx_arg);
116template <
typename PointT,
117 typename LeafContainerT,
118 typename BranchContainerT,
124 assert(cloud_arg ==
input_);
126 cloud_arg->push_back(point_arg);
132template <
typename PointT,
133 typename LeafContainerT,
134 typename BranchContainerT,
142 assert(cloud_arg ==
input_);
145 cloud_arg->push_back(point_arg);
151template <
typename PointT,
152 typename LeafContainerT,
153 typename BranchContainerT,
173template <
typename PointT,
174 typename LeafContainerT,
175 typename BranchContainerT,
182 const PointT& point = (*this->
input_)[point_idx_arg];
189template <
typename PointT,
190 typename LeafContainerT,
191 typename BranchContainerT,
196 const double point_y_arg,
197 const double point_z_arg)
const
201 point.x = point_x_arg;
202 point.y = point_y_arg;
203 point.z = point_z_arg;
210template <
typename PointT,
211 typename LeafContainerT,
212 typename BranchContainerT,
231template <
typename PointT,
232 typename LeafContainerT,
233 typename BranchContainerT,
240 const PointT& point = (*this->
input_)[point_idx_arg];
247template <
typename PointT,
248 typename LeafContainerT,
249 typename BranchContainerT,
256 key.
x = key.
y = key.
z = 0;
258 voxel_center_list_arg.clear();
264template <
typename PointT,
265 typename LeafContainerT,
266 typename BranchContainerT,
271 const Eigen::Vector3f&
end,
275 Eigen::Vector3f direction =
end - origin;
276 float norm = direction.norm();
277 direction.normalize();
279 const float step_size =
static_cast<float>(
resolution_) * precision;
281 const auto nsteps = std::max<std::size_t>(1, norm / step_size);
285 bool bkeyDefined =
false;
288 for (std::size_t i = 0; i < nsteps; ++i) {
289 Eigen::Vector3f p = origin + (direction * step_size *
static_cast<float>(i));
300 if ((key == prev_key) && (bkeyDefined))
308 voxel_center_list.push_back(center);
316 this->genOctreeKeyforPoint(end_p, end_key);
317 if (!(end_key == prev_key)) {
319 genLeafNodeCenterFromOctreeKey(end_key, center);
320 voxel_center_list.push_back(center);
323 return (
static_cast<uindex_t>(voxel_center_list.size()));
327template <
typename PointT,
328 typename LeafContainerT,
329 typename BranchContainerT,
336 double minX, minY, minZ, maxX, maxY, maxZ;
346 float minValue = std::numeric_limits<float>::epsilon() * 512.0f;
352 maxX = max_pt.x + minValue;
353 maxY = max_pt.y + minValue;
354 maxZ = max_pt.z + minValue;
361template <
typename PointT,
362 typename LeafContainerT,
363 typename BranchContainerT,
368 const double min_y_arg,
369 const double min_z_arg,
370 const double max_x_arg,
371 const double max_y_arg,
372 const double max_z_arg)
377 assert(max_x_arg >= min_x_arg);
378 assert(max_y_arg >= min_y_arg);
379 assert(max_z_arg >= min_z_arg);
405template <
typename PointT,
406 typename LeafContainerT,
407 typename BranchContainerT,
412 const double max_y_arg,
413 const double max_z_arg)
418 assert(max_x_arg >= 0.0f);
419 assert(max_y_arg >= 0.0f);
420 assert(max_z_arg >= 0.0f);
446template <
typename PointT,
447 typename LeafContainerT,
448 typename BranchContainerT,
457 assert(cubeLen_arg >= 0.0f);
483template <
typename PointT,
484 typename LeafContainerT,
485 typename BranchContainerT,
494 double& max_z_arg)
const
506template <
typename PointT,
507 typename LeafContainerT,
508 typename BranchContainerT,
515 const float minValue = std::numeric_limits<float>::epsilon();
519 bool bLowerBoundViolationX = (point_idx_arg.x <
min_x_);
520 bool bLowerBoundViolationY = (point_idx_arg.y <
min_y_);
521 bool bLowerBoundViolationZ = (point_idx_arg.z <
min_z_);
523 bool bUpperBoundViolationX = (point_idx_arg.x >=
max_x_);
524 bool bUpperBoundViolationY = (point_idx_arg.y >=
max_y_);
525 bool bUpperBoundViolationZ = (point_idx_arg.z >=
max_z_);
528 if (bLowerBoundViolationX || bLowerBoundViolationY || bLowerBoundViolationZ ||
529 bUpperBoundViolationX || bUpperBoundViolationY || bUpperBoundViolationZ ||
534 double octreeSideLen;
535 unsigned char child_idx;
539 child_idx =
static_cast<unsigned char>(((!bUpperBoundViolationX) << 2) |
540 ((!bUpperBoundViolationY) << 1) |
541 ((!bUpperBoundViolationZ)));
554 if (!bUpperBoundViolationX)
557 if (!bUpperBoundViolationY)
560 if (!bUpperBoundViolationZ)
579 this->min_x_ = point_idx_arg.x - this->resolution_ / 2;
580 this->min_y_ = point_idx_arg.y - this->resolution_ / 2;
581 this->min_z_ = point_idx_arg.z - this->resolution_ / 2;
583 this->max_x_ = point_idx_arg.x + this->resolution_ / 2;
584 this->max_y_ = point_idx_arg.y + this->resolution_ / 2;
585 this->max_z_ = point_idx_arg.z + this->resolution_ / 2;
589 bounding_box_defined_ =
true;
599template <
typename PointT,
600 typename LeafContainerT,
601 typename BranchContainerT,
607 unsigned char child_idx,
613 std::size_t leaf_obj_count = (*leaf_node)->getSize();
617 leafIndices.reserve(leaf_obj_count);
619 (*leaf_node)->getPointIndices(leafIndices);
632 for (
const auto& leafIndex : leafIndices) {
634 const PointT& point_from_index = (*input_)[leafIndex];
641 new_index_key, depth_mask, childBranch, newLeaf, newBranchParent);
643 (*newLeaf)->addPointIndex(leafIndex);
649template <
typename PointT,
650 typename LeafContainerT,
651 typename BranchContainerT,
659 assert(point_idx_arg < input_->size());
661 const PointT& point = (*input_)[point_idx_arg];
676 std::size_t leaf_obj_count = (*leaf_node)->getSize();
682 expandLeafNode(leaf_node, parent_branch_of_leaf_node, child_idx, depth_mask);
688 parent_branch_of_leaf_node);
689 leaf_obj_count = (*leaf_node)->getSize();
693 (*leaf_node)->addPointIndex(point_idx_arg);
697template <
typename PointT,
698 typename LeafContainerT,
699 typename BranchContainerT,
706 assert(index_arg < input_->size());
707 return ((*this->
input_)[index_arg]);
711template <
typename PointT,
712 typename LeafContainerT,
713 typename BranchContainerT,
719 const float minValue = std::numeric_limits<float>::epsilon();
722 const auto max_key_x =
724 const auto max_key_y =
726 const auto max_key_z =
730 const auto max_voxels =
731 std::max<uindex_t>(std::max(std::max(max_key_x, max_key_y), max_key_z), 2);
736 std::ceil(std::log2(max_voxels) - minValue)),
739 const auto octree_side_len =
743 double octree_oversize_x;
744 double octree_oversize_y;
745 double octree_oversize_z;
747 octree_oversize_x = (octree_side_len - (
max_x_ -
min_x_)) / 2.0;
748 octree_oversize_y = (octree_side_len - (
max_y_ -
min_y_)) / 2.0;
749 octree_oversize_z = (octree_side_len - (
max_z_ -
min_z_)) / 2.0;
751 assert(octree_oversize_x > -minValue);
752 assert(octree_oversize_y > -minValue);
753 assert(octree_oversize_z > -minValue);
755 if (octree_oversize_x > minValue) {
756 min_x_ -= octree_oversize_x;
757 max_x_ += octree_oversize_x;
759 if (octree_oversize_y > minValue) {
760 min_y_ -= octree_oversize_y;
761 max_y_ += octree_oversize_y;
763 if (octree_oversize_z > minValue) {
764 min_z_ -= octree_oversize_z;
765 max_z_ += octree_oversize_z;
779template <
typename PointT,
780 typename LeafContainerT,
781 typename BranchContainerT,
792 assert(key_arg.
x <= this->max_key_.x);
793 assert(key_arg.
y <= this->max_key_.y);
794 assert(key_arg.
z <= this->max_key_.z);
798template <
typename PointT,
799 typename LeafContainerT,
800 typename BranchContainerT,
805 const double point_y_arg,
806 const double point_z_arg,
811 temp_point.x =
static_cast<float>(point_x_arg);
812 temp_point.y =
static_cast<float>(point_y_arg);
813 temp_point.z =
static_cast<float>(point_z_arg);
820template <
typename PointT,
821 typename LeafContainerT,
822 typename BranchContainerT,
837template <
typename PointT,
838 typename LeafContainerT,
839 typename BranchContainerT,
846 point.x =
static_cast<float>((
static_cast<double>(key.
x) + 0.5f) * this->
resolution_ +
848 point.y =
static_cast<float>((
static_cast<double>(key.
y) + 0.5f) * this->
resolution_ +
850 point.z =
static_cast<float>((
static_cast<double>(key.
z) + 0.5f) * this->
resolution_ +
855template <
typename PointT,
856 typename LeafContainerT,
857 typename BranchContainerT,
863 PointT& point_arg)
const
866 point_arg.x =
static_cast<float>(
867 (
static_cast<double>(key_arg.
x) + 0.5f) *
869 static_cast<double>(1 << (this->
octree_depth_ - tree_depth_arg))) +
871 point_arg.y =
static_cast<float>(
872 (
static_cast<double>(key_arg.
y) + 0.5f) *
874 static_cast<double>(1 << (this->
octree_depth_ - tree_depth_arg))) +
876 point_arg.z =
static_cast<float>(
877 (
static_cast<double>(key_arg.
z) + 0.5f) *
879 static_cast<double>(1 << (this->
octree_depth_ - tree_depth_arg))) +
884template <
typename PointT,
885 typename LeafContainerT,
886 typename BranchContainerT,
892 Eigen::Vector3f& min_pt,
893 Eigen::Vector3f& max_pt)
const
896 double voxel_side_len =
898 static_cast<double>(1 << (this->
octree_depth_ - tree_depth_arg));
901 min_pt(0) =
static_cast<float>(
static_cast<double>(key_arg.
x) * voxel_side_len +
903 min_pt(1) =
static_cast<float>(
static_cast<double>(key_arg.
y) * voxel_side_len +
905 min_pt(2) =
static_cast<float>(
static_cast<double>(key_arg.
z) * voxel_side_len +
908 max_pt(0) =
static_cast<float>(
static_cast<double>(key_arg.
x + 1) * voxel_side_len +
910 max_pt(1) =
static_cast<float>(
static_cast<double>(key_arg.
y + 1) * voxel_side_len +
912 max_pt(2) =
static_cast<float>(
static_cast<double>(key_arg.
z + 1) * voxel_side_len +
917template <
typename PointT,
918 typename LeafContainerT,
919 typename BranchContainerT,
929 static_cast<double>(1 << (this->
octree_depth_ - tree_depth_arg));
932 side_len *= side_len;
938template <
typename PointT,
939 typename LeafContainerT,
940 typename BranchContainerT,
951template <
typename PointT,
952 typename LeafContainerT,
953 typename BranchContainerT,
964 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
973 new_key.
x = (key_arg.
x << 1) | (!!(child_idx & (1 << 2)));
974 new_key.
y = (key_arg.
y << 1) | (!!(child_idx & (1 << 1)));
975 new_key.
z = (key_arg.
z << 1) | (!!(child_idx & (1 << 0)));
981 static_cast<const BranchNode*
>(child_node), new_key, voxel_center_list_arg);
988 voxel_center_list_arg.push_back(new_point);
997 return (voxel_count);
1000#define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataTVector(T) \
1001 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1003 pcl::octree::OctreeContainerPointIndices, \
1004 pcl::octree::OctreeContainerEmpty, \
1005 pcl::octree::OctreeBase<pcl::octree::OctreeContainerPointIndices, \
1006 pcl::octree::OctreeContainerEmpty>>;
1007#define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataTVector(T) \
1008 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1010 pcl::octree::OctreeContainerPointIndices, \
1011 pcl::octree::OctreeContainerEmpty, \
1012 pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerPointIndices, \
1013 pcl::octree::OctreeContainerEmpty>>;
1015#define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataT(T) \
1016 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1018 pcl::octree::OctreeContainerPointIndex, \
1019 pcl::octree::OctreeContainerEmpty, \
1020 pcl::octree::OctreeBase<pcl::octree::OctreeContainerPointIndex, \
1021 pcl::octree::OctreeContainerEmpty>>;
1022#define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataT(T) \
1023 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1025 pcl::octree::OctreeContainerPointIndex, \
1026 pcl::octree::OctreeContainerEmpty, \
1027 pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerPointIndex, \
1028 pcl::octree::OctreeContainerEmpty>>;
1030#define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithEmptyLeaf(T) \
1031 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1033 pcl::octree::OctreeContainerEmpty, \
1034 pcl::octree::OctreeContainerEmpty, \
1035 pcl::octree::OctreeBase<pcl::octree::OctreeContainerEmpty, \
1036 pcl::octree::OctreeContainerEmpty>>;
1037#define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithEmptyLeaf(T) \
1038 template class PCL_EXPORTS pcl::octree::OctreePointCloud< \
1040 pcl::octree::OctreeContainerEmpty, \
1041 pcl::octree::OctreeContainerEmpty, \
1042 pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerEmpty, \
1043 pcl::octree::OctreeContainerEmpty>>;
void setTreeDepth(uindex_t depth_arg)
Octree2BufBase< OctreeContainerPointIndices, OctreeContainerEmpty > OctreeT
void setBranchChildPtr(BranchNode &branch_arg, unsigned char child_idx_arg, OctreeNode *new_child_arg)
std::size_t branch_count_
void setTreeDepth(uindex_t max_depth_arg)
Set the maximum depth of the octree.
std::size_t leaf_count_
Amount of leaf nodes.
BranchNode * root_node_
Pointer to root branch node of octree.
uindex_t depth_mask_
Depth mask based on octree depth.
bool branchHasChild(const BranchNode &branch_arg, unsigned char child_idx_arg) const
Check if branch is pointing to a particular child node.
std::size_t branch_count_
Amount of branch nodes.
bool dynamic_depth_enabled_
Enable dynamic_depth.
uindex_t createLeafRecursive(const OctreeKey &key_arg, uindex_t depth_mask_arg, BranchNode *branch_arg, LeafNode *&return_leaf_arg, BranchNode *&parent_of_leaf_arg)
Create a leaf node at octree key.
BranchNode * createBranchChild(BranchNode &branch_arg, unsigned char child_idx_arg)
Create and add a new branch child to a branch class.
OctreeBase< LeafContainerT, BranchContainerT > OctreeT
uindex_t octree_depth_
Octree depth.
bool existLeaf(uindex_t idx_x_arg, uindex_t idx_y_arg, uindex_t idx_z_arg) const
idx_x_arg for the existence of leaf node at (idx_x_arg, idx_y_arg, idx_z_arg).
void removeLeaf(uindex_t idx_x_arg, uindex_t idx_y_arg, uindex_t idx_z_arg)
Remove leaf node at (idx_x_arg, idx_y_arg, idx_z_arg).
OctreeNode * getBranchChildPtr(const BranchNode &branch_arg, unsigned char child_idx_arg) const
Retrieve a child node pointer for child node at child_idx.
void deleteBranchChild(BranchNode &branch_arg, unsigned char child_idx_arg)
Delete child node and all its subchilds from octree.
static const unsigned char maxDepth
unsigned char getChildIdxWithDepthMask(uindex_t depthMask) const
get child node index using depthMask
Abstract octree node class
virtual node_type_t getNodeType() const =0
Pure virtual method for receiving the type of octree node (branch or leaf).
double getVoxelSquaredDiameter() const
Calculates the squared diameter of a voxel at leaf depth.
std::vector< PointT, Eigen::aligned_allocator< PointT > > AlignedPointTVector
bool isPointWithinBoundingBox(const PointT &point_idx_arg) const
Checks if given point is within the bounding box of the 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.
const PointT & getPointByIndex(uindex_t index_arg) const
Get point at index from input pointcloud dataset.
void addPointToCloud(const PointT &point_arg, PointCloudPtr cloud_arg)
Add point simultaneously to octree and input point cloud.
virtual bool genOctreeKeyForDataT(const index_t &data_arg, OctreeKey &key_arg) const
Virtual method for generating octree key for a given point index.
std::size_t max_objs_per_leaf_
Amount of DataT objects per leafNode before expanding branch.
void addPointsFromInputCloud()
Add points from input point cloud to octree.
PointCloudConstPtr input_
Pointer to input point cloud dataset.
void genLeafNodeCenterFromOctreeKey(const OctreeKey &key_arg, PointT &point_arg) const
void genOctreeKeyforPoint(const PointT &point_arg, OctreeKey &key_arg) const
Generate octree key for voxel at a given point.
typename PointCloud::Ptr PointCloudPtr
IndicesConstPtr indices_
A pointer to the vector of point indices to use.
shared_ptr< Indices > IndicesPtr
typename PointCloud::ConstPtr PointCloudConstPtr
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.
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.
OctreePointCloud(const double resolution_arg)
Octree pointcloud constructor.
double getVoxelSquaredSideLen(uindex_t tree_depth_arg) const
Calculates the squared voxel cube side length at given tree depth.
void adoptBoundingBoxToPoint(const PointT &point_idx_arg)
Grow the bounding box/octree until point fits.
bool bounding_box_defined_
Flag indicating if octree has defined bounding box.
uindex_t getOccupiedVoxelCenters(AlignedPointTVector &voxel_center_list_arg) const
Get a PointT vector of centers of all occupied voxels.
void addPointFromCloud(uindex_t point_idx_arg, IndicesPtr indices_arg)
Add point at given index from input point cloud to octree.
typename OctreeT::LeafNode LeafNode
double getVoxelSquaredSideLen() const
Calculates the squared voxel cube side length at leaf level.
void defineBoundingBox()
Investigate dimensions of pointcloud data set and define corresponding bounding box for octree.
double epsilon_
Epsilon precision (error bound) for nearest neighbors searches.
bool isVoxelOccupiedAtPoint(const PointT &point_arg) const
Check if voxel at given point exist.
void deleteVoxelAtPoint(const PointT &point_arg)
Delete leaf node / voxel at given point.
typename Octree2BufBase< OctreeContainerPointIndices, OctreeContainerEmpty >::BranchNode BranchNode
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.
shared_ptr< const Indices > IndicesConstPtr
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.
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.
double resolution_
Octree resolution.
virtual void addPointIdx(uindex_t point_idx_arg)
Define standard C methods and C++ classes that are common to all methods.
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.
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...
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
IndicesAllocator<> Indices
Type used for indices in PCL.
detail::int_type_t< detail::index_type_size, false > uindex_t
Type used for an unsigned index in PCL.
Defines basic non-point types used by PCL.