Point Cloud Library (PCL)  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree_base.h
Go to the documentation of this file.
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 3749 2011-12-31 22:58:01Z rusu $
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   {
00054 
00061 
00062     template<typename DataT, typename LeafT = OctreeLeafDataT<DataT> >
00063       class OctreeBase
00064       {
00065 
00066         friend class OctreeNodeIterator<DataT, LeafT, OctreeBase> ;
00067         friend class OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> ;
00068 
00069       public:
00070 
00071         // Octree iterators
00072         typedef OctreeNodeIterator<DataT, LeafT, OctreeBase> Iterator;
00073         typedef const OctreeNodeIterator<DataT, LeafT, OctreeBase> ConstIterator;
00074 
00075         // Octree iterators
00076         typedef OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> LeafNodeIterator;
00077         typedef const OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> ConstLeafNodeIterator;
00078 
00080         OctreeBase ();
00081 
00083         virtual
00084         ~OctreeBase ();
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 () const
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 
00165         void
00166         deleteTree ( bool freeMemory_arg = false );
00167 
00171         void
00172         serializeTree (std::vector<char>& binaryTreeOut_arg);
00173 
00178         void
00179         serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg);
00180 
00184         void
00185         serializeLeafs (std::vector<DataT>& dataVector_arg);
00186 
00190         void
00191         deserializeTree (std::vector<char>& binaryTreeIn_arg);
00192 
00197         void
00198         deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg);
00199 
00204         void
00205         deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg);
00206 
00207       protected:
00208 
00210 
00214 
00215         class OctreeKey
00216         {
00217         public:
00218 
00222           bool
00223           operator == (const OctreeKey& b) const
00224           {
00225             return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z));
00226           }
00227 
00228           // Indices addressing a voxel at (X, Y, Z)
00229           unsigned int x;unsigned int y;unsigned int z;
00230         };
00231 
00233 
00237 
00238         class OctreeBranch : public OctreeNode
00239         {
00240           // OctreeBase is a friend!
00241           friend class OctreeBase;
00242 
00243         public:
00244 
00246           OctreeBranch ()
00247           {
00248             memset (this->subNodes_, 0, sizeof(this->subNodes_));
00249           }
00250 
00252           virtual
00253           ~OctreeBranch ()
00254           {
00255           }
00256 
00260           virtual node_type_t
00261           getNodeType () const
00262           {
00263             return BRANCH_NODE;
00264           }
00265 
00266         private:
00267 
00269           const OctreeNode * subNodes_[8];
00270 
00271         };
00272 
00273         typedef LeafT OctreeLeaf;
00274 
00276         // Protected octree methods based on octree keys
00278 
00279 
00281         const OctreeNode*
00282         getRootNode () const
00283         {
00284           return this->rootNode_;
00285         }
00286 
00292         virtual bool
00293         genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const
00294         {
00295           // this class cannot relate DataT objects to octree keys
00296           return false;
00297         }
00298 
00304         virtual bool
00305         genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const
00306         {
00307           // this class cannot relate DataT objects to octree keys
00308           return false;
00309         }
00310 
00317         inline void
00318         genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg,
00319                               OctreeKey & key_arg) const
00320         {
00321           // copy data to octree key class
00322           key_arg.x = idxX_arg;
00323           key_arg.y = idxY_arg;
00324           key_arg.z = idxZ_arg;
00325         }
00326 
00331         inline void
00332         add (const OctreeKey& key_arg, const DataT& data_arg)
00333         {
00334           // request a (new) leaf from tree
00335           LeafT* leaf = getLeaf (key_arg);
00336 
00337           // assign data to leaf
00338           if (leaf)
00339           {
00340             leaf->setData (data_arg);
00341             objectCount_++;
00342           }
00343         }
00344 
00349         void
00350         add (const std::vector<OctreeKey>& key_vector_arg, const std::vector<DataT>& data_vector_arg);
00351 
00356         inline LeafT*
00357         findLeaf (const OctreeKey& key_arg) const
00358         {
00359           return findLeafRecursive (key_arg, depthMask_, rootNode_);
00360         }
00361 
00367         inline LeafT*
00368         getLeaf (const OctreeKey& key_arg)
00369         {
00370           return getLeafRecursive (key_arg, depthMask_, rootNode_);
00371         }
00372 
00377         inline bool
00378         existLeaf (const OctreeKey& key_arg) const
00379         {
00380           return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0);
00381         }
00382 
00386         inline void
00387         removeLeaf (const OctreeKey& key_arg)
00388         {
00389           deleteLeafRecursive (key_arg, depthMask_, rootNode_);
00390         }
00391 
00393         // Branch node accessor inline functions
00395 
00401         inline const OctreeNode*
00402         getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const
00403         {
00404           return branch_arg.subNodes_[childIdx_arg];
00405         }
00406 
00412         inline bool
00413         branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const
00414         {
00415           return (branch_arg.subNodes_[childIdx_arg] != 0);
00416         }
00417 
00422         inline char
00423         getBranchBitPattern (const OctreeBranch& branch_arg) const
00424         {
00425           unsigned char i;
00426           char nodeBits;
00427 
00428           // create bit pattern
00429           nodeBits = 0;
00430           for (i = 0; i < 8; i++)
00431           {
00432             nodeBits |= (!!branch_arg.subNodes_[i]) << i;
00433           }
00434 
00435           return nodeBits;
00436         }
00437 
00443         inline void
00444         setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, const OctreeNode * newChild_arg)
00445         {
00446           branch_arg.subNodes_[childIdx_arg] = newChild_arg;
00447         }
00448 
00453         inline void
00454         deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg)
00455         {
00456           if (branchHasChild (branch_arg, childIdx_arg))
00457           {
00458             const OctreeNode* branchChild;
00459             branchChild = getBranchChild (branch_arg, childIdx_arg);
00460 
00461             switch (branchChild->getNodeType ())
00462             {
00463               case BRANCH_NODE:
00464                 // free child branch recursively
00465                 deleteBranch (*(OctreeBranch*)branchChild);
00466 
00467                 // push unused branch to branch pool
00468                 unusedBranchesPool_.push_back ((OctreeBranch*)branchChild);
00469                 break;
00470 
00471               case LEAF_NODE:
00472 
00473                 // push unused leaf to branch pool
00474                 unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild);
00475                 break;
00476             }
00477 
00478             // set branch child pointer to 0
00479             setBranchChild (branch_arg, childIdx_arg, 0);
00480           }
00481         }
00482 
00486         inline void
00487         deleteBranch (OctreeBranch& branch_arg)
00488         {
00489           char i;
00490 
00491           // delete all branch node children
00492           for (i = 0; i < 8; i++)
00493           {
00494             deleteBranchChild (branch_arg, i);
00495           }
00496         }
00497 
00501         inline void
00502         createBranch (OctreeBranch*& newBranchChild_arg)
00503         {
00504           if (!unusedBranchesPool_.size ())
00505           {
00506             // branch pool is empty
00507             // we need to create a new octree branch class
00508             newBranchChild_arg = (OctreeBranch*)new OctreeBranch ();
00509           }
00510           else
00511           {
00512             // reuse branch from branch pool
00513             newBranchChild_arg = unusedBranchesPool_.back ();
00514             unusedBranchesPool_.pop_back ();
00515             branchReset (*newBranchChild_arg);
00516           }
00517         }
00518 
00524         inline void
00525         createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg,
00526                            OctreeBranch*& newBranchChild_arg)
00527         {
00528           createBranch ( newBranchChild_arg );
00529           setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg);
00530         }
00531 
00532 
00538         inline void
00539         createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg)
00540         {
00541 
00542           if (!unusedLeafsPool_.size ())
00543           {
00544             // leaf pool is empty
00545             // we need to create a new octree leaf class
00546             newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf ();
00547           }
00548           else
00549           {
00550             // reuse leaf node from branch pool
00551             newLeafChild_arg = unusedLeafsPool_.back ();
00552             unusedLeafsPool_.pop_back ();
00553           }
00554 
00555           newLeafChild_arg->reset ();
00556 
00557           setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg);
00558 
00559         }
00560 
00564         inline void
00565         branchReset (OctreeBranch& branch_arg)
00566         {
00567           memset (branch_arg.subNodes_, 0, sizeof(branch_arg.subNodes_));
00568         }
00569 
00572         inline void
00573         poolCleanUp ()
00574         {
00575           // delete all branch instances from branch pool
00576           while (!unusedBranchesPool_.empty ())
00577           {
00578             delete (unusedBranchesPool_.back ());
00579             unusedBranchesPool_.pop_back ();
00580           }
00581 
00582           // delete all leaf instances from leaf pool
00583           while (!unusedLeafsPool_.empty ())
00584           {
00585             delete (unusedLeafsPool_.back ());
00586             unusedLeafsPool_.pop_back ();
00587           }
00588         }
00589 
00591         // Recursive octree methods
00593 
00594 
00601         LeafT*
00602         getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg);
00603 
00611         LeafT*
00612         findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const;
00613 
00620         bool
00621         deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg);
00622 
00628         void
00629         serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, const OctreeKey& key_arg);
00630 
00637         void
00638         serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg,
00639                                 const OctreeKey& key_arg, typename std::vector<DataT>& dataVector_arg);
00640 
00646         void
00647         serializeLeafsRecursive (const OctreeBranch* branch_arg, const OctreeKey& key_arg,
00648                                  typename std::vector<DataT>& dataVector_arg);
00649 
00656         void
00657         deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00658                                   OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg);
00659 
00668         void
00669         deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00670                                   OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg,
00671                                   typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00672                                   typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg);
00673 
00681         void
00682         deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00683                                                    OctreeBranch* branch_arg, const unsigned int depthMask_arg,
00684                                                    const OctreeKey& key_arg,
00685                                                    typename std::vector<DataT>& dataVector_arg);
00686 
00688         // Serialization callbacks
00690 
00695         virtual void
00696         serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg);
00697 
00703         virtual void
00704         serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg);
00705 
00710         virtual void
00711         deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg);
00712 
00719         virtual void
00720         deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
00721                                  typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00722                                  typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg);
00723 
00729         virtual void
00730         deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg,
00731                                                  std::vector<DataT>& dataVector_arg);
00732 
00734         // Helpers
00736 
00741         inline double
00742         Log2 (double n_arg)
00743         {
00744            return log( n_arg ) / log( 2.0 );
00745         }
00746 
00750         inline bool
00751         octreeCanResize ()
00752         {
00753           return (true);
00754         }
00755 
00757         // Globals
00759 
00761         unsigned int leafCount_;
00762 
00764         unsigned int branchCount_;
00765 
00767         unsigned int objectCount_;
00768 
00770         OctreeBranch* rootNode_;
00771 
00773         unsigned int depthMask_;
00774 
00776         unsigned int octreeDepth_;
00777 
00779         std::vector<OctreeBranch*> unusedBranchesPool_;
00780 
00782         std::vector<LeafT*> unusedLeafsPool_;
00783 
00784       };
00785   }
00786 }
00787 
00788 //#include "impl/octree_base.hpp"
00789 
00790 #endif
00791 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines