|
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-2012, 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 6201 2012-07-06 11:53:17Z jkammerl $ 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 #include "octree_container.h" 00046 #include "octree_key.h" 00047 #include "octree_iterator.h" 00048 #include "octree_node_pool.h" 00049 00050 #include <stdio.h> 00051 #include <string.h> 00052 00053 namespace pcl 00054 { 00055 namespace octree 00056 { 00057 00058 template<typename ContainerT> 00059 class BufferedBranchNode : public OctreeNode, ContainerT 00060 { 00061 using ContainerT::getSize; 00062 using ContainerT::getData; 00063 using ContainerT::setData; 00064 00065 public: 00067 BufferedBranchNode () : OctreeNode(), ContainerT(), preBuf(0xFFFFFF), postBuf(0xFFFFFF) 00068 { 00069 reset (); 00070 } 00071 00073 BufferedBranchNode (const BufferedBranchNode& source) : ContainerT(source) 00074 { 00075 *this = source; 00076 } 00077 00079 inline BufferedBranchNode& 00080 operator = (const BufferedBranchNode &source_arg) 00081 { 00082 00083 unsigned char i, b; 00084 00085 memset (childNodeArray_, 0, sizeof(childNodeArray_)); 00086 00087 for (b = 0; b < 2; ++b) 00088 for (i = 0; i < 8; ++i) 00089 if (source_arg.childNodeArray_[b][i]) 00090 childNodeArray_[b][i] = source_arg.childNodeArray_[b][i]->deepCopy (); 00091 00092 return (*this); 00093 00094 } 00095 00097 virtual ~BufferedBranchNode () 00098 { 00099 } 00100 00102 virtual BufferedBranchNode* 00103 deepCopy () const 00104 { 00105 return new BufferedBranchNode (*this); 00106 } 00107 00113 inline OctreeNode* 00114 getChildPtr (unsigned char buffer_arg, unsigned char index_arg) const 00115 { 00116 assert( (buffer_arg<2) && (index_arg<8)); 00117 return childNodeArray_[buffer_arg][index_arg]; 00118 } 00119 00125 inline void setChildPtr (unsigned char buffer_arg, unsigned char index_arg, 00126 OctreeNode* newNode_arg) 00127 { 00128 assert( (buffer_arg<2) && (index_arg<8)); 00129 childNodeArray_[buffer_arg][index_arg] = newNode_arg; 00130 } 00131 00137 inline bool hasChild (unsigned char buffer_arg, unsigned char index_arg) const 00138 { 00139 assert( (buffer_arg<2) && (index_arg<8)); 00140 return (childNodeArray_[buffer_arg][index_arg] != 0); 00141 } 00142 00144 virtual node_type_t getNodeType () const 00145 { 00146 return BRANCH_NODE; 00147 } 00148 00150 inline void reset () 00151 { 00152 memset (&childNodeArray_[0][0], 0, sizeof(OctreeNode*) * 8 * 2); 00153 ContainerT::reset (); 00154 } 00155 00156 protected: 00157 int preBuf; 00158 OctreeNode* childNodeArray_[2][8]; 00159 int postBuf; 00160 00161 }; 00162 00176 template<typename DataT, typename LeafT = OctreeContainerDataT<DataT>, 00177 typename BranchT = OctreeContainerEmpty<DataT> > 00178 class Octree2BufBase 00179 { 00180 00181 public: 00182 00183 typedef Octree2BufBase<DataT, LeafT, BranchT> OctreeT; 00184 00185 // iterators are friends 00186 friend class OctreeIteratorBase<DataT, OctreeT> ; 00187 friend class OctreeDepthFirstIterator<DataT, OctreeT> ; 00188 friend class OctreeBreadthFirstIterator<DataT, OctreeT> ; 00189 friend class OctreeLeafNodeIterator<DataT, OctreeT> ; 00190 00191 typedef BufferedBranchNode<BranchT> BranchNode; 00192 typedef OctreeLeafNode<LeafT> LeafNode; 00193 00194 // Octree iterators 00195 typedef OctreeDepthFirstIterator<DataT, OctreeT> Iterator; 00196 typedef const OctreeDepthFirstIterator<DataT, OctreeT> ConstIterator; 00197 00198 typedef OctreeLeafNodeIterator<DataT, OctreeT> LeafNodeIterator; 00199 typedef const OctreeLeafNodeIterator<DataT, OctreeT> ConstLeafNodeIterator; 00200 00201 typedef OctreeDepthFirstIterator<DataT, OctreeT> DepthFirstIterator; 00202 typedef const OctreeDepthFirstIterator<DataT, OctreeT> ConstDepthFirstIterator; 00203 typedef OctreeBreadthFirstIterator<DataT, OctreeT> BreadthFirstIterator; 00204 typedef const OctreeBreadthFirstIterator<DataT, OctreeT> ConstBreadthFirstIterator; 00205 00207 Octree2BufBase (); 00208 00210 virtual 00211 ~Octree2BufBase (); 00212 00214 Octree2BufBase (const Octree2BufBase& source) : 00215 leafCount_ (source.leafCount_), branchCount_ (source.branchCount_), objectCount_ ( 00216 source.objectCount_), rootNode_ ( 00217 new (BranchNode) (* (source.rootNode_))), depthMask_ ( 00218 source.depthMask_), maxKey_ (source.maxKey_), branchNodePool_ (), leafNodePool_ (), bufferSelector_ ( 00219 source.bufferSelector_), treeDirtyFlag_ (source.treeDirtyFlag_), octreeDepth_ ( 00220 source.octreeDepth_) 00221 { 00222 } 00223 00225 inline Octree2BufBase& 00226 operator = (const Octree2BufBase& source) 00227 { 00228 leafCount_ = source.leafCount_; 00229 branchCount_ = source.branchCount_; 00230 objectCount_ = source.objectCount_; 00231 rootNode_ = new (BranchNode) (* (source.rootNode_)); 00232 depthMask_ = source.depthMask_; 00233 maxKey_ = source.maxKey_; 00234 bufferSelector_ = source.bufferSelector_; 00235 treeDirtyFlag_ = source.treeDirtyFlag_; 00236 octreeDepth_ = source.octreeDepth_; 00237 return (*this); 00238 } 00239 00243 void 00244 setMaxVoxelIndex (unsigned int maxVoxelIndex_arg); 00245 00249 void 00250 setTreeDepth (unsigned int depth_arg); 00251 00255 inline unsigned int getTreeDepth () const 00256 { 00257 return this->octreeDepth_; 00258 } 00259 00266 void 00267 addData (unsigned int idxX_arg, unsigned int idxY_arg, 00268 unsigned int idxZ_arg, const DataT& data_arg); 00269 00277 bool 00278 getData (unsigned int idxX_arg, unsigned int idxY_arg, 00279 unsigned int idxZ_arg, DataT& data_arg) const; 00280 00287 bool 00288 existLeaf (unsigned int idxX_arg, unsigned int idxY_arg, 00289 unsigned int idxZ_arg) const; 00290 00296 void 00297 removeLeaf (unsigned int idxX_arg, unsigned int idxY_arg, 00298 unsigned int idxZ_arg); 00299 00303 inline unsigned int getLeafCount () const 00304 { 00305 return (static_cast<unsigned int> (leafCount_)); 00306 } 00307 00311 inline unsigned int getBranchCount () const 00312 { 00313 return (static_cast<unsigned int> (branchCount_)); 00314 } 00315 00319 void 00320 deleteTree (bool freeMemory_arg = false); 00321 00323 inline void deletePreviousBuffer () 00324 { 00325 treeCleanUpRecursive (rootNode_); 00326 } 00327 00329 inline void deleteCurrentBuffer () 00330 { 00331 bufferSelector_ = !bufferSelector_; 00332 treeCleanUpRecursive (rootNode_); 00333 leafCount_ = 0; 00334 } 00335 00337 void 00338 switchBuffers (); 00339 00344 void 00345 serializeTree (std::vector<char>& binaryTreeOut_arg, 00346 bool doXOREncoding_arg = false); 00347 00353 void 00354 serializeTree (std::vector<char>& binaryTreeOut_arg, 00355 std::vector<DataT>& dataVector_arg, bool doXOREncoding_arg = false); 00356 00360 void 00361 serializeLeafs (std::vector<DataT>& dataVector_arg); 00362 00367 void 00368 serializeNewLeafs (std::vector<DataT>& dataVector_arg, 00369 const int minPointsPerLeaf_arg = 0); 00370 00375 void 00376 deserializeTree (std::vector<char>& binaryTreeIn_arg, 00377 bool doXORDecoding_arg = false); 00378 00384 void 00385 deserializeTree (std::vector<char>& binaryTreeIn_arg, 00386 std::vector<DataT>& dataVector_arg, bool doXORDecoding_arg = false); 00387 00388 protected: 00389 00391 // Protected octree methods based on octree keys 00393 00395 OctreeNode* 00396 getRootNode () const 00397 { 00398 return (this->rootNode_); 00399 } 00400 00406 virtual bool genOctreeKeyForDataT (const DataT &, OctreeKey &) const 00407 { 00408 // this class cannot relate DataT objects to octree keys 00409 return (false); 00410 } 00411 00417 virtual bool genDataTByOctreeKey (const OctreeKey &, DataT &) const 00418 { 00419 // this class cannot relate DataT objects to octree keys 00420 return (false); 00421 } 00422 00427 inline void addData (const OctreeKey& key_arg, const DataT& data_arg) 00428 { 00429 // request a (new) leaf from tree 00430 LeafT* leaf = createLeaf (key_arg); 00431 00432 // assign data to leaf 00433 if (leaf) 00434 { 00435 leaf->setData (data_arg); 00436 objectCount_++; 00437 } 00438 } 00439 00444 inline LeafT* 00445 findLeaf (const OctreeKey& key_arg) const 00446 { 00447 return findLeafRecursive (key_arg, depthMask_, rootNode_); 00448 } 00449 00455 inline LeafT* 00456 createLeaf (const OctreeKey& key_arg) 00457 { 00458 LeafT* result; 00459 00460 result = createLeafRecursive (key_arg, depthMask_, rootNode_, false); 00461 00462 // getLeafRecursive has changed the octree -> clean-up/tree-reset might be required 00463 treeDirtyFlag_ = true; 00464 00465 return result; 00466 } 00467 00472 inline bool existLeaf (const OctreeKey& key_arg) const 00473 { 00474 return ( (key_arg <= maxKey_) 00475 && (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0)); 00476 } 00477 00481 inline void removeLeaf (const OctreeKey& key_arg) 00482 { 00483 if (key_arg <= maxKey_) 00484 { 00485 deleteLeafRecursive (key_arg, depthMask_, rootNode_); 00486 00487 // we changed the octree structure -> dirty 00488 treeDirtyFlag_ = true; 00489 } 00490 } 00491 00493 // Branch node accessor inline functions 00495 00501 inline bool 00502 branchHasChild (const BranchNode& branch_arg, unsigned char childIdx_arg) const 00503 { 00504 // test occupancyByte for child existence 00505 return (branch_arg.getChildPtr(bufferSelector_, childIdx_arg) != 0); 00506 } 00507 00513 inline OctreeNode* 00514 getBranchChildPtr (const BranchNode& branch_arg, 00515 unsigned char childIdx_arg) const 00516 { 00517 return branch_arg.getChildPtr(bufferSelector_, childIdx_arg); 00518 } 00519 00525 inline void setBranchChildPtr (BranchNode& branch_arg, 00526 unsigned char childIdx_arg, OctreeNode* newChild_arg) 00527 { 00528 branch_arg.setChildPtr(bufferSelector_, childIdx_arg, newChild_arg); 00529 } 00530 00535 inline void getDataFromOctreeNode (const OctreeNode* node_arg, 00536 DataT& data_arg) 00537 { 00538 if (node_arg->getNodeType () == LEAF_NODE) 00539 { 00540 const LeafT* leafContainer = dynamic_cast<const LeafT*> (node_arg); 00541 leafContainer->getData (data_arg); 00542 } 00543 else 00544 { 00545 const BranchT* branchContainer = 00546 dynamic_cast<const BranchT*> (node_arg); 00547 branchContainer->getData (data_arg); 00548 } 00549 } 00550 00555 inline void getDataFromOctreeNode (const OctreeNode* node_arg, 00556 std::vector<DataT>& data_arg) 00557 { 00558 if (node_arg->getNodeType () == LEAF_NODE) 00559 { 00560 const LeafT* leafContainer = dynamic_cast<const LeafT*> (node_arg); 00561 leafContainer->getData (data_arg); 00562 } 00563 else 00564 { 00565 const BranchT* branchContainer = 00566 dynamic_cast<const BranchT*> (node_arg); 00567 branchContainer->getData (data_arg); 00568 } 00569 } 00570 00575 inline size_t getDataSizeFromOctreeNode (const OctreeNode* node_arg) 00576 { 00577 size_t nodeSize; 00578 if (node_arg->getNodeType () == LEAF_NODE) 00579 { 00580 const LeafT* leafContainer = dynamic_cast<const LeafT*> (node_arg); 00581 nodeSize = leafContainer->getSize (); 00582 } 00583 else 00584 { 00585 const BranchT* branchContainer = 00586 dynamic_cast<const BranchT*> (node_arg); 00587 nodeSize = branchContainer->getSize (); 00588 } 00589 return nodeSize; 00590 } 00591 00596 inline char getBranchBitPattern (const BranchNode& branch_arg) const 00597 { 00598 unsigned char i; 00599 char nodeBits; 00600 00601 // create bit pattern 00602 nodeBits = 0; 00603 for (i = 0; i < 8; i++) 00604 { 00605 nodeBits |= static_cast<char> ( (!!branch_arg.getChildPtr ( 00606 bufferSelector_, i)) << i); 00607 } 00608 00609 return (nodeBits); 00610 } 00611 00617 inline char getBranchBitPattern (const BranchNode& branch_arg, 00618 unsigned char bufferSelector_arg) const 00619 { 00620 unsigned char i; 00621 char nodeBits; 00622 00623 // create bit pattern 00624 nodeBits = 0; 00625 for (i = 0; i < 8; i++) 00626 { 00627 nodeBits |= static_cast<char> ( (!!branch_arg.getChildPtr ( 00628 bufferSelector_arg, i)) << i); 00629 } 00630 00631 return (nodeBits); 00632 } 00633 00638 inline char getBranchXORBitPattern ( 00639 const BranchNode& branch_arg) const 00640 { 00641 unsigned char i; 00642 char nodeBits[2]; 00643 00644 // create bit pattern for both buffers 00645 nodeBits[0] = nodeBits[1] = 0; 00646 00647 for (i = 0; i < 8; i++) 00648 { 00649 nodeBits[0] |= static_cast<char> ( (!!branch_arg.getChildPtr (0, i)) 00650 << i); 00651 nodeBits[1] |= static_cast<char> ( (!!branch_arg.getChildPtr (1, i)) 00652 << i); 00653 } 00654 00655 return nodeBits[0] ^ nodeBits[1]; 00656 } 00657 00662 inline bool hasBranchChanges (const BranchNode& branch_arg) const 00663 { 00664 return (getBranchXORBitPattern (branch_arg) > 0); 00665 } 00666 00672 inline void deleteBranchChild (BranchNode& branch_arg, 00673 unsigned char bufferSelector_arg, 00674 unsigned char childIdx_arg) 00675 { 00676 if (branch_arg.hasChild(bufferSelector_arg, childIdx_arg)) 00677 { 00678 OctreeNode* branchChild = branch_arg.getChildPtr(bufferSelector_arg, childIdx_arg); 00679 00680 switch (branchChild->getNodeType ()) 00681 { 00682 case BRANCH_NODE: 00683 { 00684 // free child branch recursively 00685 deleteBranch (*static_cast<BranchNode*> (branchChild)); 00686 00687 // push unused branch to branch pool 00688 branchNodePool_.pushNode ( 00689 static_cast<BranchNode*> (branchChild)); 00690 break; 00691 } 00692 00693 case LEAF_NODE: 00694 { 00695 // push unused leaf to branch pool 00696 leafNodePool_.pushNode( 00697 static_cast<LeafNode*> (branchChild)); 00698 break; 00699 } 00700 default: 00701 break; 00702 } 00703 00704 // set branch child pointer to 0 00705 branch_arg.setChildPtr(bufferSelector_arg, childIdx_arg, 0); 00706 } 00707 } 00708 00712 inline void deleteBranch (BranchNode& branch_arg) 00713 { 00714 char i; 00715 00716 // delete all branch node children 00717 for (i = 0; i < 8; i++) 00718 { 00719 00720 if (branch_arg.getChildPtr(0, i) == branch_arg.getChildPtr(1, i)) 00721 { 00722 // reference was copied - there is only one child instance to be deleted 00723 deleteBranchChild (branch_arg, 0, i); 00724 00725 // remove pointers from both buffers 00726 branch_arg.setChildPtr(0, i, 0); 00727 branch_arg.setChildPtr(1, i, 0); 00728 } 00729 else 00730 { 00731 deleteBranchChild (branch_arg, 0, i); 00732 deleteBranchChild (branch_arg, 1, i); 00733 } 00734 } 00735 } 00736 00742 inline void createBranchChild (BranchNode& branch_arg, 00743 unsigned char childIdx_arg, BranchNode*& newBranchChild_arg) 00744 { 00745 00746 newBranchChild_arg = branchNodePool_.popNode(); 00747 00748 branch_arg.setChildPtr (bufferSelector_, childIdx_arg, 00749 static_cast<OctreeNode*> (newBranchChild_arg)); 00750 } 00751 00757 inline void createLeafChild (BranchNode& branch_arg, 00758 unsigned char childIdx_arg, LeafNode*& newLeafChild_arg) 00759 { 00760 newLeafChild_arg = leafNodePool_.popNode(); 00761 00762 branch_arg.setChildPtr(bufferSelector_, childIdx_arg, newLeafChild_arg); 00763 } 00764 00767 inline void poolCleanUp () 00768 { 00769 branchNodePool_.deletePool(); 00770 leafNodePool_.deletePool(); 00771 } 00772 00774 // Recursive octree methods 00776 00784 LeafT* 00785 createLeafRecursive (const OctreeKey& key_arg, 00786 unsigned int depthMask_arg, BranchNode* branch_arg, 00787 bool branchReset_arg); 00788 00796 LeafT* 00797 findLeafRecursive (const OctreeKey& key_arg, unsigned int depthMask_arg, 00798 BranchNode* branch_arg) const; 00799 00806 bool 00807 deleteLeafRecursive (const OctreeKey& key_arg, 00808 unsigned int depthMask_arg, BranchNode* branch_arg); 00809 00819 void 00820 serializeTreeRecursive (BranchNode* branch_arg, OctreeKey& key_arg, 00821 std::vector<char>* binaryTreeOut_arg, 00822 typename std::vector<DataT>* dataVector_arg, bool doXOREncoding_arg = false, 00823 bool newLeafsFilter_arg = false, std::size_t minPointsPerLeaf_arg = 0); 00824 00835 void 00836 deserializeTreeRecursive (BranchNode* branch_arg, 00837 unsigned int depthMask_arg, OctreeKey& key_arg, 00838 typename std::vector<char>::const_iterator& binaryTreeIT_arg, 00839 typename std::vector<char>::const_iterator& binaryTreeIT_End_arg, 00840 typename std::vector<DataT>::const_iterator* dataVectorIterator_arg, 00841 typename std::vector<DataT>::const_iterator* dataVectorEndIterator_arg, 00842 bool branchReset_arg = false, bool doXORDecoding_arg = false); 00843 00844 00846 // Serialization callbacks 00848 00851 virtual void serializeTreeCallback (LeafNode &, const OctreeKey &) 00852 { 00853 00854 } 00855 00858 virtual void deserializeTreeCallback (LeafNode&, const OctreeKey&) 00859 { 00860 00861 } 00862 00864 // Helpers 00866 00870 void 00871 treeCleanUpRecursive (BranchNode* branch_arg); 00872 00877 inline double Log2 (double n_arg) 00878 { 00879 return log (n_arg) / log (2.0); 00880 } 00881 00885 inline bool octreeCanResize () 00886 { 00887 return (false); 00888 } 00889 00893 inline void printBinary (char data_arg) 00894 { 00895 unsigned char mask = 1; // Bit mask 00896 00897 // Extract the bits 00898 for (int i = 0; i < 8; i++) 00899 { 00900 // Mask each bit in the byte and print it 00901 std::cout << ((data_arg & (mask << i)) ? "1" : "0"); 00902 } 00903 std::cout << std::endl; 00904 } 00905 00907 // Globals 00909 00911 std::size_t leafCount_; 00912 00914 std::size_t branchCount_; 00915 00917 std::size_t objectCount_; 00918 00920 BranchNode* rootNode_; 00921 00923 unsigned int depthMask_; 00924 00926 OctreeKey maxKey_; 00927 00929 OctreeNodePool<BranchNode> branchNodePool_; 00930 00932 OctreeNodePool<LeafNode> leafNodePool_; 00933 00935 unsigned char bufferSelector_; 00936 00937 // flags indicating if unused branches and leafs might exist in previous buffer 00938 bool treeDirtyFlag_; 00939 00941 unsigned int octreeDepth_; 00942 }; 00943 } 00944 } 00945 00946 //#include "impl/octree2buf_base.hpp" 00947 00948 #endif 00949
1.7.6.1