Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree2buf_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: octree2buf_base.hpp 4702 2012-02-23 09:39:33Z gedikli $
00037  */
00038 
00039 #ifndef OCTREE_2BUF_BASE_HPP
00040 #define OCTREE_2BUF_BASE_HPP
00041 
00042 namespace pcl
00043 {
00044   namespace octree
00045   {
00046 
00047     using namespace std;
00048 
00050     template<typename DataT, typename LeafT>
00051     Octree2BufBase<DataT, LeafT>::Octree2BufBase ()
00052     {
00053       // Initialization of globals
00054       rootNode_ = new OctreeBranch ();
00055       leafCount_ = 0;
00056       branchCount_ = 1;
00057       objectCount_ = 0;
00058       depthMask_ = 0;
00059       octreeDepth_ = 0;
00060       bufferSelector_ = 0;
00061       resetTree_ = false;
00062       treeDirtyFlag_ = false;
00063     }
00064 
00066     template<typename DataT, typename LeafT>
00067     Octree2BufBase<DataT, LeafT>::~Octree2BufBase ()
00068     {
00069       // deallocate tree structure
00070       deleteTree ();
00071       delete (rootNode_);
00072       poolCleanUp ();
00073     }
00074 
00076     template<typename DataT, typename LeafT>
00077     void
00078     Octree2BufBase<DataT, LeafT>::setMaxVoxelIndex (unsigned int maxVoxelIndex_arg)
00079     {
00080       unsigned int treeDepth;
00081 
00082       assert (maxVoxelIndex_arg > 0);
00083 
00084       // tree depth == amount of bits of maxVoxels
00085       treeDepth = max ((min ((unsigned int)OCT_MAXTREEDEPTH, (unsigned int)ceil (Log2 (maxVoxelIndex_arg)))),
00086                        (unsigned int)0);
00087 
00088       // define depthMask_ by setting a single bit to 1 at bit position == tree depth
00089       depthMask_ = (1 << (treeDepth - 1));
00090 
00091     }
00092 
00094     template<typename DataT, typename LeafT>
00095     void
00096     Octree2BufBase<DataT, LeafT>::setTreeDepth (unsigned int depth_arg)
00097     {
00098       assert (depth_arg > 0);
00099 
00100       // set octree depth
00101       octreeDepth_ = depth_arg;
00102 
00103       // define depthMask_ by setting a single bit to 1 at bit position == tree depth
00104       depthMask_ = (1 << (depth_arg - 1));
00105     }
00106 
00108     template<typename DataT, typename LeafT>
00109     void
00110     Octree2BufBase<DataT, LeafT>::add (const unsigned int idxX_arg, const unsigned int idxY_arg,
00111                                        const unsigned int idxZ_arg, const DataT& data_arg)
00112     {
00113       OctreeKey key;
00114 
00115       // generate key
00116       genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00117 
00118       // add data_arg to octree
00119       add (key, data_arg);
00120 
00121       objectCount_++;
00122     }
00123 
00125     template<typename DataT, typename LeafT>
00126     bool
00127     Octree2BufBase<DataT, LeafT>::get (const unsigned int idxX_arg, const unsigned int idxY_arg,
00128                                        const unsigned int idxZ_arg, DataT& data_arg) const
00129     {
00130       OctreeKey key;
00131 
00132       // generate key
00133       genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00134 
00135       // search for leaf at key
00136       LeafT* leaf = findLeaf (key);
00137       if (leaf)
00138       {
00139         const DataT * dataPtr;
00140         // if successful, decode data to data_arg
00141         leaf->getData (dataPtr);
00142         if (dataPtr)
00143           data_arg = *dataPtr;
00144       }
00145       // returns true on success
00146       return (leaf != 0);
00147     }
00148 
00150     template<typename DataT, typename LeafT>
00151     bool
00152     Octree2BufBase<DataT, LeafT>::existLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg,
00153                                              const unsigned int idxZ_arg) const
00154     {
00155       OctreeKey key;
00156 
00157       // generate key
00158       this->genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00159 
00160       // check if key exist in octree
00161       return existLeaf (key);
00162     }
00163 
00165     template<typename DataT, typename LeafT>
00166     void
00167     Octree2BufBase<DataT, LeafT>::removeLeaf (const unsigned int idxX_arg, const unsigned int idxY_arg,
00168                                               const unsigned int idxZ_arg)
00169     {
00170       OctreeKey key;
00171 
00172       // generate key
00173       this->genOctreeKeyByIntIdx (idxX_arg, idxY_arg, idxZ_arg, key);
00174 
00175       // free voxel at key
00176       return this->removeLeaf (key);
00177     }
00178 
00180     template<typename DataT, typename LeafT>
00181     void
00182     Octree2BufBase<DataT, LeafT>::deleteTree ( bool freeMemory_arg )
00183     {
00184       if (rootNode_)
00185       {
00186         // reset octree
00187         deleteBranch (*rootNode_);
00188         leafCount_ = 0;
00189         branchCount_ = 1;
00190         objectCount_ = 0;
00191         
00192         resetTree_ = false;
00193         treeDirtyFlag_ = false;
00194         depthMask_ = 0;
00195         octreeDepth_ = 0;
00196       }
00197 
00198       // delete node pool
00199       if (freeMemory_arg)
00200         poolCleanUp ();
00201     }
00202 
00204     template<typename DataT, typename LeafT>
00205     void
00206     Octree2BufBase<DataT, LeafT>::switchBuffers ()
00207     {
00208       if (treeDirtyFlag_)
00209       {
00210         // make sure that all unused branch nodes from previous buffer are deleted
00211         treeCleanUpRecursive (rootNode_);
00212       }
00213 
00214       // switch butter selector
00215       bufferSelector_ = !bufferSelector_;
00216 
00217       // reset flags
00218       treeDirtyFlag_ = true;
00219       leafCount_ = 0;
00220       objectCount_ = 0;
00221       branchCount_ = 1;
00222       resetTree_ = true;
00223     }
00224 
00226     template<typename DataT, typename LeafT>
00227     void
00228     Octree2BufBase<DataT, LeafT>::serializeTree (std::vector<char>& binaryTreeOut_arg, bool doXOREncoding_arg)
00229     {
00230       OctreeKey newKey;
00231       newKey.x = newKey.y = newKey.z = 0;
00232       
00233       // clear binary vector
00234       binaryTreeOut_arg.clear ();
00235       binaryTreeOut_arg.reserve (this->branchCount_);
00236 
00237       serializeTreeRecursive (binaryTreeOut_arg, rootNode_, newKey, doXOREncoding_arg);
00238 
00239       // serializeTreeRecursive cleans-up unused octree nodes in previous octree
00240       treeDirtyFlag_ = false;
00241     }
00242 
00244     template<typename DataT, typename LeafT>
00245     void
00246     Octree2BufBase<DataT, LeafT>::serializeTree (std::vector<char>& binaryTreeOut_arg,
00247                                                  std::vector<DataT>& dataVector_arg, bool doXOREncoding_arg)
00248     {
00249       OctreeKey newKey;
00250       newKey.x = newKey.y = newKey.z = 0;
00251 
00252       // clear output vectors
00253       binaryTreeOut_arg.clear ();
00254       dataVector_arg.clear ();
00255 
00256       dataVector_arg.reserve (objectCount_);
00257       binaryTreeOut_arg.reserve (this->branchCount_);
00258 
00259       Octree2BufBase<DataT, LeafT>::serializeTreeRecursive (binaryTreeOut_arg, rootNode_, newKey,
00260                                                             dataVector_arg, doXOREncoding_arg);
00261 
00262       // serializeTreeRecursive cleans-up unused octree nodes in previous octree
00263       treeDirtyFlag_ = false;
00264     }
00265 
00267     template<typename DataT, typename LeafT>
00268     void
00269     Octree2BufBase<DataT, LeafT>::serializeLeafs (std::vector<DataT>& dataVector_arg)
00270     {
00271       OctreeKey newKey;
00272       newKey.x = newKey.y = newKey.z = 0;
00273 
00274       // clear output vector
00275       dataVector_arg.clear ();
00276 
00277       dataVector_arg.reserve (objectCount_);
00278 
00279       serializeLeafsRecursive (rootNode_, newKey, dataVector_arg);
00280 
00281       // serializeLeafsRecursive cleans-up unused octree nodes in previous octree
00282       treeDirtyFlag_ = false;
00283     }
00284 
00286     template<typename DataT, typename LeafT>
00287     void
00288     Octree2BufBase<DataT, LeafT>::deserializeTree (std::vector<char>& binaryTreeIn_arg, bool doXORDecoding_arg)
00289     {
00290       OctreeKey newKey;
00291       newKey.x = newKey.y = newKey.z = 0;
00292 
00293       // we will rebuild an octree -> reset leafCount
00294       leafCount_ = 0;
00295 
00296       // iterator for binary tree structure vector
00297       vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00298 
00299       deserializeTreeRecursive (binaryTreeVectorIterator, rootNode_, depthMask_, newKey, resetTree_, doXORDecoding_arg);
00300 
00301       // we modified the octree structure -> clean-up/tree-reset might be required
00302       resetTree_ = false;
00303       treeDirtyFlag_ = true;
00304 
00305       objectCount_ = this->leafCount_;
00306     }
00307 
00309     template<typename DataT, typename LeafT>
00310     void
00311     Octree2BufBase<DataT, LeafT>::deserializeTree (std::vector<char>& binaryTreeIn_arg,
00312                                                    std::vector<DataT>& dataVector_arg, bool doXORDecoding_arg)
00313     {
00314       OctreeKey newKey;
00315       newKey.x = newKey.y = newKey.z = 0;
00316 
00317       // set data iterator to first element
00318       typename std::vector<DataT>::const_iterator dataVectorIterator = dataVector_arg.begin ();
00319 
00320       // set data iterator to last element
00321       typename std::vector<DataT>::const_iterator dataVectorEndIterator = dataVector_arg.end ();
00322 
00323       // we will rebuild an octree -> reset leafCount
00324       leafCount_ = 0;
00325 
00326       // iterator for binary tree structure vector
00327       vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00328 
00329       deserializeTreeRecursive (binaryTreeVectorIterator, rootNode_, depthMask_, newKey, dataVectorIterator,
00330                                 dataVectorEndIterator, resetTree_, doXORDecoding_arg);
00331 
00332       // we modified the octree structure -> clean-up/tree-reset might be required
00333       resetTree_ = false;
00334       treeDirtyFlag_ = true;
00335 
00336       objectCount_ = (unsigned int)dataVector_arg.size();
00337     }
00338 
00340     template<typename DataT, typename LeafT>
00341     void
00342     Octree2BufBase<DataT, LeafT>::deserializeTreeAndOutputLeafData (std::vector<char>& binaryTreeIn_arg,
00343                                                                     std::vector<DataT>& dataVector_arg,
00344                                                                     bool doXORDecoding_arg)
00345     {
00346       OctreeKey newKey;
00347       newKey.x = newKey.y = newKey.z = 0;
00348 
00349       // free existing tree before tree rebuild
00350       deleteTree ();
00351 
00352       // iterator for binary tree structure vector
00353       vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00354 
00355       deserializeTreeAndOutputLeafDataRecursive (binaryTreeVectorIterator, rootNode_, depthMask_, newKey,
00356                                                  dataVector_arg, resetTree_, doXORDecoding_arg);
00357 
00358       // we modified the octree structure -> clean-up/tree-reset might be required
00359       resetTree_ = false;
00360       treeDirtyFlag_ = true;
00361 
00362       objectCount_ = (unsigned int)dataVector_arg.size();
00363     }
00364 
00366     template<typename DataT, typename LeafT>
00367     void
00368     Octree2BufBase<DataT, LeafT>::serializeNewLeafs (std::vector<DataT>& dataVector_arg,
00369                                                      const int minPointsPerLeaf_arg)
00370     {
00371       OctreeKey newKey;
00372       newKey.x = newKey.y = newKey.z = 0;
00373 
00374       // clear output vector
00375       dataVector_arg.clear ();
00376 
00377       dataVector_arg.reserve (leafCount_);
00378 
00379       serializeNewLeafsRecursive (rootNode_, newKey, dataVector_arg, minPointsPerLeaf_arg);
00380 
00381       // serializeLeafsRecursive cleans-up unused octree nodes in previous octree
00382       treeDirtyFlag_ = false;
00383     }
00384 
00386     template<typename DataT, typename LeafT>
00387     LeafT*
00388     Octree2BufBase<DataT, LeafT>::getLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg,
00389                                                     OctreeBranch* branch_arg, bool branchReset_arg)
00390     {
00391       // index to branch child
00392       unsigned char childIdx;
00393       LeafT* result = 0;
00394 
00395       // branch reset -> this branch has been taken from previous buffer
00396       if (branchReset_arg)
00397       {
00398         // we can safely remove children references
00399         for (childIdx = 0; childIdx < 8; childIdx++)
00400         {
00401           setBranchChild (*branch_arg, childIdx, 0);
00402         }
00403       }
00404 
00405       // find branch child from key
00406       childIdx = ((!!(key_arg.x & depthMask_arg)) << 2) | ((!!(key_arg.y & depthMask_arg)) << 1) | (!!(key_arg.z
00407                                                                                                        & depthMask_arg));
00408 
00409       if (depthMask_arg > 1)
00410       {
00411         // we have not reached maximum tree depth
00412 
00413         OctreeBranch* childBranch;
00414         bool doNodeReset;
00415 
00416         doNodeReset = false;
00417 
00418         // if required branch does not exist
00419         if (!branchHasChild (*branch_arg, childIdx))
00420         {
00421           // check if we find a branch node reference in previous buffer
00422           if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
00423           {
00424 
00425             // take child branch from previous buffer
00426             childBranch = (OctreeBranch*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
00427             setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childBranch);
00428 
00429             doNodeReset = true; // reset the branch pointer array of stolen child node
00430 
00431           }
00432           else
00433           {
00434             // if required branch does not exist -> create it
00435             createBranchChild (*branch_arg, childIdx, childBranch);
00436           }
00437 
00438           branchCount_++;
00439 
00440         }
00441         else
00442         {
00443           // required branch node already exists - use it
00444           childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00445         }
00446         
00447         // recursively proceed with indexed child branch
00448         result = getLeafRecursive (key_arg, depthMask_arg / 2, childBranch, doNodeReset);
00449         
00450       }
00451       else
00452       {
00453         // branch childs are leaf nodes
00454         
00455         OctreeLeaf* childLeaf;
00456         if (!branchHasChild (*branch_arg, childIdx))
00457         {
00458           // leaf node at childIdx does not exist
00459           
00460           // check if we can take copy a reference from previous buffer
00461           if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
00462           {
00463             // take child leaf node from previous buffer
00464             childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
00465             setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childLeaf);
00466             
00467             childLeaf->reset ();
00468             
00469             leafCount_++;  
00470           }
00471           else
00472           {
00473             // if required leaf does not exist -> create it
00474             createLeafChild (*branch_arg, childIdx, childLeaf);
00475             leafCount_++;
00476           }
00477           
00478           // return leaf node
00479           result = childLeaf;  
00480         }
00481         else
00482         {
00483           // leaf node already exist
00484           childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, childIdx);
00485           
00486           // return leaf node
00487           result = childLeaf;
00488           
00489         }
00490         
00491       }
00492       
00493       return result;
00494       
00495     }
00496 
00498     template<typename DataT, typename LeafT>
00499     LeafT*
00500     Octree2BufBase<DataT, LeafT>::findLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg,
00501                                                      OctreeBranch* branch_arg) const
00502     {
00503       // return leaf node
00504       unsigned char childIdx;
00505       LeafT* result = 0;
00506 
00507       // find branch child from key
00508       childIdx = ((!!(key_arg.x & depthMask_arg)) << 2) | ((!!(key_arg.y & depthMask_arg)) << 1) | (!!(key_arg.z
00509                                                                                                        & depthMask_arg));
00510 
00511       if (depthMask_arg > 1)
00512       {
00513         // we have not reached maximum tree depth
00514         OctreeBranch* childBranch;
00515         childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00516         
00517         if (childBranch)
00518           // recursively proceed with indexed child branch
00519           result = findLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00520         
00521       }
00522       else
00523       {
00524         // we reached leaf node level
00525         if (branchHasChild (*branch_arg, childIdx))
00526         {
00527           // return existing leaf node
00528           OctreeLeaf* childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, childIdx);
00529           result = childLeaf;
00530         }
00531         
00532       }
00533     
00534       return result;
00535     }
00536 
00538     template<typename DataT, typename LeafT>
00539     bool
00540     Octree2BufBase<DataT, LeafT>::deleteLeafRecursive (const OctreeKey& key_arg, const unsigned int depthMask_arg,
00541                                                        OctreeBranch* branch_arg)
00542     {
00543       // index to branch child
00544       unsigned char childIdx;
00545       // indicates if branch is empty and can be safely removed
00546       bool bNoChilds;
00547 
00548       // find branch child from key
00549       childIdx = ((!!(key_arg.x & depthMask_arg)) << 2) | ((!!(key_arg.y & depthMask_arg)) << 1) | (!!(key_arg.z
00550                                                                                                        & depthMask_arg));
00551 
00552       if (depthMask_arg > 1)
00553       {
00554         // we have not reached maximum tree depth
00555         
00556         OctreeBranch* childBranch;
00557         bool bBranchOccupied;
00558         
00559         // next branch child on our path through the tree
00560         childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00561         
00562         if (childBranch)
00563         {
00564           // recursively explore the indexed child branch
00565           bBranchOccupied = deleteLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00566           
00567           if (!bBranchOccupied)
00568           {
00569             // child branch does not own any sub-child nodes anymore -> delete child branch
00570             deleteBranchChild (*branch_arg, childIdx);
00571             branchCount_--;
00572           }
00573         }
00574       }
00575       else
00576       {
00577         // our child is a leaf node -> delete it
00578         deleteBranchChild (*branch_arg, childIdx);
00579         leafCount_--;
00580       }
00581 
00582       // check if current branch still owns childs
00583       bNoChilds = false;
00584       for (childIdx = 0; childIdx < 8; childIdx++)
00585       {
00586         bNoChilds = branchHasChild (*branch_arg, childIdx);
00587         if (bNoChilds)
00588           break;
00589       }
00590 
00591       // return true if current branch can be deleted
00592       return bNoChilds;
00593     }
00594 
00596     template<typename DataT, typename LeafT>
00597     void
00598     Octree2BufBase<DataT, LeafT>::serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg,
00599                                                           OctreeBranch* branch_arg, const OctreeKey& key_arg,
00600                                                           bool doXOREncoding_arg)
00601     {
00602       // child iterator
00603       unsigned char childIdx;
00604 
00605       // bit pattern
00606       char nodeBitPatternCurrentBuffer;
00607       char nodeBitPatternLastBuffer;
00608       char nodeXORBitPattern;
00609       char unusedBranchesBits;
00610 
00611       // occupancy bit patterns of branch node  (current and previous octree buffer)
00612       nodeBitPatternCurrentBuffer = getBranchBitPattern (*branch_arg, bufferSelector_);
00613       nodeBitPatternLastBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
00614 
00615       // XOR of current and previous occupancy bit patterns
00616       nodeXORBitPattern = nodeBitPatternCurrentBuffer ^ nodeBitPatternLastBuffer;
00617 
00618       // bit pattern indicating unused octree nodes in previous branch
00619       unusedBranchesBits = nodeXORBitPattern & nodeBitPatternLastBuffer;
00620 
00621       if (doXOREncoding_arg)
00622       {
00623         // write XOR bit pattern to output vector
00624         binaryTreeOut_arg.push_back (nodeXORBitPattern);
00625       }
00626       else
00627       {
00628         // write bit pattern of current buffer to output vector
00629         binaryTreeOut_arg.push_back (nodeBitPatternCurrentBuffer);
00630       }
00631 
00632       // iterate over all children
00633       for (childIdx = 0; childIdx < 8; childIdx++)
00634       {
00635         if (branchHasChild (*branch_arg, childIdx))
00636         {
00637           const OctreeNode * childNode;
00638           childNode = getBranchChild (*branch_arg, childIdx);
00639           
00640           // generate new key for current branch voxel
00641           OctreeKey newKey;
00642           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00643           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00644           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00645           
00646           switch (childNode->getNodeType ())
00647           {
00648             case BRANCH_NODE:
00649               // recursively proceed with indexed child branch
00650               serializeTreeRecursive (binaryTreeOut_arg, (OctreeBranch*)childNode, newKey, doXOREncoding_arg);
00651               break;
00652             case LEAF_NODE:
00653             {
00654               OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00655               
00656               // we reached a leaf node -> execute serialization callback
00657               serializeLeafCallback (*childLeaf, newKey);
00658             }
00659             break;
00660             default:
00661               break;
00662           }
00663         }
00664 
00665         // check for unused branches in previous buffer
00666         if (unusedBranchesBits & (1 << childIdx))
00667         {
00668           // delete branch, free memory
00669           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00670         }
00671       }
00672     }
00673 
00675     template<typename DataT, typename LeafT>
00676     void
00677     Octree2BufBase<DataT, LeafT>::serializeTreeRecursive (std::vector<char>& binaryTreeOut_arg,
00678                                                           OctreeBranch* branch_arg, const OctreeKey& key_arg,
00679                                                           typename std::vector<DataT>& dataVector_arg,
00680                                                           bool doXOREncoding_arg)
00681     {
00682 
00683       // child iterator
00684       unsigned char childIdx;
00685 
00686       // bit pattern
00687       char nodeBitPatternCurrentBuffer;
00688       char nodeBitPatternLastBuffer;
00689       char nodeXORBitPattern;
00690       char unusedBranchesBits;
00691 
00692       // occupancy bit patterns of branch node  (current and previous octree buffer)
00693       nodeBitPatternCurrentBuffer = getBranchBitPattern (*branch_arg, bufferSelector_);
00694       nodeBitPatternLastBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
00695 
00696       // XOR of current and previous occupancy bit patterns
00697       nodeXORBitPattern = nodeBitPatternCurrentBuffer ^ nodeBitPatternLastBuffer;
00698 
00699       // bit pattern indicating unused octree nodes in previous branch
00700       unusedBranchesBits = nodeXORBitPattern & nodeBitPatternLastBuffer;
00701 
00702       if (doXOREncoding_arg)
00703       {
00704         // write XOR bit pattern to output vector
00705         binaryTreeOut_arg.push_back (nodeXORBitPattern);
00706       }
00707       else
00708       {
00709         // write bit pattern of current buffer to output vector
00710         binaryTreeOut_arg.push_back (nodeBitPatternCurrentBuffer);
00711       }
00712 
00713       // iterate over all children
00714       for (childIdx = 0; childIdx < 8; childIdx++)
00715       {
00716         if (branchHasChild (*branch_arg, childIdx))
00717         {
00718           // generate new key for current branch voxel
00719           OctreeKey newKey;
00720           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00721           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00722           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00723           
00724           const OctreeNode * childNode;
00725           childNode = getBranchChild (*branch_arg, childIdx);
00726           
00727           switch (childNode->getNodeType ())
00728           {
00729             case BRANCH_NODE:
00730               // recursively proceed with indexed child branch
00731               serializeTreeRecursive (binaryTreeOut_arg, (OctreeBranch*)childNode, newKey, dataVector_arg,
00732                                       doXOREncoding_arg);
00733               break;
00734             case LEAF_NODE:
00735             {
00736               OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00737               
00738               // we reached a leaf node -> execute serialization callback
00739               serializeLeafCallback (*childLeaf, newKey, dataVector_arg);
00740             }
00741             break;
00742             default:
00743               break;
00744           }
00745         }
00746 
00747         // check for unused branches in previous buffer
00748         if (unusedBranchesBits & (1 << childIdx))
00749         {
00750           // delete branch, free memory
00751           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00752         }
00753       }
00754     }
00755 
00757     template<typename DataT, typename LeafT>
00758     void
00759     Octree2BufBase<DataT, LeafT>::serializeLeafsRecursive (OctreeBranch* branch_arg, const OctreeKey& key_arg,
00760                                                            typename std::vector<DataT>& dataVector_arg)
00761     {
00762       // child iterator
00763       unsigned char childIdx;
00764 
00765       // bit pattern
00766       char nodeBitPatternLastBuffer;
00767       char nodeXORBitPattern;
00768       char unusedBranchesBits;
00769 
00770       // occupancy bit pattern of branch node  (previous octree buffer)
00771       nodeBitPatternLastBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
00772 
00773       // XOR of current and previous occupancy bit patterns
00774       nodeXORBitPattern = getBranchXORBitPattern (*branch_arg);
00775 
00776       // bit pattern indicating unused octree nodes in previous branch
00777       unusedBranchesBits = nodeXORBitPattern & nodeBitPatternLastBuffer;
00778 
00779       // iterate over all children
00780       for (childIdx = 0; childIdx < 8; childIdx++)
00781       {
00782         if (branchHasChild (*branch_arg, childIdx))
00783         {
00784           const OctreeNode * childNode;
00785           childNode = getBranchChild (*branch_arg, childIdx);
00786           
00787           // generate new key for current branch voxel
00788           OctreeKey newKey;
00789           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00790           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00791           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00792           
00793           switch (childNode->getNodeType ())
00794           {
00795             case BRANCH_NODE:
00796               // recursively proceed with indexed child branch
00797               serializeLeafsRecursive ((OctreeBranch*)childNode, newKey, dataVector_arg);
00798               break;
00799             case LEAF_NODE:
00800             {
00801               OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00802               
00803               // we reached a leaf node -> execute serialization callback
00804               serializeLeafCallback (*childLeaf, newKey, dataVector_arg);
00805             }
00806             break;
00807             default:
00808               break;
00809           }
00810         }
00811         
00812         // check for unused branches in previous buffer
00813         if (unusedBranchesBits & (1 << childIdx))
00814         {
00815           // delete branch, free memory
00816           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00817         }   
00818       }
00819     }
00820 
00822     template<typename DataT, typename LeafT>
00823     void
00824     Octree2BufBase<DataT, LeafT>::serializeNewLeafsRecursive (OctreeBranch* branch_arg, const OctreeKey& key_arg,
00825                                                               std::vector<DataT>& dataVector_arg,
00826                                                               const int minPointsPerLeaf_arg)
00827     {
00828       // child iterator
00829       unsigned char childIdx;
00830 
00831       // bit pattern
00832       char nodeBitPatternLastBuffer;
00833       char nodeXORBitPattern;
00834       char unusedBranchesBits;
00835 
00836       // occupancy bit pattern of branch node  (previous octree buffer)
00837       nodeBitPatternLastBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
00838 
00839       // XOR of current and previous occupancy bit patterns
00840       nodeXORBitPattern = getBranchXORBitPattern (*branch_arg);
00841 
00842       // bit pattern indicating unused octree nodes in previous branch
00843       unusedBranchesBits = nodeXORBitPattern & nodeBitPatternLastBuffer;
00844 
00845       // iterate over all children
00846       for (childIdx = 0; childIdx < 8; childIdx++)
00847       {
00848         if (branchHasChild (*branch_arg, childIdx))
00849         {
00850           const OctreeNode * childNode;
00851           childNode = getBranchChild (*branch_arg, childIdx);
00852           
00853           // generate new key for current branch voxel
00854           OctreeKey newKey;
00855           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00856           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00857           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00858           
00859           switch (childNode->getNodeType ())
00860           {
00861             case BRANCH_NODE:
00862               // recursively proceed with indexed child branch
00863               serializeNewLeafsRecursive ((OctreeBranch*)childNode, newKey, dataVector_arg, minPointsPerLeaf_arg);
00864               break;
00865             case LEAF_NODE:
00866             {
00867               // check if leaf existed already in previous buffer
00868               if (!(nodeBitPatternLastBuffer & (1 << childIdx)))
00869               {
00870                 // we reached a leaf node
00871                 
00872                 OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
00873                 
00874                 serializeNewLeafCallback (*childLeaf, newKey, minPointsPerLeaf_arg, dataVector_arg);
00875               }
00876             }
00877             break;
00878             default:
00879               break;
00880           }
00881         }
00882         
00883         // check for unused branches in previous buffer
00884         if (unusedBranchesBits & (1 << childIdx))
00885         {
00886           // delete branch, free memory
00887           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00888         }   
00889       }
00890     }
00891 
00893     template<typename DataT, typename LeafT>
00894     void
00895     Octree2BufBase<DataT, LeafT>::deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
00896                                                             OctreeBranch* branch_arg,
00897                                                             const unsigned int depthMask_arg,
00898                                                             const OctreeKey& key_arg, bool branchReset_arg,
00899                                                             bool doXORDecoding_arg)
00900     {
00901       // child iterator
00902       unsigned char childIdx;
00903 
00904       // node bits
00905       char nodeBits;
00906       char recoveredNodeBits;
00907 
00908       // branch reset -> this branch has been taken from previous buffer
00909       if (branchReset_arg)
00910       {
00911         // we can safely remove children references
00912         for (childIdx = 0; childIdx < 8; childIdx++)
00913         {
00914           setBranchChild (*branch_arg, childIdx, 0);
00915         }  
00916       }
00917 
00918       // read branch occupancy bit pattern from vector
00919       nodeBits = (*binaryTreeIn_arg);
00920       binaryTreeIn_arg++;
00921 
00922       // recover branch occupancy bit pattern
00923       if (doXORDecoding_arg)
00924       {
00925         recoveredNodeBits = getBranchBitPattern (*branch_arg, !bufferSelector_) ^ nodeBits;
00926       }
00927       else
00928       {
00929         recoveredNodeBits = nodeBits;
00930       }
00931 
00932       // iterate over all children
00933       for (childIdx = 0; childIdx < 8; childIdx++)
00934       {
00935         // if occupancy bit for childIdx is set..
00936         if (recoveredNodeBits & (1 << childIdx))
00937         {
00938           // generate new key for current branch voxel
00939           OctreeKey newKey;
00940           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
00941           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
00942           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
00943           
00944           bool doNodeReset;
00945           
00946           doNodeReset = false;
00947           
00948           if (depthMask_arg > 1)
00949           {
00950             // we have not reached maximum tree depth
00951             OctreeBranch* childBranch;
00952             
00953             if (!branchHasChild (*branch_arg, childIdx))
00954             {
00955               // check if we find a branch node reference in previous buffer
00956               if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
00957               {
00958                 // take child branch from previous buffer
00959                 childBranch = (OctreeBranch*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
00960                 setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childBranch);
00961                 doNodeReset = true;
00962                 
00963               }
00964               else
00965               {
00966                 // if required branch does not exist -> create it
00967                 createBranchChild (*branch_arg, childIdx, childBranch);
00968               }
00969               
00970               branchCount_++;
00971               
00972             }
00973             else
00974             {
00975               // required branch node already exists - use it
00976               childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
00977             }
00978             
00979             // recursively proceed with indexed child branch
00980             deserializeTreeRecursive (binaryTreeIn_arg, childBranch, depthMask_arg / 2, newKey, doNodeReset, doXORDecoding_arg);
00981             
00982           }
00983           else
00984           {
00985             // branch childs are leaf nodes
00986             
00987             OctreeLeaf* childLeaf;
00988             
00989             // check if we can take copy a reference from previous buffer
00990             if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
00991             {
00992               // take child leaf node from previous buffer
00993               childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
00994               setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childLeaf);
00995               
00996               // reset child leaf
00997               childLeaf->reset ();
00998               
00999             }
01000             else
01001             {
01002               // if required leaf does not exist -> create it
01003               createLeafChild (*branch_arg, childIdx, childLeaf);
01004               
01005             }
01006             
01007             // execute deserialization callback
01008             deserializeLeafCallback (*childLeaf, newKey);
01009             
01010             leafCount_++;
01011             
01012           }
01013         }
01014         else
01015         {
01016           // remove old branch pointer information in current branch
01017           setBranchChild (*branch_arg, bufferSelector_, childIdx, 0);
01018           
01019           // remove unused branches in previous buffer
01020           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
01021         }
01022       } 
01023     }
01024 
01026     template<typename DataT, typename LeafT>
01027     void
01028     Octree2BufBase<DataT, LeafT>::deserializeTreeRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
01029                                                             OctreeBranch* branch_arg,
01030                                                             const unsigned int depthMask_arg,
01031                                                             const OctreeKey& key_arg,
01032                                                             typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
01033                                                             typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg,
01034                                                             bool branchReset_arg, bool doXORDecoding_arg)
01035     {
01036       // child iterator
01037       unsigned char childIdx;
01038 
01039       // node bits
01040       char nodeBits;
01041       char recoveredNodeBits;
01042 
01043       // branch reset -> this branch has been taken from previous buffer
01044       if (branchReset_arg)
01045       {
01046         // we can safely remove children references
01047         for (childIdx = 0; childIdx < 8; childIdx++)
01048         {
01049           setBranchChild (*branch_arg, childIdx, 0);
01050         }  
01051       }
01052       
01053       // read branch occupancy bit pattern from vector
01054       nodeBits = (*binaryTreeIn_arg);
01055       binaryTreeIn_arg++;
01056       
01057       // recover branch occupancy bit pattern
01058       if (doXORDecoding_arg)
01059       {
01060         recoveredNodeBits = getBranchBitPattern (*branch_arg, !bufferSelector_) ^ nodeBits;
01061       }
01062       else
01063       {
01064         recoveredNodeBits = nodeBits;
01065       }
01066       
01067       // iterate over all children
01068       for (childIdx = 0; childIdx < 8; childIdx++)
01069       {
01070         // if occupancy bit for childIdx is set..
01071         if (recoveredNodeBits & (1 << childIdx))
01072         {
01073           // generate new key for current branch voxel
01074           OctreeKey newKey;
01075           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
01076           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
01077           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
01078           
01079           bool doNodeReset;
01080           
01081           doNodeReset = false;
01082           
01083           if (depthMask_arg > 1)
01084           {
01085             // we have not reached maximum tree depth
01086             
01087             OctreeBranch* childBranch;
01088             
01089             // check if we find a branch node reference in previous buffer
01090             if (!branchHasChild (*branch_arg, childIdx))
01091             {
01092               
01093               if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
01094               {
01095                 // take child branch from previous buffer
01096                 childBranch = (OctreeBranch*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
01097                 setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childBranch);
01098                 doNodeReset = true;
01099                 
01100               }
01101               else
01102               {
01103                 // if required branch does not exist -> create it
01104                 createBranchChild (*branch_arg, childIdx, childBranch);
01105               }
01106               
01107               branchCount_++;
01108               
01109             }
01110             else
01111             {
01112               // required branch node already exists - use it
01113               childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
01114             }
01115             
01116             // recursively proceed with indexed child branch
01117             deserializeTreeRecursive (binaryTreeIn_arg, childBranch, depthMask_arg / 2, newKey,
01118                                       dataVectorIterator_arg, dataVectorEndIterator_arg, doNodeReset, doXORDecoding_arg);
01119             
01120           }
01121           else
01122           {
01123             // branch childs are leaf nodes
01124             
01125             OctreeLeaf* childLeaf;
01126             
01127             // check if we can take copy a reference pointer from previous buffer
01128             if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
01129             {
01130               // take child leaf node from previous buffer
01131               childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
01132               setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childLeaf);
01133               
01134               // reset child leaf
01135               childLeaf->reset ();
01136               
01137             }
01138             else
01139             {
01140               // if required leaf does not exist -> create it
01141               createLeafChild (*branch_arg, childIdx, childLeaf);
01142             }
01143             
01144             leafCount_++;
01145             
01146             // execute deserialization callback
01147             deserializeLeafCallback (*childLeaf, newKey, dataVectorIterator_arg, dataVectorEndIterator_arg);
01148             
01149           }
01150         }
01151         else
01152         {      
01153           // remove old branch pointer information in current branch
01154           setBranchChild (*branch_arg, bufferSelector_, childIdx, 0);
01155           
01156           // remove unused branches in previous buffer
01157           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
01158         }
01159       }
01160     }
01161     
01163     template<typename DataT, typename LeafT>
01164     void
01165     Octree2BufBase<DataT, LeafT>::deserializeTreeAndOutputLeafDataRecursive (typename std::vector<char>::const_iterator& binaryTreeIn_arg,
01166                                                                              OctreeBranch* branch_arg,
01167                                                                              const unsigned int depthMask_arg,
01168                                                                              const OctreeKey& key_arg,
01169                                                                              typename std::vector<DataT>& dataVector_arg,
01170                                                                              bool branchReset_arg, bool doXORDecoding_arg)
01171     {
01172       // child iterator
01173       unsigned char childIdx;
01174 
01175       // node bits
01176       char nodeBits;
01177       char recoveredNodeBits;
01178 
01179       // branch reset -> this branch has been taken from previous buffer
01180       if (branchReset_arg)
01181       {
01182         // we can safely remove children references
01183         for (childIdx = 0; childIdx < 8; childIdx++)
01184         {
01185           setBranchChild (*branch_arg, childIdx, 0);
01186         }
01187       }
01188 
01189       // read branch occupancy bit pattern from vector
01190       nodeBits = (*binaryTreeIn_arg);
01191       binaryTreeIn_arg++;
01192 
01193       // recover branch occupancy bit pattern
01194       if (doXORDecoding_arg)
01195       {
01196         recoveredNodeBits = getBranchBitPattern (*branch_arg, !bufferSelector_) ^ nodeBits;
01197       }
01198       else
01199       {
01200         recoveredNodeBits = nodeBits;
01201       }
01202       
01203       // iterate over all children
01204       for (childIdx = 0; childIdx < 8; childIdx++)
01205       {
01206         // if occupancy bit for childIdx is set..
01207         if (recoveredNodeBits & (1 << childIdx))
01208         {
01209           
01210           // generate new key for current branch voxel
01211           OctreeKey newKey;
01212           newKey.x = (key_arg.x << 1) | (!!(childIdx & (1 << 2)));
01213           newKey.y = (key_arg.y << 1) | (!!(childIdx & (1 << 1)));
01214           newKey.z = (key_arg.z << 1) | (!!(childIdx & (1 << 0)));
01215           
01216           bool doNodeReset;
01217           
01218           doNodeReset = false;
01219           
01220           if (depthMask_arg > 1)
01221           {
01222             // we have not reached maximum tree depth
01223             OctreeBranch* childBranch;
01224             
01225             if (!branchHasChild (*branch_arg, childIdx))
01226             {    
01227               // check if we find a branch node reference in previous buffer
01228               if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
01229               {
01230                 // take child branch from previous buffer
01231                 childBranch = (OctreeBranch*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
01232                 setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childBranch);
01233                 doNodeReset = true;
01234                 
01235               }
01236               else
01237               {
01238                 // if required branch does not exist -> create it
01239                 createBranchChild (*branch_arg, childIdx, childBranch);
01240               }
01241               
01242               branchCount_++;
01243               
01244             }
01245             else
01246             {
01247               // required branch node already exists - use it
01248               childBranch = (OctreeBranch*)getBranchChild (*branch_arg, childIdx);
01249             }
01250             
01251             // recursively proceed with indexed child branch
01252             deserializeTreeRecursive (binaryTreeIn_arg, childBranch, depthMask_arg / 2, newKey, doNodeReset, doXORDecoding_arg);
01253             
01254           }
01255           else
01256           {
01257             // branch childs are leaf nodes
01258             
01259             OctreeLeaf* childLeaf;
01260             
01261             // check if we can take copy a reference from previous buffer
01262             if (branchHasChild (*branch_arg, !bufferSelector_, childIdx))
01263             {
01264               // take child leaf node from previous buffer
01265               childLeaf = (OctreeLeaf*)getBranchChild (*branch_arg, !bufferSelector_, childIdx);
01266               setBranchChild (*branch_arg, bufferSelector_, childIdx, (OctreeNode*)childLeaf);
01267               
01268               // reset child leaf
01269               childLeaf->reset ();
01270               
01271             }
01272             else
01273             {
01274               // if required leaf does not exist -> create it
01275               createLeafChild (*branch_arg, childIdx, childLeaf);
01276               
01277             }
01278             
01279             // execute deserialization callback
01280             deserializeTreeAndSerializeLeafCallback (*childLeaf, newKey, dataVector_arg);
01281             
01282             leafCount_++;
01283             
01284           }
01285         }
01286         else
01287         {
01288           // remove old branch pointer information in current branch
01289           setBranchChild (*branch_arg, bufferSelector_, childIdx, 0);
01290           
01291           // remove unused branches in previous buffer
01292           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
01293         }
01294       } 
01295     }
01296 
01298     template<typename DataT, typename LeafT>
01299     void
01300     Octree2BufBase<DataT, LeafT>::serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg)
01301     {
01302       // nothing to do
01303     }
01304 
01306     template<typename DataT, typename LeafT>
01307     void
01308     Octree2BufBase<DataT, LeafT>::serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
01309                                                          std::vector<DataT>& dataVector_arg)
01310     {
01311       leaf_arg.getData (dataVector_arg);
01312     }
01313 
01315     template<typename DataT, typename LeafT>
01316     void
01317     Octree2BufBase<DataT, LeafT>::serializeNewLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
01318                                                             const int minPointsPerLeaf_arg,
01319                                                             std::vector<DataT>& dataVector_arg)
01320     {
01321       // we reached a leaf node
01322       std::vector<int> newPointIdx;
01323 
01324       if (minPointsPerLeaf_arg != 0)
01325       {
01326         // push to newPointIdx
01327         leaf_arg.getData (newPointIdx);
01328         
01329         // check for minimum amount of leaf point indices
01330         if (newPointIdx.size () >= (size_t)minPointsPerLeaf_arg)
01331         {
01332           dataVector_arg.insert (dataVector_arg.end (), newPointIdx.begin (), newPointIdx.end ());
01333         }
01334       }
01335       else
01336       {
01337         // push leaf data to dataVector_arg
01338         leaf_arg.getData (dataVector_arg);
01339       }
01340     }
01341 
01343     template<typename DataT, typename LeafT>
01344     void
01345     Octree2BufBase<DataT, LeafT>::deserializeLeafCallback (
01346                                                            OctreeLeaf& leaf_arg,
01347                                                            const OctreeKey& key_arg,
01348                                                            typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
01349                                                            typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg)
01350     {
01351       OctreeKey dataKey;
01352       bool bKeyBasedEncoding = false;
01353 
01354       // add DataT objects to octree leaf as long as their key fit to voxel
01355       while ((dataVectorIterator_arg != dataVectorEndIterator_arg)
01356              && (this->genOctreeKeyForDataT (*dataVectorIterator_arg, dataKey) && (dataKey == key_arg)))
01357       {
01358         leaf_arg.setData (*dataVectorIterator_arg);
01359         dataVectorIterator_arg++;
01360         bKeyBasedEncoding = true;
01361       }
01362       
01363       // add single DataT object to octree if key-based encoding is disabled
01364       if (!bKeyBasedEncoding)
01365       {
01366         leaf_arg.setData (*dataVectorIterator_arg);
01367         dataVectorIterator_arg++;
01368       }
01369     }
01370 
01372     template<typename DataT, typename LeafT>
01373     void
01374     Octree2BufBase<DataT, LeafT>::deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg)
01375     {
01376 
01377       DataT newDataT;
01378 
01379       // initialize new leaf child
01380       if (genDataTByOctreeKey (key_arg, newDataT))
01381       {
01382         leaf_arg.setData (newDataT);
01383       } 
01384     }
01385 
01387     template<typename DataT, typename LeafT>
01388     void
01389     Octree2BufBase<DataT, LeafT>::deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg,
01390                                                                            const OctreeKey& key_arg,
01391                                                                            std::vector<DataT>& dataVector_arg)
01392     {
01393 
01394       DataT newDataT;
01395 
01396       // initialize new leaf child
01397       if (genDataTByOctreeKey (key_arg, newDataT))
01398       {
01399         leaf_arg.setData (newDataT);
01400         dataVector_arg.push_back (newDataT);
01401       }
01402     }
01403 
01405     template<typename DataT, typename LeafT>
01406     void
01407     Octree2BufBase<DataT, LeafT>::treeCleanUpRecursive (OctreeBranch* branch_arg)
01408     {
01409 
01410       // child iterator
01411       unsigned char childIdx;
01412 
01413       // bit pattern
01414       char nodeBitPatternLastBuffer;
01415       char nodeXORBitPattern;
01416       char unusedBranchesBits;
01417 
01418       // occupancy bit pattern of branch node  (previous octree buffer)
01419       nodeBitPatternLastBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
01420 
01421       // XOR of current and previous occupancy bit patterns
01422       nodeXORBitPattern = getBranchXORBitPattern (*branch_arg);
01423 
01424       // bit pattern indicating unused octree nodes in previous branch
01425       unusedBranchesBits = nodeXORBitPattern & nodeBitPatternLastBuffer;
01426 
01427       // iterate over all children
01428       for (childIdx = 0; childIdx < 8; childIdx++)
01429       {
01430         if (branchHasChild (*branch_arg, childIdx))
01431         {
01432           const OctreeNode * childNode;
01433           childNode = getBranchChild (*branch_arg, childIdx);
01434           
01435           switch (childNode->getNodeType ())
01436           {
01437             case BRANCH_NODE:
01438               // recursively proceed with indexed child branch
01439               treeCleanUpRecursive ((OctreeBranch*)childNode);
01440               break;
01441             case LEAF_NODE:
01442               // leaf level - nothing to do..
01443               break;
01444             default:
01445               break;
01446           }
01447         }
01448 
01449           // check for unused branches in previous buffer
01450         if (unusedBranchesBits & (1 << childIdx))
01451         {
01452           // delete branch, free memory
01453           deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
01454         }  
01455       }
01456     }
01457   }
01458 }
01459 
01460 #define PCL_INSTANTIATE_Octree2BufBase(T) template class PCL_EXPORTS pcl::octree::Octree2BufBase<T>;
01461 
01462 #endif
01463