Unstitch and Reverse Normal (#856)

Unstitch takes a body's faces out as surface bodies; Reverse Normal turns a surface body's faces over. Both are saved in format 18. Closes #766.
This commit is contained in:
Irakli Kourtis authored and GitHub committed 2026-10-13 16:45:31 -04:00
1 parent b702f0efde
commit 753b0a2eab
16 files changed
+322 -19

No files matched your search

+25
View File
@@ -829,6 +829,31 @@ fn surface_extrude_dialog_takes_profiles_and_curves() {
assert_eq!(back.inputs[0].items.len(), 2);
}
#[test]
fn unstitch_and_reverse_normal_dialogs_take_a_body_or_faces() {
// A whole box picked: Unstitch sends the body alone; two of its faces: their points.
let mut app = app_with(json!([{"command": "solid.box", "params": {"length": 10, "width": 10, "height": 10, "body_name": "Box"}}]));
let mut d = start(&mut app, vec![], "surface.unstitch");
d.inputs[0].items = vec![Sel::Body { name: "Box".into() }];
let (id, p) = apply_commands(&app, &d).unwrap().remove(0);
assert_eq!((id.as_str(), &p["body"], &p["faces"]), ("surface.unstitch", &json!("Box"), &json!([])), "{p}");
let top = Vec3::new(5.0, 5.0, 10.0);
d.inputs[0].items = vec![Sel::Face { body: "Box".into(), index: 0, point: top }];
let (_, p) = apply_commands(&app, &d).unwrap().remove(0);
assert_eq!(p["faces"], json!([[5.0, 5.0, 10.0]]), "{p}");
app.session.execute("surface.unstitch", &p).unwrap();
assert_eq!(app.session.model.state().bodies.len(), 2);
let fid = app.session.doc.features.last().unwrap().id;
assert!(matches!(crate::dialogs::for_feature(&app, fid, None).unwrap().kind, Kind::Surface(_)));
app.dialog = None;
let sheet = app.session.model.state().bodies.last().unwrap().name.clone();
let mut d = start(&mut app, vec![], "surface.reverse_normal");
d.inputs[0].items = vec![Sel::Body { name: sheet.clone() }];
let (id, p) = apply_commands(&app, &d).unwrap().remove(0);
assert_eq!((id.as_str(), &p["body"]), ("surface.reverse_normal", &json!(sheet)), "{p}");
app.session.execute(&id, &p).unwrap();
}
#[test]
fn patch_dialog_fills_a_loop_of_edges_that_is_not_planar() {
// A box with its top cut away by a sideways cylinder: its rim is a closed loop of four