A SAP2000-style desktop GUI for OpenSeesPy. Draw the model, click run, look at the diagrams.
Pre-alpha. Under active development. APIs and file formats will change.
---  ## Why OpenSees does nonlinear FEM well. Its user interface is a script. OTKO puts a visual front-end on it: - Draw nodes, frames, supports, and loads on a snapped grid. - Assign materials, sections, and load patterns through dialogs. - Run static, modal, pushover, and time-history analyses with progress and cancel. - Look at the results — deformed shape, mode shapes, force diagrams, pushover curves, time-history plots, hysteresis loops. - Save the model as one `.osmodel` JSON file. Diffs cleanly in Git, builds cleanly from Python. Underneath, the `core` Pydantic model works fine from a script or notebook. The GUI is a front-end, not the whole product. ## What works today - **Modeling** — grids, nodes, frames (elastic + force-based), trusses, quads, zero-length sections, restraints, equalDOF constraints, distributed loads, ground motions (`PathTimeSeries` / `UniformExcitation`). - **Materials and sections** — `Steel01`, `Steel02`, `Concrete01`, `Concrete02`, `ElasticPP`, `Hysteretic`, fiber sections (rectangular / circular patches + rebar layers), `SectionAggregator`, `BeamWithHinges`. - **Analyses** — static (load- or displacement-controlled), modal, displacement-controlled pushover, transient time-history with mode-1 Rayleigh damping. Chained workflows: gravity preload → `loadConst -time 0.0` → pushover or transient. - **Post-processing** — deformed shape (with scale slider), animated mode shapes, axial / shear / moment diagrams, pushover curves (in display units), time-history plots, hysteresis loops, response-spectrum SRSS / CQC, snapshot + video export. - **Persistence** — one JSON `.osmodel` per project, Pydantic-validated, round-trips clean. - **Examples** — 20+ verified examples, including OpenSees Wiki Examples 1–4 and a fiber-section RC frame pushover. See [`examples/README.md`](examples/README.md). ## Tech stack | Layer | Library | | ------------ | ------------------------------------ | | GUI | PySide6 (Qt 6) | | 3D viewport | PyVista + pyvistaqt (VTK) | | 2D plots | pyqtgraph | | Solver | OpenSeesPy 3.8.0.0 | | Numerics | NumPy | | Storage | Pydantic v2 (model), h5py (results) | | Tests | pytest, pytest-qt | | Lint / type | ruff, mypy | ## Architecture Strict MVVM + service layer. `core` is pure Python — no Qt, no OpenSeesPy imports — and unit-tests in isolation. ``` views (Qt) → viewmodels → services (OpenSeesRunner, Persistence) → core (model) ``` Long version in [`docs/architecture.md`](docs/architecture.md), including the OpenSeesPy command order the runner emits. ## Documentation Practical, task-first walkthroughs live in [`docs/QUICK_GUIDE.md`](docs/QUICK_GUIDE.md) — a cantilever build, modal analysis, report/script export, display units, and undo/redo. The full index is [`docs/README.md`](docs/README.md). ## Install (development) **Desktop GUI** (Qt, PyVista, pyqtgraph, imageio): ```bash git clone ssh://git@smill-home.ddns.net/smill/otko.git cd otko python -m venv .venv .venv\Scripts\activate # Windows source .venv/bin/activate # Linux / macOS pip install -e ".[gui,dev]" ``` **Headless** (core + services only, no Qt): ```bash pip install -e . ``` That pulls pydantic, numpy, h5py, openseespy and nothing else. Use it for scripts, notebooks, and web backends that reuse `otko.core` or `otko.services` without the GUI. Python 3.10+. On Windows use **3.12+** — `openseespywin==3.8.0.0` has no 3.11 wheel (`Requires-Python >=3.12`). Both pins already live in `pyproject.toml`. ## Quick start ```bash python -m otko ``` Then: 1. **File → Open** → `examples/cantilever.osmodel`. 2. **Analyze → Cases** → run `Tip-Load`. 3. **Display → Show Force Diagram** → **M3**: linear moment, 50 kN·m at the fixed end. **V2**: constant -10 kN. 4. **Display → Show Deformed Shape** → cantilever curve, as advertised. Nonlinear version: open `examples/portal_pushover.osmodel`, run `Push-X`, **Display → Show Pushover Curve**. Elastic ramp, then a yield plateau as the base hinges form. ## Run the test suite ```bash pytest tests/unit # pure logic, milliseconds pytest tests/gui # Qt event-loop tests (pytest-qt) pytest tests/integration # real OpenSeesPy runs on bundled examples ``` CI runs lint + the non-`slow` subset on Linux / macOS / Windows × Python 3.10 / 3.11 / 3.12. ## Roadmap [`docs/roadmap.md`](docs/roadmap.md) has the phase-by-phase plan. Phases 0–7 (modeling, analysis, post-processing) are mostly done. Phase 8 (isolators, ground-motion library, IDA, fiber-section editor polish) is where the open work is. ## Collaborators wanted Most useful to people who already work with OpenSees and want a shorter path from idea to model — and would rather build it together than alone. Open an issue or say hi if you are: - A **structural / earthquake engineer** who knows OpenSees Tcl or OpenSeesPy and can tell us when a feature is almost right but not quite. - A **researcher** running pushover, IDA, or response-spectrum studies who can check the GUI against hand-built scripts. - A **Python / Qt developer** into scientific desktop apps, VTK rendering, or Pydantic schema design. - A **student** learning FEM and GUI architecture at the same time — the examples and tests are meant to read as documentation. - A **UX / icon designer** willing to argue about dialogs, toolbar icons, and visual language. Bug reports and reproducible test cases count as contributions. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for setup and the rules enforced in review. ## License OTKO is **GNU Affero General Public License v3.0** ([`LICENSE`](LICENSE)). Read the license itself, not just this: - Research, education, personal projects: fine, keep the copyright notice. - Fork and modify: fine. - Distribute it (modified or not): release your full source under AGPL-3.0. - Run a modified version as a network service: release your modifications under AGPL-3.0. Commercial forks stay open. If you need a different arrangement (e.g. closed-source commercial license), open an issue. Copyright © 2026 Ozan and contributors.