|
Point Cloud Library (PCL)
1.5.1
|
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
1.8.0