Chamfers with two distances or a distance and an angle (distance2 / angle, flip for which face comes first), on straight edges between planar faces; pattern copies keep them
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
a762391697
commit
551d068ae2
7 files changed
+147
-17
No files matched your search
@@ -32,7 +32,7 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
.icon("fillet")
|
||||
.key("F")
|
||||
.params("edges: [[x,y,z] point on edge | {body, index}]; radius: expr; body?"),
|
||||
CommandSpec::new("FusionChamferCommand", "Chamfer", chamfer).at("SOLID", "MODIFY").icon("chamfer").params("edges: [[x,y,z] | {body, index}]; distance: expr; body?"),
|
||||
CommandSpec::new("FusionChamferCommand", "Chamfer", chamfer).at("SOLID", "MODIFY").icon("chamfer").params("edges: [[x,y,z] | {body, index}]; distance: expr; distance2?: expr (along the second face) | angle?: expr (from the first face); flip?: bool (which face is first: by default the one facing up most); body?"),
|
||||
CommandSpec::new("FusionCombineCommand", "Combine", combine).at("SOLID", "MODIFY").icon("combine").params("target: body; tools: [body]; operation?: join|cut|intersect; keep_tools?: bool"),
|
||||
CommandSpec::new("PatternRectangular", "Rectangular Pattern", pattern_rect)
|
||||
.at("SOLID", "CREATE")
|
||||
@@ -497,7 +497,18 @@ fn chamfer(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let edges = edge_points(s, p, cmd)?;
|
||||
let distance = req_expr(cmd, p, "distance")?;
|
||||
check_expr(s, &distance, Kind::Length, cmd, "distance")?;
|
||||
add_feature(s, p, FeatureKind::Chamfer { edges, distance, body: str_(p, "body").map(str::to_string) })
|
||||
let (distance2, angle) = (expr(p, "distance2"), expr(p, "angle"));
|
||||
if let Some(d) = &distance2 {
|
||||
check_expr(s, d, Kind::Length, cmd, "distance2")?;
|
||||
}
|
||||
if let Some(a) = &angle {
|
||||
check_expr(s, a, Kind::Angle, cmd, "angle")?;
|
||||
}
|
||||
if distance2.is_some() && angle.is_some() {
|
||||
return Err(bad(cmd, "give `distance2` or `angle`, not both"));
|
||||
}
|
||||
let flip = bool_(p, "flip").unwrap_or(false);
|
||||
add_feature(s, p, FeatureKind::Chamfer { edges, distance, distance2, angle, flip, body: str_(p, "body").map(str::to_string) })
|
||||
}
|
||||
|
||||
fn combine(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
@@ -1412,3 +1412,18 @@ fn press_pull_on_curved_faces() {
|
||||
let v1 = volume(&mut s);
|
||||
assert!(rel(v1 - v0, PI * (25.0 - 16.0) * 20.0) < 1e-3, "{v0} {v1}");
|
||||
}
|
||||
|
||||
/// Chamfers with two distances or a distance and an angle.
|
||||
#[test]
|
||||
fn unequal_chamfers() {
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "PrimitiveBox", json!({"length": 40, "width": 30, "height": 20}));
|
||||
// Top front edge: 2 along the top (the face facing up), 4 down the front.
|
||||
run(&mut s, "FusionChamferCommand", json!({"edges": [[20, 0, 20]], "distance": 2, "distance2": 4}));
|
||||
assert!(rel(volume(&mut s), 24000.0 - 0.5 * 2.0 * 4.0 * 40.0) < 1e-6, "{}", volume(&mut s));
|
||||
// Bottom back edge: 3 along the bottom, at 30° from it (down the back face 3·tan 30°).
|
||||
run(&mut s, "FusionChamferCommand", json!({"edges": [[20, 30, 0]], "distance": 3, "angle": "30 deg", "flip": true}));
|
||||
let d2 = 3.0 * (30f64).to_radians().tan();
|
||||
assert!(rel(volume(&mut s), 24000.0 - 160.0 - 0.5 * 3.0 * d2 * 40.0) < 1e-6, "{}", volume(&mut s));
|
||||
assert!(s.execute("FusionChamferCommand", &json!({"edges": [[0, 15, 20]], "distance": 1, "distance2": 2, "angle": "30 deg"})).is_err());
|
||||
}
|
||||
Reference in new issue
Block a user