Recompute normals without cloning faces / verts
This commit is contained in:
@@ -180,7 +180,7 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_mesh<T: BufRead + Seek>(&mut self, buf: &mut T, format: &str, name: String) {
|
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,
|
Ok(model) => model,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.popup.open(Popup::simple(
|
self.popup.open(Popup::simple(
|
||||||
@@ -193,11 +193,6 @@ impl App {
|
|||||||
};
|
};
|
||||||
info!("Loaded model `{name}` with {} faces", model.face_count());
|
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)
|
let rendered_mesh = RenderedMesh::from_mesh(model)
|
||||||
.with_name(name.clone())
|
.with_name(name.clone())
|
||||||
.with_random_color();
|
.with_random_color();
|
||||||
|
@@ -6,6 +6,7 @@ use std::{
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use nalgebra::{Matrix4, Vector3};
|
use nalgebra::{Matrix4, Vector3};
|
||||||
use obj::{Obj, Vertex};
|
use obj::{Obj, Vertex};
|
||||||
|
use tracing::warn;
|
||||||
|
|
||||||
use crate::Pos;
|
use crate::Pos;
|
||||||
|
|
||||||
@@ -33,8 +34,14 @@ struct MeshInner {
|
|||||||
impl Mesh {
|
impl Mesh {
|
||||||
/// Creates a new mesh from the givin vertices and faces. The
|
/// Creates a new mesh from the givin vertices and faces. The
|
||||||
/// transformations are all 0 by default.
|
/// 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);
|
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)
|
Self::new_uncentred(vertices, faces, normals)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,17 +90,7 @@ impl Mesh {
|
|||||||
/// Makes a copy of the mesh with normals computed from the triangles
|
/// Makes a copy of the mesh with normals computed from the triangles
|
||||||
/// directly. The copy makes this operation kinda expensive.
|
/// directly. The copy makes this operation kinda expensive.
|
||||||
pub fn recompute_normals(&mut self) {
|
pub fn recompute_normals(&mut self) {
|
||||||
let vertices = self.vertices();
|
let normals = recompute_normals(self.vertices(), self.faces());
|
||||||
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();
|
|
||||||
|
|
||||||
self.overwrite_normals(normals)
|
self.overwrite_normals(normals)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,3 +374,14 @@ fn center_vertices(vertices: &mut [Pos]) {
|
|||||||
let center = Pos::new(center.x, center.y, min.z);
|
let center = Pos::new(center.x, center.y, min.z);
|
||||||
vertices.iter_mut().for_each(|v| *v -= center);
|
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()
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user