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

312 lines
7.0 KiB

  1. /*
  2. * Copyright (C) 2023 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_BREP_VERTEX_HPP
  20. #define ANTKEEPER_GEOM_BREP_VERTEX_HPP
  21. #include <engine/geom/brep/brep-edge.hpp>
  22. #include <engine/geom/brep/brep-element-container.hpp>
  23. #include <cstddef>
  24. #include <iterator>
  25. namespace geom {
  26. class brep_mesh;
  27. class brep_edge;
  28. class brep_vertex;
  29. template <class T>
  30. class brep_element_container;
  31. /**
  32. * List of B-rep edges bounded by a common vertex.
  33. */
  34. class brep_vertex_edge_list
  35. {
  36. public:
  37. friend class brep_mesh;
  38. friend class brep_vertex_container;
  39. friend class brep_edge_container;
  40. struct const_iterator
  41. {
  42. public:
  43. friend class brep_vertex_edge_list;
  44. using iterator_category = std::bidirectional_iterator_tag;
  45. using iterator_concept = std::bidirectional_iterator_tag;
  46. using difference_type = std::ptrdiff_t;
  47. using value_type = brep_edge*;
  48. using pointer = const value_type*;
  49. using reference = const value_type&;
  50. [[nodiscard]] inline constexpr value_type operator*() const noexcept
  51. {
  52. return m_edge;
  53. }
  54. [[nodiscard]] inline constexpr value_type operator->() const noexcept
  55. {
  56. return m_edge;
  57. }
  58. inline const_iterator& operator++() noexcept
  59. {
  60. m_edge = m_edge->m_vertex_next[m_edge->vertices()[1] == m_vertex];
  61. ++m_position;
  62. return *this;
  63. }
  64. [[nodiscard]] inline const_iterator operator++(int) noexcept
  65. {
  66. const_iterator tmp = *this;
  67. ++(*this);
  68. return tmp;
  69. }
  70. inline const_iterator& operator--() noexcept
  71. {
  72. m_edge = m_edge->m_vertex_previous[m_edge->vertices()[1] == m_vertex];
  73. --m_position;
  74. return *this;
  75. }
  76. [[nodiscard]] inline const_iterator operator--(int) noexcept
  77. {
  78. const_iterator tmp = *this;
  79. --(*this);
  80. return tmp;
  81. }
  82. [[nodiscard]] inline bool operator==(const const_iterator& other) const noexcept
  83. {
  84. return m_position == other.m_position;
  85. };
  86. [[nodiscard]] inline std::weak_ordering operator<=>(const const_iterator& other) const noexcept
  87. {
  88. return m_position <=> other.m_position;
  89. }
  90. [[nodiscard]] inline difference_type operator-(const const_iterator& rhs) const noexcept
  91. {
  92. return m_position - rhs.m_position;
  93. }
  94. private:
  95. brep_vertex* m_vertex;
  96. brep_edge* m_edge;
  97. std::ptrdiff_t m_position;
  98. };
  99. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  100. /// @name Element access
  101. /// @{
  102. /// Returns the first edge.
  103. [[nodiscard]] inline brep_edge* front() const noexcept
  104. {
  105. return m_head;
  106. }
  107. /// Returns the last edge.
  108. [[nodiscard]] inline brep_edge* back() const noexcept
  109. {
  110. return m_head->m_vertex_previous[m_head->vertices()[1] == m_vertex];
  111. }
  112. /// @}
  113. /// @name Iterators
  114. /// @{
  115. /// Returns an iterator to the first edge.
  116. /// @{
  117. [[nodiscard]] inline constexpr const_iterator begin() const noexcept
  118. {
  119. const_iterator it;
  120. it.m_vertex = m_vertex;
  121. it.m_edge = m_head;
  122. it.m_position = 0;
  123. return it;
  124. }
  125. [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept
  126. {
  127. return begin();
  128. }
  129. /// @}
  130. /// Returns an iterator to the edge following the last edge.
  131. /// @{
  132. [[nodiscard]] inline constexpr const_iterator end() const noexcept
  133. {
  134. const_iterator it;
  135. it.m_vertex = m_vertex;
  136. it.m_edge = m_head;
  137. it.m_position = static_cast<std::ptrdiff_t>(m_size);
  138. return it;
  139. }
  140. [[nodiscard]] inline constexpr const_iterator cend() const noexcept
  141. {
  142. return end();
  143. }
  144. /// @}
  145. /// Returns a reverse iterator to the first edge of the reversed list.
  146. /// @{
  147. [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept
  148. {
  149. return std::make_reverse_iterator(end());
  150. }
  151. [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept
  152. {
  153. return rbegin();
  154. }
  155. /// @}
  156. /// Returns a reverse iterator to the edge following the last edge of the reversed list.
  157. /// @{
  158. [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept
  159. {
  160. return std::make_reverse_iterator(begin());
  161. }
  162. [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept
  163. {
  164. return rend();
  165. }
  166. /// @}
  167. /// @}
  168. /// @name Capacity
  169. /// @{
  170. /// Returns `true` if the list is empty, `false` otherwise.
  171. [[nodiscard]] inline constexpr bool empty() const noexcept
  172. {
  173. return !m_size;
  174. }
  175. /// Returns the number of edges in the list.
  176. [[nodiscard]] inline constexpr std::size_t size() const noexcept
  177. {
  178. return m_size;
  179. }
  180. /// @}
  181. /// @name Modifiers
  182. /// @{
  183. /**
  184. * Appends an edge to the end of the list.
  185. *
  186. * @param edge Pointer to the edge to append.
  187. */
  188. void push_back(brep_edge* edge);
  189. /**
  190. * Removes an edge from the list.
  191. *
  192. * @param edge Pointer to the edge to remove.
  193. */
  194. void remove(brep_edge* edge);
  195. /// @}
  196. private:
  197. brep_vertex* m_vertex{};
  198. brep_edge* m_head{};
  199. std::size_t m_size{};
  200. };
  201. /**
  202. * A point in space.
  203. */
  204. class brep_vertex
  205. {
  206. public:
  207. friend class brep_mesh;
  208. friend class brep_element_container<brep_vertex>;
  209. friend class brep_vertex_container;
  210. friend class brep_edge_container;
  211. /**
  212. * Returns the index of this vertex in the mesh vertex array.
  213. *
  214. * @warning This index may change if any vertices are removed from the mesh.
  215. */
  216. [[nodiscard]] inline constexpr std::size_t index() const noexcept
  217. {
  218. return m_index;
  219. }
  220. /// Returns the list of edges bounded by this vertex.
  221. [[nodiscard]] inline constexpr const brep_vertex_edge_list& edges() const noexcept
  222. {
  223. return m_edges;
  224. }
  225. private:
  226. std::size_t m_index;
  227. brep_vertex_edge_list m_edges;
  228. };
  229. /**
  230. * B-rep vertex container.
  231. */
  232. class brep_vertex_container: public brep_element_container<brep_vertex>
  233. {
  234. public:
  235. /**
  236. * Appends a new vertex to the end of the container.
  237. *
  238. * @return Pointer to the new vertex.
  239. */
  240. brep_vertex* emplace_back() override;
  241. /**
  242. * Erases a vertex and all dependent edges, loops, and faces.
  243. *
  244. * @param vertex Pointer to the vertex to erase.
  245. *
  246. * @warning Invalidates iterators and indices of vertices, edges, loops, and faces.
  247. */
  248. void erase(brep_vertex* vertex) override;
  249. /**
  250. * Erases all vertices and their dependent edges, loops, and faces.
  251. */
  252. void clear() noexcept;
  253. private:
  254. friend class brep_mesh;
  255. /**
  256. * Constructs a B-rep vertex container.
  257. *
  258. * @param mesh Pointer to the parent mesh.
  259. */
  260. inline explicit brep_vertex_container(brep_mesh* mesh) noexcept:
  261. brep_element_container<brep_vertex>(mesh)
  262. {}
  263. };
  264. } // namespace geom
  265. #endif // ANTKEEPER_GEOM_BREP_VERTEX_HPP