Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree_iterator.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_iterator.hpp 4702 2012-02-23 09:39:33Z gedikli $
00037  */
00038 
00039 #ifndef OCTREE_ITERATOR_HPP_
00040 #define OCTREE_ITERATOR_HPP_
00041 
00042 #include <vector>
00043 #include <assert.h>
00044 
00045 #include "pcl/common/common.h"
00046 
00047 namespace pcl
00048 {
00049   namespace octree
00050   {
00051 
00052     using namespace std;
00053 
00055     template<typename DataT, typename LeafT, typename OctreeT>
00056       OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::OctreeDepthFirstIterator (const OctreeT& octree_arg) :
00057           OctreeIteratorBase<DataT, LeafT, OctreeT> (octree_arg),currentChildIdx_ (0)
00058       {
00059 
00060         // allocate stack
00061         stack_.reserve (this->octree_.getTreeDepth ());
00062 
00063         // initialize iterator
00064         reset ();
00065 
00066       }
00067 
00069     template<typename DataT, typename LeafT, typename OctreeT>
00070       OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::~OctreeDepthFirstIterator ()
00071       {
00072 
00073       }
00074 
00076     template<typename DataT, typename LeafT, typename OctreeT>
00077       void
00078       OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::reset ()
00079       {
00080         OctreeIteratorBase<DataT, LeafT, OctreeT>::reset ();
00081 
00082         // empty stack
00083         stack_.clear ();
00084       }
00085 
00087     template<typename DataT, typename LeafT, typename OctreeT>
00088       void
00089       OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::skipChildVoxels ()
00090       {
00091         if (this->currentNode_)
00092         {
00093           // make sure, we are not at the root node
00094           if (stack_.size () > 0)
00095           {
00096             // pop stack
00097             std::pair<OctreeNode const*, unsigned char>& stackEntry = stack_.back ();
00098             stack_.pop_back ();
00099 
00100             // assign parent node and child index
00101             this->currentNode_ = stackEntry.first;
00102             currentChildIdx_ = stackEntry.second;
00103 
00104             // update octree key
00105             this->currentOctreeKey_.x = (this->currentOctreeKey_.x >> 1);
00106             this->currentOctreeKey_.y = (this->currentOctreeKey_.y >> 1);
00107             this->currentOctreeKey_.z = (this->currentOctreeKey_.z >> 1);
00108 
00109             // update octree depth
00110             this->currentOctreeDepth_--;
00111 
00112           }
00113           else
00114           {
00115             // we are at root node level - finish
00116             this->currentNode_ = NULL;
00117           }
00118 
00119         }
00120 
00121       }
00122 
00124     template<typename DataT, typename LeafT, typename OctreeT>
00125       OctreeDepthFirstIterator<DataT, LeafT, OctreeT>&
00126       OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::operator++ ()
00127       {
00128         if (this->currentNode_)
00129         {
00130 
00131           bool bTreeUp = false;
00132           const OctreeNode* itNode = NULL;
00133 
00134           if (this->currentNode_->getNodeType () == BRANCH_NODE)
00135           {
00136             // current node is a branch node
00137             const OctreeBranch* currentBranch = (const OctreeBranch*)this->currentNode_;
00138 
00139             // find next existing child node
00140             while ((currentChildIdx_ < 8) && !(itNode = this->octree_.getBranchChild (*currentBranch, currentChildIdx_)))
00141             {
00142               currentChildIdx_++;
00143             };
00144 
00145             if (currentChildIdx_ == 8)
00146             {
00147               // all childs traversed -> back to parent node
00148               bTreeUp = true;
00149             }
00150           }
00151           else
00152           {
00153             // at leaf node level, we need to return to parent node
00154             bTreeUp = true;
00155           }
00156 
00157           if (bTreeUp)
00158           {
00159             // return to parent node
00160 
00161             if (stack_.size () > 0)
00162             {
00163               // pop the stack
00164               std::pair<OctreeNode const*, unsigned char>& stackEntry = stack_.back ();
00165               stack_.pop_back ();
00166 
00167               // assign parent node and child index
00168               this->currentNode_ = stackEntry.first;
00169               currentChildIdx_ = stackEntry.second;
00170 
00171               // update octree key
00172               this->currentOctreeKey_.x = (this->currentOctreeKey_.x >> 1);
00173               this->currentOctreeKey_.y = (this->currentOctreeKey_.y >> 1);
00174               this->currentOctreeKey_.z = (this->currentOctreeKey_.z >> 1);
00175 
00176               // update octree depth
00177               this->currentOctreeDepth_--;
00178             }
00179             else
00180             {
00181               // root level -> finish
00182               this->currentNode_ = NULL;
00183             }
00184 
00185           }
00186           else
00187           {
00188             // traverse child node
00189 
00190             // new stack entry
00191             std::pair<OctreeNode const*, unsigned char> newStackEntry;
00192 
00193             // assign current node and child index to stack entry
00194             newStackEntry.first = this->currentNode_;
00195             newStackEntry.second = currentChildIdx_ + 1;
00196 
00197             // push stack entry to stack
00198             stack_.push_back (newStackEntry);
00199 
00200             // update octree key
00201             this->currentOctreeKey_.x = (this->currentOctreeKey_.x << 1) | (!!(currentChildIdx_ & (1 << 2)));
00202             this->currentOctreeKey_.y = (this->currentOctreeKey_.y << 1) | (!!(currentChildIdx_ & (1 << 1)));
00203             this->currentOctreeKey_.z = (this->currentOctreeKey_.z << 1) | (!!(currentChildIdx_ & (1 << 0)));
00204 
00205             // update octree depth
00206             this->currentOctreeDepth_++;
00207 
00208             // traverse to child node
00209             currentChildIdx_ = 0;
00210             this->currentNode_ = itNode;
00211           }
00212         }
00213 
00214         return (*this);
00215       }
00216 
00218     template<typename DataT, typename LeafT, typename OctreeT>
00219       OctreeBreadthFirstIterator<DataT, LeafT, OctreeT>::OctreeBreadthFirstIterator (const OctreeT& octree_arg) :
00220           OctreeIteratorBase<DataT, LeafT, OctreeT> (octree_arg)
00221       {
00222         OctreeIteratorBase<DataT, LeafT, OctreeT>::reset ();
00223 
00224         // initialize iterator
00225         reset ();
00226 
00227       }
00228 
00230     template<typename DataT, typename LeafT, typename OctreeT>
00231       OctreeBreadthFirstIterator<DataT, LeafT, OctreeT>::~OctreeBreadthFirstIterator ()
00232       {
00233       }
00234 
00236     template<typename DataT, typename LeafT, typename OctreeT>
00237       void
00238       OctreeBreadthFirstIterator<DataT, LeafT, OctreeT>::addChildNodesToFIFO (const OctreeNode* node)
00239       {
00240         unsigned char i;
00241 
00242         if (node && (node->getNodeType () == BRANCH_NODE))
00243         {
00244 
00245           for (i = 0; i < 8; i++)
00246           {
00247             // current node is a branch node
00248             const OctreeBranch* currentBranch = (const OctreeBranch*)this->currentNode_;
00249 
00250             const OctreeNode* itNode = (const OctreeNode*)this->octree_.getBranchChild (*currentBranch, i);
00251 
00252             // if node exist, push it to FIFO
00253             if (itNode)
00254             {
00255               OctreeKey newKey;
00256 
00257               // generate octree key
00258               newKey.x = (this->currentOctreeKey_.x << 1) | (!!(i & (1 << 2)));
00259               newKey.y = (this->currentOctreeKey_.y << 1) | (!!(i & (1 << 1)));
00260               newKey.z = (this->currentOctreeKey_.z << 1) | (!!(i & (1 << 0)));
00261 
00262               FIFOElement newListElement;
00263               newListElement.node = itNode;
00264               newListElement.key = newKey;
00265               newListElement.depth = this->currentOctreeDepth_ + 1;
00266 
00267               FIFO_.push_back (newListElement);
00268             }
00269           }
00270         }
00271 
00272       }
00273 
00275     template<typename DataT, typename LeafT, typename OctreeT>
00276       void
00277       OctreeBreadthFirstIterator<DataT, LeafT, OctreeT>::reset ()
00278       {
00279         OctreeIteratorBase<DataT, LeafT, OctreeT>::reset ();
00280 
00281         // init FIFO
00282         FIFO_.clear ();
00283 
00284       }
00285 
00287     template<typename DataT, typename LeafT, typename OctreeT>
00288       OctreeBreadthFirstIterator<DataT, LeafT, OctreeT>&
00289       OctreeBreadthFirstIterator<DataT, LeafT, OctreeT>::operator++ ()
00290       {
00291         if (this->currentNode_)
00292         {
00293 
00294           // add childs of current node to FIFO
00295           addChildNodesToFIFO (this->currentNode_);
00296 
00297           if (FIFO_.size () > 0)
00298           {
00299             FIFOElement FIFOElement;
00300 
00301             // get FIFO front element
00302             FIFOElement = FIFO_.front ();
00303             FIFO_.pop_front ();
00304 
00305             // update iterator variables
00306             this->currentNode_ = FIFOElement.node;
00307             this->currentOctreeKey_ = FIFOElement.key;
00308             this->currentOctreeDepth_ = FIFOElement.depth;
00309 
00310           }
00311           else
00312           {
00313             // last node reached
00314             this->currentNode_ = NULL;
00315           }
00316 
00317         }
00318 
00319         return (*this);
00320       }
00321   }
00322 }
00323 
00324 #endif