Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
octree_iterator.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2011, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of Willow Garage, Inc. nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id: octree_iterator.h 4702 2012-02-23 09:39:33Z gedikli $
00037  */
00038 
00039 #ifndef OCTREE_ITERATOR_H
00040 #define OCTREE_ITERATOR_H
00041 
00042 #include <cstddef>
00043 #include <vector>
00044 #include <deque>
00045 
00046 #include "octree_nodes.h"
00047 
00048 #include <pcl/point_cloud.h>
00049 #include <pcl/point_types.h>
00050 
00051 #include <iterator>
00052 
00053 namespace pcl
00054 {
00055   namespace octree
00056   {
00058 
00063     template<typename DataT, typename LeafT, typename OctreeT>
00064       class OctreeIteratorBase : public std::iterator<std::forward_iterator_tag, const OctreeNode, void,
00065           const OctreeNode*, const OctreeNode&>
00066       {
00067 
00068       public:
00069 
00070         // public typedefs
00071         typedef typename OctreeT::OctreeBranch OctreeBranch;
00072         typedef typename OctreeT::OctreeKey OctreeKey;
00073 
00077         explicit
00078         OctreeIteratorBase (const OctreeT& octree_arg) :
00079             octree_ (octree_arg), currentNode_ (NULL)
00080         {
00081           reset ();
00082         }
00083 
00085         virtual
00086         ~OctreeIteratorBase ()
00087         {
00088         }
00089 
00092         inline void
00093         reset ()
00094         {
00095           // initialize iterator globals
00096           currentNode_ = (OctreeNode*)octree_.getRootNode ();
00097           currentOctreeDepth_ = 0;
00098 
00099           // reset octree key
00100           currentOctreeKey_.x = currentOctreeKey_.y = currentOctreeKey_.z = 0;
00101         }
00102 
00106         inline const OctreeKey&
00107         getCurrentOctreeKey () const
00108         {
00109           return (currentOctreeKey_);
00110         }
00111 
00115         inline unsigned int
00116         getCurrentOctreeDepth () const
00117         {
00118           return (currentOctreeDepth_);
00119         }
00120 
00124         inline const OctreeNode*
00125         getCurrentOctreeNode () const
00126         {
00127           return (currentNode_);
00128         }
00129 
00133         inline const OctreeNode*
00134         operator* () const
00135         { // return designated object
00136           return (this->getCurrentOctreeNode ());
00137         }
00138 
00142         inline bool
00143         isBranchNode () const
00144         {
00145           return (currentNode_->getNodeType () == BRANCH_NODE);
00146         }
00147 
00151         inline bool
00152         isLeafNode () const
00153         {
00154           return (currentNode_->getNodeType () == LEAF_NODE);
00155         }
00156 
00160         inline char
00161         getNodeConfiguration () const
00162         {
00163           char ret = 0;
00164 
00165           if (isBranchNode ())
00166           {
00167 
00168             // current node is a branch node
00169             const OctreeBranch* currentBranch = (const OctreeBranch*)this->currentNode_;
00170 
00171             // get child configuration bit pattern
00172             ret = octree_.getBranchBitPattern (*currentBranch);
00173 
00174           }
00175 
00176           return ret;
00177         }
00178 
00179 
00183         virtual void
00184         getData (const DataT*& data_arg) const
00185         {
00186           const DataT* result = 0;
00187 
00188           if (this->currentNode_ && (this->currentNode_->getNodeType () == LEAF_NODE))
00189           {
00190             const LeafT* leafNode = (const LeafT*)this->currentNode_;
00191             leafNode->getData (result);
00192           }
00193           data_arg = result;
00194         }
00195 
00199         virtual void
00200         getData (std::vector<DataT>& dataVector_arg) const
00201         {
00202           if (this->currentNode_ && (this->currentNode_->getNodeType () == LEAF_NODE))
00203           {
00204             const LeafT* leafNode = (const LeafT*)this->currentNode_;
00205             leafNode->getData (dataVector_arg);
00206           }
00207         }
00208 
00212         virtual unsigned long
00213         getNodeID () const
00214         {
00215           unsigned long id = 0;
00216 
00217           if (this->currentNode_)
00218           {
00219             // calculate integer id with respect to octree key
00220             unsigned int depth = octree_.getTreeDepth();
00221             id = currentOctreeKey_.x << (depth*2) |
00222                  currentOctreeKey_.y << (depth*1) |
00223                  currentOctreeKey_.z << (depth*0);
00224           }
00225 
00226           return id;
00227         }
00228 
00229       protected:
00231         const OctreeT& octree_;
00232 
00234         const OctreeNode* currentNode_;
00235 
00237         unsigned int currentOctreeDepth_;
00238 
00240         OctreeKey currentOctreeKey_;
00241       };
00242 
00244 
00249     template<typename DataT, typename LeafT, typename OctreeT>
00250       class OctreeDepthFirstIterator : public OctreeIteratorBase<DataT, LeafT, OctreeT>
00251       {
00252         // public typedefs
00253         typedef typename OctreeIteratorBase<DataT, LeafT, OctreeT>::OctreeBranch OctreeBranch;
00254         typedef typename OctreeIteratorBase<DataT, LeafT, OctreeT>::OctreeKey OctreeKey;
00255 
00256       public:
00260         explicit
00261         OctreeDepthFirstIterator (const OctreeT& octree_arg);
00262 
00264         virtual
00265         ~OctreeDepthFirstIterator ();
00266 
00269         virtual void
00270         reset ();
00271 
00275         OctreeDepthFirstIterator&
00276         operator++ ();
00277 
00281         inline OctreeDepthFirstIterator
00282         operator++ (int)
00283         {
00284           OctreeDepthFirstIterator _Tmp = *this;
00285           ++*this;
00286           return (_Tmp);
00287         }
00288 
00291         void
00292         skipChildVoxels ();
00293 
00294       protected:
00296         unsigned char currentChildIdx_;
00297 
00299         std::vector<std::pair<OctreeNode const*, unsigned char> > stack_;
00300       };
00301 
00303 
00308     template<typename DataT, typename LeafT, typename OctreeT>
00309       class OctreeBreadthFirstIterator : public OctreeIteratorBase<DataT, LeafT, OctreeT>
00310       {
00311         // public typedefs
00312         typedef typename OctreeIteratorBase<DataT, LeafT, OctreeT>::OctreeBranch OctreeBranch;
00313         typedef typename OctreeIteratorBase<DataT, LeafT, OctreeT>::OctreeKey OctreeKey;
00314 
00315         struct FIFOElement {
00316           const OctreeNode* node;
00317           OctreeKey key;
00318           unsigned int depth;
00319         };
00320 
00321       public:
00325         explicit
00326         OctreeBreadthFirstIterator (const OctreeT& octree_arg);
00327 
00329         virtual
00330         ~OctreeBreadthFirstIterator ();
00331 
00334         void
00335         reset ();
00336 
00340         OctreeBreadthFirstIterator&
00341         operator++ ();
00342 
00346         inline OctreeBreadthFirstIterator
00347         operator++ (int)
00348         {
00349           OctreeBreadthFirstIterator _Tmp = *this;
00350           ++*this;
00351           return (_Tmp);
00352         }
00353 
00354       protected:
00358         void
00359         addChildNodesToFIFO (const OctreeNode* node);
00360 
00362         std::deque<FIFOElement> FIFO_;
00363       };
00364 
00366 
00371 
00372     template<typename DataT, typename LeafT, typename OctreeT>
00373       class OctreeLeafNodeIterator : public OctreeDepthFirstIterator<DataT, LeafT, OctreeT>
00374       {
00375       public:
00379         explicit
00380         OctreeLeafNodeIterator (const OctreeT& octree_arg) :
00381             OctreeDepthFirstIterator<DataT, LeafT, OctreeT> (octree_arg)
00382         {
00383           reset ();
00384         }
00385 
00387         virtual
00388         ~OctreeLeafNodeIterator ()
00389         {
00390         }
00391 
00394         inline void
00395         reset ()
00396         {
00397           OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::reset ();
00398         }
00399 
00403         inline OctreeLeafNodeIterator&
00404         operator++ ()
00405         {
00406           do
00407           {
00408             OctreeDepthFirstIterator<DataT, LeafT, OctreeT>::operator++ ();
00409           } while ((this->currentNode_) && (this->currentNode_->getNodeType () != LEAF_NODE));
00410 
00411           return (*this);
00412         }
00413 
00417         inline OctreeLeafNodeIterator
00418         operator++ (int)
00419         {
00420           OctreeLeafNodeIterator _Tmp = *this;
00421           ++*this;
00422           return (_Tmp);
00423         }
00424 
00428         const LeafT*
00429         operator* () const
00430         {
00431           // return designated object
00432           const LeafT* ret = NULL;
00433 
00434           if (this->currentNode_ && (this->currentNode_->getNodeType () == LEAF_NODE))
00435             ret = (const LeafT*)this->currentNode_;
00436           return (ret);
00437         }
00438       };
00439 
00440   }
00441 }
00442 
00443 #endif
00444