Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree_lowmemory_base.hpp
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.hpp 4702 2012-02-23 09:39:33Z gedikli $
00037  */
00038 
00039 #ifndef OCTREE_LOWMEM_TREE_BASE_HPP
00040 #define OCTREE_LOWMEM_TREE_BASE_HPP
00041 
00042 #include <vector>
00043 
00044 #include "pcl/impl/instantiate.hpp"
00045 #include "pcl/point_types.h"
00046 #include "pcl/octree/octree.h"
00047 
00048 namespace pcl
00049 {
00050   namespace octree
00051   {
00052 
00053     using namespace std;
00054 
00056     template<typename DataT, typename LeafT>
00057     OctreeLowMemBase<DataT, LeafT>::OctreeLowMemBase ()
00058     {
00059 
00060       // Initialization of globals
00061       rootNode_ = new OctreeBranch ();
00062       leafCount_ = 0;
00063       depthMask_ = 0;
00064       branchCount_ = 1;
00065       objectCount_ = 0;
00066       octreeDepth_ = 0;
00067 
00068     }
00069 
00071     template<typename DataT, typename LeafT>
00072     OctreeLowMemBase<DataT, LeafT>::~OctreeLowMemBase ()
00073     {
00074 
00075       // deallocate tree structure
00076       deleteTree ();
00077       delete (rootNode_);
00078     }
00079 
00081     template<typename DataT, typename LeafT>
00082     void
00083     OctreeLowMemBase<DataT, LeafT>::setMaxVoxelIndex (unsigned int maxVoxelIndex_arg)
00084     {
00085       unsigned int treeDepth;
00086 
00087       assert (maxVoxelIndex_arg>0);
00088 
00089       // tree depth == amount of bits of maxVoxels
00090       treeDepth = max ((min ((unsigned int)OCT_MAXTREEDEPTH, (unsigned int)ceil (Log2 (maxVoxelIndex_arg)))),
00091                        (unsigned int)0);
00092 
00093       // define depthMask_ by setting a single bit to 1 at bit position == tree depth
00094       depthMask_ = (1 << (treeDepth - 1));
00095 
00096     }
00097 
00099     template<typename DataT, typename LeafT>
00100     void
00101     OctreeLowMemBase<DataT, LeafT>::setTreeDepth (unsigned int depth_arg)
00102     {
00103 
00104       assert (depth_arg>0);
00105 
00106       // set octree depth
00107       octreeDepth_ = depth_arg;
00108 
00109       // define depthMask_ by setting a single bit to 1 at bit position == tree depth
00110       depthMask_ = (1 << (depth_arg - 1));
00111 
00112     }
00113 
00115     template<typename DataT, typename LeafT>
00116     void
00117     OctreeLowMemBase<DataT, LeafT>::add (const unsigned int idxX_arg, const unsigned int idxY_arg,
00118                                          const unsigned int idxZ_arg, const DataT& data_arg)
00119     {
00120 
00121       OctreeKey key;
00122 
00123       // generate key
00124       genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00125 
00126       // add data_arg to octree
00127       add (key, data_arg);
00128 
00129       objectCount_++;
00130 
00131     }
00132 
00133 
00134 
00136     template<typename DataT, typename LeafT>
00137     bool
00138     OctreeLowMemBase<DataT, LeafT>::get (const unsigned int idxX_arg, const unsigned int idxY_arg,
00139                                          const unsigned int idxZ_arg, DataT& data_arg) const
00140     {
00141       OctreeKey key;
00142 
00143       // generate key
00144       genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00145 
00146       // search for leaf at key
00147       LeafT* leaf = findLeaf (key);
00148       if (leaf)
00149       {
00150         const DataT * dataPtr;
00151         // if successful, decode data to data_arg
00152         leaf->getData (dataPtr);
00153         if (dataPtr)
00154           data_arg = *dataPtr;
00155       }
00156 
00157       // returns true on success
00158       return (leaf != 0);
00159     }
00160 
00162     template<typename DataT, typename LeafT>
00163     bool
00164     OctreeLowMemBase<DataT, LeafT>::existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg,
00165                                                const unsigned int idxZ_arg) const
00166     {
00167       OctreeKey key;
00168 
00169       // generate key
00170       this->genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00171 
00172       // check if key exist in octree
00173       return existLeaf (key);
00174     }
00175 
00177     template<typename DataT, typename LeafT>
00178     void
00179     OctreeLowMemBase<DataT, LeafT>::removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg,
00180                                                 const unsigned int idxZ_arg)
00181     {
00182       OctreeKey key;
00183 
00184       // generate key
00185       this->genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00186 
00187       // check if key exist in octree
00188       deleteLeafRecursive (key, depthMask_, rootNode_);
00189     }
00190 
00192     template<typename DataT, typename LeafT>
00193     void
00194     OctreeLowMemBase<DataT, LeafT>::deleteTree ( )
00195     {
00196 
00197       if (rootNode_)
00198       {
00199         // reset octree
00200         deleteBranch (*rootNode_);
00201         leafCount_ = 0;
00202         branchCount_ = 1;
00203         objectCount_ = 0;
00204 
00205       }
00206 
00207     }
00208 
00210     template<typename DataT, typename LeafT>
00211     void
00212     OctreeLowMemBase<DataT, LeafT>::serializeTree (std::vector<char>& binaryTreeOut_arg,
00213                                                    bool doXOREncoding_arg)
00214     {
00215       OctreeKey newKey;
00216       newKey.x = newKey.y = newKey.z = 0;
00217 
00218       // clear binary vector
00219       binaryTreeOut_arg.clear ();
00220       binaryTreeOut_arg.reserve (this->branchCount_);
00221 
00222       serializeTreeRecursive (binaryTreeOut_arg, rootNode_, newKey);
00223     }
00224 
00226     template<typename DataT, typename LeafT>
00227     void
00228     OctreeLowMemBase<DataT, LeafT>::serializeTree (std::vector<char>& binaryTreeOut_arg,
00229                                                    std::vector<DataT>& dataVector_arg, bool doXOREncoding_arg)
00230     {
00231       OctreeKey newKey;
00232       newKey.x = newKey.y = newKey.z = 0;
00233 
00234       // clear output vectors
00235       binaryTreeOut_arg.clear ();
00236       dataVector_arg.clear ();
00237 
00238       dataVector_arg.reserve (this->objectCount_);
00239       binaryTreeOut_arg.reserve (this->branchCount_);
00240 
00241       OctreeLowMemBase<DataT, LeafT>::serializeTreeRecursive (binaryTreeOut_arg, rootNode_, newKey, dataVector_arg);
00242     }
00243 
00245     template<typename DataT, typename LeafT>
00246     void
00247     OctreeLowMemBase<DataT, LeafT>::serializeLeafs (std::vector<DataT>& dataVector_arg)
00248     {
00249 
00250       OctreeKey newKey;
00251       newKey.x = newKey.y = newKey.z = 0;
00252 
00253       // clear output vector
00254       dataVector_arg.clear ();
00255 
00256       dataVector_arg.reserve(this->objectCount_);
00257 
00258       serializeLeafsRecursive (rootNode_, newKey, dataVector_arg);
00259     }
00260 
00262     template<typename DataT, typename LeafT>
00263     void
00264     OctreeLowMemBase<DataT, LeafT>::deserializeTree (std::vector<char>& binaryTreeIn_arg,
00265                                                      bool doXORDecoding_arg)
00266     {
00267 
00268       OctreeKey newKey;
00269       newKey.x = newKey.y = newKey.z = 0;
00270 
00271       // free existing tree before tree rebuild
00272       deleteTree ();
00273 
00274       //iterator for binary tree structure vector
00275       vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00276 
00277       deserializeTreeRecursive (binaryTreeVectorIterator, rootNode_, depthMask_, newKey);
00278 
00279       objectCount_ = this->leafCount_;
00280     }
00281 
00283     template<typename DataT, typename LeafT>
00284     void
00285     OctreeLowMemBase<DataT, LeafT>::deserializeTree (std::vector<char>& binaryTreeIn_arg,
00286                                                      std::vector<DataT>& dataVector_arg,
00287                                                      bool doXORDecoding_arg)
00288     {
00289       OctreeKey newKey;
00290       newKey.x = newKey.y = newKey.z = 0;
00291 
00292       // set data iterator to first element
00293       typename std::vector<DataT>::const_iterator dataVectorIterator = dataVector_arg.begin ();
00294 
00295       // set data iterator to last element
00296       typename std::vector<DataT>::const_iterator dataVectorEndIterator = dataVector_arg.end ();
00297 
00298       // free existing tree before tree rebuild
00299       deleteTree ();
00300 
00301       //iterator for binary tree structure vector
00302       vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00303 
00304       deserializeTreeRecursive (binaryTreeVectorIterator, rootNode_, depthMask_, newKey, dataVectorIterator,
00305                                 dataVectorEndIterator);
00306 
00307       objectCount_ = (unsigned int)dataVector_arg.size();
00308     }
00309 
00311     template<typename DataT, typename LeafT>
00312     void
00313     OctreeLowMemBase<DataT, LeafT>::deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg,
00314                                                                       std::vector<DataT>& dataVector_arg)
00315     {
00316 
00317       OctreeKey newKey;
00318       newKey.x = newKey.y = newKey.z = 0;
00319 
00320       // free existing tree before tree rebuild
00321       deleteTree ();
00322 
00323       //iterator for binary tree structure vector
00324       vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00325 
00326       deserializeTreeAndOutputLeafDataRecursive (binaryTreeVectorIterator, rootNode_, depthMask_, newKey,
00327                                                  dataVector_arg);
00328 
00329       objectCount_ = (unsigned int)dataVector_arg.size();
00330     }
00331 
00333     template<typename DataT, typename LeafT>
00334     LeafT*
00335     OctreeLowMemBase<DataT, LeafT>::getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg,
00336                                                       OctreeBranch* branch_arg)
00337     {
00338 
00339       // index to branch child
00340       unsigned char childIdx;
00341       LeafT* result = 0;
00342 
00343       // find branch child from key
00344       childIdx = ((!!(key_arg.x & depthMask_arg)) << 2) | ((!!(key_arg.y & depthMask_arg)) << 1) | (!!(key_arg.z
00345                                                                                                        & depthMask_arg));
00346 
00347       if (depthMask_arg > 1)
00348       {
00349         // we have not reached maximum tree depth
00350 
00351         OctreeBranch* childBranch;
00352         if (!branchHasChild (*branch_arg, childIdx))
00353         {
00354 
00355           // if required branch does not exist -> create it
00356           createBranchChild (*branch_arg, childIdx, childBranch);
00357 
00358           branchCount_++;
00359 
00360         }
00361         else
00362         {
00363 
00364           // required branch exists
00365           childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00366         }
00367 
00368         // recursively proceed with indexed child branch
00369         result = getLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00370 
00371       }
00372       else
00373       {
00374         // branch childs are leaf nodes
00375 
00376         OctreeLeaf* childLeaf;
00377         if (!branchHasChild (*branch_arg, childIdx))
00378         {
00379 
00380           // if leaf node at childIdx does not exist
00381           createLeafChild (*branch_arg, childIdx, childLeaf);
00382           leafCount_++;
00383 
00384           // return leaf node
00385           result = childLeaf;
00386 
00387         }
00388         else
00389         {
00390 
00391           // leaf node already exist
00392           childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, childIdx);
00393 
00394           // return leaf node
00395           result = childLeaf;
00396 
00397         }
00398 
00399       }
00400 
00401       return result;
00402 
00403     }
00404 
00406     template<typename DataT, typename LeafT>
00407     LeafT*
00408     OctreeLowMemBase<DataT, LeafT>::findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg,
00409                                                        OctreeBranch* branch_arg) const
00410     {
00411       // index to branch child
00412       unsigned char childIdx;
00413       LeafT* result = 0;
00414 
00415       // find branch child from key
00416       childIdx = ((!!(key_arg.x & depthMask_arg)) << 2) | ((!!(key_arg.y & depthMask_arg)) << 1) | (!!(key_arg.z
00417                                                                                                        & depthMask_arg));
00418 
00419       if (depthMask_arg > 1)
00420       {
00421         // we have not reached maximum tree depth
00422         OctreeBranch* childBranch;
00423         childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00424 
00425         if (childBranch)
00426           // recursively proceed with indexed child branch
00427           result = findLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00428 
00429       }
00430       else
00431       {
00432         // we reached leaf node level
00433         if (branchHasChild (*branch_arg, childIdx))
00434         {
00435 
00436           // return existing leaf node
00437           OctreeLeaf* childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, childIdx);
00438           result = childLeaf;
00439         }
00440 
00441       }
00442 
00443       return result;
00444 
00445     }
00446 
00448     template<typename DataT, typename LeafT>
00449     bool
00450     OctreeLowMemBase<DataT, LeafT>::deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg,
00451                                                          OctreeBranch* branch_arg)
00452     {
00453       // index to branch child
00454       unsigned char childIdx;
00455       // indicates if branch is empty and can be safely removed
00456       bool bNoChilds;
00457 
00458       // find branch child from key
00459       childIdx = ((!!(key_arg.x & depthMask_arg)) << 2) | ((!!(key_arg.y & depthMask_arg)) << 1) | (!!(key_arg.z
00460                                                                                                        & depthMask_arg));
00461 
00462       if (depthMask_arg > 1)
00463       {
00464         // we have not reached maximum tree depth
00465 
00466         OctreeBranch* childBranch;
00467         bool bBranchOccupied;
00468 
00469         // next branch child on our path through the tree
00470         childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00471 
00472         if (childBranch)
00473         {
00474           // recursively explore the indexed child branch
00475           bBranchOccupied = deleteLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00476 
00477           if (!bBranchOccupied)
00478           {
00479             // child branch does not own any sub-child nodes anymore -> delete child branch
00480             delete (childBranch);
00481             setBranchChild (*branch_arg, childIdx, 0);
00482             branchCount_--;
00483           }
00484         }
00485 
00486       }
00487       else
00488       {
00489 
00490         // our child is a leaf node -> delete it
00491         deleteBranchChild (*branch_arg, childIdx);
00492         leafCount_--;
00493       }
00494 
00495       // check if current branch still owns childs
00496       bNoChilds = false;
00497       for (childIdx = 0; childIdx < 8; childIdx++)
00498       {
00499         bNoChilds = branchHasChild (*branch_arg, childIdx);
00500         if (bNoChilds)
00501           break;
00502       }
00503 
00504       // return true if current branch can be deleted
00505       return bNoChilds;
00506 
00507     }
00508 
00510     template<typename DataT, typename LeafT>
00511     void
00512     OctreeLowMemBase<DataT, LeafT>::serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg,
00513                                                             const OctreeBranch* branch_arg, const OctreeKey& key_arg)
00514     {
00515 
00516       // child iterator
00517       unsigned char childIdx;
00518       char nodeBitPattern;
00519 
00520       // branch occupancy bit pattern
00521       nodeBitPattern = getBranchBitPattern (*branch_arg);
00522 
00523       // write bit pattern to output vector
00524       binaryTreeOut_arg.push_back (nodeBitPattern);
00525 
00526       // iterate over all children
00527       for (childIdx = 0; childIdx < 8; childIdx++)
00528       {
00529 
00530         // if child exist
00531         if (branchHasChild (*branch_arg, childIdx))
00532         {
00533 
00534           // generate new key for current branch voxel
00535           OctreeKey newKey;
00536           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00537           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00538           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00539 
00540           const OctreeNode * childNode;
00541           childNode = getBranchChild (*branch_arg, childIdx);
00542 
00543           switch (childNode->getNodeType ())
00544           {
00545             case BRANCH_NODE:
00546               // recursively proceed with indexed child branch
00547               serializeTreeRecursive (binaryTreeOut_arg, (OctreeBranch*)childNode, newKey);
00548               break;
00549             case LEAF_NODE:
00550             {
00551               OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00552               
00553               // we reached a leaf node -> execute serialization callback
00554               serializeLeafCallback (*childLeaf, newKey);
00555             }
00556             break;
00557             default:
00558             break;
00559 
00560           }
00561         }
00562       }
00563     }
00564 
00566     template<typename DataT, typename LeafT>
00567     void
00568     OctreeLowMemBase<DataT, LeafT>::serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg,
00569                                                             const OctreeBranch* branch_arg, const OctreeKey& key_arg,
00570                                                             typename std::vector<DataT>& dataVector_arg)
00571     {
00572 
00573       // child iterator
00574       unsigned char childIdx;
00575       char nodeBitPattern;
00576 
00577       // branch occupancy bit pattern
00578       nodeBitPattern = getBranchBitPattern (*branch_arg);
00579 
00580       // write bit pattern to output vector
00581       binaryTreeOut_arg.push_back (nodeBitPattern);
00582 
00583       // iterate over all children
00584       for (childIdx = 0; childIdx < 8; childIdx++)
00585       {
00586 
00587         // if child exist
00588         if (branchHasChild (*branch_arg, childIdx))
00589         {
00590 
00591           // generate new key for current branch voxel
00592           OctreeKey newKey;
00593           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00594           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00595           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00596 
00597           const OctreeNode * childNode;
00598           childNode = getBranchChild (*branch_arg, childIdx);
00599 
00600           switch (childNode->getNodeType ())
00601           {
00602             case BRANCH_NODE:
00603               
00604               // recursively proceed with indexed child branch
00605               serializeTreeRecursive (binaryTreeOut_arg, (OctreeBranch*)childNode, newKey, dataVector_arg);
00606               break;
00607 
00608             case LEAF_NODE:
00609             {
00610               OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00611               
00612               // we reached a leaf node -> execute serialization callback
00613               serializeLeafCallback (*childLeaf, newKey, dataVector_arg);
00614             }
00615               break;
00616             default:
00617               break;
00618 
00619           }
00620         }
00621       }
00622     }
00623 
00625     template<typename DataT, typename LeafT>
00626     void
00627     OctreeLowMemBase<DataT, LeafT>::serializeLeafsRecursive (const OctreeBranch* branch_arg, const OctreeKey& key_arg,
00628                                                              std::vector<DataT>& dataVector_arg)
00629     {
00630       // child iterator
00631       unsigned char childIdx;
00632 
00633       // iterate over all children
00634       for (childIdx = 0; childIdx < 8; childIdx++)
00635       {
00636 
00637         // if child exist
00638         if (branchHasChild (*branch_arg, childIdx))
00639         {
00640           const OctreeNode * childNode;
00641           childNode = getBranchChild (*branch_arg, childIdx);
00642 
00643           // generate new key for current branch voxel
00644           OctreeKey newKey;
00645           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00646           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00647           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00648 
00649           switch (childNode->getNodeType ())
00650           {
00651             case BRANCH_NODE:
00652               
00653               // recursively proceed with indexed child branch
00654               serializeLeafsRecursive ((OctreeBranch*)childNode, newKey, dataVector_arg);
00655               break;
00656 
00657             case LEAF_NODE:
00658             {
00659               OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00660 
00661               // we reached a leaf node -> execute serialization callback
00662               serializeLeafCallback (*childLeaf, newKey, dataVector_arg);
00663             }
00664             break;
00665             default:
00666               break;
00667 
00668           }
00669         }
00670       }
00671     }
00672 
00674     template<typename DataT, typename LeafT>
00675     void
00676     OctreeLowMemBase<DataT, LeafT>::deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00677                                                               OctreeBranch* branch_arg, const unsigned int depthMask_arg,
00678                                                               const OctreeKey& key_arg)
00679     {
00680       // child iterator
00681       unsigned char childIdx;
00682       char nodeBits;
00683 
00684       // read branch occupancy bit pattern from input vector
00685       nodeBits = (*binaryTreeIn_arg);
00686       binaryTreeIn_arg++;
00687 
00688       // iterate over all children
00689       for (childIdx = 0; childIdx < 8; childIdx++)
00690       {
00691         // if occupancy bit for childIdx is set..
00692         if (nodeBits & (1 << childIdx))
00693         {
00694 
00695           // generate new key for current branch voxel
00696           OctreeKey newKey;
00697           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00698           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00699           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00700 
00701           if (depthMask_arg > 1)
00702           {
00703             // we have not reached maximum tree depth
00704             OctreeBranch * newBranch;
00705 
00706             // create new child branch
00707             createBranchChild (*branch_arg, childIdx, newBranch);
00708 
00709             branchCount_++;
00710 
00711             // recursively proceed with new child branch
00712             deserializeTreeRecursive (binaryTreeIn_arg, newBranch, depthMask_arg / 2, newKey);
00713 
00714           }
00715           else
00716           {
00717             // we reached leaf node level
00718             OctreeLeaf* childLeaf;
00719 
00720             // create leaf node
00721             createLeafChild (*branch_arg, childIdx, childLeaf);
00722 
00723             // execute deserialization callback
00724             deserializeLeafCallback (*childLeaf, newKey);
00725 
00726             leafCount_++;
00727           }
00728         }
00729       }
00730 
00731     }
00732 
00734     template<typename DataT, typename LeafT>
00735     void
00736     OctreeLowMemBase<DataT, LeafT>::deserializeTreeRecursive (
00737       typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00738       OctreeBranch* branch_arg,
00739       const unsigned int depthMask_arg,
00740       const OctreeKey& key_arg,
00741       typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00742       typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg)
00743     {
00744       // child iterator
00745       unsigned char childIdx;
00746       char nodeBits;
00747 
00748       // read branch occupancy bit pattern from input vector
00749       nodeBits = (*binaryTreeIn_arg);
00750       binaryTreeIn_arg++;
00751 
00752       // iterate over all children
00753       for (childIdx = 0; childIdx < 8; childIdx++)
00754       {
00755         // if occupancy bit for childIdx is set..
00756         if (nodeBits & (1 << childIdx))
00757         {
00758           // generate new key for current branch voxel
00759           OctreeKey newKey;
00760           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00761           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00762           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00763 
00764           if (depthMask_arg > 1)
00765           {
00766             // we have not reached maximum tree depth
00767             OctreeBranch * newBranch;
00768 
00769             // create new child branch
00770             createBranchChild (*branch_arg, childIdx, newBranch);
00771 
00772             branchCount_++;
00773 
00774             // recursively proceed with new child branch
00775             deserializeTreeRecursive (binaryTreeIn_arg, newBranch, depthMask_arg / 2, newKey, dataVectorIterator_arg,
00776                                       dataVectorEndIterator_arg);
00777 
00778           }
00779           else
00780           {
00781             // we reached leaf node level
00782 
00783             OctreeLeaf* childLeaf;
00784 
00785             // create leaf node
00786             createLeafChild (*branch_arg, childIdx, childLeaf);
00787 
00788             // execute deserialization callback
00789             deserializeLeafCallback (*childLeaf, newKey, dataVectorIterator_arg, dataVectorEndIterator_arg);
00790 
00791             leafCount_++;
00792           }
00793         }
00794       }
00795     }
00796 
00798     template<typename DataT, typename LeafT>
00799     void
00800     OctreeLowMemBase<DataT, LeafT>::deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00801                                                                                OctreeBranch* branch_arg,
00802                                                                                const unsigned int depthMask_arg,
00803                                                                                const OctreeKey& key_arg,
00804                                                                                std::vector<DataT>& dataVector_arg)
00805     {
00806       // child iterator
00807       unsigned char childIdx;
00808       char nodeBits;
00809 
00810       // read branch occupancy bit pattern from input vector
00811       nodeBits = (*binaryTreeIn_arg);
00812       binaryTreeIn_arg++;
00813 
00814       // iterate over all children
00815       for (childIdx = 0; childIdx < 8; childIdx++)
00816       {
00817         // if occupancy bit for childIdx is set..
00818         if (nodeBits & (1 << childIdx))
00819         {
00820 
00821           // generate new key for current branch voxel
00822           OctreeKey newKey;
00823           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00824           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00825           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00826 
00827           if (depthMask_arg > 1)
00828           {
00829             // we have not reached maximum tree depth
00830             OctreeBranch * newBranch;
00831 
00832             // create new child branch
00833             createBranchChild (*branch_arg, childIdx, newBranch);
00834 
00835             branchCount_++;
00836 
00837             // recursively proceed with new child branch
00838             deserializeTreeAndOutputLeafDataRecursive (binaryTreeIn_arg, newBranch, depthMask_arg / 2, newKey,
00839                                                        dataVector_arg);
00840 
00841           }
00842           else
00843           {
00844             // we reached leaf node level
00845             OctreeLeaf* childLeaf;
00846 
00847             // create leaf node
00848             createLeafChild (*branch_arg, childIdx, childLeaf);
00849 
00850             // execute deserialization callback
00851             deserializeTreeAndSerializeLeafCallback (*childLeaf, newKey, dataVector_arg);
00852 
00853             leafCount_++;
00854           }
00855         }
00856       }
00857 
00858     }
00859 
00861     template<typename DataT, typename LeafT>
00862     void
00863     OctreeLowMemBase<DataT, LeafT>::serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg)
00864     {
00865       // nothing to do
00866     }
00867 
00868 
00870     template<typename DataT, typename LeafT>
00871     void
00872     OctreeLowMemBase<DataT, LeafT>::serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
00873                                                            std::vector<DataT>& dataVector_arg)
00874     {
00875       leaf_arg.getData (dataVector_arg);
00876     }
00877 
00879     template<typename DataT, typename LeafT>
00880     void
00881     OctreeLowMemBase<DataT, LeafT>::deserializeLeafCallback (
00882       OctreeLeaf& leaf_arg,
00883       const OctreeKey& key_arg,
00884       typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
00885       typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg)
00886     {
00887       OctreeKey dataKey;
00888       bool bKeyBasedEncoding = false;
00889 
00890       // add DataT objects to octree leaf as long as their key fit to voxel
00891       while ((dataVectorIterator_arg != dataVectorEndIterator_arg)
00892              && (this->genOctreeKeyForDataT (*dataVectorIterator_arg, dataKey) && (dataKey == key_arg)))
00893       {
00894         leaf_arg.setData (*dataVectorIterator_arg);
00895         dataVectorIterator_arg++;
00896         bKeyBasedEncoding = true;
00897       }
00898 
00899       // add single DataT object to octree if key-based encoding is disabled
00900       if (!bKeyBasedEncoding)
00901       {
00902         leaf_arg.setData (*dataVectorIterator_arg);
00903         dataVectorIterator_arg++;
00904       }
00905     }
00906 
00908     template<typename DataT, typename LeafT>
00909     void
00910     OctreeLowMemBase<DataT, LeafT>::deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg)
00911     {
00912 
00913       DataT newDataT;
00914 
00915       // initialize new leaf child
00916       if (genDataTByOctreeKey (key_arg, newDataT))
00917       {
00918         leaf_arg.setData (newDataT);
00919       }
00920 
00921     }
00922 
00924     template<typename DataT, typename LeafT>
00925     void
00926     OctreeLowMemBase<DataT, LeafT>::deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg,
00927                                                                              const OctreeKey& key_arg,
00928                                                                              std::vector<DataT>& dataVector_arg)
00929     {
00930 
00931       DataT newDataT;
00932 
00933       // initialize new leaf child
00934       if (genDataTByOctreeKey (key_arg, newDataT))
00935       {
00936         leaf_arg.setData (newDataT);
00937         dataVector_arg.push_back (newDataT);
00938       }
00939     }
00940 
00941   }
00942 }
00943 
00944 #define PCL_INSTANTIATE_OctreeLowMemBase(T) template class PCL_EXPORTS pcl::octree::OctreeLowMemBase<T>;
00945 
00946 #endif
00947