💿🐜 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.

199 lines
4.7 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 <vector>
  22. #include "utility/fundamental-types.hpp"
  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. typedef std::vector<edge*> loop;
  36. /**
  37. * Constructs a mesh.
  38. */
  39. mesh() = default;
  40. /// Copy-constructs a mesh.
  41. mesh(const mesh& other);
  42. /**
  43. * Destroys a mesh.
  44. */
  45. ~mesh();
  46. /// Copies another mesh into this mesh.
  47. mesh& operator=(const mesh& other);
  48. /// Removes all vertices, edges, and faces from the mesh.
  49. void clear();
  50. /**
  51. * Adds a vertex to the mesh. This vertex initially has a null edge.
  52. *
  53. * @param position Position of the vertex.
  54. * @return Pointer to the added vertex.
  55. */
  56. mesh::vertex* add_vertex(const float3& position);
  57. /**
  58. * Adds an edge to the mesh.
  59. *
  60. * @param a The vertex from which the edge originates.
  61. * @param b The vertex at which the edge ends.
  62. * @return Pointer to the added edge.
  63. */
  64. mesh::edge* add_edge(mesh::vertex* a, mesh::vertex* b);
  65. /**
  66. * Adds a face to the mesh.
  67. *
  68. * @param loop List of edges which form the face.
  69. * @return Pointer to the added face.
  70. *
  71. * @exception std::runtime_error Empty edge loop.
  72. * @exception std::runtime_error Disconnected edge loop.
  73. * @exception std::runtime_error Non-manifold mesh 1.
  74. * @exception std::runtime_error Non-manifold mesh 2.
  75. */
  76. mesh::face* add_face(const loop& loop);
  77. /**
  78. * Removes a face from the mesh.
  79. *
  80. * @param face Face to be removed. This face will be deallocated after removal.
  81. */
  82. void remove_face(mesh::face* face);
  83. /**
  84. * Removes an edge and all dependent faces from the mesh.
  85. *
  86. * @param edge Edge to be removed. This edge will be deallocated after removal.
  87. */
  88. void remove_edge(mesh::edge* edge);
  89. /**
  90. * Removes a vertex, all dependent edges, and all dependent faces from the mesh.
  91. *
  92. * @param vertex Vertex to be removed. This vertex will be deallocated after removal.
  93. */
  94. void remove_vertex(mesh::vertex* vertex);
  95. /// Returns the mesh vertices
  96. const std::vector<mesh::vertex*>& get_vertices() const;
  97. /// Returns the mesh edges
  98. const std::vector<mesh::edge*>& get_edges() const;
  99. /// Returns the mesh faces
  100. const std::vector<mesh::face*>& get_faces() const;
  101. /**
  102. * Half-edge vertex which contains a pointer to its parent edge, a position vector, and an index.
  103. */
  104. struct vertex
  105. {
  106. /// Pointer to the edge to which this vertex belongs
  107. mesh::edge* edge;
  108. /// Vertex position
  109. float3 position;
  110. /// Index of this vertex
  111. std::size_t index;
  112. };
  113. /**
  114. * Half-edge edge which contains pointers to its starting vertex, parent face, and related edges.
  115. */
  116. struct edge
  117. {
  118. /// Pointer to the vertex at which the edge starts
  119. mesh::vertex* vertex;
  120. /// Pointer to the face on the left of this edge
  121. mesh::face* face;
  122. /// Pointer to the previous edge in the parent face
  123. mesh::edge* previous;
  124. /// Pointer to the next edge in the parent face
  125. mesh::edge* next;
  126. /// Pointer to the symmetric edge
  127. mesh::edge* symmetric;
  128. /// Index of this edge
  129. std::size_t index;
  130. };
  131. /**
  132. * Half-edge face which contains a pointer to its first edge and its normal vector.
  133. */
  134. struct face
  135. {
  136. /// Pointer to the first edge in this face
  137. mesh::edge* edge;
  138. /// Index of this face
  139. std::size_t index;
  140. };
  141. private:
  142. mesh::edge* find_free_incident(mesh::vertex* vertex) const;
  143. mesh::edge* find_free_incident(mesh::edge* start_edge, mesh::edge* end_edge) const;
  144. bool make_adjacent(mesh::edge* in_edge, mesh::edge* out_edge);
  145. std::vector<mesh::vertex*> vertices;
  146. std::vector<mesh::edge*> edges;
  147. std::vector<mesh::face*> faces;
  148. };
  149. inline const std::vector<mesh::vertex*>& mesh::get_vertices() const
  150. {
  151. return vertices;
  152. }
  153. inline const std::vector<mesh::edge*>& mesh::get_edges() const
  154. {
  155. return edges;
  156. }
  157. inline const std::vector<mesh::face*>& mesh::get_faces() const
  158. {
  159. return faces;
  160. }
  161. } // namespace geom
  162. #endif // ANTKEEPER_GEOM_MESH_HPP