Variable-radius fillets through middle points: radii at positions along the edge, straight or smooth between
kernel::fillet_variable_points(body, edge, start, [(position, radius)...], smooth): the radius law is a B-spline of the edge parameter (straight pieces, or C1 cubic pieces with Catmull-Rom slopes), and since every section's arc is affine in its radius the blend is exactly a rational B-spline (degree 2 across, the law's degree along) with B-spline contact curves on the faces. The largest radius along the edge decides whether the blend fits. Fillet type variable takes mid: [[position, radius expr], ...] and smooth; middle radii are parameters of the feature (Mid radius) and follow user parameters. Tests: straight pieces against (1 - pi/4) L (a^2 + ab + b^2) / 3 per piece, smooth against the integrated law, either end as start, refusals; engine test with a parameter-driven middle radius. Refs #9 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
This commit is contained in:
1 parent
a7fe0429f0
commit
be18bd6573
8 files changed
+192
-19
No files matched your search
@@ -1069,6 +1069,29 @@ fn chord_and_variable_fillets() {
|
||||
let removed = (1.0 - PI / 4.0) * 20.0 * (4.0 + 10.0 + 25.0) / 3.0;
|
||||
assert!(rel(v, 6000.0 - removed) < 1e-4, "{v}");
|
||||
assert!(s.execute("solid.fillet", &json!({"edges": [[10, 10, 30]], "radius": 2, "type": "variable"})).is_err());
|
||||
// A radius through a middle point (a user parameter), straight between: 2 → 4 → 2.
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "solid.box", json!({"length": 10, "width": 20, "height": 30, "body_name": "B"}));
|
||||
run(&mut s, "parameters.add", json!({"name": "waist", "expression": "4 mm"}));
|
||||
run(
|
||||
&mut s,
|
||||
"solid.fillet",
|
||||
json!({"edges": [[10, 10, 30]], "radius": 2, "type": "variable", "radius2": 2, "start": [10, 0, 30], "mid": [[0.5, "waist"]]}),
|
||||
);
|
||||
let vol = |s: &Session| solvecraft_kernel::measure(&s.world_state().body("B").unwrap().body).unwrap().volume;
|
||||
let removed = 2.0 * (1.0 - PI / 4.0) * 10.0 * (4.0 + 8.0 + 16.0) / 3.0;
|
||||
assert!(rel(vol(&s), 6000.0 - removed) < 1e-4, "{}", vol(&s));
|
||||
// The middle radius follows its parameter.
|
||||
run(&mut s, "parameters.change", json!({"name": "waist", "expression": "3 mm"}));
|
||||
let removed = 2.0 * (1.0 - PI / 4.0) * 10.0 * (4.0 + 6.0 + 9.0) / 3.0;
|
||||
assert!(rel(vol(&s), 6000.0 - removed) < 1e-4, "{}", vol(&s));
|
||||
assert!(
|
||||
s.execute(
|
||||
"solid.fillet",
|
||||
&json!({"edges": [[10, 10, 30]], "radius": 2, "type": "variable", "radius2": 2, "start": [10, 0, 30], "mid": [[1.5, 3]]})
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
/// Components export as a STEP assembly: products, occurrences, placements.
|
||||
|
||||
Reference in new issue
Block a user