2026-09-16 12:03:07 -04:00
|
|
|
# OTKO Quick Guide
|
|
|
|
|
|
|
|
|
|
A practical, task-first guide to the OTKO desktop GUI. It assumes you
|
|
|
|
|
have already installed the desktop extras and can launch the app:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
pip install -e ".[gui,dev]"
|
|
|
|
|
python -m otko
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Project files use the `.osmodel` extension — a single, Pydantic-validated
|
|
|
|
|
JSON document that diffs cleanly in Git. Analysis output is written
|
|
|
|
|
separately to `*.osresults.h5`.
|
|
|
|
|
|
|
|
|
|
For the layer map and the OpenSeesPy command order, see
|
|
|
|
|
[`architecture.md`](architecture.md). For the feature-by-feature plan, see
|
|
|
|
|
[`roadmap.md`](roadmap.md).
|
|
|
|
|
|
|
|
|
|
## 1. A cantilever walkthrough
|
|
|
|
|
|
|
|
|
|
This follows the bundled `examples/cantilever.osmodel` model: a 5 m
|
|
|
|
|
horizontal beam, fixed at the left end, with a tip load. If you would
|
|
|
|
|
rather build it by hand, the steps are below.
|
|
|
|
|
|
|
|
|
|
1. **Start a project.** **File → New (3D Frame)**. Pick display units in
|
|
|
|
|
the bottom-right **Units** combo before typing any values.
|
|
|
|
|
2. **Lay out a grid.** **Define → Coordinate System/Grids…** (Ctrl+G).
|
|
|
|
|
Define X lines at 0…5 m (say, every 1 m), Y = 0, Z = 0, and set the
|
|
|
|
|
grid as the active coordinate system. The 3D canvas will draw it as
|
|
|
|
|
reference geometry.
|
|
|
|
|
3. **Add nodes.** **Define → Add Node…** (Ctrl+N), or use the **Draw
|
|
|
|
|
Node** tool and click on grid intersections at (0,0,0) … (5,0,0).
|
|
|
|
|
4. **Define material and section.** **Define → Material Library…**
|
|
|
|
|
(Ctrl+Shift+M) then **Define → Section Library…** (Ctrl+Shift+S). The
|
|
|
|
|
example uses a steel `ElasticSection` named `W12x40`.
|
|
|
|
|
5. **Draw the element.** **Assign/Define → Draw Frame** (F2), then click
|
|
|
|
|
from the first node to the last. Assign the section with
|
|
|
|
|
**Assign → Frame → Section…**.
|
|
|
|
|
6. **Add the support.** Select the node at x = 0 and use
|
|
|
|
|
**Assign → Joint → Restraints…** (Ctrl+R); restrain all six DOF. The
|
|
|
|
|
support icon confirms the fixed end.
|
|
|
|
|
7. **Add the load.** Select the tip node and use **Assign → Joint →
|
|
|
|
|
Point Loads…** (Ctrl+L). The example applies -10 kN in Y. Alternatively
|
|
|
|
|
build the distributed case with **Assign → Frame → Distributed
|
|
|
|
|
Load…**.
|
|
|
|
|
8. **Set up and run the case.** **Analyze → Cases…** (Ctrl+Shift+A) to
|
|
|
|
|
create or review a Static case, then **Analyze → Run…** (F5). The
|
|
|
|
|
bundled file already contains `Tip-Load`, `Uniform-Load`, and a modal
|
|
|
|
|
`Modal-3` case.
|
|
|
|
|
|
|
|
|
|
### Smoke check
|
|
|
|
|
|
|
|
|
|
Open `examples/cantilever.osmodel`, run the `Tip-Load` static case, then
|
|
|
|
|
**Display → Show Force Diagram… → M3**. The moment diagram is linear and
|
|
|
|
|
peaks at **50 kN·m at the fixed end**. V2 is a constant -10 kN along the
|
|
|
|
|
span. If you see that, the model, runner, and post-processor are wired up
|
|
|
|
|
correctly.
|
|
|
|
|
|
|
|
|
|
## 2. Running a modal analysis
|
|
|
|
|
|
|
|
|
|
1. Open a model that has mass assigned (the bundled cantilever lumps mass
|
|
|
|
|
at every free node so modal works out of the box).
|
|
|
|
|
2. **Analyze → Cases…**, add or select a **Modal** case, and set the
|
|
|
|
|
number of modes `n_modes` (the example uses 3).
|
|
|
|
|
3. **Analyze → Run…** (F5). Results appear in the results/report panel:
|
|
|
|
|
periods, frequencies, and participation factors per mode.
|
|
|
|
|
4. **Display → Animate Mode Shape** to view each mode. Use the mode
|
|
|
|
|
selector and the animation controls, and **Export…** if you want a
|
feat(plotly): opstool-style contour, loads, supports, ghost and animation
Bring the Plotly canvas in line with opstool's visualisation recipes.
Camera / interaction:
- frame the camera in plotly's normalized scene units, using the model
bounds (grid excluded); a data-unit eye rendered the model as a speck
- use turntable dragmode so Z stays up and the horizon stays level
- align mouse bindings with the PyVista/VTK backend and document them in
Help → Mouse Controls
Visualisation:
- colour deformed / modal shapes by response with a shared colourbar
- scale load arrows by |F|, tint per load pattern, hover the magnitude,
and fix cones rendering as oversized fins (sizemode scaled, not absolute)
- draw DOF-accurate support glyphs (ported from opstool; see NOTICE)
- add an undeformed-reference overlay on both canvas backends
- play mode shapes with plotly frame animation in-page
Tests: builder unit tests plus GUI regression tests for gestures, the
deformed push, the undeformed reference and animation payloads.
2026-09-16 23:10:22 -04:00
|
|
|
video of the mode shape. On the Plotly backend the **Play** button runs
|
|
|
|
|
the animation inside the viewport (plotly frames); on PyVista it is
|
|
|
|
|
driven from Python.
|
2026-09-16 12:03:07 -04:00
|
|
|
5. Modal results also feed the response-spectrum case: define a response
|
|
|
|
|
spectrum, then run the SRSS or CQC combination and open
|
|
|
|
|
**Display → Show Response Spectrum**.
|
|
|
|
|
|
|
|
|
|
## 3. Reviewing results and exporting a report or script
|
|
|
|
|
|
|
|
|
|
After a run, the results/report panel shows a summary for the active case
|
|
|
|
|
(static reactions and forces, modal periods, and so on). Use the display
|
|
|
|
|
actions to inspect the model visually:
|
|
|
|
|
|
feat(plotly): opstool-style contour, loads, supports, ghost and animation
Bring the Plotly canvas in line with opstool's visualisation recipes.
Camera / interaction:
- frame the camera in plotly's normalized scene units, using the model
bounds (grid excluded); a data-unit eye rendered the model as a speck
- use turntable dragmode so Z stays up and the horizon stays level
- align mouse bindings with the PyVista/VTK backend and document them in
Help → Mouse Controls
Visualisation:
- colour deformed / modal shapes by response with a shared colourbar
- scale load arrows by |F|, tint per load pattern, hover the magnitude,
and fix cones rendering as oversized fins (sizemode scaled, not absolute)
- draw DOF-accurate support glyphs (ported from opstool; see NOTICE)
- add an undeformed-reference overlay on both canvas backends
- play mode shapes with plotly frame animation in-page
Tests: builder unit tests plus GUI regression tests for gestures, the
deformed push, the undeformed reference and animation payloads.
2026-09-16 23:10:22 -04:00
|
|
|
- **Display → Show Deformed Shape** — with a scale slider. The deformed
|
|
|
|
|
shape is coloured by displacement magnitude with a colourbar, and
|
|
|
|
|
**Display → Show Undeformed Reference** overlays the original shape for
|
|
|
|
|
comparison.
|
2026-09-16 12:03:07 -04:00
|
|
|
- **Display → Show Force Diagram…** — axial (P), shear (V2/V3), moment
|
|
|
|
|
(M2/M3) diagrams.
|
|
|
|
|
- **Display → Show Pushover Curve**, **Show Time-History**, **Show
|
|
|
|
|
Hysteresis** as applicable.
|
|
|
|
|
|
feat(plotly): opstool-style contour, loads, supports, ghost and animation
Bring the Plotly canvas in line with opstool's visualisation recipes.
Camera / interaction:
- frame the camera in plotly's normalized scene units, using the model
bounds (grid excluded); a data-unit eye rendered the model as a speck
- use turntable dragmode so Z stays up and the horizon stays level
- align mouse bindings with the PyVista/VTK backend and document them in
Help → Mouse Controls
Visualisation:
- colour deformed / modal shapes by response with a shared colourbar
- scale load arrows by |F|, tint per load pattern, hover the magnitude,
and fix cones rendering as oversized fins (sizemode scaled, not absolute)
- draw DOF-accurate support glyphs (ported from opstool; see NOTICE)
- add an undeformed-reference overlay on both canvas backends
- play mode shapes with plotly frame animation in-page
Tests: builder unit tests plus GUI regression tests for gestures, the
deformed push, the undeformed reference and animation payloads.
2026-09-16 23:10:22 -04:00
|
|
|
Nodal and distributed loads are drawn as arrows whose length scales with the
|
|
|
|
|
load magnitude; each load pattern gets its own colour and hovering an arrow
|
|
|
|
|
shows its value. Support symbols show which translation directions are
|
|
|
|
|
restrained.
|
|
|
|
|
|
2026-09-16 12:03:07 -04:00
|
|
|
To hand the analysis to someone else, or to archive exactly what was run,
|
|
|
|
|
export a script:
|
|
|
|
|
|
|
|
|
|
- **File → Export OpenSeesPy (.py)…** — writes the full model, and
|
|
|
|
|
optionally a selected analysis case, as a runnable Python script.
|
|
|
|
|
- **File → Export Tcl (.tcl)…** — the same model as classic OpenSees Tcl.
|
|
|
|
|
|
|
|
|
|
The export dialog lets you choose "Model only (no analysis case)" or one
|
|
|
|
|
of the configured cases. The generated script follows the runner's fixed
|
|
|
|
|
command order (`wipe → model → node → fix → … → analyze`), so it
|
|
|
|
|
reproduces the analysis outside the GUI.
|
|
|
|
|
|
|
|
|
|
## 4. Changing display units
|
|
|
|
|
|
|
|
|
|
Use either control, they are the same setting:
|
|
|
|
|
|
|
|
|
|
- The **Units** combo in the bottom-right of the status bar, or
|
|
|
|
|
- **Options → Set Display Units…**
|
|
|
|
|
|
|
|
|
|
Changing units updates how lengths, forces, and moments are formatted in
|
|
|
|
|
the UI and plots. It does **not** rescale the underlying model numbers —
|
|
|
|
|
pick the right unit system before you type values, and convert
|
|
|
|
|
deliberately if you switch later. A set of unit labels is available in the
|
|
|
|
|
unit-label tests under `tests/unit/test_unit_labels.py`.
|
|
|
|
|
|
|
|
|
|
## 5. Undo and redo
|
|
|
|
|
|
|
|
|
|
Every model mutation goes through the undo stack, so most edits are
|
|
|
|
|
reversible:
|
|
|
|
|
|
|
|
|
|
- **Edit → Undo** (Ctrl+Z)
|
|
|
|
|
- **Edit → Redo** (Ctrl+Y / Ctrl+Shift+Z)
|
|
|
|
|
|
|
|
|
|
Menu text is dynamic — it names the operation, for example "Undo Add 4
|
|
|
|
|
Nodes". Compound operations such as drawing a frame (node + element) are
|
|
|
|
|
wrapped in a single macro, so one undo removes the whole step. File
|
|
|
|
|
loads, analysis runs, and display-only changes are not model mutations and
|
|
|
|
|
are not undoable.
|
|
|
|
|
|
feat(plotly): opstool-style contour, loads, supports, ghost and animation
Bring the Plotly canvas in line with opstool's visualisation recipes.
Camera / interaction:
- frame the camera in plotly's normalized scene units, using the model
bounds (grid excluded); a data-unit eye rendered the model as a speck
- use turntable dragmode so Z stays up and the horizon stays level
- align mouse bindings with the PyVista/VTK backend and document them in
Help → Mouse Controls
Visualisation:
- colour deformed / modal shapes by response with a shared colourbar
- scale load arrows by |F|, tint per load pattern, hover the magnitude,
and fix cones rendering as oversized fins (sizemode scaled, not absolute)
- draw DOF-accurate support glyphs (ported from opstool; see NOTICE)
- add an undeformed-reference overlay on both canvas backends
- play mode shapes with plotly frame animation in-page
Tests: builder unit tests plus GUI regression tests for gestures, the
deformed push, the undeformed reference and animation payloads.
2026-09-16 23:10:22 -04:00
|
|
|
## 6. Navigating the 3D view
|
|
|
|
|
|
|
|
|
|
Both canvas backends (**Options → Canvas Backend**) use the same VTK-style mouse
|
|
|
|
|
bindings, and **Help → Mouse Controls** lists them in the app:
|
|
|
|
|
|
|
|
|
|
- **Rotate** — left-drag.
|
|
|
|
|
- **Pan** — Shift + left-drag, or middle-drag.
|
|
|
|
|
- **Zoom** — right-drag, or the mouse wheel.
|
|
|
|
|
- **Spin (roll)** — Ctrl + left-drag.
|
|
|
|
|
- **Select** — left-click a node or element; Ctrl+click or Shift+click adds
|
|
|
|
|
to the selection. A drag moves the view; only a click without movement
|
|
|
|
|
changes the selection.
|
|
|
|
|
|
|
|
|
|
View presets: **Ctrl+1** isometric, **Ctrl+2** top (XY), **Ctrl+3** front
|
|
|
|
|
(XZ), **Ctrl+4** right (YZ), **Ctrl+E** zoom extents. The camera keeps Z up,
|
|
|
|
|
so the horizon stays level while you orbit.
|
|
|
|
|
|
2026-09-16 12:03:07 -04:00
|
|
|
## Where to go next
|
|
|
|
|
|
|
|
|
|
- [`architecture.md`](architecture.md) — MVVM layering and command order.
|
|
|
|
|
- [`roadmap.md`](roadmap.md) — what is done and what is planned.
|
|
|
|
|
- `examples/` — 20+ verified models, each generated from a checked-in
|
|
|
|
|
Python script.
|
|
|
|
|
- [`../CONTRIBUTING.md`](../CONTRIBUTING.md) — setup, rules, and verify
|
|
|
|
|
commands.
|