Holes as deep as the material: a drilled hole whose drill point would start exactly on the exit face is cut through (QA: depth = plate thickness failed with coincident faces on curved bodies)
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
c0f6aeb574
commit
35ac9569dc
2 files changed
+34
-1
No files matched your search
@@ -1189,7 +1189,13 @@ fn hole_tools(
|
||||
HoleKind::Simple => tools.push(cyl(r, bottom, top)?),
|
||||
HoleKind::Drilled { tip_angle } => {
|
||||
let half = val(vals, tip_angle, Kind::Angle)? / 2.0;
|
||||
if depth.is_some() && half > 1e-3 && half < std::f64::consts::FRAC_PI_2 {
|
||||
// A hole exactly as deep as the material: the point is in the air past the exit
|
||||
// face, which would lie on the drill point's shoulder (a through hole, as drilled).
|
||||
let at = |h: f64| *position + dir * (-h);
|
||||
let eps = size * 1e-6;
|
||||
let solid_at = |h: f64| st.bodies.iter().any(|b| b.body.contains(at(h)));
|
||||
let exits_at_shoulder = solid_at(bottom + eps) && !solid_at(bottom - eps);
|
||||
if depth.is_some() && half > 1e-3 && half < std::f64::consts::FRAC_PI_2 && !exits_at_shoulder {
|
||||
// One revolved tool (cylinder with a drill point).
|
||||
let tip = r / half.tan();
|
||||
let up = -dir;
|
||||
|
||||
@@ -1558,3 +1558,30 @@ fn lip_after_boss() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A drilled hole as deep as the plate: the drill point breaks through the bottom.
|
||||
#[test]
|
||||
fn hole_as_deep_as_the_plate() {
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "PrimitiveBox", json!({"length": 50, "width": 25, "height": 10}));
|
||||
let v0 = volume(&mut s);
|
||||
run(&mut s, "FusionHoleCommand", json!({"position": [25, 12.5, 10], "diameter": 6, "depth": 10, "type": "drilled"}));
|
||||
let v = volume(&mut s);
|
||||
assert!(v < v0 - PI * 9.0 * 9.0 && v > v0 - PI * 9.0 * 10.0 - 1.0, "{v0} {v}");
|
||||
// Other sizes and places, the defaults, and a tapped hole.
|
||||
for (i, p) in [
|
||||
json!({"position": [10, 10, 10], "diameter": 5, "depth": 10, "type": "drilled"}),
|
||||
json!({"position": [40, 15, 10], "diameter": 5, "depth": 10}),
|
||||
json!({"position": [12, 6, 10], "diameter": 8.5, "depth": 10}),
|
||||
json!({"position": [30, 7, 10], "thread": "M6", "depth": 10}),
|
||||
json!({"position": [20, 18, 10], "diameter": 4, "depth": 10, "tip_angle": 90}),
|
||||
]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
let before = volume(&mut s);
|
||||
let r = s.execute("FusionHoleCommand", &p);
|
||||
assert!(r.is_ok(), "{i} {p}: {r:?}");
|
||||
assert!(volume(&mut s) < before - 1.0, "{i} {p}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user