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

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