Point Cloud Library (PCL)  1.5.1
 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 4702 2012-02-23 09:39:33Z gedikli $
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   {
00053 
00054 
00056 
00063 
00064     template<typename DataT, typename LeafT = OctreeLeafDataT<DataT>, typename OctreeBranchT = OctreeBranch >
00065     class OctreeBase
00066     {
00067 
00068       // iterators are friends
00069       friend class OctreeIteratorBase<DataT, LeafT, OctreeBase> ;
00070       friend class OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> ;
00071       friend class OctreeBreadthFirstIterator<DataT, LeafT, OctreeBase> ;
00072       friend class OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> ;
00073 
00074     public:
00075       typedef OctreeBranchT OctreeBranch;
00076 
00077       // Octree iterators
00078       typedef OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> Iterator;
00079       typedef const OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> ConstIterator;
00080 
00081       typedef OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> LeafNodeIterator;
00082       typedef const OctreeLeafNodeIterator<DataT, LeafT, OctreeBase> ConstLeafNodeIterator;
00083 
00084       typedef OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> DepthFirstIterator;
00085       typedef const OctreeDepthFirstIterator<DataT, LeafT, OctreeBase> ConstDepthFirstIterator;
00086       typedef OctreeBreadthFirstIterator<DataT, LeafT, OctreeBase> BreadthFirstIterator;
00087       typedef const OctreeBreadthFirstIterator<DataT, LeafT, OctreeBase> ConstBreadthFirstIterator;
00088 
00090       OctreeBase ();
00091 
00093       virtual
00094       ~OctreeBase ();
00095 
00097       OctreeBase (const OctreeBase& source)
00098       {
00099         leafCount_ = source.leafCount_;
00100         branchCount_ = source.branchCount_;
00101         objectCount_ = source.objectCount_;
00102         rootNode_ = new (OctreeBranch) (*(source.rootNode_));
00103         depthMask_ = source.depthMask_;
00104         octreeDepth_ = source.octreeDepth_;
00105       }
00106 
00110       void
00111       setMaxVoxelIndex (unsigned int maxVoxelIndex_arg);
00112 
00116       void
00117       setTreeDepth (unsigned int depth_arg);
00118 
00122       inline unsigned int
00123       getTreeDepth () const
00124       {
00125         return this->octreeDepth_;
00126       }
00127 
00134       void
00135       add (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg,
00136            const DataT& data_arg);
00137 
00145       bool
00146       get (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, DataT& data_arg) const ;
00147 
00154       bool
00155       existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg) const ;
00156 
00162       void
00163       removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg);
00164 
00168       inline unsigned int
00169       getLeafCount () const
00170       {
00171         return leafCount_;
00172       }
00173 
00177       inline unsigned int
00178       getBranchCount () const
00179       {
00180         return branchCount_;
00181       }
00182 
00186       void
00187       deleteTree ( bool freeMemory_arg = false );
00188 
00192       void
00193       serializeTree (std::vector<char>& binaryTreeOut_arg);
00194 
00199       void
00200       serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg);
00201 
00205       void
00206       serializeLeafs (std::vector<DataT>& dataVector_arg);
00207 
00211       void
00212       deserializeTree (std::vector<char>& binaryTreeIn_arg);
00213 
00218       void
00219       deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg);
00220 
00225       void
00226       deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg);
00227 
00228     protected:
00229 
00231 
00235 
00236       class OctreeKey
00237       {
00238       public:
00239 
00243         bool
00244         operator == (const OctreeKey& b) const
00245         {
00246           return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z));
00247         }
00248 
00249         // Indices addressing a voxel at (X, Y, Z)
00250         unsigned int x;unsigned int y;unsigned int z;
00251       };
00252 
00253       typedef LeafT OctreeLeaf;
00254       
00256       // Protected octree methods based on octree keys
00258 
00260       const OctreeNode*
00261       getRootNode () const
00262       {
00263         return this->rootNode_;
00264       }
00265 
00271       virtual bool
00272       genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const
00273       {
00274         // this class cannot relate DataT objects to octree keys
00275         return false;
00276       }
00277 
00283       virtual bool
00284       genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const
00285       {
00286         // this class cannot relate DataT objects to octree keys
00287         return false;
00288       }
00289 
00296       inline void
00297       genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg,
00298                             OctreeKey & key_arg) const
00299       {
00300         // copy data to octree key class
00301         key_arg.x = idxX_arg;
00302         key_arg.y = idxY_arg;
00303         key_arg.z = idxZ_arg;
00304       }
00305 
00310       inline void
00311       add (const OctreeKey& key_arg, const DataT& data_arg)
00312       {
00313         // request a (new) leaf from tree
00314         LeafT* leaf = getLeaf (key_arg);
00315 
00316         // assign data to leaf
00317         if (leaf)
00318         {
00319           leaf->setData (data_arg);
00320           objectCount_++;
00321         }
00322       }
00323 
00328       inline LeafT*
00329       findLeaf (const OctreeKey& key_arg) const
00330       {
00331         return findLeafRecursive (key_arg, depthMask_, rootNode_);
00332       }
00333 
00339       inline LeafT*
00340       getLeaf (const OctreeKey& key_arg)
00341       {
00342         return getLeafRecursive (key_arg, depthMask_, rootNode_);
00343       }
00344 
00349       inline bool
00350       existLeaf (const OctreeKey& key_arg) const
00351       {
00352         return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0);
00353       }
00354 
00358       inline void
00359       removeLeaf (const OctreeKey& key_arg)
00360       {
00361         deleteLeafRecursive (key_arg, depthMask_, rootNode_);
00362       }
00363 
00365       // Branch node accessor inline functions
00367 
00373       inline const OctreeNode*
00374       getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const
00375       {
00376         return branch_arg[childIdx_arg];
00377       }
00378 
00384       inline OctreeBranch*
00385       getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg)
00386       {
00387         return (OctreeBranch*)branch_arg[childIdx_arg];
00388       }
00389 
00395       inline bool
00396       branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const
00397       {
00398         return (branch_arg[childIdx_arg] != 0);
00399       }
00400 
00405       inline char
00406       getBranchBitPattern (const OctreeBranch& branch_arg) const
00407       {
00408         unsigned char i;
00409         char nodeBits;
00410 
00411         // create bit pattern
00412         nodeBits = 0;
00413         for (i = 0; i < 8; i++)
00414         {
00415           nodeBits |= (!!branch_arg[i]) << i;
00416         }
00417 
00418         return nodeBits;
00419       }
00420        
00426       inline void
00427       setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, const OctreeNode * newChild_arg)
00428       {
00429         branch_arg[childIdx_arg] = newChild_arg;
00430       }
00431 
00436       inline void
00437       deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg)
00438       {
00439         if (branchHasChild (branch_arg, childIdx_arg))
00440         {
00441           const OctreeNode* branchChild;
00442           branchChild = getBranchChild (branch_arg, childIdx_arg);
00443           
00444           switch (branchChild->getNodeType ())
00445           {
00446             case BRANCH_NODE:
00447             {
00448               // free child branch recursively
00449               deleteBranch (*(OctreeBranch*)branchChild);
00450               // push unused branch to branch pool
00451               unusedBranchesPool_.push_back ((OctreeBranch*)branchChild);
00452             }
00453             break;
00454 
00455             case LEAF_NODE:
00456               // push unused leaf to branch pool
00457               unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild);
00458               break;
00459               
00460             default:
00461               break;
00462           }
00463 
00464           // set branch child pointer to 0
00465           setBranchChild (branch_arg, childIdx_arg, 0);
00466         }
00467       }
00468 
00472       inline void
00473       deleteBranch (OctreeBranch& branch_arg)
00474       {
00475         char i;
00476 
00477         // delete all branch node children
00478         for (i = 0; i < 8; i++)
00479         {
00480           deleteBranchChild (branch_arg, i);
00481         }
00482       }
00483 
00487       inline void
00488       createBranch (OctreeBranch*& newBranchChild_arg)
00489       {
00490         if (!unusedBranchesPool_.size ())
00491         {
00492           // branch pool is empty
00493           // we need to create a new octree branch class
00494           newBranchChild_arg = (OctreeBranch*)new OctreeBranch ();
00495         }
00496         else
00497         {
00498           // reuse branch from branch pool
00499           newBranchChild_arg = unusedBranchesPool_.back ();
00500           unusedBranchesPool_.pop_back ();
00501           branchReset (*newBranchChild_arg);
00502         }
00503       }
00504 
00510       inline void
00511       createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg,
00512                          OctreeBranch*& newBranchChild_arg)
00513       {
00514         createBranch ( newBranchChild_arg );
00515         setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg);
00516       }
00517 
00523       inline void
00524       createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg)
00525       {
00526 
00527         if (!unusedLeafsPool_.size ())
00528         {
00529           // leaf pool is empty
00530           // we need to create a new octree leaf class
00531           newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf ();
00532         }
00533         else
00534         {
00535           // reuse leaf node from branch pool
00536           newLeafChild_arg = unusedLeafsPool_.back ();
00537           unusedLeafsPool_.pop_back ();
00538         }
00539 
00540         newLeafChild_arg->reset ();
00541 
00542         setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg);
00543       }
00544 
00548       inline void
00549       branchReset (OctreeBranch& branch_arg)
00550       {
00551         branch_arg.reset ();
00552       }
00553 
00556       inline void
00557       poolCleanUp ()
00558       {
00559         // delete all branch instances from branch pool
00560         while (!unusedBranchesPool_.empty ())
00561         {
00562           delete (unusedBranchesPool_.back ());
00563           unusedBranchesPool_.pop_back ();
00564         }
00565 
00566         // delete all leaf instances from leaf pool
00567         while (!unusedLeafsPool_.empty ())
00568         {
00569           delete (unusedLeafsPool_.back ());
00570           unusedLeafsPool_.pop_back ();
00571         }
00572       }
00573 
00575       // Recursive octree methods
00577 
00584       LeafT*
00585       getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg);
00586 
00594       LeafT*
00595       findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const;
00596 
00603       bool
00604       deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg);
00605 
00611       void
00612       serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg, const OctreeKey& key_arg);
00613 
00620       void
00621       serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, const OctreeBranch* branch_arg,
00622                               const OctreeKey& key_arg, typename std::vector<DataT>& dataVector_arg);
00623 
00629       void
00630       serializeLeafsRecursive (const OctreeBranch* branch_arg, const OctreeKey& key_arg,
00631                                typename std::vector<DataT>& dataVector_arg);
00632 
00639       void
00640       deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00641                                 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg);
00642 
00651       void
00652       deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00653                                 OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg,
00654                                 typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00655                                 typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg);
00656 
00664       void
00665       deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00666                                                  OctreeBranch* branch_arg, const unsigned int depthMask_arg,
00667                                                  const OctreeKey& key_arg,
00668                                                  typename std::vector<DataT>& dataVector_arg);
00669 
00671       // Serialization callbacks
00673 
00678       virtual void
00679       serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg);
00680 
00686       virtual void
00687       serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg);
00688 
00693       virtual void
00694       deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg);
00695 
00702       virtual void
00703       deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
00704                                typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00705                                typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg);
00706 
00712       virtual void
00713       deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg,
00714                                                std::vector<DataT>& dataVector_arg);
00715 
00717       // Helpers
00719 
00724       inline double
00725       Log2 (double n_arg)
00726       {
00727         return log( n_arg ) / log( 2.0 );
00728       }
00729 
00733       inline bool
00734       octreeCanResize ()
00735       {
00736         return (true);
00737       }
00738 
00740       // Globals
00742 
00744       unsigned int leafCount_;
00745 
00747       unsigned int branchCount_;
00748 
00750       unsigned int objectCount_;
00751 
00753       OctreeBranch* rootNode_;
00754 
00756       unsigned int depthMask_;
00757 
00759       unsigned int octreeDepth_;
00760 
00762       std::vector<OctreeBranch*> unusedBranchesPool_;
00763 
00765       std::vector<LeafT*> unusedLeafsPool_;
00766 
00767       };
00768   }
00769 }
00770 
00771 //#include "impl/octree_base.hpp"
00772 
00773 #endif
00774