octomap 1.5.0
|
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_ */