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