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

10 KiB
Raw Blame History

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
  • ✅ 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 QIcons 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):

  1. ⬜ 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.
  2. ⬜ 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.
  3. ⬜ Case-manager edit preservation — modelMutated while the manager is open rebuilds the form and discards in-progress edits (audit C2).
  4. ⬜ Table dock phase-4 polish — CSV copy/paste, column visibility (deferred from the Table plan).
  5. ⬜ Display-settings persistence — extruded-sections / local-axes / parallel-projection toggles reset per project; persist viewport prefs in QSettings (no DisplaySettings module exists yet).
  6. ⬜ 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.
  7. ⬜ 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.
  8. ⬜ Exported-Tcl round trip — .py export is solver-verified; add an equivalent exec-and-compare test for the .tcl renderer.