Lips on rounded, shelled rims: the band along the rim's edge is raised from the body's own faces (kernel::raise_band: the rim face split along the band's exact offset edge, the band's walls swept up from the walls below, a top), since a join can't merge walls that continue each other; grooves cut with a band reaching into the free side so no wall coincides; tests against the band's area times its height

Fixes #29

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-10 00:04:37 +00:00
1 parent 80f5a58806
commit 67c79ec91c
6 files changed
+297 -4

No files matched your search

+30
View File
@@ -280,3 +280,33 @@ fn lip_after_boss() {
}
}
}
/// A lip, a groove and an outside lip on the rim of a rounded, shelled enclosure (#29: the
/// lip's walls continue the shell's walls, which a boolean join couldn't do).
#[test]
fn lip_on_a_rounded_shelled_rim() {
use std::f64::consts::PI;
let base = json!([
{"command": "solid.box", "params": {"corner": [-40, -30, 0], "length": 80, "width": 60, "height": 30}},
{"command": "solid.fillet", "params": {"edges": [[40, 30, 15], [-40, 30, 15], [-40, -30, 15], [40, -30, 15]], "radius": 6}},
{"command": "solid.shell", "params": {"faces": [[0, 0, 30]], "thickness": 2}}
]);
let v0 = total_volume(&script(base.clone()));
let ar = |w: f64, h: f64, r: f64| w * h - (4.0 - PI) * r * r;
let inside = ar(78.0, 58.0, 5.0) - ar(76.0, 56.0, 4.0);
for (extra, want) in [
(json!({}), v0 + inside * 1.5),
(json!({"side": "outside"}), v0 + (ar(80.0, 60.0, 6.0) - ar(78.0, 58.0, 5.0)) * 1.5),
// (The groove's band comes from the rim's meshed outline: within its sag.)
(json!({"type": "groove"}), v0 - inside * 1.5),
] {
let mut p = json!({"face": [0, 29, 30], "width": 1, "height": 1.5});
if let (Some(o), Some(e)) = (p.as_object_mut(), extra.as_object()) {
o.extend(e.clone());
}
let mut steps = base.as_array().cloned().unwrap_or_default();
steps.push(json!({"command": "plastic.lip", "params": p}));
let v = total_volume(&script(Value::Array(steps)));
assert!((v - want).abs() < 1e-3 * want, "{extra}: {v} vs {want}");
}
}