|
Point Cloud Library (PCL)
1.6.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2012, 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 6119 2012-07-03 18:50:04Z aichim $ 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 BranchT, typename OctreeT> 00049 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::OctreePointCloud (const double resolution) : 00050 OctreeT (), input_ (PointCloudConstPtr ()), indices_ (IndicesConstPtr ()), 00051 epsilon_ (0), resolution_ (resolution), minX_ (0.0f), maxX_ (resolution), minY_ (0.0f), 00052 maxY_ (resolution), minZ_ (0.0f), maxZ_ (resolution), boundingBoxDefined_ (false) 00053 { 00054 assert (resolution > 0.0f); 00055 } 00056 00058 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> 00059 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::~OctreePointCloud () 00060 { 00061 } 00062 00064 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00065 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::addPointsFromInputCloud () 00066 { 00067 size_t i; 00068 00069 assert (this->leafCount_==0); 00070 if (indices_) 00071 { 00072 for (std::vector<int>::const_iterator current = indices_->begin (); current != indices_->end (); ++current) 00073 { 00074 if (isFinite (input_->points[*current])) 00075 { 00076 assert( (*current>=0) && (*current < static_cast<int> (input_->points.size ()))); 00077 00078 // add points to octree 00079 this->addPointIdx (*current); 00080 } 00081 } 00082 } 00083 else 00084 { 00085 for (i = 0; i < input_->points.size (); i++) 00086 { 00087 if (isFinite (input_->points[i])) 00088 { 00089 // add points to octree 00090 this->addPointIdx (static_cast<unsigned int> (i)); 00091 } 00092 } 00093 } 00094 } 00095 00097 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00098 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::addPointFromCloud (const int pointIdx_arg, IndicesPtr indices_arg) 00099 { 00100 this->addPointIdx (pointIdx_arg); 00101 if (indices_arg) 00102 indices_arg->push_back (pointIdx_arg); 00103 } 00104 00106 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00107 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg) 00108 { 00109 assert (cloud_arg==input_); 00110 00111 cloud_arg->push_back (point_arg); 00112 00113 this->addPointIdx (static_cast<const int> (cloud_arg->points.size ()) - 1); 00114 } 00115 00117 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00118 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg, 00119 IndicesPtr indices_arg) 00120 { 00121 assert (cloud_arg==input_); 00122 assert (indices_arg==indices_); 00123 00124 cloud_arg->push_back (point_arg); 00125 00126 this->addPointFromCloud (static_cast<const int> (cloud_arg->points.size ()) - 1, indices_arg); 00127 } 00128 00130 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> bool 00131 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::isVoxelOccupiedAtPoint (const PointT& point_arg) const 00132 { 00133 OctreeKey key; 00134 00135 // generate key for point 00136 this->genOctreeKeyforPoint (point_arg, key); 00137 00138 // search for key in octree 00139 return (isPointWithinBoundingBox (point_arg) && this->existLeaf (key)); 00140 } 00141 00143 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> bool 00144 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::isVoxelOccupiedAtPoint (const int& pointIdx_arg) const 00145 { 00146 // retrieve point from input cloud 00147 const PointT& point = this->input_->points[pointIdx_arg]; 00148 00149 // search for voxel at point in octree 00150 return (this->isVoxelOccupiedAtPoint (point)); 00151 } 00152 00154 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> bool 00155 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::isVoxelOccupiedAtPoint ( 00156 const double pointX_arg, const double pointY_arg, const double pointZ_arg) const 00157 { 00158 OctreeKey key; 00159 00160 // generate key for point 00161 this->genOctreeKeyforPoint (pointX_arg, pointY_arg, pointZ_arg, key); 00162 00163 return (this->existLeaf (key)); 00164 } 00165 00167 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00168 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::deleteVoxelAtPoint (const PointT& point_arg) 00169 { 00170 OctreeKey key; 00171 00172 // generate key for point 00173 this->genOctreeKeyforPoint (point_arg, key); 00174 00175 this->removeLeaf (key); 00176 } 00177 00179 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00180 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::deleteVoxelAtPoint (const int& pointIdx_arg) 00181 { 00182 // retrieve point from input cloud 00183 const PointT& point = this->input_->points[pointIdx_arg]; 00184 00185 // delete leaf at point 00186 this->deleteVoxelAtPoint (point); 00187 } 00188 00190 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> int 00191 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::getOccupiedVoxelCenters ( 00192 AlignedPointTVector &voxelCenterList_arg) const 00193 { 00194 OctreeKey key; 00195 key.x = key.y = key.z = 0; 00196 00197 voxelCenterList_arg.clear (); 00198 00199 return getOccupiedVoxelCentersRecursive (this->rootNode_, key, voxelCenterList_arg); 00200 00201 } 00202 00204 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> int 00205 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::getApproxIntersectedVoxelCentersBySegment ( 00206 const Eigen::Vector3f& origin, 00207 const Eigen::Vector3f& end, 00208 AlignedPointTVector &voxel_center_list, 00209 float precision) 00210 { 00211 Eigen::Vector3f direction = end - origin; 00212 float norm = direction.norm (); 00213 direction.normalize (); 00214 00215 const float step_size = static_cast<const float> (resolution_) * precision; 00216 // Ensure we get at least one step for the first voxel. 00217 const int nsteps = std::max (1, static_cast<int> (norm / step_size)); 00218 00219 OctreeKey prev_key; 00220 00221 bool bkeyDefined = false; 00222 00223 // Walk along the line segment with small steps. 00224 for (int i = 0; i < nsteps; ++i) 00225 { 00226 Eigen::Vector3f p = origin + (direction * step_size * static_cast<const float> (i)); 00227 00228 PointT octree_p; 00229 octree_p.x = p.x (); 00230 octree_p.y = p.y (); 00231 octree_p.z = p.z (); 00232 00233 OctreeKey key; 00234 this->genOctreeKeyforPoint (octree_p, key); 00235 00236 // Not a new key, still the same voxel. 00237 if ((key == prev_key) && (bkeyDefined) ) 00238 continue; 00239 00240 prev_key = key; 00241 bkeyDefined = true; 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 (static_cast<int> (voxel_center_list.size ())); 00262 } 00263 00265 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00266 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, 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 float minValue = std::numeric_limits<float>::epsilon () * 512.0f; 00280 00281 minX = min_pt.x; 00282 minY = min_pt.y; 00283 minZ = min_pt.z; 00284 00285 maxX = max_pt.x + minValue; 00286 maxY = max_pt.y + minValue; 00287 maxZ = max_pt.z + minValue; 00288 00289 // generate bit masks for octree 00290 defineBoundingBox (minX, minY, minZ, maxX, maxY, maxZ); 00291 } 00292 00294 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00295 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::defineBoundingBox (const double minX_arg, 00296 const double minY_arg, 00297 const double minZ_arg, 00298 const double maxX_arg, 00299 const double maxY_arg, 00300 const double maxZ_arg) 00301 { 00302 // bounding box cannot be changed once the octree contains elements 00303 assert (this->leafCount_ == 0); 00304 00305 assert (maxX_arg >= minX_arg); 00306 assert (maxY_arg >= minY_arg); 00307 assert (maxZ_arg >= minZ_arg); 00308 00309 minX_ = minX_arg; 00310 maxX_ = maxX_arg; 00311 00312 minY_ = minY_arg; 00313 maxY_ = maxY_arg; 00314 00315 minZ_ = minZ_arg; 00316 maxZ_ = maxZ_arg; 00317 00318 minX_ = min (minX_, maxX_); 00319 minY_ = min (minY_, maxY_); 00320 minZ_ = min (minZ_, maxZ_); 00321 00322 maxX_ = max (minX_, maxX_); 00323 maxY_ = max (minY_, maxY_); 00324 maxZ_ = max (minZ_, maxZ_); 00325 00326 // generate bit masks for octree 00327 getKeyBitSize (); 00328 00329 boundingBoxDefined_ = true; 00330 } 00331 00333 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00334 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::defineBoundingBox ( 00335 const double maxX_arg, const double maxY_arg, const double maxZ_arg) 00336 { 00337 // bounding box cannot be changed once the octree contains elements 00338 assert (this->leafCount_ == 0); 00339 00340 assert (maxX_arg >= 0.0f); 00341 assert (maxY_arg >= 0.0f); 00342 assert (maxZ_arg >= 0.0f); 00343 00344 minX_ = 0.0f; 00345 maxX_ = maxX_arg; 00346 00347 minY_ = 0.0f; 00348 maxY_ = maxY_arg; 00349 00350 minZ_ = 0.0f; 00351 maxZ_ = maxZ_arg; 00352 00353 minX_ = min (minX_, maxX_); 00354 minY_ = min (minY_, maxY_); 00355 minZ_ = min (minZ_, maxZ_); 00356 00357 maxX_ = max (minX_, maxX_); 00358 maxY_ = max (minY_, maxY_); 00359 maxZ_ = max (minZ_, maxZ_); 00360 00361 // generate bit masks for octree 00362 getKeyBitSize (); 00363 00364 boundingBoxDefined_ = true; 00365 } 00366 00368 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00369 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::defineBoundingBox (const double cubeLen_arg) 00370 { 00371 // bounding box cannot be changed once the octree contains elements 00372 assert (this->leafCount_ == 0); 00373 00374 assert (cubeLen_arg >= 0.0f); 00375 00376 minX_ = 0.0f; 00377 maxX_ = cubeLen_arg; 00378 00379 minY_ = 0.0f; 00380 maxY_ = cubeLen_arg; 00381 00382 minZ_ = 0.0f; 00383 maxZ_ = cubeLen_arg; 00384 00385 minX_ = min (minX_, maxX_); 00386 minY_ = min (minY_, maxY_); 00387 minZ_ = min (minZ_, maxZ_); 00388 00389 maxX_ = max (minX_, maxX_); 00390 maxY_ = max (minY_, maxY_); 00391 maxZ_ = max (minZ_, maxZ_); 00392 00393 // generate bit masks for octree 00394 getKeyBitSize (); 00395 00396 boundingBoxDefined_ = true; 00397 } 00398 00400 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00401 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::getBoundingBox ( 00402 double& minX_arg, double& minY_arg, double& minZ_arg, 00403 double& maxX_arg, double& maxY_arg, double& maxZ_arg) const 00404 { 00405 minX_arg = minX_; 00406 minY_arg = minY_; 00407 minZ_arg = minZ_; 00408 00409 maxX_arg = maxX_; 00410 maxY_arg = maxY_; 00411 maxZ_arg = maxZ_; 00412 } 00413 00415 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> 00416 void 00417 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::adoptBoundingBoxToPoint (const PointT& pointIdx_arg) 00418 { 00419 00420 const float minValue = std::numeric_limits<float>::epsilon (); 00421 00422 // increase octree size until point fits into bounding box 00423 while (true) 00424 { 00425 bool bLowerBoundViolationX = (pointIdx_arg.x < minX_); 00426 bool bLowerBoundViolationY = (pointIdx_arg.y < minY_); 00427 bool bLowerBoundViolationZ = (pointIdx_arg.z < minZ_); 00428 00429 bool bUpperBoundViolationX = (pointIdx_arg.x >= maxX_); 00430 bool bUpperBoundViolationY = (pointIdx_arg.y >= maxY_); 00431 bool bUpperBoundViolationZ = (pointIdx_arg.z >= maxZ_); 00432 00433 // do we violate any bounds? 00434 if (bLowerBoundViolationX || bLowerBoundViolationY || bLowerBoundViolationZ || bUpperBoundViolationX 00435 || bUpperBoundViolationY || bUpperBoundViolationZ ) 00436 { 00437 00438 if (boundingBoxDefined_) 00439 { 00440 00441 double octreeSideLen; 00442 unsigned char childIdx; 00443 00444 // octree not empty - we add another tree level and thus increase its size by a factor of 2*2*2 00445 childIdx = static_cast<unsigned char> (((!bUpperBoundViolationX) << 2) | ((!bUpperBoundViolationY) << 1) 00446 | ((!bUpperBoundViolationZ))); 00447 00448 BranchNode* newRootBranch; 00449 00450 newRootBranch = this->branchNodePool_.popNode(); 00451 this->branchCount_++; 00452 00453 this->setBranchChildPtr (*newRootBranch, childIdx, this->rootNode_); 00454 00455 this->rootNode_ = newRootBranch; 00456 00457 octreeSideLen = static_cast<double> (1 << this->octreeDepth_) * resolution_; 00458 00459 if (!bUpperBoundViolationX) 00460 minX_ -= octreeSideLen; 00461 00462 if (!bUpperBoundViolationY) 00463 minY_ -= octreeSideLen; 00464 00465 if (!bUpperBoundViolationZ) 00466 minZ_ -= octreeSideLen; 00467 00468 // configure tree depth of octree 00469 this->octreeDepth_++; 00470 this->setTreeDepth (this->octreeDepth_); 00471 00472 // recalculate bounding box width 00473 octreeSideLen = static_cast<double> (1 << this->octreeDepth_) * resolution_ - minValue; 00474 00475 // increase octree bounding box 00476 maxX_ = minX_ + octreeSideLen; 00477 maxY_ = minY_ + octreeSideLen; 00478 maxZ_ = minZ_ + octreeSideLen; 00479 00480 } 00481 // bounding box is not defined - set it to point position 00482 else 00483 { 00484 // octree is empty - we set the center of the bounding box to our first pixel 00485 this->minX_ = pointIdx_arg.x - this->resolution_ / 2; 00486 this->minY_ = pointIdx_arg.y - this->resolution_ / 2; 00487 this->minZ_ = pointIdx_arg.z - this->resolution_ / 2; 00488 00489 this->maxX_ = pointIdx_arg.x + this->resolution_ / 2; 00490 this->maxY_ = pointIdx_arg.y + this->resolution_ / 2; 00491 this->maxZ_ = pointIdx_arg.z + this->resolution_ / 2; 00492 00493 getKeyBitSize (); 00494 00495 boundingBoxDefined_ = true; 00496 } 00497 00498 } 00499 else 00500 // no bound violations anymore - leave while loop 00501 break; 00502 } 00503 } 00504 00506 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00507 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::addPointIdx (const int pointIdx_arg) 00508 { 00509 OctreeKey key; 00510 00511 assert (pointIdx_arg < static_cast<int> (input_->points.size ())); 00512 00513 const PointT& point = input_->points[pointIdx_arg]; 00514 00515 // make sure bounding box is big enough 00516 adoptBoundingBoxToPoint (point); 00517 00518 // generate key 00519 genOctreeKeyforPoint (point, key); 00520 00521 // add point to octree at key 00522 this->addData (key, pointIdx_arg); 00523 } 00524 00526 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> const PointT& 00527 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::getPointByIndex (const unsigned int index_arg) const 00528 { 00529 // retrieve point from input cloud 00530 assert (index_arg < static_cast<unsigned int> (input_->points.size ())); 00531 return (this->input_->points[index_arg]); 00532 } 00533 00535 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> LeafT* 00536 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::findLeafAtPoint (const PointT& point) const 00537 { 00538 OctreeKey key; 00539 00540 // generate key for point 00541 this->genOctreeKeyforPoint (point, key); 00542 00543 return (this->findLeaf (key)); 00544 } 00545 00547 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00548 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::getKeyBitSize () 00549 { 00550 unsigned int maxVoxels; 00551 00552 unsigned int maxKeyX; 00553 unsigned int maxKeyY; 00554 unsigned int maxKeyZ; 00555 00556 double octreeSideLen; 00557 00558 const float minValue = std::numeric_limits<float>::epsilon(); 00559 00560 // find maximum key values for x, y, z 00561 maxKeyX = static_cast<unsigned int> ((maxX_ - minX_) / resolution_); 00562 maxKeyY = static_cast<unsigned int> ((maxY_ - minY_) / resolution_); 00563 maxKeyZ = static_cast<unsigned int> ((maxZ_ - minZ_) / resolution_); 00564 00565 // find maximum amount of keys 00566 maxVoxels = max (max (max (maxKeyX, maxKeyY), maxKeyZ), static_cast<unsigned int> (2)); 00567 00568 00569 // tree depth == amount of bits of maxVoxels 00570 this->octreeDepth_ = max ((min (static_cast<unsigned int> (OCT_MAXTREEDEPTH), static_cast<unsigned int> (ceil (this->Log2 (maxVoxels)-minValue)))), 00571 static_cast<unsigned int> (0)); 00572 00573 octreeSideLen = static_cast<double> (1 << this->octreeDepth_) * resolution_-minValue; 00574 00575 if (this->leafCount_ == 0) 00576 { 00577 double octreeOversizeX; 00578 double octreeOversizeY; 00579 double octreeOversizeZ; 00580 00581 octreeOversizeX = (octreeSideLen - (maxX_ - minX_)) / 2.0; 00582 octreeOversizeY = (octreeSideLen - (maxY_ - minY_)) / 2.0; 00583 octreeOversizeZ = (octreeSideLen - (maxZ_ - minZ_)) / 2.0; 00584 00585 minX_ -= octreeOversizeX; 00586 minY_ -= octreeOversizeY; 00587 minZ_ -= octreeOversizeZ; 00588 00589 maxX_ += octreeOversizeX; 00590 maxY_ += octreeOversizeY; 00591 maxZ_ += octreeOversizeZ; 00592 } 00593 else 00594 { 00595 maxX_ = minX_ + octreeSideLen; 00596 maxY_ = minY_ + octreeSideLen; 00597 maxZ_ = minZ_ + octreeSideLen; 00598 } 00599 00600 // configure tree depth of octree 00601 this->setTreeDepth (this->octreeDepth_); 00602 00603 } 00604 00606 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00607 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::genOctreeKeyforPoint (const PointT& point_arg, 00608 OctreeKey & key_arg) const 00609 { 00610 // calculate integer key for point coordinates 00611 key_arg.x = static_cast<unsigned int> ((point_arg.x - this->minX_) / this->resolution_); 00612 key_arg.y = static_cast<unsigned int> ((point_arg.y - this->minY_) / this->resolution_); 00613 key_arg.z = static_cast<unsigned int> ((point_arg.z - this->minZ_) / this->resolution_); 00614 } 00615 00617 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00618 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::genOctreeKeyforPoint ( 00619 const double pointX_arg, const double pointY_arg, 00620 const double pointZ_arg, OctreeKey & key_arg) const 00621 { 00622 PointT tempPoint; 00623 00624 tempPoint.x = static_cast<float> (pointX_arg); 00625 tempPoint.y = static_cast<float> (pointY_arg); 00626 tempPoint.z = static_cast<float> (pointZ_arg); 00627 00628 // generate key for point 00629 genOctreeKeyforPoint (tempPoint, key_arg); 00630 } 00631 00633 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> bool 00634 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::genOctreeKeyForDataT (const int& data_arg, OctreeKey & key_arg) const 00635 { 00636 const PointT tempPoint = getPointByIndex (data_arg); 00637 00638 // generate key for point 00639 genOctreeKeyforPoint (tempPoint, key_arg); 00640 00641 return (true); 00642 } 00643 00645 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00646 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::genLeafNodeCenterFromOctreeKey (const OctreeKey & key, PointT & point) const 00647 { 00648 // define point to leaf node voxel center 00649 point.x = static_cast<float> ((static_cast<double> (key.x) + 0.5f) * this->resolution_ + this->minX_); 00650 point.y = static_cast<float> ((static_cast<double> (key.y) + 0.5f) * this->resolution_ + this->minY_); 00651 point.z = static_cast<float> ((static_cast<double> (key.z) + 0.5f) * this->resolution_ + this->minZ_); 00652 } 00653 00655 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00656 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::genVoxelCenterFromOctreeKey ( 00657 const OctreeKey & key_arg, 00658 unsigned int treeDepth_arg, 00659 PointT& point_arg) const 00660 { 00661 // generate point for voxel center defined by treedepth (bitLen) and key 00662 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_); 00663 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_); 00664 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_); 00665 } 00666 00668 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> void 00669 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, 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_ * static_cast<double> (1 << (this->octreeDepth_ - treeDepth_arg)); 00677 00678 // calculate voxel bounds 00679 min_pt (0) = static_cast<float> (static_cast<double> (key_arg.x) * voxel_side_len + this->minX_); 00680 min_pt (1) = static_cast<float> (static_cast<double> (key_arg.y) * voxel_side_len + this->minY_); 00681 min_pt (2) = static_cast<float> (static_cast<double> (key_arg.z) * voxel_side_len + this->minZ_); 00682 00683 max_pt (0) = static_cast<float> (static_cast<double> (key_arg.x + 1) * voxel_side_len + this->minX_); 00684 max_pt (1) = static_cast<float> (static_cast<double> (key_arg.y + 1) * voxel_side_len + this->minY_); 00685 max_pt (2) = static_cast<float> (static_cast<double> (key_arg.z + 1) * voxel_side_len + this->minZ_); 00686 } 00687 00689 template<typename PointT, typename LeafT, typename BranchT, typename OctreeT> double 00690 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, 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_ * static_cast<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 BranchT, typename OctreeT> double 00705 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, 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 BranchT, typename OctreeT> int 00713 pcl::octree::OctreePointCloud<PointT, LeafT, BranchT, OctreeT>::getOccupiedVoxelCentersRecursive ( 00714 const BranchNode* node_arg, 00715 const OctreeKey& key_arg, 00716 AlignedPointTVector &voxelCenterList_arg) const 00717 { 00718 // child iterator 00719 unsigned char childIdx; 00720 00721 int voxelCount = 0; 00722 00723 // iterate over all children 00724 for (childIdx = 0; childIdx < 8; childIdx++) 00725 { 00726 if (!this->branchHasChild (*node_arg, childIdx)) 00727 continue; 00728 00729 const OctreeNode * childNode; 00730 childNode = this->getBranchChildPtr (*node_arg, childIdx); 00731 00732 // generate new key for current branch voxel 00733 OctreeKey newKey; 00734 newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2))); 00735 newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1))); 00736 newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0))); 00737 00738 switch (childNode->getNodeType ()) 00739 { 00740 case BRANCH_NODE: 00741 { 00742 // recursively proceed with indexed child branch 00743 voxelCount += getOccupiedVoxelCentersRecursive (static_cast<const BranchNode*> (childNode), newKey, voxelCenterList_arg); 00744 break; 00745 } 00746 case LEAF_NODE: 00747 { 00748 PointT newPoint; 00749 00750 genLeafNodeCenterFromOctreeKey (newKey, newPoint); 00751 voxelCenterList_arg.push_back (newPoint); 00752 00753 voxelCount++; 00754 break; 00755 } 00756 default: 00757 break; 00758 } 00759 } 00760 return (voxelCount); 00761 } 00762 00763 #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> > >; 00764 #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> > >; 00765 00766 #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> > >; 00767 #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> > >; 00768 00769 #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> > >; 00770 #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> > >; 00771 00772 #endif /* OCTREE_POINTCLOUD_HPP_ */
1.7.6.1