From 12ffc3961f5ae4fe8b37d6780885d6286efe0642 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Tue, 13 Oct 2026 16:29:27 +0300 Subject: [PATCH] feat(section): volume top/bottom grips; live sections cut closed meshes A section volume now shows grips on its top and bottom faces, so its height is pushed and pulled in place like its sides, not only through the Properties palette. Live sectioning also cuts MESH, polygon mesh and polyface mesh objects that close a volume, drawing each as the capped solid it bounds in every visual style. Refs #1407 Co-Authored-By: Claude Opus 5.5 --- src/entities/extended.rs | 6 ++++++ src/scene/mod.rs | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/entities/extended.rs b/src/entities/extended.rs index 3a815d8d0..dc9b536ab 100644 --- a/src/entities/extended.rs +++ b/src/entities/extended.rs @@ -1971,6 +1971,12 @@ fn grips(entity: &ExtendedEntity) -> Vec { }) .collect() }; + // A section volume is also pushed or pulled at its top and bottom. + if data.state == 4 { + grips.extend(section_plane_edge_grips(data).into_iter().filter(|grip| { + matches!(grip.id, SECTION_GRIP_TOP | SECTION_GRIP_BOTTOM) + })); + } if let Some(right) = data.vertices.last() { let vertical = normalized(data.vertical_direction, Vector3::UNIT_Z); let edge_center_offset = (data.top_height - data.bottom_height) * 0.5; diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 42256cccb..f11b795ed 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -8847,6 +8847,14 @@ impl Scene { body.wires = wires; body.silhouettes.clear(); } + // The cut mesh is drawn as the solid it bounds. + EntityType::Mesh(_) | EntityType::PolygonMesh(_) | EntityType::PolyfaceMesh(_) => { + let mut solid = codec::entities::Solid3D::new(); + solid.common = entity.common().clone(); + solid.point_of_reference = reference; + solid.wires = wires; + entity = EntityType::Solid3D(solid); + } _ => return Err(()), } Ok(Some(entity)) @@ -8872,6 +8880,12 @@ impl Scene { Some(EntityType::Surface(surface)) => { crate::scene::convert::solid3d_tess::kernel_surface_body(surface) } + // A mesh that closes a volume is cut as the solid it bounds. + Some( + mesh @ (EntityType::Mesh(_) + | EntityType::PolygonMesh(_) + | EntityType::PolyfaceMesh(_)), + ) => crate::entities::mesh::closed_mesh_body(mesh), _ => None, }?; Some(std::borrow::Cow::Owned(body))