Kernel tests: the round into a hole moves to the rig, with the hole cut the test's way

a_round_into_a_hole_is_cut_by_it (issue_324_tests.rs) built rig case
fillets/324-fillet-over-hole-overlap's body, but cut its hole with a cylinder
longer than the block (z -1 to 11) where the rig extrudes a sketch circle
flush. The new case fillets/324-fillet-over-hole-cut-by-overlong-cylinder
builds it that way (solid.cylinder, base z -1, height 12, cut) and holds it to
the same hand-derived answer: block 40x20x10 less the r3 hole at (20, 14.5)
(282.74) less the R4 round on the top edge at y = 20, 40 (16 - 4 pi) = 137.35,
plus what both remove, the integral over y in [16, 17.5] of
(4 - sqrt(16 - (y - 16)^2)) * 2 sqrt(9 - (y - 14.5)^2) = 0.375830 (re-derived
with the substitution y = 17.5 - s^2, 200000 steps):
V = 8000 - 90 pi - 40 (16 - 4 pi) + 0.375830 = 7580.287315, and G1 on the
blend. It passes today (aarch64, SMLib), as the flush case does, so it needs no
KNOWN_FAILING line; the unit test, a duplicate of the two cases, is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-30 06:34:40 -04:00
committed by Irakli Kourtis
parent 51641123cf
commit e9963439b1
4 changed files with 57 additions and 48 deletions
-46
View File
@@ -1,46 +0,0 @@
//! #324: a round on a block's top edge that runs over a through hole: built as if the top went
//! on, and cut by the hole.
use solidcraft_geom::Vec3;
use crate::{Body, BoolOp, build::box_solid, build::cylinder, ops::boolean};
/// A 40 x 20 x 10 block with a through hole of radius 3 at (20, `y`).
fn block_with_hole(y: f64) -> Body {
let block = box_solid(Vec3::new(0.0, 0.0, 0.0), Vec3::new(40.0, 20.0, 10.0)).unwrap();
let hole = cylinder(Vec3::new(20.0, y, -1.0), Vec3::Z, 3.0, 12.0).unwrap();
boolean(&block, &hole, BoolOp::Cut).unwrap().unwrap()
}
/// The round on the top edge at y = 20 covers the top face from y = 20 - r, and the hole's
/// wall reaches y = 17.5: a radius over 2.5 runs into the hole. R4 is built as if the top went
/// on over the hole and cut from the block (the blend-overflow decision, 237f0ae74): the round
/// takes 16 (1 - π/4) of the section along 40, less its part over the hole, where the round's
/// height above its arc, 4 - √(16 - (y - 16)²), stands over the hole's width
/// 2 √(9 - (y - 14.5)²) for y in [16, 17.5] (integrated with y = 17.5 - s², smooth in s).
#[test]
fn a_round_into_a_hole_is_cut_by_it() {
use std::f64::consts::{FRAC_PI_4, PI};
let b = block_with_hole(14.5);
let edge = Vec3::new(10.0, 20.0, 10.0);
let r = crate::fillet(&b, &[edge], 4.0).unwrap();
assert!(r.validity().is_empty(), "{:?}", r.validity());
let (n, top) = (20000, 1.5f64.sqrt());
let over: f64 = (0..n)
.map(|i| {
let s = (i as f64 + 0.5) * top / n as f64;
let y = 17.5 - s * s;
2.0 * (9.0 - (y - 14.5).powi(2)).sqrt() * (4.0 - (16.0 - (y - 16.0).powi(2)).sqrt()) * 2.0 * s
})
.sum::<f64>()
* top
/ n as f64;
let want = 8000.0 - PI * 9.0 * 10.0 - (40.0 * 16.0 * (1.0 - FRAC_PI_4) - over);
let v = crate::measure(&r).unwrap().volume;
assert!((v - want).abs() < 1e-7 * want, "{v} against {want}");
// Clear of the hole (up to 2.5) the round keeps its whole section.
let r = crate::fillet(&b, &[edge], 2.5).unwrap();
let want = 8000.0 - PI * 9.0 * 10.0 - 40.0 * 2.5 * 2.5 * (1.0 - FRAC_PI_4);
let v = r.volume_at(0.005).unwrap();
assert!((v - want).abs() < 0.05, "{v} against {want}");
}
-2
View File
@@ -62,8 +62,6 @@ mod issue_1510_tests;
#[cfg(test)]
mod issue_2005_tests;
#[cfg(test)]
mod issue_324_tests;
#[cfg(test)]
mod issue_616_tests;
#[cfg(test)]
mod issue_674_tests;
@@ -0,0 +1,13 @@
{
"sources": [
"tangency-labs/solidcraft#324"
],
"what": "324-fillet-over-hole-overlap with the hole cut by a cylinder longer than the block (z -1 to 11), so the hole's wall is trimmed by both the top and the bottom face",
"source": "analytic",
"method": "the same body as 324-fillet-over-hole-overlap: block 40x20x10 minus a through hole of r=3 centred (20,14.5), then R4 on the top long edge at y=20. The round covers y=16..20 and removes 40*(16-4pi) = 137.35; the hole removes 9*pi*10 = 282.74; where both remove the same material (y in 16..17.5) add it back: overlap = integral over y from 16 to 17.5 of [4 - sqrt(16-(y-16)^2)] x 2 sqrt(9-(y-14.5)^2) dy = 0.3758. V = 8000 - 9*pi*10 - 40*(16-4*pi) + overlap = 7580.287.",
"body_count": 1,
"volume_mm3": 7580.287315360674,
"continuity": {
"order": "g1"
}
}
@@ -0,0 +1,44 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
0,
0,
0
],
"length": 40,
"width": 20,
"height": 10,
"body_name": "Block"
}
},
{
"command": "solid.cylinder",
"params": {
"base": [
20,
14.5,
-1
],
"radius": 3,
"height": 12,
"operation": "cut"
}
},
{
"command": "solid.fillet",
"params": {
"edges": [
[
10,
20,
10
]
],
"radius": "4 mm"
}
}
]
}