|
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: octree_lowmemory_base.h 3749 2011-12-31 22:58:01Z rusu $ 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 friend class OctreeNodeIterator<DataT, LeafT, OctreeLowMemBase> ; 00067 friend class OctreeLeafNodeIterator<DataT, LeafT, OctreeLowMemBase> ; 00068 00069 public: 00070 00071 // Octree iterators 00072 typedef OctreeNodeIterator<DataT, LeafT, OctreeLowMemBase> Iterator; 00073 typedef const OctreeNodeIterator<DataT, LeafT, OctreeLowMemBase> ConstIterator; 00074 00075 // Octree iterators 00076 typedef OctreeLeafNodeIterator<DataT, LeafT, OctreeLowMemBase> LeafNodeIterator; 00077 typedef const OctreeLeafNodeIterator<DataT, LeafT, OctreeLowMemBase> ConstLeafNodeIterator; 00078 00080 OctreeLowMemBase (); 00081 00083 virtual 00084 ~OctreeLowMemBase (); 00085 00089 void 00090 setMaxVoxelIndex (unsigned int maxVoxelIndex_arg); 00091 00095 void 00096 setTreeDepth (unsigned int depth_arg); 00097 00101 inline unsigned int 00102 getTreeDepth () 00103 { 00104 return this->octreeDepth_; 00105 } 00106 00113 void 00114 add (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00115 const DataT& data_arg); 00116 00124 bool 00125 get (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, DataT& data_arg) const ; 00126 00133 bool 00134 existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg) const ; 00135 00141 void 00142 removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg); 00143 00147 inline unsigned int 00148 getLeafCount () const 00149 { 00150 return leafCount_; 00151 } 00152 00156 inline unsigned int 00157 getBranchCount () const 00158 { 00159 return branchCount_; 00160 } 00161 00164 void 00165 deleteTree ( ); 00166 00171 void 00172 serializeTree (std::vector<char>& binaryTreeOut_arg, bool doXOREncoding_arg = false); 00173 00179 void 00180 serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg, 00181 bool doXOREncoding_arg = false); 00182 00186 void 00187 serializeLeafs (std::vector<DataT>& dataVector_arg); 00188 00193 void 00194 deserializeTree (std::vector<char>& binaryTreeIn_arg, bool doXORDecoding_arg = false); 00195 00201 void 00202 deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg, 00203 bool doXORDecoding_arg = false); 00204 00209 void 00210 deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg); 00211 00213 void 00214 switchBuffers () 00215 { 00216 this->deleteTree (); 00217 } 00218 00219 protected: 00220 00222 00226 00227 class OctreeKey 00228 { 00229 public: 00230 00234 bool 00235 operator == (const OctreeKey& b) const 00236 { 00237 return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z)); 00238 } 00239 00240 // Indices addressing a voxel at (X, Y, Z) 00241 unsigned int x; 00242 unsigned int y; 00243 unsigned int z; 00244 }; 00245 00247 00251 00252 class OctreeBranch : public OctreeNode 00253 { 00254 // OctreeBase is a friend! 00255 friend class OctreeLowMemBase; 00256 00257 public: 00258 00260 OctreeBranch () 00261 { 00262 // initialize 00263 occupancyByte_ = 0; 00264 this->reset(); 00265 } 00266 00268 void 00269 reset () 00270 { 00271 // if pointers to childs exist, we delete them 00272 if (occupancyByte_) 00273 delete[] subNodes_; 00274 00275 // reset occupancy byte 00276 occupancyByte_ = 0; 00277 } 00278 00280 virtual 00281 ~OctreeBranch () 00282 { 00283 } 00284 00288 virtual node_type_t 00289 getNodeType () const 00290 { 00291 return BRANCH_NODE; 00292 } 00293 00294 private: 00295 00296 unsigned char occupancyByte_; 00297 OctreeNode** subNodes_; 00298 00299 }; 00300 00301 typedef LeafT OctreeLeaf; 00302 00304 // Protected octree methods based on octree keys 00306 00308 const OctreeNode* 00309 getRootNode () const 00310 { 00311 return this->rootNode_; 00312 } 00313 00319 virtual bool 00320 genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const 00321 { 00322 // this class cannot relate DataT objects to octree keys 00323 return false; 00324 } 00325 00331 virtual bool 00332 genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const 00333 { 00334 // this class cannot relate DataT objects to octree keys 00335 return false; 00336 } 00337 00344 inline void 00345 genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, 00346 OctreeKey & key_arg) const 00347 { 00348 // copy data to octree key class 00349 key_arg.x = idxX_arg; 00350 key_arg.y = idxY_arg; 00351 key_arg.z = idxZ_arg; 00352 } 00353 00358 inline void 00359 add (const OctreeKey& key_arg, const DataT& data_arg) 00360 { 00361 // request a (new) leaf from tree 00362 LeafT* leaf = getLeaf (key_arg); 00363 00364 // assign data to leaf 00365 if (leaf) 00366 { 00367 leaf->setData (data_arg); 00368 objectCount_++; 00369 } 00370 } 00371 00376 void 00377 add (const std::vector<OctreeKey>& key_vector_arg, const std::vector<DataT>& data_vector_arg); 00378 00383 inline LeafT* 00384 findLeaf (const OctreeKey& key_arg) const 00385 { 00386 return findLeafRecursive (key_arg, depthMask_, rootNode_); 00387 } 00388 00394 inline LeafT* 00395 getLeaf (const OctreeKey& key_arg) 00396 { 00397 return getLeafRecursive (key_arg, depthMask_, rootNode_); 00398 } 00399 00404 inline bool 00405 existLeaf (const OctreeKey& key_arg) const 00406 { 00407 return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0); 00408 } 00409 00413 inline void 00414 removeLeaf (const OctreeKey& key_arg) 00415 { 00416 deleteLeafRecursive (key_arg, depthMask_, rootNode_); 00417 } 00418 00420 // Branch node accessor inline functions 00422 00428 inline const OctreeNode* 00429 getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00430 { 00431 // check if branch child exists according to occupancyBtye 00432 if (branch_arg.occupancyByte_ & (1 << childIdx_arg)) 00433 { 00434 unsigned int c, idx; 00435 00436 // retrieve array index of child pointer 00437 idx = 0; 00438 for (c = 0; c < childIdx_arg; c++) 00439 { 00440 if (branch_arg.occupancyByte_ & (1 << c)) 00441 idx++; 00442 } 00443 00444 return branch_arg.subNodes_[idx]; 00445 00446 } 00447 00448 return 0; 00449 } 00450 00456 inline bool 00457 branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const 00458 { 00459 // test occupancyByte for child existence 00460 return (branch_arg.occupancyByte_ & (1 << childIdx_arg)); 00461 } 00462 00467 inline char 00468 getBranchBitPattern (const OctreeBranch& branch_arg) const 00469 { 00470 return branch_arg.occupancyByte_; 00471 } 00472 00478 inline void 00479 setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeNode * newChild_arg) 00480 { 00481 00482 if (!(branch_arg.occupancyByte_ & (1 << childIdx_arg))) 00483 { 00484 // branch child does not exists 00485 unsigned int c, idx, total; 00486 00487 // retrieve total amount of child pointers and retrieve index of new child pointer 00488 idx = 0; 00489 total = 0; 00490 for (c = 0; c < 8; c++) 00491 { 00492 if (branch_arg.occupancyByte_ & (1 << c)) 00493 { 00494 if (c < childIdx_arg) 00495 idx++; 00496 00497 total++; 00498 } 00499 } 00500 00501 if (newChild_arg != 0) 00502 { 00503 // a new child pointer is to be added to child array 00504 00505 // allocate new pointer array 00506 OctreeNode** newNodes = new OctreeNode*[total + 1]; 00507 00508 // copy pointers to new pointer array 00509 memcpy (&newNodes[0], &branch_arg.subNodes_[0], idx * sizeof(OctreeNode*)); 00510 newNodes[idx] = newChild_arg; 00511 memcpy (&newNodes[idx + 1], &branch_arg.subNodes_[idx], (total - idx) * sizeof(OctreeNode*)); 00512 00513 // delete old pointer array 00514 if (total > 0) 00515 delete[] branch_arg.subNodes_; 00516 00517 // set new child pointer array 00518 branch_arg.subNodes_ = newNodes; 00519 00520 // update occupancyByte 00521 branch_arg.occupancyByte_ |= (1 << childIdx_arg); 00522 } 00523 00524 } 00525 else 00526 { 00527 // child pointer already exists 00528 unsigned int c, idx, total; 00529 00530 // pointer set to 0 -> delete child pointer 00531 if (newChild_arg == 0) 00532 { 00533 00534 // retrieve total amount of child pointers and detect index of child pointer to be removed 00535 idx = 0; 00536 total = 0; 00537 for (c = 0; c < 8; c++) 00538 { 00539 if (branch_arg.occupancyByte_ & (1 << c)) 00540 { 00541 if (c < childIdx_arg) 00542 idx++; 00543 00544 total++; 00545 } 00546 } 00547 00548 if (total == 1) 00549 { 00550 // if only a single pointer exists, simply delete the data structure 00551 delete[] branch_arg.subNodes_; 00552 00553 branch_arg.subNodes_ = 0; 00554 branch_arg.occupancyByte_ = 0; 00555 } 00556 else 00557 { 00558 // allocate new pointer array with reduced size 00559 OctreeNode** newNodes = new OctreeNode*[total - 1]; 00560 00561 // copy old pointer references to new array 00562 memcpy (&newNodes[0], &branch_arg.subNodes_[0], idx * sizeof(OctreeNode*)); 00563 memcpy (&newNodes[idx], &branch_arg.subNodes_[idx + 1], (total - (idx + 1)) * sizeof(OctreeNode*)); 00564 00565 // delete previous pointer array and update "branch_arg.subNodes_" 00566 delete[] branch_arg.subNodes_; 00567 branch_arg.subNodes_ = newNodes; 00568 00569 // update occupancyByte by removing the corresponding bit 00570 branch_arg.occupancyByte_ &= ~(1 << childIdx_arg); 00571 00572 } 00573 00574 } 00575 else 00576 { 00577 // update existing child pointer 00578 00579 // retrieve index of child pointer to be updated 00580 idx = 0; 00581 for (c = 0; c < childIdx_arg; c++) 00582 { 00583 if (branch_arg.occupancyByte_ & (1 << c)) 00584 { 00585 idx++; 00586 } 00587 } 00588 00589 // update pointer 00590 branch_arg.subNodes_[idx] = newChild_arg; 00591 } 00592 00593 } 00594 00595 } 00596 00601 inline void 00602 deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg) 00603 { 00604 if (branchHasChild (branch_arg, childIdx_arg)) 00605 { 00606 const OctreeNode* branchChild; 00607 branchChild = getBranchChild (branch_arg, childIdx_arg); 00608 00609 switch (branchChild->getNodeType ()) 00610 { 00611 case BRANCH_NODE: 00612 // free child branch recursively 00613 deleteBranch (*(OctreeBranch*)branchChild); 00614 00615 break; 00616 00617 case LEAF_NODE: 00618 00619 break; 00620 } 00621 00622 // delete branch child 00623 delete (branchChild); 00624 00625 // set branch child pointer to 0 00626 setBranchChild (branch_arg, childIdx_arg, 0); 00627 } 00628 } 00629 00633 inline void 00634 deleteBranch (OctreeBranch& branch_arg) 00635 { 00636 char i; 00637 00638 // delete all branch node children 00639 for (i = 0; i < 8; i++) 00640 { 00641 deleteBranchChild (branch_arg, i); 00642 } 00643 } 00644 00648 inline void 00649 createBranch (OctreeBranch*& newBranchChild_arg) 00650 { 00651 00652 // we need to create a new octree branch class 00653 newBranchChild_arg = (OctreeBranch*)new OctreeBranch (); 00654 00655 } 00656 00662 inline void 00663 createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, 00664 OctreeBranch*& newBranchChild_arg) 00665 { 00666 createBranch (newBranchChild_arg); 00667 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg); 00668 } 00669 00675 inline void 00676 createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg) 00677 { 00678 00679 // we need to create a new octree leaf class 00680 newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf (); 00681 newLeafChild_arg->reset(); 00682 00683 setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg); 00684 00685 } 00686 00690 inline void 00691 branchReset (OctreeBranch& branch_arg) 00692 { 00693 branch_arg.reset(); 00694 } 00695 00696 00698 // Recursive octree methods 00700 00701 00708 LeafT* 00709 getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00710 00718 LeafT* 00719 findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const; 00720 00727 bool 00728 deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg); 00729 00735 void 00736 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, const OctreeKey& key_arg); 00737 00744 void 00745 serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, 00746 const OctreeKey& key_arg, typename std::vector<DataT>& dataVector_arg); 00747 00753 void 00754 serializeLeafsRecursive (const OctreeBranch* branch_arg, const OctreeKey& key_arg, 00755 typename std::vector<DataT>& dataVector_arg); 00756 00763 void 00764 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00765 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg); 00766 00775 void 00776 deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00777 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg, 00778 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00779 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00780 00788 void 00789 deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg, 00790 OctreeBranch* branch_arg, const unsigned int depthMask_arg, 00791 const OctreeKey& key_arg, 00792 typename std::vector<DataT>& dataVector_arg); 00793 00795 // Serialization callbacks 00797 00802 virtual void 00803 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00804 00810 virtual void 00811 serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg); 00812 00817 virtual void 00818 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg); 00819 00826 virtual void 00827 deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, 00828 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg, 00829 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg); 00830 00836 virtual void 00837 deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg, 00838 std::vector<DataT>& dataVector_arg); 00839 00841 // Helpers 00843 00848 inline double 00849 Log2 (double n_arg) 00850 { 00851 return log( n_arg ) / log( 2.0 ); 00852 } 00853 00857 inline bool 00858 octreeCanResize () 00859 { 00860 return (true); 00861 } 00862 00864 // Globals 00866 00868 unsigned int leafCount_; 00869 00871 unsigned int branchCount_; 00872 00874 unsigned int objectCount_; 00875 00877 OctreeBranch* rootNode_; 00878 00880 unsigned int depthMask_; 00881 00883 unsigned int octreeDepth_; 00884 00886 std::vector<OctreeBranch*> unusedBranchesPool_; 00887 00889 std::vector<LeafT*> unusedLeafsPool_; 00890 00891 }; 00892 } 00893 } 00894 00895 //#include "impl/octree_base.hpp" 00896 00897 #endif 00898
1.7.6.1