|
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-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_base.hpp 6119 2012-07-03 18:50:04Z aichim $ 00037 */ 00038 00039 #ifndef OCTREE_BASE_HPP 00040 #define OCTREE_BASE_HPP 00041 00042 #include <vector> 00043 00044 #include <pcl/impl/instantiate.hpp> 00045 #include <pcl/point_types.h> 00046 #include <pcl/octree/octree.h> 00047 00048 // maximum depth of octree as we are using "unsigned int" octree keys / bit masks 00049 #define OCT_MAXTREEDEPTH ( sizeof(size_t) * 8 ) 00050 00051 namespace pcl 00052 { 00053 namespace octree 00054 { 00056 template<typename DataT, typename LeafT, typename BranchT> 00057 OctreeBase<DataT, LeafT, BranchT>::OctreeBase () : 00058 leafCount_ (0), 00059 branchCount_ (1), 00060 objectCount_ (0), 00061 rootNode_ (new BranchNode ()), 00062 maxObjsPerLeaf_(0), 00063 depthMask_ (0), 00064 octreeDepth_ (0), 00065 maxKey_ (), 00066 branchNodePool_ (), 00067 leafNodePool_ () 00068 { 00069 } 00070 00072 template<typename DataT, typename LeafT, typename BranchT> 00073 OctreeBase<DataT, LeafT, BranchT>::~OctreeBase () 00074 { 00075 // deallocate tree structure 00076 deleteTree (); 00077 delete (rootNode_); 00078 poolCleanUp (); 00079 } 00080 00082 template<typename DataT, typename LeafT, typename BranchT> void 00083 OctreeBase<DataT, LeafT, BranchT>::setMaxVoxelIndex (unsigned int maxVoxelIndex_arg) 00084 { 00085 unsigned int treeDepth; 00086 00087 assert (maxVoxelIndex_arg>0); 00088 00089 // tree depth == amount of bits of maxVoxels 00090 treeDepth = std::max ((std::min (static_cast<unsigned int> (OCT_MAXTREEDEPTH), 00091 static_cast<unsigned int> (std::ceil (Log2 (maxVoxelIndex_arg))))), 00092 static_cast<unsigned int> (0)); 00093 00094 // define depthMask_ by setting a single bit to 1 at bit position == tree depth 00095 depthMask_ = (1 << (treeDepth - 1)); 00096 } 00097 00099 template<typename DataT, typename LeafT, typename BranchT> 00100 void 00101 OctreeBase<DataT, LeafT, BranchT>::setTreeDepth (unsigned int depth_arg) 00102 { 00103 assert(depth_arg>0); 00104 00105 // set octree depth 00106 octreeDepth_ = depth_arg; 00107 00108 // define depthMask_ by setting a single bit to 1 at bit position == tree depth 00109 depthMask_ = (1 << (depth_arg - 1)); 00110 00111 // define max. keys 00112 maxKey_.x = maxKey_.y = maxKey_.z = (1 << depth_arg) - 1; 00113 } 00114 00116 template<typename DataT, typename LeafT, typename BranchT> void 00117 OctreeBase<DataT, LeafT, BranchT>::addData (unsigned int idxX_arg, unsigned int idxY_arg, 00118 unsigned int idxZ_arg, const DataT& data_arg) 00119 { 00120 // generate key 00121 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg); 00122 00123 // add data_arg to octree 00124 addData (key, data_arg); 00125 } 00126 00128 template<typename DataT, typename LeafT, typename BranchT>bool 00129 OctreeBase<DataT, LeafT, BranchT>::getData (unsigned int idxX_arg, unsigned int idxY_arg, 00130 unsigned int idxZ_arg, DataT& data_arg) const 00131 { 00132 // generate key 00133 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg); 00134 00135 // search for leaf at key 00136 LeafNode* leaf = findLeaf (key); 00137 if (leaf) 00138 { 00139 // if successful, decode data to data_arg 00140 leaf->getData (data_arg); 00141 } 00142 00143 // returns true on success 00144 return (leaf != 0); 00145 } 00146 00148 template<typename DataT, typename LeafT, typename BranchT> bool 00149 OctreeBase<DataT, LeafT, BranchT>::existLeaf (unsigned int idxX_arg, unsigned int idxY_arg, 00150 unsigned int idxZ_arg) const 00151 { 00152 // generate key 00153 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg); 00154 00155 // check if key exist in octree 00156 return ( existLeaf (key)); 00157 } 00158 00160 template<typename DataT, typename LeafT, typename BranchT> void 00161 OctreeBase<DataT, LeafT, BranchT>::removeLeaf (unsigned int idxX_arg, unsigned int idxY_arg, 00162 unsigned int idxZ_arg) 00163 { 00164 // generate key 00165 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg); 00166 00167 // check if key exist in octree 00168 deleteLeafRecursive (key, depthMask_, rootNode_); 00169 } 00170 00172 template<typename DataT, typename LeafT, typename BranchT> void 00173 OctreeBase<DataT, LeafT, BranchT>::deleteTree (bool freeMemory_arg ) 00174 { 00175 00176 if (rootNode_) 00177 { 00178 // reset octree 00179 deleteBranch (*rootNode_); 00180 leafCount_ = 0; 00181 branchCount_ = 1; 00182 objectCount_ = 0; 00183 00184 } 00185 00186 // delete node pool 00187 if (freeMemory_arg) 00188 poolCleanUp (); 00189 00190 } 00191 00193 template<typename DataT, typename LeafT, typename BranchT> void 00194 OctreeBase<DataT, LeafT, BranchT>::serializeTree (std::vector<char>& binaryTreeOut_arg) 00195 { 00196 // serialization requires fixed octree depth 00197 // maxObjsPerLeaf_>0 indicates a dynamic octree structure 00198 assert (!maxObjsPerLeaf_); 00199 00200 OctreeKey newKey; 00201 00202 // clear binary vector 00203 binaryTreeOut_arg.clear (); 00204 binaryTreeOut_arg.reserve (this->branchCount_); 00205 00206 serializeTreeRecursive (rootNode_, newKey, &binaryTreeOut_arg, 0 ); 00207 } 00208 00210 template<typename DataT, typename LeafT, typename BranchT> void 00211 OctreeBase<DataT, LeafT, BranchT>::serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg) 00212 { 00213 // serialization requires fixed octree depth 00214 // maxObjsPerLeaf_>0 indicates a dynamic octree structure 00215 assert (!maxObjsPerLeaf_); 00216 00217 OctreeKey newKey; 00218 00219 // clear output vectors 00220 binaryTreeOut_arg.clear (); 00221 dataVector_arg.clear (); 00222 00223 dataVector_arg.reserve (this->objectCount_); 00224 binaryTreeOut_arg.reserve (this->branchCount_); 00225 00226 serializeTreeRecursive (rootNode_, newKey, &binaryTreeOut_arg, &dataVector_arg ); 00227 } 00228 00230 template<typename DataT, typename LeafT, typename BranchT> void 00231 OctreeBase<DataT, LeafT, BranchT>::serializeLeafs (std::vector<DataT>& dataVector_arg) 00232 { 00233 // serialization requires fixed octree depth 00234 // maxObjsPerLeaf_>0 indicates a dynamic octree structure 00235 assert (!maxObjsPerLeaf_); 00236 00237 OctreeKey newKey; 00238 00239 // clear output vector 00240 dataVector_arg.clear (); 00241 00242 dataVector_arg.reserve(this->objectCount_); 00243 00244 serializeTreeRecursive (rootNode_, newKey, 0, &dataVector_arg ); 00245 } 00246 00248 template<typename DataT, typename LeafT, typename BranchT> void 00249 OctreeBase<DataT, LeafT, BranchT>::deserializeTree (std::vector<char>& binaryTreeIn_arg) 00250 { 00251 // serialization requires fixed octree depth 00252 // maxObjsPerLeaf_>0 indicates a dynamic octree structure 00253 assert (!maxObjsPerLeaf_); 00254 00255 OctreeKey newKey; 00256 00257 // free existing tree before tree rebuild 00258 deleteTree (); 00259 00260 //iterator for binary tree structure vector 00261 std::vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin (); 00262 std::vector<char>::const_iterator binaryTreeVectorIteratorEnd = binaryTreeIn_arg.end (); 00263 00264 deserializeTreeRecursive (rootNode_, depthMask_, newKey, 00265 binaryTreeVectorIterator, binaryTreeVectorIteratorEnd, 0, 0); 00266 00267 } 00268 00270 template<typename DataT, typename LeafT, typename BranchT> void 00271 OctreeBase<DataT, LeafT, BranchT>::deserializeTree (std::vector<char>& binaryTreeIn_arg, 00272 std::vector<DataT>& dataVector_arg) 00273 { 00274 // serialization requires fixed octree depth 00275 // maxObjsPerLeaf_>0 indicates a dynamic octree structure 00276 assert (!maxObjsPerLeaf_); 00277 00278 OctreeKey newKey; 00279 00280 // set data iterator to first element 00281 typename std::vector<DataT>::const_iterator dataVectorIterator = dataVector_arg.begin (); 00282 00283 // set data iterator to last element 00284 typename std::vector<DataT>::const_iterator dataVectorEndIterator = dataVector_arg.end (); 00285 00286 // free existing tree before tree rebuild 00287 deleteTree (); 00288 00289 //iterator for binary tree structure vector 00290 std::vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin (); 00291 std::vector<char>::const_iterator binaryTreeVectorIteratorEnd = binaryTreeIn_arg.end (); 00292 00293 deserializeTreeRecursive (rootNode_, depthMask_, newKey, 00294 binaryTreeVectorIterator, binaryTreeVectorIteratorEnd, &dataVectorIterator, &dataVectorEndIterator); 00295 00296 } 00297 00299 template<typename DataT, typename LeafT, typename BranchT> void OctreeBase< 00300 DataT, LeafT, BranchT>::addDataToLeafRecursive ( 00301 const OctreeKey& key_arg, unsigned int depthMask_arg, 00302 const DataT& data_arg, BranchNode* branch_arg) 00303 { 00304 // index to branch child 00305 unsigned char childIdx; 00306 00307 // find branch child from key 00308 childIdx = key_arg.getChildIdxWithDepthMask(depthMask_arg); 00309 00310 // add data to branch node container 00311 branch_arg->setData (data_arg); 00312 00313 OctreeNode* childNode = (*branch_arg)[childIdx]; 00314 00315 if (!childNode) 00316 { 00317 if ((!maxObjsPerLeaf_) && (depthMask_arg > 1)) { 00318 // if required branch does not exist -> create it 00319 BranchNode* childBranch; 00320 createBranchChild (*branch_arg, childIdx, childBranch); 00321 00322 branchCount_++; 00323 00324 // recursively proceed with indexed child branch 00325 addDataToLeafRecursive (key_arg, depthMask_arg / 2, data_arg, childBranch); 00326 00327 } else { 00328 LeafNode* childLeaf; 00329 00330 // if leaf node at childIdx does not exist 00331 createLeafChild (*branch_arg, childIdx, childLeaf); 00332 leafCount_++; 00333 00334 // add data to leaf 00335 childLeaf->setData (data_arg); 00336 objectCount_++; 00337 } 00338 } else { 00339 00340 // Node exists already 00341 switch (childNode->getNodeType()) { 00342 case BRANCH_NODE: 00343 // recursively proceed with indexed child branch 00344 addDataToLeafRecursive (key_arg, depthMask_arg / 2, data_arg, static_cast<BranchNode*> (childNode)); 00345 break; 00346 00347 case LEAF_NODE: 00348 LeafNode* childLeaf = static_cast<LeafNode*> (childNode); 00349 00350 if ( (!maxObjsPerLeaf_) || (!depthMask_arg) ) 00351 { 00352 // add data to leaf 00353 childLeaf->setData (data_arg); 00354 objectCount_++; 00355 } else { 00356 size_t leafObjCount = childLeaf->getSize(); 00357 00358 if (leafObjCount<maxObjsPerLeaf_) { 00359 // add data to leaf 00360 childLeaf->setData (data_arg); 00361 objectCount_++; 00362 } else { 00363 // leaf node needs to be expanded 00364 00365 // copy leaf data 00366 std::vector<DataT> leafData; 00367 leafData.reserve(leafObjCount); 00368 00369 childLeaf->getData (leafData); 00370 00371 // delete current leaf node 00372 deleteBranchChild(*branch_arg,childIdx); 00373 leafCount_ --; 00374 00375 // create new branch node 00376 BranchNode* childBranch; 00377 createBranchChild (*branch_arg, childIdx, childBranch); 00378 branchCount_ ++; 00379 00380 typename std::vector<DataT>::const_iterator lData = leafData.begin(); 00381 typename std::vector<DataT>::const_iterator lDataEnd = leafData.end(); 00382 00383 // add data to new branch 00384 OctreeKey dataKey; 00385 while (lData!=lDataEnd) { 00386 // get data object 00387 const DataT& data = *lData++; 00388 00389 // generate new key for data object 00390 if (this->genOctreeKeyForDataT(data, dataKey)) { 00391 addDataToLeafRecursive (dataKey, depthMask_arg / 2, data, childBranch); 00392 } 00393 } 00394 00395 // and add new DataT object 00396 addDataToLeafRecursive (key_arg, depthMask_arg / 2, data_arg, childBranch); 00397 00398 // correct object counter 00399 objectCount_ -= leafObjCount; 00400 } 00401 } 00402 break; 00403 } 00404 } 00405 } 00406 00408 template<typename DataT, typename LeafT, typename BranchT> void 00409 OctreeBase<DataT, LeafT, BranchT>::findLeafRecursive ( 00410 const OctreeKey& key_arg, unsigned int depthMask_arg, BranchNode* branch_arg, LeafNode*& result_arg) const 00411 { 00412 // index to branch child 00413 unsigned char childIdx; 00414 00415 // find branch child from key 00416 childIdx = key_arg.getChildIdxWithDepthMask(depthMask_arg); 00417 00418 OctreeNode* childNode = (*branch_arg)[childIdx]; 00419 00420 if (childNode) { 00421 switch (childNode->getNodeType()) { 00422 case BRANCH_NODE: 00423 // we have not reached maximum tree depth 00424 BranchNode* childBranch; 00425 childBranch = static_cast<BranchNode*> (childNode); 00426 00427 findLeafRecursive (key_arg, depthMask_arg / 2, childBranch, result_arg); 00428 break; 00429 00430 case LEAF_NODE: 00431 // return existing leaf node 00432 LeafNode* childLeaf; 00433 childLeaf = static_cast<LeafNode*> (childNode); 00434 result_arg = childLeaf; 00435 break; 00436 } 00437 } 00438 } 00439 00441 template<typename DataT, typename LeafT, typename BranchT> bool 00442 OctreeBase<DataT, LeafT, BranchT>::deleteLeafRecursive (const OctreeKey& key_arg, unsigned int depthMask_arg, 00443 BranchNode* branch_arg) 00444 { 00445 // index to branch child 00446 unsigned char childIdx; 00447 // indicates if branch is empty and can be safely removed 00448 bool bNoChilds; 00449 00450 // find branch child from key 00451 childIdx = key_arg.getChildIdxWithDepthMask(depthMask_arg); 00452 00453 OctreeNode* childNode = (*branch_arg)[childIdx]; 00454 00455 if (childNode) { 00456 switch (childNode->getNodeType()) { 00457 00458 case BRANCH_NODE: 00459 BranchNode* childBranch; 00460 childBranch = static_cast<BranchNode*> (childNode); 00461 00462 // recursively explore the indexed child branch 00463 bNoChilds = deleteLeafRecursive (key_arg, depthMask_arg / 2, childBranch); 00464 00465 if (!bNoChilds) 00466 { 00467 // child branch does not own any sub-child nodes anymore -> delete child branch 00468 deleteBranchChild(*branch_arg, childIdx); 00469 branchCount_--; 00470 } 00471 break; 00472 00473 case LEAF_NODE: 00474 // return existing leaf node 00475 00476 // our child is a leaf node -> delete it 00477 deleteBranchChild (*branch_arg, childIdx); 00478 leafCount_--; 00479 break; 00480 } 00481 } 00482 00483 // check if current branch still owns childs 00484 bNoChilds = false; 00485 for (childIdx = 0; (!bNoChilds) && (childIdx < 8); childIdx++) 00486 { 00487 bNoChilds = branch_arg->hasChild(childIdx); 00488 } 00489 // return true if current branch can be deleted 00490 return (bNoChilds); 00491 } 00492 00494 template<typename DataT, typename LeafT, typename BranchT> void OctreeBase< 00495 DataT, LeafT, BranchT>::serializeTreeRecursive (const BranchNode* branch_arg, OctreeKey& key_arg, 00496 std::vector<char>* binaryTreeOut_arg, 00497 typename std::vector<DataT>* dataVector_arg) const 00498 { 00499 00500 // child iterator 00501 unsigned char childIdx; 00502 char nodeBitPattern; 00503 00504 // branch occupancy bit pattern 00505 nodeBitPattern = getBranchBitPattern (*branch_arg); 00506 00507 // write bit pattern to output vector 00508 if (binaryTreeOut_arg) 00509 binaryTreeOut_arg->push_back (nodeBitPattern); 00510 00511 // iterate over all children 00512 for (childIdx = 0; childIdx < 8; childIdx++) 00513 { 00514 00515 // if child exist 00516 if (branch_arg->hasChild(childIdx)) 00517 { 00518 // add current branch voxel to key 00519 key_arg.pushBranch(childIdx); 00520 00521 const OctreeNode *childNode = branch_arg->getChildPtr(childIdx); 00522 00523 switch (childNode->getNodeType ()) 00524 { 00525 case BRANCH_NODE: 00526 { 00527 // recursively proceed with indexed child branch 00528 serializeTreeRecursive ( 00529 static_cast<const BranchNode*> (childNode), key_arg, 00530 binaryTreeOut_arg, dataVector_arg); 00531 break; 00532 } 00533 case LEAF_NODE: 00534 { 00535 const LeafNode* childLeaf = static_cast<const LeafNode*> (childNode); 00536 00537 if (dataVector_arg) 00538 childLeaf->getData (*dataVector_arg); 00539 00540 // we reached a leaf node -> execute serialization callback 00541 serializeTreeCallback (*childLeaf, key_arg); 00542 break; 00543 } 00544 default: 00545 break; 00546 } 00547 00548 // pop current branch voxel from key 00549 key_arg.popBranch(); 00550 } 00551 } 00552 } 00553 00554 00555 00557 template<typename DataT, typename LeafT, typename BranchT> void 00558 OctreeBase<DataT, LeafT, BranchT>::deserializeTreeRecursive (BranchNode* branch_arg, 00559 unsigned int depthMask_arg, OctreeKey& key_arg, 00560 typename std::vector<char>::const_iterator& binaryTreeIT_arg, 00561 typename std::vector<char>::const_iterator& binaryTreeIT_End_arg, 00562 typename std::vector<DataT>::const_iterator* dataVectorIterator_arg, 00563 typename std::vector<DataT>::const_iterator* dataVectorEndIterator_arg) 00564 { 00565 // child iterator 00566 unsigned char childIdx; 00567 char nodeBits; 00568 00569 if (binaryTreeIT_arg != binaryTreeIT_End_arg ) { 00570 // read branch occupancy bit pattern from input vector 00571 nodeBits = (*binaryTreeIT_arg); 00572 binaryTreeIT_arg++; 00573 00574 // iterate over all children 00575 for (childIdx = 0; childIdx < 8; childIdx++) 00576 { 00577 // if occupancy bit for childIdx is set.. 00578 if (nodeBits & (1 << childIdx)) 00579 { 00580 // add current branch voxel to key 00581 key_arg.pushBranch(childIdx); 00582 00583 if (depthMask_arg > 1) 00584 { 00585 // we have not reached maximum tree depth 00586 BranchNode * newBranch; 00587 00588 // create new child branch 00589 createBranchChild (*branch_arg, childIdx, newBranch); 00590 00591 branchCount_++; 00592 00593 // recursively proceed with new child branch 00594 deserializeTreeRecursive (newBranch, depthMask_arg / 2, key_arg, binaryTreeIT_arg,binaryTreeIT_End_arg, dataVectorIterator_arg, 00595 dataVectorEndIterator_arg); 00596 } 00597 else 00598 { 00599 // we reached leaf node level 00600 00601 LeafNode* childLeaf; 00602 00603 // create leaf node 00604 createLeafChild (*branch_arg, childIdx, childLeaf); 00605 00606 OctreeKey dataKey; 00607 bool bKeyBasedEncoding = false; 00608 00609 if (dataVectorIterator_arg 00610 && (*dataVectorIterator_arg != *dataVectorEndIterator_arg)) 00611 { 00612 00613 // add DataT objects to octree leaf as long as their key fit to voxel 00614 while ( ( (*dataVectorIterator_arg) 00615 != (*dataVectorEndIterator_arg)) 00616 && (this->genOctreeKeyForDataT (**dataVectorIterator_arg, 00617 dataKey) && (dataKey == key_arg))) 00618 { 00619 childLeaf->setData (**dataVectorIterator_arg); 00620 (*dataVectorIterator_arg)++; 00621 bKeyBasedEncoding = true; 00622 objectCount_++; 00623 } 00624 00625 // add single DataT object to octree if key-based encoding is disabled 00626 if (!bKeyBasedEncoding) 00627 { 00628 childLeaf->setData (**dataVectorIterator_arg); 00629 (*dataVectorIterator_arg)++; 00630 objectCount_++; 00631 } 00632 } 00633 00634 leafCount_++; 00635 00636 // execute deserialization callback 00637 deserializeTreeCallback (*childLeaf, key_arg); 00638 } 00639 00640 // pop current branch voxel from key 00641 key_arg.popBranch(); 00642 } 00643 } 00644 } 00645 } 00646 00647 } 00648 } 00649 00650 #define PCL_INSTANTIATE_OctreeBase(T) template class PCL_EXPORTS pcl::octree::OctreeBase<T>; 00651 00652 #endif 00653
1.7.6.1