Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest, 3.10) (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.10) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (windows-latest, 3.10) (push) Has been cancelled
CI / test (windows-latest, 3.11) (push) Has been cancelled
CI / test (windows-latest, 3.12) (push) Has been cancelled
198 lines
11 KiB
Markdown
198 lines
11 KiB
Markdown
# Roadmap
|
||
|
||
OTKO is built in eight phases. Phases 0–7 ship the core GUI
|
||
plus all the post-processing tooling we need for verification work.
|
||
Phase 8 layers in the earthquake-engineering primitives that turn the
|
||
GUI from "OpenSees frontend" into a usable research tool.
|
||
|
||
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.
|