octomap 1.5.0
include/octomap/OcTreeIterator.hxx
Go to the documentation of this file.
00001 // $Id: OcTreeIterator.hxx 420 2012-08-27 14:10:25Z ahornung $
00002 
00003 /*
00004  * OctoMap:
00005  * A probabilistic, flexible, and compact 3D mapping library for robotic systems.
00006  * @author K. M. Wurm, A. Hornung, University of Freiburg, Copyright (C) 2009.
00007  * @see http://octomap.sourceforge.net/
00008  * License: New BSD License
00009  */
00010 
00011 /*
00012  * Copyright (c) 2009, K. M. Wurm, A. Hornung, University of Freiburg
00013  * All rights reserved.
00014  *
00015  * Redistribution and use in source and binary forms, with or without
00016  * modification, are permitted provided that the following conditions are met:
00017  *
00018  *     * Redistributions of source code must retain the above copyright
00019  *       notice, this list of conditions and the following disclaimer.
00020  *     * Redistributions in binary form must reproduce the above copyright
00021  *       notice, this list of conditions and the following disclaimer in the
00022  *       documentation and/or other materials provided with the distribution.
00023  *     * Neither the name of the University of Freiburg nor the names of its
00024  *       contributors may be used to endorse or promote products derived from
00025  *       this software without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 #ifndef OCTOMAP_OCTREEITERATOR_HXX_
00041 #define OCTOMAP_OCTREEITERATOR_HXX_
00042 
00048     class iterator_base : public std::iterator<std::forward_iterator_tag, NodeType>{
00049     public:
00050       struct StackElement;
00052       iterator_base() : tree(NULL), maxDepth(0){}
00053 
00060       iterator_base(OcTreeBaseImpl<NodeType,INTERFACE> const* tree, unsigned char depth=0)
00061         : tree(tree), maxDepth(depth)
00062       {
00063         if (maxDepth == 0)
00064           maxDepth = tree->getTreeDepth();
00065 
00066         StackElement s;
00067         s.node = tree->root;
00068         s.depth = 0;
00069         s.key[0] = s.key[1] = s.key[2] = tree->tree_max_val;
00070         stack.push(s);
00071       }
00072 
00074       iterator_base(const iterator_base& other)
00075       : tree(other.tree), maxDepth(other.maxDepth), stack(other.stack) {}
00076 
00078       bool operator==(const iterator_base& other) const {
00079         return (tree ==other.tree && stack.size() == other.stack.size()
00080             && (stack.size()==0 || (stack.size() > 0 && (stack.top().node == other.stack.top().node
00081                 && stack.top().depth == other.stack.top().depth
00082                 && stack.top().key == other.stack.top().key ))));
00083       }
00084 
00086       bool operator!=(const iterator_base& other) const {
00087         return (tree !=other.tree || stack.size() != other.stack.size()
00088             || (stack.size() > 0 && ((stack.top().node != other.stack.top().node
00089                 || stack.top().depth != other.stack.top().depth
00090                 || stack.top().key != other.stack.top().key ))));
00091       }
00092 
00093       iterator_base& operator=(const iterator_base& other){
00094         tree = other.tree;
00095         maxDepth = other.maxDepth;
00096         stack = other.stack;
00097         return *this;
00098       };
00099 
00102       NodeType const* operator->() const { return stack.top().node;}
00103 
00106       NodeType* operator->() { return stack.top().node;}
00107 
00110       const NodeType& operator*() const { return *(stack.top().node);}
00111 
00114       NodeType& operator*() { return *(stack.top().node);}
00115 
00117       point3d getCoordinate() const {
00118         return tree->keyToCoord(stack.top().key, stack.top().depth);
00119       }
00120 
00122       double getX() const{
00123         return tree->keyToCoord(stack.top().key[0], stack.top().depth);
00124       }
00126       double getY() const{
00127         return tree->keyToCoord(stack.top().key[1], stack.top().depth);
00128       }
00130       double getZ() const{
00131         return tree->keyToCoord(stack.top().key[2], stack.top().depth);
00132       }
00133 
00135       double getSize() const {return  tree->getNodeSize(stack.top().depth); }
00136 
00138       unsigned getDepth() const {return unsigned(stack.top().depth); }
00139 
00141       const OcTreeKey& getKey() const {return stack.top().key;}
00142 
00144       OcTreeKey getIndexKey() const {
00145         return computeIndexKey(tree->getTreeDepth() - stack.top().depth, stack.top().key);
00146       }
00147 
00148 
00150       struct StackElement{
00151         NodeType* node;
00152         OcTreeKey key;
00153         unsigned char depth;
00154       };
00155 
00156 
00157     protected:
00160       void singleIncrement(){
00161         StackElement top = stack.top();
00162         stack.pop();
00163         if (top.depth == maxDepth)
00164           return;
00165 
00166         StackElement s;
00167         s.depth = top.depth +1;
00168 
00169         unsigned short int center_offset_key = tree->tree_max_val >> (top.depth +1);
00170         // push on stack in reverse order
00171         for (int i=7; i>=0; --i) {
00172           if (top.node->childExists(i)) {
00173             computeChildKey(i, center_offset_key, top.key, s.key);
00174             s.node = top.node->getChild(i);
00175             //OCTOMAP_DEBUG_STR("Current depth: " << int(top.depth) << " new: "<< int(s.depth) << " child#" << i <<" ptr: "<<s.node);
00176             stack.push(s);
00177             assert(s.depth <= maxDepth);
00178           }
00179         }
00180       }
00181 
00182       OcTreeBaseImpl<NodeType,INTERFACE> const* tree; 
00183       unsigned char maxDepth; 
00184 
00186       std::stack<StackElement,std::vector<StackElement> > stack;
00187 
00188     };
00189 
00207     class tree_iterator : public iterator_base {
00208     public:
00209       tree_iterator() : iterator_base(){}
00216       tree_iterator(OcTreeBaseImpl<NodeType,INTERFACE> const* tree, unsigned char depth=0) : iterator_base(tree, depth) {};
00217 
00219       tree_iterator operator++(int){
00220         tree_iterator result = *this;
00221         ++(*this);
00222         return result;
00223       }
00224 
00226       tree_iterator& operator++(){
00227 
00228         if (!this->stack.empty()){
00229           this->singleIncrement();
00230         }
00231 
00232         if (this->stack.empty()){
00233           this->tree = NULL;
00234         }
00235 
00236         return *this;
00237       }
00238 
00240       bool isLeaf() const{ return (!this->stack.top().node->hasChildren() || this->stack.top().depth == this->maxDepth); }
00241     };
00242 
00261     class leaf_iterator : public iterator_base {
00262       public:
00263           leaf_iterator() : iterator_base(){}
00264 
00271           leaf_iterator(OcTreeBaseImpl<NodeType, INTERFACE> const* tree, unsigned char depth=0) : iterator_base(tree, depth) {
00272             // skip forward to next valid leaf node:
00273             // add root another time (one will be removed) and ++
00274             this->stack.push(this->stack.top());
00275             operator ++();
00276           }
00277 
00278           leaf_iterator(const leaf_iterator& other) : iterator_base(other) {};
00279 
00281           leaf_iterator operator++(int){
00282             leaf_iterator result = *this;
00283             ++(*this);
00284             return result;
00285           }
00286 
00288           leaf_iterator& operator++(){
00289             if (this->stack.empty()){
00290               this->tree = NULL; // TODO check?
00291 
00292             } else {
00293               this->stack.pop();
00294 
00295               // skip forward to next leaf
00296               while(!this->stack.empty()  && this->stack.top().depth < this->maxDepth
00297                   && this->stack.top().node->hasChildren())
00298               {
00299                 this->singleIncrement();
00300               }
00301               // done: either stack is empty (== end iterator) or a next leaf node is reached!
00302               if (this->stack.empty())
00303                 this->tree = NULL;
00304             }
00305 
00306 
00307             return *this;
00308           }
00309 
00310     };
00311 
00329     class leaf_bbx_iterator : public iterator_base {
00330     public:
00331       leaf_bbx_iterator() : iterator_base() {};
00347       leaf_bbx_iterator(OcTreeBaseImpl<NodeType,INTERFACE> const* tree, const point3d& min, const point3d& max, unsigned char depth=0)
00348         : iterator_base(tree, depth)
00349       {
00350 
00351         if (!this->tree->coordToKeyChecked(min, minKey) || !this->tree->coordToKeyChecked(max, maxKey)){
00352           // coordinates invalid, set to end iterator
00353           tree = NULL;
00354           this->maxDepth = 0;
00355         } else{  // else: keys are generated and stored
00356 
00357           // advance from root to next valid leaf in bbx:
00358           this->stack.push(this->stack.top());
00359           this->operator ++();
00360         }
00361 
00362       }
00363 
00373       leaf_bbx_iterator(OcTreeBaseImpl<NodeType,INTERFACE> const* tree, const OcTreeKey& min, const OcTreeKey& max, unsigned char depth=0)
00374         : iterator_base(tree, depth), minKey(min), maxKey(max)
00375       {
00376           // advance from root to next valid leaf in bbx:
00377           this->stack.push(this->stack.top());
00378           this->operator ++();
00379       }
00380 
00381       leaf_bbx_iterator(const leaf_bbx_iterator& other) : iterator_base(other) {
00382         minKey = other.minKey;
00383         maxKey = other.maxKey;
00384       }
00385 
00386 
00387 
00389       leaf_bbx_iterator operator++(int){
00390         leaf_bbx_iterator result = *this;
00391         ++(*this);
00392         return result;
00393       }
00394 
00396       leaf_bbx_iterator& operator++(){
00397         if (this->stack.empty()){
00398           this->tree = NULL; // TODO check?
00399 
00400         } else {
00401           this->stack.pop();
00402 
00403           // skip forward to next leaf
00404           while(!this->stack.empty()  && this->stack.top().depth < this->maxDepth
00405               && this->stack.top().node->hasChildren())
00406           {
00407             this->singleIncrement();
00408           }
00409           // done: either stack is empty (== end iterator) or a next leaf node is reached!
00410           if (this->stack.empty())
00411             this->tree = NULL;
00412         }
00413 
00414 
00415         return *this;
00416       };
00417 
00418     protected:
00419 
00420       void singleIncrement(){
00421         typename iterator_base::StackElement top = this->stack.top();
00422         this->stack.pop();
00423 
00424         typename iterator_base::StackElement s;
00425         s.depth = top.depth +1;
00426         unsigned short int center_offset_key = this->tree->tree_max_val >> (top.depth +1);
00427         // push on stack in reverse order
00428         for (int i=7; i>=0; --i) {
00429           if (top.node->childExists(i)) {
00430             computeChildKey(i, center_offset_key, top.key, s.key);
00431 
00432             // overlap of query bbx and child bbx?
00433             if ((minKey[0] <= (s.key[0] + center_offset_key)) && (maxKey[0] >= (s.key[0] - center_offset_key))
00434                 && (minKey[1] <= (s.key[1] + center_offset_key)) && (maxKey[1] >= (s.key[1] - center_offset_key))
00435                 && (minKey[2] <= (s.key[2] + center_offset_key)) && (maxKey[2] >= (s.key[2] - center_offset_key)))
00436             {
00437               s.node = top.node->getChild(i);
00438               this->stack.push(s);
00439               assert(s.depth <= this->maxDepth);
00440             }
00441           }
00442         }
00443       }
00444 
00445 
00446       OcTreeKey minKey;
00447       OcTreeKey maxKey;
00448     };
00449 
00450 
00451 #endif /* OCTREEITERATOR_HXX_ */