/* * Software License Agreement (BSD License) * * Point Cloud Library (PCL) - www.pointclouds.org * Copyright (c) 2009-2012, Willow Garage, Inc. * Copyright (c) 2012-, 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 the copyright holder(s) 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$ * */ // NOTE: This file has been created with // 'pcl_src/geometry/include/pcl/geometry/mesh_circulators.py' #pragma once #include #include //////////////////////////////////////////////////////////////////////////////// // VertexAroundVertexCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates counter-clockwise around a vertex and returns an index to the * terminating vertex of the outgoing half-edge (the target). The best way to declare * the circulator is to use the method * pcl::geometry::MeshBase::getVertexAroundVertexCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class VertexAroundVertexCirculator : boost::equality_comparable< pcl::geometry::VertexAroundVertexCirculator, boost::unit_steppable>> { public: using Base = boost::equality_comparable< pcl::geometry::VertexAroundVertexCirculator, boost::unit_steppable>>; using Self = pcl::geometry::VertexAroundVertexCirculator; using Mesh = MeshT; using VertexIndex = typename Mesh::VertexIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ VertexAroundVertexCirculator() : mesh_(nullptr), idx_outgoing_half_edge_() {} /** \brief Construct from the vertex around which we want to circulate. */ VertexAroundVertexCirculator(const VertexIndex& idx_vertex, Mesh* const mesh) : mesh_(mesh), idx_outgoing_half_edge_(mesh->getOutgoingHalfEdgeIndex(idx_vertex)) {} /** \brief Construct directly from the outgoing half-edge. */ VertexAroundVertexCirculator(const HalfEdgeIndex& idx_outgoing_half_edge, Mesh* const mesh) : mesh_(mesh), idx_outgoing_half_edge_(idx_outgoing_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_outgoing_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_outgoing_half_edge_ == other.idx_outgoing_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_outgoing_half_edge_ = mesh_->getNextHalfEdgeIndex( mesh_->getOppositeHalfEdgeIndex(idx_outgoing_half_edge_)); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_outgoing_half_edge_ = mesh_->getOppositeHalfEdgeIndex( mesh_->getPrevHalfEdgeIndex(idx_outgoing_half_edge_)); return (*this); } /** \brief Get the index to the target vertex. */ inline VertexIndex getTargetIndex() const { return (mesh_->getTerminatingVertexIndex(idx_outgoing_half_edge_)); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_outgoing_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The outgoing half-edge of the vertex around which we want to circulate. */ HalfEdgeIndex idx_outgoing_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // OutgoingHalfEdgeAroundVertexCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates counter-clockwise around a vertex and returns an index to the * outgoing half-edge (the target). The best way to declare the circulator is to use the * method pcl::geometry::MeshBase::getOutgoingHalfEdgeAroundVertexCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to * change the connectivity in the mesh (only const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class OutgoingHalfEdgeAroundVertexCirculator : boost::equality_comparable< pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator, boost::unit_steppable< pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator>> { public: using Base = boost::equality_comparable< pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator, boost::unit_steppable< pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator>>; using Self = pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator; using Mesh = MeshT; using VertexIndex = typename Mesh::VertexIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ OutgoingHalfEdgeAroundVertexCirculator() : mesh_(nullptr), idx_outgoing_half_edge_() {} /** \brief Construct from the vertex around which we want to circulate. */ OutgoingHalfEdgeAroundVertexCirculator(const VertexIndex& idx_vertex, Mesh* const mesh) : mesh_(mesh), idx_outgoing_half_edge_(mesh->getOutgoingHalfEdgeIndex(idx_vertex)) {} /** \brief Construct directly from the outgoing half-edge. */ OutgoingHalfEdgeAroundVertexCirculator(const HalfEdgeIndex& idx_outgoing_half_edge, Mesh* const mesh) : mesh_(mesh), idx_outgoing_half_edge_(idx_outgoing_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_outgoing_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_outgoing_half_edge_ == other.idx_outgoing_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_outgoing_half_edge_ = mesh_->getNextHalfEdgeIndex( mesh_->getOppositeHalfEdgeIndex(idx_outgoing_half_edge_)); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_outgoing_half_edge_ = mesh_->getOppositeHalfEdgeIndex( mesh_->getPrevHalfEdgeIndex(idx_outgoing_half_edge_)); return (*this); } /** \brief Get the index to the outgoing half-edge. */ inline HalfEdgeIndex getTargetIndex() const { return (idx_outgoing_half_edge_); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_outgoing_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The outgoing half-edge of the vertex around which we want to circulate. */ HalfEdgeIndex idx_outgoing_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // IncomingHalfEdgeAroundVertexCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates counter-clockwise around a vertex and returns an index to the * incoming half-edge (the target). The best way to declare the circulator is to use the * method pcl::geometry::MeshBase::getIncomingHalfEdgeAroundVertexCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class IncomingHalfEdgeAroundVertexCirculator : boost::equality_comparable< pcl::geometry::IncomingHalfEdgeAroundVertexCirculator, boost::unit_steppable< pcl::geometry::IncomingHalfEdgeAroundVertexCirculator>> { public: using Base = boost::equality_comparable< pcl::geometry::IncomingHalfEdgeAroundVertexCirculator, boost::unit_steppable< pcl::geometry::IncomingHalfEdgeAroundVertexCirculator>>; using Self = pcl::geometry::IncomingHalfEdgeAroundVertexCirculator; using Mesh = MeshT; using VertexIndex = typename Mesh::VertexIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ IncomingHalfEdgeAroundVertexCirculator() : mesh_(nullptr), idx_incoming_half_edge_() {} /** \brief Construct from the vertex around which we want to circulate. */ IncomingHalfEdgeAroundVertexCirculator(const VertexIndex& idx_vertex, Mesh* const mesh) : mesh_(mesh), idx_incoming_half_edge_(mesh->getIncomingHalfEdgeIndex(idx_vertex)) {} /** \brief Construct directly from the incoming half-edge. */ IncomingHalfEdgeAroundVertexCirculator(const HalfEdgeIndex& idx_incoming_half_edge, Mesh* const mesh) : mesh_(mesh), idx_incoming_half_edge_(idx_incoming_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_incoming_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_incoming_half_edge_ == other.idx_incoming_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_incoming_half_edge_ = mesh_->getOppositeHalfEdgeIndex( mesh_->getNextHalfEdgeIndex(idx_incoming_half_edge_)); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_incoming_half_edge_ = mesh_->getPrevHalfEdgeIndex( mesh_->getOppositeHalfEdgeIndex(idx_incoming_half_edge_)); return (*this); } /** \brief Get the index to the incoming half-edge. */ inline HalfEdgeIndex getTargetIndex() const { return (idx_incoming_half_edge_); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_incoming_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The incoming half-edge of the vertex around which we want to circulate. */ HalfEdgeIndex idx_incoming_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // FaceAroundVertexCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates counter-clockwise around a vertex and returns an index to the face * of the outgoing half-edge (the target). The best way to declare the circulator is to * use the method pcl::geometry::MeshBase::getFaceAroundVertexCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class FaceAroundVertexCirculator : boost::equality_comparable< pcl::geometry::FaceAroundVertexCirculator, boost::unit_steppable>> { public: using Base = boost::equality_comparable< pcl::geometry::FaceAroundVertexCirculator, boost::unit_steppable>>; using Self = pcl::geometry::FaceAroundVertexCirculator; using Mesh = MeshT; using FaceIndex = typename Mesh::FaceIndex; using VertexIndex = typename Mesh::VertexIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ FaceAroundVertexCirculator() : mesh_(nullptr), idx_outgoing_half_edge_() {} /** \brief Construct from the vertex around which we want to circulate. */ FaceAroundVertexCirculator(const VertexIndex& idx_vertex, Mesh* const mesh) : mesh_(mesh), idx_outgoing_half_edge_(mesh->getOutgoingHalfEdgeIndex(idx_vertex)) {} /** \brief Construct directly from the outgoing half-edge. */ FaceAroundVertexCirculator(const HalfEdgeIndex& idx_outgoing_half_edge, Mesh* const mesh) : mesh_(mesh), idx_outgoing_half_edge_(idx_outgoing_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_outgoing_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_outgoing_half_edge_ == other.idx_outgoing_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_outgoing_half_edge_ = mesh_->getNextHalfEdgeIndex( mesh_->getOppositeHalfEdgeIndex(idx_outgoing_half_edge_)); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_outgoing_half_edge_ = mesh_->getOppositeHalfEdgeIndex( mesh_->getPrevHalfEdgeIndex(idx_outgoing_half_edge_)); return (*this); } /** \brief Get the index to the target face. */ inline FaceIndex getTargetIndex() const { return (mesh_->getFaceIndex(idx_outgoing_half_edge_)); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_outgoing_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The outgoing half-edge of the vertex around which we want to circulate. */ HalfEdgeIndex idx_outgoing_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // VertexAroundFaceCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates clockwise around a face and returns an index to the terminating * vertex of the inner half-edge (the target). The best way to declare the circulator is * to use the method pcl::geometry::MeshBase::getVertexAroundFaceCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class VertexAroundFaceCirculator : boost::equality_comparable< pcl::geometry::VertexAroundFaceCirculator, boost::unit_steppable>> { public: using Base = boost::equality_comparable< pcl::geometry::VertexAroundFaceCirculator, boost::unit_steppable>>; using Self = pcl::geometry::VertexAroundFaceCirculator; using Mesh = MeshT; using VertexIndex = typename Mesh::VertexIndex; using FaceIndex = typename Mesh::FaceIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ VertexAroundFaceCirculator() : mesh_(nullptr), idx_inner_half_edge_() {} /** \brief Construct from the face around which we want to circulate. */ VertexAroundFaceCirculator(const FaceIndex& idx_face, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(mesh->getInnerHalfEdgeIndex(idx_face)) {} /** \brief Construct directly from the inner half-edge. */ VertexAroundFaceCirculator(const HalfEdgeIndex& idx_inner_half_edge, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(idx_inner_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_inner_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_inner_half_edge_ == other.idx_inner_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Get the index to the target vertex. */ inline VertexIndex getTargetIndex() const { return (mesh_->getTerminatingVertexIndex(idx_inner_half_edge_)); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_inner_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The inner half-edge of the face around which we want to circulate. */ HalfEdgeIndex idx_inner_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // InnerHalfEdgeAroundFaceCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates clockwise around a face and returns an index to the inner * half-edge (the target). The best way to declare the circulator is to use the method * pcl::geometry::MeshBase::getInnerHalfEdgeAroundFaceCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class InnerHalfEdgeAroundFaceCirculator : boost::equality_comparable< pcl::geometry::InnerHalfEdgeAroundFaceCirculator, boost::unit_steppable>> { public: using Base = boost::equality_comparable< pcl::geometry::InnerHalfEdgeAroundFaceCirculator, boost::unit_steppable>>; using Self = pcl::geometry::InnerHalfEdgeAroundFaceCirculator; using Mesh = MeshT; using FaceIndex = typename Mesh::FaceIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ InnerHalfEdgeAroundFaceCirculator() : mesh_(nullptr), idx_inner_half_edge_() {} /** \brief Construct from the face around which we want to circulate. */ InnerHalfEdgeAroundFaceCirculator(const FaceIndex& idx_face, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(mesh->getInnerHalfEdgeIndex(idx_face)) {} /** \brief Construct directly from the inner half-edge. */ InnerHalfEdgeAroundFaceCirculator(const HalfEdgeIndex& idx_inner_half_edge, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(idx_inner_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_inner_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_inner_half_edge_ == other.idx_inner_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Get the index to the inner half-edge. */ inline HalfEdgeIndex getTargetIndex() const { return (idx_inner_half_edge_); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_inner_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The inner half-edge of the face around which we want to circulate. */ HalfEdgeIndex idx_inner_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // OuterHalfEdgeAroundFaceCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates clockwise around a face and returns an index to the outer * half-edge (the target). The best way to declare the circulator is to use the method * pcl::geometry::MeshBase::getOuterHalfEdgeAroundFaceCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class OuterHalfEdgeAroundFaceCirculator : boost::equality_comparable< pcl::geometry::OuterHalfEdgeAroundFaceCirculator, boost::unit_steppable>> { public: using Base = boost::equality_comparable< pcl::geometry::OuterHalfEdgeAroundFaceCirculator, boost::unit_steppable>>; using Self = pcl::geometry::OuterHalfEdgeAroundFaceCirculator; using Mesh = MeshT; using FaceIndex = typename Mesh::FaceIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ OuterHalfEdgeAroundFaceCirculator() : mesh_(nullptr), idx_inner_half_edge_() {} /** \brief Construct from the face around which we want to circulate. */ OuterHalfEdgeAroundFaceCirculator(const FaceIndex& idx_face, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(mesh->getInnerHalfEdgeIndex(idx_face)) {} /** \brief Construct directly from the inner half-edge. */ OuterHalfEdgeAroundFaceCirculator(const HalfEdgeIndex& idx_inner_half_edge, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(idx_inner_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_inner_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_inner_half_edge_ == other.idx_inner_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Get the index to the outer half-edge. */ inline HalfEdgeIndex getTargetIndex() const { return (mesh_->getOppositeHalfEdgeIndex(idx_inner_half_edge_)); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_inner_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The inner half-edge of the face around which we want to circulate. */ HalfEdgeIndex idx_inner_half_edge_; }; } // End namespace geometry } // End namespace pcl //////////////////////////////////////////////////////////////////////////////// // FaceAroundFaceCirculator //////////////////////////////////////////////////////////////////////////////// namespace pcl { namespace geometry { /** \brief Circulates clockwise around a face and returns an index to the face of the * outer half-edge (the target). The best way to declare the circulator is to use the * method pcl::geometry::MeshBase::getFaceAroundFaceCirculator (). * \tparam MeshT Mesh to which this circulator belongs to. * \note The circulator can't be used to change the connectivity in the mesh (only * const circulators are valid). * \author Martin Saelzle * \ingroup geometry */ template class FaceAroundFaceCirculator : boost::equality_comparable< pcl::geometry::FaceAroundFaceCirculator, boost::unit_steppable>> { public: using Base = boost::equality_comparable< pcl::geometry::FaceAroundFaceCirculator, boost::unit_steppable>>; using Self = pcl::geometry::FaceAroundFaceCirculator; using Mesh = MeshT; using FaceIndex = typename Mesh::FaceIndex; using HalfEdgeIndex = typename Mesh::HalfEdgeIndex; /** \brief Constructor resulting in an invalid circulator. */ FaceAroundFaceCirculator() : mesh_(nullptr), idx_inner_half_edge_() {} /** \brief Construct from the face around which we want to circulate. */ FaceAroundFaceCirculator(const FaceIndex& idx_face, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(mesh->getInnerHalfEdgeIndex(idx_face)) {} /** \brief Construct directly from the inner half-edge. */ FaceAroundFaceCirculator(const HalfEdgeIndex& idx_inner_half_edge, Mesh* const mesh) : mesh_(mesh), idx_inner_half_edge_(idx_inner_half_edge) {} /** \brief Check if the circulator is valid. * \warning Does NOT check if the stored mesh pointer is valid. You have to ensure * this yourself when constructing the circulator. */ inline bool isValid() const { return (idx_inner_half_edge_.isValid()); } /** \brief Comparison operators (with boost::operators): == != * \warning Does NOT check if the circulators belong to the same mesh. Please check * this yourself. */ inline bool operator==(const Self& other) const { return (idx_inner_half_edge_ == other.idx_inner_half_edge_); } /** \brief Increment operators (with boost::operators): ++ (pre and post) */ inline Self& operator++() { idx_inner_half_edge_ = mesh_->getNextHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Decrement operators (with boost::operators): -- (pre and post) */ inline Self& operator--() { idx_inner_half_edge_ = mesh_->getPrevHalfEdgeIndex(idx_inner_half_edge_); return (*this); } /** \brief Get the index to the target face. */ inline FaceIndex getTargetIndex() const { return (mesh_->getOppositeFaceIndex(idx_inner_half_edge_)); } /** \brief Get the half-edge that is currently stored in the circulator. */ inline HalfEdgeIndex getCurrentHalfEdgeIndex() const { return (idx_inner_half_edge_); } /** \brief The mesh to which this circulator belongs to. */ Mesh* mesh_; /** \brief The inner half-edge of the face around which we want to circulate. */ HalfEdgeIndex idx_inner_half_edge_; }; } // End namespace geometry } // End namespace pcl