873 lines
31 KiB
C++

/*
* 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 <pcl/geometry/boost.h>
#include <pcl/geometry/mesh_indices.h>
////////////////////////////////////////////////////////////////////////////////
// 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 MeshT>
class VertexAroundVertexCirculator
: boost::equality_comparable<
pcl::geometry::VertexAroundVertexCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::VertexAroundVertexCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::VertexAroundVertexCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::VertexAroundVertexCirculator<MeshT>>>;
using Self = pcl::geometry::VertexAroundVertexCirculator<MeshT>;
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 MeshT>
class OutgoingHalfEdgeAroundVertexCirculator
: boost::equality_comparable<
pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator<MeshT>,
boost::unit_steppable<
pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator<MeshT>,
boost::unit_steppable<
pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator<MeshT>>>;
using Self = pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator<MeshT>;
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 MeshT>
class IncomingHalfEdgeAroundVertexCirculator
: boost::equality_comparable<
pcl::geometry::IncomingHalfEdgeAroundVertexCirculator<MeshT>,
boost::unit_steppable<
pcl::geometry::IncomingHalfEdgeAroundVertexCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::IncomingHalfEdgeAroundVertexCirculator<MeshT>,
boost::unit_steppable<
pcl::geometry::IncomingHalfEdgeAroundVertexCirculator<MeshT>>>;
using Self = pcl::geometry::IncomingHalfEdgeAroundVertexCirculator<MeshT>;
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 MeshT>
class FaceAroundVertexCirculator
: boost::equality_comparable<
pcl::geometry::FaceAroundVertexCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::FaceAroundVertexCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::FaceAroundVertexCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::FaceAroundVertexCirculator<MeshT>>>;
using Self = pcl::geometry::FaceAroundVertexCirculator<MeshT>;
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 MeshT>
class VertexAroundFaceCirculator
: boost::equality_comparable<
pcl::geometry::VertexAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::VertexAroundFaceCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::VertexAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::VertexAroundFaceCirculator<MeshT>>>;
using Self = pcl::geometry::VertexAroundFaceCirculator<MeshT>;
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 MeshT>
class InnerHalfEdgeAroundFaceCirculator
: boost::equality_comparable<
pcl::geometry::InnerHalfEdgeAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::InnerHalfEdgeAroundFaceCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::InnerHalfEdgeAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::InnerHalfEdgeAroundFaceCirculator<MeshT>>>;
using Self = pcl::geometry::InnerHalfEdgeAroundFaceCirculator<MeshT>;
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 MeshT>
class OuterHalfEdgeAroundFaceCirculator
: boost::equality_comparable<
pcl::geometry::OuterHalfEdgeAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::OuterHalfEdgeAroundFaceCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::OuterHalfEdgeAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::OuterHalfEdgeAroundFaceCirculator<MeshT>>>;
using Self = pcl::geometry::OuterHalfEdgeAroundFaceCirculator<MeshT>;
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 MeshT>
class FaceAroundFaceCirculator
: boost::equality_comparable<
pcl::geometry::FaceAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::FaceAroundFaceCirculator<MeshT>>> {
public:
using Base = boost::equality_comparable<
pcl::geometry::FaceAroundFaceCirculator<MeshT>,
boost::unit_steppable<pcl::geometry::FaceAroundFaceCirculator<MeshT>>>;
using Self = pcl::geometry::FaceAroundFaceCirculator<MeshT>;
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