From ad5c37b3eb07f4fa9908039303e89fdb3fac93f3 Mon Sep 17 00:00:00 2001 From: Marc-Stefan Cassola Date: Fri, 11 Apr 2025 15:22:39 -0500 Subject: [PATCH] some minor cleanup and docs --- docs/images/HalfedgeOps.svg | 99 ++++++++++++++++++++++++++++++++++++ src/smesh/edit_operations.rs | 12 ++++- src/smesh/model/mesh.rs | 16 +++--- 3 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 docs/images/HalfedgeOps.svg diff --git a/docs/images/HalfedgeOps.svg b/docs/images/HalfedgeOps.svg new file mode 100644 index 0000000..94c1c14 --- /dev/null +++ b/docs/images/HalfedgeOps.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + opposite + + + + + dst_vert / vert + + + src_vert + + + + + face + + + + + next + + + + + prev + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/smesh/edit_operations.rs b/src/smesh/edit_operations.rs index 81957bc..a356fd1 100644 --- a/src/smesh/edit_operations.rs +++ b/src/smesh/edit_operations.rs @@ -228,21 +228,26 @@ impl SMesh { // Returned selection let mut selection = MeshSelection::new(); for he in halfedges { - let he_opposite = he.opposite().run(self)?; if he_cache.contains(&he) { continue; } + + let he_opposite = he.opposite().run(self)?; + let p0 = he.src_vert().position(self)?; let p1 = he.dst_vert().position(self)?; let v = self.add_vertex(0.5 * (p0 + p1)); let new_he = self.insert_vertex(he, v)?; + he_cache.insert(he); he_cache.insert(he_opposite); + selection.insert(he); selection.insert(he_opposite); selection.insert(new_he); selection.insert(new_he.opposite().run(self)?); } + for f in faces { let valence = f.valence(self) / 2; let corner = face_corners[&f]; @@ -251,6 +256,7 @@ impl SMesh { .find(|he| he.src_vert().run(self).unwrap() == corner) .unwrap(); let he_loop = self.halfedge_loop(corner_edge.next().run(self)?); + if valence == 3 { self.delete_only_face(f)?; for (h0, h1) in he_loop.iter().circular_tuple_windows().step_by(2) { @@ -269,6 +275,7 @@ impl SMesh { )?; selection.insert(f); } + if valence == 4 { let center = self.get_face_centroid(f)?; let v_c = self.add_vertex(center); @@ -283,6 +290,7 @@ impl SMesh { selection.insert(f); } } + // valence > 4: ngons simply stay as ngons (same behaviour as blender) } @@ -374,7 +382,7 @@ impl SMesh { self.uvs.as_mut().unwrap().insert(v_map[&id], value); } } - // TODO: copy custom attributes + // TODO: copy custom attributes // for attr in self.vertex_attributes { // // } diff --git a/src/smesh/model/mesh.rs b/src/smesh/model/mesh.rs index 9b620dd..2ac10e7 100644 --- a/src/smesh/model/mesh.rs +++ b/src/smesh/model/mesh.rs @@ -110,7 +110,7 @@ impl SMesh { bail!(DefaultError); } - let mut halfedeges: Vec<(HalfedgeId, bool)> = Vec::with_capacity(n); + let mut halfedges: Vec<(HalfedgeId, bool)> = Vec::with_capacity(n); let mut next_cache: Vec<(HalfedgeId, HalfedgeId)> = vec![]; let mut needs_adjust: Vec = vec![]; @@ -125,19 +125,19 @@ impl SMesh { if !he_id.is_boundary(self) { bail!(TopologyError); } - halfedeges.push((he_id, false)); + halfedges.push((he_id, false)); } Err(_) => { // New halfedge // TODO: Check if only one he should be added here? let (he_id, _) = self.make_edge_internal(*v0, *v1); - halfedeges.push((he_id, true)); + halfedges.push((he_id, true)); } } } // re-link patches if necessary for ((inner_prev_id, prev_new), (inner_next_id, next_new)) in - halfedeges.iter().circular_tuple_windows() + halfedges.iter().circular_tuple_windows() { if !prev_new && !next_new { let inner_prev = *inner_prev_id; @@ -179,14 +179,14 @@ impl SMesh { // create the face let face = Face { - halfedge: Some(halfedeges.get(n - 1).unwrap().0), + halfedge: Some(halfedges.get(n - 1).unwrap().0), }; let face_id = self.faces_mut().insert(face); for (i, ii) in (0..n).circular_tuple_windows() { let v = vertices[ii]; - let (inner_prev, prev_new) = halfedeges[i]; - let (inner_next, next_new) = halfedeges[ii]; + let (inner_prev, prev_new) = halfedges[i]; + let (inner_next, next_new) = halfedges[ii]; if prev_new || next_new { let outer_prev = inner_next.opposite().run(self)?; @@ -223,7 +223,7 @@ impl SMesh { } // set face id - self.he_mut(halfedeges[i].0).face = Some(face_id); + self.he_mut(halfedges[i].0).face = Some(face_id); } // process next halfedge cache