31 const auto& vertex_positions = mesh.vertices().attributes().at<
math::fvec3>(
"position");
36 auto loop = face->loops().begin();
37 const auto&
a = vertex_positions[loop->vertex()->index()];
38 const auto&
b = vertex_positions[(++loop)->vertex()->index()];
39 const auto&
c = vertex_positions[(++loop)->vertex()->index()];
48 if (!mesh.faces().attributes().contains(
"normal"))
53 const auto& vertex_positions = mesh.vertices().attributes().at<
math::fvec3>(
"position");
54 const auto& face_normals = mesh.faces().attributes().at<
math::fvec3>(
"normal");
60 auto& vertex_normal = vertex_normals[vertex->index()];
64 if (vertex->edges().empty())
70 const auto& vertex_position = vertex_positions[vertex->index()];
76 if (edge->loops().empty())
84 vertex_positions[edge->vertices()[edge->vertices().front() == vertex]->index()] -
92 if (loop->vertex() != vertex)
100 vertex_positions[loop->previous()->vertex()->index()] -
105 const auto cos_edge_angle =
math::dot(direction0, direction1);
106 const auto edge_angle = std::acos(cos_edge_angle);
109 vertex_normal += face_normals[loop->face()->index()] * edge_angle;
124 const auto& vertex_positions = mesh.vertices().attributes().at<
math::fvec3>(
"position");
129 auto loop = face->loops().begin();
130 loop_barycentric[loop->index()] = {1.0f, 0.0f, 0.0f};
131 loop_barycentric[(++loop)->index()] = {0.0f, 1.0f, 0.0f};
132 loop_barycentric[(++loop)->index()] = {0.0f, 0.0f, 1.0f};
140 if (
auto attribute_it = mesh.vertices().attributes().find(
"position"); attribute_it != mesh.vertices().attributes().end())
147 if (
auto attribute_it = mesh.vertices().attributes().find(
"normal"); attribute_it != mesh.vertices().attributes().end())
153 auto model = std::make_unique<render::model>();
156 auto& bounds = model->get_bounds();
160 std::size_t vertex_stride = 0;
161 std::vector<gl::vertex_input_attribute> vertex_attributes;
163 if (vertex_positions)
166 position_attribute.binding = 0;
168 position_attribute.offset = 0;
169 vertex_attributes.emplace_back(position_attribute);
171 vertex_stride += 3 *
sizeof(float);
177 normal_attribute.binding = 0;
179 normal_attribute.offset =
static_cast<std::uint32_t
>(vertex_stride);
180 vertex_attributes.emplace_back(normal_attribute);
182 vertex_stride += 3 *
sizeof(float);
184 auto& vao = model->get_vertex_array();
185 vao = std::make_unique<gl::vertex_array>(vertex_attributes);
188 std::vector<std::byte> vertex_data(mesh.faces().size() * 3 * vertex_stride);
189 if (vertex_positions)
191 std::byte* v = vertex_data.data() + position_attribute.offset;
192 for (
auto face: mesh.faces())
194 for (
auto loop: face->loops())
196 const auto&
position = (*vertex_positions)[loop->vertex()->index()];
197 std::memcpy(v,
position.data(),
sizeof(
float) * 3);
207 std::byte* v = vertex_data.data() + normal_attribute.offset;
208 for (
auto face: mesh.faces())
210 for (
auto loop: face->loops())
212 const auto& normal = (*vertex_normals)[loop->vertex()->index()];
213 std::memcpy(v, normal.data(),
sizeof(
float) * 3);
220 auto& vbo = model->get_vertex_buffer();
222 model->set_vertex_offset(0);
223 model->set_vertex_stride(vertex_stride);
226 model->get_groups().resize(1);
233 model_group.
vertex_count =
static_cast<std::uint32_t
>(mesh.faces().size() * 3);
Curve segment bounded by two vertices.
Portion of a shell bounded by loops.
Connected boundary of a single face.
Boundary representation (B-rep) of a mesh.
std::unique_ptr< render::model > generate_model(const brep_mesh &mesh, std::shared_ptr< render::material > material)
Generates a model from a B-rep mesh.
void generate_loop_barycentric(brep_mesh &mesh)
Generates the math::fvec3 loop attribute "barycentric" for a B-rep mesh.
void generate_face_normals(brep_mesh &mesh)
Generates the math::fvec3 face attribute "normal" for a B-rep mesh.
void generate_vertex_normals(brep_mesh &mesh)
Generates the math::fvec3 vertex attribute "normal" for a B-rep mesh.
@ static_draw
Data will be modified once, by the application, and used many times, for drawing commands.
@ triangle_list
Separate triangle primitives.
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
constexpr T sqr_length(const quaternion< T > &q) noexcept
Calculates the square length of a quaternion.
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculates the cross product of two vectors.
vector< T, N > sqrt(const vector< T, N > &x)
Takes the square root of each element.
constexpr T dot(const quaternion< T > &a, const quaternion< T > &b) noexcept
Calculates the dot product of two quaternions.
@ normal
Vertex normal (vec3)
@ position
Vertex position (vec3)
static constexpr vector infinity() noexcept
Returns a vector of infinities, where every element is equal to infinity.
Part of a model which is associated with exactly one material.
std::shared_ptr< render::material > material
gl::primitive_topology primitive_topology
std::uint32_t vertex_count
std::uint32_t first_vertex