Joints mate face to face; Drive Joints takes the keyboard; Appearance on the engine's list
Joint dialog: picked origins mate as in Fusion, B's z opposite A's (two top faces put B upside down on A, not inside it; a pin goes into its hole); the dialog's Flip turns B the other way (sent as the command's flip, which turns B over from coinciding frames). Edit Joint shows the same. Found by solvecraft-sketchux's scenarios. Drive Joints: the first value box takes the keyboard with its text selected when the dialog opens, so typing 90 and Enter drives the joint (found by solvecraft-sketchux). Appearance: "In This Design" from appearance.list (in_design) when the engine has it; faces are sent as face targets once the engine knows them. Tests: face snaps mate face to face and Flip undoes it; typing into Drive Joints drives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
b2d611bafe
commit
4c3a5d9853
3 files changed
+130
-19
No files matched your search
@@ -203,3 +203,62 @@ fn ok_click_survives_a_busy_preview() {
|
||||
assert_eq!(app.session.doc.assembly.joints.len(), 1, "the click applied the joint");
|
||||
assert!(app.dialog.is_none());
|
||||
}
|
||||
|
||||
/// 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]
|
||||
fn face_snaps_mate_face_to_face() {
|
||||
let mut app = two_boxes();
|
||||
app.start("JointAssembleCmdNew");
|
||||
let mut d = app.dialog.clone().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, 10.0)).unwrap());
|
||||
let c = apply_commands(&app, &d).unwrap();
|
||||
assert_eq!(c[0].1["flip"], true, "the mate turns B over");
|
||||
for (id, p) in c {
|
||||
app.run(&id, p).unwrap();
|
||||
}
|
||||
let st = app.session.world_state();
|
||||
let b = st.body("Body2").unwrap().mesh().bounds();
|
||||
assert!((b.min.z - 10.0).abs() < 1e-6 && (b.max.z - 20.0).abs() < 1e-6, "{b:?}");
|
||||
// Edit Joint shows the mate unflipped; Flip puts B back into A's volume.
|
||||
let id = app.session.doc.assembly.joints[0].id;
|
||||
let mut e = edit_joint(&app, id).unwrap();
|
||||
if let Kind::Assembly(Asm::Joint(f)) = &mut e.kind {
|
||||
assert!(!f.flip);
|
||||
f.flip = true;
|
||||
}
|
||||
for (id, p) in apply_commands(&app, &e).unwrap() {
|
||||
app.run(&id, p).unwrap();
|
||||
}
|
||||
let b = app.session.world_state().body("Body2").unwrap().mesh().bounds();
|
||||
assert!((b.max.z - 10.0).abs() < 1e-6, "{b:?}");
|
||||
}
|
||||
|
||||
/// Drive Joints takes the keyboard: typing a value and Enter drives the joint.
|
||||
#[test]
|
||||
fn drive_value_takes_the_keyboard() {
|
||||
let mut app = two_boxes();
|
||||
let (a, b) = (occ(&app, "A"), occ(&app, "B"));
|
||||
app.run(
|
||||
"JointAssembleCmdNew",
|
||||
json!({"type": "revolute", "a": {"occurrence": a, "face": [10, 10, 10]}, "b": {"occurrence": b, "face": [40, 10, 0]}}),
|
||||
)
|
||||
.unwrap();
|
||||
app.start("FusionMoveJointsCommand");
|
||||
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() };
|
||||
ctx.run_ui(input, |ui| crate::dialogs::show(app, ui.ctx()))
|
||||
};
|
||||
frame(&mut app, vec![]);
|
||||
frame(&mut app, vec![]);
|
||||
frame(&mut app, vec![egui::Event::Text("90".into())]);
|
||||
let key = |pressed| egui::Event::Key { key: egui::Key::Enter, physical_key: None, pressed, repeat: false, modifiers: Default::default() };
|
||||
frame(&mut app, vec![key(true), key(false)]);
|
||||
frame(&mut app, vec![]);
|
||||
let j = &app.session.doc.assembly.joints[0];
|
||||
assert!((j.values[0] - 90f64.to_radians()).abs() < 1e-9, "{:?}", j.values);
|
||||
assert!(app.dialog.is_none());
|
||||
}
|
||||
Reference in new issue
Block a user