Recompute normals without cloning faces / verts

This commit is contained in:
Connor Slade
2025-02-10 11:43:18 -05:00
parent 21d3edf6a2
commit 6a8a9ccfda
2 changed files with 21 additions and 18 deletions

View File

@@ -180,7 +180,7 @@ impl App {
}
pub fn load_mesh<T: BufRead + Seek>(&mut self, buf: &mut T, format: &str, name: String) {
let mut model = match slicer::mesh::load_mesh(buf, format) {
let model = match slicer::mesh::load_mesh(buf, format) {
Ok(model) => model,
Err(err) => {
self.popup.open(Popup::simple(
@@ -193,11 +193,6 @@ impl App {
};
info!("Loaded model `{name}` with {} faces", model.face_count());
if model.normals().iter().any(|x| x.magnitude_squared() == 0.0) {
warn!("Model `{name}` has invalid normals. Recomputing.");
model.recompute_normals();
}
let rendered_mesh = RenderedMesh::from_mesh(model)
.with_name(name.clone())
.with_random_color();

View File

@@ -6,6 +6,7 @@ use std::{
use anyhow::Result;
use nalgebra::{Matrix4, Vector3};
use obj::{Obj, Vertex};
use tracing::warn;
use crate::Pos;
@@ -33,8 +34,14 @@ struct MeshInner {
impl Mesh {
/// Creates a new mesh from the givin vertices and faces. The
/// transformations are all 0 by default.
pub fn new(mut vertices: Vec<Pos>, faces: Vec<[u32; 3]>, normals: Vec<Pos>) -> Self {
pub fn new(mut vertices: Vec<Pos>, faces: Vec<[u32; 3]>, mut normals: Vec<Pos>) -> Self {
center_vertices(&mut vertices);
if normals.iter().any(|x| x.magnitude_squared() == 0.0) {
warn!("Model has invalid normals. Recomputing.");
normals = recompute_normals(&vertices, &faces);
}
Self::new_uncentred(vertices, faces, normals)
}
@@ -83,17 +90,7 @@ impl Mesh {
/// Makes a copy of the mesh with normals computed from the triangles
/// directly. The copy makes this operation kinda expensive.
pub fn recompute_normals(&mut self) {
let vertices = self.vertices();
let normals = self
.faces()
.iter()
.map(|f| {
let edge1 = vertices[f[2] as usize] - vertices[f[1] as usize];
let edge2 = vertices[f[0] as usize] - vertices[f[1] as usize];
edge1.cross(&edge2).normalize()
})
.collect();
let normals = recompute_normals(self.vertices(), self.faces());
self.overwrite_normals(normals)
}
@@ -377,3 +374,14 @@ fn center_vertices(vertices: &mut [Pos]) {
let center = Pos::new(center.x, center.y, min.z);
vertices.iter_mut().for_each(|v| *v -= center);
}
fn recompute_normals(vertices: &[Pos], faces: &[[u32; 3]]) -> Vec<Vector3<f32>> {
faces
.iter()
.map(|f| {
let edge1 = vertices[f[2] as usize] - vertices[f[1] as usize];
let edge2 = vertices[f[0] as usize] - vertices[f[1] as usize];
edge1.cross(&edge2).normalize()
})
.collect()
}