SWMMVis  6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
swmm2dresultslayer.h
Go to the documentation of this file.
1
21#ifndef OPENSWMMVIS_LAYERS_SWMM2DRESULTSLAYER_H
22#define OPENSWMMVIS_LAYERS_SWMM2DRESULTSLAYER_H
23
24#include "io/mesh2dh5reader.h" // openswmmvis::io::CoordinateReference
27#include "layers/vertexdepthreconstruct.h" // VertexDepthReconstruct::CellSplit
28#include "map/mapextent.h"
29
30#include <ogr_spatialref.h> // OGRCoordinateTransformation (issue #155)
31
32#include <QDateTime>
33#include <QLineF>
34#include <QPointF>
35#include <QPolygonF>
36#include <QRectF>
37#include <QSet>
38#include <QTimer>
39#include <QString>
40#include <QVector>
41
42#include <array>
43#include <memory>
44#include <vector>
45
46class QGraphicsScene;
47class QGraphicsItem;
50
51namespace openswmmvis::io { class Mesh2DH5Reader; }
52namespace OpenSWMM::Render {
53class IFeatureRenderer;
54class RuleList; // Slice B.5b — see ruleList() override below.
55}
56
57// Slice S5.6 (RENDERING_OUTPUT_SUBLAYERS_PLAN.md) — 2D sublayer foundation.
58#include "render/iattributeprovider.h" // Slice DM.3
68
69// ---------------------------------------------------------------------------
70// IMesh2DSource — data-source abstraction shared by live + replay modes
71// ---------------------------------------------------------------------------
72
81{
82public:
83 virtual ~IMesh2DSource() = default;
84
91 virtual int vertexCount() const = 0;
92 virtual int triangleCount() const = 0;
93
95 virtual int timeCount() const = 0;
96
101 virtual bool isLive() const { return false; }
102
109 virtual bool readMeshGeometry(std::vector<double>& vx,
110 std::vector<double>& vy,
111 std::vector<double>& vz,
112 std::vector<std::array<int, 3>>& tris) = 0;
113
121 virtual bool readCells(std::vector<double>& vx,
122 std::vector<double>& vy,
123 std::vector<double>& vz,
124 std::vector<std::array<int, 4>>& cells)
125 {
126 std::vector<std::array<int, 3>> tris;
127 if (!readMeshGeometry(vx, vy, vz, tris)) return false;
128 cells.resize(tris.size());
129 for (size_t i = 0; i < tris.size(); ++i)
130 cells[i] = { tris[i][0], tris[i][1], tris[i][2], -1 };
131 return true;
132 }
133
145 {
146 return {};
147 }
148
150 virtual bool readDepthsAt(int timeIdx, std::vector<float>& depths) = 0;
151
156 virtual bool readDepthAt(int timeIdx, int cell, float& out)
157 {
158 std::vector<float> row;
159 if (!readDepthsAt(timeIdx, row) || cell < 0 || cell >= static_cast<int>(row.size()))
160 return false;
161 out = row[static_cast<size_t>(cell)];
162 return true;
163 }
164
168 virtual int historyGeneration() const { return 0; }
169
171 virtual QDateTime simTimeAt(int timeIdx) const { (void)timeIdx; return {}; }
172
183 virtual bool readEdgeFluxAt(int timeIdx, std::vector<float>& flux)
184 {
185 (void)timeIdx; (void)flux;
186 return false;
187 }
188
195 virtual bool readEdgeGeometry(std::vector<float>& length,
196 std::vector<float>& nx,
197 std::vector<float>& ny)
198 {
199 (void)length; (void)nx; (void)ny;
200 return false;
201 }
202
218 virtual bool readVertexDepthsAt(int timeIdx, std::vector<float>& vdepths)
219 {
220 (void)timeIdx; (void)vdepths;
221 return false;
222 }
223
230 virtual bool hasFaceField(const char* dataset) const
231 {
232 (void)dataset;
233 return false;
234 }
235
238 virtual bool readFaceFieldAt(const char* dataset, int timeIdx,
239 std::vector<float>& values)
240 {
241 (void)dataset; (void)timeIdx; (void)values;
242 return false;
243 }
244
253 virtual bool readFaceEnvelope(const char* dataset, std::vector<float>& values)
254 {
255 (void)dataset; (void)values;
256 return false;
257 }
258};
259
260// ---------------------------------------------------------------------------
261// EngineMesh2DSource — live source driven by SimulationRunner ticks
262// ---------------------------------------------------------------------------
263
265{
266public:
275 EngineMesh2DSource(std::vector<double> vx,
276 std::vector<double> vy,
277 std::vector<double> vz,
278 std::vector<std::array<int,3>> tris);
279
285 EngineMesh2DSource(std::vector<double> vx,
286 std::vector<double> vy,
287 std::vector<double> vz,
288 std::vector<std::array<int,4>> cells);
289
296 void pushDepths(std::vector<float> depths,
297 QDateTime simTime,
298 double elapsedSec);
299
312 void pushFlux(std::vector<float> flux,
313 QDateTime simTime,
314 double elapsedSec);
315
324 void pushVertexSignedDepths(std::vector<double> depths,
325 QDateTime simTime,
326 double elapsedSec);
327
336 void pushRainfall(std::vector<float> rainfall,
337 std::vector<float> rainCum,
338 QDateTime simTime,
339 double elapsedSec);
340
349 void pushHeads(std::vector<float> heads,
350 QDateTime simTime,
351 double elapsedSec);
352
360 void setEnvelopes(std::vector<float> maxDepth, std::vector<float> maxVel);
361
367 void setDryDepth(double m) { dry_depth_ = m; }
368 double dryDepth() const noexcept { return dry_depth_; }
369
378 void setHistoryPinned(bool pinned);
379 bool historyPinned() const noexcept { return pinned_; }
380
388 void setEdgeGeometry(std::vector<float> length,
389 std::vector<float> nx,
390 std::vector<float> ny);
391
392 // IMesh2DSource
393 int vertexCount() const override { return static_cast<int>(vx_.size()); }
394 int triangleCount() const override { return static_cast<int>(cells_.size()); }
395 int timeCount() const override { return static_cast<int>(history_.size()); }
396 bool isLive() const override { return !finished_; } // streaming from the running sim
397
404 void markFinished() { finished_ = true; }
405 bool readDepthAt(int timeIdx, int cell, float& out) override;
406 int historyGeneration() const override { return generation_; }
407
413 void setMaxFrames(int n) { max_frames_ = n; enforceCap_(); }
414 int maxFrames() const noexcept { return max_frames_; }
415
422 void setMaxBytes(size_t bytes) { max_bytes_ = bytes; enforceCap_(); }
423 size_t maxBytes() const noexcept { return max_bytes_; }
425 size_t historyBytes() const;
426 bool readMeshGeometry(std::vector<double>& vx,
427 std::vector<double>& vy,
428 std::vector<double>& vz,
429 std::vector<std::array<int, 3>>& tris) override;
430 bool readCells(std::vector<double>& vx,
431 std::vector<double>& vy,
432 std::vector<double>& vz,
433 std::vector<std::array<int, 4>>& cells) override;
434 bool readDepthsAt(int timeIdx, std::vector<float>& depths) override;
435 QDateTime simTimeAt(int timeIdx) const override;
436
437 bool readEdgeFluxAt(int timeIdx, std::vector<float>& flux) override;
438 bool readEdgeGeometry(std::vector<float>& length,
439 std::vector<float>& nx,
440 std::vector<float>& ny) override;
441 bool readVertexDepthsAt(int timeIdx, std::vector<float>& vdepths) override;
446 bool hasFaceField(const char* dataset) const override;
447 bool readFaceFieldAt(const char* dataset, int timeIdx,
448 std::vector<float>& values) override;
449 bool readFaceEnvelope(const char* dataset, std::vector<float>& values) override;
450
451private:
454 std::vector<float> toEdgeSlots_(std::vector<float> a) const;
455
456 std::vector<double> vx_, vy_, vz_;
457 std::vector<std::array<int,4>> cells_;
458
459 struct Tick {
460 std::vector<float> depths;
461 std::vector<float> flux;
462 std::vector<float> vertex_depths;
463 std::vector<float> rainfall;
464 std::vector<float> rain_cum;
465 std::vector<float> heads;
466 QDateTime sim_time;
467 double elapsed_sec = 0.0;
468 };
469 std::vector<Tick> history_;
470 bool has_rainfall_ = false;
471 bool has_heads_ = false;
472 bool has_flux_ = false;
473 std::vector<float> env_max_depth_;
474 std::vector<float> env_max_vel_;
475 double dry_depth_ = 1e-4;
476 int max_frames_ = 2000;
477 size_t max_bytes_ = 0;
478 int generation_ = 0;
479 bool finished_ = false;
480 bool pinned_ = false;
481 void enforceCap_();
483 bool reconstructVelocity_(int timeIdx, std::vector<float>& vx,
484 std::vector<float>& vy) const;
485
486 // Time-invariant edge geometry; populated once at twoDInitialized via
487 // setEdgeGeometry. Empty when the engine lacks the bulk geometry API.
488 std::vector<float> edge_length_;
489 std::vector<float> edge_nx_;
490 std::vector<float> edge_ny_;
491};
492
493// ---------------------------------------------------------------------------
494// HDF5Mesh2DSource — post-run source backed by Mesh2DH5Reader
495// ---------------------------------------------------------------------------
496
498{
499public:
502
503 bool open(const QString& path);
504 const QString& path() const noexcept { return path_; }
505
506 // IMesh2DSource
507 int vertexCount() const override;
508 int triangleCount() const override;
509 int timeCount() const override;
510 bool readMeshGeometry(std::vector<double>& vx,
511 std::vector<double>& vy,
512 std::vector<double>& vz,
513 std::vector<std::array<int, 3>>& tris) override;
514 bool readCells(std::vector<double>& vx,
515 std::vector<double>& vy,
516 std::vector<double>& vz,
517 std::vector<std::array<int, 4>>& cells) override;
518 bool readDepthsAt(int timeIdx, std::vector<float>& depths) override;
519 QDateTime simTimeAt(int timeIdx) const override;
520
521 bool readEdgeFluxAt(int timeIdx, std::vector<float>& flux) override;
522 bool readEdgeGeometry(std::vector<float>& length,
523 std::vector<float>& nx,
524 std::vector<float>& ny) override;
525 bool readVertexDepthsAt(int timeIdx, std::vector<float>& vdepths) override;
526 bool hasFaceField(const char* dataset) const override;
527 bool readFaceFieldAt(const char* dataset, int timeIdx,
528 std::vector<float>& values) override;
529 bool readFaceEnvelope(const char* dataset, std::vector<float>& values) override;
531
534 void setSimulationStart(QDateTime t) { sim_start_ = t; }
535
536private:
537 QString path_;
538 std::unique_ptr<openswmmvis::io::Mesh2DH5Reader> reader_;
539 QDateTime sim_start_;
540 std::vector<float> depth_buf_;
541};
542
543// ---------------------------------------------------------------------------
544// SWMM2DResultsLayer
545// ---------------------------------------------------------------------------
546
549 public OpenSWMM::Render::IAttributeProvider // Slice DM.3
550{
551 Q_OBJECT
552 Q_INTERFACES(OpenSWMM::Render::IAttributeProvider) // Slice DM.3
553public:
554 // Slice DM.3 — exposes depth / head / velocity-magnitude / velocity-
555 // x / velocity-y so renderer panels can theme the heatmap and
556 // contour rules by the right variable. All entries are dynamic.
557 // 2D results have no SWMM category concept; we ignore the cat
558 // argument and always return the mesh-scope field set.
559 [[nodiscard]] QVector<OpenSWMM::Render::AttributeField>
561 explicit SWMM2DResultsLayer(const QString& name = QStringLiteral("2D Results"),
562 OpenSWMMVisWorkspace* parent = nullptr);
563 ~SWMM2DResultsLayer() override;
564
573 void setSource(std::unique_ptr<IMesh2DSource> source);
574
575 IMesh2DSource* source() noexcept { return source_.get(); }
576 const IMesh2DSource* source() const noexcept { return source_.get(); }
577
598 void setFallbackCoordinateScale(double metresPerModelUnit);
599
603 int currentTimeIndex() const noexcept { return current_time_idx_; }
604 void setCurrentTimeIndex(int t);
605
614 void refreshCurrentFrame();
615
620 void refreshTimeRange();
621
630 void setFollowLive(bool on) noexcept { follow_live_ = on; }
631 [[nodiscard]] bool followLive() const noexcept { return follow_live_; }
632
643 void setLiveRenderEnabled(bool on);
644 [[nodiscard]] bool liveRenderEnabled() const noexcept { return live_render_enabled_; }
645
656 void closeSource();
657
659 double dryDepth() const noexcept { return dry_depth_; }
660 void setDryDepth(double d);
661
662 // ----- Self-description for the Layer Properties dialog ----------------
663 [[nodiscard]] QString sourceDescription() const override;
664 [[nodiscard]] QVector<QPair<QString, QString>> extendedMetadata() const override;
665
666 // ----- VS.8 — QSG (GPU) rendering ownership ------------------------------
667 //
668 // When MapCanvas hosts this layer in SWMM2DResultsQSGRenderer, it sets
669 // this flag and the QGraphicsItem QPainter passes return early (same
670 // per-kind bypass pattern as SWMMLayerItem §QSG-1). The CPU path stays
671 // intact as the fallback (mask clip active, QSG init failure).
672 [[nodiscard]] bool qsgOwnsRendering() const noexcept { return m_qsgOwnsRendering; }
673 void setQsgOwnsRendering(bool own);
674
677 double maxDepth() const noexcept { return max_depth_; }
678 void setMaxDepth(double d);
679
680 // ----- Velocity vector overlay (CF.2) -----------------------------------
681 //
682 // Gap A3.1 — these knobs (and the band / isoline ones below) are now
683 // facades over the sublayer model (visibility + style bags), which is
684 // the single source of truth the paint passes consult. The legacy
685 // fields survive only as fallbacks for the (never-hit) no-sublayer
686 // case. Both the dialog (legacy setters) and the layer tree (sublayer
687 // toggles) therefore drive — and report — the same state.
688
690 bool velocityVectorsVisible() const;
691 void setVelocityVectorsVisible(bool v);
692
694 qreal velocityOpacity() const;
695 void setVelocityOpacity(qreal alpha);
696
699 double velocityArrowScale() const;
700 void setVelocityArrowScale(double scale);
701
704 double maxVelocity() const noexcept { return max_velocity_; }
705 void setMaxVelocity(double v);
706
712 bool hasVelocityData() const noexcept { return have_velocity_; }
713
717 bool hasEdgeFluxData() const;
718
719 // ----- Color-ramp + contour styling (Slice CF.MVP-fix.3) ----------------
720
730 [[nodiscard]] ColorRampStyle colorRampStyle() const noexcept { return color_ramp_style_; }
732
733 [[nodiscard]] int colorClasses() const noexcept { return color_classes_; }
734 void setColorClasses(int n);
735
739 [[nodiscard]] bool filledContours() const;
740 void setFilledContours(bool on);
741 [[nodiscard]] double filledContoursOpacity() const;
742 void setFilledContoursOpacity(double a);
743 [[nodiscard]] int filledContoursLevels() const;
744 void setFilledContoursLevels(int n);
745
748 [[nodiscard]] bool isolines() const;
749 void setIsolines(bool on);
750 [[nodiscard]] int isolinesLevels() const;
751 void setIsolinesLevels(int n);
752 [[nodiscard]] QColor isolinesColor() const;
753 void setIsolinesColor(QColor c);
754 [[nodiscard]] double isolinesWidth() const;
755 void setIsolinesWidth(double px);
756
757 // ----- Renderer (Slice BI Phase 8.13.6.6) -----------------------------
758 // API plumbing only — the existing paint path still uses dry_depth_ /
759 // max_depth_ directly. Sub-phase 8.13.6.4 (deferred until Slice BB
760 // ColorRamp lands) will swap the paint loop to consult m_renderer.
761
768 [[nodiscard]] OpenSWMM::Render::IFeatureRenderer *renderer() const;
769
776 void setRenderer(std::unique_ptr<OpenSWMM::Render::IFeatureRenderer> r);
777
783 std::pair<float, int> currentPeak() const;
784
790 void setCurrentSimTime(QDateTime t);
791
800 void setCurrentSimTimeAsOf(QDateTime cursor);
801
802 // ----- Cell selection / picking (CF.3) ----------------------------------
803
809 [[nodiscard]] QVector<int> pickCellsInRect(const QRectF& sceneRect) const;
810
815 [[nodiscard]] QVector<int> pickCellsInPolygon(const QPolygonF& scenePoly) const;
816
821 [[nodiscard]] int pickCellAt(const QPointF& scenePt) const;
822
827 [[nodiscard]] float depthAtSceneNow(const QPointF& scenePt) const;
828
837 [[nodiscard]] double depthToMeshUnits() const { return resolveCoordinateScale_(); }
838
846 [[nodiscard]] float depthAtSceneInterp(const QPointF& scenePt) const;
847
853 [[nodiscard]] float depthAtCellInterp(int triIdx, const QPointF& scenePt) const;
854
860 [[nodiscard]] bool cellHasSurface(int triIdx) const;
861
869 [[nodiscard]] bool velocityAtScene(const QPointF& scenePt,
870 float& outVx, float& outVy) const;
871
878 [[nodiscard]] QVector<float> maxDepthPerVertex() const;
879
885 [[nodiscard]] float maxDepthAtSceneInterp(const QPointF& scenePt,
886 const QVector<float>& vertMax) const;
887
890 void highlightCells(const QSet<int>& triIdxSet);
891
893 void clearHighlights();
894
896 [[nodiscard]] const QSet<int>& highlightedCells() const noexcept { return m_highlighted; }
897
898 // ----- OpenSWMMVisLayer interface ----------------------------------------
899
900 void populateScene(QGraphicsScene* scene,
901 const MapExtent& canvasExtent,
902 const SpatialReferenceSystem* canvasSRS) override;
903
904 void depopulateScene(QGraphicsScene* scene) override;
905
906 void refreshScene(QGraphicsScene* scene,
907 const MapExtent& canvasExtent,
908 const SpatialReferenceSystem* canvasSRS) override;
909
910 void onCanvasCRSChanged(const SpatialReferenceSystem* newCanvasSRS) override;
911
912 // ----- Scene caches (public for the graphics item) -----------------------
913
915 struct SceneTri {
916 QPointF a, b, c;
917 QPointF centroid;
918 float depth = 0.0f;
919 // Per-corner SIGNED depths η−z (m), used by the marching-triangles
920 // contour passes. Recomputed each tick in applyCurrentDepths_() from
921 // the wet-masked vertex free-surface field, so the contour passes see
922 // a continuous scalar across cell boundaries. Without this the
923 // algorithm degenerates (v0==v1==v2 → vMax > vMin is false) and the
924 // contour passes silently skip every triangle.
925 //
926 // Exactly 0 is the NO-DATA sentinel (no wet incident cell) — EXCEPT in
927 // a cell that has at least one wet corner, where the dry corners carry
928 // the extrapolated pooling surface maxEta − z_k (negative where the bed
929 // stands above the pool). That keeps the field LINEAR on the triangle,
930 // which is what the marching passes assume, so they cut the shoreline
931 // on the true sub-cell bed intercept. Per-corner, so these are NOT
932 // interchangeable across the cells sharing a vertex.
933 // (workplans/2D_MAP_POOLING_EXTRAPOLATION_PLAN_2026-08-04.md)
934 float dv0 = 0.0f;
935 float dv1 = 0.0f;
936 float dv2 = 0.0f;
937 float vx = 0.0f;
938 float vy = 0.0f;
939 float vmag = 0.0f;
940 };
941
943 QVector<SceneTri> m_sceneTris;
947
955 struct SceneEdge {
956 QPointF a, b;
957 float slope = 0.0f;
958 };
959 QVector<SceneEdge> m_sceneEdges;
960
966 QVector<QPointF> m_sceneVerts;
967
973 [[nodiscard]] const std::vector<std::array<int, 3>> &triVertexIndices() const noexcept
974 { return tris_; }
975
978 [[nodiscard]] const std::vector<std::array<int, 4>> &cellVertexIndices() const noexcept
979 { return cells_; }
980
982 [[nodiscard]] const std::vector<int> &triCellMap() const noexcept { return triCell_; }
983
986 [[nodiscard]] const std::vector<int> &cellTriRange() const noexcept { return cellTri0_; }
987
989 [[nodiscard]] int cellCount() const noexcept { return static_cast<int>(cells_.size()); }
990
995 [[nodiscard]] quint64 geomRevision() const noexcept { return m_geomRevision; }
996
997signals:
999 void timeRangeChanged(int lo, int hi);
1000
1003
1010 void currentDateTimeChanged(const QDateTime &dt);
1011
1013 void cellHovered(int triIdx);
1014
1017
1020
1021private:
1022 bool loadFrame_(int t);
1023 void rebuildSceneGeometry_();
1024 void applyCurrentDepths_();
1025 void applyCurrentFlux_();
1026
1035 [[nodiscard]] double resolveCoordinateScale_() const;
1036
1038 quint64 m_geomRevision = 0;
1039
1043 OGRCoordinateTransformation *m_transform = nullptr;
1044
1047 mutable bool m_warnedUndeclaredCrs = false;
1048
1052 double m_fallbackMetresPerModelUnit = 1.0;
1053
1056 [[nodiscard]] int pickDisplayTriAt_(const QPointF& scenePt) const;
1059 [[nodiscard]] float depthAtDisplayTriInterp_(int triIdx, const QPointF& scenePt) const;
1060
1061 std::unique_ptr<IMesh2DSource> source_;
1062 std::vector<double> vx_, vy_, vz_;
1063 // Mixed-mesh split (workplans/TRI_QUAD_MESHING_PLAN_2026-09-06.md): the
1064 // CELLS carry the per-face values; the display FAN (one sub-triangle per
1065 // triangle cell, two per quad on the engine's VFR diagonal) is what the
1066 // scene, hit-testing, contours and interpolation run on. Every per-face
1067 // lookup for a display triangle goes through triCell_.
1068 std::vector<std::array<int,4>> cells_;
1069 std::vector<std::array<int,3>> tris_;
1070 std::vector<int> triCell_;
1071 std::vector<int> cellTri0_;
1072 std::vector<VertexDepthReconstruct::CellSplit> cellSplit_;
1073 std::vector<QPointF> cellCentroidScene_;
1074 std::vector<float> current_depths_;
1075
1076 // Sub-cell free-surface reconstruction for partial wet/dry rendering. The
1077 // engine reports a per-cell mean depth h = V/A under a flat-cell closure;
1078 // its free surface is η = z_centroid + h (horizontal at equilibrium). We
1079 // reconstruct that η at vertices and carry a SIGNED per-vertex depth so the
1080 // wet/dry shoreline cuts through cells instead of snapping to cell edges.
1081 // cellZc_ is each cell's centroid bed elevation (static; built once in
1082 // rebuildSceneGeometry_); the eta_* vectors are per-frame scratch reused by
1083 // applyCurrentDepths_ to avoid per-frame allocation.
1084 std::vector<float> cellZc_;
1085 std::vector<float> eta_vsum_;
1086 std::vector<float> eta_wsum_;
1087 std::vector<float> vdepth_;
1088
1089 // V1 (Issue 5) — per-vertex velocity field, reconstructed each frame in
1090 // applyCurrentFlux_ as the depth-weighted average of incident cell vectors.
1091 // A continuous (C0) field so glyphs sampled across cell boundaries vary
1092 // smoothly instead of stepping at each cell; the peer of vdepth_ for flow.
1093 std::vector<float> vvx_;
1094 std::vector<float> vvy_;
1095
1096 // CF.2 — per-tick flux + time-invariant edge geometry pulled once from the source.
1097 std::vector<float> current_flux_;
1098 std::vector<float> edge_length_;
1099 std::vector<float> edge_nx_;
1100 std::vector<float> edge_ny_;
1101 bool have_edge_geom_ = false;
1102 bool have_velocity_ = false;
1105 mutable int edge_flux_probe_ = 0;
1106
1107 int current_time_idx_ = -1;
1108 bool follow_live_ = true; // live source: auto-advance to newest frame until the user scrubs
1109 bool live_render_enabled_ = true; // live source: master gate for streaming/render work (Issue 2 toggle)
1110
1111 // Live-tick coalescing. A tick arrives as up to four queued pushes
1112 // (depths, flux, vertex depths, rainfall), each followed by a refresh
1113 // request; the requests are folded into ONE range emission + ONE frame
1114 // load per event-loop turn (scheduleLiveSync_ / liveSync_).
1115 bool live_sync_pending_ = false;
1116 bool live_range_dirty_ = false;
1117 bool live_frame_dirty_ = false;
1118 int last_range_hi_ = -1;
1119 void scheduleLiveSync_();
1120 void liveSync_();
1121
1122 // Incremental per-vertex max-depth envelope (maxDepthPerVertex): frames
1123 // already folded in are not re-read on the next call. Keyed on the source
1124 // and its history generation; the newest frame is always re-folded.
1125 mutable std::vector<float> vertMaxCache_;
1126 mutable std::vector<uint8_t> vertWetCache_;
1127 mutable int vertMaxFramesDone_ = 0;
1128 mutable const IMesh2DSource* vertMaxSource_ = nullptr;
1129 mutable int vertMaxGeneration_ = -1;
1130 double dry_depth_ = 1e-4; // 0.1 mm — auto-tuned per project
1131 double max_depth_ = 0.01; // 10 mm — auto-grows from data each tick
1132 bool max_depth_user_set_ = false;
1133
1134 // Velocity overlay state.
1135 // CF.2 transitional default: arrows ON so the overlay is eyeball-able
1136 // before the layer-panel UI lands. Flip back to false once a UI toggle
1137 // exists.
1138 bool velocity_visible_ = true;
1139 qreal velocity_opacity_ = 0.9;
1140 double velocity_arrow_scale_ = 30.0; // px per log1p(vmag/vRef)
1141 double max_velocity_ = 1.0; // m/s, auto-grown
1142 bool max_velocity_user_set_ = false;
1143
1144 SWMM2DResultsGraphicsItem* graphics_item_ = nullptr;
1145 SWMM2DVelocityArrowsItem* arrows_item_ = nullptr;
1146
1147 // VS.8 — true while SWMM2DResultsQSGRenderer owns the on-screen pixels.
1148 bool m_qsgOwnsRendering = false;
1149
1150 // CF.3 — selection / highlight state.
1151 QSet<int> m_highlighted;
1152
1153 // Slice BI Phase 8.13.6.6 — renderer plumbing. Initialised eagerly in
1154 // the ctor (default GraduatedRenderer) so renderer() never returns
1155 // null. Paint refactor deferred until Slice BB ColorRamp ships.
1156 std::unique_ptr<OpenSWMM::Render::IFeatureRenderer> m_renderer;
1157
1158 // Slice CF.MVP-fix.3 — graduated colour + contour styling. All default
1159 // values preserve the pre-fix.3 paint output byte-identically.
1160 ColorRampStyle color_ramp_style_ = ColorRampStyle::Smooth;
1161 int color_classes_ = 5;
1162 bool filled_contours_ = false;
1163 double filled_contours_opacity_ = 0.60;
1164 int filled_contours_levels_ = 8;
1165 bool isolines_ = false;
1166 int isolines_levels_ = 5;
1167 QColor isolines_color_ = QColor(20, 20, 20, 230);
1168 double isolines_width_ = 1.0; // pixels
1169
1170 // Slice S5.6 — sublayer foundation (dormant pointers, populated in
1171 // ctor). The existing paint pipeline does not yet consume these; the
1172 // final paint-replacement slice will replace the current SceneTri
1173 // pipeline with sublayer-driven QSG geometry.
1174 OpenSWMM::Render::MeshFillSublayer *m_meshFillSublayer = nullptr;
1175 OpenSWMM::Render::MeshEdgeSublayer *m_meshEdgeSublayer = nullptr;
1176 OpenSWMM::Render::MeshNodeSublayer *m_meshNodeSublayer = nullptr;
1177 OpenSWMM::Render::ContourBandSublayer *m_contourBandSublayer = nullptr;
1178 OpenSWMM::Render::CellDepthFillSublayer *m_cellDepthFillSublayer = nullptr;
1179 OpenSWMM::Render::SmoothDepthFillSublayer *m_smoothDepthFillSublayer = nullptr;
1180 OpenSWMM::Render::IsolineSublayer *m_isolineSublayer = nullptr;
1181 OpenSWMM::Render::VelocityVectorSublayer *m_velocityVectorSublayer = nullptr;
1182
1183 // User-customisable paint order (Slice GUI-2026-05-30 §2). Lazy-seeded
1184 // from the default order in sublayers(); reordered via moveSublayer();
1185 // round-tripped through ISublayerHost::save/loadSublayersFromJson.
1186 mutable QList<OpenSWMM::Render::ISublayer *> m_sublayerOrder;
1187
1188public:
1189 // ----- ISublayerHost interface (Slice S5.6) -----------------------------
1190 //
1191 // Default sublayer mix (2026-06-21; depth color ramp + flow arrows removed):
1192 // [0] MeshFillSublayer (static — terrain hillshade base)
1193 // [1] ContourBandSublayer (dynamic — filled bands; the depth fill, default on)
1194 // [2] MeshEdgeSublayer (static — wireframe over results)
1195 // [3] IsolineSublayer (dynamic — marching-squares isolines; default off)
1196 // [4] MeshNodeSublayer (static — coupled-vertex markers)
1197 // [5] VelocityVectorSublayer (dynamic — RT0 arrow glyphs; also show direction)
1198 [[nodiscard]] QList<OpenSWMM::Render::ISublayer *> sublayers() const override;
1199
1202 bool moveSublayer(int from, int to) override;
1203
1210 [[nodiscard]] QList<OpenSWMM::Render::LegendSymbolItem>
1211 sublayerLegendItems() const;
1212
1214 meshFillSublayer() const { return m_meshFillSublayer; }
1216 meshEdgeSublayer() const { return m_meshEdgeSublayer; }
1218 meshNodeSublayer() const { return m_meshNodeSublayer; }
1220 contourBandSublayer() const { return m_contourBandSublayer; }
1222 cellDepthFillSublayer() const { return m_cellDepthFillSublayer; }
1224 smoothDepthFillSublayer() const { return m_smoothDepthFillSublayer; }
1225 [[nodiscard]] OpenSWMM::Render::IsolineSublayer *
1226 isolineSublayer() const { return m_isolineSublayer; }
1228 velocityVectorSublayer() const { return m_velocityVectorSublayer; }
1229
1232 [[nodiscard]] std::vector<std::unique_ptr<openswmmvis::ui::ILayerStyleSubject>>
1233 styleSubjects() override;
1234
1235 // ----- Rule Model (Slice B.5b, Phase B) -------------------------------
1236 //
1237 // Five seed Rules covering the result-layer decoration archetypes
1238 // (Depth color ramp / Velocity vectors / Contour / Mesh edges /
1239 // Mesh nodes). Same lazy-build pattern as SWMM2DMeshLayer.
1240 [[nodiscard]] OpenSWMM::Render::RuleList *ruleList() override;
1241 [[nodiscard]] const OpenSWMM::Render::RuleList *ruleList() const override;
1242
1243private:
1244 void buildRuleListLazy() const;
1245 mutable std::unique_ptr<OpenSWMM::Render::RuleList> m_ruleList;
1246};
1247
1248#endif // OPENSWMMVIS_LAYERS_SWMM2DRESULTSLAYER_H
Definition swmm2dresultslayer.h:265
void pushDepths(std::vector< float > depths, QDateTime simTime, double elapsedSec)
Append one tick's worth of per-triangle depth.
Definition swmm2dresultslayer.cpp:995
size_t maxBytes() const noexcept
Definition swmm2dresultslayer.h:423
void pushRainfall(std::vector< float > rainfall, std::vector< float > rainCum, QDateTime simTime, double elapsedSec)
Append one tick's per-cell rainfall intensity (m/s) and cumulative rainfall volume (m³) — the live co...
Definition swmm2dresultslayer.cpp:1074
void pushHeads(std::vector< float > heads, QDateTime simTime, double elapsedSec)
Append one tick's per-cell water-surface elevation (m, swmm_2d_get_heads_bulk) — the live counterpart...
Definition swmm2dresultslayer.cpp:1098
bool readCells(std::vector< double > &vx, std::vector< double > &vy, std::vector< double > &vz, std::vector< std::array< int, 4 > > &cells) override
Fetch mesh geometry as CELLS: cells[i] = {v0,v1,v2,v3} with v3 == -1 for a triangle (cyclic order for...
Definition swmm2dresultslayer.cpp:1289
bool readDepthAt(int timeIdx, int cell, float &out) override
One cell's depth at timeIdx. The default copies the whole frame through readDepthsAt; a source holdin...
Definition swmm2dresultslayer.cpp:1171
QDateTime simTimeAt(int timeIdx) const override
Wall-clock sim time at timeIdx (invalid if out of range or unknown).
Definition swmm2dresultslayer.cpp:1311
void setHistoryPinned(bool pinned)
Hold the frame numbering still: while pinned, pushDepths and friends still append but the history cap...
Definition swmm2dresultslayer.cpp:1126
double dryDepth() const noexcept
Definition swmm2dresultslayer.h:368
bool readEdgeGeometry(std::vector< float > &length, std::vector< float > &nx, std::vector< float > &ny) override
Fetch time-invariant edge geometry (length + outward unit normal).
Definition swmm2dresultslayer.cpp:1334
void setEdgeGeometry(std::vector< float > length, std::vector< float > nx, std::vector< float > ny)
Install time-invariant edge geometry queried via swmm_2d_edge_get_geometry_bulk once at twoDInitializ...
Definition swmm2dresultslayer.cpp:1267
void markFinished()
Stop advertising as live once the run has ended. The retained in-memory history stays fully scrubbabl...
Definition swmm2dresultslayer.h:404
bool readMeshGeometry(std::vector< double > &vx, std::vector< double > &vy, std::vector< double > &vz, std::vector< std::array< int, 3 > > &tris) override
Fetch mesh geometry as a DISPLAY triangle fan. Resizes outputs.
Definition swmm2dresultslayer.cpp:1276
bool isLive() const override
True while this source is streaming from a running simulation (frames keep arriving)....
Definition swmm2dresultslayer.h:396
int vertexCount() const override
Geometry counts. Stable for the lifetime of the source.
Definition swmm2dresultslayer.h:393
void setMaxBytes(size_t bytes)
Byte budget for the retained history (0 = unlimited), checked alongside the frame cap....
Definition swmm2dresultslayer.h:422
int triangleCount() const override
Definition swmm2dresultslayer.h:394
int timeCount() const override
Latest known time-step count (grows during live mode).
Definition swmm2dresultslayer.h:395
int historyGeneration() const override
Bumps whenever frames are removed or reordered (a live source thinning its history),...
Definition swmm2dresultslayer.h:406
void pushVertexSignedDepths(std::vector< double > depths, QDateTime simTime, double elapsedSec)
Append one tick's worth of SIGNED per-vertex render depths (swmm_2d_vertex_get_render_depths_bulk — t...
Definition swmm2dresultslayer.cpp:1044
size_t historyBytes() const
Bytes held by the retained frames' payload vectors.
Definition swmm2dresultslayer.cpp:1132
bool readVertexDepthsAt(int timeIdx, std::vector< float > &vdepths) override
Fetch per-vertex SIGNED water depth (m) at timeIdx — the engine's wet-masked, depth-weighted render r...
Definition swmm2dresultslayer.cpp:1345
void setEnvelopes(std::vector< float > maxDepth, std::vector< float > maxVel)
Replace the cumulative per-cell envelopes (m, m/s) read via swmm_2d_get_stat_max_depths / _velocities...
Definition swmm2dresultslayer.cpp:1119
bool historyPinned() const noexcept
Definition swmm2dresultslayer.h:379
bool readDepthsAt(int timeIdx, std::vector< float > &depths) override
Fetch per-triangle depth at timeIdx. Resizes depths to triangleCount().
Definition swmm2dresultslayer.cpp:1301
int maxFrames() const noexcept
Definition swmm2dresultslayer.h:414
bool readFaceEnvelope(const char *dataset, std::vector< float > &values) override
Fetch a time-INVARIANT per-face [nFace] envelope written by the engine's ENVELOPES output group ("Mes...
Definition swmm2dresultslayer.cpp:1256
bool readEdgeFluxAt(int timeIdx, std::vector< float > &flux) override
Fetch per-edge signed normal flux at timeIdx.
Definition swmm2dresultslayer.cpp:1317
void setMaxFrames(int n)
Cap on retained frames (default 2000). Past the cap the OLDER half of the history is thinned 2:1 (fra...
Definition swmm2dresultslayer.h:413
void setDryDepth(double m)
Dry threshold (m) below which a cell's reconstructed velocity is zero — the engine's dry_depth cutoff...
Definition swmm2dresultslayer.h:367
bool readFaceFieldAt(const char *dataset, int timeIdx, std::vector< float > &values) override
Fetch one time slice of a named per-face field (engine SI units). Resized to triangleCount()....
Definition swmm2dresultslayer.cpp:1194
void pushFlux(std::vector< float > flux, QDateTime simTime, double elapsedSec)
Append one tick's worth of per-edge signed normal flux.
Definition swmm2dresultslayer.cpp:1018
bool hasFaceField(const char *dataset) const override
Definition swmm2dresultslayer.cpp:1180
Definition swmm2dresultslayer.h:498
~HDF5Mesh2DSource() override
int timeCount() const override
Latest known time-step count (grows during live mode).
Definition swmm2dresultslayer.cpp:1379
openswmmvis::io::CoordinateReference coordinateReference() const override
How the coordinates from readMeshGeometry relate to the model CRS — see openswmmvis::io::CoordinateRe...
Definition swmm2dresultslayer.cpp:1401
int vertexCount() const override
Geometry counts. Stable for the lifetime of the source.
Definition swmm2dresultslayer.cpp:1376
bool readEdgeFluxAt(int timeIdx, std::vector< float > &flux) override
Fetch per-edge signed normal flux at timeIdx.
Definition swmm2dresultslayer.cpp:1414
bool readMeshGeometry(std::vector< double > &vx, std::vector< double > &vy, std::vector< double > &vz, std::vector< std::array< int, 3 > > &tris) override
Fetch mesh geometry as a DISPLAY triangle fan. Resizes outputs.
Definition swmm2dresultslayer.cpp:1381
HDF5Mesh2DSource()
Definition swmm2dresultslayer.cpp:1364
bool readDepthsAt(int timeIdx, std::vector< float > &depths) override
Fetch per-triangle depth at timeIdx. Resizes depths to triangleCount().
Definition swmm2dresultslayer.cpp:1409
bool hasFaceField(const char *dataset) const override
Whether the source carries a named per-face [nTime, nFace] field beyond depth (e.g....
Definition swmm2dresultslayer.cpp:1419
bool readCells(std::vector< double > &vx, std::vector< double > &vy, std::vector< double > &vz, std::vector< std::array< int, 4 > > &cells) override
Fetch mesh geometry as CELLS: cells[i] = {v0,v1,v2,v3} with v3 == -1 for a triangle (cyclic order for...
Definition swmm2dresultslayer.cpp:1391
int triangleCount() const override
Definition swmm2dresultslayer.cpp:1378
bool readFaceEnvelope(const char *dataset, std::vector< float > &values) override
Fetch a time-INVARIANT per-face [nFace] envelope written by the engine's ENVELOPES output group ("Mes...
Definition swmm2dresultslayer.cpp:1430
bool readFaceFieldAt(const char *dataset, int timeIdx, std::vector< float > &values) override
Fetch one time slice of a named per-face field (engine SI units). Resized to triangleCount()....
Definition swmm2dresultslayer.cpp:1424
bool readVertexDepthsAt(int timeIdx, std::vector< float > &vdepths) override
Fetch per-vertex SIGNED water depth (m) at timeIdx — the engine's wet-masked, depth-weighted render r...
Definition swmm2dresultslayer.cpp:1443
const QString & path() const noexcept
Definition swmm2dresultslayer.h:504
void setSimulationStart(QDateTime t)
Anchor wall-clock time for the simulation start (so /time (seconds since start) maps back to a QDateT...
Definition swmm2dresultslayer.h:534
bool readEdgeGeometry(std::vector< float > &length, std::vector< float > &nx, std::vector< float > &ny) override
Fetch time-invariant edge geometry (length + outward unit normal).
Definition swmm2dresultslayer.cpp:1436
bool open(const QString &path)
Definition swmm2dresultslayer.cpp:1370
QDateTime simTimeAt(int timeIdx) const override
Wall-clock sim time at timeIdx (invalid if out of range or unknown).
Definition swmm2dresultslayer.cpp:1458
Abstract source of mesh geometry + per-triangle depth time series.
Definition swmm2dresultslayer.h:81
virtual bool readDepthAt(int timeIdx, int cell, float &out)
One cell's depth at timeIdx. The default copies the whole frame through readDepthsAt; a source holdin...
Definition swmm2dresultslayer.h:156
virtual bool readEdgeFluxAt(int timeIdx, std::vector< float > &flux)
Fetch per-edge signed normal flux at timeIdx.
Definition swmm2dresultslayer.h:183
virtual bool readFaceEnvelope(const char *dataset, std::vector< float > &values)
Fetch a time-INVARIANT per-face [nFace] envelope written by the engine's ENVELOPES output group ("Mes...
Definition swmm2dresultslayer.h:253
virtual int timeCount() const =0
Latest known time-step count (grows during live mode).
virtual bool readEdgeGeometry(std::vector< float > &length, std::vector< float > &nx, std::vector< float > &ny)
Fetch time-invariant edge geometry (length + outward unit normal).
Definition swmm2dresultslayer.h:195
virtual bool readMeshGeometry(std::vector< double > &vx, std::vector< double > &vy, std::vector< double > &vz, std::vector< std::array< int, 3 > > &tris)=0
Fetch mesh geometry as a DISPLAY triangle fan. Resizes outputs.
virtual int historyGeneration() const
Bumps whenever frames are removed or reordered (a live source thinning its history),...
Definition swmm2dresultslayer.h:168
virtual bool readCells(std::vector< double > &vx, std::vector< double > &vy, std::vector< double > &vz, std::vector< std::array< int, 4 > > &cells)
Fetch mesh geometry as CELLS: cells[i] = {v0,v1,v2,v3} with v3 == -1 for a triangle (cyclic order for...
Definition swmm2dresultslayer.h:121
virtual bool readFaceFieldAt(const char *dataset, int timeIdx, std::vector< float > &values)
Fetch one time slice of a named per-face field (engine SI units). Resized to triangleCount()....
Definition swmm2dresultslayer.h:238
virtual bool isLive() const
True while this source is streaming from a running simulation (frames keep arriving)....
Definition swmm2dresultslayer.h:101
virtual bool hasFaceField(const char *dataset) const
Whether the source carries a named per-face [nTime, nFace] field beyond depth (e.g....
Definition swmm2dresultslayer.h:230
virtual QDateTime simTimeAt(int timeIdx) const
Wall-clock sim time at timeIdx (invalid if out of range or unknown).
Definition swmm2dresultslayer.h:171
virtual int triangleCount() const =0
virtual ~IMesh2DSource()=default
virtual openswmmvis::io::CoordinateReference coordinateReference() const
How the coordinates from readMeshGeometry relate to the model CRS — see openswmmvis::io::CoordinateRe...
Definition swmm2dresultslayer.h:144
virtual int vertexCount() const =0
Geometry counts. Stable for the lifetime of the source.
virtual bool readVertexDepthsAt(int timeIdx, std::vector< float > &vdepths)
Fetch per-vertex SIGNED water depth (m) at timeIdx — the engine's wet-masked, depth-weighted render r...
Definition swmm2dresultslayer.h:218
virtual bool readDepthsAt(int timeIdx, std::vector< float > &depths)=0
Fetch per-triangle depth at timeIdx. Resizes depths to triangleCount().
An axis-aligned bounding box in the coordinate space of a given CRS.
Definition mapextent.h:26
Definition scalarfillsublayer.h:104
Definition contourbandsublayer.h:111
Interface every themeable layer implements so renderer panels can populate attribute combos without h...
Definition iattributeprovider.h:73
Abstract interface — every vector layer's paint path goes here.
Definition ifeaturerenderer.h:85
Mixin interface for layers that expose a list of ISublayers.
Definition isublayerhost.h:64
Definition isolinesublayer.h:142
Definition meshedgesublayer.h:110
Definition meshfillsublayer.h:183
Definition meshnodesublayer.h:80
Ordered owning container for Rules on one layer.
Definition rulelist.h:48
Definition scalarfillsublayer.h:142
Definition velocityvectorsublayer.h:147
Abstract base class for all layers displayed in the MapCanvas.
Definition openswmmvislayer.h:116
QString name() const
Returns the user-visible name of this layer.
Definition openswmmvislayer.cpp:62
@ SWMM2DResultsLayer
Definition openswmmvislayer.h:150
Top-level project container managing sessions, the SWMM model layer, and persistence paths for one SW...
Definition openswmmvisworkspace.h:42
Definition swmm2dresultslayer.cpp:249
Definition swmm2dresultslayer.h:550
void setDryDepth(double d)
Definition swmm2dresultslayer.cpp:2042
bool filledContours() const
Show filled-band contour polygons over the heatmap (off by default). Gap A3.1 — facades over the Cont...
Definition swmm2dresultslayer.cpp:2169
void highlightedCellsChanged()
bool liveRenderEnabled() const noexcept
Definition swmm2dresultslayer.h:644
bool velocityVectorsVisible() const
Whether centroid arrow glyphs are drawn over the depth fill.
Definition swmm2dresultslayer.cpp:2078
bool followLive() const noexcept
Definition swmm2dresultslayer.h:631
OpenSWMM::Render::CellDepthFillSublayer * cellDepthFillSublayer() const
Definition swmm2dresultslayer.h:1222
std::pair< float, int > currentPeak() const
Statistic on the current frame — useful for the status-bar peak readout.
Definition swmm2dresultslayer.cpp:2288
OpenSWMM::Render::IsolineSublayer * isolineSublayer() const
Definition swmm2dresultslayer.h:1226
QVector< float > maxDepthPerVertex() const
Per-**vertex** maximum water depth (m), the temporal max of the per-frame signed vertex reconstructio...
Definition swmm2dresultslayer.cpp:2587
ColorRampStyle colorRampStyle() const noexcept
Definition swmm2dresultslayer.h:730
QVector< QPointF > m_sceneVerts
Definition swmm2dresultslayer.h:966
void closeSource()
Release the active source — closes its underlying HDF5 handle (when the source is an HDF5Mesh2DSource...
Definition swmm2dresultslayer.cpp:2009
float maxDepthAtSceneInterp(const QPointF &scenePt, const QVector< float > &vertMax) const
Barycentrically interpolated max water depth (m) at scenePt from a precomputed per-vertex max array v...
Definition swmm2dresultslayer.cpp:2644
OpenSWMM::Render::VelocityVectorSublayer * velocityVectorSublayer() const
Definition swmm2dresultslayer.h:1228
QList< OpenSWMM::Render::ISublayer * > sublayers() const override
The ordered list of sublayers owned by this layer.
Definition swmm2dresultslayer.cpp:1583
double velocityArrowScale() const
Per-glyph pixel scale: arrow_length_px = scale * log1p(vmag / vmagRef). Default 30 — a 1 m/s velocity...
Definition swmm2dresultslayer.cpp:2113
const std::vector< std::array< int, 4 > > & cellVertexIndices() const noexcept
Definition swmm2dresultslayer.h:978
bool velocityAtScene(const QPointF &scenePt, float &outVx, float &outVy) const
Barycentrically-interpolated scene-space velocity (m/s) at scenePt, from the per-vertex velocity fiel...
Definition swmm2dresultslayer.cpp:2531
void setFilledContoursLevels(int n)
Definition swmm2dresultslayer.cpp:2209
bool hasVelocityData() const noexcept
Whether the active source produced both edge geometry and a flux slice — i.e. whether the velocity ov...
Definition swmm2dresultslayer.h:712
void setFallbackCoordinateScale(double metresPerModelUnit)
Metres per model-CRS linear unit, for sources that declare none.
Definition swmm2dresultslayer.cpp:3251
void rendererChanged()
Emitted when setRenderer() swaps the renderer pointer.
void setMaxVelocity(double v)
Definition swmm2dresultslayer.cpp:2132
int currentTimeIndex() const noexcept
Current time index displayed on the canvas. -1 = no frame yet.
Definition swmm2dresultslayer.h:603
QVector< QPair< QString, QString > > extendedMetadata() const override
Ordered key→value pairs of TYPE-SPECIFIC metadata, rendered by the Metadata tab below the common bloc...
Definition swmm2dresultslayer.cpp:1941
double depthToMeshUnits() const
Factor that takes a 2D result DEPTH (engine SI metres — every depth accessor on this layer returns me...
Definition swmm2dresultslayer.h:837
const std::vector< int > & triCellMap() const noexcept
Definition swmm2dresultslayer.h:982
OpenSWMM::Render::RuleList * ruleList() override
Definition swmm2dresultslayer.cpp:3533
void setIsolinesColor(QColor c)
Definition swmm2dresultslayer.cpp:2260
void setColorRampStyle(ColorRampStyle s)
Definition swmm2dresultslayer.cpp:2146
~SWMM2DResultsLayer() override
Definition swmm2dresultslayer.cpp:1577
void setColorClasses(int n)
Definition swmm2dresultslayer.cpp:2154
QString sourceDescription() const override
Human-readable source of this layer: a file path, a service URL, or a description for in-memory / der...
Definition swmm2dresultslayer.cpp:1932
void setSource(std::unique_ptr< IMesh2DSource > source)
Swap the data source. Triggers a one-time mesh-geometry rebuild; the current time index is clamped to...
Definition swmm2dresultslayer.cpp:1663
int colorClasses() const noexcept
Definition swmm2dresultslayer.h:733
void highlightCells(const QSet< int > &triIdxSet)
Replace the highlight set. Triggers an Overlay repaint via the layer's existing invalidate path.
Definition swmm2dresultslayer.cpp:2674
float depthAtSceneNow(const QPointF &scenePt) const
Current-frame water depth (m) at scenePt: locates the containing cell via pickCellAt and returns its ...
Definition swmm2dresultslayer.cpp:2454
IMesh2DSource * source() noexcept
Definition swmm2dresultslayer.h:575
bool isolines() const
Stroke iso-depth contour lines over the heatmap (off by default). Gap A3.1 — facades over the Isoline...
Definition swmm2dresultslayer.cpp:2220
void cellHovered(int triIdx)
QVector< int > pickCellsInRect(const QRectF &sceneRect) const
Return CELL indices whose scene-space (area) centroid falls inside sceneRect. Linear scan over the ce...
Definition swmm2dresultslayer.cpp:2369
void setFollowLive(bool on) noexcept
Follow-latest behavior for a LIVE (streaming) source. When on (the default), refreshTimeRange() advan...
Definition swmm2dresultslayer.h:630
OpenSWMM::Render::MeshFillSublayer * meshFillSublayer() const
Definition swmm2dresultslayer.h:1214
bool hasEdgeFluxData() const
Whether the run carries per-edge flux data at all, independent of the current frame....
Definition swmm2dresultslayer.cpp:1645
quint64 geomRevision() const noexcept
Definition swmm2dresultslayer.h:995
int pickCellAt(const QPointF &scenePt) const
Return the CELL containing scenePt, or -1 (barycentric test on the display fan, mapped to the owning ...
Definition swmm2dresultslayer.cpp:2422
QVector< OpenSWMM::Render::AttributeField > availableAttributes(OpenSWMMVis::SwmmCategory cat) const override
Definition swmm2dresultslayer.cpp:3509
void currentDateTimeChanged(const QDateTime &dt)
Emitted alongside currentTimeChanged(int) with the QDateTime of the frame (or invalid if the source h...
QVector< SceneTri > m_sceneTris
Definition swmm2dresultslayer.h:943
void populateScene(QGraphicsScene *scene, const MapExtent &canvasExtent, const SpatialReferenceSystem *canvasSRS) override
Creates / updates QGraphicsItems representing this layer in the scene.
Definition swmm2dresultslayer.cpp:3190
void setIsolinesWidth(double px)
Definition swmm2dresultslayer.cpp:2277
void currentTimeChanged(int t)
float depthAtCellInterp(int triIdx, const QPointF &scenePt) const
Barycentrically interpolated current-frame depth (m) at scenePt when its containing cell index is alr...
Definition swmm2dresultslayer.cpp:2466
OpenSWMM::Render::MeshEdgeSublayer * meshEdgeSublayer() const
Definition swmm2dresultslayer.h:1216
void setVelocityArrowScale(double scale)
Definition swmm2dresultslayer.cpp:2120
OpenSWMM::Render::IFeatureRenderer * renderer() const
The IFeatureRenderer that will drive this layer's paint pass.
Definition swmm2dresultslayer.cpp:1630
void refreshScene(QGraphicsScene *scene, const MapExtent &canvasExtent, const SpatialReferenceSystem *canvasSRS) override
Smart scene refresh — updates existing items instead of destroying and recreating.
Definition swmm2dresultslayer.cpp:3239
std::vector< std::unique_ptr< openswmmvis::ui::ILayerStyleSubject > > styleSubjects() override
Definition swmm2dresultslayer.cpp:3786
void setCurrentSimTimeAsOf(QDateTime cursor)
Set the current frame causally: the latest frame whose simulation time is at or before cursor (floor)...
Definition swmm2dresultslayer.cpp:2335
void setFilledContours(bool on)
Definition swmm2dresultslayer.cpp:2175
bool qsgOwnsRendering() const noexcept
Definition swmm2dresultslayer.h:672
OpenSWMM::Render::ContourBandSublayer * contourBandSublayer() const
Definition swmm2dresultslayer.h:1220
MeshSpatialGrid m_triGrid
Definition swmm2dresultslayer.h:946
void setCurrentTimeIndex(int t)
Definition swmm2dresultslayer.cpp:1839
void setVelocityVectorsVisible(bool v)
Definition swmm2dresultslayer.cpp:2084
QList< OpenSWMM::Render::LegendSymbolItem > sublayerLegendItems() const
Definition swmm2dresultslayer.cpp:3343
void setIsolinesLevels(int n)
Definition swmm2dresultslayer.cpp:2242
void depopulateScene(QGraphicsScene *scene) override
Removes all QGraphicsItems belonging to this layer from the scene.
Definition swmm2dresultslayer.cpp:3213
OpenSWMM::Render::SmoothDepthFillSublayer * smoothDepthFillSublayer() const
Definition swmm2dresultslayer.h:1224
void setQsgOwnsRendering(bool own)
Definition swmm2dresultslayer.cpp:1902
QVector< int > pickCellsInPolygon(const QPolygonF &scenePoly) const
Return CELL indices whose scene-space centroid falls inside scenePoly (odd-even fill rule)....
Definition swmm2dresultslayer.cpp:2382
bool moveSublayer(int from, int to) override
Definition swmm2dresultslayer.cpp:1614
void setRenderer(std::unique_ptr< OpenSWMM::Render::IFeatureRenderer > r)
Replaces the current renderer.
Definition swmm2dresultslayer.cpp:1635
const QSet< int > & highlightedCells() const noexcept
Current highlight set (read-only).
Definition swmm2dresultslayer.h:896
bool cellHasSurface(int triIdx) const
True when any corner of cell triIdx carries a valid free surface η this frame (signed per-vertex dept...
Definition swmm2dresultslayer.cpp:2518
void setMaxDepth(double d)
Definition swmm2dresultslayer.cpp:2063
double maxVelocity() const noexcept
Upper end of the velocity colour ramp (m/s). Auto-tracks the running max unless explicitly set.
Definition swmm2dresultslayer.h:704
void clearHighlights()
Add to / clear the highlight set.
Definition swmm2dresultslayer.cpp:2687
void setFilledContoursOpacity(double a)
Definition swmm2dresultslayer.cpp:2191
OpenSWMM::Render::MeshNodeSublayer * meshNodeSublayer() const
Definition swmm2dresultslayer.h:1218
const std::vector< int > & cellTriRange() const noexcept
Definition swmm2dresultslayer.h:986
void setLiveRenderEnabled(bool on)
Master on/off gate for LIVE (streaming) rendering during a run. Distinct from followLive (which only ...
Definition swmm2dresultslayer.cpp:1913
double isolinesWidth() const
Definition swmm2dresultslayer.cpp:2270
double maxDepth() const noexcept
Upper end of the colour ramp (metres). Auto-tracks the global max depth seen so far across all loaded...
Definition swmm2dresultslayer.h:677
QRectF m_sceneBBox
Definition swmm2dresultslayer.h:942
float depthAtSceneInterp(const QPointF &scenePt) const
Current-frame water depth (m) at scenePt, barycentrically interpolated from the containing cell's per...
Definition swmm2dresultslayer.cpp:2461
int cellCount() const noexcept
Definition swmm2dresultslayer.h:989
void setIsolines(bool on)
Definition swmm2dresultslayer.cpp:2225
const std::vector< std::array< int, 3 > > & triVertexIndices() const noexcept
Definition swmm2dresultslayer.h:973
int isolinesLevels() const
Definition swmm2dresultslayer.cpp:2235
qreal velocityOpacity() const
Overall alpha applied to all arrow glyphs, 0..1. Default 0.9.
Definition swmm2dresultslayer.cpp:2095
QVector< SceneEdge > m_sceneEdges
Definition swmm2dresultslayer.h:959
QColor isolinesColor() const
Definition swmm2dresultslayer.cpp:2253
ColorRampStyle
How depth is mapped to colour in the per-cell heatmap pass.
Definition swmm2dresultslayer.h:729
double filledContoursOpacity() const
Definition swmm2dresultslayer.cpp:2185
void refreshTimeRange()
Re-query source()->timeCount() and emit timeRangeChanged if it grew. Used by the runner's per-tick re...
Definition swmm2dresultslayer.cpp:1974
void setCurrentSimTime(QDateTime t)
Set the current frame by nearest simulation time. Used to keep the 2D layer in step with the existing...
Definition swmm2dresultslayer.cpp:2295
double dryDepth() const noexcept
Dry-cell depth threshold in metres. Cells below this draw with alpha 0.
Definition swmm2dresultslayer.h:659
void onCanvasCRSChanged(const SpatialReferenceSystem *newCanvasSRS) override
Called when the user changes the canvas CRS so layers can pre-compute any CRS-dependent transform cac...
Definition swmm2dresultslayer.cpp:3311
void timeRangeChanged(int lo, int hi)
void setVelocityOpacity(qreal alpha)
Definition swmm2dresultslayer.cpp:2101
void refreshCurrentFrame()
Re-read and re-apply the current frame without moving the cursor.
Definition swmm2dresultslayer.cpp:1849
int filledContoursLevels() const
Definition swmm2dresultslayer.cpp:2202
const IMesh2DSource * source() const noexcept
Definition swmm2dresultslayer.h:576
Definition swmm2dresultslayer.cpp:768
Represents a coordinate reference system backed by a GDAL OGRSpatialReference.
Definition spatialreferencesystem.h:28
Dynamic marching-squares filled-contour-bands sublayer over a 2D mesh. Plan §3 — fifth sublayer in th...
size_t i
Definition contourjob.cpp:27
DiagramType t
Definition diagramspec.cpp:20
Layer-side seam for "what attributes can I theme by?" — Slice DM.1.
double s
Scene px per model length unit.
Definition inletdrawingview.cpp:82
QGraphicsScene * scene
Definition inletdrawingview.cpp:78
int e
Definition inpmeshreader.cpp:41
Dynamic marching-squares isoline sublayer over a 2D mesh. Plan §3 — fourth sublayer in the SWMM2DResu...
Mixin interface for layers that own a list of ISublayers.
One row in a layer's legend — label + swatch symbol + optional range.
Axis-aligned bounding box in a map coordinate system, used by MapCanvas and all layer types to define...
MaskMode m
Definition maskspec.cpp:18
std::vector< double > nx
Definition mesh2dresultsexport.cpp:448
std::vector< mesh::MeshTriangle > cells
Definition mesh2dresultsexport.cpp:102
std::vector< double > ny
Definition mesh2dresultsexport.cpp:448
std::size_t n
Definition mesh2dresultsexport.cpp:426
std::vector< int > cell
Definition mesh2dresultsexport.cpp:609
Stylable wireframe-edge sublayer for the 2D mesh.
Static terrain-fill sublayer for the 2D mesh.
Stylable mesh-vertex marker sublayer.
double length
Definition meshpatch.cpp:64
int a
Definition meshquadmatch.cpp:46
Definition gisrasterlayer.h:40
SwmmCategory
Stable ordinal categorising every SWMM-element kind that has per-kind styling, per-kind tree rows,...
Definition swmm_category.h:28
Definition gdaldrivers.h:22
Abstract base class for all map layers displayed in the MapCanvas.
QVector< int > v
pool vertex indices
Definition pslgminsize.cpp:159
QVector< int > parent
union-find
Definition pslgminsize.cpp:176
Per-cell (flat) and per-vertex (Gouraud) scalar-fill sublayers over a 2D mesh. Unlike ContourBandSubl...
Uniform spatial grid index over a set of axis-aligned bboxes.
Definition meshspatialgrid.h:63
Definition swmm2dresultslayer.h:955
QPointF a
Definition swmm2dresultslayer.h:956
QPointF b
Definition swmm2dresultslayer.h:956
float slope
Definition swmm2dresultslayer.h:957
Definition swmm2dresultslayer.h:915
QPointF a
Definition swmm2dresultslayer.h:916
float vy
Scene-space velocity y (m/s).
Definition swmm2dresultslayer.h:938
QPointF centroid
Scene-space centroid; cached at rebuildSceneGeometry_.
Definition swmm2dresultslayer.h:917
float dv2
Definition swmm2dresultslayer.h:936
float depth
Cell-centre depth (m) — drives the heatmap fill.
Definition swmm2dresultslayer.h:918
QPointF c
Definition swmm2dresultslayer.h:916
float vmag
|v| in m/s, computed in model coords.
Definition swmm2dresultslayer.h:939
float vx
Scene-space velocity x (m/s; sign flipped to match scene Y).
Definition swmm2dresultslayer.h:937
QPointF b
Definition swmm2dresultslayer.h:916
float dv0
Definition swmm2dresultslayer.h:934
float dv1
Definition swmm2dresultslayer.h:935
How a 2D result source's XY coordinates relate to the model's CRS.
Definition mesh2dh5reader.h:91
Dynamic velocity-arrow glyph sublayer over a 2D mesh. Plan §3 — third sublayer in the SWMM2DResultsLa...
Depth-weighted, wet-masked free-surface reconstruction at mesh vertices — the GUI mirror of the engin...