/* * Software License Agreement (BSD License) * * Point Cloud Library (PCL) - www.pointclouds.org * Copyright (c) 2010-2012, Willow Garage, Inc. * Copyright (c) 2017-, Open Perception, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $Id$ */ #pragma once #include #include #include #include #include #include // Ignore warnings in the above headers #ifdef __GNUC__ #pragma GCC system_header #endif namespace pcl { namespace octree { // Octree iterator state pushed on stack/list struct IteratorState { OctreeNode* node_; OctreeKey key_; uindex_t depth_; }; /** \brief @b Abstract octree iterator class * \note Octree iterator base class * \ingroup octree * \author Julius Kammerl (julius@kammerl.de) */ template class OctreeIteratorBase : public std::iterator { public: using LeafNode = typename OctreeT::LeafNode; using BranchNode = typename OctreeT::BranchNode; using LeafContainer = typename OctreeT::LeafContainer; using BranchContainer = typename OctreeT::BranchContainer; /** \brief Empty constructor. */ OctreeIteratorBase() : OctreeIteratorBase(nullptr, 0u) {} /** \brief Constructor. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeIteratorBase(uindex_t max_depth_arg) : octree_(nullptr), current_state_(nullptr), max_octree_depth_(max_depth_arg) { this->reset(); } /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal */ OctreeIteratorBase(OctreeT* octree_arg) : OctreeIteratorBase(octree_arg, 0u) {} /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeIteratorBase(OctreeT* octree_arg, uindex_t max_depth_arg) : octree_(octree_arg), current_state_(0), max_octree_depth_(max_depth_arg) { this->reset(); } /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal * \param[in] current_state A pointer to the current iterator state * * \warning For advanced users only. */ explicit OctreeIteratorBase(OctreeT* octree_arg, uindex_t max_depth_arg, IteratorState* current_state) : octree_(octree_arg), current_state_(current_state), max_octree_depth_(max_depth_arg) {} /** \brief Empty deconstructor. */ virtual ~OctreeIteratorBase() {} /** \brief Equal comparison operator * \param[in] other OctreeIteratorBase to compare with */ bool operator==(const OctreeIteratorBase& other) const { if (this == &other) // same object return true; if (octree_ != other.octree_) // refer to different octrees return false; if (!current_state_ && !other.current_state_) // both are end iterators return true; if (max_octree_depth_ == other.max_octree_depth_ && current_state_ && other.current_state_ && // null dereference protection current_state_->key_ == other.current_state_->key_) return true; return false; } /** \brief Inequal comparison operator * \param[in] other OctreeIteratorBase to compare with */ bool operator!=(const OctreeIteratorBase& other) const { return !operator==(other); } /** \brief Reset iterator */ inline void reset() { current_state_ = 0; if (octree_ && (!max_octree_depth_)) { max_octree_depth_ = octree_->getTreeDepth(); } } /** \brief Get octree key for the current iterator octree node * \return octree key of current node */ inline const OctreeKey& getCurrentOctreeKey() const { assert(octree_ != 0); assert(current_state_ != 0); return (current_state_->key_); } /** \brief Get the current depth level of octree * \return depth level */ inline uindex_t getCurrentOctreeDepth() const { assert(octree_ != 0); assert(current_state_ != 0); return (current_state_->depth_); } /** \brief Get the current octree node * \return pointer to current octree node */ inline OctreeNode* getCurrentOctreeNode() const { assert(octree_ != 0); assert(current_state_ != 0); return (current_state_->node_); } /** \brief check if current node is a branch node * \return true if current node is a branch node, false otherwise */ inline bool isBranchNode() const { assert(octree_ != 0); assert(current_state_ != 0); return (current_state_->node_->getNodeType() == BRANCH_NODE); } /** \brief check if current node is a branch node * \return true if current node is a branch node, false otherwise */ inline bool isLeafNode() const { assert(octree_ != 0); assert(current_state_ != 0); return (current_state_->node_->getNodeType() == LEAF_NODE); } /** \brief *operator. * \return pointer to the current octree node */ inline OctreeNode* operator*() const { // return designated object if (octree_ && current_state_) { return (current_state_->node_); } else { return 0; } } /** \brief Get bit pattern of children configuration of current node * \return bit pattern (byte) describing the existence of 8 children of the current * node */ inline char getNodeConfiguration() const { char ret = 0; assert(octree_ != 0); assert(current_state_ != 0); if (isBranchNode()) { // current node is a branch node const BranchNode* current_branch = static_cast(current_state_->node_); // get child configuration bit pattern ret = octree_->getBranchBitPattern(*current_branch); } return (ret); } /** \brief Method for retrieving a single leaf container from the octree leaf node * \return Reference to container class of leaf node. */ const LeafContainer& getLeafContainer() const { assert(octree_ != 0); assert(current_state_ != 0); assert(this->isLeafNode()); LeafNode* leaf_node = static_cast(current_state_->node_); return leaf_node->getContainer(); } /** \brief Method for retrieving a single leaf container from the octree leaf node * \return Reference to container class of leaf node. */ LeafContainer& getLeafContainer() { assert(octree_ != 0); assert(current_state_ != 0); assert(this->isLeafNode()); LeafNode* leaf_node = static_cast(current_state_->node_); return leaf_node->getContainer(); } /** \brief Method for retrieving the container from an octree branch node * \return BranchContainer. */ const BranchContainer& getBranchContainer() const { assert(octree_ != 0); assert(current_state_ != 0); assert(this->isBranchNode()); BranchNode* branch_node = static_cast(current_state_->node_); return branch_node->getContainer(); } /** \brief Method for retrieving the container from an octree branch node * \return BranchContainer. */ BranchContainer& getBranchContainer() { assert(octree_ != 0); assert(current_state_ != 0); assert(this->isBranchNode()); BranchNode* branch_node = static_cast(current_state_->node_); return branch_node->getContainer(); } /** \brief get a integer identifier for current node (note: identifier depends on tree * depth). \return node id. */ virtual unsigned long getNodeID() const { unsigned long id = 0; assert(octree_ != 0); assert(current_state_ != 0); if (current_state_) { const OctreeKey& key = getCurrentOctreeKey(); // calculate integer id with respect to octree key uindex_t depth = octree_->getTreeDepth(); id = static_cast(key.x) << (depth * 2) | static_cast(key.y) << (depth * 1) | static_cast(key.z) << (depth * 0); } return id; } protected: /** \brief Reference to octree class. */ OctreeT* octree_; /** \brief Pointer to current iterator state. */ IteratorState* current_state_; /** \brief Maximum octree depth */ uindex_t max_octree_depth_; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** \brief @b Octree iterator class * \note This class implements a forward iterator for traversing octrees in a * depth-first manner. * \ingroup octree * \author Julius Kammerl (julius@kammerl.de) */ template class OctreeDepthFirstIterator : public OctreeIteratorBase { public: using LeafNode = typename OctreeIteratorBase::LeafNode; using BranchNode = typename OctreeIteratorBase::BranchNode; /** \brief Empty constructor. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeDepthFirstIterator(uindex_t max_depth_arg = 0); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeDepthFirstIterator(OctreeT* octree_arg, uindex_t max_depth_arg = 0); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal * \param[in] current_state A pointer to the current iterator state * * \warning For advanced users only. */ explicit OctreeDepthFirstIterator( OctreeT* octree_arg, uindex_t max_depth_arg, IteratorState* current_state, const std::vector& stack = std::vector()) : OctreeIteratorBase(octree_arg, max_depth_arg, current_state), stack_(stack) {} /** \brief Copy Constructor. * \param[in] other Another OctreeDepthFirstIterator to copy from */ OctreeDepthFirstIterator(const OctreeDepthFirstIterator& other) : OctreeIteratorBase(other), stack_(other.stack_) { this->current_state_ = stack_.size() ? &stack_.back() : NULL; } /** \brief Copy assignment * \param[in] src the iterator to copy into this */ inline OctreeDepthFirstIterator& operator=(const OctreeDepthFirstIterator& src) { OctreeIteratorBase::operator=(src); stack_ = src.stack_; if (stack_.size()) { this->current_state_ = &stack_.back(); } else { this->current_state_ = 0; } return (*this); } /** \brief Reset the iterator to the root node of the octree */ virtual void reset(); /** \brief Preincrement operator. * \note recursively step to next octree node */ OctreeDepthFirstIterator& operator++(); /** \brief postincrement operator. * \note recursively step to next octree node */ inline OctreeDepthFirstIterator operator++(int) { OctreeDepthFirstIterator _Tmp = *this; ++*this; return (_Tmp); } /** \brief Skip all child voxels of current node and return to parent node. */ void skipChildVoxels(); protected: /** Stack structure. */ std::vector stack_; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** \brief @b Octree iterator class * \note This class implements a forward iterator for traversing octrees in a * breadth-first manner. * \ingroup octree * \author Julius Kammerl (julius@kammerl.de) */ template class OctreeBreadthFirstIterator : public OctreeIteratorBase { public: // public typedefs using BranchNode = typename OctreeIteratorBase::BranchNode; using LeafNode = typename OctreeIteratorBase::LeafNode; /** \brief Empty constructor. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeBreadthFirstIterator(uindex_t max_depth_arg = 0); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeBreadthFirstIterator(OctreeT* octree_arg, uindex_t max_depth_arg = 0); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal * \param[in] current_state A pointer to the current iterator state * * \warning For advanced users only. */ explicit OctreeBreadthFirstIterator( OctreeT* octree_arg, uindex_t max_depth_arg, IteratorState* current_state, const std::deque& fifo = std::deque()) : OctreeIteratorBase(octree_arg, max_depth_arg, current_state), FIFO_(fifo) {} /** \brief Copy Constructor. * \param[in] other Another OctreeBreadthFirstIterator to copy from */ OctreeBreadthFirstIterator(const OctreeBreadthFirstIterator& other) : OctreeIteratorBase(other), FIFO_(other.FIFO_) { this->current_state_ = FIFO_.size() ? &FIFO_.front() : NULL; } /** \brief Copy operator. * \param[in] src the iterator to copy into this */ inline OctreeBreadthFirstIterator& operator=(const OctreeBreadthFirstIterator& src) { OctreeIteratorBase::operator=(src); FIFO_ = src.FIFO_; if (FIFO_.size()) { this->current_state_ = &FIFO_.front(); } else { this->current_state_ = 0; } return (*this); } /** \brief Reset the iterator to the root node of the octree */ void reset(); /** \brief Preincrement operator. * \note step to next octree node */ OctreeBreadthFirstIterator& operator++(); /** \brief postincrement operator. * \note step to next octree node */ inline OctreeBreadthFirstIterator operator++(int) { OctreeBreadthFirstIterator _Tmp = *this; ++*this; return (_Tmp); } protected: /** FIFO list */ std::deque FIFO_; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** \brief @b Octree iterator class * \note Iterator over all existing nodes at a given depth. It walks across an octree * in a breadth-first manner. * \ingroup octree * \author Fabien Rozar (fabien.rozar@gmail.com) */ template class OctreeFixedDepthIterator : public OctreeBreadthFirstIterator { public: // public typedefs using typename OctreeBreadthFirstIterator::BranchNode; using typename OctreeBreadthFirstIterator::LeafNode; /** \brief Empty constructor. */ OctreeFixedDepthIterator(); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] fixed_depth_arg Depth level during traversal */ explicit OctreeFixedDepthIterator(OctreeT* octree_arg, uindex_t fixed_depth_arg = 0); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] fixed_depth_arg Depth level during traversal * \param[in] current_state A pointer to the current iterator state * \param[in] fifo Internal container of octree node to go through * * \warning For advanced users only. */ OctreeFixedDepthIterator( OctreeT* octree_arg, uindex_t fixed_depth_arg, IteratorState* current_state, const std::deque& fifo = std::deque()) : OctreeBreadthFirstIterator( octree_arg, fixed_depth_arg, current_state, fifo) , fixed_depth_(fixed_depth_arg) {} /** \brief Copy Constructor. * \param[in] other Another OctreeFixedDepthIterator to copy from */ OctreeFixedDepthIterator(const OctreeFixedDepthIterator& other) : OctreeBreadthFirstIterator(other) { this->fixed_depth_ = other.fixed_depth_; } /** \brief Copy assignment. * \param[in] src the iterator to copy into this * \return pointer to the current octree node */ inline OctreeFixedDepthIterator& operator=(const OctreeFixedDepthIterator& src) { OctreeBreadthFirstIterator::operator=(src); this->fixed_depth_ = src.fixed_depth_; return (*this); } /** \brief Reset the iterator to the first node at the depth given as parameter * \param[in] fixed_depth_arg Depth level during traversal */ void reset(uindex_t fixed_depth_arg); /** \brief Reset the iterator to the first node at the current depth */ void reset() { this->reset(fixed_depth_); } protected: using OctreeBreadthFirstIterator::FIFO_; /** \brief Given level of the node to be iterated */ uindex_t fixed_depth_; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** \brief Octree leaf node iterator class * \note This class implements a forward iterator for traversing the leaf nodes of an * octree data structure. * \ingroup octree * \author Julius Kammerl (julius@kammerl.de) */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template class OctreeLeafNodeDepthFirstIterator : public OctreeDepthFirstIterator { using BranchNode = typename OctreeDepthFirstIterator::BranchNode; using LeafNode = typename OctreeDepthFirstIterator::LeafNode; public: /** \brief Empty constructor. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeLeafNodeDepthFirstIterator(uindex_t max_depth_arg = 0) : OctreeDepthFirstIterator(max_depth_arg) { reset(); } /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeLeafNodeDepthFirstIterator(OctreeT* octree_arg, uindex_t max_depth_arg = 0) : OctreeDepthFirstIterator(octree_arg, max_depth_arg) { reset(); } /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal * \param[in] current_state A pointer to the current iterator state * * \warning For advanced users only. */ explicit OctreeLeafNodeDepthFirstIterator( OctreeT* octree_arg, uindex_t max_depth_arg, IteratorState* current_state, const std::vector& stack = std::vector()) : OctreeDepthFirstIterator(octree_arg, max_depth_arg, current_state, stack) {} /** \brief Reset the iterator to the root node of the octree */ inline void reset() { OctreeDepthFirstIterator::reset(); this->operator++(); } /** \brief Preincrement operator. * \note recursively step to next octree leaf node */ inline OctreeLeafNodeDepthFirstIterator& operator++() { do { OctreeDepthFirstIterator::operator++(); } while ((this->current_state_) && (this->current_state_->node_->getNodeType() != LEAF_NODE)); return (*this); } /** \brief postincrement operator. * \note step to next octree node */ inline OctreeLeafNodeDepthFirstIterator operator++(int) { OctreeLeafNodeDepthFirstIterator _Tmp = *this; ++*this; return (_Tmp); } /** \brief *operator. * \return pointer to the current octree leaf node */ OctreeNode* operator*() const { // return designated object OctreeNode* ret = 0; if (this->current_state_ && (this->current_state_->node_->getNodeType() == LEAF_NODE)) ret = this->current_state_->node_; return (ret); } }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** \brief Octree leaf node iterator class * \note This class implements a forward iterator for traversing the leaf nodes of an * octree data structure in the breadth first way. * \ingroup octree * \author Fabien Rozar * (fabien.rozar@gmail.com) */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template class OctreeLeafNodeBreadthFirstIterator : public OctreeBreadthFirstIterator { using BranchNode = typename OctreeBreadthFirstIterator::BranchNode; using LeafNode = typename OctreeBreadthFirstIterator::LeafNode; public: /** \brief Empty constructor. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeLeafNodeBreadthFirstIterator(uindex_t max_depth_arg = 0); /** \brief Constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal */ explicit OctreeLeafNodeBreadthFirstIterator(OctreeT* octree_arg, uindex_t max_depth_arg = 0); /** \brief Copy constructor. * \param[in] octree_arg Octree to be iterated. Initially the iterator is set to its * root node. * \param[in] max_depth_arg Depth limitation during traversal * \param[in] current_state A pointer to the current iterator state * \param[in] fifo Internal container of octree node to go through * * \warning For advanced users only. */ explicit OctreeLeafNodeBreadthFirstIterator( OctreeT* octree_arg, uindex_t max_depth_arg, IteratorState* current_state, const std::deque& fifo = std::deque()); /** \brief Reset the iterator to the first leaf in the breadth first way. */ inline void reset(); /** \brief Preincrement operator. * \note recursively step to next octree leaf node */ inline OctreeLeafNodeBreadthFirstIterator& operator++(); /** \brief Postincrement operator. * \note step to next octree node */ inline OctreeLeafNodeBreadthFirstIterator operator++(int); }; } // namespace octree } // namespace pcl /* * Note: Since octree iterators depend on octrees, don't precompile them. */ #include