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