perf: prism pairs before the mesh, bodies measured once, and a STEP import that copies less (#714)

A cut or an intersection between prisms (a plate and the tools through it) is now decided in 2D before either operand is meshed. A body's size and volume are measured once, a placement reads its orientation from its matrix, the evaluation cache is bounded to 64 MiB, and STEP import copies fewer shells. Hole plates evaluate 20-30% faster with less memory, and models are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SahenandClaude Opus 5.5 authored and GitHub committed 2026-10-13 10:55:56 -04:00
1 parent a1cb8d4d36
commit 2bb24d1d2a
13 files changed
+630 -71

No files matched your search

+46 -2
View File
@@ -461,8 +461,9 @@ fn hand_written_part_in_inches_with_colour() {
assert_eq!(imp.tree[0].name, "Widget");
}
#[test]
fn hand_written_assembly() {
/// A cube part (in cm) placed twice in a millimetre assembly: the file asks one brep item for
/// two bodies.
fn two_instance_assembly() -> String {
let mut t = String::from(HEAD);
t += "#8=PRODUCT_DEFINITION_CONTEXT('part definition',#9,'design');\n#9=APPLICATION_CONTEXT('');\n";
t += &cube_entities();
@@ -489,6 +490,12 @@ fn hand_written_assembly() {
t += &format!("#{}=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#{},#{});\n", n + 4, n + 3, n + 1);
}
t += TAIL;
t
}
#[test]
fn hand_written_assembly() {
let t = two_instance_assembly();
let imp = step_import(&t).unwrap();
assert_same_import(&step_import_with_workers(&t, 1).unwrap(), &step_import_with_workers(&t, 8).unwrap());
let expanded = t.replace("(#101,#65)", "(#101,#2000,#2001,#2002,#2003,#65)");
@@ -516,6 +523,43 @@ fn hand_written_assembly() {
assert!((root.children[1].transform[3][0] - 100.0).abs() < 1e-9);
}
/// The import keeps a conversion only where the file can ask for the item again. A flat file of
/// separate solids converts each item exactly once (no second copy of the whole import is held);
/// an assembly that instances one item keeps it, and each instance still gets geometry of its
/// own. Both files import to the same bodies either way.
#[test]
fn repeated_items_are_shared_and_one_use_items_are_not() {
let a = box_solid(Vec3::ZERO, Vec3::new(10.0, 10.0, 10.0)).unwrap();
let b = box_solid(Vec3::new(20.0, 0.0, 0.0), Vec3::new(30.0, 10.0, 10.0)).unwrap();
let flat = step_export(&[&a, &b], "test").unwrap();
let ex = p21::parse(&flat).unwrap();
let mut rd = Reader::new(&ex, 1);
rd.index();
assert_eq!(rd.once.len(), 2, "each solid of a flat file is converted once");
let imp = step_import(&flat).unwrap();
assert_eq!(imp.bodies.len(), 2);
assert!(imp.bodies.iter().all(|b| b.closed));
let vol: f64 = imp.bodies.iter().map(|b| measure(&b.body).unwrap().volume).sum();
assert!(rel(vol, 2000.0) < 1e-6, "{vol}");
let assembly = two_instance_assembly();
let ex = p21::parse(&assembly).unwrap();
let mut rd = Reader::new(&ex, 1);
rd.index();
assert!(rd.once.is_empty(), "an assembly may convert an item again for the second instance");
let imp = step_import(&assembly).unwrap();
assert_eq!(imp.bodies.len(), 2);
assert!(imp.bodies.iter().all(|b| b.name == "Cube" && b.closed));
let boxes: Vec<_> = imp.bodies.iter().map(|b| measure(&b.body).unwrap()).collect();
for m in &boxes {
assert!(rel(m.volume, 1000.0) < 1e-9, "{}", m.volume);
}
// Each instance owns its placed geometry: the two bodies are not one shared solid.
assert!(!imp.bodies[0].body.same(&imp.bodies[1].body));
// The two instances sit at their own placements, so the second conversion was not skipped.
assert!(boxes[1].bbox.min.dist(Vec3::new(90.0, 0.0, 0.0)) < 1e-6, "{:?}", boxes[1].bbox);
}
#[test]
fn unsupported_face_is_left_out_and_reported() {
let mut t = String::from(HEAD);