Toshihiro Shimizu 890ddd
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