Fix face Extrude Join targets in assemblies (#1375)

A new face-based Extrude Join (and outward Press Pull) joins the picked face's body by default and stores that scope, so an edge-touching neighbour is no longer tried first or absorbed. Explicit targets and participants still win. Related to #226.
This commit is contained in:
Karl Von Richter authored and GitHub committed 2026-10-15 08:33:48 -04:00
1 parent 4674f0a61c
commit 8a6332be83
10 files changed
+258 -19

No files matched your search

+4 -2
View File
@@ -3395,8 +3395,10 @@ fn dialog_commands(app: &SolveApp, d: &Dialog) -> Result<Vec<(String, Value)>, S
out.push(("solid.extrude".to_string(), with(json!({"sketch": sketch, "profiles": idx}))));
}
// Each planar body face extrudes on its own.
for p in face_points(0) {
out.push(("solid.extrude".to_string(), with(json!({ "face": p }))));
for pick in sels(d, 0) {
if let Sel::Face { body, point, .. } = pick {
out.push(("solid.extrude".to_string(), with(json!({"face": pt(*point), "face_body": body}))));
}
}
return Ok(out);
}
+18
View File
@@ -9,6 +9,24 @@ use solidcraft_engine::{Sel, Session};
use crate::dialogs::{Dialog, Kind, apply_commands};
use crate::{Services, SolveApp};
#[test]
fn a_face_extrude_keeps_the_picked_body_when_faces_coincide() {
let mut app = app_with(json!([
{"command":"solid.box","params":{"length":40,"width":30,"height":20,"body_name":"Other"}},
{"command":"solid.box","params":{"length":40,"width":30,"height":20,"body_name":"Wall"}}
]));
let before = app.session.model.state();
let pick = Sel::Face { body: "Wall".into(), index: 2, point: Vec3::new(40.0, 15.0, 10.0) };
let d = start(&mut app, vec![pick], "solid.extrude");
let (command, params) = apply_commands(&app, &d).unwrap().remove(0);
assert_eq!(params["face_body"], json!("Wall"));
app.session.execute(&command, &params).unwrap();
let after = app.session.model.state();
assert_eq!(after.bodies.len(), 2);
assert!(after.body("Other").unwrap().body.same(&before.body("Other").unwrap().body));
assert!(after.body("Wall").unwrap().body.contains(Vec3::new(49.0, 15.0, 10.0)));
}
#[test]
fn path_plane_click_retains_source_and_previews_then_edits_in_place() {
let mut h = crate::scenario::Harness::new();