|
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: octree2buf_base.h 3749 2011-12-31 22:58:01Z rusu $ 00037 */ 00038 00039 #ifndef OCTREE_TREE_2BUF_BASE_H 00040 #define OCTREE_TREE_2BUF_BASE_H 00041 00042 #include <vector> 00043 00044 #include "octree_nodes.h" 00045 00046 #include "octree_iterator.h" 00047 00048 namespace pcl 00049 { 00050 namespace octree 00051 { 00065 template<typename DataT, typename LeafT = OctreeLeafDataT<DataT> > 00066 class Octree2BufBase 00067 { 00068 00069 friend class OctreeNodeIterator<DataT, LeafT, Octree2BufBase> ; 00070 friend class OctreeLeafNodeIterator<DataT, LeafT, Octree2BufBase> ; 00071 00072 public: 00073 00074 // Octree iterators 00075 typedef OctreeNodeIterator<DataT, LeafT, Octree2BufBase> Iterator; 00076 typedef const OctreeNodeIterator<DataT, LeafT, Octree2BufBase> ConstIterator; 00077 00078 // Octree iterators 00079 typedef OctreeLeafNodeIterator<DataT, LeafT, Octree2BufBase> LeafNodeIterator; 00080 typedef const OctreeLeafNodeIterator<DataT, LeafT, Octree2BufBase> ConstLeafNodeIterator; 00081 00083 Octree2BufBase (); 00084 00086 virtual 00087 ~Octree2BufBase (); 00088 00092 void 00093 setMaxVoxelIndex (unsigned int maxVoxelIndex_arg); 00094 00098 void 00099 setTreeDepth (unsigned int depth_arg); 00100 00104 inline unsigned int 00105 getTreeDepth () 00106 { 00107 return this->octreeDepth_; 00108 } 00109 00116 void 00117 add (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00118 const DataT& data_arg); 00119 00127 bool 00128 get (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, DataT& data_arg) const ; 00129 00136 bool 00137 existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg) const ; 00138 00144 void 00145 removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg); 00146 00150 inline unsigned int 00151 getLeafCount () const 00152 { 00153 return leafCount_; 00154 } 00155 00159 inline unsigned int 00160 getBranchCount () const 00161 { 00162 return branchCount_; 00163 } 00164 00168 void 00169 deleteTree ( bool freeMemory_arg = false ); 00170 00172 inline void 00173 deletePreviousBuffer () 00174 { 00175 treeCleanUpRecursive (rootNode_); 00176 } 00177 00179 inline void 00180 deleteCurrentBuffer () 00181 { 00182 bufferSelector_ = !bufferSelector_; 00183 treeCleanUpRecursive (rootNode_); 00184 leafCount_ = 0; 00185 } 00186 00188 void 00189 switchBuffers (); 00190 00195 void 00196 serializeTree (std::vector<char>& binaryTreeOut_arg, bool doXOREncoding_arg = false); 00197 00203 void 00204 serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg, 00205 bool doXOREncoding_arg = false); 00206 00210 void 00211 serializeLeafs (std::vector<DataT>& dataVector_arg); 00212 00217 void 00218 serializeNewLeafs (std::vector<DataT>& dataVector_arg, const int minPointsPerLeaf_arg = 0); 00219 00224 void 00225 deserializeTree (std::vector<char>& binaryTreeIn_arg, bool doXORDecoding_arg = false); 00226 00232 void 00233 deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg, 00234 bool doXORDecoding_arg = false); 00235 00241 void 00242 deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg, 00243 bool doXORDecoding_arg = false); 00244 00245 protected: 00246 00248 00252 00253 class OctreeKey 00254 { 00255 public: 00256 00260 bool 00261 operator == (const OctreeKey& b) const 00262 { 00263 return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z)); 00264 } 00265 00266 // Indices addressing a voxel at (X, Y, Z) 00267 unsigned int x;unsigned int y;unsigned int z; 00268 }; 00269 00271 00275 00276 class OctreeBranch : public OctreeNode 00277 { 00278 00279 // Octree2BufBase is a friend! 00280 friend class Octree2BufBase; 00281 00282 public: 00283 00285 OctreeBranch () 00286 { 00287 memset (this->subNodes_, 0, sizeof(this->subNodes_)); 00288 } 00289 00291 virtual 00292 ~OctreeBranch () 00293 { 00294 } 00295 00299 virtual node_type_t 00300 getNodeType () const 00301 { 00302 return BRANCH_NODE; 00303 } 00304 00305 private: 00306 00308 const OctreeNode * subNodes_[2][8]; 00309 00310 }; 00311 00312 typedef LeafT OctreeLeaf; 00313 00315 // Protected octree methods based on octree keys 00317 00319 const OctreeNode* 00320 getRootNode () const 00321 { 00322 return this->rootNode_; 00323 } 00324 00330 virtual bool 00331 genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const 00332 { 00333 // this class cannot relate DataT objects to octree keys 00334 return false; 00335 } 00336 00342 virtual bool 00343 genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const 00344 { 00345 // this class cannot relate DataT objects to octree keys 00346 return false; 00347 } 00348 00355 inline void 00356 genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00357 OctreeKey & key_arg) const 00358 { 00359 // copy data to octree key class 00360 key_arg.x = idxX_arg; 00361 key_arg.y = idxY_arg; 00362 key_arg.z = idxZ_arg; 00363 } 00364 00369 inline void 00370 add (const OctreeKey& key_arg, const DataT& data_arg) 00371 { 00372 // request a (new) leaf from tree 00373 LeafT* leaf = getLeaf (key_arg); 00374 00375 // assign data to leaf 00376 if (leaf) 00377 { 00378 leaf->setData (data_arg); 00379 objectCount_++; 00380 } 00381 } 00382 00387 inline LeafT* 00388 findLeaf (const OctreeKey& key_arg) const 00389 { 00390 return findLeafRecursive (key_arg, depthMask_, rootNode_); 00391 } 00392 00398 inline LeafT* 00399 getLeaf (const OctreeKey& key_arg) 00400 { 00401 LeafT* result; 00402 00403 result = getLeafRecursive (key_arg, depthMask_, rootNode_, resetTree_); 00404 00405 // getLeafRecursive has changed the octree -> clean-up/tree-reset might be required 00406 resetTree_ = false; 00407 treeDirtyFlag_ = true; 00408 00409 return result; 00410 } 00411 00416 inline bool 00417 existLeaf (const OctreeKey& key_arg) const 00418 { 00419 return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0); 00420 } 00421 00425 inline void 00426 removeLeaf (const OctreeKey& key_arg) 00427 { 00428 deleteLeafRecursive (key_arg, depthMask_, rootNode_); 00429 00430 // we changed the octree structure -> dirty 00431 treeDirtyFlag_ = true; 00432 } 00433 00435 // Branch node accessor inline functions 00437 00438 00444 inline const OctreeNode* 00445 getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00446 { 00447 return branch_arg.subNodes_[bufferSelector_][childIdx_arg]; 00448 } 00449 00456 inline const OctreeNode* 00457 getBranchChild (const OctreeBranch& branch_arg, const unsigned char bufferSelector_arg, 00458 const unsigned char childIdx_arg) const 00459 { 00460 return branch_arg.subNodes_[bufferSelector_arg][childIdx_arg]; 00461 } 00462 00468 inline bool 00469 branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00470 { 00471 return (branch_arg.subNodes_[bufferSelector_][childIdx_arg] != 0); 00472 } 00473 00480 inline bool 00481 branchHasChild (const OctreeBranch& branch_arg, const unsigned char bufferSelector_arg, 00482 const unsigned char childIdx_arg) const 00483 { 00484 return (branch_arg.subNodes_[bufferSelector_arg][childIdx_arg] != 0); 00485 00486 } 00487 00492 inline char 00493 getBranchBitPattern (const OctreeBranch& branch_arg) const 00494 { 00495 unsigned char i; 00496 char nodeBits; 00497 00498 // create bit pattern 00499 nodeBits = 0; 00500 for (i = 0; i < 8; i++) 00501 { 00502 nodeBits |= (!!branch_arg.subNodes_[bufferSelector_][i]) << i; 00503 } 00504 00505 return nodeBits; 00506 } 00507 00513 inline char 00514 getBranchBitPattern (const OctreeBranch& branch_arg, const unsigned char bufferSelector_arg) const 00515 { 00516 unsigned char i; 00517 char nodeBits; 00518 00519 // create bit pattern 00520 nodeBits = 0; 00521 for (i = 0; i < 8; i++) 00522 { 00523 nodeBits |= (!!branch_arg.subNodes_[bufferSelector_arg][i]) << i; 00524 } 00525 00526 return nodeBits; 00527 } 00528 00533 inline char 00534 getBranchXORBitPattern (const OctreeBranch& branch_arg) const 00535 { 00536 unsigned char i; 00537 char nodeBits[2]; 00538 00539 // create bit pattern for both buffers 00540 nodeBits[0] = nodeBits[1] = 0; 00541 00542 for (i = 0; i < 8; i++) 00543 { 00544 nodeBits[0] |= (!!branch_arg.subNodes_[0][i]) << i; 00545 nodeBits[1] |= (!!branch_arg.subNodes_[1][i]) << i; 00546 } 00547 00548 return nodeBits[0] ^ nodeBits[1]; 00549 } 00550 00555 inline bool 00556 hasBranchChanges (const OctreeBranch& branch_arg) const 00557 { 00558 return (getBranchXORBitPattern (branch_arg) > 0); 00559 } 00560 00566 inline void 00567 setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, const OctreeNode * newChild_arg) 00568 { 00569 branch_arg.subNodes_[bufferSelector_][childIdx_arg] = newChild_arg; 00570 } 00571 00578 inline void 00579 setBranchChild (OctreeBranch& branch_arg, const unsigned char bufferSelector_arg, 00580 const unsigned char childIdx_arg, const OctreeNode * newChild_arg) 00581 { 00582 branch_arg.subNodes_[bufferSelector_arg][childIdx_arg] = newChild_arg; 00583 } 00584 00589 inline void 00590 deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg) 00591 { 00592 if (branchHasChild (branch_arg, childIdx_arg)) 00593 { 00594 const OctreeNode* branchChild; 00595 branchChild = getBranchChild (branch_arg, childIdx_arg); 00596 00597 switch (branchChild->getNodeType ()) 00598 { 00599 case BRANCH_NODE: 00600 // free child branch recursively 00601 deleteBranch (*(OctreeBranch*)branchChild); 00602 00603 // push unused branch to branch pool 00604 unusedBranchesPool_.push_back ((OctreeBranch*)branchChild); 00605 break; 00606 00607 case LEAF_NODE: 00608 00609 // push unused leaf to branch pool 00610 unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild); 00611 break; 00612 } 00613 00614 // set branch child pointer to 0 00615 setBranchChild (branch_arg, childIdx_arg, 0); 00616 } 00617 } 00618 00624 inline void 00625 deleteBranchChild (OctreeBranch& branch_arg, const unsigned char bufferSelector_arg, 00626 const unsigned char childIdx_arg) 00627 { 00628 if (branchHasChild (branch_arg, bufferSelector_arg, childIdx_arg)) 00629 { 00630 const OctreeNode* branchChild; 00631 branchChild = getBranchChild (branch_arg, bufferSelector_arg, childIdx_arg); 00632 00633 switch (branchChild->getNodeType ()) 00634 { 00635 case BRANCH_NODE: 00636 // free child branch recursively 00637 deleteBranch (*(OctreeBranch*)branchChild); 00638 00639 // push unused branch to branch pool 00640 unusedBranchesPool_.push_back ((OctreeBranch*)branchChild); 00641 break; 00642 00643 case LEAF_NODE: 00644 00645 // push unused leaf to branch pool 00646 unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild); 00647 break; 00648 } 00649 00650 // set branch child pointer to 0 00651 setBranchChild (branch_arg, bufferSelector_arg, childIdx_arg, 0); 00652 00653 } 00654 } 00655 00659 inline void 00660 deleteBranch (OctreeBranch& branch_arg) 00661 { 00662 char i; 00663 00664 // delete all branch node children 00665 for (i = 0; i < 8; i++) 00666 { 00667 00668 if (getBranchChild (branch_arg, 0, i) == getBranchChild (branch_arg, 1, i)) 00669 { 00670 // reference was copied - there is only one child instance to be deleted 00671 deleteBranchChild (branch_arg, 0, i); 00672 00673 // remove pointers from both buffers 00674 setBranchChild (branch_arg, 0, i, 0); 00675 setBranchChild (branch_arg, 1, i, 0); 00676 00677 } 00678 else 00679 { 00680 deleteBranchChild (branch_arg, 0, i); 00681 deleteBranchChild (branch_arg, 1, i); 00682 } 00683 } 00684 } 00685 00691 inline void 00692 createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, 00693 OctreeBranch*& newBranchChild_arg) 00694 { 00695 if (!unusedBranchesPool_.size ()) 00696 { 00697 newBranchChild_arg = (OctreeBranch*)new OctreeBranch (); 00698 } 00699 else 00700 { 00701 newBranchChild_arg = unusedBranchesPool_.back (); 00702 unusedBranchesPool_.pop_back (); 00703 branchReset (*newBranchChild_arg); 00704 } 00705 00706 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg); 00707 } 00708 00712 inline void 00713 createBranch (OctreeBranch*& newBranchChild_arg) 00714 { 00715 00716 if (!unusedBranchesPool_.size ()) 00717 { 00718 // branch pool is empty 00719 // we need to create a new octree branch class 00720 newBranchChild_arg = (OctreeBranch*)new OctreeBranch (); 00721 } 00722 else 00723 { 00724 // reuse branch from branch pool 00725 newBranchChild_arg = unusedBranchesPool_.back (); 00726 unusedBranchesPool_.pop_back (); 00727 branchReset (*newBranchChild_arg); 00728 } 00729 } 00730 00736 inline void 00737 createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg) 00738 { 00739 if (!unusedLeafsPool_.size ()) 00740 { 00741 // leaf pool is empty 00742 // we need to create a new octree leaf class 00743 newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf (); 00744 } 00745 else 00746 { 00747 // reuse leaf node from branch pool 00748 newLeafChild_arg = unusedLeafsPool_.back (); 00749 unusedLeafsPool_.pop_back (); 00750 } 00751 00752 newLeafChild_arg->reset (); 00753 00754 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg); 00755 } 00756 00760 inline void 00761 branchReset (OctreeBranch& branch_arg) 00762 { 00763 memset (branch_arg.subNodes_, 0, sizeof(branch_arg.subNodes_)); 00764 } 00765 00768 inline void 00769 poolCleanUp () 00770 { 00771 // delete all branch instances from branch pool 00772 while (!unusedBranchesPool_.empty ()) 00773 { 00774 delete (unusedBranchesPool_.back ()); 00775 unusedBranchesPool_.pop_back (); 00776 } 00777 00778 // delete all leaf instances from leaf pool 00779 while (!unusedLeafsPool_.empty ()) 00780 { 00781 delete (unusedLeafsPool_.back ()); 00782 unusedLeafsPool_.pop_back (); 00783 } 00784 } 00785 00787 // Recursive octree methods 00789 00790 00798 LeafT* 00799 getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg, 00800 bool branchReset_arg); 00801 00809 LeafT* 00810 findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const; 00811 00818 bool 00819 deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00820 00827 void 00828 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, OctreeBranch* branch_arg, const OctreeKey& key_arg, 00829 bool doXOREncoding_arg); 00830 00838 void 00839 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, OctreeBranch* branch_arg, const OctreeKey& key_arg, 00840 typename std::vector<DataT>& dataVector_arg, bool doXOREncoding_arg); 00841 00847 void 00848 serializeLeafsRecursive (OctreeBranch* branch_arg, const OctreeKey& key_arg, 00849 typename std::vector<DataT>& dataVector_arg); 00850 00857 void 00858 serializeNewLeafsRecursive (OctreeBranch* branch_arg, const OctreeKey& key_arg, 00859 std::vector<DataT>& dataVector_arg, const int minPointsPerLeaf_arg = 0); 00860 00869 void 00870 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00871 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg, 00872 bool branchReset_arg, bool doXORDecoding_arg); 00873 00884 void 00885 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00886 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg, 00887 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00888 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg, 00889 bool branchReset_arg, bool doXORDecoding_arg); 00890 00900 void 00901 deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00902 OctreeBranch* branch_arg, const unsigned int depthMask_arg, 00903 const OctreeKey& key_arg, 00904 typename std::vector<DataT>& dataVector_arg, 00905 bool branchReset_arg, bool doXORDecoding_arg); 00906 00908 // Serialization callbacks 00910 00915 virtual void 00916 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00917 00923 virtual void 00924 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg); 00925 00932 virtual void 00933 serializeNewLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, const int minPointsPerLeaf_arg, 00934 std::vector<DataT>& dataVector_arg); 00935 00940 virtual void 00941 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00942 00949 virtual void 00950 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, 00951 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00952 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00953 00959 virtual void 00960 deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg, 00961 std::vector<DataT>& dataVector_arg); 00962 00964 // Helpers 00966 00970 void 00971 treeCleanUpRecursive (OctreeBranch* branch_arg); 00972 00977 inline double 00978 Log2 (double n_arg) 00979 { 00980 return log (n_arg) / log (2.0); 00981 } 00982 00986 inline bool 00987 octreeCanResize () 00988 { 00989 return (false); 00990 } 00991 00993 // Globals 00995 00996 00998 unsigned int leafCount_; 00999 01001 unsigned int branchCount_; 01002 01004 unsigned int objectCount_; 01005 01007 OctreeBranch* rootNode_; 01008 01010 unsigned int depthMask_; 01011 01013 std::vector<OctreeBranch*> unusedBranchesPool_; 01014 01016 std::vector<LeafT*> unusedLeafsPool_; 01017 01019 unsigned char bufferSelector_; 01020 01021 // flags indicating if unused branches and leafs might exist in previous buffer 01022 bool resetTree_; 01023 bool treeDirtyFlag_; 01024 01026 unsigned int octreeDepth_; 01027 01028 }; 01029 } 01030 } 01031 01032 //#include "impl/octree2buf_base.hpp" 01033 01034 #endif 01035
1.7.6.1