/* * Copyright (C) 2021 Christopher J. Howard * * This file is part of Antkeeper source code. * * Antkeeper source code is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Antkeeper source code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Antkeeper source code. If not, see . */ #ifndef ANTKEEPER_GEOM_MESH_HPP #define ANTKEEPER_GEOM_MESH_HPP #include #include "utility/fundamental-types.hpp" namespace geom { /** * Half-edge mesh. * * @see http://kaba.hilvi.org/homepage/blog/halfedge/halfedge.htm */ class mesh { public: struct vertex; struct edge; struct face; typedef std::vector loop; /** * Constructs a mesh. */ mesh() = default; /// Copy-constructs a mesh. mesh(const mesh& other); /** * Destroys a mesh. */ ~mesh(); /// Copies another mesh into this mesh. mesh& operator=(const mesh& other); /// Removes all vertices, edges, and faces from the mesh. void clear(); /** * Adds a vertex to the mesh. This vertex initially has a null edge. * * @param position Position of the vertex. * @return Pointer to the added vertex. */ mesh::vertex* add_vertex(const float3& position); /** * Adds an edge to the mesh. * * @param a The vertex from which the edge originates. * @param b The vertex at which the edge ends. * @return Pointer to the added edge. */ mesh::edge* add_edge(mesh::vertex* a, mesh::vertex* b); /** * Adds a face to the mesh. * * @param loop List of edges which form the face. * @return Pointer to the added face. * * @exception std::runtime_error Empty edge loop. * @exception std::runtime_error Disconnected edge loop. * @exception std::runtime_error Non-manifold mesh 1. * @exception std::runtime_error Non-manifold mesh 2. */ mesh::face* add_face(const loop& loop); /** * Removes a face from the mesh. * * @param face Face to be removed. This face will be deallocated after removal. */ void remove_face(mesh::face* face); /** * Removes an edge and all dependent faces from the mesh. * * @param edge Edge to be removed. This edge will be deallocated after removal. */ void remove_edge(mesh::edge* edge); /** * Removes a vertex, all dependent edges, and all dependent faces from the mesh. * * @param vertex Vertex to be removed. This vertex will be deallocated after removal. */ void remove_vertex(mesh::vertex* vertex); /// Returns the mesh vertices const std::vector& get_vertices() const; /// Returns the mesh edges const std::vector& get_edges() const; /// Returns the mesh faces const std::vector& get_faces() const; /** * Half-edge vertex which contains a pointer to its parent edge, a position vector, and an index. */ struct vertex { /// Pointer to the edge to which this vertex belongs mesh::edge* edge; /// Vertex position float3 position; /// Index of this vertex std::size_t index; }; /** * Half-edge edge which contains pointers to its starting vertex, parent face, and related edges. */ struct edge { /// Pointer to the vertex at which the edge starts mesh::vertex* vertex; /// Pointer to the face on the left of this edge mesh::face* face; /// Pointer to the previous edge in the parent face mesh::edge* previous; /// Pointer to the next edge in the parent face mesh::edge* next; /// Pointer to the symmetric edge mesh::edge* symmetric; /// Index of this edge std::size_t index; }; /** * Half-edge face which contains a pointer to its first edge and its normal vector. */ struct face { /// Pointer to the first edge in this face mesh::edge* edge; /// Index of this face std::size_t index; }; private: mesh::edge* find_free_incident(mesh::vertex* vertex) const; mesh::edge* find_free_incident(mesh::edge* start_edge, mesh::edge* end_edge) const; bool make_adjacent(mesh::edge* in_edge, mesh::edge* out_edge); std::vector vertices; std::vector edges; std::vector faces; }; inline const std::vector& mesh::get_vertices() const { return vertices; } inline const std::vector& mesh::get_edges() const { return edges; } inline const std::vector& mesh::get_faces() const { return faces; } } // namespace geom #endif // ANTKEEPER_GEOM_MESH_HPP