diff --git a/mslicer/src/app/mod.rs b/mslicer/src/app/mod.rs index 8e8d625..4131ae6 100644 --- a/mslicer/src/app/mod.rs +++ b/mslicer/src/app/mod.rs @@ -180,7 +180,7 @@ impl App { } pub fn load_mesh(&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(); diff --git a/slicer/src/mesh.rs b/slicer/src/mesh.rs index ce5eaae..92011f9 100644 --- a/slicer/src/mesh.rs +++ b/slicer/src/mesh.rs @@ -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, faces: Vec<[u32; 3]>, normals: Vec) -> Self { + pub fn new(mut vertices: Vec, faces: Vec<[u32; 3]>, mut normals: Vec) -> 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> { + 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() +}