Cut an extrude's profiles that stand apart in one boolean (#848)

When an extrude cuts with profiles whose outlines stay more than 1 µm apart (the letters of a text), their tools are apart too, so they are joined and cut from the body in one boolean instead of one per profile. A ten-letter text cut drops from about 13 s to 1.5 s with the same result. Sheet metal targets and touching profiles keep cutting tool by tool. Tapered extrudes are unaffected.
This commit is contained in:
phanoob authored and GitHub committed 2026-10-13 18:29:49 -04:00
1 parent 96f6424aec
commit 1f7f37d1ef
6 files changed
+194 -3

No files matched your search

+1 -1
View File
@@ -101,7 +101,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, split_by_plane, transform, transform_matrix, union_apart};
pub use ops::{BoolOp, boolean, can_join_touching_faces, 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};
+11
View File
@@ -883,6 +883,17 @@ pub fn union_apart(bodies: &[Body]) -> Result<Option<Body>> {
}
}
}
join_apart(bodies)
}
/// Bodies the caller knows are apart (no two meet or touch), as one body of several pieces,
/// without any intersection work: [`union_apart`] without its check, for tools whose making
/// shows they are apart (profiles apart in their sketch, extruded alike). `None` for fewer than
/// two bodies or a mesh.
pub fn join_apart(bodies: &[Body]) -> Result<Option<Body>> {
if bodies.len() < 2 || bodies.len() > 10_000 || bodies.iter().any(Body::is_mesh) {
return Ok(None);
}
// The pieces stay as they are, side by side: each face and edge of the result is its piece's
// own (the history over `bodies`).
let Some(joined) = join_pieces(bodies.to_vec())? else { return Ok(None) };