Shinya Kitaoka 810553
// #pragma once // could not use by INCLUDE_HPP
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef MESH_H
Toshihiro Shimizu 890ddd
#define MESH_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "list.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Polygon Mesh template class
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
  \brief    The mesh class models entities composed of vertices, edges and face
Toshihiro Shimizu 890ddd
            using an index-based random access approach.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  This mesh implementation uses 3 separate tcg::list to provide the
Shinya Kitaoka 120a6e
            fundamental index-based access to components, one per component
Shinya Kitaoka 120a6e
  type.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            Said component containers are an explicit requirement of the mesh
Toshihiro Shimizu 890ddd
            class, and direct access is therefore provided. However, use of
Toshihiro Shimizu 890ddd
            (mutating) direct accessors should be restricted to special cases,
Toshihiro Shimizu 890ddd
            since direct components manipulation is \a nontrivial - use the
Toshihiro Shimizu 890ddd
            appropriate \p add and \p remove methods to manipulate single
Toshihiro Shimizu 890ddd
            components.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  \sa       Classes tcg::Vertex, tcg::Edge and tcg::Face  for
Shinya Kitaoka 120a6e
  tcg::Mesh-compatible
Toshihiro Shimizu 890ddd
            VEF models.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
class Mesh {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef V vertex_type;
Shinya Kitaoka 120a6e
  typedef E edge_type;
Shinya Kitaoka 120a6e
  typedef F face_type;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typedef list<v> vertices_container;</v>
Shinya Kitaoka 120a6e
  typedef list<e> edges_container;</e>
Shinya Kitaoka 120a6e
  typedef list<f> faces_container;</f>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  vertices_container m_vertices;
Shinya Kitaoka 120a6e
  edges_container m_edges;
Shinya Kitaoka 120a6e
  faces_container m_faces;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Mesh() {}
Shinya Kitaoka 120a6e
  ~Mesh() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool empty() const { return m_vertices.empty(); }
Shinya Kitaoka 120a6e
  void clear() {
Shinya Kitaoka 120a6e
    m_vertices.clear();
Shinya Kitaoka 120a6e
    m_edges.clear();
Shinya Kitaoka 120a6e
    m_faces.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int verticesCount() const { return int(m_vertices.size()); }
Shinya Kitaoka 120a6e
  int edgesCount() const { return int(m_edges.size()); }
Shinya Kitaoka 120a6e
  int facesCount() const { return int(m_faces.size()); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const vertices_container &vertices() const { return m_vertices; }
Shinya Kitaoka 120a6e
  vertices_container &vertices() { return m_vertices; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const edges_container &edges() const { return m_edges; }
Shinya Kitaoka 120a6e
  edges_container &edges() { return m_edges; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const faces_container &faces() const { return m_faces; }
Shinya Kitaoka 120a6e
  faces_container &faces() { return m_faces; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int addVertex(const V &v) {
Shinya Kitaoka 120a6e
    int idx = int(m_vertices.push_back(v));
Shinya Kitaoka 120a6e
    m_vertices[idx].setIndex(idx);
Shinya Kitaoka 120a6e
    return idx;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int addEdge(const E &e);
Shinya Kitaoka 120a6e
  int addFace(const F &f);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void removeVertex(int v);  //!< Removes the <tt>v</tt>-th vertex from the
Shinya Kitaoka 38fd86
                             //! mesh.  \warning  Any adjacent edge or face will
Shinya Kitaoka 38fd86
  //! be removed, too.  \param v  Index of the vertex
Shinya Kitaoka 38fd86
  //! to be removed.
Shinya Kitaoka 38fd86
  void removeEdge(int e);  //!< Removes the <tt>e</tt>-th edge from the mesh.
Shinya Kitaoka 120a6e
                           //!\warning  Any adjacent face will be removed, too.
Shinya Kitaoka 120a6e
                           //!\param e  Index of the edge to be removed.
Shinya Kitaoka 120a6e
  void removeFace(int f);  //!< Removes the <tt>f</tt>-th face from the mesh.
Shinya Kitaoka 120a6e
                           //!\param f  Index of the face to be removed.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const V &vertex(int v) const { return m_vertices[v]; }
Shinya Kitaoka 120a6e
  V &vertex(int v) {
Shinya Kitaoka 120a6e
    return m_vertices[v];
Shinya Kitaoka 120a6e
  }  //!< Returns the <tt>v</tt>-th mesh vertex.   \param v  Index of the vertex
Shinya Kitaoka 38fd86
     //! to be returned.  \return  See description.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const E &edge(int e) const { return m_edges[e]; }
Shinya Kitaoka 120a6e
  E &edge(int e) {
Shinya Kitaoka 120a6e
    return m_edges[e];
Shinya Kitaoka 120a6e
  }  //!< Returns the <tt>e</tt>-th mesh edge.   \param e  Index of the edge to
Shinya Kitaoka 38fd86
     //! be returned.  \return  See description.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const F &face(int f) const { return m_faces[f]; }
Shinya Kitaoka 120a6e
  F &face(int f) {
Shinya Kitaoka 120a6e
    return m_faces[f];
Shinya Kitaoka 120a6e
  }  //!< Returns the <tt>f</tt>-th mesh face.   \param f  Index of the face to
Shinya Kitaoka 38fd86
     //! be returned.  \return  See description.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const V &edgeVertex(int e, int i) const { return vertex(edge(e).vertex(i)); }
Shinya Kitaoka 120a6e
  V &edgeVertex(int e, int i)  //!  \param e  Host edge index.  \param i  Vertex
Shinya Kitaoka 120a6e
                               //!  index in e.  \return See description.
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return vertex(edge(e).vertex(i));
Shinya Kitaoka 120a6e
  }  //!< Returns the <tt>i</tt>-th vertex in the edge of index \p e.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const F &edgeFace(int e, int i) const { return face(edge(e).face(i)); }
Shinya Kitaoka 120a6e
  F &edgeFace(int e, int i)  //!  \param e  Host edge index.  \param i  Face
Shinya Kitaoka 120a6e
                             //!  index in e.  \return See description.
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return face(edge(e).face(i));
Shinya Kitaoka 120a6e
  }  //!< Returns the <tt>i</tt>-th face in the edge of index \p e.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const V &otherEdgeVertex(int e, int v) const {
Shinya Kitaoka 120a6e
    return vertex(edge(e).otherVertex(v));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  V &otherEdgeVertex(int e, int v)  //!  \param e  Host edge index.  \param v
Shinya Kitaoka 120a6e
                                    //!  Index of the adjacent vertex to \p e
Shinya Kitaoka 120a6e
                                    //!  we're not interested in.  \return See
Shinya Kitaoka 120a6e
                                    //!  description.
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return vertex(edge(e).otherVertex(v));
Shinya Kitaoka 120a6e
  }  //!< Retrieves the vertex adjacent to \p e whose index is \a not \p v.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const F &otherEdgeFace(int e, int f) const {
Shinya Kitaoka 120a6e
    return face(edge(e).otherFace(f));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  F &otherEdgeFace(int e, int f)  //!  \param e  Host edge index.  \param f
Shinya Kitaoka 120a6e
                                  //!  Index of the adjacent face to \p e we're
Shinya Kitaoka 120a6e
                                  //!  not interested in.  \return See
Shinya Kitaoka 120a6e
                                  //!  description.
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return face(edge(e).otherFace(f));
Shinya Kitaoka 120a6e
  }  //!< Retrieves the face adjacent to \p e whose index is \a not \p f.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
\remark   Index \p n is arbitrary. Use it to traverse all edges inciding \p v1
Shinya Kitaoka 120a6e
and \p v2:
Shinya Kitaoka 120a6e
          \code for(int n=0; mesh.edgeInciding(v1, v2, n) > 0; ++n) ... \endcode
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  int edgeInciding(int v1, int v2, int n = 0) const;  //!< \brief Returns the
Shinya Kitaoka 38fd86
                                                      //! edge index of the
Shinya Kitaoka 38fd86
  //!<tt>n</tt>-th edge
Shinya Kitaoka 38fd86
  //! inciding
Shinya Kitaoka 120a6e
  //!  \p v1 and \p v2, or \p -1 if the required edge could not be found.
Shinya Kitaoka 120a6e
  //!  \param v1  First edge endpoint.  \param v2  Second edge endpoint.  \param
Shinya Kitaoka 120a6e
  //!  n  Index in the sequence of all edges inciding \p v1 and \p v2.  \return
Shinya Kitaoka 120a6e
  //!  See description.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! \remark  All indices and iterators will be \a invalidated.
Shinya Kitaoka 120a6e
  void
Shinya Kitaoka 120a6e
  squeeze();  //!< \brief Eliminates unused list nodes in the representation of
Shinya Kitaoka 120a6e
              //!  vertices, edges and faces.
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Triangular Mesh template class
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
class TriMesh : public Mesh<v, e,="" f=""> {</v,>
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  using Mesh<v, e,="" f="">::m_vertices;</v,>
Shinya Kitaoka 120a6e
  using Mesh<v, e,="" f="">::m_edges;</v,>
Shinya Kitaoka 120a6e
  using Mesh<v, e,="" f="">::m_faces;</v,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TriMesh() {}
Shinya Kitaoka 120a6e
  TriMesh(int verticesHint);
Shinya Kitaoka 120a6e
  ~TriMesh() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int addFace(V &v1, V &v2, V &v3);
Shinya Kitaoka 120a6e
  int addFace(int v1, int v2, int v3) {
Shinya Kitaoka 120a6e
    return addFace(Mesh<v, e,="" f="">::vertex(v1), Mesh<v, e,="" f="">::vertex(v2),</v,></v,>
Shinya Kitaoka 120a6e
                   Mesh<v, e,="" f="">::vertex(v3));</v,>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int otherFaceVertex(int f, int e) const;
Shinya Kitaoka 120a6e
  int otherFaceVertex(int f, int v1, int v2) const {
Shinya Kitaoka 120a6e
    return otherFaceVertex(f, Mesh<v, e,="" f="">::edgeInciding(v1, v2));</v,>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int otherFaceEdge(int f, int v) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void faceVertices(int f, int &v1, int &v2, int &v3) const {
Shinya Kitaoka 120a6e
    const E &ed = Mesh<v, e,="" f="">::edge(Mesh<v, e,="" f="">::face(f).edge(0));</v,></v,>
Shinya Kitaoka 120a6e
    v1          = ed.vertex(0);
Shinya Kitaoka 120a6e
    v2          = ed.vertex(1);
Shinya Kitaoka 120a6e
    v3          = otherFaceVertex(f, ed.getIndex());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
\details    This function selects an edge with \a two adjacent faces, and swaps
Shinya Kitaoka 120a6e
          its endpoints with their otherFaceVertex().
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\remark     This function is idempotent - swapEdge(swapEdge(e)) has no effect
Shinya Kitaoka 120a6e
          on the mesh (assuming swapEdge(e) is not \p -1). In particular,
Shinya Kitaoka 120a6e
indices
Shinya Kitaoka 120a6e
          should remain the same.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\note       In current implementation, the result is the very same input
Shinya Kitaoka 120a6e
          edge index.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\return     The swapped edge, or \p -1 if the supplied edge did not have \a two
Shinya Kitaoka 120a6e
          adjacent faces.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  int swapEdge(
Shinya Kitaoka 120a6e
      int e);  //!< Swaps the specified edge in the \a two adjacent faces.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
\details    Specifically, this function removes <tt>edgeVertex(e, 1)</tt> and
Shinya Kitaoka 120a6e
redirects its edges to
Shinya Kitaoka 120a6e
          <tt>edgeVertex(e, 0)</tt>. One edge per adjacent face (other than \p
Shinya Kitaoka 120a6e
e) will be removed
Shinya Kitaoka 120a6e
          (which can be thought as 'merged' with the remaining one), and each
Shinya Kitaoka 120a6e
adjacent face will be
Shinya Kitaoka 120a6e
          removed.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\note       This function removes at most 1 vertex, 3 edges and 2 faces,
Shinya Kitaoka 120a6e
total.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\warning    The user is respondible for ensuring that every vertex adjacent to
Shinya Kitaoka 120a6e
\a both the
Shinya Kitaoka 120a6e
          collapsed edge's endpoints is \a also adjacent to one of the edge's \a
Shinya Kitaoka 120a6e
faces.
Shinya Kitaoka 120a6e
          If not, the output configuration would be ill-formed. This function
Shinya Kitaoka 120a6e
will
Shinya Kitaoka 120a6e
          \a assert in this case, and result in undefined behavior.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\return     The remaining vertex index - specifically, <tt>edgeVertex(e,</tt>
Shinya Kitaoka 120a6e
0).
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  int collapseEdge(int e);  //!< Collapses the specified edge.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
\details    This function inserts a new vertex at the midpoint of the specified
Shinya Kitaoka 120a6e
edge, and
Shinya Kitaoka 120a6e
          splits any adjacent face in two.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\return     The inserted vertex index.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  int splitEdge(int e);  //!< \brief Splits the specified edge, inserting a new
Shinya Kitaoka 120a6e
                         //!  vertex at the middle.
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // MESH_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef INCLUDE_HPP
Toshihiro Shimizu 890ddd
#include "hpp/mesh.hpp"
Toshihiro Shimizu 890ddd
#endif