otko/docs/roadmap.md
smillmorel 3d809ca301
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / test (macos-latest, 3.10) (pull_request) Has been cancelled
CI / test (macos-latest, 3.11) (pull_request) Has been cancelled
CI / test (macos-latest, 3.12) (pull_request) Has been cancelled
CI / test (ubuntu-latest, 3.10) (pull_request) Has been cancelled
CI / test (ubuntu-latest, 3.11) (pull_request) Has been cancelled
CI / test (ubuntu-latest, 3.12) (pull_request) Has been cancelled
CI / test (windows-latest, 3.10) (pull_request) Has been cancelled
CI / test (windows-latest, 3.11) (pull_request) Has been cancelled
CI / test (windows-latest, 3.12) (pull_request) Has been cancelled
docs: rewrite READMEs dry and blunt, rename Studio to OTKO
2026-09-08 02:41:03 -04:00

197 lines
10 KiB
Markdown
Raw Permalink 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.

# Roadmap
Eight phases. 0–7 are the core GUI plus post-processing. Phase 8 is the
earthquake-engineering primitives — the part that makes it a research
tool instead of a model viewer.
Status legend: ✅ done · 🟡 partial · ⬜ planned · ✂️ deferred / out-of-scope.
## Phase 0 — Scaffolding ✅
- ✅ Repo, `.gitignore`, `pyproject.toml`
- ✅ Pre-commit + ruff + mypy
- ✅ GitHub Actions CI (Linux/Mac/Win × Py 3.10–3.12)
- ✅ `python -m otko` opens a `MainWindow` with PyVista 3D
viewport, model-tree dock, property dock, console dock, working-plane
toolbar, and a full menu bar (File / Edit / Define / Assign /
Analyze / Display / View / Options / Help)
- 🟡 Application icon and About dialog — wordmark logo done; native
OS icon (`.ico` / `.icns`) still pending
## Phase 1 — Core Data Model ✅
- ✅ `core.geometry`: `Node`, `Element`, `TrussElement`, `CorotTrussElement`,
`ElasticBeamColumn`, `ForceBeamColumn`, `DispBeamColumn`,
`ZeroLengthElement`, `ZeroLengthSectionElement`, `BeamWithHingesElement`,
`QuadElement`, plus `GridSystem` / `CoordinateSystem`
- ✅ `core.materials`: `ElasticIsotropic`, `ElasticUniaxial`, `ElasticPP`,
`Steel01`, `Steel02`, `Concrete01`, `Concrete02`, `HystereticMaterial`
- ✅ `core.sections`: `ElasticSection`, `FiberSection` with rectangular
/ circular patches and straight rebar layers, `SectionAggregator`
- ✅ `core.loads`: `NodalLoad`, `UniformElementLoad`, `LinearTimeSeries`,
`ConstantTimeSeries`, `PathTimeSeries`, `PlainLoadPattern`,
`UniformExcitationPattern`, `ResponseSpectrum`
- ✅ `core.analysis`: `StaticCase`, `ModalCase`, `TransientCase`,
`PushoverCase`, `ResponseSpectrumCase` — including chained preload
via `preload_case_ids` and pattern removal for free-vibration runs
- ✅ `core.constraints`: `EqualDOFConstraint` (multi-point constraints)
- ✅ `core.project.Project` aggregator with id allocation, validation,
`validate_references()`
- ✅ `services.persistence`: `.osmodel` (Pydantic JSON) load/save with
round-trip-clean assertion in every example script
## Phase 2 — OpenSees Service ✅
- ✅ `services.opensees_runner.OpenSeesRunner` emits commands in the
canonical order documented in [`architecture.md`](architecture.md)
- ✅ Verified examples (matched analytically or against the OpenSees
Wiki Tcl reference): cantilever (point + UDL), portal frame, basic
truss, SDOF pushover, RC frame gravity / pushover / earthquake,
Examples 1–4 family, two-storey shear / one-bay frames, simply
supported beam with quad elements
- ✅ `AnalysisWorker(QObject)` runnable inside a `QThread` with
`progress(int)` / `log(str)` / `finished(ResultsHandle)` signals
## Phase 3 — 3D Viewport ✅
- ✅ `views.canvas3d.ModelCanvas` (subclass of `QtInteractor` from pyvistaqt)
- ✅ Grid plane, world axes triad, view-cube-style preset buttons
(Isometric / Top XY / Front XZ / Right YZ), parallel projection toggle
- ✅ Node rendering as glyphs; element rendering as tubes (frames /
trusses) and shells (quads); supports rendered as gizmos
- ✅ Mouse picking → `nodePicked` / `elementPicked` signals; pixel-space
grid snap (rejects clicks more than 15 px from an intersection)
- ✅ Selection highlighting with in-place colour updates
## Phase 4 — Modeling Tools ✅
- ✅ Grid system dialog (X / Y / Z spacing, generates nodes); SAP2000-style
table editor; off-grid clicks rejected
- ✅ Working-plane filter — grid + snap restricted to the active level
- ✅ Draw Node / Draw Frame / Draw Truss tools with hover snap highlight
- ✅ Inline element editing from the Properties dock (truss area,
any scalar field)
- ✅ Assign Support tool (Free / Pin / Roller / Fix + custom 6-DOF dialog)
- ✅ Assign Load: nodal loads, distributed beam loads, ground motions
- ✅ Assign EqualDOF (multi-point constraints) from the UI
- ✅ Show Extruded Sections toolbar shortcut
- ✅ Undo / Redo via `QUndoStack` for every model mutation
- 🟡 Replicate / Mirror / Move / Extrude — basic copy works; story-extrude
and mirror still pending
## Phase 5 — Properties ✅
- ✅ Material library dialog (CRUD)
- ✅ Section library dialog (incl. `FiberSection` rows that previously
crashed are now handled)
- ✅ Property editor dock — context-aware, multi-selection assignment,
inline mass editor
- 🟡 Fiber-section visual editor — exists; some UI polish still needed
## Phase 6 — Analysis Pipeline ✅
- ✅ Analysis case manager dialog with case-type factories
- ✅ Run dialog with progress + log + cancel
- ✅ Per-run Rayleigh damping override (no project mutation)
- ✅ Results stored to `<project>.osresults.h5`
- 🟡 Convergence diagnostics view (residuals per step) — partial info
in run log; dedicated diagnostics dock pending
## Phase 7 — Post-processing ✅
- ✅ Deformed shape with scale-factor slider
- ✅ Mode-shape animator (1-indexed; play / scrub / scale)
- ✅ Element force diagrams (axial, shear, moment) with auto-pick of
the largest-magnitude component on dock open, numerical labels at
global min/max ends
- ✅ Time-history plotter (pyqtgraph) with displacement / velocity /
acceleration switching
- ✅ Hysteresis plotter — node DOF orbits and element local-force loops
- ✅ Pushover curve view in display units
- ✅ Response-spectrum view (Sa-T curve with modal-period markers and a
mass-participation table)
- ✅ Snapshot / video export (mode shapes + time histories) via
`imageio[ffmpeg]`
- ⬜ **Render performance pass** — collapse per-entity actors into glyphed
PolyData (single draw call), in-place colour updates for selection,
AA, lower-tessellation spheres. Target: 10k nodes / 20k frames @ 30 fps
## Phase 8 — Earthquake Engineering 🟡
- ✅ `HystereticMaterial`, `BeamWithHinges`, `FiberSection` → all
flowing into the runner, end-to-end pushover example
- ✅ Response spectrum generator + SRSS / CQC modal combination
- ✅ Ground-motion import via `PathTimeSeries` + `UniformExcitationPattern`,
with an example wired up against the OpenSees A10000 record
- ✅ `ZeroLengthSectionElement` for moment-curvature workflows; closed-form
verification example shipped
- ✅ `Concrete04` (Popovics) end-to-end: model → runner → UI form → tests →
fiber-section cantilever example
- ✅ **Material Tester service** (`services/material_tester.py`) — headless,
Qt-free; runs any uniaxial material through a monotonic or cyclic strain
protocol in an isolated single-element model and returns the full
stress–strain history. Verified: Elastic linearity, ElasticPP plateau,
Steel01 hysteresis energy (EPP formula, <1%), Concrete04 Popovics C1
continuity; state-cleanup and interleave proofs.
- ⬜ **Material Tester dialog** — Qt front-end for the service above; live
stress–strain plot with strain-amplitude and step controls
- ⬜ Seismic isolators: `elastomericBearing*`, `frictionPendulumBearing`,
`singleFPBearing`, `TripleFrictionPendulum`
- ⬜ Ground-motion library (PEER-style record set + scaling tools)
- ⬜ IDA (Incremental Dynamic Analysis) batch runner
- 🟡 Fiber-section editor — exists for rectangular / circular sections;
confined / unconfined visual presets pending
## Out-of-scope (for now)
- ✂️ Code-checking (TBDY-2018, ASCE 41, Eurocode 8)
- ✂️ Soil-structure interaction GUI
- ✂️ Cloud / collaborative editing
- ✂️ Native shell-element rendering / pre-processing (quads exist as a
primitive, but a proper shell workflow is its own phase)
## Next sessions — backlog (Sept 2026 cooldown session)
Session handoff first: ~60 files of uncommitted work in the tree
(Table dock, extrusion shapes, exporter, pattern_factors, all audit
fixes). Commit per Conventional Commits on `develop` before new work
(`feat:`/`fix:` split per lane), then `ruff check src tests &&
ruff format src tests`, `mypy`, `pytest -m "not slow"`.
Requested (user-ordered):
1. ⬜ Toolbar button icons — `resources/icons/` exists; wire `QIcon`s
in `menu_builder.py` toolbar builders (`@designer` lane: layout,
hierarchy, affordances). Include OS icon (`.ico`/`.icns`, Phase 0 🟡).
2. ⬜ Shell objects — analysis first: `QuadElement` today is continuum
(plane stress/strain). Scope OpenSees `ShellMITC4`/`ShellDKGQ` +
shell sections/materials, then core element + `_emit` + renderer
quad→shell + section dialog. Keep solver-source untouched
(emit `-factor`-style floats only). (`@oracle` for the scope call.)
3. ⬜ Input-dialog layout/usability pass — continue the Lane C pattern:
`QFormLayout` consistency, prefill from selection (done for assign
dialogs), inline validation messages instead of silent reverts,
units-aware labels. (`@designer` for layout, orchestrator for copy.)
4. ⬜ Hover tooltips — two halves: (a) canvas entity hover (node/element
id + key values via existing picking signals); (b) widget tooltip
audit (every toolbar button/dialog field documents itself).
5. ⬜ Load visibility filter — show only loads of the selected pattern /
case; hide the rest. Renderer load-overlay filter + selector combo
(builds on the Table Loads tabs' pattern filter). Natural home:
View toolbar next to Show Local Axes.
Identified this session (audit + build leftovers):
6. ⬜ Named load combinations (deferred phase 3) — `pattern_factors`
covers per-case factoring; add a reusable named-combo entity only
if one combo must be shared across many cases.
7. ⬜ Per-row Run + status in Table Analyses tab — run control lives
only in the Run dialog today; add per-case Run button + last-run
status (converged/failed/when). No overlap: the tab lists cases,
this operates them.
8. ⬜ Case-manager edit preservation — `modelMutated` while the manager
is open rebuilds the form and discards in-progress edits (audit C2).
9. ⬜ Table dock phase-4 polish — CSV copy/paste, column visibility
(deferred from the Table plan).
10. ⬜ Display-settings persistence — extruded-sections / local-axes /
parallel-projection toggles reset per project; persist viewport
prefs in `QSettings` (no `DisplaySettings` module exists yet).
11. ⬜ GUI test coverage under xvfb — `views/*` omitted from coverage;
lanes verified via offscreen smoke only. Add pytest-qt tests for:
dock toggles, Level refresh, post-state teardown, Table edits,
factor spins, local-axes overlay.
12. ⬜ Pin ruff version — local ruff (0.15.x) flags pre-existing drift
(UP037/RUF001/RUF003/E702) that repo CI doesn't; pin in
`pyproject.toml` or baseline-allowlist so `ruff check` is green.
13. ⬜ Exported-Tcl round trip — `.py` export is solver-verified;
add an equivalent exec-and-compare test for the `.tcl` renderer.