Fillets and chamfers along open chains of curved edges that end at planar faces square to them (the round edge of a D-shaped block): the end faces take the blend's end arcs and their edges stop at the contacts; the curved blend is tried only for curved edges or edges between curved faces, and refuses a blend larger than its neighbouring faces

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-08 08:32:45 +00:00
1 parent ae4570ed39
commit f7703ca720
4 files changed
+216 -58

No files matched your search

+23
View File
@@ -1079,3 +1079,26 @@ fn fillet_where_a_branch_pipe_meets_a_main_pipe() {
// Main cylinder, branch cylinder, the blend, the branch's top and the main's two ends.
assert_eq!(m.merged.faces, 6, "{:?}", m.merged);
}
#[test]
fn fillet_an_open_curved_edge() {
use solvecraft_geom::Seg2;
// A D-shaped block: the round top edge only, ending at the flat wall's sharp corners.
let d = Loop2 {
segs: vec![
Seg2::Arc { center: Vec2::ZERO, radius: 10.0, start: 0.0, sweep: PI },
Seg2::Line { a: Vec2::new(-10.0, 0.0), b: Vec2::new(10.0, 0.0) },
],
};
let b = extrude(&Plane::XY, &[Region2 { outer: d, holes: vec![] }], 0.0, 15.0).unwrap().pop().unwrap();
let v0 = measure(&b).unwrap().volume;
let f = fillet(&b, &[Vec3::new(0.0, 10.0, 15.0)], 2.0).unwrap();
// (A fine tessellation: the difference of two measured volumes magnifies their error.)
let _ = v0;
let fine = |x: &Body| x.tessellate_with(0.002, true).unwrap().measure().volume;
let removed = fine(&b) - fine(&f);
// Pappus: the corner's cross-section r²(1 − π/4), its centroid 0.2234 r in from the wall.
let r = 2.0;
let want = r * r * (1.0 - PI / 4.0) * (10.0 - r * (10.0 - 3.0 * PI) / (3.0 * (4.0 - PI))) * PI;
assert!(rel(removed, want) < 1e-3, "{removed} vs {want}");
}