From b92433d324fedf109852540695689e5c82980a46 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Oct 2024 10:40:18 +0200 Subject: [PATCH] extrude faces works --- examples/extrude.rs | 1 - src/smesh/attribute.rs | 12 ++++-- src/smesh/edit_operations.rs | 59 ++++++++++++++++------------- src/smesh/topological_operations.rs | 21 +++++----- src/smesh/util.rs | 35 +++++++++++++++++ 5 files changed, 87 insertions(+), 41 deletions(-) diff --git a/examples/extrude.rs b/examples/extrude.rs index f0bad00..0c33675 100644 --- a/examples/extrude.rs +++ b/examples/extrude.rs @@ -29,7 +29,6 @@ fn extrude_faces() -> SMeshResult { let faces = smesh.extrude_faces(vec![f0, f1, f2])?; // let faces = smesh.extrude_faces(vec![f0])?; smesh.translate(faces, Vec3::Y * 2.0)?; - smesh.recalculate_normals()?; Ok(smesh) } diff --git a/src/smesh/attribute.rs b/src/smesh/attribute.rs index e35bc61..a75c835 100644 --- a/src/smesh/attribute.rs +++ b/src/smesh/attribute.rs @@ -260,8 +260,14 @@ mod test { fn basic_string() { let mut smesh = SMesh::new(); let v0 = smesh.add_vertex(vec3(1.0, 1.0, 1.0)); - let curvature = smesh.add_attribute_map::("curvature").unwrap(); - curvature.insert(v0, "hello".to_string()); - assert_eq!(curvature.get(v0), Some("hello".to_string())); + smesh.add_attribute_map::("curvature").unwrap(); + smesh + .attribute_mut("curvature") + .unwrap() + .insert(v0, "hello".to_string()); + assert_eq!( + smesh.attribute("curvature").unwrap().get(v0), + Some("hello".to_string()) + ); } } diff --git a/src/smesh/edit_operations.rs b/src/smesh/edit_operations.rs index 264a309..d43ccba 100644 --- a/src/smesh/edit_operations.rs +++ b/src/smesh/edit_operations.rs @@ -1,5 +1,6 @@ use std::collections::{HashMap, HashSet}; +use attribute::CustomAttributeMapOps; use bevy::{log::info, reflect::List}; use glam::Vec3; use itertools::Itertools; @@ -31,6 +32,7 @@ impl SMesh { } pub fn extrude_faces(&mut self, faces: Vec) -> SMeshResult> { + self.add_attribute_map::("debug").unwrap(); // Step 1: Collect all unique vertices and create mapping to new vertices let mut vertex_map = HashMap::new(); for &face in faces.iter() { @@ -60,33 +62,43 @@ impl SMesh { let opp = half_edge.opposite().run(self)?; let adjacent_face = opp.face().run(self).ok(); if adjacent_face.is_none() || !selected_faces.contains(&adjacent_face.unwrap()) { - boundary_half_edges.push(opp); - boundary_vertices.push(opp.src_vert().run(self)?); - boundary_vertices.push(opp.dst_vert().run(self)?); + boundary_half_edges.push(half_edge); + boundary_vertices.push(half_edge.src_vert().run(self)?); + boundary_vertices.push(half_edge.dst_vert().run(self)?); + info!("test"); } else { - inner_half_edges.push(opp); + let face = half_edge.face().run(self).ok(); + if face.is_some() && selected_faces.contains(&face.unwrap()) { + inner_half_edges.push(half_edge); + } } } } + for &he in &boundary_half_edges { + self.attribute_mut("debug") + .unwrap() + .insert(he, "red".to_string()); + } + // Step 4: Delete the old vertices/faces - // if faces.len() == 1 { - // self.delete_only_face(*faces.first().unwrap())?; - // info!("deleted face"); - // } - // for vertex in faces - // .iter() - // .flat_map(|f| f.vertices(self)) - // .filter(|v| !boundary_vertices.contains(v)) - // .collect_vec() - // { - // self.delete_vertex(vertex)?; - // info!("deleted vertex"); - // } - // for he in inner_half_edges { - // self.delete_only_edge(he)?; - // info!("deleted edge"); - // } + if faces.len() == 1 { + self.delete_only_face(*faces.first().unwrap())?; + info!("deleted face"); + } + for vertex in faces + .iter() + .flat_map(|f| f.vertices(self)) + .filter(|v| !boundary_vertices.contains(v)) + .collect_vec() + { + self.delete_vertex(vertex)?; + info!("deleted vertex"); + } + for he in inner_half_edges { + self.delete_only_edge(he).ok(); + info!("deleted edge"); + } // Step 5: Create side faces along boundary edges for edge in boundary_half_edges.iter() { @@ -94,19 +106,14 @@ impl SMesh { let dst_old = edge.dst_vert().run(self)?; let src_new = vertex_map[&src_old]; let dst_new = vertex_map[&dst_old]; - // self.translate(vec![src_new, dst_new], Vec3::Y)?; self.make_quad(src_old, dst_old, dst_new, src_new)?; } - for ele in self.faces() { - info!("{:?}", ele.vertices(self).collect_vec().len()); - } // Step 6: Create new faces on top let mut new_faces = Vec::new(); for &face in faces.iter() { let old_vertices = &face_vertex_map[&face]; let mut new_vertices = old_vertices.iter().map(|&v| vertex_map[&v]).collect_vec(); - new_vertices.reverse(); let new_face = self.make_face(new_vertices)?; new_faces.push(new_face); } diff --git a/src/smesh/topological_operations.rs b/src/smesh/topological_operations.rs index 2683481..f521f49 100644 --- a/src/smesh/topological_operations.rs +++ b/src/smesh/topological_operations.rs @@ -205,18 +205,17 @@ impl SMesh { if let Ok(prev) = e.prev().run(self) { he_needs_adjust.insert(prev); } - self.get_mut(e).delete().ok(); - // if let Ok(opposite) = e.opposite().run(self) { - // if let Ok(face) = opposite.face().run(self) { - // self.delete_only_face(face)?; - // } - // if let Ok(prev) = opposite.prev().run(self) { - // he_needs_adjust.insert(prev); - // } - // vert_needs_adjust.insert(opposite.src_vert().run(self)?); - // self.get_mut(opposite).delete()?; - // } + if let Ok(opposite) = e.opposite().run(self) { + if let Ok(face) = opposite.face().run(self) { + self.delete_only_face(face)?; + } + if let Ok(prev) = opposite.prev().run(self) { + he_needs_adjust.insert(prev); + } + vert_needs_adjust.insert(opposite.src_vert().run(self)?); + } + self.get_mut(e).delete().ok(); for v_id in vert_needs_adjust { self.get_mut(v_id).adjust_outgoing_halfedge()?; info!("Adjusting verts"); diff --git a/src/smesh/util.rs b/src/smesh/util.rs index a6a3b4a..2378b30 100644 --- a/src/smesh/util.rs +++ b/src/smesh/util.rs @@ -50,4 +50,39 @@ impl SMesh { self.face_normals = Some(face_normals); Ok(()) } + + pub fn flip_normals(&mut self) -> SMeshResult<()> { + // Step 1: Flip Face Normals + if let Some(face_normals) = &mut self.face_normals { + for (_face, normal) in face_normals.iter_mut() { + *normal = -*normal; + } + } + + // Step 2: Flip Vertex Normals + if let Some(vertex_normals) = &mut self.vertex_normals { + for (_vertex, normal) in vertex_normals.iter_mut() { + *normal = -*normal; + } + } + + // // Step 3: Reverse the Winding Order of Each Face + // let faces_to_update = self.faces().collect_vec(); + // for face in faces_to_update { + // // Collect the vertices of the face + // let vertices: Vec = face.vertices(self).collect(); + // + // // Delete the face + // self.delete_only_face(face)?; + // + // // Reverse the order of vertices + // let reversed_vertices: Vec = vertices.into_iter().rev().collect(); + // + // // Recreate the face with reversed vertices + // self.make_face(reversed_vertices)?; + // } + todo!(); + + Ok(()) + } }