fix(engine): pick the face of a named body where bodies meet flush (face_body) (#710)
Extrude and Revolve from a body face take `face_body` to say whose face is meant where faces of several bodies meet flush at the picked point. Without it, an ambiguous pick now names the bodies that meet there instead of saying there is no face. Fixes #703. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d7f5b2435e
commit
a513304917
3 files changed
+54
-16
No files matched your search
@@ -13,11 +13,11 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
.at("SOLID", "CREATE")
|
||||
.icon("extrude")
|
||||
.key("E")
|
||||
.params("distance: expr (or through_all: true); taper?: angle expr; sketch?: id|name (default: active or last sketch); profiles?: all | [index] | [{curves: [ids]}] (the profile whose outer loop is made of exactly these curves, or pieces of them; found again on every recompute, so it follows parameter changes; islands inside are its holes; an error when no profile or several match) | [{point:[x,y]}] (index and point picks are stored by their curves when that finds the same profile); face?: [x,y,z] (extrude a planar body face instead of a sketch profile); direction?: positive|negative|symmetric; distance2?; start_offset?: expr (along the sketch normal, also with direction: negative); to?: [x,y,z] (To Object: a face, vertex or point; to_offset?: expr past it); from?: [x,y,z] (From Object: start at that face or point); operation?: new|join|cut|intersect|auto (cut into a body, otherwise join existing solids; new in an empty component); targets?: [body]; name?; body_name?"),
|
||||
.params("distance: expr (or through_all: true); taper?: angle expr; sketch?: id|name (default: active or last sketch); profiles?: all | [index] | [{curves: [ids]}] (the profile whose outer loop is made of exactly these curves, or pieces of them; found again on every recompute, so it follows parameter changes; islands inside are its holes; an error when no profile or several match) | [{point:[x,y]}] (index and point picks are stored by their curves when that finds the same profile); face?: [x,y,z] (extrude a planar body face instead of a sketch profile); face_body?: name (whose face, where faces of several bodies meet at the point); direction?: positive|negative|symmetric; distance2?; start_offset?: expr (along the sketch normal, also with direction: negative); to?: [x,y,z] (To Object: a face, vertex or point; to_offset?: expr past it); from?: [x,y,z] (From Object: start at that face or point); operation?: new|join|cut|intersect|auto (cut into a body, otherwise join existing solids; new in an empty component); targets?: [body]; name?; body_name?"),
|
||||
CommandSpec::new("solid.revolve", "Revolve", revolve)
|
||||
.at("SOLID", "CREATE")
|
||||
.icon("revolve")
|
||||
.params("axis: sketch line id | x | y (sketch axes) | X|Y|Z (world); angle?: expr (default 360 deg); angle2?: expr (Two Sides: the other side's angle); direction?: symmetric (angle split either side, independent of axis direction); convention?: sketch_normal|legacy_axis_start (default sketch_normal; legacy retains older angular starts); to?: [x,y,z] (To Object: turn until that face, vertex or point); sketch?, profiles? | face: [x,y,z] (a planar body face as the profile), operation?, targets?, name?, body_name?"),
|
||||
.params("axis: sketch line id | x | y (sketch axes) | X|Y|Z (world); angle?: expr (default 360 deg); angle2?: expr (Two Sides: the other side's angle); direction?: symmetric (angle split either side, independent of axis direction); convention?: sketch_normal|legacy_axis_start (default sketch_normal; legacy retains older angular starts); to?: [x,y,z] (To Object: turn until that face, vertex or point); sketch?, profiles? | face: [x,y,z] (a planar body face as the profile) and face_body?: name (whose face, where faces of several bodies meet), operation?, targets?, name?, body_name?"),
|
||||
CommandSpec::new("solid.sweep", "Sweep", sweep)
|
||||
.at("SOLID", "CREATE")
|
||||
.icon("sweep")
|
||||
@@ -114,7 +114,7 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
/// face, and the unit normal.
|
||||
fn extrude_base(s: &Session, p: &Value) -> Option<(Vec3, Vec3)> {
|
||||
if let Some(fp) = p.get("face").and_then(vec3) {
|
||||
return Some((fp, super::face::face_normal(s, fp)?));
|
||||
return Some((fp, super::face::face_normal_in(s, fp, str_(p, "face_body"))?));
|
||||
}
|
||||
let sid = feature_sketch(s, p, "Extrude").ok()?;
|
||||
let st = s.model.state();
|
||||
@@ -495,7 +495,7 @@ fn extrude(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
// A planar body face extrudes like a profile: its boundary is copied into a sketch on it.
|
||||
let (sketch, face_profile) = match p.get("face").and_then(vec3) {
|
||||
Some(fp) => {
|
||||
let (id, inside) = super::face::sketch_of_face(s, fp, cmd)?;
|
||||
let (id, inside) = super::face::sketch_of_face(s, fp, cmd, str_(p, "face_body"))?;
|
||||
(id, Some(ProfileSel::Points { points: vec![inside] }))
|
||||
}
|
||||
None => (feature_sketch(s, p, cmd)?, None),
|
||||
@@ -559,7 +559,7 @@ fn revolve(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
// A planar body face revolves like a profile (its edges projected into a sketch on it).
|
||||
let (sketch, face_profile) = match p.get("face").and_then(vec3) {
|
||||
Some(fp) => {
|
||||
let (id, inside) = super::face::sketch_of_face(s, fp, cmd)?;
|
||||
let (id, inside) = super::face::sketch_of_face(s, fp, cmd, str_(p, "face_body"))?;
|
||||
s.active_sketch = None;
|
||||
(id, Some(ProfileSel::Points { points: vec![inside] }))
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user