Split Body: the face a plane split cuts takes an attachment that follows the plane (#565) (#1746)

Thanks @SychPL.
This commit is contained in:
Mateusz Sych authored and GitHub committed 2026-10-16 13:26:11 -04:00
1 parent e2667b749d
commit 31b2ddc0cf
7 files changed
+131 -36

No files matched your search

+1 -1
View File
@@ -159,7 +159,7 @@ pub use mesh_convert::convert_prismatic_mesh;
pub use meshbody::{MAX_TRIANGLES, mesh_body};
pub use native::{decode_native_body, encode_native_body, native_preview_mesh};
pub use offset::with_same_surface;
pub use ops::{BoolOp, boolean, can_join_touching_faces, join_apart, split_by_plane, transform, transform_matrix, union_apart};
pub use ops::{BoolOp, boolean, can_join_touching_faces, half_space, join_apart, split_by_plane, transform, transform_matrix, union_apart};
pub use polybool::{faceted_boolean, planar_boolean};
pub use polyhedron::{HalfSpace, convex_polyhedron, draft, offset_faces, shell};
pub use prism::{PLANAR_FIT_TOL, extrude_planar_regions, planar_regions_boolean};
+8 -5
View File
@@ -1428,16 +1428,19 @@ pub fn transform(body: &Body, translate: Vec3, origin: Vec3, axis: Vec3, angle:
pub fn split_by_plane(body: &Body, plane: &solidcraft_geom::Plane) -> Result<Vec<Body>> {
let mut out = Vec::new();
for positive in [true, false] {
out.extend(half_space(body, plane, positive)?);
out.extend(half_space(body, plane, positive)?.0);
}
Ok(out)
}
/// The part of a body on one side of a plane (`None` when nothing is there): its intersection
/// with [`half_box`] (whose history it carries, over the body and the box).
pub(crate) fn half_space(body: &Body, plane: &solidcraft_geom::Plane, positive: bool) -> Result<Option<Body>> {
/// The part of a body on one side of a plane (`None` when nothing is there), and the tool it is
/// cut with: the part is the body's intersection with [`half_box`] (the tool), whose history it
/// carries, over the body and the box. The box's face in the plane, the part's cut face, is its
/// start cap on the positive side and its end cap on the negative side.
pub fn half_space(body: &Body, plane: &solidcraft_geom::Plane, positive: bool) -> Result<(Option<Body>, Body)> {
// The box's own construction roles describe no face of the design: the cut face has none.
boolean(body, &half_box(body, plane, positive)?.with_face_sources(None), BoolOp::Intersect)
let tool = half_box(body, plane, positive)?.with_face_sources(None);
Ok((boolean(body, &tool, BoolOp::Intersect)?, tool))
}
/// A box covering everything of `body` on one side of a plane, its start cap in the plane.