💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
4.8 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_GEOM_MESH_HPP
  20. #define ANTKEEPER_GEOM_MESH_HPP
  21. #include "utility/fundamental-types.hpp"
  22. #include <vector>
  23. namespace geom {
  24. /**
  25. * Half-edge mesh.
  26. *
  27. * @see http://kaba.hilvi.org/homepage/blog/halfedge/halfedge.htm
  28. */
  29. class mesh
  30. {
  31. public:
  32. struct vertex;
  33. struct edge;
  34. struct face;
  35. /// List of edges which form a face.
  36. typedef std::vector<edge*> loop;
  37. /**
  38. * Constructs a mesh.
  39. */
  40. mesh() = default;
  41. /// Copy-constructs a mesh.
  42. mesh(const mesh& other);
  43. /**
  44. * Destroys a mesh.
  45. */
  46. ~mesh();
  47. /// Copies another mesh into this mesh.
  48. mesh& operator=(const mesh& other);
  49. /// Removes all vertices, edges, and faces from the mesh.
  50. void clear();
  51. /**
  52. * Adds a vertex to the mesh. This vertex initially has a null edge.
  53. *
  54. * @param position Position of the vertex.
  55. * @return Pointer to the added vertex.
  56. */
  57. mesh::vertex* add_vertex(const float3& position);
  58. /**
  59. * Adds an edge to the mesh.
  60. *
  61. * @param a The vertex from which the edge originates.
  62. * @param b The vertex at which the edge ends.
  63. * @return Pointer to the added edge.
  64. */
  65. mesh::edge* add_edge(mesh::vertex* a, mesh::vertex* b);
  66. /**
  67. * Adds a face to the mesh.
  68. *
  69. * @param loop List of edges which form the face.
  70. * @return Pointer to the added face.
  71. *
  72. * @exception std::runtime_error Empty edge loop.
  73. * @exception std::runtime_error Disconnected edge loop.
  74. * @exception std::runtime_error Non-manifold mesh 1.
  75. * @exception std::runtime_error Non-manifold mesh 2.
  76. */
  77. mesh::face* add_face(const loop& loop);
  78. /**
  79. * Removes a face from the mesh.
  80. *
  81. * @param face Face to be removed. This face will be deallocated after removal.
  82. */
  83. void remove_face(mesh::face* face);
  84. /**
  85. * Removes an edge and all dependent faces from the mesh.
  86. *
  87. * @param edge Edge to be removed. This edge will be deallocated after removal.
  88. */
  89. void remove_edge(mesh::edge* edge);
  90. /**
  91. * Removes a vertex, all dependent edges, and all dependent faces from the mesh.
  92. *
  93. * @param vertex Vertex to be removed. This vertex will be deallocated after removal.
  94. */
  95. void remove_vertex(mesh::vertex* vertex);
  96. /// Returns the mesh vertices
  97. const std::vector<mesh::vertex*>& get_vertices() const;
  98. /// Returns the mesh edges
  99. const std::vector<mesh::edge*>& get_edges() const;
  100. /// Returns the mesh faces
  101. const std::vector<mesh::face*>& get_faces() const;
  102. /**
  103. * Half-edge vertex which contains its index, a pointer to its parent edge, and its position vector.
  104. */
  105. struct vertex
  106. {
  107. /// Index of this vertex.
  108. std::size_t index;
  109. /// Pointer to the edge to which this vertex belongs.
  110. mesh::edge* edge;
  111. /// Vertex position.
  112. float3 position;
  113. };
  114. /**
  115. * Half-edge edge which contains its index and pointers to its starting vertex, parent face, and related edges.
  116. */
  117. struct edge
  118. {
  119. /// Index of this edge.
  120. std::size_t index;
  121. /// Pointer to the vertex at which the edge starts.
  122. mesh::vertex* vertex;
  123. /// Pointer to the face on the left of this edge.
  124. mesh::face* face;
  125. /// Pointer to the previous edge in the parent face.
  126. mesh::edge* previous;
  127. /// Pointer to the next edge in the parent face.
  128. mesh::edge* next;
  129. /// Pointer to the symmetric edge.
  130. mesh::edge* symmetric;
  131. };
  132. /**
  133. * Half-edge face which contains its index and a pointer to its first edge.
  134. */
  135. struct face
  136. {
  137. /// Index of this face.
  138. std::size_t index;
  139. /// Pointer to the first edge in this face.
  140. mesh::edge* edge;
  141. };
  142. private:
  143. mesh::edge* find_free_incident(mesh::vertex* vertex) const;
  144. mesh::edge* find_free_incident(mesh::edge* start_edge, mesh::edge* end_edge) const;
  145. bool make_adjacent(mesh::edge* in_edge, mesh::edge* out_edge);
  146. std::vector<mesh::vertex*> vertices;
  147. std::vector<mesh::edge*> edges;
  148. std::vector<mesh::face*> faces;
  149. };
  150. inline const std::vector<mesh::vertex*>& mesh::get_vertices() const
  151. {
  152. return vertices;
  153. }
  154. inline const std::vector<mesh::edge*>& mesh::get_edges() const
  155. {
  156. return edges;
  157. }
  158. inline const std::vector<mesh::face*>& mesh::get_faces() const
  159. {
  160. return faces;
  161. }
  162. } // namespace geom
  163. #endif // ANTKEEPER_GEOM_MESH_HPP