Offset Plane from a planar body face (#167)
construct.plane.offset now takes a planar face as its base
({"face": [x,y,z], body?, index?, path?}), captured with the same exact
face attachment a sketch on that face uses. The Offset Plane dialog accepts
planar faces as well as origin and construction planes.
A construction plane on a face is resolved through its face anchor when the
timeline is evaluated, so it follows the face when upstream features change
(and after reopening), instead of keeping the plane as it was when picked.
Tests: engine (top and side faces, follows a box resize, survives reopen,
hostile picks are refused without adding a feature) and a UI scenario that
picks a face in the dialog and builds a pad on the new plane.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
c308a1ba7a
commit
cab698bf12
5 files changed
+134
-7
No files matched your search
@@ -382,7 +382,9 @@ impl Dialog {
|
||||
),
|
||||
"solid.pipe" => Dialog::new(Kind::Pipe { diameter: "5 mm".into(), wall: String::new() }, vec![SelInput::new("Path", CURVES, true)]),
|
||||
"solid.bounding_solid" => Dialog::new(Kind::Stock { margin: "2 mm".into() }, vec![SelInput::new("Bodies (all if none)", BODIES, true)]),
|
||||
"construct.plane.offset" => Dialog::new(Kind::OffsetPlane { offset: "10 mm".into() }, vec![SelInput::new("Plane", PLANES, false)]),
|
||||
"construct.plane.offset" => {
|
||||
Dialog::new(Kind::OffsetPlane { offset: "10 mm".into() }, vec![SelInput::new("Plane", PLANES | PLANAR_FACES, false)])
|
||||
}
|
||||
"construct.plane.at_angle" => Dialog::new(
|
||||
Kind::AnglePlane { angle: "45 deg".into() },
|
||||
vec![SelInput::new("Plane", PLANES, false), SelInput::new("Axis", AXES, false)],
|
||||
@@ -2589,8 +2591,11 @@ fn dialog_commands(app: &SolveApp, d: &Dialog) -> Result<Vec<(String, Value)>, S
|
||||
Kind::OffsetPlane { offset } => {
|
||||
need(0, "a plane")?;
|
||||
let base = match sels(d, 0).first() {
|
||||
Some(Sel::Plane { name }) => name.clone(),
|
||||
_ => return Err("pick an origin or construction plane".into()),
|
||||
Some(Sel::Plane { name }) => json!(name),
|
||||
Some(face @ Sel::Face { .. }) => {
|
||||
crate::sketch_attachment_ui::face_plane(app, face).ok_or("the picked face is no longer in the model")?
|
||||
}
|
||||
_ => return Err("pick an origin or construction plane, or a planar face".into()),
|
||||
};
|
||||
("construct.plane.offset", json!({"base": base, "offset": offset}))
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user