Skip to main content

brep_app/workbench/
simulation.rs

1//! The "Simulation" workbench: motion studies of an assembly.
2//!
3//! A study is NOT feature creation: the `includes` predicate rejects every
4//! catalogue entry. An assembly keeps its studies in its own `simulation`
5//! block (`brep_simulation`). A motor is one of the assembly's distance or
6//! angle mates, run at a constant speed or along a motion profile; every
7//! other part follows through the assembly solver on each frame. What the
8//! workbench adds is its Simulation pane — the studies, and the selected
9//! study's timeline of motors and clips — and the buttons below. They join the
10//! row only on an assembly, the one kind of document a study can drive, so
11//! no other document's toolbar changes.
12
13use super::{ButtonState, FeatureInfo, Workbench, WorkbenchButton};
14
15/// The Simulation pane's id (claim + registration key).
16pub const PANEL_ID: &str = "simulation";
17
18/// The toolbar buttons' ids.
19pub const NEW_STUDY_BUTTON_ID: &str = "simulation.new_study";
20pub const ADD_MOTOR_BUTTON_ID: &str = "simulation.add_motor";
21
22/// No creatable features: studies are not history features.
23fn includes(_feature: &FeatureInfo<'_>) -> bool {
24    false
25}
26
27/// Whether the open document is an assembly a study can drive.
28fn is_assembly(state: &ButtonState) -> bool {
29    state.engine.simulation_available()
30}
31
32fn add_motor_disabled(state: &ButtonState) -> Option<&'static str> {
33    if state.engine.simulation_motor_mates().is_empty() {
34        Some("Add a distance or angle mate first: a motor drives one")
35    } else {
36        None
37    }
38}
39
40static BUTTONS: &[WorkbenchButton] = &[
41    WorkbenchButton {
42        id: NEW_STUDY_BUTTON_ID,
43        // A timeline gaining a row.
44        glyph: "\u{E0D2}",
45        ribbon_path: "Home/Simulation/New study", size: crate::workbench::CommandSize::Large, tooltip: "New motion study of this assembly",
46        when: Some(is_assembly),
47        pressed: None,
48        disabled: None,
49        caption: None,
50        menu: &[],
51    },
52    WorkbenchButton {
53        id: ADD_MOTOR_BUTTON_ID,
54        // A mate with a turning arrow.
55        glyph: "\u{E0D3}",
56        ribbon_path: "Home/Simulation/Add motor", size: crate::workbench::CommandSize::Large, tooltip: "Add a motor: drive a distance or angle mate at a speed or along a profile",
57        when: Some(is_assembly),
58        pressed: None,
59        disabled: Some(add_motor_disabled),
60        caption: None,
61        menu: &[],
62    },
63];
64
65static PANELS: &[&str] = &[PANEL_ID];
66
67pub static SIMULATION: Workbench = Workbench {
68    id: "simulation",
69    label: "Simulation",
70    // A crank turning on a timeline.
71    glyph: "\u{E0D1}",
72    includes,
73    buttons: BUTTONS,
74    panels: PANELS,
75};