|
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_lowmemory_base.h 4702 2012-02-23 09:39:33Z gedikli $ 00037 */ 00038 00039 #ifndef OCTREE_LOWMEM_TREE_BASE_H 00040 #define OCTREE_LOWMEM_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 { 00054 00061 00062 template<typename DataT, typename LeafT = OctreeLeafDataT<DataT> > 00063 class OctreeLowMemBase 00064 { 00065 00066 // iterators are friends 00067 friend class OctreeIteratorBase<DataT, LeafT, OctreeLowMemBase> ; 00068 friend class OctreeDepthFirstIterator<DataT, LeafT, OctreeLowMemBase> ; 00069 friend class OctreeBreadthFirstIterator<DataT, LeafT, OctreeLowMemBase> ; 00070 friend class OctreeLeafNodeIterator<DataT, LeafT, OctreeLowMemBase> ; 00071 00072 public: 00073 00074 // Octree iterators 00075 typedef OctreeDepthFirstIterator<DataT, LeafT, OctreeLowMemBase> Iterator; 00076 typedef const OctreeDepthFirstIterator<DataT, LeafT, OctreeLowMemBase> ConstIterator; 00077 00078 typedef OctreeLeafNodeIterator<DataT, LeafT, OctreeLowMemBase> LeafNodeIterator; 00079 typedef const OctreeLeafNodeIterator<DataT, LeafT, OctreeLowMemBase> ConstLeafNodeIterator; 00080 00081 typedef OctreeDepthFirstIterator<DataT, LeafT, OctreeLowMemBase> DepthFirstIterator; 00082 typedef const OctreeDepthFirstIterator<DataT, LeafT, OctreeLowMemBase> ConstDepthFirstIterator; 00083 typedef OctreeBreadthFirstIterator<DataT, LeafT, OctreeLowMemBase> BreadthFirstIterator; 00084 typedef const OctreeBreadthFirstIterator<DataT, LeafT, OctreeLowMemBase> ConstBreadthFirstIterator; 00085 00087 OctreeLowMemBase (); 00088 00090 virtual 00091 ~OctreeLowMemBase (); 00092 00094 OctreeLowMemBase (const OctreeLowMemBase& source) 00095 { 00096 leafCount_ = source.leafCount_; 00097 branchCount_ = source.branchCount_; 00098 objectCount_ = source.objectCount_; 00099 rootNode_ = new (OctreeBranch) (*(source.rootNode_)); 00100 depthMask_ = source.depthMask_; 00101 octreeDepth_ = source.octreeDepth_; 00102 } 00103 00104 00108 void 00109 setMaxVoxelIndex (unsigned int maxVoxelIndex_arg); 00110 00114 void 00115 setTreeDepth (unsigned int depth_arg); 00116 00120 inline unsigned int 00121 getTreeDepth () const 00122 { 00123 return this->octreeDepth_; 00124 } 00125 00132 void 00133 add (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00134 const DataT& data_arg); 00135 00143 bool 00144 get (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, DataT& data_arg) const ; 00145 00152 bool 00153 existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg) const ; 00154 00160 void 00161 removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg); 00162 00166 inline unsigned int 00167 getLeafCount () const 00168 { 00169 return leafCount_; 00170 } 00171 00175 inline unsigned int 00176 getBranchCount () const 00177 { 00178 return branchCount_; 00179 } 00180 00183 void 00184 deleteTree ( ); 00185 00190 void 00191 serializeTree (std::vector<char>& binaryTreeOut_arg, bool doXOREncoding_arg = false); 00192 00198 void 00199 serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg, 00200 bool doXOREncoding_arg = false); 00201 00205 void 00206 serializeLeafs (std::vector<DataT>& dataVector_arg); 00207 00212 void 00213 deserializeTree (std::vector<char>& binaryTreeIn_arg, bool doXORDecoding_arg = false); 00214 00220 void 00221 deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg, 00222 bool doXORDecoding_arg = false); 00223 00228 void 00229 deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg); 00230 00232 void 00233 switchBuffers () 00234 { 00235 this->deleteTree (); 00236 } 00237 00238 protected: 00239 00241 00245 00246 class OctreeKey 00247 { 00248 public: 00249 00253 bool 00254 operator == (const OctreeKey& b) const 00255 { 00256 return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z)); 00257 } 00258 00259 // Indices addressing a voxel at (X, Y, Z) 00260 unsigned int x; 00261 unsigned int y; 00262 unsigned int z; 00263 }; 00264 00266 00270 00271 class OctreeBranch : public OctreeNode 00272 { 00273 // OctreeBase is a friend! 00274 friend class OctreeLowMemBase; 00275 00276 public: 00277 00279 OctreeBranch () 00280 { 00281 // initialize 00282 occupancyByte_ = 0; 00283 this->reset(); 00284 } 00285 00287 void 00288 reset () 00289 { 00290 // if pointers to childs exist, we delete them 00291 if (occupancyByte_) 00292 delete[] subNodes_; 00293 00294 // reset occupancy byte 00295 occupancyByte_ = 0; 00296 } 00297 00299 virtual 00300 ~OctreeBranch () 00301 { 00302 } 00303 00305 virtual OctreeNode * 00306 deepCopy () const 00307 { 00308 return (OctreeNode*) new OctreeBranch (*this); 00309 } 00310 00314 virtual node_type_t 00315 getNodeType () const 00316 { 00317 return BRANCH_NODE; 00318 } 00319 00320 private: 00321 00322 unsigned char occupancyByte_; 00323 OctreeNode** subNodes_; 00324 00325 }; 00326 00327 typedef LeafT OctreeLeaf; 00328 00330 // Protected octree methods based on octree keys 00332 00334 const OctreeNode* 00335 getRootNode () const 00336 { 00337 return this->rootNode_; 00338 } 00339 00345 virtual bool 00346 genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const 00347 { 00348 // this class cannot relate DataT objects to octree keys 00349 return false; 00350 } 00351 00357 virtual bool 00358 genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const 00359 { 00360 // this class cannot relate DataT objects to octree keys 00361 return false; 00362 } 00363 00370 inline void 00371 genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00372 OctreeKey & key_arg) const 00373 { 00374 // copy data to octree key class 00375 key_arg.x = idxX_arg; 00376 key_arg.y = idxY_arg; 00377 key_arg.z = idxZ_arg; 00378 } 00379 00384 inline void 00385 add (const OctreeKey& key_arg, const DataT& data_arg) 00386 { 00387 // request a (new) leaf from tree 00388 LeafT* leaf = getLeaf (key_arg); 00389 00390 // assign data to leaf 00391 if (leaf) 00392 { 00393 leaf->setData (data_arg); 00394 objectCount_++; 00395 } 00396 } 00397 00402 inline LeafT* 00403 findLeaf (const OctreeKey& key_arg) const 00404 { 00405 return findLeafRecursive (key_arg, depthMask_, rootNode_); 00406 } 00407 00413 inline LeafT* 00414 getLeaf (const OctreeKey& key_arg) 00415 { 00416 return getLeafRecursive (key_arg, depthMask_, rootNode_); 00417 } 00418 00423 inline bool 00424 existLeaf (const OctreeKey& key_arg) const 00425 { 00426 return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0); 00427 } 00428 00432 inline void 00433 removeLeaf (const OctreeKey& key_arg) 00434 { 00435 deleteLeafRecursive (key_arg, depthMask_, rootNode_); 00436 } 00437 00439 // Branch node accessor inline functions 00441 00447 inline const OctreeNode* 00448 getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00449 { 00450 // check if branch child exists according to occupancyBtye 00451 if (branch_arg.occupancyByte_ & (1 << childIdx_arg)) 00452 { 00453 unsigned int c, idx; 00454 00455 // retrieve array index of child pointer 00456 idx = 0; 00457 for (c = 0; c < childIdx_arg; c++) 00458 { 00459 if (branch_arg.occupancyByte_ & (1 << c)) 00460 idx++; 00461 } 00462 00463 return branch_arg.subNodes_[idx]; 00464 00465 } 00466 00467 return 0; 00468 } 00469 00475 inline bool 00476 branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00477 { 00478 // test occupancyByte for child existence 00479 return ((branch_arg.occupancyByte_ & (1 << childIdx_arg)) != 0); 00480 } 00481 00486 inline char 00487 getBranchBitPattern (const OctreeBranch& branch_arg) const 00488 { 00489 return branch_arg.occupancyByte_; 00490 } 00491 00497 inline void 00498 setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeNode * newChild_arg) 00499 { 00500 00501 if (!(branch_arg.occupancyByte_ & (1 << childIdx_arg))) 00502 { 00503 // branch child does not exists 00504 unsigned int c, idx, total; 00505 00506 // retrieve total amount of child pointers and retrieve index of new child pointer 00507 idx = 0; 00508 total = 0; 00509 for (c = 0; c < 8; c++) 00510 { 00511 if (branch_arg.occupancyByte_ & (1 << c)) 00512 { 00513 if (c < childIdx_arg) 00514 idx++; 00515 00516 total++; 00517 } 00518 } 00519 00520 if (newChild_arg != 0) 00521 { 00522 // a new child pointer is to be added to child array 00523 00524 // allocate new pointer array 00525 OctreeNode** newNodes = new OctreeNode*[total + 1]; 00526 00527 // copy pointers to new pointer array 00528 memcpy (&newNodes[0], &branch_arg.subNodes_[0], idx * sizeof(OctreeNode*)); 00529 newNodes[idx] = newChild_arg; 00530 memcpy (&newNodes[idx + 1], &branch_arg.subNodes_[idx], (total - idx) * sizeof(OctreeNode*)); 00531 00532 // delete old pointer array 00533 if (total > 0) 00534 delete[] branch_arg.subNodes_; 00535 00536 // set new child pointer array 00537 branch_arg.subNodes_ = newNodes; 00538 00539 // update occupancyByte 00540 branch_arg.occupancyByte_ |= (1 << childIdx_arg); 00541 } 00542 00543 } 00544 else 00545 { 00546 // child pointer already exists 00547 unsigned int c, idx, total; 00548 00549 // pointer set to 0 -> delete child pointer 00550 if (newChild_arg == 0) 00551 { 00552 00553 // retrieve total amount of child pointers and detect index of child pointer to be removed 00554 idx = 0; 00555 total = 0; 00556 for (c = 0; c < 8; c++) 00557 { 00558 if (branch_arg.occupancyByte_ & (1 << c)) 00559 { 00560 if (c < childIdx_arg) 00561 idx++; 00562 00563 total++; 00564 } 00565 } 00566 00567 if (total == 1) 00568 { 00569 // if only a single pointer exists, simply delete the data structure 00570 delete[] branch_arg.subNodes_; 00571 00572 branch_arg.subNodes_ = 0; 00573 branch_arg.occupancyByte_ = 0; 00574 } 00575 else 00576 { 00577 // allocate new pointer array with reduced size 00578 OctreeNode** newNodes = new OctreeNode*[total - 1]; 00579 00580 // copy old pointer references to new array 00581 memcpy (&newNodes[0], &branch_arg.subNodes_[0], idx * sizeof(OctreeNode*)); 00582 memcpy (&newNodes[idx], &branch_arg.subNodes_[idx + 1], (total - (idx + 1)) * sizeof(OctreeNode*)); 00583 00584 // delete previous pointer array and update "branch_arg.subNodes_" 00585 delete[] branch_arg.subNodes_; 00586 branch_arg.subNodes_ = newNodes; 00587 00588 // update occupancyByte by removing the corresponding bit 00589 branch_arg.occupancyByte_ &= ~(1 << childIdx_arg); 00590 00591 } 00592 00593 } 00594 else 00595 { 00596 // update existing child pointer 00597 00598 // retrieve index of child pointer to be updated 00599 idx = 0; 00600 for (c = 0; c < childIdx_arg; c++) 00601 { 00602 if (branch_arg.occupancyByte_ & (1 << c)) 00603 { 00604 idx++; 00605 } 00606 } 00607 00608 // update pointer 00609 branch_arg.subNodes_[idx] = newChild_arg; 00610 } 00611 00612 } 00613 00614 } 00615 00620 inline void 00621 deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg) 00622 { 00623 if (branchHasChild (branch_arg, childIdx_arg)) 00624 { 00625 const OctreeNode* branchChild; 00626 branchChild = getBranchChild (branch_arg, childIdx_arg); 00627 00628 switch (branchChild->getNodeType ()) 00629 { 00630 case BRANCH_NODE: 00631 // free child branch recursively 00632 deleteBranch (*(OctreeBranch*)branchChild); 00633 break; 00634 case LEAF_NODE: 00635 break; 00636 default: 00637 break; 00638 00639 } 00640 00641 // delete branch child 00642 delete (branchChild); 00643 00644 // set branch child pointer to 0 00645 setBranchChild (branch_arg, childIdx_arg, 0); 00646 } 00647 } 00648 00652 inline void 00653 deleteBranch (OctreeBranch& branch_arg) 00654 { 00655 char i; 00656 00657 // delete all branch node children 00658 for (i = 0; i < 8; i++) 00659 { 00660 deleteBranchChild (branch_arg, i); 00661 } 00662 } 00663 00667 inline void 00668 createBranch (OctreeBranch*& newBranchChild_arg) 00669 { 00670 00671 // we need to create a new octree branch class 00672 newBranchChild_arg = (OctreeBranch*)new OctreeBranch (); 00673 00674 } 00675 00681 inline void 00682 createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, 00683 OctreeBranch*& newBranchChild_arg) 00684 { 00685 createBranch (newBranchChild_arg); 00686 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg); 00687 } 00688 00694 inline void 00695 createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg) 00696 { 00697 00698 // we need to create a new octree leaf class 00699 newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf (); 00700 newLeafChild_arg->reset(); 00701 00702 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg); 00703 00704 } 00705 00709 inline void 00710 branchReset (OctreeBranch& branch_arg) 00711 { 00712 branch_arg.reset(); 00713 } 00714 00715 00717 // Recursive octree methods 00719 00720 00727 LeafT* 00728 getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00729 00737 LeafT* 00738 findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const; 00739 00746 bool 00747 deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00748 00754 void 00755 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, const OctreeKey& key_arg); 00756 00763 void 00764 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, 00765 const OctreeKey& key_arg, typename std::vector<DataT>& dataVector_arg); 00766 00772 void 00773 serializeLeafsRecursive (const OctreeBranch* branch_arg, const OctreeKey& key_arg, 00774 typename std::vector<DataT>& dataVector_arg); 00775 00782 void 00783 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00784 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg); 00785 00794 void 00795 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00796 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg, 00797 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00798 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00799 00807 void 00808 deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00809 OctreeBranch* branch_arg, const unsigned int depthMask_arg, 00810 const OctreeKey& key_arg, 00811 typename std::vector<DataT>& dataVector_arg); 00812 00814 // Serialization callbacks 00816 00821 virtual void 00822 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00823 00829 virtual void 00830 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg); 00831 00836 virtual void 00837 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00838 00845 virtual void 00846 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, 00847 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00848 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00849 00855 virtual void 00856 deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg, 00857 std::vector<DataT>& dataVector_arg); 00858 00860 // Helpers 00862 00867 inline double 00868 Log2 (double n_arg) 00869 { 00870 return log( n_arg ) / log( 2.0 ); 00871 } 00872 00876 inline bool 00877 octreeCanResize () 00878 { 00879 return (true); 00880 } 00881 00883 // Globals 00885 00887 unsigned int leafCount_; 00888 00890 unsigned int branchCount_; 00891 00893 unsigned int objectCount_; 00894 00896 OctreeBranch* rootNode_; 00897 00899 unsigned int depthMask_; 00900 00902 unsigned int octreeDepth_; 00903 00905 std::vector<OctreeBranch*> unusedBranchesPool_; 00906 00908 std::vector<LeafT*> unusedLeafsPool_; 00909 00910 }; 00911 } 00912 } 00913 00914 //#include "impl/octree_base.hpp" 00915 00916 #endif 00917
1.8.0