Sketch inline dimensions while drawing (line length/angle, rectangle width/height, circle diameter, arc radius/sweep, polygon radius/sides, slot length/width): boxes sit on what they measure, typing goes into the first box and locks it, Tab moves on, Enter places the shape, typed values become dimension constraints (expressions and units); Press Pull (Q: faces extrude/cut by sign, edges fillet), X toggles construction on selected curves, Move dialog (M) with preview
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
ea3dd0ed6e
commit
eb22a149b1
11 files changed
+411
-25
No files matched your search
@@ -65,6 +65,11 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
.icon("plane")
|
||||
.params("base: XY|XZ|YZ|plane name; axis: X|Y|Z|{origin, dir}; angle: expr; name?"),
|
||||
CommandSpec::new("FusionSplitBodyCommand", "Split Body", split_body).at("SOLID", "MODIFY").icon("split").params("body: name; plane: XY|XZ|YZ|plane name|{origin, normal}"),
|
||||
CommandSpec::new("FusionPressPullCommand", "Press Pull", press_pull)
|
||||
.at("SOLID", "MODIFY")
|
||||
.icon("presspull")
|
||||
.key("Q")
|
||||
.params("face: [x,y,z] and distance: expr (positive adds material, negative cuts), or edges: [[x,y,z]…] and distance (a fillet)"),
|
||||
CommandSpec::new("FusionMoveCommand", "Move/Copy", move_bodies).at("SOLID", "MODIFY").icon("move").key("M").params("bodies: [names]; translate?: [x,y,z] (exprs or numbers); axis?: [x,y,z]; angle?: expr"),
|
||||
];
|
||||
|
||||
@@ -318,6 +323,23 @@ fn edge_points(s: &Session, p: &Value, cmd: &str) -> Result<Vec<Vec3>> {
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Press Pull: a face moves along its normal (an extrude that joins outward or cuts inward); an
|
||||
/// edge is rounded (a fillet).
|
||||
fn press_pull(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let cmd = "FusionPressPullCommand";
|
||||
let distance = req_expr(cmd, p, "distance")?;
|
||||
if p.get("edges").is_some() {
|
||||
return fillet(s, &json!({"edges": p.get("edges"), "radius": distance}));
|
||||
}
|
||||
let face = p.get("face").ok_or_else(|| bad(cmd, "needs `face` or `edges`"))?;
|
||||
let d = s.doc.eval(&distance, Kind::Length).map_err(|e| bad(cmd, format!("distance: {e}")))?;
|
||||
if d.abs() < 1e-9 {
|
||||
return Err(bad(cmd, "the distance must not be zero"));
|
||||
}
|
||||
let (dist, dir, op) = if d > 0.0 { (distance, "positive", "join") } else { (format!("-({distance})"), "negative", "cut") };
|
||||
extrude(s, &json!({"face": face, "distance": dist, "direction": dir, "operation": op}))
|
||||
}
|
||||
|
||||
fn fillet(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let cmd = "FusionFilletEdgesCommand";
|
||||
let edges = edge_points(s, p, cmd)?;
|
||||
|
||||
@@ -147,6 +147,7 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
CommandSpec::new("sketch.construction", "Normal/Construction", construction)
|
||||
.at("SKETCH", "CREATE")
|
||||
.icon("construction")
|
||||
.key("X")
|
||||
.enabled(in_sketch)
|
||||
.params("curves: [ids], value?: bool (default toggles)"),
|
||||
CommandSpec::new("sketch.delete", "Delete Sketch Entities", sketch_delete)
|
||||
|
||||
@@ -526,6 +526,22 @@ fn preview_of_an_edit() {
|
||||
assert!(Arc::ptr_eq(&doc, &s.doc));
|
||||
}
|
||||
|
||||
/// Press Pull: positive pulls a face out, negative pushes it in (a cut), edges get a fillet.
|
||||
#[test]
|
||||
fn press_pull() {
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "PrimitiveBox", json!({"length": 40, "width": 30, "height": 20}));
|
||||
run(&mut s, "FusionPressPullCommand", json!({"face": [20, 15, 20], "distance": 5}));
|
||||
assert!(rel(volume(&mut s), 40.0 * 30.0 * 25.0) < 1e-6);
|
||||
run(&mut s, "FusionPressPullCommand", json!({"face": [20, 15, 25], "distance": "-10"}));
|
||||
assert!(rel(volume(&mut s), 40.0 * 30.0 * 15.0) < 1e-6);
|
||||
assert!(s.execute("FusionPressPullCommand", &json!({"face": [20, 15, 15], "distance": 0})).is_err());
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "PrimitiveBox", json!({"length": 40, "width": 30, "height": 20}));
|
||||
run(&mut s, "FusionPressPullCommand", json!({"edges": [[0, 0, 7]], "distance": 3}));
|
||||
assert!(rel(volume(&mut s), 24000.0 - (9.0 - PI * 9.0 / 4.0) * 20.0) < 2e-4);
|
||||
}
|
||||
|
||||
/// Extruding a planar body face (press-pull style): the face boundary becomes a sketch profile.
|
||||
#[test]
|
||||
fn extrude_a_body_face() {
|
||||
|
||||
Reference in new issue
Block a user