Tests: a mirrored sheet's flat pattern is its source's mirrored, as the code makes it

a_mirrored_or_patterned_sheet_body_is_sheet_metal_with_its_flat_pattern
(1171c4c2a) expected the mirrored copy's model turned over: the same outline,
its bend down and its pocket on top. That describes a SheetBody::moved that
never landed. The code on develop is SheetBody::copied (d9d6af51c, #3354): a
mirror moves the frame and mirrors the flat x -> -x with the same thickness
side, the opposite hand's blank with each bend turning the same way, which
a_mirrored_sheet_copy_is_the_opposite_hand_with_the_mirror_image_flat_pattern
asserts on an asymmetric bracket. The YZ mirror keeps z, so a pocket cut from
below stays below and the flange on y = 0 still turns up: the flat pattern
reads blank x 0..100 -> -100..0, pocket x 20..30 -> -30..-20, side bottom,
bend up.

The test now asserts that: the same flat size, the outline and the pocket
outline equal to the source's with x negated (to 1e-6), pocket side bottom and
bend up on both. The volume doubling, the bend table and the flange rebuilt
on the copy (point containment) stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-30 06:38:11 -04:00
committed by Irakli Kourtis
parent 5ea43b5c29
commit 978ae1d512
+11 -6
View File
@@ -5424,8 +5424,10 @@ fn flat_exports(s: &mut Session) -> Vec<std::result::Result<Value, String>> {
/// A sheet metal body mirrored, or patterned, into new bodies makes sheet metal bodies (#3353):
/// each copy has a flat pattern and a bend table, and a sheet metal feature on a copy rebuilds it
/// from its moved model where it is. A mirrored copy's model is its source's turned over: the
/// same blank, bent the other way, its pocket on the other face.
/// from its moved model where it is. A mirrored copy's model is its source's mirrored in the
/// flat (x → −x) with the same thickness side (`SheetBody::copied`, d9d6af51c, as
/// `a_mirrored_sheet_copy_is_the_opposite_hand_with_the_mirror_image_flat_pattern` has it): the
/// opposite hand's blank, each bend turning the same way, its pocket on the same face.
#[test]
fn a_mirrored_or_patterned_sheet_body_is_sheet_metal_with_its_flat_pattern() {
use solidcraft_geom::Vec3;
@@ -5443,10 +5445,13 @@ fn a_mirrored_or_patterned_sheet_body_is_sheet_metal_with_its_flat_pattern() {
let copy = s.model.state().bodies[1].name.clone();
assert!(rel(volume(&mut s), 2.0 * before) < 1e-9);
let mirrored = run(&mut s, "sheet.flat_pattern", json!({"body": copy}));
assert_eq!(mirrored["outline"], blank["outline"], "the same blank");
assert_eq!(blank["pockets"][0]["side"], "bottom");
assert_eq!(mirrored["pockets"][0]["side"], "top", "{mirrored}");
assert_eq!((&blank["bends"][0]["direction"], &mirrored["bends"][0]["direction"]), (&json!("up"), &json!("down")), "{mirrored}");
// The source's blank and pocket mirrored, the same size, bend and pocket side.
assert_eq!(mirrored["flat_size_mm"], blank["flat_size_mm"], "{mirrored}");
assert_eq!(flat_points(&mirrored["outline"], 1.0), flat_points(&blank["outline"], -1.0), "the mirrored blank: {mirrored}");
let pocket = |f: &Value| json!([f["pockets"][0]["outline"]]);
assert_eq!(flat_points(&pocket(&mirrored), 1.0), flat_points(&pocket(&blank), -1.0), "{mirrored}");
assert_eq!((&blank["pockets"][0]["side"], &mirrored["pockets"][0]["side"]), (&json!("bottom"), &json!("bottom")), "{mirrored}");
assert_eq!((&blank["bends"][0]["direction"], &mirrored["bends"][0]["direction"]), (&json!("up"), &json!("up")), "{mirrored}");
run(&mut s, "sheet.export_bend_table", json!({"body": copy}));
// The copy's model is where its body is: a flange on the copy rebuilds it in place, its