Files
OneCAD/crates/ui-egui/src/stand_up.rs
T
bherbruckandClaude Opus 5.5 7318b98b8d Preferences: one Fusion-style dialog from the gear at the top right and Ctrl+, (Cmd+,)
Pages: General (theme Dark/Light/System, UI scale, units of new designs, autosave, display
precision, the agent cursor), Navigation (Fusion, SolidWorks, Inventor, Alias and Tinkercad
mouse presets, reverse zoom, zoom to the cursor, orbit centre, view-change animation on/off and
speed), Keyboard Shortcuts (the old Shortcuts window as a page: search, rebind, conflicts),
Design (default modelling orientation Y up / Z up for #3, and the offer to stand up a Y-up STEP
or IGES file: a quarter turn about X as one undoable Move), Graphics, Sketch, Selection.
Changes apply at once; Cancel or Esc puts back what was there when the dialog opened, Apply
keeps them, OK closes, Restore Defaults resets the page. The theme, ground shadow and agent
cursor settings are now kept between runs. File and Help › Keyboard Shortcuts open the page;
the unused docked Preferences dialog is gone. Control: ui.prefs {open, button, stand_up, …}.
Scenario s45_preferences; tests for Cancel/Apply/defaults and standing a Y-up file up.

Fixes #36

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
2026-10-10 05:09:03 +00:00

73 lines
3.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Standing up a Y-up file (#3). Many CAD programs save parts with Y up, so a STEP or IGES file
//! from them opens lying on its back in a Z-up design. After such a file opens, SolveCraft
//! offers to stand it up: a quarter turn about X (Y → Z) of the bodies it brought, as one
//! Move feature that can be undone or edited. Preferences › Design › "Offer to stand up Y-up
//! files" turns the offer off; with Y up as the default orientation it isn't needed.
use serde_json::json;
use crate::SolveApp;
/// The bodies a just-opened file brought (`before`: body names before it opened, none for a
/// new design): offer to stand them up.
pub fn offer(app: &mut SolveApp, path: &str, before: &[String]) {
let io = &solvecraft_engine::io::is_step_path;
if !(io(path) || solvecraft_engine::io::is_iges_path(path)) || !app.preferences.offer_stand_up || app.preferences.up_axis != "z" {
return;
}
let bodies: Vec<String> = app.session.world_state().bodies.iter().map(|b| b.name.clone()).filter(|n| !before.contains(n)).collect();
if !bodies.is_empty() {
app.stand_up = Some(bodies);
}
}
/// Turn the offered bodies a quarter turn about X (Y up becomes Z up).
pub fn stand_up(app: &mut SolveApp) -> Result<(), String> {
let Some(bodies) = app.stand_up.take() else { return Err("no file is waiting to be stood up".into()) };
app.run("solid.move", json!({ "bodies": bodies, "axis": [1, 0, 0], "angle": "90 deg" })).map_err(|e| e.to_string())?;
app.animate_view("home");
Ok(())
}
/// The offer, under the toolbar.
pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
if app.stand_up.is_none() {
return;
}
let mut act: Option<&str> = None;
crate::frame::window(ctx, "Stand this part up?", crate::frame::Width::Normal)
.id(egui::Id::new("sc_stand_up"))
.collapsible(false)
.resizable(false)
.anchor(egui::Align2::CENTER_TOP, egui::vec2(0.0, 140.0))
.show(ctx, |ui| {
ui.label("Files from many CAD programs have Y up, so they open lying on their back here (Z up).");
ui.label("Stand it up: a quarter turn about X, as one Move feature you can undo.");
ui.add_space(6.0);
ui.horizontal(|ui| {
if ui.button("Stand it up").clicked() {
act = Some("stand");
}
if ui.button("Leave it").clicked() {
act = Some("leave");
}
if ui.button("Don't ask again").on_hover_text("Preferences › Design turns the offer back on").clicked() {
act = Some("never");
}
});
});
match act {
Some("stand") => {
if let Err(e) = stand_up(app) {
app.set_status(e, true);
}
}
Some("leave") => app.stand_up = None,
Some("never") => {
app.stand_up = None;
app.preferences.offer_stand_up = false;
}
_ => {}
}
}