39 #ifndef OCTREE_POINTCLOUD_HPP_
40 #define OCTREE_POINTCLOUD_HPP_
48 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
51 epsilon_ (0), resolution_ (resolution), minX_ (0.0f), maxX_ (resolution), minY_ (0.0f),
52 maxY_ (resolution), minZ_ (0.0f), maxZ_ (resolution), boundingBoxDefined_ (false)
54 assert (resolution > 0.0f);
58 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
64 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
69 assert (this->leafCount_==0);
72 for (std::vector<int>::const_iterator current = indices_->begin (); current != indices_->end (); ++current)
74 if (
isFinite (input_->points[*current]))
76 assert( (*current>=0) && (*current < static_cast<int> (input_->points.size ())));
79 this->addPointIdx (*current);
85 for (i = 0; i < input_->points.size (); i++)
90 this->addPointIdx (static_cast<unsigned int> (i));
97 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
100 this->addPointIdx (pointIdx_arg);
102 indices_arg->push_back (pointIdx_arg);
106 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
109 assert (cloud_arg==input_);
111 cloud_arg->push_back (point_arg);
113 this->addPointIdx (static_cast<const int> (cloud_arg->points.size ()) - 1);
117 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
121 assert (cloud_arg==input_);
122 assert (indices_arg==indices_);
124 cloud_arg->push_back (point_arg);
126 this->addPointFromCloud (static_cast<const int> (cloud_arg->points.size ()) - 1, indices_arg);
130 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
bool
136 this->genOctreeKeyforPoint (point_arg, key);
139 return (isPointWithinBoundingBox (point_arg) && this->existLeaf (key));
143 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
bool
147 const PointT& point = this->input_->points[pointIdx_arg];
150 return (this->isVoxelOccupiedAtPoint (point));
154 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
bool
156 const double pointX_arg,
const double pointY_arg,
const double pointZ_arg)
const
161 this->genOctreeKeyforPoint (pointX_arg, pointY_arg, pointZ_arg, key);
163 return (this->existLeaf (key));
167 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
173 this->genOctreeKeyforPoint (point_arg, key);
175 this->removeLeaf (key);
179 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
183 const PointT& point = this->input_->points[pointIdx_arg];
186 this->deleteVoxelAtPoint (point);
190 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
int
195 key.
x = key.
y = key.
z = 0;
197 voxelCenterList_arg.clear ();
199 return getOccupiedVoxelCentersRecursive (this->rootNode_, key, voxelCenterList_arg);
204 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
int
206 const Eigen::Vector3f& origin,
207 const Eigen::Vector3f& end,
211 Eigen::Vector3f direction = end - origin;
212 float norm = direction.norm ();
213 direction.normalize ();
215 const float step_size =
static_cast<const float> (resolution_) * precision;
217 const int nsteps = std::max (1, static_cast<int> (norm / step_size));
221 bool bkeyDefined =
false;
224 for (
int i = 0; i < nsteps; ++i)
226 Eigen::Vector3f p = origin + (direction * step_size *
static_cast<const float> (i));
234 this->genOctreeKeyforPoint (octree_p, key);
237 if ((key == prev_key) && (bkeyDefined) )
244 genLeafNodeCenterFromOctreeKey (key, center);
245 voxel_center_list.push_back (center);
253 this->genOctreeKeyforPoint (end_p, end_key);
254 if (!(end_key == prev_key))
257 genLeafNodeCenterFromOctreeKey (end_key, center);
258 voxel_center_list.push_back (center);
261 return (static_cast<int> (voxel_center_list.size ()));
265 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
269 double minX, minY, minZ, maxX, maxY, maxZ;
275 assert (this->leafCount_ == 0);
279 float minValue = std::numeric_limits<float>::epsilon () * 512.0f;
285 maxX = max_pt.x + minValue;
286 maxY = max_pt.y + minValue;
287 maxZ = max_pt.z + minValue;
290 defineBoundingBox (minX, minY, minZ, maxX, maxY, maxZ);
294 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
296 const double minY_arg,
297 const double minZ_arg,
298 const double maxX_arg,
299 const double maxY_arg,
300 const double maxZ_arg)
303 assert (this->leafCount_ == 0);
305 assert (maxX_arg >= minX_arg);
306 assert (maxY_arg >= minY_arg);
307 assert (maxZ_arg >= minZ_arg);
318 minX_ = min (minX_, maxX_);
319 minY_ = min (minY_, maxY_);
320 minZ_ = min (minZ_, maxZ_);
322 maxX_ = max (minX_, maxX_);
323 maxY_ = max (minY_, maxY_);
324 maxZ_ = max (minZ_, maxZ_);
329 boundingBoxDefined_ =
true;
333 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
335 const double maxX_arg,
const double maxY_arg,
const double maxZ_arg)
338 assert (this->leafCount_ == 0);
340 assert (maxX_arg >= 0.0f);
341 assert (maxY_arg >= 0.0f);
342 assert (maxZ_arg >= 0.0f);
353 minX_ = min (minX_, maxX_);
354 minY_ = min (minY_, maxY_);
355 minZ_ = min (minZ_, maxZ_);
357 maxX_ = max (minX_, maxX_);
358 maxY_ = max (minY_, maxY_);
359 maxZ_ = max (minZ_, maxZ_);
364 boundingBoxDefined_ =
true;
368 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
372 assert (this->leafCount_ == 0);
374 assert (cubeLen_arg >= 0.0f);
385 minX_ = min (minX_, maxX_);
386 minY_ = min (minY_, maxY_);
387 minZ_ = min (minZ_, maxZ_);
389 maxX_ = max (minX_, maxX_);
390 maxY_ = max (minY_, maxY_);
391 maxZ_ = max (minZ_, maxZ_);
396 boundingBoxDefined_ =
true;
400 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
402 double& minX_arg,
double& minY_arg,
double& minZ_arg,
403 double& maxX_arg,
double& maxY_arg,
double& maxZ_arg)
const
415 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
420 const float minValue = std::numeric_limits<float>::epsilon ();
425 bool bLowerBoundViolationX = (pointIdx_arg.x < minX_);
426 bool bLowerBoundViolationY = (pointIdx_arg.y < minY_);
427 bool bLowerBoundViolationZ = (pointIdx_arg.z < minZ_);
429 bool bUpperBoundViolationX = (pointIdx_arg.x >= maxX_);
430 bool bUpperBoundViolationY = (pointIdx_arg.y >= maxY_);
431 bool bUpperBoundViolationZ = (pointIdx_arg.z >= maxZ_);
434 if (bLowerBoundViolationX || bLowerBoundViolationY || bLowerBoundViolationZ || bUpperBoundViolationX
435 || bUpperBoundViolationY || bUpperBoundViolationZ )
438 if (boundingBoxDefined_)
441 double octreeSideLen;
442 unsigned char childIdx;
445 childIdx =
static_cast<unsigned char> (((!bUpperBoundViolationX) << 2) | ((!bUpperBoundViolationY) << 1)
446 | ((!bUpperBoundViolationZ)));
448 BranchNode* newRootBranch;
450 newRootBranch = this->branchNodePool_.popNode();
451 this->branchCount_++;
453 this->setBranchChildPtr (*newRootBranch, childIdx, this->rootNode_);
455 this->rootNode_ = newRootBranch;
457 octreeSideLen =
static_cast<double> (1 << this->octreeDepth_) * resolution_;
459 if (!bUpperBoundViolationX)
460 minX_ -= octreeSideLen;
462 if (!bUpperBoundViolationY)
463 minY_ -= octreeSideLen;
465 if (!bUpperBoundViolationZ)
466 minZ_ -= octreeSideLen;
469 this->octreeDepth_++;
470 this->setTreeDepth (this->octreeDepth_);
473 octreeSideLen =
static_cast<double> (1 << this->octreeDepth_) * resolution_ - minValue;
476 maxX_ = minX_ + octreeSideLen;
477 maxY_ = minY_ + octreeSideLen;
478 maxZ_ = minZ_ + octreeSideLen;
485 this->minX_ = pointIdx_arg.x - this->resolution_ / 2;
486 this->minY_ = pointIdx_arg.y - this->resolution_ / 2;
487 this->minZ_ = pointIdx_arg.z - this->resolution_ / 2;
489 this->maxX_ = pointIdx_arg.x + this->resolution_ / 2;
490 this->maxY_ = pointIdx_arg.y + this->resolution_ / 2;
491 this->maxZ_ = pointIdx_arg.z + this->resolution_ / 2;
495 boundingBoxDefined_ =
true;
506 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
511 assert (pointIdx_arg < static_cast<int> (input_->points.size ()));
513 const PointT& point = input_->points[pointIdx_arg];
516 adoptBoundingBoxToPoint (point);
519 genOctreeKeyforPoint (point, key);
522 this->addData (key, pointIdx_arg);
526 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
const PointT&
530 assert (index_arg < static_cast<unsigned int> (input_->points.size ()));
531 return (this->input_->points[index_arg]);
535 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT> LeafT*
541 this->genOctreeKeyforPoint (point, key);
543 return (this->findLeaf (key));
547 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
550 unsigned int maxVoxels;
552 unsigned int maxKeyX;
553 unsigned int maxKeyY;
554 unsigned int maxKeyZ;
556 double octreeSideLen;
558 const float minValue = std::numeric_limits<float>::epsilon();
561 maxKeyX =
static_cast<unsigned int> ((maxX_ - minX_) / resolution_);
562 maxKeyY =
static_cast<unsigned int> ((maxY_ - minY_) / resolution_);
563 maxKeyZ =
static_cast<unsigned int> ((maxZ_ - minZ_) / resolution_);
566 maxVoxels = max (max (max (maxKeyX, maxKeyY), maxKeyZ), static_cast<unsigned int> (2));
570 this->octreeDepth_ = max ((min (static_cast<unsigned int> (
OCT_MAXTREEDEPTH), static_cast<unsigned int> (ceil (this->
Log2 (maxVoxels)-minValue)))),
571 static_cast<unsigned int> (0));
573 octreeSideLen =
static_cast<double> (1 << this->octreeDepth_) * resolution_-minValue;
575 if (this->leafCount_ == 0)
577 double octreeOversizeX;
578 double octreeOversizeY;
579 double octreeOversizeZ;
581 octreeOversizeX = (octreeSideLen - (maxX_ - minX_)) / 2.0;
582 octreeOversizeY = (octreeSideLen - (maxY_ - minY_)) / 2.0;
583 octreeOversizeZ = (octreeSideLen - (maxZ_ - minZ_)) / 2.0;
585 minX_ -= octreeOversizeX;
586 minY_ -= octreeOversizeY;
587 minZ_ -= octreeOversizeZ;
589 maxX_ += octreeOversizeX;
590 maxY_ += octreeOversizeY;
591 maxZ_ += octreeOversizeZ;
595 maxX_ = minX_ + octreeSideLen;
596 maxY_ = minY_ + octreeSideLen;
597 maxZ_ = minZ_ + octreeSideLen;
601 this->setTreeDepth (this->octreeDepth_);
606 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
608 OctreeKey & key_arg)
const
611 key_arg.x =
static_cast<unsigned int> ((point_arg.x - this->minX_) / this->resolution_);
612 key_arg.y =
static_cast<unsigned int> ((point_arg.y - this->minY_) / this->resolution_);
613 key_arg.z =
static_cast<unsigned int> ((point_arg.z - this->minZ_) / this->resolution_);
617 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
619 const double pointX_arg,
const double pointY_arg,
620 const double pointZ_arg, OctreeKey & key_arg)
const
624 tempPoint.x =
static_cast<float> (pointX_arg);
625 tempPoint.y =
static_cast<float> (pointY_arg);
626 tempPoint.z =
static_cast<float> (pointZ_arg);
629 genOctreeKeyforPoint (tempPoint, key_arg);
633 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
bool
636 const PointT tempPoint = getPointByIndex (data_arg);
639 genOctreeKeyforPoint (tempPoint, key_arg);
645 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
649 point.x =
static_cast<float> ((
static_cast<double> (key.x) + 0.5f) * this->resolution_ + this->minX_);
650 point.y =
static_cast<float> ((
static_cast<double> (key.y) + 0.5f) * this->resolution_ + this->minY_);
651 point.z =
static_cast<float> ((
static_cast<double> (key.z) + 0.5f) * this->resolution_ + this->minZ_);
655 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
657 const OctreeKey & key_arg,
658 unsigned int treeDepth_arg,
662 point_arg.x =
static_cast<float> ((static_cast <
double> (key_arg.x) + 0.5f) * (this->resolution_ *
static_cast<double> (1 << (this->octreeDepth_ - treeDepth_arg))) + this->minX_);
663 point_arg.y =
static_cast<float> ((static_cast <
double> (key_arg.y) + 0.5f) * (this->resolution_ *
static_cast<double> (1 << (this->octreeDepth_ - treeDepth_arg))) + this->minY_);
664 point_arg.z =
static_cast<float> ((static_cast <
double> (key_arg.z) + 0.5f) * (this->resolution_ *
static_cast<double> (1 << (this->octreeDepth_ - treeDepth_arg))) + this->minZ_);
668 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
void
670 const OctreeKey & key_arg,
671 unsigned int treeDepth_arg,
672 Eigen::Vector3f &min_pt,
673 Eigen::Vector3f &max_pt)
const
676 double voxel_side_len = this->resolution_ *
static_cast<double> (1 << (this->octreeDepth_ - treeDepth_arg));
679 min_pt (0) =
static_cast<float> (
static_cast<double> (key_arg.x) * voxel_side_len + this->minX_);
680 min_pt (1) =
static_cast<float> (
static_cast<double> (key_arg.y) * voxel_side_len + this->minY_);
681 min_pt (2) =
static_cast<float> (
static_cast<double> (key_arg.z) * voxel_side_len + this->minZ_);
683 max_pt (0) =
static_cast<float> (
static_cast<double> (key_arg.x + 1) * voxel_side_len + this->minX_);
684 max_pt (1) =
static_cast<float> (
static_cast<double> (key_arg.y + 1) * voxel_side_len + this->minY_);
685 max_pt (2) =
static_cast<float> (
static_cast<double> (key_arg.z + 1) * voxel_side_len + this->minZ_);
689 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
double
695 sideLen = this->resolution_ *
static_cast<double>(1 << (this->octreeDepth_ - treeDepth_arg));
704 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
double
708 return (getVoxelSquaredSideLen (treeDepth_arg) * 3);
712 template<
typename Po
intT,
typename LeafT,
typename BranchT,
typename OctreeT>
int
714 const BranchNode* node_arg,
716 AlignedPointTVector &voxelCenterList_arg)
const
719 unsigned char childIdx;
724 for (childIdx = 0; childIdx < 8; childIdx++)
726 if (!this->branchHasChild (*node_arg, childIdx))
730 childNode = this->getBranchChildPtr (*node_arg, childIdx);
734 newKey.
x = (key_arg.
x << 1) | (!!(childIdx & (1 << 2)));
735 newKey.
y = (key_arg.
y << 1) | (!!(childIdx & (1 << 1)));
736 newKey.
z = (key_arg.
z << 1) | (!!(childIdx & (1 << 0)));
743 voxelCount += getOccupiedVoxelCentersRecursive (static_cast<const BranchNode*> (childNode), newKey, voxelCenterList_arg);
750 genLeafNodeCenterFromOctreeKey (newKey, newPoint);
751 voxelCenterList_arg.push_back (newPoint);
763 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeContainerDataTVector<int> , pcl::octree::OctreeContainerEmpty<int>, pcl::octree::OctreeBase<int, pcl::octree::OctreeContainerDataTVector<int>, pcl::octree::OctreeContainerEmpty<int> > >;
764 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeContainerDataTVector<int> , pcl::octree::OctreeContainerEmpty<int>, pcl::octree::Octree2BufBase<int, pcl::octree::OctreeContainerDataTVector<int>, pcl::octree::OctreeContainerEmpty<int> > >;
766 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataT<int>, pcl::octree::OctreeContainerEmpty<int> , pcl::octree::OctreeBase<int, pcl::octree::OctreeContainerDataT<int>, pcl::octree::OctreeContainerEmpty<int> > >;
767 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataT<int>, pcl::octree::OctreeContainerEmpty<int> , pcl::octree::Octree2BufBase<int, pcl::octree::OctreeContainerDataT<int>, pcl::octree::OctreeContainerEmpty<int> > >;
769 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty<int>, pcl::octree::OctreeContainerEmpty<int> , pcl::octree::OctreeBase<int, pcl::octree::OctreeContainerDataT<int>, pcl::octree::OctreeContainerEmpty<int> > >;
770 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty<int>, pcl::octree::OctreeContainerEmpty<int> , pcl::octree::Octree2BufBase<int, pcl::octree::OctreeContainerDataT<int>, pcl::octree::OctreeContainerEmpty<int> > >;