mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 18:45:55 +00:00
Tests: the arc-touching cut is checked by its volume and area, not its face count
cut_whose_end_touches_an_arc_side_leaves_no_sliver compared the touching cut's face count with a clear cut's, a count of how the kernel splits its faces. It now compares what the two parts are. The plate's arc runs from (0, 20) through (-10, 10) to (0, 0): centre (0, 10), r 10, so it reaches x = -10 only at y = 10. The r 5 cut along x about (y, z) = (12.5, 12.5) spans x -10..7.5 (touching) or -10.1..7.4 (clear). Both open the same patch of the arc; the slice x 7.4..7.5 lies wholly inside the plate (y 7.5..17.5, z 7.5..17.5 in 0..20 x 0..27.5). So V(clear) - V(touching) = pi 5^2 0.1 = 7.853982 mm^3 A(touching) - A(clear) = 2 pi 5 0.1 = 3.141593 mm^2 (the hole wall; the floor disc is the same) both to 1e-4 (the measure integrates the exact faces to 1e-8). A sliver of the arc left where the end touches adds about a square millimetre of faces. Seed 14's half (the fuzz generator's seed, then a shell) is pinned as its own test, shell_after_a_cut_whose_end_touches_an_arc_side, with the commands the generator gives today: the touching cut, then a 2 mm shell opening the top face y = 20. It fails at the shell (SMLib status 1001), a kernel gap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,8 +57,12 @@ fn shell_with_a_hole_through_a_curved_side() {
|
||||
/// A cut whose end only touches the plate's arc side (#897, robustness seed 14): the end lies
|
||||
/// tangent to the arc at its apex, the direct boolean fails, and the last-resort nudge used to
|
||||
/// push the end into the arc, leaving a sliver of it a tenth of a millimetre wide that a shell
|
||||
/// then couldn't offset. The nudge the other way parts them: the same faces as a cut clear of
|
||||
/// the apex, and seed 14 shells and fillets again.
|
||||
/// then couldn't offset. The touching cut must make the same part as a cut 0.1 clear of the
|
||||
/// apex (x = −10.1 .. 7.4 instead of −10 .. 7.5), less the hole's last 0.1 mm: the arc (centre
|
||||
/// (0, 10), r 10) reaches x = −10 only at y = 10, so both cuts open the same patch of it, and
|
||||
/// the slice x = 7.4 .. 7.5 of the r 5 hole lies wholly inside the plate. The touching cut has
|
||||
/// π 5² 0.1 less volume and 2π 5 0.1 more area (the longer hole wall; the floor disc is the
|
||||
/// same); a sliver left on the arc adds about a square millimetre of faces.
|
||||
#[test]
|
||||
fn cut_whose_end_touches_an_arc_side_leaves_no_sliver() {
|
||||
let plate = |x: f64| {
|
||||
@@ -72,11 +76,27 @@ fn cut_whose_end_touches_an_arc_side_leaves_no_sliver() {
|
||||
]))
|
||||
};
|
||||
let (touching, clear) = (plate(-10.0), plate(-10.1));
|
||||
let faces = |s: &Session| s.model.state().bodies.iter().map(|b| b.body.face_count()).sum::<usize>();
|
||||
assert_eq!(faces(&touching), faces(&clear), "a sliver face was left where the cut's end touches the arc");
|
||||
let r = fuzz::run(14, 8);
|
||||
let kinds: Vec<&str> = r.steps.iter().map(|s| s.kind).collect();
|
||||
assert!(r.outcome.kind == "ok" && kinds.contains(&"shell"), "seed 14: {:?} {kinds:?}\n{}", r.outcome, r.script());
|
||||
let area = |s: &Session| s.model.state().bodies.iter().map(|b| solidcraft_kernel::measure(&b.body).map(|m| m.area).unwrap_or(0.0)).sum::<f64>();
|
||||
let dv = total_volume(&clear) - total_volume(&touching);
|
||||
assert!((dv - PI * 25.0 * 0.1).abs() < 1e-4, "volume: clear − touching = {dv}, not π 5² 0.1");
|
||||
let da = area(&touching) - area(&clear);
|
||||
assert!((da - 2.0 * PI * 5.0 * 0.1).abs() < 1e-4, "area: touching − clear = {da}, not 2π 5 0.1: a sliver where the cut's end touches the arc");
|
||||
assert_eq!(touching.model.state().bodies.len(), 1);
|
||||
}
|
||||
|
||||
/// Robustness seed 14 (#897) as the generator made it: the touching cut above, then a shell
|
||||
/// opening the plate's top face (y = 20). Every step builds and the body is a sound solid.
|
||||
#[test]
|
||||
fn shell_after_a_cut_whose_end_touches_an_arc_side() {
|
||||
script(json!([
|
||||
{"command": "sketch.create", "params": {"plane": "XY"}},
|
||||
{"command": "sketch.line", "params": {"points": [[0, 0], [42.5, 0], [42.5, 20.0], [0, 20.0]]}},
|
||||
{"command": "sketch.arc.three_point", "params": {"end": [0, 0], "start": [0, 20.0], "through": [-10.0, 10.0]}},
|
||||
{"command": "sketch.finish", "params": {}},
|
||||
{"command": "solid.extrude", "params": {"distance": 27.5}},
|
||||
{"command": "solid.cylinder", "params": {"axis": [1.0, 0.0, 0.0], "base": [-10.000000000000002, 12.5, 12.5], "height": 17.5, "operation": "cut", "radius": 5.0}},
|
||||
{"command": "solid.shell", "params": {"faces": [[21.25, 19.999999999999993, 13.749999999999998]], "thickness": 2.0}}
|
||||
]));
|
||||
}
|
||||
|
||||
/// #827: a hinge barrel joined to a laptop lid through its mounting leaf. The barrel's top lies
|
||||
|
||||
Reference in New Issue
Block a user