|
Point Cloud Library (PCL)
1.4.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id: octree_pointcloud.hpp 3749 2011-12-31 22:58:01Z rusu $ 00037 */ 00038 00039 #ifndef OCTREE_POINTCLOUD_HPP_ 00040 #define OCTREE_POINTCLOUD_HPP_ 00041 00042 #include <vector> 00043 #include <assert.h> 00044 00045 #include "pcl/common/common.h" 00046 00048 template<typename PointT, typename LeafT, typename OctreeT> 00049 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::OctreePointCloud (const double resolution) : 00050 OctreeT (), epsilon_ (0), resolution_ (resolution), minX_ (0.0f), maxX_ (resolution), minY_ (0.0f), 00051 maxY_ (resolution), minZ_ (0.0f), maxZ_ (resolution), maxKeys_ (1), boundingBoxDefined_ (false) 00052 { 00053 assert ( resolution > 0.0f ); 00054 input_ = PointCloudConstPtr (); 00055 } 00056 00058 template<typename PointT, typename LeafT, typename OctreeT> 00059 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::~OctreePointCloud () 00060 { 00061 } 00062 00064 template<typename PointT, typename LeafT, typename OctreeT> void 00065 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::addPointsFromInputCloud () 00066 { 00067 size_t i; 00068 00069 assert (this->leafCount_==0); 00070 if (indices_) 00071 { 00072 std::vector<int>::const_iterator current = indices_->begin (); 00073 while (current != indices_->end ()) 00074 { 00075 if ((input_->points[*current].x == input_->points[*current].x) && (input_->points[*current].y 00076 == input_->points[*current].y) && (input_->points[*current].z == input_->points[*current].z)) 00077 { 00078 // add points to octree 00079 this->addPointIdx (*current); 00080 ++current; 00081 } 00082 } 00083 } 00084 else 00085 { 00086 for (i = 0; i < input_->points.size (); i++) 00087 { 00088 if ((input_->points[i].x == input_->points[i].x) && (input_->points[i].y == input_->points[i].y) 00089 && (input_->points[i].z == input_->points[i].z)) 00090 { 00091 // add points to octree 00092 this->addPointIdx ((unsigned int)i); 00093 } 00094 } 00095 } 00096 } 00097 00099 template<typename PointT, typename LeafT, typename OctreeT> void 00100 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::addPointFromCloud (const int pointIdx_arg, IndicesPtr indices_arg) 00101 { 00102 this->addPointIdx (pointIdx_arg); 00103 if (indices_arg) 00104 indices_arg->push_back (pointIdx_arg); 00105 } 00106 00108 template<typename PointT, typename LeafT, typename OctreeT> void 00109 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg) 00110 { 00111 assert (cloud_arg==input_); 00112 00113 cloud_arg->points.push_back (point_arg); 00114 00115 this->addPointIdx (cloud_arg->points.size () - 1); 00116 } 00117 00119 template<typename PointT, typename LeafT, typename OctreeT> void 00120 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg, 00121 IndicesPtr indices_arg) 00122 { 00123 assert (cloud_arg==input_); 00124 assert (indices_arg==indices_); 00125 00126 cloud_arg->points.push_back (point_arg); 00127 00128 this->addPointFromCloud (cloud_arg->points.size () - 1, indices_arg); 00129 } 00130 00132 template<typename PointT, typename LeafT, typename OctreeT> bool 00133 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::isVoxelOccupiedAtPoint (const PointT& point_arg) const 00134 { 00135 OctreeKey key; 00136 00137 // generate key for point 00138 this->genOctreeKeyforPoint (point_arg, key); 00139 00140 // search for key in octree 00141 return (this->existLeaf (key)); 00142 } 00143 00145 template<typename PointT, typename LeafT, typename OctreeT> bool 00146 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::isVoxelOccupiedAtPoint (const int& pointIdx_arg) const 00147 { 00148 // retrieve point from input cloud 00149 const PointT& point = this->input_->points[pointIdx_arg]; 00150 00151 // search for voxel at point in octree 00152 return (this->isVoxelOccupiedAtPoint (point)); 00153 } 00154 00156 template<typename PointT, typename LeafT, typename OctreeT> bool 00157 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::isVoxelOccupiedAtPoint ( 00158 const double pointX_arg, const double pointY_arg, const double pointZ_arg) const 00159 { 00160 OctreeKey key; 00161 00162 // generate key for point 00163 this->genOctreeKeyforPoint (pointX_arg, pointY_arg, pointZ_arg, key); 00164 00165 return (this->existLeaf (key)); 00166 } 00167 00169 template<typename PointT, typename LeafT, typename OctreeT> void 00170 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::deleteVoxelAtPoint (const PointT& point_arg) 00171 { 00172 OctreeKey key; 00173 00174 // generate key for point 00175 this->genOctreeKeyforPoint (point_arg, key); 00176 00177 this->removeLeaf (key); 00178 } 00179 00181 template<typename PointT, typename LeafT, typename OctreeT> void 00182 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::deleteVoxelAtPoint (const int& pointIdx_arg) 00183 { 00184 // retrieve point from input cloud 00185 const PointT& point = this->input_->points[pointIdx_arg]; 00186 00187 // delete leaf at point 00188 this->deleteVoxelAtPoint (point); 00189 } 00190 00192 template<typename PointT, typename LeafT, typename OctreeT> int 00193 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getOccupiedVoxelCenters ( 00194 std::vector<PointT, Eigen::aligned_allocator<PointT> > &voxelCenterList_arg) const 00195 { 00196 OctreeKey key; 00197 key.x = key.y = key.z = 0; 00198 00199 voxelCenterList_arg.clear (); 00200 00201 return getOccupiedVoxelCentersRecursive (this->rootNode_, key, voxelCenterList_arg); 00202 00203 } 00204 00206 template<typename PointT, typename LeafT, typename OctreeT> int 00207 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getApproxIntersectedVoxelCentersBySegment ( 00208 const Eigen::Vector3f& origin, 00209 const Eigen::Vector3f& end, 00210 AlignedPointTVector &voxel_center_list, 00211 float precision) 00212 { 00213 Eigen::Vector3f direction = end - origin; 00214 float norm = direction.norm (); 00215 direction.normalize (); 00216 00217 const float step_size = resolution_ * precision; 00218 // Ensure we get at least one step for the first voxel. 00219 const int nsteps = std::max (1, (int) (norm / step_size)); 00220 00221 OctreeKey prev_key; 00222 prev_key.x = prev_key.y = prev_key.z = -1; 00223 00224 // Walk along the line segment with small steps. 00225 for (int i = 0; i < nsteps; ++i) 00226 { 00227 Eigen::Vector3f p = origin + (direction * step_size * 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 // Not a new key, still the same voxel. 00238 if (key == prev_key) 00239 continue; 00240 00241 prev_key = key; 00242 00243 PointT center; 00244 genLeafNodeCenterFromOctreeKey (key, center); 00245 voxel_center_list.push_back (center); 00246 } 00247 00248 OctreeKey end_key; 00249 PointT end_p; 00250 end_p.x = end.x (); 00251 end_p.y = end.y (); 00252 end_p.z = end.z (); 00253 this->genOctreeKeyforPoint (end_p, end_key); 00254 if (!(end_key == prev_key)) 00255 { 00256 PointT center; 00257 genLeafNodeCenterFromOctreeKey (end_key, center); 00258 voxel_center_list.push_back (center); 00259 } 00260 00261 return (voxel_center_list.size ()); 00262 } 00263 00265 template<typename PointT, typename LeafT, typename OctreeT> void 00266 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::defineBoundingBox () 00267 { 00268 00269 double minX, minY, minZ, maxX, maxY, maxZ; 00270 00271 PointT min_pt; 00272 PointT max_pt; 00273 00274 // bounding box cannot be changed once the octree contains elements 00275 assert (this->leafCount_ == 0); 00276 00277 pcl::getMinMax3D (*input_, min_pt, max_pt); 00278 00279 minX = min_pt.x; 00280 minY = min_pt.y; 00281 minZ = min_pt.z; 00282 00283 maxX = max_pt.x; 00284 maxY = max_pt.y; 00285 maxZ = max_pt.z; 00286 00287 minX -= this->resolution_ * 0.5f; 00288 minY -= this->resolution_ * 0.5f; 00289 minZ -= this->resolution_ * 0.5f; 00290 00291 maxX += this->resolution_ * 0.5f; 00292 maxY += this->resolution_ * 0.5f; 00293 maxZ += this->resolution_ * 0.5f; 00294 00295 // generate bit masks for octree 00296 defineBoundingBox (minX, minY, minZ, maxX, maxY, maxZ); 00297 } 00298 00300 template<typename PointT, typename LeafT, typename OctreeT> void 00301 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::defineBoundingBox ( 00302 const double minX_arg, const double minY_arg, 00303 const double minZ_arg, const double maxX_arg, 00304 const double maxY_arg, const double maxZ_arg) 00305 { 00306 // bounding box cannot be changed once the octree contains elements 00307 assert (this->leafCount_ == 0); 00308 00309 assert (maxX_arg >= minX_arg); 00310 assert (maxY_arg >= minY_arg); 00311 assert (maxZ_arg >= minZ_arg); 00312 00313 minX_ = minX_arg; 00314 maxX_ = maxX_arg; 00315 00316 minY_ = minY_arg; 00317 maxY_ = maxY_arg; 00318 00319 minZ_ = minZ_arg; 00320 maxZ_ = maxZ_arg; 00321 00322 minX_ = min (minX_, maxX_); 00323 minY_ = min (minY_, maxY_); 00324 minZ_ = min (minZ_, maxZ_); 00325 00326 maxX_ = max (minX_, maxX_); 00327 maxY_ = max (minY_, maxY_); 00328 maxZ_ = max (minZ_, maxZ_); 00329 00330 // generate bit masks for octree 00331 getKeyBitSize (); 00332 00333 boundingBoxDefined_ = true; 00334 } 00335 00337 template<typename PointT, typename LeafT, typename OctreeT> void 00338 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::defineBoundingBox ( 00339 const double maxX_arg, const double maxY_arg, const double maxZ_arg) 00340 { 00341 // bounding box cannot be changed once the octree contains elements 00342 assert (this->leafCount_ == 0); 00343 00344 assert (maxX_arg >= 0.0f); 00345 assert (maxY_arg >= 0.0f); 00346 assert (maxZ_arg >= 0.0f); 00347 00348 minX_ = 0.0f; 00349 maxX_ = maxX_arg; 00350 00351 minY_ = 0.0f; 00352 maxY_ = maxY_arg; 00353 00354 minZ_ = 0.0f; 00355 maxZ_ = maxZ_arg; 00356 00357 minX_ = min (minX_, maxX_); 00358 minY_ = min (minY_, maxY_); 00359 minZ_ = min (minZ_, maxZ_); 00360 00361 maxX_ = max (minX_, maxX_); 00362 maxY_ = max (minY_, maxY_); 00363 maxZ_ = max (minZ_, maxZ_); 00364 00365 // generate bit masks for octree 00366 getKeyBitSize (); 00367 00368 boundingBoxDefined_ = true; 00369 } 00370 00372 template<typename PointT, typename LeafT, typename OctreeT> void 00373 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::defineBoundingBox (const double cubeLen_arg) 00374 { 00375 // bounding box cannot be changed once the octree contains elements 00376 assert (this->leafCount_ == 0); 00377 00378 assert (cubeLen_arg >= 0.0f); 00379 00380 minX_ = 0.0f; 00381 maxX_ = cubeLen_arg; 00382 00383 minY_ = 0.0f; 00384 maxY_ = cubeLen_arg; 00385 00386 minZ_ = 0.0f; 00387 maxZ_ = cubeLen_arg; 00388 00389 minX_ = min (minX_, maxX_); 00390 minY_ = min (minY_, maxY_); 00391 minZ_ = min (minZ_, maxZ_); 00392 00393 maxX_ = max (minX_, maxX_); 00394 maxY_ = max (minY_, maxY_); 00395 maxZ_ = max (minZ_, maxZ_); 00396 00397 // generate bit masks for octree 00398 getKeyBitSize (); 00399 00400 boundingBoxDefined_ = true; 00401 } 00402 00404 template<typename PointT, typename LeafT, typename OctreeT> void 00405 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getBoundingBox ( 00406 double& minX_arg, double& minY_arg, double& minZ_arg, 00407 double& maxX_arg, double& maxY_arg, double& maxZ_arg) const 00408 { 00409 minX_arg = minX_; 00410 minY_arg = minY_; 00411 minZ_arg = minZ_; 00412 00413 maxX_arg = maxX_; 00414 maxY_arg = maxY_; 00415 maxZ_arg = maxZ_; 00416 } 00417 00419 template<typename PointT, typename LeafT, typename OctreeT> void 00420 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::adoptBoundingBoxToPoint (const PointT& pointIdx_arg) 00421 { 00422 const double minValue = 1e-10; 00423 00424 // increase octree size until point fits into bounding box 00425 while (true) 00426 { 00427 bool bLowerBoundViolationX = (pointIdx_arg.x < minX_); 00428 bool bLowerBoundViolationY = (pointIdx_arg.y < minY_); 00429 bool bLowerBoundViolationZ = (pointIdx_arg.z < minZ_); 00430 00431 bool bUpperBoundViolationX = (pointIdx_arg.x >= maxX_); 00432 bool bUpperBoundViolationY = (pointIdx_arg.y >= maxY_); 00433 bool bUpperBoundViolationZ = (pointIdx_arg.z >= maxZ_); 00434 00435 // do we violate any bounds? 00436 if (bLowerBoundViolationX || bLowerBoundViolationY || bLowerBoundViolationZ || bUpperBoundViolationX 00437 || bUpperBoundViolationY || bUpperBoundViolationZ || (!boundingBoxDefined_)) 00438 { 00439 00440 double octreeSideLen; 00441 unsigned char childIdx; 00442 00443 if (this->leafCount_ > 0) 00444 { 00445 // octree not empty - we add another tree level and thus increase its size by a factor of 2*2*2 00446 childIdx = ((!bUpperBoundViolationX) << 2) | ((!bUpperBoundViolationY) << 1) | ((!bUpperBoundViolationZ)); 00447 00448 OctreeBranch* newRootBranch; 00449 00450 this->createBranch (newRootBranch); 00451 this->branchCount_++; 00452 00453 this->setBranchChild (*newRootBranch, childIdx, this->rootNode_); 00454 00455 this->rootNode_ = newRootBranch; 00456 00457 octreeSideLen = maxX_ - minX_ - minValue; 00458 00459 if (bUpperBoundViolationX) 00460 maxX_ += octreeSideLen; 00461 else 00462 minX_ -= octreeSideLen; 00463 00464 if (bUpperBoundViolationY) 00465 maxY_ += octreeSideLen; 00466 else 00467 minY_ -= octreeSideLen; 00468 00469 if (bUpperBoundViolationZ) 00470 maxZ_ += octreeSideLen; 00471 else 00472 minZ_ -= octreeSideLen; 00473 } 00474 else 00475 { 00476 // octree is empty - we set the center of the bounding box to our first pixel 00477 this->minX_ = pointIdx_arg.x - this->resolution_ / 2 + minValue; 00478 this->minY_ = pointIdx_arg.y - this->resolution_ / 2 + minValue; 00479 this->minZ_ = pointIdx_arg.z - this->resolution_ / 2 + minValue; 00480 00481 this->maxX_ = pointIdx_arg.x + this->resolution_ / 2 - minValue; 00482 this->maxY_ = pointIdx_arg.y + this->resolution_ / 2 - minValue; 00483 this->maxZ_ = pointIdx_arg.z + this->resolution_ / 2 - minValue; 00484 } 00485 00486 getKeyBitSize (); 00487 boundingBoxDefined_ = true; 00488 } 00489 else 00490 // no bound violations anymore - leave while loop 00491 break; 00492 } 00493 } 00494 00496 template<typename PointT, typename LeafT, typename OctreeT> void 00497 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::addPointIdx (const int pointIdx_arg) 00498 { 00499 OctreeKey key; 00500 00501 assert (pointIdx_arg < (int) input_->points.size()); 00502 00503 const PointT& point = input_->points[pointIdx_arg]; 00504 00505 // make sure bounding box is big enough 00506 adoptBoundingBoxToPoint (point); 00507 00508 // generate key 00509 genOctreeKeyforPoint (point, key); 00510 00511 // add point to octree at key 00512 this->add (key, pointIdx_arg); 00513 } 00514 00516 template<typename PointT, typename LeafT, typename OctreeT> const PointT& 00517 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getPointByIndex (const unsigned int index_arg) const 00518 { 00519 // retrieve point from input cloud 00520 if (indices_ == 0) 00521 { 00522 assert (index_arg < (unsigned int)input_->points.size ()); 00523 return (this->input_->points[index_arg]); 00524 } 00525 else 00526 { 00527 assert (index_arg < (unsigned int)indices_->size ()); 00528 return (input_->points[(*indices_)[index_arg]]); 00529 } 00530 } 00531 00533 template<typename PointT, typename LeafT, typename OctreeT> LeafT* 00534 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::findLeafAtPoint (const PointT& point) const 00535 { 00536 OctreeKey key; 00537 00538 // generate key for point 00539 this->genOctreeKeyforPoint (point, key); 00540 00541 return (this->findLeaf (key)); 00542 } 00543 00545 template<typename PointT, typename LeafT, typename OctreeT> void 00546 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getKeyBitSize () 00547 { 00548 unsigned int maxVoxels; 00549 00550 unsigned int maxKeyX; 00551 unsigned int maxKeyY; 00552 unsigned int maxKeyZ; 00553 00554 double octreeSideLen; 00555 00556 const double minValue = 1e-10; 00557 00558 // find maximum key values for x, y, z 00559 maxKeyX = ceil ((maxX_ - minX_) / resolution_); 00560 maxKeyY = ceil ((maxY_ - minY_) / resolution_); 00561 maxKeyZ = ceil ((maxZ_ - minZ_) / resolution_); 00562 00563 // find maximum amount of keys 00564 maxVoxels = max (max (max (maxKeyX, maxKeyY), maxKeyZ), (unsigned int)2); 00565 00566 // tree depth == amount of bits of maxVoxels 00567 this->octreeDepth_ = max ((min ((unsigned int)OCT_MAXTREEDEPTH, (unsigned int)ceil (this->Log2 (maxVoxels)))), 00568 (unsigned int)0); 00569 00570 maxKeys_ = (1 << this->octreeDepth_); 00571 00572 octreeSideLen = (double)maxKeys_ * resolution_ - minValue; 00573 00574 if (this->leafCount_ == 0) 00575 { 00576 double octreeOversizeX; 00577 double octreeOversizeY; 00578 double octreeOversizeZ; 00579 00580 octreeOversizeX = (octreeSideLen - (maxX_ - minX_)) / 2.0; 00581 octreeOversizeY = (octreeSideLen - (maxY_ - minY_)) / 2.0; 00582 octreeOversizeZ = (octreeSideLen - (maxZ_ - minZ_)) / 2.0; 00583 00584 minX_ -= octreeOversizeX; 00585 minY_ -= octreeOversizeY; 00586 minZ_ -= octreeOversizeZ; 00587 00588 maxX_ += octreeOversizeX; 00589 maxY_ += octreeOversizeY; 00590 maxZ_ += octreeOversizeZ; 00591 } 00592 else 00593 { 00594 maxX_ = minX_ + octreeSideLen; 00595 maxY_ = minY_ + octreeSideLen; 00596 maxZ_ = minZ_ + octreeSideLen; 00597 } 00598 00599 // configure tree depth of octree 00600 this->setTreeDepth (this->octreeDepth_); 00601 } 00602 00604 template<typename PointT, typename LeafT, typename OctreeT> void 00605 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::genOctreeKeyforPoint (const PointT& point_arg, OctreeKey & key_arg) const 00606 { 00607 // calculate integer key for point coordinates 00608 key_arg.x = (unsigned int)((point_arg.x - this->minX_) / this->resolution_); 00609 key_arg.y = (unsigned int)((point_arg.y - this->minY_) / this->resolution_); 00610 key_arg.z = (unsigned int)((point_arg.z - this->minZ_) / this->resolution_); 00611 } 00612 00614 template<typename PointT, typename LeafT, typename OctreeT> void 00615 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::genOctreeKeyforPoint ( 00616 const double pointX_arg, const double pointY_arg, 00617 const double pointZ_arg, OctreeKey & key_arg) const 00618 { 00619 PointT tempPoint; 00620 00621 tempPoint.x = pointX_arg; 00622 tempPoint.y = pointY_arg; 00623 tempPoint.z = pointZ_arg; 00624 00625 // generate key for point 00626 genOctreeKeyforPoint (tempPoint, key_arg); 00627 } 00628 00630 template<typename PointT, typename LeafT, typename OctreeT> bool 00631 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::genOctreeKeyForDataT (const int& data_arg, OctreeKey & key_arg) const 00632 { 00633 const PointT tempPoint = getPointByIndex (data_arg); 00634 00635 // generate key for point 00636 genOctreeKeyforPoint (tempPoint, key_arg); 00637 00638 return (true); 00639 } 00640 00642 template<typename PointT, typename LeafT, typename OctreeT> void 00643 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::genLeafNodeCenterFromOctreeKey (const OctreeKey & key, PointT & point) const 00644 { 00645 // define point to leaf node voxel center 00646 point.x = ((double)key.x + 0.5f) * this->resolution_ + this->minX_; 00647 point.y = ((double)key.y + 0.5f) * this->resolution_ + this->minY_; 00648 point.z = ((double)key.z + 0.5f) * this->resolution_ + this->minZ_; 00649 } 00650 00652 template<typename PointT, typename LeafT, typename OctreeT> void 00653 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::genVoxelCenterFromOctreeKey ( 00654 const OctreeKey & key_arg, 00655 unsigned int treeDepth_arg, 00656 PointT& point_arg) const 00657 { 00658 // generate point for voxel center defined by treedepth (bitLen) and key 00659 point_arg.x = ((double)(key_arg.x) + 0.5f) * (this->resolution_ * (double)(1 << (this->octreeDepth_ 00660 - treeDepth_arg))) + this->minX_; 00661 point_arg.y = ((double)(key_arg.y) + 0.5f) * (this->resolution_ * (double)(1 << (this->octreeDepth_ 00662 - treeDepth_arg))) + this->minY_; 00663 point_arg.z = ((double)(key_arg.z) + 0.5f) * (this->resolution_ * (double)(1 << (this->octreeDepth_ 00664 - treeDepth_arg))) + this->minZ_; 00665 } 00666 00668 template<typename PointT, typename LeafT, typename OctreeT> void 00669 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::genVoxelBoundsFromOctreeKey ( 00670 const OctreeKey & key_arg, 00671 unsigned int treeDepth_arg, 00672 Eigen::Vector3f &min_pt, 00673 Eigen::Vector3f &max_pt) const 00674 { 00675 // calculate voxel size of current tree depth 00676 double voxel_side_len = this->resolution_ * (double)(1 << (this->octreeDepth_ - treeDepth_arg)); 00677 00678 // calculate voxel bounds 00679 min_pt (0) = (double)(key_arg.x) * voxel_side_len + this->minX_; 00680 min_pt (1) = (double)(key_arg.y) * voxel_side_len + this->minY_; 00681 min_pt (2) = (double)(key_arg.z) * voxel_side_len + this->minZ_; 00682 00683 max_pt (0) = (double)(key_arg.x + 1) * voxel_side_len + this->minX_; 00684 max_pt (1) = (double)(key_arg.y + 1) * voxel_side_len + this->minY_; 00685 max_pt (2) = (double)(key_arg.z + 1) * voxel_side_len + this->minZ_; 00686 } 00687 00689 template<typename PointT, typename LeafT, typename OctreeT> double 00690 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getVoxelSquaredSideLen (unsigned int treeDepth_arg) const 00691 { 00692 double sideLen; 00693 00694 // side length of the voxel cube increases exponentially with the octree depth 00695 sideLen = this->resolution_ * (double)(1 << (this->octreeDepth_ - treeDepth_arg)); 00696 00697 // squared voxel side length 00698 sideLen *= sideLen; 00699 00700 return (sideLen); 00701 } 00702 00704 template<typename PointT, typename LeafT, typename OctreeT> double 00705 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getVoxelSquaredDiameter (unsigned int treeDepth_arg) const 00706 { 00707 // return the squared side length of the voxel cube as a function of the octree depth 00708 return (getVoxelSquaredSideLen (treeDepth_arg) * 3); 00709 } 00710 00712 template<typename PointT, typename LeafT, typename OctreeT> int 00713 pcl::octree::OctreePointCloud<PointT, LeafT, OctreeT>::getOccupiedVoxelCentersRecursive ( 00714 const OctreeBranch* node_arg, 00715 const OctreeKey& key_arg, 00716 std::vector<PointT, 00717 Eigen::aligned_allocator<PointT> > &voxelCenterList_arg) const 00718 { 00719 // child iterator 00720 unsigned char childIdx; 00721 00722 int voxelCount = 0; 00723 00724 // iterate over all children 00725 for (childIdx = 0; childIdx < 8; childIdx++) 00726 { 00727 if (!this->branchHasChild (*node_arg, childIdx)) 00728 continue; 00729 00730 const OctreeNode * childNode; 00731 childNode = this->getBranchChild (*node_arg, childIdx); 00732 00733 // generate new key for current branch voxel 00734 OctreeKey newKey; 00735 newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2))); 00736 newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1))); 00737 newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0))); 00738 00739 switch (childNode->getNodeType ()) 00740 { 00741 case BRANCH_NODE: 00742 { 00743 // recursively proceed with indexed child branch 00744 voxelCount += getOccupiedVoxelCentersRecursive ((OctreeBranch*)childNode, newKey, voxelCenterList_arg); 00745 break; 00746 } 00747 case LEAF_NODE: 00748 { 00749 PointT newPoint; 00750 00751 genLeafNodeCenterFromOctreeKey (newKey, newPoint); 00752 voxelCenterList_arg.push_back (newPoint); 00753 00754 voxelCount++; 00755 break; 00756 } 00757 } 00758 } 00759 return (voxelCount); 00760 } 00761 00762 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataTVector<int> , pcl::octree::OctreeBase<int, pcl::octree::OctreeLeafDataTVector<int> > >; 00763 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataTVector<int> , pcl::octree::Octree2BufBase<int, pcl::octree::OctreeLeafDataTVector<int> > >; 00764 #define PCL_INSTANTIATE_OctreePointCloudLowMemWithLeafDataTVector(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataTVector<int> , pcl::octree::OctreeLowMemBase<int, pcl::octree::OctreeLeafDataTVector<int> > >; 00765 00766 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataT<int> , pcl::octree::OctreeBase<int, pcl::octree::OctreeLeafDataT<int> > >; 00767 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataT<int> , pcl::octree::Octree2BufBase<int, pcl::octree::OctreeLeafDataT<int> > >; 00768 #define PCL_INSTANTIATE_OctreePointCloudLowMemWithLeafDataT(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafDataT<int> , pcl::octree::OctreeLowMemBase<int, pcl::octree::OctreeLeafDataT<int> > >; 00769 00770 #define PCL_INSTANTIATE_OctreePointCloudSingleBufferWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty<int> , pcl::octree::OctreeBase<int, pcl::octree::OctreeLeafEmpty<int> > >; 00771 #define PCL_INSTANTIATE_OctreePointCloudDoubleBufferWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty<int> , pcl::octree::Octree2BufBase<int, pcl::octree::OctreeLeafEmpty<int> > >; 00772 #define PCL_INSTANTIATE_OctreePointCloudLowMemWithEmptyLeaf(T) template class PCL_EXPORTS pcl::octree::OctreePointCloud<T, pcl::octree::OctreeLeafEmpty<int> , pcl::octree::OctreeLowMemBase<int, pcl::octree::OctreeLeafEmpty<int> > >; 00773 00774 #endif /* OCTREE_POINTCLOUD_HPP_ */
1.7.6.1