Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree_lowmemory_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_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