Joint dialog: say why picks on one component make no joint (#1367)
The Joint and As-built Joint dialogs explain why picks make no joint and offer Create Components from Bodies when every pick is on one component; joint.create and joint.as_built suggest component.from_bodies. Labels in all catalogs. Fixes #1239.
This commit is contained in:
1 parent
6fbb1c5d91
commit
4674f0a61c
14 files changed
+174
-10
No files matched your search
@@ -207,6 +207,66 @@ fn ok_click_survives_a_busy_preview() {
|
||||
assert!(app.dialog.is_none());
|
||||
}
|
||||
|
||||
/// #1239: two parts as bodies of one component (a multi-body STEP import). Picks on both used to
|
||||
/// make no joint with nothing said, so no option seemed to do anything. The dialog now says why
|
||||
/// under the picks and offers Create Components from Bodies, after which the same picks join.
|
||||
#[test]
|
||||
fn picks_on_one_component_say_why_and_offer_components() {
|
||||
let mut s = Session::default();
|
||||
s.execute("solid.box", &json!({"length": 20, "width": 20, "height": 10})).unwrap();
|
||||
s.execute("solid.box", &json!({"length": 20, "width": 20, "height": 10, "corner": [30, 0, 0]})).unwrap();
|
||||
let mut app = SolveApp::new(s, Services::default());
|
||||
let bodies = vec!["Body1".to_string(), "Body2".to_string()];
|
||||
// As-built: two bodies of one component are one component.
|
||||
app.session.selection = vec![Sel::Body { name: "Body1".into() }, Sel::Body { name: "Body2".into() }];
|
||||
app.start("joint.as_built");
|
||||
let d = app.dialog.take().unwrap();
|
||||
let Kind::Assembly(k) = &d.kind else { panic!("{:?}", d.kind) };
|
||||
assert_eq!(joint_problem(&app, k, &d.inputs).map(|p| p.1), Some(bodies.clone()));
|
||||
// Two faces of one body: pick another part (nothing to part).
|
||||
app.session.selection.clear();
|
||||
app.start("joint.create");
|
||||
let mut d = app.dialog.take().unwrap();
|
||||
d.pick(&app.session, face_sel(&app.session, Vec3::new(10.0, 10.0, 10.0)).unwrap());
|
||||
d.pick(&app.session, face_sel(&app.session, Vec3::new(10.0, 10.0, 0.0)).unwrap());
|
||||
let Kind::Assembly(k) = &d.kind else { panic!("{:?}", d.kind) };
|
||||
assert_eq!(joint_problem(&app, k, &d.inputs).map(|p| p.1), Some(vec![]));
|
||||
// A face of each body.
|
||||
app.start("joint.create");
|
||||
let mut d = app.dialog.take().unwrap();
|
||||
d.pick(&app.session, face_sel(&app.session, Vec3::new(10.0, 10.0, 10.0)).unwrap());
|
||||
d.pick(&app.session, face_sel(&app.session, Vec3::new(40.0, 10.0, 0.0)).unwrap());
|
||||
assert!(apply_commands(&app, &d).is_err(), "one component: no joint");
|
||||
app.dialog = Some(d);
|
||||
let ctx = egui::Context::default();
|
||||
let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1600.0, 1000.0));
|
||||
let frame = |app: &mut SolveApp, events: Vec<egui::Event>| {
|
||||
let input = egui::RawInput { screen_rect: Some(screen), events, ..Default::default() };
|
||||
let mut out = ctx.run_ui(input, |ui| crate::dialogs::show(app, ui.ctx()));
|
||||
// Nothing is painted: drop the texture changes (an unapplied delta panics on drop).
|
||||
out.textures_delta.clear();
|
||||
out
|
||||
};
|
||||
// The auto-sized dialog takes a few frames to settle its width.
|
||||
for _ in 0..3 {
|
||||
frame(&mut app, vec![]);
|
||||
}
|
||||
let out = frame(&mut app, vec![]);
|
||||
let why = crate::i18n::format("joint.one_component", &[("bodies", "Body1, Body2")]);
|
||||
assert!(text_at(&out, &why).is_some(), "the dialog says why");
|
||||
let at = text_at(&out, crate::i18n::tr("cmd.component_from_bodies")).expect("and offers the way out");
|
||||
let button = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
|
||||
frame(&mut app, vec![egui::Event::PointerMoved(at)]);
|
||||
frame(&mut app, vec![button(true)]);
|
||||
frame(&mut app, vec![button(false)]);
|
||||
assert!(bodies.iter().all(|b| app.session.doc.find_component(b).is_some()), "each body has a component");
|
||||
let d = app.dialog.as_ref().expect("the dialog stays open");
|
||||
let c = apply_commands(&app, d).unwrap();
|
||||
assert_eq!((c[0].1["a"]["occurrence"].clone(), c[0].1["b"]["occurrence"].clone()), (json!(occ(&app, "Body1")), json!(occ(&app, "Body2"))));
|
||||
let out = frame(&mut app, vec![]);
|
||||
assert!(text_at(&out, &why).is_none(), "nothing left to say");
|
||||
}
|
||||
|
||||
/// Two top faces mate face to face as in Fusion: B ends up upside down on A, not inside it;
|
||||
/// Flip turns it back over (into A).
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user