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