Antkeeper  0.0.1
brep-mesh.cpp
Go to the documentation of this file.
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 
21 #include <engine/math/vector.hpp>
25 #include <array>
26 
27 namespace geom {
28 
30  m_vertices(this),
31  m_edges(this),
32  m_loops(this),
33  m_faces(this)
34 {}
35 
37  brep_mesh()
38 {
39  *this = other;
40 }
41 
43 {
44  // Allocate containers
45  m_vertices.m_elements.resize(other.m_vertices.m_elements.size());
46  m_edges.m_elements.resize(other.m_edges.m_elements.size());
47  m_loops.m_elements.resize(other.m_loops.m_elements.size());
48  m_faces.m_elements.resize(other.m_faces.m_elements.size());
49 
50  // Copy-construct elements
51  for (std::size_t i = 0; i < m_vertices.m_elements.size(); ++i)
52  {
53  m_vertices.m_elements[i] = std::make_unique<brep_vertex>(*other.m_vertices.m_elements[i]);
54  }
55  for (std::size_t i = 0; i < m_edges.m_elements.size(); ++i)
56  {
57  m_edges.m_elements[i] = std::make_unique<brep_edge>(*other.m_edges.m_elements[i]);
58  }
59  for (std::size_t i = 0; i < m_loops.m_elements.size(); ++i)
60  {
61  m_loops.m_elements[i] = std::make_unique<brep_loop>(*other.m_loops.m_elements[i]);
62  }
63  for (std::size_t i = 0; i < m_faces.m_elements.size(); ++i)
64  {
65  m_faces.m_elements[i] = std::make_unique<brep_face>(*other.m_faces.m_elements[i]);
66  }
67 
68  // Copy per-element attributes
69  m_vertices.m_attribute_map = other.m_vertices.m_attribute_map;
70  m_edges.m_attribute_map = other.m_edges.m_attribute_map;
71  m_loops.m_attribute_map = other.m_loops.m_attribute_map;
72  m_faces.m_attribute_map = other.m_faces.m_attribute_map;
73 
74  // Reassign element pointers
75  for (const auto& vertex: m_vertices.m_elements)
76  {
77  if (!vertex->edges().empty())
78  {
79  vertex->m_edges.m_head = m_edges.m_elements[vertex->m_edges.m_head->m_index].get();
80  }
81  }
82  for (const auto& edge: m_edges.m_elements)
83  {
84  edge->m_vertices[0] = m_vertices.m_elements[edge->m_vertices[0]->m_index].get();
85  edge->m_vertices[1] = m_vertices.m_elements[edge->m_vertices[1]->m_index].get();
86  edge->m_vertex_next[0] = m_edges.m_elements[edge->m_vertex_next[0]->m_index].get();
87  edge->m_vertex_next[1] = m_edges.m_elements[edge->m_vertex_next[1]->m_index].get();
88  edge->m_vertex_previous[0] = m_edges.m_elements[edge->m_vertex_previous[0]->m_index].get();
89  edge->m_vertex_previous[1] = m_edges.m_elements[edge->m_vertex_previous[1]->m_index].get();
90 
91  if (!edge->loops().empty())
92  {
93  edge->m_loops.m_head = m_loops.m_elements[edge->m_loops.m_head->m_index].get();
94  }
95  }
96  for (const auto& loop: m_loops.m_elements)
97  {
98  loop->m_vertex = m_vertices.m_elements[loop->m_vertex->m_index].get();
99  loop->m_edge = m_edges.m_elements[loop->m_edge->m_index].get();
100  loop->m_face = m_faces.m_elements[loop->m_face->m_index].get();
101  loop->m_edge_next = m_loops.m_elements[loop->m_edge_next->m_index].get();
102  loop->m_edge_previous = m_loops.m_elements[loop->m_edge_previous->m_index].get();
103  loop->m_face_next = m_loops.m_elements[loop->m_face_next->m_index].get();
104  loop->m_face_previous = m_loops.m_elements[loop->m_face_previous->m_index].get();
105  }
106  for (const auto& face: m_faces.m_elements)
107  {
108  face->m_loops.m_head = m_loops.m_elements[face->m_loops.m_head->m_index].get();
109  }
110 
111  return *this;
112 }
113 
114 void brep_mesh::clear() noexcept
115 {
116  m_vertices.clear();
117 }
118 
119 } // namespace geom
120 
129 template <>
131 {
132  // Read vertex, edge, and face counts
133  std::uint32_t vertex_count = 0;
134  std::uint32_t edge_count = 0;
135  std::uint32_t face_count = 0;
136  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&vertex_count), 1);
137  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&edge_count), 1);
138  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&face_count), 1);
139 
140  // Make vertices
141  for (std::size_t i = 0; i < vertex_count; ++i)
142  {
143  mesh.vertices().emplace_back();
144  }
145 
146  // Read edge vertex indices into buffer
147  std::vector<std::array<std::uint32_t, 2>> edges(edge_count);
148  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(edges.data()), edge_count * 2);
149 
150  // Make edges
151  for (const auto& e: edges)
152  {
153  mesh.edges().emplace_back(mesh.vertices()[e[0]], mesh.vertices()[e[1]]);
154  }
155  edges.clear();
156 
157  // Read face vertex indices into buffer
158  std::vector<std::array<std::uint32_t, 3>> faces(face_count);
159  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(faces.data()), face_count * 3);
160 
161  // Make faces
162  for (const auto& f: faces)
163  {
164  geom::brep_vertex* vertices[3] = {mesh.vertices()[f[0]], mesh.vertices()[f[1]], mesh.vertices()[f[2]]};
165  mesh.faces().emplace_back(vertices);
166  }
167  faces.clear();
168 
169  // Make vertex attributes
170  auto& vertex_positions = static_cast<geom::brep_attribute<math::fvec3>&>(*mesh.vertices().attributes().emplace<math::fvec3>("position"));
171 
172  // Read vertex attributes
173  ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(vertex_positions.data()), vertex_count * 3);
174 }
175 
176 template <>
178 {
179  auto resource = std::make_unique<geom::brep_mesh>();
180  deserializer<geom::brep_mesh>().deserialize(*resource, ctx);
181  return resource;
182 }
Per-element B-rep data.
constexpr std::size_t size() const noexcept
Returns the number of elements in the container.
Boundary representation (B-rep) of a mesh.
Definition: brep-mesh.hpp:34
void clear() noexcept
Erases all vertices, edges, loops, and faces.
Definition: brep-mesh.cpp:114
brep_mesh() noexcept
Constructs an empty mesh.
Definition: brep-mesh.cpp:29
brep_mesh & operator=(const brep_mesh &other)
Copies another mesh into this mesh.
Definition: brep-mesh.cpp:42
void clear() noexcept
Erases all vertices and their dependent edges, loops, and faces.
Definition: brep-vertex.cpp:94
A point in space.
static std::unique_ptr< T > load(::resource_manager &resource_manager, deserialize_context &ctx)
Loads a resource.
Manages the loading, caching, and saving of resources.
Geometric algorithms.
constexpr T e
e.
Definition: numbers.hpp:37
Provides access to a deserialization state.
std::size_t read32(std::byte *data, std::size_t count) noexcept(false)
Reads 32-bit (double word) data.
Specializations of deserializer define the deserialization process for a given type.
void deserialize(T &value, deserialize_context &ctx)
Deserializes a value.
n-dimensional vector.
Definition: vector.hpp:44