Point Cloud Library (PCL)  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree2buf_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: octree2buf_base.h 3749 2011-12-31 22:58:01Z rusu $
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 
00046 #include "octree_iterator.h"
00047 
00048 namespace pcl
00049 {
00050   namespace octree
00051   {
00065     template<typename DataT, typename LeafT = OctreeLeafDataT<DataT> >
00066     class Octree2BufBase
00067       {
00068 
00069         friend class OctreeNodeIterator<DataT, LeafT, Octree2BufBase> ;
00070         friend class OctreeLeafNodeIterator<DataT, LeafT, Octree2BufBase> ;
00071 
00072       public:
00073 
00074         // Octree iterators
00075         typedef OctreeNodeIterator<DataT, LeafT, Octree2BufBase> Iterator;
00076         typedef const OctreeNodeIterator<DataT, LeafT, Octree2BufBase> ConstIterator;
00077 
00078         // Octree iterators
00079         typedef OctreeLeafNodeIterator<DataT, LeafT, Octree2BufBase> LeafNodeIterator;
00080         typedef const OctreeLeafNodeIterator<DataT, LeafT, Octree2BufBase> ConstLeafNodeIterator;
00081 
00083         Octree2BufBase ();
00084 
00086         virtual
00087         ~Octree2BufBase ();
00088 
00092         void
00093         setMaxVoxelIndex (unsigned int maxVoxelIndex_arg);
00094 
00098         void
00099         setTreeDepth (unsigned int depth_arg);
00100 
00104         inline unsigned int
00105         getTreeDepth ()
00106         {
00107           return this->octreeDepth_;
00108         }
00109 
00116         void
00117         add (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg,
00118              const DataT& data_arg);
00119 
00127         bool
00128         get (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg, DataT& data_arg) const ;
00129 
00136         bool
00137         existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg) const ;
00138 
00144         void
00145         removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg);
00146 
00150         inline unsigned int
00151         getLeafCount () const
00152         {
00153           return leafCount_;
00154         }
00155 
00159         inline unsigned int
00160         getBranchCount () const
00161         {
00162           return branchCount_;
00163         }
00164 
00168         void
00169         deleteTree ( bool freeMemory_arg = false );
00170 
00172         inline void
00173         deletePreviousBuffer ()
00174         {
00175           treeCleanUpRecursive (rootNode_);
00176         }
00177 
00179         inline void
00180         deleteCurrentBuffer ()
00181         {
00182           bufferSelector_ = !bufferSelector_;
00183           treeCleanUpRecursive (rootNode_);
00184           leafCount_ = 0;
00185         }
00186 
00188         void
00189         switchBuffers ();
00190 
00195         void
00196         serializeTree (std::vector<char>& binaryTreeOut_arg, bool doXOREncoding_arg = false);
00197 
00203         void
00204         serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg,
00205                        bool doXOREncoding_arg = false);
00206 
00210         void
00211         serializeLeafs (std::vector<DataT>& dataVector_arg);
00212 
00217         void
00218         serializeNewLeafs (std::vector<DataT>& dataVector_arg, const int minPointsPerLeaf_arg = 0);
00219 
00224         void
00225         deserializeTree (std::vector<char>& binaryTreeIn_arg, bool doXORDecoding_arg = false);
00226 
00232         void
00233         deserializeTree (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg,
00234                          bool doXORDecoding_arg = false);
00235 
00241         void
00242         deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg, std::vector<DataT>& dataVector_arg,
00243                                           bool doXORDecoding_arg = false);
00244 
00245       protected:
00246 
00248 
00252 
00253         class OctreeKey
00254         {
00255         public:
00256 
00260           bool
00261           operator == (const OctreeKey& b) const
00262           {
00263             return ((b.x == this->x) && (b.y == this->y) && (b.z == this->z));
00264           }
00265 
00266           // Indices addressing a voxel at (X, Y, Z)
00267           unsigned int x;unsigned int y;unsigned int z;
00268         };
00269 
00271 
00275 
00276         class OctreeBranch : public OctreeNode
00277         {
00278 
00279           // Octree2BufBase is a friend!
00280           friend class Octree2BufBase;
00281 
00282         public:
00283 
00285           OctreeBranch ()
00286           {
00287             memset (this->subNodes_, 0, sizeof(this->subNodes_));
00288           }
00289 
00291           virtual
00292           ~OctreeBranch ()
00293           {
00294           }
00295 
00299           virtual node_type_t
00300           getNodeType () const
00301           {
00302             return BRANCH_NODE;
00303           }
00304 
00305         private:
00306 
00308           const OctreeNode * subNodes_[2][8];
00309 
00310         };
00311 
00312         typedef LeafT OctreeLeaf;
00313 
00315         // Protected octree methods based on octree keys
00317 
00319         const OctreeNode*
00320         getRootNode () const
00321         {
00322           return this->rootNode_;
00323         }
00324 
00330         virtual bool
00331         genOctreeKeyForDataT (const DataT& data_arg, OctreeKey & key_arg) const
00332         {
00333           // this class cannot relate DataT objects to octree keys
00334           return false;
00335         }
00336 
00342         virtual bool
00343         genDataTByOctreeKey (const OctreeKey & key_arg, DataT& data_arg) const
00344         {
00345           // this class cannot relate DataT objects to octree keys
00346           return false;
00347         }
00348 
00355         inline void
00356         genOctreeKeyByIntIdx (const unsigned int idxX_arg, const unsigned int idxY_arg, const unsigned int idxZ_arg,
00357                               OctreeKey & key_arg) const
00358         {
00359           // copy data to octree key class
00360           key_arg.x = idxX_arg;
00361           key_arg.y = idxY_arg;
00362           key_arg.z = idxZ_arg;
00363         }
00364 
00369         inline void
00370         add (const OctreeKey& key_arg, const DataT& data_arg)
00371         {
00372           // request a (new) leaf from tree
00373           LeafT* leaf = getLeaf (key_arg);
00374 
00375           // assign data to leaf
00376           if (leaf)
00377           {
00378             leaf->setData (data_arg);
00379             objectCount_++;
00380           }
00381         }
00382 
00387         inline LeafT*
00388         findLeaf (const OctreeKey& key_arg) const
00389         {
00390           return findLeafRecursive (key_arg, depthMask_, rootNode_);
00391         }
00392 
00398         inline LeafT*
00399         getLeaf (const OctreeKey& key_arg)
00400         {
00401           LeafT* result;
00402 
00403           result = getLeafRecursive (key_arg, depthMask_, rootNode_, resetTree_);
00404 
00405           // getLeafRecursive has changed the octree -> clean-up/tree-reset might be required
00406           resetTree_ = false;
00407           treeDirtyFlag_ = true;
00408 
00409           return result;
00410         }
00411 
00416         inline bool
00417         existLeaf (const OctreeKey& key_arg) const
00418         {
00419           return (findLeafRecursive (key_arg, depthMask_, rootNode_) != 0);
00420         }
00421 
00425         inline void
00426         removeLeaf (const OctreeKey& key_arg)
00427         {
00428           deleteLeafRecursive (key_arg, depthMask_, rootNode_);
00429 
00430           // we changed the octree structure -> dirty
00431           treeDirtyFlag_ = true;
00432         }
00433 
00435         // Branch node accessor inline functions
00437 
00438 
00444         inline const OctreeNode*
00445         getBranchChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const
00446         {
00447           return branch_arg.subNodes_[bufferSelector_][childIdx_arg];
00448         }
00449 
00456         inline const OctreeNode*
00457         getBranchChild (const OctreeBranch& branch_arg, const unsigned char bufferSelector_arg,
00458                         const unsigned char childIdx_arg) const
00459         {
00460           return branch_arg.subNodes_[bufferSelector_arg][childIdx_arg];
00461         }
00462 
00468         inline bool
00469         branchHasChild (const OctreeBranch& branch_arg, const unsigned char childIdx_arg) const
00470         {
00471           return (branch_arg.subNodes_[bufferSelector_][childIdx_arg] != 0);
00472         }
00473 
00480         inline bool
00481         branchHasChild (const OctreeBranch& branch_arg, const unsigned char bufferSelector_arg,
00482                         const unsigned char childIdx_arg) const
00483         {
00484           return (branch_arg.subNodes_[bufferSelector_arg][childIdx_arg] != 0);
00485 
00486         }
00487 
00492         inline char
00493         getBranchBitPattern (const OctreeBranch& branch_arg) const
00494         {
00495           unsigned char i;
00496           char nodeBits;
00497 
00498           // create bit pattern
00499           nodeBits = 0;
00500           for (i = 0; i < 8; i++)
00501           {
00502             nodeBits |= (!!branch_arg.subNodes_[bufferSelector_][i]) << i;
00503           }
00504 
00505           return nodeBits;
00506         }
00507 
00513         inline char
00514         getBranchBitPattern (const OctreeBranch& branch_arg, const unsigned char bufferSelector_arg) const
00515         {
00516           unsigned char i;
00517           char nodeBits;
00518 
00519           // create bit pattern
00520           nodeBits = 0;
00521           for (i = 0; i < 8; i++)
00522           {
00523             nodeBits |= (!!branch_arg.subNodes_[bufferSelector_arg][i]) << i;
00524           }
00525 
00526           return nodeBits;
00527         }
00528 
00533         inline char
00534         getBranchXORBitPattern (const OctreeBranch& branch_arg) const
00535         {
00536           unsigned char i;
00537           char nodeBits[2];
00538 
00539           // create bit pattern for both buffers
00540           nodeBits[0] = nodeBits[1] = 0;
00541 
00542           for (i = 0; i < 8; i++)
00543           {
00544             nodeBits[0] |= (!!branch_arg.subNodes_[0][i]) << i;
00545             nodeBits[1] |= (!!branch_arg.subNodes_[1][i]) << i;
00546           }
00547 
00548           return nodeBits[0] ^ nodeBits[1];
00549         }
00550 
00555         inline bool
00556         hasBranchChanges (const OctreeBranch& branch_arg) const
00557         {
00558           return (getBranchXORBitPattern (branch_arg) > 0);
00559         }
00560 
00566         inline void
00567         setBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, const OctreeNode * newChild_arg)
00568         {
00569           branch_arg.subNodes_[bufferSelector_][childIdx_arg] = newChild_arg;
00570         }
00571 
00578         inline void
00579         setBranchChild (OctreeBranch& branch_arg, const unsigned char bufferSelector_arg,
00580                         const unsigned char childIdx_arg, const OctreeNode * newChild_arg)
00581         {
00582           branch_arg.subNodes_[bufferSelector_arg][childIdx_arg] = newChild_arg;
00583         }
00584 
00589         inline void
00590         deleteBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg)
00591         {
00592           if (branchHasChild (branch_arg, childIdx_arg))
00593           {
00594             const OctreeNode* branchChild;
00595             branchChild = getBranchChild (branch_arg, childIdx_arg);
00596 
00597             switch (branchChild->getNodeType ())
00598             {
00599               case BRANCH_NODE:
00600                 // free child branch recursively
00601                 deleteBranch (*(OctreeBranch*)branchChild);
00602 
00603                 // push unused branch to branch pool
00604                 unusedBranchesPool_.push_back ((OctreeBranch*)branchChild);
00605                 break;
00606 
00607               case LEAF_NODE:
00608 
00609                 // push unused leaf to branch pool
00610                 unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild);
00611                 break;
00612             }
00613 
00614             // set branch child pointer to 0
00615             setBranchChild (branch_arg, childIdx_arg, 0);
00616           }
00617         }
00618 
00624         inline void
00625         deleteBranchChild (OctreeBranch& branch_arg, const unsigned char bufferSelector_arg,
00626                            const unsigned char childIdx_arg)
00627         {
00628           if (branchHasChild (branch_arg, bufferSelector_arg, childIdx_arg))
00629           {
00630             const OctreeNode* branchChild;
00631             branchChild = getBranchChild (branch_arg, bufferSelector_arg, childIdx_arg);
00632 
00633             switch (branchChild->getNodeType ())
00634             {
00635               case BRANCH_NODE:
00636                 // free child branch recursively
00637                 deleteBranch (*(OctreeBranch*)branchChild);
00638 
00639                 // push unused branch to branch pool
00640                 unusedBranchesPool_.push_back ((OctreeBranch*)branchChild);
00641                 break;
00642 
00643               case LEAF_NODE:
00644 
00645                 // push unused leaf to branch pool
00646                 unusedLeafsPool_.push_back ((OctreeLeaf*)branchChild);
00647                 break;
00648             }
00649 
00650             // set branch child pointer to 0
00651             setBranchChild (branch_arg, bufferSelector_arg, childIdx_arg, 0);
00652 
00653           }
00654         }
00655 
00659         inline void
00660         deleteBranch (OctreeBranch& branch_arg)
00661         {
00662           char i;
00663 
00664           // delete all branch node children
00665           for (i = 0; i < 8; i++)
00666           {
00667 
00668             if (getBranchChild (branch_arg, 0, i) == getBranchChild (branch_arg, 1, i))
00669             {
00670               // reference was copied - there is only one child instance to be deleted
00671               deleteBranchChild (branch_arg, 0, i);
00672 
00673               // remove pointers from both buffers
00674               setBranchChild (branch_arg, 0, i, 0);
00675               setBranchChild (branch_arg, 1, i, 0);
00676 
00677             }
00678             else
00679             {
00680               deleteBranchChild (branch_arg, 0, i);
00681               deleteBranchChild (branch_arg, 1, i);
00682             }
00683           }
00684         }
00685 
00691         inline void
00692         createBranchChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg,
00693                            OctreeBranch*& newBranchChild_arg)
00694         {
00695           if (!unusedBranchesPool_.size ())
00696           {
00697             newBranchChild_arg = (OctreeBranch*)new OctreeBranch ();
00698           }
00699           else
00700           {
00701             newBranchChild_arg = unusedBranchesPool_.back ();
00702             unusedBranchesPool_.pop_back ();
00703             branchReset (*newBranchChild_arg);
00704           }
00705 
00706           setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newBranchChild_arg);
00707         }
00708 
00712         inline void
00713         createBranch (OctreeBranch*& newBranchChild_arg)
00714         {
00715 
00716           if (!unusedBranchesPool_.size ())
00717           {
00718             // branch pool is empty
00719             // we need to create a new octree branch class
00720             newBranchChild_arg = (OctreeBranch*)new OctreeBranch ();
00721           }
00722           else
00723           {
00724             // reuse branch from branch pool
00725             newBranchChild_arg = unusedBranchesPool_.back ();
00726             unusedBranchesPool_.pop_back ();
00727             branchReset (*newBranchChild_arg);
00728           }
00729         }
00730 
00736         inline void
00737         createLeafChild (OctreeBranch& branch_arg, const unsigned char childIdx_arg, OctreeLeaf*& newLeafChild_arg)
00738         {
00739           if (!unusedLeafsPool_.size ())
00740           {
00741             // leaf pool is empty
00742             // we need to create a new octree leaf class
00743             newLeafChild_arg = (OctreeLeaf*)new OctreeLeaf ();
00744           }
00745           else
00746           {
00747             // reuse leaf node from branch pool
00748             newLeafChild_arg = unusedLeafsPool_.back ();
00749             unusedLeafsPool_.pop_back ();
00750           }
00751 
00752           newLeafChild_arg->reset ();
00753 
00754           setBranchChild (branch_arg, childIdx_arg, (OctreeNode*)newLeafChild_arg);
00755         }
00756 
00760         inline void
00761         branchReset (OctreeBranch& branch_arg)
00762         {
00763           memset (branch_arg.subNodes_, 0, sizeof(branch_arg.subNodes_));
00764         }
00765 
00768         inline void
00769         poolCleanUp ()
00770         {
00771           // delete all branch instances from branch pool
00772           while (!unusedBranchesPool_.empty ())
00773           {
00774             delete (unusedBranchesPool_.back ());
00775             unusedBranchesPool_.pop_back ();
00776           }
00777 
00778           // delete all leaf instances from leaf pool
00779           while (!unusedLeafsPool_.empty ())
00780           {
00781             delete (unusedLeafsPool_.back ());
00782             unusedLeafsPool_.pop_back ();
00783           }
00784         }
00785 
00787         // Recursive octree methods
00789 
00790 
00798         LeafT*
00799         getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg,
00800                           bool branchReset_arg);
00801 
00809         LeafT*
00810         findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg) const;
00811 
00818         bool
00819         deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg, OctreeBranch* branch_arg);
00820 
00827         void
00828         serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, OctreeBranch* branch_arg, const OctreeKey& key_arg,
00829                                 bool doXOREncoding_arg);
00830 
00838         void
00839         serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg, OctreeBranch* branch_arg, const OctreeKey& key_arg,
00840                                 typename std::vector<DataT>& dataVector_arg, bool doXOREncoding_arg);
00841 
00847         void
00848         serializeLeafsRecursive (OctreeBranch* branch_arg, const OctreeKey& key_arg,
00849                                  typename std::vector<DataT>& dataVector_arg);
00850 
00857         void
00858         serializeNewLeafsRecursive (OctreeBranch* branch_arg, const OctreeKey& key_arg,
00859                                     std::vector<DataT>& dataVector_arg, const int minPointsPerLeaf_arg = 0);
00860 
00869         void
00870         deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00871                                   OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg,
00872                                   bool branchReset_arg, bool doXORDecoding_arg);
00873 
00884         void
00885         deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00886                                   OctreeBranch* branch_arg, const unsigned int depthMask_arg, const OctreeKey& key_arg,
00887                                   typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00888                                   typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg,
00889                                   bool branchReset_arg, bool doXORDecoding_arg);
00890 
00900         void
00901         deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00902                                                    OctreeBranch* branch_arg, const unsigned int depthMask_arg,
00903                                                    const OctreeKey& key_arg,
00904                                                    typename std::vector<DataT>& dataVector_arg,
00905                                                    bool branchReset_arg, bool doXORDecoding_arg);
00906 
00908         // Serialization callbacks
00910 
00915         virtual void
00916         serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg);
00917 
00923         virtual void
00924         serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, std::vector<DataT>& dataVector_arg);
00925 
00932         virtual void
00933         serializeNewLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg, const int minPointsPerLeaf_arg,
00934                                   std::vector<DataT>& dataVector_arg);
00935 
00940         virtual void
00941         deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg);
00942 
00949         virtual void
00950         deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
00951                                  typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00952                                  typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg);
00953 
00959         virtual void
00960         deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey & key_arg,
00961                                                  std::vector<DataT>& dataVector_arg);
00962 
00964         // Helpers
00966 
00970         void
00971         treeCleanUpRecursive (OctreeBranch* branch_arg);
00972 
00977         inline double
00978         Log2 (double n_arg)
00979         {
00980           return log (n_arg) / log (2.0);
00981         }
00982 
00986         inline bool
00987         octreeCanResize ()
00988         {
00989           return (false);
00990         }
00991 
00993         // Globals
00995 
00996 
00998         unsigned int leafCount_;
00999 
01001         unsigned int branchCount_;
01002 
01004         unsigned int objectCount_;
01005 
01007         OctreeBranch* rootNode_;
01008 
01010         unsigned int depthMask_;
01011 
01013         std::vector<OctreeBranch*> unusedBranchesPool_;
01014 
01016         std::vector<LeafT*> unusedLeafsPool_;
01017 
01019         unsigned char bufferSelector_;
01020 
01021         // flags indicating if unused branches and leafs might exist in previous buffer
01022         bool resetTree_;
01023         bool treeDirtyFlag_;
01024 
01026         unsigned int octreeDepth_;
01027 
01028       };
01029   }
01030 }
01031 
01032 //#include "impl/octree2buf_base.hpp"
01033 
01034 #endif
01035 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines