00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef PCL_OCTREE_POINTCLOUD_HPP_
00040 #define PCL_OCTREE_POINTCLOUD_HPP_
00041
00042 #include <vector>
00043 #include <assert.h>
00044
00045 #include <pcl/common/common.h>
00046
00047 using namespace std;
00048
00050 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT>
00051 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::OctreePointCloud (const double resolution) :
00052 OctreeT (), input_ (PointCloudConstPtr ()), indices_ (IndicesConstPtr ()),
00053 epsilon_ (0), resolution_ (resolution), min_x_ (0.0f), max_x_ (resolution), min_y_ (0.0f),
00054 max_y_ (resolution), min_z_ (0.0f), max_z_ (resolution), bounding_box_defined_ (false), max_objs_per_leaf_(0)
00055 {
00056 assert (resolution > 0.0f);
00057 }
00058
00060 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT>
00061 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::~OctreePointCloud ()
00062 {
00063 }
00064
00066 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00067 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::addPointsFromInputCloud ()
00068 {
00069 size_t i;
00070
00071 if (indices_)
00072 {
00073 for (std::vector<int>::const_iterator current = indices_->begin (); current != indices_->end (); ++current)
00074 {
00075 assert( (*current>=0) && (*current < static_cast<int> (input_->points.size ())));
00076
00077 if (isFinite (input_->points[*current]))
00078 {
00079
00080 this->addPointIdx (*current);
00081 }
00082 }
00083 }
00084 else
00085 {
00086 for (i = 0; i < input_->points.size (); i++)
00087 {
00088 if (isFinite (input_->points[i]))
00089 {
00090
00091 this->addPointIdx (static_cast<unsigned int> (i));
00092 }
00093 }
00094 }
00095 }
00096
00098 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00099 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::addPointFromCloud (const int point_idx_arg, IndicesPtr indices_arg)
00100 {
00101 this->addPointIdx (point_idx_arg);
00102 if (indices_arg)
00103 indices_arg->push_back (point_idx_arg);
00104 }
00105
00107 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00108 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg)
00109 {
00110 assert (cloud_arg==input_);
00111
00112 cloud_arg->push_back (point_arg);
00113
00114 this->addPointIdx (static_cast<const int> (cloud_arg->points.size ()) - 1);
00115 }
00116
00118 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00119 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg,
00120 IndicesPtr indices_arg)
00121 {
00122 assert (cloud_arg==input_);
00123 assert (indices_arg==indices_);
00124
00125 cloud_arg->push_back (point_arg);
00126
00127 this->addPointFromCloud (static_cast<const int> (cloud_arg->points.size ()) - 1, indices_arg);
00128 }
00129
00131 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> bool
00132 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::isVoxelOccupiedAtPoint (const PointT& point_arg) const
00133 {
00134 OctreeKey key;
00135
00136
00137 this->genOctreeKeyforPoint (point_arg, key);
00138
00139
00140 return (isPointWithinBoundingBox (point_arg) && this->existLeaf (key));
00141 }
00142
00144 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> bool
00145 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::isVoxelOccupiedAtPoint (const int& point_idx_arg) const
00146 {
00147
00148 const PointT& point = this->input_->points[point_idx_arg];
00149
00150
00151 return (this->isVoxelOccupiedAtPoint (point));
00152 }
00153
00155 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> bool
00156 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::isVoxelOccupiedAtPoint (
00157 const double point_x_arg, const double point_y_arg, const double point_z_arg) const
00158 {
00159 OctreeKey key;
00160
00161
00162 this->genOctreeKeyforPoint (point_x_arg, point_y_arg, point_z_arg, key);
00163
00164 return (this->existLeaf (key));
00165 }
00166
00168 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00169 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::deleteVoxelAtPoint (const PointT& point_arg)
00170 {
00171 OctreeKey key;
00172
00173
00174 this->genOctreeKeyforPoint (point_arg, key);
00175
00176 this->removeLeaf (key);
00177 }
00178
00180 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00181 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::deleteVoxelAtPoint (const int& point_idx_arg)
00182 {
00183
00184 const PointT& point = this->input_->points[point_idx_arg];
00185
00186
00187 this->deleteVoxelAtPoint (point);
00188 }
00189
00191 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> int
00192 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getOccupiedVoxelCenters (
00193 AlignedPointTVector &voxel_center_list_arg) const
00194 {
00195 OctreeKey key;
00196 key.x = key.y = key.z = 0;
00197
00198 voxel_center_list_arg.clear ();
00199
00200 return getOccupiedVoxelCentersRecursive (this->root_node_, key, voxel_center_list_arg);
00201
00202 }
00203
00205 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> int
00206 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getApproxIntersectedVoxelCentersBySegment (
00207 const Eigen::Vector3f& origin,
00208 const Eigen::Vector3f& end,
00209 AlignedPointTVector &voxel_center_list,
00210 float precision)
00211 {
00212 Eigen::Vector3f direction = end - origin;
00213 float norm = direction.norm ();
00214 direction.normalize ();
00215
00216 const float step_size = static_cast<const float> (resolution_) * precision;
00217
00218 const int nsteps = std::max (1, static_cast<int> (norm / step_size));
00219
00220 OctreeKey prev_key;
00221
00222 bool bkeyDefined = false;
00223
00224
00225 for (int i = 0; i < nsteps; ++i)
00226 {
00227 Eigen::Vector3f p = origin + (direction * step_size * static_cast<const float> (i));
00228
00229 PointT octree_p;
00230 octree_p.x = p.x ();
00231 octree_p.y = p.y ();
00232 octree_p.z = p.z ();
00233
00234 OctreeKey key;
00235 this->genOctreeKeyforPoint (octree_p, key);
00236
00237
00238 if ((key == prev_key) && (bkeyDefined) )
00239 continue;
00240
00241 prev_key = key;
00242 bkeyDefined = true;
00243
00244 PointT center;
00245 genLeafNodeCenterFromOctreeKey (key, center);
00246 voxel_center_list.push_back (center);
00247 }
00248
00249 OctreeKey end_key;
00250 PointT end_p;
00251 end_p.x = end.x ();
00252 end_p.y = end.y ();
00253 end_p.z = end.z ();
00254 this->genOctreeKeyforPoint (end_p, end_key);
00255 if (!(end_key == prev_key))
00256 {
00257 PointT center;
00258 genLeafNodeCenterFromOctreeKey (end_key, center);
00259 voxel_center_list.push_back (center);
00260 }
00261
00262 return (static_cast<int> (voxel_center_list.size ()));
00263 }
00264
00266 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00267 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::defineBoundingBox ()
00268 {
00269
00270 double minX, minY, minZ, maxX, maxY, maxZ;
00271
00272 PointT min_pt;
00273 PointT max_pt;
00274
00275
00276 assert (this->leaf_count_ == 0);
00277
00278 pcl::getMinMax3D (*input_, min_pt, max_pt);
00279
00280 float minValue = std::numeric_limits<float>::epsilon () * 512.0f;
00281
00282 minX = min_pt.x;
00283 minY = min_pt.y;
00284 minZ = min_pt.z;
00285
00286 maxX = max_pt.x + minValue;
00287 maxY = max_pt.y + minValue;
00288 maxZ = max_pt.z + minValue;
00289
00290
00291 defineBoundingBox (minX, minY, minZ, maxX, maxY, maxZ);
00292 }
00293
00295 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00296 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::defineBoundingBox (const double min_x_arg,
00297 const double min_y_arg,
00298 const double min_z_arg,
00299 const double max_x_arg,
00300 const double max_y_arg,
00301 const double max_z_arg)
00302 {
00303
00304 assert (this->leaf_count_ == 0);
00305
00306 assert (max_x_arg >= min_x_arg);
00307 assert (max_y_arg >= min_y_arg);
00308 assert (max_z_arg >= min_z_arg);
00309
00310 min_x_ = min_x_arg;
00311 max_x_ = max_x_arg;
00312
00313 min_y_ = min_y_arg;
00314 max_y_ = max_y_arg;
00315
00316 min_z_ = min_z_arg;
00317 max_z_ = max_z_arg;
00318
00319 min_x_ = min (min_x_, max_x_);
00320 min_y_ = min (min_y_, max_y_);
00321 min_z_ = min (min_z_, max_z_);
00322
00323 max_x_ = max (min_x_, max_x_);
00324 max_y_ = max (min_y_, max_y_);
00325 max_z_ = max (min_z_, max_z_);
00326
00327
00328 getKeyBitSize ();
00329
00330 bounding_box_defined_ = true;
00331 }
00332
00334 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00335 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::defineBoundingBox (
00336 const double max_x_arg, const double max_y_arg, const double max_z_arg)
00337 {
00338
00339 assert (this->leaf_count_ == 0);
00340
00341 assert (max_x_arg >= 0.0f);
00342 assert (max_y_arg >= 0.0f);
00343 assert (max_z_arg >= 0.0f);
00344
00345 min_x_ = 0.0f;
00346 max_x_ = max_x_arg;
00347
00348 min_y_ = 0.0f;
00349 max_y_ = max_y_arg;
00350
00351 min_z_ = 0.0f;
00352 max_z_ = max_z_arg;
00353
00354 min_x_ = min (min_x_, max_x_);
00355 min_y_ = min (min_y_, max_y_);
00356 min_z_ = min (min_z_, max_z_);
00357
00358 max_x_ = max (min_x_, max_x_);
00359 max_y_ = max (min_y_, max_y_);
00360 max_z_ = max (min_z_, max_z_);
00361
00362
00363 getKeyBitSize ();
00364
00365 bounding_box_defined_ = true;
00366 }
00367
00369 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00370 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::defineBoundingBox (const double cubeLen_arg)
00371 {
00372
00373 assert (this->leaf_count_ == 0);
00374
00375 assert (cubeLen_arg >= 0.0f);
00376
00377 min_x_ = 0.0f;
00378 max_x_ = cubeLen_arg;
00379
00380 min_y_ = 0.0f;
00381 max_y_ = cubeLen_arg;
00382
00383 min_z_ = 0.0f;
00384 max_z_ = cubeLen_arg;
00385
00386 min_x_ = min (min_x_, max_x_);
00387 min_y_ = min (min_y_, max_y_);
00388 min_z_ = min (min_z_, max_z_);
00389
00390 max_x_ = max (min_x_, max_x_);
00391 max_y_ = max (min_y_, max_y_);
00392 max_z_ = max (min_z_, max_z_);
00393
00394
00395 getKeyBitSize ();
00396
00397 bounding_box_defined_ = true;
00398 }
00399
00401 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00402 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getBoundingBox (
00403 double& min_x_arg, double& min_y_arg, double& min_z_arg,
00404 double& max_x_arg, double& max_y_arg, double& max_z_arg) const
00405 {
00406 min_x_arg = min_x_;
00407 min_y_arg = min_y_;
00408 min_z_arg = min_z_;
00409
00410 max_x_arg = max_x_;
00411 max_y_arg = max_y_;
00412 max_z_arg = max_z_;
00413 }
00414
00415
00417 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT>
00418 void
00419 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::adoptBoundingBoxToPoint (const PointT& point_idx_arg)
00420 {
00421
00422 const float minValue = std::numeric_limits<float>::epsilon ();
00423
00424
00425 while (true)
00426 {
00427 bool bLowerBoundViolationX = (point_idx_arg.x < min_x_);
00428 bool bLowerBoundViolationY = (point_idx_arg.y < min_y_);
00429 bool bLowerBoundViolationZ = (point_idx_arg.z < min_z_);
00430
00431 bool bUpperBoundViolationX = (point_idx_arg.x >= max_x_);
00432 bool bUpperBoundViolationY = (point_idx_arg.y >= max_y_);
00433 bool bUpperBoundViolationZ = (point_idx_arg.z >= max_z_);
00434
00435
00436 if (bLowerBoundViolationX || bLowerBoundViolationY || bLowerBoundViolationZ || bUpperBoundViolationX
00437 || bUpperBoundViolationY || bUpperBoundViolationZ || (!bounding_box_defined_) )
00438 {
00439
00440 if (bounding_box_defined_)
00441 {
00442
00443 double octreeSideLen;
00444 unsigned char child_idx;
00445
00446
00447 child_idx = static_cast<unsigned char> (((!bUpperBoundViolationX) << 2) | ((!bUpperBoundViolationY) << 1)
00448 | ((!bUpperBoundViolationZ)));
00449
00450 BranchNode* newRootBranch;
00451
00452 newRootBranch = new BranchNode();
00453 this->branch_count_++;
00454
00455 this->setBranchChildPtr (*newRootBranch, child_idx, this->root_node_);
00456
00457 this->root_node_ = newRootBranch;
00458
00459 octreeSideLen = static_cast<double> (1 << this->octree_depth_) * resolution_;
00460
00461 if (!bUpperBoundViolationX)
00462 min_x_ -= octreeSideLen;
00463
00464 if (!bUpperBoundViolationY)
00465 min_y_ -= octreeSideLen;
00466
00467 if (!bUpperBoundViolationZ)
00468 min_z_ -= octreeSideLen;
00469
00470
00471 this->octree_depth_++;
00472 this->setTreeDepth (this->octree_depth_);
00473
00474
00475 octreeSideLen = static_cast<double> (1 << this->octree_depth_) * resolution_ - minValue;
00476
00477
00478 max_x_ = min_x_ + octreeSideLen;
00479 max_y_ = min_y_ + octreeSideLen;
00480 max_z_ = min_z_ + octreeSideLen;
00481
00482 }
00483
00484 else
00485 {
00486
00487 this->min_x_ = point_idx_arg.x - this->resolution_ / 2;
00488 this->min_y_ = point_idx_arg.y - this->resolution_ / 2;
00489 this->min_z_ = point_idx_arg.z - this->resolution_ / 2;
00490
00491 this->max_x_ = point_idx_arg.x + this->resolution_ / 2;
00492 this->max_y_ = point_idx_arg.y + this->resolution_ / 2;
00493 this->max_z_ = point_idx_arg.z + this->resolution_ / 2;
00494
00495 getKeyBitSize ();
00496
00497 bounding_box_defined_ = true;
00498 }
00499
00500 }
00501 else
00502
00503 break;
00504 }
00505 }
00506
00508 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00509 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::expandLeafNode (LeafNode* leaf_node, BranchNode* parent_branch, unsigned char child_idx, unsigned int depth_mask)
00510 {
00511
00512 if (depth_mask)
00513 {
00514
00515 size_t leaf_obj_count = (*leaf_node)->getSize ();
00516
00517
00518 std::vector<int> leafIndices;
00519 leafIndices.reserve(leaf_obj_count);
00520
00521 (*leaf_node)->getPointIndices(leafIndices);
00522
00523
00524 this->deleteBranchChild(*parent_branch, child_idx);
00525 this->leaf_count_ --;
00526
00527
00528 BranchNode* childBranch = this->createBranchChild (*parent_branch, child_idx);
00529 this->branch_count_ ++;
00530
00531 typename std::vector<int>::iterator it = leafIndices.begin();
00532 typename std::vector<int>::const_iterator it_end = leafIndices.end();
00533
00534
00535 OctreeKey new_index_key;
00536
00537 for (it = leafIndices.begin(); it!=it_end; ++it)
00538 {
00539
00540 const PointT& point_from_index = input_->points[*it];
00541
00542 genOctreeKeyforPoint (point_from_index, new_index_key);
00543
00544 LeafNode* newLeaf;
00545 BranchNode* newBranchParent;
00546 this->createLeafRecursive (new_index_key, depth_mask, childBranch, newLeaf, newBranchParent);
00547
00548 (*newLeaf)->addPointIndex(*it);
00549 }
00550 }
00551
00552
00553 }
00554
00555
00557 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00558 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::addPointIdx (const int point_idx_arg)
00559 {
00560 OctreeKey key;
00561
00562 assert (point_idx_arg < static_cast<int> (input_->points.size ()));
00563
00564 const PointT& point = input_->points[point_idx_arg];
00565
00566
00567 adoptBoundingBoxToPoint (point);
00568
00569
00570 genOctreeKeyforPoint (point, key);
00571
00572 LeafNode* leaf_node;
00573 BranchNode* parent_branch_of_leaf_node;
00574 unsigned int depth_mask = this->createLeafRecursive (key, this->depth_mask_ ,this->root_node_, leaf_node, parent_branch_of_leaf_node);
00575
00576 if (this->dynamic_depth_enabled_ && depth_mask)
00577 {
00578
00579 size_t leaf_obj_count = (*leaf_node)->getSize ();
00580
00581 while (leaf_obj_count>=max_objs_per_leaf_ && depth_mask)
00582 {
00583
00584 unsigned char child_idx = key.getChildIdxWithDepthMask (depth_mask*2);
00585
00586 expandLeafNode (leaf_node,
00587 parent_branch_of_leaf_node,
00588 child_idx,
00589 depth_mask);
00590
00591 depth_mask = this->createLeafRecursive (key, this->depth_mask_ ,this->root_node_, leaf_node, parent_branch_of_leaf_node);
00592 leaf_obj_count = (*leaf_node)->getSize ();
00593 }
00594
00595 }
00596
00597 (*leaf_node)->addPointIndex (point_idx_arg);
00598 }
00599
00601 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> const PointT&
00602 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getPointByIndex (const unsigned int index_arg) const
00603 {
00604
00605 assert (index_arg < static_cast<unsigned int> (input_->points.size ()));
00606 return (this->input_->points[index_arg]);
00607 }
00608
00610 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00611 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getKeyBitSize ()
00612 {
00613 unsigned int max_voxels;
00614
00615 unsigned int max_key_x;
00616 unsigned int max_key_y;
00617 unsigned int max_key_z;
00618
00619 double octree_side_len;
00620
00621 const float minValue = std::numeric_limits<float>::epsilon();
00622
00623
00624 max_key_x = static_cast<unsigned int> ((max_x_ - min_x_) / resolution_);
00625 max_key_y = static_cast<unsigned int> ((max_y_ - min_y_) / resolution_);
00626 max_key_z = static_cast<unsigned int> ((max_z_ - min_z_) / resolution_);
00627
00628
00629 max_voxels = max (max (max (max_key_x, max_key_y), max_key_z), static_cast<unsigned int> (2));
00630
00631
00632
00633 this->octree_depth_ = max ((min (static_cast<unsigned int> (OctreeKey::maxDepth), static_cast<unsigned int> (ceil (this->Log2 (max_voxels)-minValue)))),
00634 static_cast<unsigned int> (0));
00635
00636 octree_side_len = static_cast<double> (1 << this->octree_depth_) * resolution_-minValue;
00637
00638 if (this->leaf_count_ == 0)
00639 {
00640 double octree_oversize_x;
00641 double octree_oversize_y;
00642 double octree_oversize_z;
00643
00644 octree_oversize_x = (octree_side_len - (max_x_ - min_x_)) / 2.0;
00645 octree_oversize_y = (octree_side_len - (max_y_ - min_y_)) / 2.0;
00646 octree_oversize_z = (octree_side_len - (max_z_ - min_z_)) / 2.0;
00647
00648 min_x_ -= octree_oversize_x;
00649 min_y_ -= octree_oversize_y;
00650 min_z_ -= octree_oversize_z;
00651
00652 max_x_ += octree_oversize_x;
00653 max_y_ += octree_oversize_y;
00654 max_z_ += octree_oversize_z;
00655 }
00656 else
00657 {
00658 max_x_ = min_x_ + octree_side_len;
00659 max_y_ = min_y_ + octree_side_len;
00660 max_z_ = min_z_ + octree_side_len;
00661 }
00662
00663
00664 this->setTreeDepth (this->octree_depth_);
00665
00666 }
00667
00669 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00670 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::genOctreeKeyforPoint (const PointT& point_arg,
00671 OctreeKey & key_arg) const
00672 {
00673
00674 key_arg.x = static_cast<unsigned int> ((point_arg.x - this->min_x_) / this->resolution_);
00675 key_arg.y = static_cast<unsigned int> ((point_arg.y - this->min_y_) / this->resolution_);
00676 key_arg.z = static_cast<unsigned int> ((point_arg.z - this->min_z_) / this->resolution_);
00677 }
00678
00680 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00681 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::genOctreeKeyforPoint (
00682 const double point_x_arg, const double point_y_arg,
00683 const double point_z_arg, OctreeKey & key_arg) const
00684 {
00685 PointT temp_point;
00686
00687 temp_point.x = static_cast<float> (point_x_arg);
00688 temp_point.y = static_cast<float> (point_y_arg);
00689 temp_point.z = static_cast<float> (point_z_arg);
00690
00691
00692 genOctreeKeyforPoint (temp_point, key_arg);
00693 }
00694
00696 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> bool
00697 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::genOctreeKeyForDataT (const int& data_arg, OctreeKey & key_arg) const
00698 {
00699 const PointT temp_point = getPointByIndex (data_arg);
00700
00701
00702 genOctreeKeyforPoint (temp_point, key_arg);
00703
00704 return (true);
00705 }
00706
00708 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00709 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::genLeafNodeCenterFromOctreeKey (const OctreeKey & key, PointT & point) const
00710 {
00711
00712 point.x = static_cast<float> ((static_cast<double> (key.x) + 0.5f) * this->resolution_ + this->min_x_);
00713 point.y = static_cast<float> ((static_cast<double> (key.y) + 0.5f) * this->resolution_ + this->min_y_);
00714 point.z = static_cast<float> ((static_cast<double> (key.z) + 0.5f) * this->resolution_ + this->min_z_);
00715 }
00716
00718 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00719 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::genVoxelCenterFromOctreeKey (
00720 const OctreeKey & key_arg,
00721 unsigned int tree_depth_arg,
00722 PointT& point_arg) const
00723 {
00724
00725 point_arg.x = static_cast<float> ((static_cast <double> (key_arg.x) + 0.5f) * (this->resolution_ * static_cast<double> (1 << (this->octree_depth_ - tree_depth_arg))) + this->min_x_);
00726 point_arg.y = static_cast<float> ((static_cast <double> (key_arg.y) + 0.5f) * (this->resolution_ * static_cast<double> (1 << (this->octree_depth_ - tree_depth_arg))) + this->min_y_);
00727 point_arg.z = static_cast<float> ((static_cast <double> (key_arg.z) + 0.5f) * (this->resolution_ * static_cast<double> (1 << (this->octree_depth_ - tree_depth_arg))) + this->min_z_);
00728 }
00729
00731 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
00732 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::genVoxelBoundsFromOctreeKey (
00733 const OctreeKey & key_arg,
00734 unsigned int tree_depth_arg,
00735 Eigen::Vector3f &min_pt,
00736 Eigen::Vector3f &max_pt) const
00737 {
00738
00739 double voxel_side_len = this->resolution_ * static_cast<double> (1 << (this->octree_depth_ - tree_depth_arg));
00740
00741
00742 min_pt (0) = static_cast<float> (static_cast<double> (key_arg.x) * voxel_side_len + this->min_x_);
00743 min_pt (1) = static_cast<float> (static_cast<double> (key_arg.y) * voxel_side_len + this->min_y_);
00744 min_pt (2) = static_cast<float> (static_cast<double> (key_arg.z) * voxel_side_len + this->min_z_);
00745
00746 max_pt (0) = static_cast<float> (static_cast<double> (key_arg.x + 1) * voxel_side_len + this->min_x_);
00747 max_pt (1) = static_cast<float> (static_cast<double> (key_arg.y + 1) * voxel_side_len + this->min_y_);
00748 max_pt (2) = static_cast<float> (static_cast<double> (key_arg.z + 1) * voxel_side_len + this->min_z_);
00749 }
00750
00752 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> double
00753 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getVoxelSquaredSideLen (unsigned int tree_depth_arg) const
00754 {
00755 double side_len;
00756
00757
00758 side_len = this->resolution_ * static_cast<double>(1 << (this->octree_depth_ - tree_depth_arg));
00759
00760
00761 side_len *= side_len;
00762
00763 return (side_len);
00764 }
00765
00767 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> double
00768 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getVoxelSquaredDiameter (unsigned int tree_depth_arg) const
00769 {
00770
00771 return (getVoxelSquaredSideLen (tree_depth_arg) * 3);
00772 }
00773
00775 template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> int
00776 pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::getOccupiedVoxelCentersRecursive (
00777 const BranchNode* node_arg,
00778 const OctreeKey& key_arg,
00779 AlignedPointTVector &voxel_center_list_arg) const
00780 {
00781
00782 unsigned char child_idx;
00783
00784 int voxel_count = 0;
00785
00786
00787 for (child_idx = 0; child_idx < 8; child_idx++)
00788 {
00789 if (!this->branchHasChild (*node_arg, child_idx))
00790 continue;
00791
00792 const OctreeNode * child_node;
00793 child_node = this->getBranchChildPtr (*node_arg, child_idx);
00794
00795
00796 OctreeKey new_key;
00797 new_key.x = (key_arg.x << 1) | (!!(child_idx & (1 << 2)));
00798 new_key.y = (key_arg.y << 1) | (!!(child_idx & (1 << 1)));
00799 new_key.z = (key_arg.z << 1) | (!!(child_idx & (1 << 0)));
00800
00801 switch (child_node->getNodeType ())
00802 {
00803 case BRANCH_NODE:
00804 {
00805
00806 voxel_count += getOccupiedVoxelCentersRecursive (static_cast<const BranchNode*> (child_node), new_key, voxel_center_list_arg);
00807 break;
00808 }
00809 case LEAF_NODE:
00810 {
00811 PointT new_point;
00812
00813 genLeafNodeCenterFromOctreeKey (new_key, new_point);
00814 voxel_center_list_arg.push_back (new_point);
00815
00816 voxel_count++;
00817 break;
00818 }
00819 default:
00820 break;
00821 }
00822 }
00823 return (voxel_count);
00824 }
00825
00826 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeContainerPointIndices, pcl::octree::OctreeContainerEmpty, pcl::octree::OctreeBase<pcl::octree::OctreeContainerPointIndices, pcl::octree::OctreeContainerEmpty > >;
00827 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeContainerPointIndices, pcl::octree::OctreeContainerEmpty, pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerPointIndices, pcl::octree::OctreeContainerEmpty > >;
00828
00829 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeContainerPointIndex, pcl::octree::OctreeContainerEmpty, pcl::octree::OctreeBase<pcl::octree::OctreeContainerPointIndex, pcl::octree::OctreeContainerEmpty > >;
00830 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeContainerPointIndex, pcl::octree::OctreeContainerEmpty, pcl::octree::Octree2BufBase<pcl::octree::OctreeContainerPointIndex, pcl::octree::OctreeContainerEmpty > >;
00831
00832 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty, pcl::octree::OctreeContainerEmpty, pcl::octree::OctreeBase<pcl::octree::OctreeLeafEmpty, pcl::octree::OctreeContainerEmpty > >;
00833 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty, pcl::octree::OctreeContainerEmpty, pcl::octree::Octree2BufBase<pcl::octree::OctreeLeafEmpty, pcl::octree::OctreeContainerEmpty > >;
00834
00835 #endif