|
Point Cloud Library (PCL)
1.5.1
|
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.h 4702 2012-02-23 09:39:33Z gedikli $ 00037 */ 00038 00039 #ifndef OCTREE_TREE_BASE_H 00040 #define OCTREE_TREE_BASE_H 00041 00042 #include <cstddef> 00043 #include <vector> 00044 00045 #include "octree_nodes.h" 00046 00047 #include "octree_iterator.h" 00048 00049 namespace pcl 00050 { 00051 namespace octree 00052 { 00053 00054 00056 00063 00064 template<typename DataT, typename LeafT = OctreeLeafDataT<DataT>, typename OctreeBranchT = OctreeBranch > 00065 class OctreeBase 00066 { 00067 00068 // iterators are friends 00069 friend class OctreeIteratorBase<DataT, LeafT, OctreeBase> ; 00070 friend class OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> ; 00071 friend class OctreeBreadthFirstIterator<DataT, LeafT, OctreeBase> ; 00072 friend class OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> ; 00073 00074 public: 00075 typedef OctreeBranchT OctreeBranch; 00076 00077 // Octree iterators 00078 typedef OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> Iterator; 00079 typedef const OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> ConstIterator; 00080 00081 typedef OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> LeafNodeIterator; 00082 typedef const OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> ConstLeafNodeIterator; 00083 00084 typedef OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> DepthFirstIterator; 00085 typedef const OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> ConstDepthFirstIterator; 00086 typedef OctreeBreadthFirstIterator<DataT, LeafT, OctreeBase> BreadthFirstIterator; 00087 typedef const OctreeBreadthFirstIterator<DataT, LeafT, OctreeBase> ConstBreadthFirstIterator; 00088 00090 OctreeBase (); 00091 00093 virtual 00094 ~OctreeBase (); 00095 00097 OctreeBase (const OctreeBase& source) 00098 { 00099 leafCount_ = source.leafCount_; 00100 branchCount_ = source.branchCount_; 00101 objectCount_ = source.objectCount_; 00102 rootNode_ = new (OctreeBranch) (*(source.rootNode_)); 00103 depthMask_ = source.depthMask_; 00104 octreeDepth_ = source.octreeDepth_; 00105 } 00106 00110 void 00111 setMaxVoxelIndex (unsigned int maxVoxelIndex_arg); 00112 00116 void 00117 setTreeDepth (unsigned int depth_arg); 00118 00122 inline unsigned int 00123 getTreeDepth () const 00124 { 00125 return this->octreeDepth_; 00126 } 00127 00134 void 00135 add (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00136 const DataT& data_arg); 00137 00145 bool 00146 get (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, DataT& data_arg) const ; 00147 00154 bool 00155 existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg) const ; 00156 00162 void 00163 removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg); 00164 00168 inline unsigned int 00169 getLeafCount () const 00170 { 00171 return leafCount_; 00172 } 00173 00177 inline unsigned int 00178 getBranchCount () const 00179 { 00180 return branchCount_; 00181 } 00182 00186 void 00187 deleteTree ( bool freeMemory_arg = false ); 00188 00192 void 00193 serializeTree (std::vector<char>& binaryTreeOut_arg); 00194 00199 void 00200 serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg); 00201 00205 void 00206 serializeLeafs (std::vector<DataT>& dataVector_arg); 00207 00211 void 00212 deserializeTree (std::vector<char>& binaryTreeIn_arg); 00213 00218 void 00219 deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg); 00220 00225 void 00226 deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg); 00227 00228 protected: 00229 00231 00235 00236 class OctreeKey 00237 { 00238 public: 00239 00243 bool 00244 operator == (const OctreeKey& b) const 00245 { 00246 return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z)); 00247 } 00248 00249 // Indices addressing a voxel at (X, Y, Z) 00250 unsigned int x;unsigned int y;unsigned int z; 00251 }; 00252 00253 typedef LeafT OctreeLeaf; 00254 00256 // Protected octree methods based on octree keys 00258 00260 const OctreeNode* 00261 getRootNode () const 00262 { 00263 return this->rootNode_; 00264 } 00265 00271 virtual bool 00272 genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const 00273 { 00274 // this class cannot relate DataT objects to octree keys 00275 return false; 00276 } 00277 00283 virtual bool 00284 genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const 00285 { 00286 // this class cannot relate DataT objects to octree keys 00287 return false; 00288 } 00289 00296 inline void 00297 genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00298 OctreeKey & key_arg) const 00299 { 00300 // copy data to octree key class 00301 key_arg.x = idxX_arg; 00302 key_arg.y = idxY_arg; 00303 key_arg.z = idxZ_arg; 00304 } 00305 00310 inline void 00311 add (const OctreeKey& key_arg, const DataT& data_arg) 00312 { 00313 // request a (new) leaf from tree 00314 LeafT* leaf = getLeaf (key_arg); 00315 00316 // assign data to leaf 00317 if (leaf) 00318 { 00319 leaf->setData (data_arg); 00320 objectCount_++; 00321 } 00322 } 00323 00328 inline LeafT* 00329 findLeaf (const OctreeKey& key_arg) const 00330 { 00331 return findLeafRecursive (key_arg, depthMask_, rootNode_); 00332 } 00333 00339 inline LeafT* 00340 getLeaf (const OctreeKey& key_arg) 00341 { 00342 return getLeafRecursive (key_arg, depthMask_, rootNode_); 00343 } 00344 00349 inline bool 00350 existLeaf (const OctreeKey& key_arg) const 00351 { 00352 return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0); 00353 } 00354 00358 inline void 00359 removeLeaf (const OctreeKey& key_arg) 00360 { 00361 deleteLeafRecursive (key_arg, depthMask_, rootNode_); 00362 } 00363 00365 // Branch node accessor inline functions 00367 00373 inline const OctreeNode* 00374 getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00375 { 00376 return branch_arg[childIdx_arg]; 00377 } 00378 00384 inline OctreeBranch* 00385 getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) 00386 { 00387 return (OctreeBranch*)branch_arg[childIdx_arg]; 00388 } 00389 00395 inline bool 00396 branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00397 { 00398 return (branch_arg[childIdx_arg] != 0); 00399 } 00400 00405 inline char 00406 getBranchBitPattern (const OctreeBranch& branch_arg) const 00407 { 00408 unsigned char i; 00409 char nodeBits; 00410 00411 // create bit pattern 00412 nodeBits = 0; 00413 for (i = 0; i < 8; i++) 00414 { 00415 nodeBits |= (!!branch_arg[i]) << i; 00416 } 00417 00418 return nodeBits; 00419 } 00420 00426 inline void 00427 setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, const OctreeNode * newChild_arg) 00428 { 00429 branch_arg[childIdx_arg] = newChild_arg; 00430 } 00431 00436 inline void 00437 deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg) 00438 { 00439 if (branchHasChild (branch_arg, childIdx_arg)) 00440 { 00441 const OctreeNode* branchChild; 00442 branchChild = getBranchChild (branch_arg, childIdx_arg); 00443 00444 switch (branchChild->getNodeType ()) 00445 { 00446 case BRANCH_NODE: 00447 { 00448 // free child branch recursively 00449 deleteBranch (*(OctreeBranch*)branchChild); 00450 // push unused branch to branch pool 00451 unusedBranchesPool_.push_back ((OctreeBranch*)branchChild); 00452 } 00453 break; 00454 00455 case LEAF_NODE: 00456 // push unused leaf to branch pool 00457 unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild); 00458 break; 00459 00460 default: 00461 break; 00462 } 00463 00464 // set branch child pointer to 0 00465 setBranchChild (branch_arg, childIdx_arg, 0); 00466 } 00467 } 00468 00472 inline void 00473 deleteBranch (OctreeBranch& branch_arg) 00474 { 00475 char i; 00476 00477 // delete all branch node children 00478 for (i = 0; i < 8; i++) 00479 { 00480 deleteBranchChild (branch_arg, i); 00481 } 00482 } 00483 00487 inline void 00488 createBranch (OctreeBranch*& newBranchChild_arg) 00489 { 00490 if (!unusedBranchesPool_.size ()) 00491 { 00492 // branch pool is empty 00493 // we need to create a new octree branch class 00494 newBranchChild_arg = (OctreeBranch*)new OctreeBranch (); 00495 } 00496 else 00497 { 00498 // reuse branch from branch pool 00499 newBranchChild_arg = unusedBranchesPool_.back (); 00500 unusedBranchesPool_.pop_back (); 00501 branchReset (*newBranchChild_arg); 00502 } 00503 } 00504 00510 inline void 00511 createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, 00512 OctreeBranch*& newBranchChild_arg) 00513 { 00514 createBranch ( newBranchChild_arg ); 00515 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg); 00516 } 00517 00523 inline void 00524 createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg) 00525 { 00526 00527 if (!unusedLeafsPool_.size ()) 00528 { 00529 // leaf pool is empty 00530 // we need to create a new octree leaf class 00531 newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf (); 00532 } 00533 else 00534 { 00535 // reuse leaf node from branch pool 00536 newLeafChild_arg = unusedLeafsPool_.back (); 00537 unusedLeafsPool_.pop_back (); 00538 } 00539 00540 newLeafChild_arg->reset (); 00541 00542 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg); 00543 } 00544 00548 inline void 00549 branchReset (OctreeBranch& branch_arg) 00550 { 00551 branch_arg.reset (); 00552 } 00553 00556 inline void 00557 poolCleanUp () 00558 { 00559 // delete all branch instances from branch pool 00560 while (!unusedBranchesPool_.empty ()) 00561 { 00562 delete (unusedBranchesPool_.back ()); 00563 unusedBranchesPool_.pop_back (); 00564 } 00565 00566 // delete all leaf instances from leaf pool 00567 while (!unusedLeafsPool_.empty ()) 00568 { 00569 delete (unusedLeafsPool_.back ()); 00570 unusedLeafsPool_.pop_back (); 00571 } 00572 } 00573 00575 // Recursive octree methods 00577 00584 LeafT* 00585 getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00586 00594 LeafT* 00595 findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const; 00596 00603 bool 00604 deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00605 00611 void 00612 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, const OctreeKey& key_arg); 00613 00620 void 00621 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, 00622 const OctreeKey& key_arg, typename std::vector<DataT>& dataVector_arg); 00623 00629 void 00630 serializeLeafsRecursive (const OctreeBranch* branch_arg, const OctreeKey& key_arg, 00631 typename std::vector<DataT>& dataVector_arg); 00632 00639 void 00640 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00641 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg); 00642 00651 void 00652 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00653 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg, 00654 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00655 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00656 00664 void 00665 deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00666 OctreeBranch* branch_arg, const unsigned int depthMask_arg, 00667 const OctreeKey& key_arg, 00668 typename std::vector<DataT>& dataVector_arg); 00669 00671 // Serialization callbacks 00673 00678 virtual void 00679 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00680 00686 virtual void 00687 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg); 00688 00693 virtual void 00694 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00695 00702 virtual void 00703 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, 00704 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00705 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00706 00712 virtual void 00713 deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg, 00714 std::vector<DataT>& dataVector_arg); 00715 00717 // Helpers 00719 00724 inline double 00725 Log2 (double n_arg) 00726 { 00727 return log( n_arg ) / log( 2.0 ); 00728 } 00729 00733 inline bool 00734 octreeCanResize () 00735 { 00736 return (true); 00737 } 00738 00740 // Globals 00742 00744 unsigned int leafCount_; 00745 00747 unsigned int branchCount_; 00748 00750 unsigned int objectCount_; 00751 00753 OctreeBranch* rootNode_; 00754 00756 unsigned int depthMask_; 00757 00759 unsigned int octreeDepth_; 00760 00762 std::vector<OctreeBranch*> unusedBranchesPool_; 00763 00765 std::vector<LeafT*> unusedLeafsPool_; 00766 00767 }; 00768 } 00769 } 00770 00771 //#include "impl/octree_base.hpp" 00772 00773 #endif 00774
1.8.0