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
SWMM2DMeshLayer Class Reference

#include <swmm2dmeshlayer.h>

Inheritance diagram for SWMM2DMeshLayer:
Collaboration diagram for SWMM2DMeshLayer:

Classes

struct  SceneEdge
 
struct  SceneNode
 
struct  SceneTri
 

Signals

void attributeChanged (const QString &refName)
 Emitted on any successful apply* mutation. refName is the MeshObjectRef-encoded element name (see meshobjectref.h).
 
void meshEditsChanged ()
 Emitted on a bulk mutation that has no single element ref (currently applyCellCouplings). Companion to attributeChanged for listeners that only need to know "the mesh was edited" — e.g. the project dirty flag.
 
void selectionInvalidated ()
 Emitted when remesh / reload invalidates element indices in any held selection — toolbar and tools clear on receipt.
 
void activeMeshChanged (bool isActive)
 Emitted when isActiveMesh() changes.
 
void overviewBuildStarted (const QString &layerName)
 Background pyramid (overview) rebuild lifecycle — mirrors GISRasterLayer::overviewBuildStarted/Finished so the app can drive the busy bar + status message during the build.
 
void overviewBuildFinished (bool ok)
 
void sceneGeometryReady ()
 The deferred heavy geometry from a progressive load (finishSceneGeometryAsync) has been adopted — wireframe, spatial culling and editing structures are now available.
 
void rendererChanged ()
 Emitted when setRenderer() swaps the renderer pointer.
 
- Signals inherited from OpenSWMMVisLayer
void nameChanged (const QString &newName)
 
void layerTypeChanged (OpenSWMMVisLayerType newType)
 
void visibilityChanged (bool visible)
 
void opacityChanged (double opacity)
 
void srsChanged (SpatialReferenceSystem *newSRS)
 
void extentChanged (const MapExtent &newExtent)
 
void childrenChanged ()
 
void repaintRequested ()
 
void temporalSpecChanged (const OpenSWMM::Render::TemporalSpec &spec)
 
void maskSpecChanged (const OpenSWMM::Render::MaskSpec &spec)
 
void auxStorageSpecChanged (const OpenSWMM::Render::AuxiliaryStorageSpec &spec)
 
void joinsChanged (const QVector< OpenSWMM::Render::JoinSpec > &joins)
 
void diagramSpecChanged (const OpenSWMM::Render::DiagramSpec &spec)
 
void labelConfigChanged ()
 

Public Member Functions

 SWMM2DMeshLayer (mesh::MeshResult result, const QString &sourcePath={}, OpenSWMMVisWorkspace *parent=nullptr, bool deferHeavyGeometry=false)
 
 ~SWMM2DMeshLayer () override
 
void finishSceneGeometryAsync ()
 Build the deferred heavy geometry (wireframe edges, spatial grids, vertex adjacency, BC slots) on a background thread and adopt it on the GUI thread. Emits sceneGeometryReady() then repaintRequested() when done. No-op when already complete or a build is in flight. If the scene geometry was re-projected mid-build (CRS change), the stale result is discarded and the build re-runs.
 
bool sceneGeometryComplete () const
 False while the heavy structures from a deferred load are still being built — the renderers fall back to the LOD pyramid and editing/picking is limited until this flips true.
 
QString sourcePath () const
 
void setSourcePath (const QString &path)
 
bool isExternalMesh () const
 True when the mesh came from an external file referenced by [2D_MESH_FILE] FILE <path>. False for an inline mesh, whose sourcePath() is the .inp itself. Save must not re-point the .inp at an inline mesh's "source" — that would overwrite the model.
 
void setExternalMesh (bool external)
 
bool meshUnitsSI () const
 True when the mesh file declared ;; UNITS: SI (m) (or an equivalent metric keyword). The engine then SKIPS its FLOW_UNITS-based ft→m mesh scaling, so 2D results coordinates come back in the same values as the mesh. Consumed by the 2D results layer's coordinate fallback — see SWMM2DResultsLayer::setFallbackCoordinateScale and issue #155.
 
void setMeshUnitsSI (bool si)
 
int triangleCount () const
 
int quadCount () const
 
int vertexCount () const
 
int boundaryEdgeCount () const
 
int edgeCount () const
 
double maxSlope () const
 
QString sourceDescription () const override
 Human-readable source of this layer: a file path, a service URL, or a description for in-memory / derived layers.
 
QVector< QPair< QString, QString > > extendedMetadata () const override
 Ordered key→value pairs of TYPE-SPECIFIC metadata, rendered by the Metadata tab below the common block the dialog builds itself.
 
bool isActiveMesh () const
 
void setActiveMesh (bool active)
 
bool qsgOwnsRendering () const noexcept
 
void setQsgOwnsRendering (bool own)
 
bool showMeshNodes () const
 
void setShowMeshNodes (bool show)
 
bool showEdges () const
 
void setShowEdges (bool show)
 
double edgeZoomMinCellPx () const
 
void setEdgeZoomMinCellPx (double px)
 
double vertexZoomMinCellPx () const
 
void setVertexZoomMinCellPx (double px)
 
double edgeMinCellAreaPx () const
 
double vertexMinCellAreaPx () const
 
double hillshadeAzimuth () const
 
double hillshadeAltitude () const
 
double hillshadeZExag () const
 
double hillshadeMinLit () const
 
void setHillshadeAzimuth (double degrees)
 
void setHillshadeAltitude (double degrees)
 
void setHillshadeZExag (double factor)
 
void setHillshadeMinLit (double minLit)
 
bool showContours () const
 
int contourIntervalCount () const
 
QColor contourColor () const
 
double contourLineWidth () const
 
void setShowContours (bool show)
 
void setContourIntervalCount (int n)
 
void setContourColor (const QColor &c)
 
void setContourLineWidth (double widthPx)
 
bool filledContours () const
 
double filledContoursOpacity () const
 
void setFilledContours (bool filled)
 
void setFilledContoursOpacity (double a)
 
const mesh::MeshResultmesh () const
 
quint64 geomRevision () const
 
bool hasUnsavedMeshEdits () const
 Has this layer's mesh state diverged from the engine's copy?
 
void markMeshEdited ()
 Mark the layer's mesh state as diverged from the engine.
 
void setMeshEditsSaved ()
 Clear the divergence flag — only after a confirmed successful write, so a failed save still re-pushes next time.
 
const QVector< mesh::MeshEdgeBC > & edgeBCs () const
 Per-edge BC values; flat-indexed by mesh::edgeSlot(cell, edgeLocal) (stride mesh::kEdgeStride = 4). Sized to mesh::edgeSlotCount(n_cells) after mesh load; interior-edge slots and a triangle's unused slot 3 stay at the default Wall value (engine ignores them).
 
QVector< mesh::MeshEdgeBC > & edgeBCsMutable ()
 Mutable BC view — used by INP reader to bulk-populate after load. Prefer the apply* helpers for user-driven edits so views receive the attributeChanged signal. Bumps the BC revision on every access: both callers assign the whole vector through this reference, and without the bump the bcSceneEdges() render cache keyed on m_bcRevision served stale geometry after a bulk reload.
 
int pickVertexAt (double sx, double sy, double tolPx, double pxPerSceneUnit) const
 Vertex pick. Returns the closest vertex index to scene point (sx,sy) within tolPx screen-pixels, or -1 if none. pxPerSceneUnit converts scene-units to screen-pixels (use the active canvas zoom).
 
int pickEdgeAt (double sx, double sy, double tolPx, double pxPerSceneUnit, bool boundaryOnly) const
 Edge pick. Returns flat edge slot mesh::edgeSlot(cell, edgeLocal) within tolPx of (sx,sy), or -1. When boundaryOnly is true, interior edges are skipped.
 
int locateTriangleAt (double sx, double sy) const
 Cell (mesh triangle/quad index) containing scene point (sx,sy), or -1 if outside every cell. A quad is tested on its sub-triangle fan.
 
int pickCellAt (const QPointF &scenePt) const
 Triangle (cell) containing scene point scenePt, or -1. Peer of SWMM2DResultsLayer::pickCellAt; lets the Select 2D Cells map tool work against the mesh layer when no results layer exists.
 
QVector< int > pickCellsInRect (const QRectF &sceneRect) const
 Triangle indices whose centroid falls inside sceneRect. Peer of SWMM2DResultsLayer::pickCellsInRect.
 
QVector< int > pickCellsInPolygon (const QPolygonF &scenePoly) const
 Triangle indices whose centroid falls inside scenePoly. Peer of SWMM2DResultsLayer::pickCellsInPolygon.
 
double sampleZAt (double sx, double sy) const
 Barycentric Z sample at scene point (sx,sy). Returns NaN when the point is outside every triangle.
 
bool isBoundaryEdge (int triIdx, int edgeLocal) const
 True when this edge slot is a boundary edge in the loaded mesh (i.e. the corresponding triangle has no neighbour across it). Boundary classification is derived from the mesh's MeshEdge list populated by InpMeshReader; non-boundary edges return false.
 
const mesh::MeshBoundaryGraphboundaryGraph ()
 Boundary-edge connectivity graph, used by the edge-select tool's Ctrl-click shortest-path picking. Built lazily on first use and cached until the boundary flags are rebuilt.
 
QPair< int, int > findEdgeNeighbour (int triIdx, int edgeLocal) const
 
bool applyMeshVertexZ (int vertexIdx, double z)
 Set vertex Z. Mutates the layer's MeshResult, rebuilds scene geometry, emits attributeChanged with the vertex ref name.
 
bool applyMeshEdgeBC (int triIdx, int edgeLocal, const mesh::MeshEdgeBC &bc)
 Replace the entire BC value for edge (triIdx,edgeLocal). Emits attributeChanged. Apply-as-you-go.
 
bool applyMeshEdgeConveyance (int triIdx, int edgeLocal, double conveyance)
 Engine §11A — set the per-edge conveyance (flux attenuation multiplier) in [0, 1]. Rejects out-of-range values (the C API does the same; the toolbar's QDoubleSpinBox range guards against this at the UI). Interior edges are mirrored to the neighbour slot so the two halves always carry the same value (matches the engine's symmetry invariant). Emits attributeChanged for the edited slot.
 
bool applyMeshVertexTag (int vertexIdx, const QString &tag)
 Set the vertex's descriptive tag ([2D_VERTICES] TAG column). Distinct from the coupled node. Emits attributeChanged.
 
bool applyMeshVertexCoupledNode (int vertexIdx, const QString &node)
 Set the vertex's coupled SWMM node ([2D_VERTEX_NODE_MAP]). Drives the coupled-vertex glyph. Clearing the coupling resets the coupling Cd/Area to the engine defaults (0.65 / 1.0 m²). Emits attributeChanged.
 
bool applyMeshVertexCouplingCd (int vertexIdx, double cd)
 Set the vertex's coupling discharge coefficient ([2D_VERTEX_NODE_MAP] CD column). Rejects uncoupled vertices and non-positive values. Emits attributeChanged.
 
bool applyMeshVertexCouplingArea (int vertexIdx, double area)
 Set the vertex's coupling exchange area in m² ([2D_VERTEX_NODE_MAP] AREA column). Rejects uncoupled vertices and non-positive values. Emits attributeChanged.
 
QVector< mesh::CellCouplingapplyCellCouplings (const QVector< mesh::CellCoupling > &rows)
 Replace the node→cell coupling row set wholesale ([2D_TRIANGLE_NODE_MAP] repeated-row form, Plan Part C). Rows with out-of-range triangles or empty node ids are dropped. Returns the previous row set so callers (undo commands) can restore it.
 
const QVector< mesh::CellCoupling > & cellCouplings () const
 Read-only view of the node→cell coupling rows.
 
bool applyMeshTriangleMannings (int triIdx, double mannings)
 Set a triangle's Manning's roughness. Emits attributeChanged with the cell ref name.
 
bool applyMeshTriangleInitDepth (int triIdx, double depth)
 Set a triangle's initial water depth in m ([2D_TRIANGLES] INIT_DEPTH column, default 0 = dry). Emits attributeChanged with the cell ref name.
 
bool applyMeshTriangleTag (int triIdx, const QString &tag)
 Set a triangle's descriptive tag ([2D_TRIANGLES] TAG column). Emits attributeChanged with the cell ref name.
 
bool applyMeshTriangleInfil (int triIdx, const mesh::InfilRow &row)
 Write a per-cell infiltration override ([2D_INFILTRATION] row, GUI plan §3.2a). The cell stops inheriting from its region tag / the '*' default until the override is cleared. Emits attributeChanged with the cell ref name.
 
bool clearMeshTriangleInfil (int triIdx)
 Erase the per-cell infiltration override, so the cell resolves through its region tag / the '*' default again.
 
bool applyMeshInfilDefault (const QString &tag, const mesh::InfilRow &row)
 Write one [2D_INFILTRATION_DEFAULTS] row — the region-level peer of applyMeshTriangleInfil.
 
bool clearMeshInfilDefault (const QString &tag)
 Erase the [2D_INFILTRATION_DEFAULTS] row for tag, so cells carrying it fall through to the '*' row (or to no model at all).
 
const QSet< int > & highlightedVertices () const
 Indices of mesh vertices currently selected for highlight rendering. Populated by the SelectionManager bridge (filtered to this layer's mesh by MeshObjectRef::layerKey).
 
void setHighlightedVertices (const QSet< int > &indices)
 
const QSet< int > & highlightedEdges () const
 Flat edge slots (mesh::edgeSlot(cell, edgeLocal)) currently selected for highlight rendering.
 
void setHighlightedEdges (const QSet< int > &flatIndices)
 
const QSet< int > & highlightedTriangles () const
 Triangle (cell) indices currently selected for highlight rendering. Populated by the SelectionManager bridge (MeshCell refs).
 
void setHighlightedTriangles (const QSet< int > &indices)
 
OpenSWMM::Render::IFeatureRendererrenderer () const override
 The IFeatureRenderer that will drive this layer's paint pass.
 
void setRenderer (std::unique_ptr< OpenSWMM::Render::IFeatureRenderer > r) override
 Replaces the current renderer.
 
QList< OpenSWMM::Render::ISublayer * > sublayers () const override
 
bool moveSublayer (int from, int to) override
 
OpenSWMM::Render::MeshFillSublayermeshFillSublayer () const
 
OpenSWMM::Render::MeshEdgeSublayermeshEdgeSublayer () const
 
OpenSWMM::Render::MeshNodeSublayermeshNodeSublayer () const
 
OpenSWMM::Render::ContourBandSublayercontourBandSublayer () const
 
OpenSWMM::Render::IsolineSublayerisolineSublayer () const
 
OpenSWMM::Render::MeshBcSublayermeshBcSublayer () const
 
OpenSWMM::Render::CoupledNodeSublayercoupledNodeSublayer () const
 
void onSublayersJsonLoaded (const QJsonObject &sublayersJson) override
 
double zMin () const
 
double zMax () const
 
QVector< doubleelevationSamples (int maxSamples=200000) const
 Per-vertex bed-elevation samples, for data-driven classification (quantile / natural-breaks / std-dev). Strided down to at most maxSamples so a "resample" on a multi-million-vertex mesh stays responsive; the resulting distribution is representative for binning.
 
quint64 attrRevision () const
 Monotonic counter bumped on every per-cell attribute write. The QSG renderer folds this into its fill-colour cache key so a Manning's edit cannot serve a stale cached colour.
 
quint64 bcRevision () const
 Monotonic counter bumped on every edge-BC write / resize.
 
const QVector< qint32 > & bcSceneEdges () const
 Scene-edge indices whose slot carries a non-Wall BC.
 
const QVector< float > & cellAttributeValues (const QByteArray &key) const
 Per-cell value of key, parallel to m_sceneTris (which skips degenerate triangles, so it is not the mesh triangle order). NaN marks an unset attribute. Cached; recomputed when the mesh geometry or attribute revision moves. Empty for an unknown key.
 
QVector< doublecellAttributeSamples (const QByteArray &key, int maxSamples=200000) const
 Strided sample of key for data-driven classification (quantile / natural-breaks / std-dev), NaNs excluded. Empty when the attribute has no data at all. Mirrors elevationSamples()'s striding so the classification editor stays responsive on huge meshes.
 
bool cellAttributeRange (const QByteArray &key, double *vMin, double *vMax) const
 Observed [min,max] over the non-NaN values of key.
 
void populateScene (QGraphicsScene *scene, const MapExtent &canvasExtent, const SpatialReferenceSystem *canvasSRS) override
 Creates / updates QGraphicsItems representing this layer in the scene.
 
void depopulateScene (QGraphicsScene *scene) override
 Removes all QGraphicsItems belonging to this layer from the scene.
 
void refreshScene (QGraphicsScene *scene, const MapExtent &canvasExtent, const SpatialReferenceSystem *canvasSRS) override
 Smart scene refresh — updates existing items instead of destroying and recreating.
 
void onCanvasCRSChanged (const SpatialReferenceSystem *newCanvasSRS) override
 Called when the user changes the canvas CRS so layers can pre-compute any CRS-dependent transform caches.
 
std::vector< std::unique_ptr< openswmmvis::ui::ILayerStyleSubject > > styleSubjects () override
 
OpenSWMM::Render::RuleListruleList () override
 
const OpenSWMM::Render::RuleListruleList () const override
 
bool hasOverview () const
 True when an LOD overview has been built and is worth using.
 
void rebuildOverviewAsync ()
 Rebuild the far-zoom LOD pyramid (overview) on a background thread. Emits overviewBuildStarted() immediately and overviewBuildFinished() from the GUI thread when the fresh pyramid has been adopted (followed by repaintRequested()). No-op while a build is already running. Surfaced by the "Rebuild pyramid" button in the layer-properties (LayerStyleDialog) Metadata tab.
 
bool overviewBuildRunning () const
 True while rebuildOverviewAsync() has a build in flight.
 
- Public Member Functions inherited from OpenSWMMVisLayer
 OpenSWMMVisLayer (OpenSWMMVisWorkspace *parent)
 
 OpenSWMMVisLayer (const QString &name="Unlabeled Layer", OpenSWMMVisWorkspace *parent=nullptr)
 
virtual ~OpenSWMMVisLayer ()
 
QString layerId () const
 Returns the layer's immutable unique identifier (UUID).
 
QString name () const
 Returns the user-visible name of this layer.
 
void setName (const QString &name)
 Sets the user-visible name.
 
OpenSWMMVisLayerType layerType () const
 Returns the layer type discriminator.
 
bool isVisible () const
 Returns true when this layer should be drawn.
 
void setVisible (bool visible)
 Shows or hides this layer.
 
double opacity () const
 Returns the layer opacity in the range [0.0, 1.0]. 0.0 = fully transparent; 1.0 = fully opaque.
 
void setOpacity (double opacity)
 Sets the layer opacity. Values are clamped to [0.0, 1.0].
 
SpatialReferenceSystemsrs () const
 Returns the spatial reference system for this layer, or nullptr if the layer has no known CRS.
 
void setSRS (SpatialReferenceSystem *srs, bool ownsSRS=false)
 Sets (or replaces) the CRS for this layer.
 
QString crsDescription () const
 Returns a human-readable summary of this layer's CRS for display in the Properties window.
 
MapExtent extent () const
 Returns the layer extent in the layer's own CRS.
 
void setExtent (const MapExtent &extent)
 Sets the layer spatial extent (in the layer's CRS).
 
virtual bool isRasterLayer () const
 Returns true for layers that render into a raster buffer (WMS, WMTS, GISRaster) rather than populating QGraphicsItems.
 
virtual bool isBasemapLayer () const
 Returns true for world-spanning basemap layers (XYZ tile providers, WMS/WMTS services covering the whole world) that should NOT be included when computing the data-driven full extent.
 
virtual void render (QPainter *painter, const MapExtent &extent, const QSize &imageSize, const SpatialReferenceSystem *srs)
 Renders this layer's content directly into painter.
 
virtual void fetchCache (const MapExtent &extent, const QSize &viewportSize, const SpatialReferenceSystem *srs)
 Triggers any asynchronous (or synchronous) tile/data fetch needed to populate this layer's internal cache for the given view state.
 
void setViewportSize (int w, int h)
 Called by MapCanvas before refreshScene so layers can request the correct pixel dimensions for tile/image requests.
 
int viewportWidth () const
 
int viewportHeight () const
 
QVector< OpenSWMMVisLayer * > children () const
 Returns the ordered list of child layers.
 
double layerZValue () const
 Returns the z-value base assigned to this layer by the canvas. Items within the layer should use z-values relative to this.
 
void setLayerZValue (double z)
 Called by the canvas to set this layer's z-value band.
 
const OpenSWMM::Render::TemporalSpectemporalSpec () const
 
void setTemporalSpec (const OpenSWMM::Render::TemporalSpec &spec)
 
const OpenSWMM::Render::LabelConfiglabelConfig () const
 
virtual void setLabelConfig (const OpenSWMM::Render::LabelConfig &cfg)
 
const OpenSWMM::Render::MaskSpecmaskSpec () const
 
void setMaskSpec (const OpenSWMM::Render::MaskSpec &spec)
 
const OpenSWMM::Render::AuxiliaryStorageSpecauxStorageSpec () const
 
void setAuxStorageSpec (const OpenSWMM::Render::AuxiliaryStorageSpec &spec)
 
const QVector< OpenSWMM::Render::JoinSpec > & joins () const
 
void setJoins (const QVector< OpenSWMM::Render::JoinSpec > &joins)
 
const OpenSWMM::Render::DiagramSpecdiagramSpec () const
 
void setDiagramSpec (const OpenSWMM::Render::DiagramSpec &spec)
 
OpenSWMMVisWorkspaceworkspace () const
 
void setBasicAuth (const QString &username, const QString &password)
 Sets HTTP Basic authentication for all subsequent network requests.
 
void setHttpHeaders (const BasemapHttpHeaders &headers)
 Sets arbitrary extra HTTP headers applied to every request.
 
BasemapHttpHeaders httpHeaders () const
 
- Public Member Functions inherited from OpenSWMM::Render::ISublayerHost
virtual ~ISublayerHost ()=default
 
virtual void dispatchAnimationTick (int period)
 Hook invoked by AnimationController on every time-step change.
 

Static Public Member Functions

template<class Tris >
static void appendVertexElevationSamples (const Tris &tris, QVector< double > &out)
 
- Static Public Member Functions inherited from OpenSWMM::Render::ISublayerHost
static QJsonObject saveSublayersToJson (const ISublayerHost &host)
 
static QList< LegendSymbolItemaggregatedLegendSymbolItems (const ISublayerHost &host)
 Aggregates every visible sublayer's legendSymbolItems() into a single flat list (Slice S4 / §J.5 — legend-from- renderer rule, sublayer extension).
 
static ISublayerfindSublayer (const ISublayerHost &host, const QString &id)
 O(N) lookup of a sublayer by its stable id. Returns nullptr when not found. Used by the legend dock's right-click handler in S4 to find the sublayer whose style dialog should open when the user clicks a sublayer-tagged swatch.
 
static void loadSublayersFromJson (ISublayerHost &host, const QJsonObject &j)
 

Public Attributes

QRectF m_sceneBBox
 
QVector< SceneTrim_sceneTris
 
QVector< SceneEdgem_sceneEdges
 
QVector< SceneNodem_sceneNodes
 
QVector< qint32 > m_cellSceneStart
 
QVector< qint32 > m_sceneEdgeSlot
 
double m_zMin = 0.0
 
double m_zMax = 0.0
 
float m_maxSlope = 0.0f
 
QVector< SceneTrim_overviewTris
 coarse LOD fill geometry (gap-fill floor)
 
double m_nativeTriSpan = 0.0
 representative native tri edge (scene units)
 
QVector< int > m_trisBySizeDesc
 
MeshSpatialGrid m_triGrid
 
MeshSpatialGrid m_edgeGrid
 
QVector< QRectF > m_triBBoxes
 parallel to m_sceneTris
 
QVector< QRectF > m_edgeBBoxes
 parallel to m_sceneEdges
 

Properties

QString sourcePath
 
int triangleCount
 
int vertexCount
 
bool showMeshNodes
 
bool showEdges
 
double hillshadeAzimuth
 
double hillshadeAltitude
 
double hillshadeZExag
 
double hillshadeMinLit
 
bool showContours
 
int contourIntervalCount
 
QColor contourColor
 
double contourLineWidth
 
bool filledContours
 
double filledContoursOpacity
 
double edgeZoomMinCellPx
 
double vertexZoomMinCellPx
 
- Properties inherited from OpenSWMMVisLayer
QString Name
 
bool Visible
 
double Opacity
 
QString LayerId
 
OpenSWMMVisLayerType LayerType
 
QVector< OpenSWMMVisLayer * > Children
 
QString CRS
 

Additional Inherited Members

- Public Types inherited from OpenSWMMVisLayer
enum  OpenSWMMVisLayerType {
  SWMMDefaultLayer = 0 ,
  SWMMModelLayer = 1 ,
  SWMMResultsLayer = 2 ,
  SWMMGISLayer = 3 ,
  SWMMVectorLayer = 4 ,
  SWMMRasterLayer = 5 ,
  SWMMImageryLayer = 6 ,
  SWMMTabularDataLayer = 7 ,
  SWMMTabularyTimeSeriesLayer = 8 ,
  SWMMSubProjectLayer = 9 ,
  SWMMWMSLayer = 10 ,
  SWMMWMTSLayer = 11 ,
  SWMM2DMeshLayer = 12 ,
  SWMM2DResultsLayer = 13 ,
  SWMMAnnotationLayer = 14 ,
  SWMMFeatureLayer = 15
}
 Discriminator for the concrete layer class. More...
 
- Protected Member Functions inherited from OpenSWMMVisLayer
bool addChild (OpenSWMMVisLayer *child)
 
bool removeChild (OpenSWMMVisLayer *child)
 
void setLayerType (OpenSWMMVisLayerType type)
 
- Protected Attributes inherited from OpenSWMMVisLayer
QByteArray m_authHeader
 "Basic <base64>" or empty
 
BasemapHttpHeaders m_httpHeaders
 arbitrary headers (incl. "referer")
 

Constructor & Destructor Documentation

◆ SWMM2DMeshLayer()

SWMM2DMeshLayer::SWMM2DMeshLayer ( mesh::MeshResult  result,
const QString &  sourcePath = {},
OpenSWMMVisWorkspace parent = nullptr,
bool  deferHeavyGeometry = false 
)
explicit
Parameters
deferHeavyGeometryProgressive-load mode (Mesh Tiled LOD P1.2): the constructor builds only what the fill needs to draw — scene triangles, bbox, elevation range, vertex dots and the LOD pyramid — so a large mesh can join the canvas and render its coarse levels immediately. The heavy structures (deduplicated wireframe edges, spatial grids, vertex adjacency, BC slots) arrive later via finishSceneGeometryAsync().
Here is the call graph for this function:

◆ ~SWMM2DMeshLayer()

SWMM2DMeshLayer::~SWMM2DMeshLayer ( )
override

Member Function Documentation

◆ activeMeshChanged

void SWMM2DMeshLayer::activeMeshChanged ( bool  isActive)
signal

Emitted when isActiveMesh() changes.

Here is the caller graph for this function:

◆ appendVertexElevationSamples()

template<class Tris >
static void SWMM2DMeshLayer::appendVertexElevationSamples ( const Tris &  tris,
QVector< double > &  out 
)
inlinestatic

Append the vertex elevations of a SceneTri fan to out, counting every CELL vertex once: a quad's second sub-triangle shares the diagonal with its first, so only its off-diagonal vertex is new. Feeds the quantile / Jenks classification samplers.

Here is the caller graph for this function:

◆ applyCellCouplings()

QVector< mesh::CellCoupling > SWMM2DMeshLayer::applyCellCouplings ( const QVector< mesh::CellCoupling > &  rows)

Replace the node→cell coupling row set wholesale ([2D_TRIANGLE_NODE_MAP] repeated-row form, Plan Part C). Rows with out-of-range triangles or empty node ids are dropped. Returns the previous row set so callers (undo commands) can restore it.

Here is the call graph for this function:

◆ applyMeshEdgeBC()

bool SWMM2DMeshLayer::applyMeshEdgeBC ( int  triIdx,
int  edgeLocal,
const mesh::MeshEdgeBC bc 
)

Replace the entire BC value for edge (triIdx,edgeLocal). Emits attributeChanged. Apply-as-you-go.

Here is the call graph for this function:

◆ applyMeshEdgeConveyance()

bool SWMM2DMeshLayer::applyMeshEdgeConveyance ( int  triIdx,
int  edgeLocal,
double  conveyance 
)

Engine §11A — set the per-edge conveyance (flux attenuation multiplier) in [0, 1]. Rejects out-of-range values (the C API does the same; the toolbar's QDoubleSpinBox range guards against this at the UI). Interior edges are mirrored to the neighbour slot so the two halves always carry the same value (matches the engine's symmetry invariant). Emits attributeChanged for the edited slot.

Here is the call graph for this function:

◆ applyMeshInfilDefault()

bool SWMM2DMeshLayer::applyMeshInfilDefault ( const QString &  tag,
const mesh::InfilRow row 
)

Write one [2D_INFILTRATION_DEFAULTS] row — the region-level peer of applyMeshTriangleInfil.

tag is a [2D_TRIANGLES] TAG value, or "*" for the mesh-wide fallback. Every cell carrying tag that has no per-cell override starts resolving through the new row, so a region-level edit reaches those cells WITHOUT materialising an override on any of them — which is the whole point of engine D-I3, and the difference between an assignment that stays editable as regions and one frozen into N per-cell rows.

An existing row for tag is replaced in place (section order is preserved); a new tag is appended. Rejects an empty tag.

Bumps the same attribute-cache revision its per-cell siblings do, so the fill-colour cache cannot serve stale colours for an inherited value. The edit has no single element ref — every inheriting cell moved — so it emits meshEditsChanged() for views that repaint wholesale, alongside a layer-scope attributeChanged() for the ones that only need "this mesh was edited".

Here is the call graph for this function:

◆ applyMeshTriangleInfil()

bool SWMM2DMeshLayer::applyMeshTriangleInfil ( int  triIdx,
const mesh::InfilRow row 
)

Write a per-cell infiltration override ([2D_INFILTRATION] row, GUI plan §3.2a). The cell stops inheriting from its region tag / the '*' default until the override is cleared. Emits attributeChanged with the cell ref name.

Here is the call graph for this function:

◆ applyMeshTriangleInitDepth()

bool SWMM2DMeshLayer::applyMeshTriangleInitDepth ( int  triIdx,
double  depth 
)

Set a triangle's initial water depth in m ([2D_TRIANGLES] INIT_DEPTH column, default 0 = dry). Emits attributeChanged with the cell ref name.

Here is the call graph for this function:

◆ applyMeshTriangleMannings()

bool SWMM2DMeshLayer::applyMeshTriangleMannings ( int  triIdx,
double  mannings 
)

Set a triangle's Manning's roughness. Emits attributeChanged with the cell ref name.

Here is the call graph for this function:

◆ applyMeshTriangleTag()

bool SWMM2DMeshLayer::applyMeshTriangleTag ( int  triIdx,
const QString &  tag 
)

Set a triangle's descriptive tag ([2D_TRIANGLES] TAG column). Emits attributeChanged with the cell ref name.

Here is the call graph for this function:

◆ applyMeshVertexCoupledNode()

bool SWMM2DMeshLayer::applyMeshVertexCoupledNode ( int  vertexIdx,
const QString &  node 
)

Set the vertex's coupled SWMM node ([2D_VERTEX_NODE_MAP]). Drives the coupled-vertex glyph. Clearing the coupling resets the coupling Cd/Area to the engine defaults (0.65 / 1.0 m²). Emits attributeChanged.

Here is the call graph for this function:

◆ applyMeshVertexCouplingArea()

bool SWMM2DMeshLayer::applyMeshVertexCouplingArea ( int  vertexIdx,
double  area 
)

Set the vertex's coupling exchange area in m² ([2D_VERTEX_NODE_MAP] AREA column). Rejects uncoupled vertices and non-positive values. Emits attributeChanged.

Here is the call graph for this function:

◆ applyMeshVertexCouplingCd()

bool SWMM2DMeshLayer::applyMeshVertexCouplingCd ( int  vertexIdx,
double  cd 
)

Set the vertex's coupling discharge coefficient ([2D_VERTEX_NODE_MAP] CD column). Rejects uncoupled vertices and non-positive values. Emits attributeChanged.

Here is the call graph for this function:

◆ applyMeshVertexTag()

bool SWMM2DMeshLayer::applyMeshVertexTag ( int  vertexIdx,
const QString &  tag 
)

Set the vertex's descriptive tag ([2D_VERTICES] TAG column). Distinct from the coupled node. Emits attributeChanged.

Here is the call graph for this function:

◆ applyMeshVertexZ()

bool SWMM2DMeshLayer::applyMeshVertexZ ( int  vertexIdx,
double  z 
)

Set vertex Z. Mutates the layer's MeshResult, rebuilds scene geometry, emits attributeChanged with the vertex ref name.

Here is the call graph for this function:

◆ attributeChanged

void SWMM2DMeshLayer::attributeChanged ( const QString &  refName)
signal

Emitted on any successful apply* mutation. refName is the MeshObjectRef-encoded element name (see meshobjectref.h).

Here is the caller graph for this function:

◆ attrRevision()

quint64 SWMM2DMeshLayer::attrRevision ( ) const
inline

Monotonic counter bumped on every per-cell attribute write. The QSG renderer folds this into its fill-colour cache key so a Manning's edit cannot serve a stale cached colour.

◆ bcRevision()

quint64 SWMM2DMeshLayer::bcRevision ( ) const
inline

Monotonic counter bumped on every edge-BC write / resize.

◆ bcSceneEdges()

const QVector< qint32 > & SWMM2DMeshLayer::bcSceneEdges ( ) const

Scene-edge indices whose slot carries a non-Wall BC.

Parallel index space to m_sceneEdges. Bounded by the boundary ring rather than the cell count, which is the whole point: the interior wireframe is correctly suppressed at far zoom (Qsg2DLodPolicy needs ~32 px per cell before it draws edges at all), but the BC ring is a small, semantically important subset that must stay visible at every zoom. The renderer walks this vector instead of rescanning every edge per frame.

Cached; recomputed when the BC or geometry revision moves.

Here is the caller graph for this function:

◆ boundaryEdgeCount()

int SWMM2DMeshLayer::boundaryEdgeCount ( ) const
inline

Number of boundary edges (domain outline + holes).

Here is the caller graph for this function:

◆ boundaryGraph()

const mesh::MeshBoundaryGraph & SWMM2DMeshLayer::boundaryGraph ( )

Boundary-edge connectivity graph, used by the edge-select tool's Ctrl-click shortest-path picking. Built lazily on first use and cached until the boundary flags are rebuilt.

Returns an empty graph while a progressive load is still finishing (sceneGeometryComplete() == false), since the boundary flags are not populated yet; the next call after sceneGeometryReady() builds it for real.

Here is the call graph for this function:

◆ cellAttributeRange()

bool SWMM2DMeshLayer::cellAttributeRange ( const QByteArray &  key,
double vMin,
double vMax 
) const

Observed [min,max] over the non-NaN values of key.

Returns
false (leaving the outputs untouched) when the attribute has no data — which is the case for every gw.* key today.
Here is the call graph for this function:

◆ cellAttributeSamples()

QVector< double > SWMM2DMeshLayer::cellAttributeSamples ( const QByteArray &  key,
int  maxSamples = 200000 
) const

Strided sample of key for data-driven classification (quantile / natural-breaks / std-dev), NaNs excluded. Empty when the attribute has no data at all. Mirrors elevationSamples()'s striding so the classification editor stays responsive on huge meshes.

Here is the call graph for this function:

◆ cellAttributeValues()

const QVector< float > & SWMM2DMeshLayer::cellAttributeValues ( const QByteArray &  key) const

Per-cell value of key, parallel to m_sceneTris (which skips degenerate triangles, so it is not the mesh triangle order). NaN marks an unset attribute. Cached; recomputed when the mesh geometry or attribute revision moves. Empty for an unknown key.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cellCouplings()

const QVector< mesh::CellCoupling > & SWMM2DMeshLayer::cellCouplings ( ) const
inline

Read-only view of the node→cell coupling rows.

◆ clearMeshInfilDefault()

bool SWMM2DMeshLayer::clearMeshInfilDefault ( const QString &  tag)

Erase the [2D_INFILTRATION_DEFAULTS] row for tag, so cells carrying it fall through to the '*' row (or to no model at all).

The inverse of applyMeshInfilDefault, and what MeshSetInfilDefaultsCommand::undo() calls for a tag that had no row before the edit. Returns true when the row is already absent.

Here is the call graph for this function:

◆ clearMeshTriangleInfil()

bool SWMM2DMeshLayer::clearMeshTriangleInfil ( int  triIdx)

Erase the per-cell infiltration override, so the cell resolves through its region tag / the '*' default again.

The inverse of applyMeshTriangleInfil, and NOT the same as writing back the inherited numbers: a materialised override with identical values looks right but silently stops tracking the region, so the next region-level edit no longer reaches the cell. This is what MeshSetTriangleInfilCommand::undo() calls for a cell that was inheriting. Emits attributeChanged with the cell ref name.

Here is the call graph for this function:

◆ contourBandSublayer()

OpenSWMM::Render::ContourBandSublayer * SWMM2DMeshLayer::contourBandSublayer ( ) const
inline
Here is the caller graph for this function:

◆ contourColor()

QColor SWMM2DMeshLayer::contourColor ( ) const
Here is the call graph for this function:

◆ contourIntervalCount()

int SWMM2DMeshLayer::contourIntervalCount ( ) const
Here is the call graph for this function:

◆ contourLineWidth()

double SWMM2DMeshLayer::contourLineWidth ( ) const
Here is the call graph for this function:

◆ coupledNodeSublayer()

OpenSWMM::Render::CoupledNodeSublayer * SWMM2DMeshLayer::coupledNodeSublayer ( ) const
inline
Here is the caller graph for this function:

◆ depopulateScene()

void SWMM2DMeshLayer::depopulateScene ( QGraphicsScene *  scene)
overridevirtual

Removes all QGraphicsItems belonging to this layer from the scene.

Reimplemented from OpenSWMMVisLayer.

Here is the caller graph for this function:

◆ edgeBCs()

const QVector< mesh::MeshEdgeBC > & SWMM2DMeshLayer::edgeBCs ( ) const
inline

Per-edge BC values; flat-indexed by mesh::edgeSlot(cell, edgeLocal) (stride mesh::kEdgeStride = 4). Sized to mesh::edgeSlotCount(n_cells) after mesh load; interior-edge slots and a triangle's unused slot 3 stay at the default Wall value (engine ignores them).

Here is the caller graph for this function:

◆ edgeBCsMutable()

QVector< mesh::MeshEdgeBC > & SWMM2DMeshLayer::edgeBCsMutable ( )
inline

Mutable BC view — used by INP reader to bulk-populate after load. Prefer the apply* helpers for user-driven edits so views receive the attributeChanged signal. Bumps the BC revision on every access: both callers assign the whole vector through this reference, and without the bump the bcSceneEdges() render cache keyed on m_bcRevision served stale geometry after a bulk reload.

◆ edgeCount()

int SWMM2DMeshLayer::edgeCount ( ) const
inline

Total number of unique mesh edges. m_sceneEdges is the deduplicated edge set (exact, conformance-independent) built by rebuildSceneGeometry(); before that runs, fall back to the conforming- mesh identity total = (Σ nv + B)/2 = (3·T + Q + B)/2.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ edgeMinCellAreaPx()

double SWMM2DMeshLayer::edgeMinCellAreaPx ( ) const
inline

Area forms (px²) the renderers actually gate on — square of the configured cell-size thresholds.

Here is the caller graph for this function:

◆ edgeZoomMinCellPx()

double SWMM2DMeshLayer::edgeZoomMinCellPx ( ) const
inline

◆ elevationSamples()

QVector< double > SWMM2DMeshLayer::elevationSamples ( int  maxSamples = 200000) const

Per-vertex bed-elevation samples, for data-driven classification (quantile / natural-breaks / std-dev). Strided down to at most maxSamples so a "resample" on a multi-million-vertex mesh stays responsive; the resulting distribution is representative for binning.

◆ extendedMetadata()

QVector< QPair< QString, QString > > SWMM2DMeshLayer::extendedMetadata ( ) const
overridevirtual

Ordered key→value pairs of TYPE-SPECIFIC metadata, rendered by the Metadata tab below the common block the dialog builds itself.

Default empty. Subclasses add only what is unique to them (e.g. a mesh: vertices / cells / edges / elevation range). QVector<QPair> preserves insertion order without a new type.

Reimplemented from OpenSWMMVisLayer.

Here is the call graph for this function:

◆ filledContours()

bool SWMM2DMeshLayer::filledContours ( ) const
Here is the call graph for this function:

◆ filledContoursOpacity()

double SWMM2DMeshLayer::filledContoursOpacity ( ) const
Here is the call graph for this function:

◆ findEdgeNeighbour()

QPair< int, int > SWMM2DMeshLayer::findEdgeNeighbour ( int  triIdx,
int  edgeLocal 
) const

Engine §11A helper — find the (tri, eLocal) slot on the other side of an interior edge. Returns (-1, -1) when the edge is on the mesh boundary (no neighbour) or the indices are out of range. Uses the vertex→triangles adjacency, so requires rebuildVertexAdjacency() to have run.

Public because the Attribute Table's Edges view canonicalises each interior edge pair onto a single row and needs the same pairing the conveyance mirror uses.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ finishSceneGeometryAsync()

void SWMM2DMeshLayer::finishSceneGeometryAsync ( )

Build the deferred heavy geometry (wireframe edges, spatial grids, vertex adjacency, BC slots) on a background thread and adopt it on the GUI thread. Emits sceneGeometryReady() then repaintRequested() when done. No-op when already complete or a build is in flight. If the scene geometry was re-projected mid-build (CRS change), the stale result is discarded and the build re-runs.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ geomRevision()

quint64 SWMM2DMeshLayer::geomRevision ( ) const
inline

◆ hasOverview()

bool SWMM2DMeshLayer::hasOverview ( ) const
inline

True when an LOD overview has been built and is worth using.

Here is the caller graph for this function:

◆ hasUnsavedMeshEdits()

bool SWMM2DMeshLayer::hasUnsavedMeshEdits ( ) const
inline

Has this layer's mesh state diverged from the engine's copy?

The save path pushes the whole mesh into the engine, which costs O(nVertices x nTriangles) there (each swmm_2d_set_vertex_z rescans every triangle). That is minutes on a million-cell mesh, so a save must not pay it when nothing was edited.

Defaults to true: only a layer built from the very file the engine parsed is known to agree with it, and that case says so explicitly via SWMMVisProjectWindow::attachMeshLayer(layer, pristine = true). A mesh generated or imported in-session leaves the engine holding the OLD mesh, so it must stay dirty.

◆ highlightedEdges()

const QSet< int > & SWMM2DMeshLayer::highlightedEdges ( ) const
inline

Flat edge slots (mesh::edgeSlot(cell, edgeLocal)) currently selected for highlight rendering.

Here is the caller graph for this function:

◆ highlightedTriangles()

const QSet< int > & SWMM2DMeshLayer::highlightedTriangles ( ) const
inline

Triangle (cell) indices currently selected for highlight rendering. Populated by the SelectionManager bridge (MeshCell refs).

Here is the caller graph for this function:

◆ highlightedVertices()

const QSet< int > & SWMM2DMeshLayer::highlightedVertices ( ) const
inline

Indices of mesh vertices currently selected for highlight rendering. Populated by the SelectionManager bridge (filtered to this layer's mesh by MeshObjectRef::layerKey).

Here is the caller graph for this function:

◆ hillshadeAltitude()

double SWMM2DMeshLayer::hillshadeAltitude ( ) const
inline

◆ hillshadeAzimuth()

double SWMM2DMeshLayer::hillshadeAzimuth ( ) const
inline

◆ hillshadeMinLit()

double SWMM2DMeshLayer::hillshadeMinLit ( ) const

◆ hillshadeZExag()

double SWMM2DMeshLayer::hillshadeZExag ( ) const
Here is the call graph for this function:

◆ isActiveMesh()

bool SWMM2DMeshLayer::isActiveMesh ( ) const
inline
Here is the caller graph for this function:

◆ isBoundaryEdge()

bool SWMM2DMeshLayer::isBoundaryEdge ( int  triIdx,
int  edgeLocal 
) const

True when this edge slot is a boundary edge in the loaded mesh (i.e. the corresponding triangle has no neighbour across it). Boundary classification is derived from the mesh's MeshEdge list populated by InpMeshReader; non-boundary edges return false.

Here is the call graph for this function:

◆ isExternalMesh()

bool SWMM2DMeshLayer::isExternalMesh ( ) const
inline

True when the mesh came from an external file referenced by [2D_MESH_FILE] FILE <path>. False for an inline mesh, whose sourcePath() is the .inp itself. Save must not re-point the .inp at an inline mesh's "source" — that would overwrite the model.

◆ isolineSublayer()

OpenSWMM::Render::IsolineSublayer * SWMM2DMeshLayer::isolineSublayer ( ) const
inline
Here is the caller graph for this function:

◆ locateTriangleAt()

int SWMM2DMeshLayer::locateTriangleAt ( double  sx,
double  sy 
) const

Cell (mesh triangle/quad index) containing scene point (sx,sy), or -1 if outside every cell. A quad is tested on its sub-triangle fan.

Here is the caller graph for this function:

◆ markMeshEdited()

void SWMM2DMeshLayer::markMeshEdited ( )
inline

Mark the layer's mesh state as diverged from the engine.

Here is the caller graph for this function:

◆ maxSlope()

double SWMM2DMeshLayer::maxSlope ( ) const
inline

Steepest edge slope in the mesh (rise/run), cached during scene build.

Here is the caller graph for this function:

◆ mesh()

const mesh::MeshResult & SWMM2DMeshLayer::mesh ( ) const
inline
Here is the caller graph for this function:

◆ meshBcSublayer()

OpenSWMM::Render::MeshBcSublayer * SWMM2DMeshLayer::meshBcSublayer ( ) const
inline
Here is the caller graph for this function:

◆ meshEdgeSublayer()

OpenSWMM::Render::MeshEdgeSublayer * SWMM2DMeshLayer::meshEdgeSublayer ( ) const
inline
Here is the caller graph for this function:

◆ meshEditsChanged

void SWMM2DMeshLayer::meshEditsChanged ( )
signal

Emitted on a bulk mutation that has no single element ref (currently applyCellCouplings). Companion to attributeChanged for listeners that only need to know "the mesh was edited" — e.g. the project dirty flag.

Here is the caller graph for this function:

◆ meshFillSublayer()

OpenSWMM::Render::MeshFillSublayer * SWMM2DMeshLayer::meshFillSublayer ( ) const
inline
Here is the caller graph for this function:

◆ meshNodeSublayer()

OpenSWMM::Render::MeshNodeSublayer * SWMM2DMeshLayer::meshNodeSublayer ( ) const
inline
Here is the caller graph for this function:

◆ meshUnitsSI()

bool SWMM2DMeshLayer::meshUnitsSI ( ) const
inline

True when the mesh file declared ;; UNITS: SI (m) (or an equivalent metric keyword). The engine then SKIPS its FLOW_UNITS-based ft→m mesh scaling, so 2D results coordinates come back in the same values as the mesh. Consumed by the 2D results layer's coordinate fallback — see SWMM2DResultsLayer::setFallbackCoordinateScale and issue #155.

◆ moveSublayer()

bool SWMM2DMeshLayer::moveSublayer ( int  from,
int  to 
)
overridevirtual

Reorder sublayers in paint order (bottom-up). Emits repaintRequested() on success. Returns false on out-of-range indices.

Reimplemented from OpenSWMM::Render::ISublayerHost.

Here is the call graph for this function:

◆ onCanvasCRSChanged()

void SWMM2DMeshLayer::onCanvasCRSChanged ( const SpatialReferenceSystem newCanvasSRS)
overridevirtual

Called when the user changes the canvas CRS so layers can pre-compute any CRS-dependent transform caches.

Parameters
newCanvasSRSThe new canvas CRS.

Reimplemented from OpenSWMMVisLayer.

Here is the call graph for this function:

◆ onSublayersJsonLoaded()

void SWMM2DMeshLayer::onSublayersJsonLoaded ( const QJsonObject &  sublayersJson)
overridevirtual

Migration hook (ISublayerHost) — seeds the BC / coupled-node sublayers from legacy MeshEdgeStyle / MeshNodeStyle JSON when a pre-split project or style file is loaded.

Reimplemented from OpenSWMM::Render::ISublayerHost.

Here is the call graph for this function:

◆ overviewBuildFinished

void SWMM2DMeshLayer::overviewBuildFinished ( bool  ok)
signal
Here is the caller graph for this function:

◆ overviewBuildRunning()

bool SWMM2DMeshLayer::overviewBuildRunning ( ) const
inline

True while rebuildOverviewAsync() has a build in flight.

◆ overviewBuildStarted

void SWMM2DMeshLayer::overviewBuildStarted ( const QString &  layerName)
signal

Background pyramid (overview) rebuild lifecycle — mirrors GISRasterLayer::overviewBuildStarted/Finished so the app can drive the busy bar + status message during the build.

Here is the caller graph for this function:

◆ pickCellAt()

int SWMM2DMeshLayer::pickCellAt ( const QPointF &  scenePt) const

Triangle (cell) containing scene point scenePt, or -1. Peer of SWMM2DResultsLayer::pickCellAt; lets the Select 2D Cells map tool work against the mesh layer when no results layer exists.

Here is the call graph for this function:

◆ pickCellsInPolygon()

QVector< int > SWMM2DMeshLayer::pickCellsInPolygon ( const QPolygonF &  scenePoly) const

Triangle indices whose centroid falls inside scenePoly. Peer of SWMM2DResultsLayer::pickCellsInPolygon.

◆ pickCellsInRect()

QVector< int > SWMM2DMeshLayer::pickCellsInRect ( const QRectF &  sceneRect) const

Triangle indices whose centroid falls inside sceneRect. Peer of SWMM2DResultsLayer::pickCellsInRect.

◆ pickEdgeAt()

int SWMM2DMeshLayer::pickEdgeAt ( double  sx,
double  sy,
double  tolPx,
double  pxPerSceneUnit,
bool  boundaryOnly 
) const

Edge pick. Returns flat edge slot mesh::edgeSlot(cell, edgeLocal) within tolPx of (sx,sy), or -1. When boundaryOnly is true, interior edges are skipped.

Here is the call graph for this function:

◆ pickVertexAt()

int SWMM2DMeshLayer::pickVertexAt ( double  sx,
double  sy,
double  tolPx,
double  pxPerSceneUnit 
) const

Vertex pick. Returns the closest vertex index to scene point (sx,sy) within tolPx screen-pixels, or -1 if none. pxPerSceneUnit converts scene-units to screen-pixels (use the active canvas zoom).

◆ populateScene()

void SWMM2DMeshLayer::populateScene ( QGraphicsScene *  scene,
const MapExtent canvasExtent,
const SpatialReferenceSystem canvasSRS 
)
overridevirtual

Creates / updates QGraphicsItems representing this layer in the scene.

Derived classes override this to add their items to the scene. Items should be created in scene coordinates (= map CRS coordinates) after reprojecting from the layer's native CRS.

Called by the MapCanvas when:

  • The layer is first added.
  • The canvas CRS changes (after onCanvasCRSChanged).
  • The layer data changes (model loaded, tile fetched, etc.).
Parameters
sceneThe shared OpenSWMMVisScene to add items to.
canvasExtentVisible extent in canvas-CRS coordinates.
canvasSRSThe CRS currently used by the MapCanvas.

Implements OpenSWMMVisLayer.

Here is the caller graph for this function:

◆ qsgOwnsRendering()

bool SWMM2DMeshLayer::qsgOwnsRendering ( ) const
inlinenoexcept

True while SWMM2DMeshQSGRenderer draws this layer inside MapCanvas's QSG frame; the CPU SWMM2DMeshGraphicsItem::paint() early-returns so the two pipelines never double-paint. Mirrors SWMM2DResultsLayer::qsgOwnsRendering.

Here is the caller graph for this function:

◆ quadCount()

int SWMM2DMeshLayer::quadCount ( ) const
inline

Number of quadrilateral cells (O(n)).

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rebuildOverviewAsync()

void SWMM2DMeshLayer::rebuildOverviewAsync ( )

Rebuild the far-zoom LOD pyramid (overview) on a background thread. Emits overviewBuildStarted() immediately and overviewBuildFinished() from the GUI thread when the fresh pyramid has been adopted (followed by repaintRequested()). No-op while a build is already running. Surfaced by the "Rebuild pyramid" button in the layer-properties (LayerStyleDialog) Metadata tab.

Here is the call graph for this function:

◆ refreshScene()

void SWMM2DMeshLayer::refreshScene ( QGraphicsScene *  scene,
const MapExtent canvasExtent,
const SpatialReferenceSystem canvasSRS 
)
overridevirtual

Smart scene refresh — updates existing items instead of destroying and recreating.

Override in subclasses to provide efficient incremental updates. The default implementation calls depopulateScene() then populateScene(), which is backward-compatible but causes flicker for raster/tile layers.

Raster/WMS layers should override to keep persistent scene items and update them in-place. Vector layers should override to skip rebuilding when only the view extent has changed (items are already in scene coords).

Reimplemented from OpenSWMMVisLayer.

Here is the call graph for this function:

◆ renderer()

OpenSWMM::Render::IFeatureRenderer * SWMM2DMeshLayer::renderer ( ) const
overridevirtual

The IFeatureRenderer that will drive this layer's paint pass.

Constructed eagerly as a default SingleSymbolRenderer so callers never have to null-check. Owned by the layer.

Reimplemented from OpenSWMMVisLayer.

◆ rendererChanged

void SWMM2DMeshLayer::rendererChanged ( )
signal

Emitted when setRenderer() swaps the renderer pointer.

Here is the caller graph for this function:

◆ ruleList() [1/2]

const OpenSWMM::Render::RuleList * SWMM2DMeshLayer::ruleList ( ) const
overridevirtual

Reimplemented from OpenSWMMVisLayer.

◆ ruleList() [2/2]

OpenSWMM::Render::RuleList * SWMM2DMeshLayer::ruleList ( )
overridevirtual

Reimplemented from OpenSWMMVisLayer.

◆ sampleZAt()

double SWMM2DMeshLayer::sampleZAt ( double  sx,
double  sy 
) const

Barycentric Z sample at scene point (sx,sy). Returns NaN when the point is outside every triangle.

◆ sceneGeometryComplete()

bool SWMM2DMeshLayer::sceneGeometryComplete ( ) const
inline

False while the heavy structures from a deferred load are still being built — the renderers fall back to the LOD pyramid and editing/picking is limited until this flips true.

◆ sceneGeometryReady

void SWMM2DMeshLayer::sceneGeometryReady ( )
signal

The deferred heavy geometry from a progressive load (finishSceneGeometryAsync) has been adopted — wireframe, spatial culling and editing structures are now available.

Here is the caller graph for this function:

◆ selectionInvalidated

void SWMM2DMeshLayer::selectionInvalidated ( )
signal

Emitted when remesh / reload invalidates element indices in any held selection — toolbar and tools clear on receipt.

◆ setActiveMesh()

void SWMM2DMeshLayer::setActiveMesh ( bool  active)
Here is the call graph for this function:

◆ setContourColor()

void SWMM2DMeshLayer::setContourColor ( const QColor &  c)
Here is the call graph for this function:

◆ setContourIntervalCount()

void SWMM2DMeshLayer::setContourIntervalCount ( int  n)
Here is the call graph for this function:

◆ setContourLineWidth()

void SWMM2DMeshLayer::setContourLineWidth ( double  widthPx)
Here is the call graph for this function:

◆ setEdgeZoomMinCellPx()

void SWMM2DMeshLayer::setEdgeZoomMinCellPx ( double  px)
Here is the call graph for this function:

◆ setExternalMesh()

void SWMM2DMeshLayer::setExternalMesh ( bool  external)
inline

◆ setFilledContours()

void SWMM2DMeshLayer::setFilledContours ( bool  filled)
Here is the call graph for this function:

◆ setFilledContoursOpacity()

void SWMM2DMeshLayer::setFilledContoursOpacity ( double  a)
Here is the call graph for this function:

◆ setHighlightedEdges()

void SWMM2DMeshLayer::setHighlightedEdges ( const QSet< int > &  flatIndices)
Here is the call graph for this function:

◆ setHighlightedTriangles()

void SWMM2DMeshLayer::setHighlightedTriangles ( const QSet< int > &  indices)
Here is the call graph for this function:

◆ setHighlightedVertices()

void SWMM2DMeshLayer::setHighlightedVertices ( const QSet< int > &  indices)
Here is the call graph for this function:

◆ setHillshadeAltitude()

void SWMM2DMeshLayer::setHillshadeAltitude ( double  degrees)
Here is the call graph for this function:

◆ setHillshadeAzimuth()

void SWMM2DMeshLayer::setHillshadeAzimuth ( double  degrees)
Here is the call graph for this function:

◆ setHillshadeMinLit()

void SWMM2DMeshLayer::setHillshadeMinLit ( double  minLit)
Here is the call graph for this function:

◆ setHillshadeZExag()

void SWMM2DMeshLayer::setHillshadeZExag ( double  factor)
Here is the call graph for this function:

◆ setMeshEditsSaved()

void SWMM2DMeshLayer::setMeshEditsSaved ( )
inline

Clear the divergence flag — only after a confirmed successful write, so a failed save still re-pushes next time.

Here is the caller graph for this function:

◆ setMeshUnitsSI()

void SWMM2DMeshLayer::setMeshUnitsSI ( bool  si)
inline

◆ setQsgOwnsRendering()

void SWMM2DMeshLayer::setQsgOwnsRendering ( bool  own)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setRenderer()

void SWMM2DMeshLayer::setRenderer ( std::unique_ptr< OpenSWMM::Render::IFeatureRenderer r)
overridevirtual

Replaces the current renderer.

The layer takes ownership. Null pointers are silently rejected. Emits rendererChanged() when the pointer actually changes.

Reimplemented from OpenSWMMVisLayer.

Here is the call graph for this function:

◆ setShowContours()

void SWMM2DMeshLayer::setShowContours ( bool  show)
Here is the call graph for this function:

◆ setShowEdges()

void SWMM2DMeshLayer::setShowEdges ( bool  show)
Here is the call graph for this function:

◆ setShowMeshNodes()

void SWMM2DMeshLayer::setShowMeshNodes ( bool  show)
Here is the call graph for this function:

◆ setSourcePath()

void SWMM2DMeshLayer::setSourcePath ( const QString &  path)
inline

◆ setVertexZoomMinCellPx()

void SWMM2DMeshLayer::setVertexZoomMinCellPx ( double  px)
Here is the call graph for this function:

◆ showContours()

bool SWMM2DMeshLayer::showContours ( ) const
Here is the call graph for this function:

◆ showEdges()

bool SWMM2DMeshLayer::showEdges ( ) const
Here is the call graph for this function:

◆ showMeshNodes()

bool SWMM2DMeshLayer::showMeshNodes ( ) const
Here is the call graph for this function:

◆ sourceDescription()

QString SWMM2DMeshLayer::sourceDescription ( ) const
overridevirtual

Human-readable source of this layer: a file path, a service URL, or a description for in-memory / derived layers.

Default empty — the dialog shows "(none)". Concrete layers override to return their real origin (e.g. modelFilePath(), resultsFilePath(), serviceUrl(), or "(generated mesh)").

Reimplemented from OpenSWMMVisLayer.

◆ sourcePath()

QString SWMM2DMeshLayer::sourcePath ( ) const

◆ styleSubjects()

std::vector< std::unique_ptr< openswmmvis::ui::ILayerStyleSubject > > SWMM2DMeshLayer::styleSubjects ( )
overridevirtual

Slice U-5 — surface the mesh layer itself as the single styleable subject for the unified LayerStyleDialog. The Q_PROPERTYs declared above drive the editor; Q_CLASSINFO("group:...") groups them into Display / Hillshade / Contours tabs.

Reimplemented from OpenSWMMVisLayer.

◆ sublayers()

QList< OpenSWMM::Render::ISublayer * > SWMM2DMeshLayer::sublayers ( ) const
overridevirtual

Ordered list of sublayers owned by this layer. Paint order is list order (bottom-up): mesh fill (static) → contour bands (filled) → mesh edges → isolines → mesh vertex markers The layer's existing Q_PROPERTYs (showEdges, showMeshNodes, showContours, ...) act as thin shims that forward to the corresponding sublayer's setVisible() / style so saved .oswp files and existing UI still work.

Implements OpenSWMM::Render::ISublayerHost.

Here is the caller graph for this function:

◆ triangleCount()

int SWMM2DMeshLayer::triangleCount ( ) const
inline

Number of cells (triangles + quads) in the loaded mesh — exposed as metadata in the Properties window. Name kept for the Q_PROPERTY / saved-project compatibility.

◆ vertexCount()

int SWMM2DMeshLayer::vertexCount ( ) const
inline

Number of vertices in the loaded mesh — exposed as metadata in the Properties window.

◆ vertexMinCellAreaPx()

double SWMM2DMeshLayer::vertexMinCellAreaPx ( ) const
inline
Here is the caller graph for this function:

◆ vertexZoomMinCellPx()

double SWMM2DMeshLayer::vertexZoomMinCellPx ( ) const
inline

◆ zMax()

double SWMM2DMeshLayer::zMax ( ) const
inline
Here is the caller graph for this function:

◆ zMin()

double SWMM2DMeshLayer::zMin ( ) const
inline

Slice US.3 — bed-elevation range of the loaded mesh, the data range the contour-band / isoline classification scheme classifies over.

Here is the caller graph for this function:

Member Data Documentation

◆ m_cellSceneStart

QVector<qint32> SWMM2DMeshLayer::m_cellSceneStart

CSR map cell → fan: the SceneTris of cell c are m_sceneTris[m_cellSceneStart[c] .. m_cellSceneStart[c+1]). Size n_cells + 1; an empty range marks a cell skipped as degenerate. Rebuilt with m_sceneTris (light and full builds).

◆ m_edgeBBoxes

QVector<QRectF> SWMM2DMeshLayer::m_edgeBBoxes

parallel to m_sceneEdges

◆ m_edgeGrid

MeshSpatialGrid SWMM2DMeshLayer::m_edgeGrid

◆ m_maxSlope

float SWMM2DMeshLayer::m_maxSlope = 0.0f

◆ m_nativeTriSpan

double SWMM2DMeshLayer::m_nativeTriSpan = 0.0

representative native tri edge (scene units)

◆ m_overviewTris

QVector<SceneTri> SWMM2DMeshLayer::m_overviewTris

coarse LOD fill geometry (gap-fill floor)

◆ m_sceneBBox

QRectF SWMM2DMeshLayer::m_sceneBBox

◆ m_sceneEdges

QVector<SceneEdge> SWMM2DMeshLayer::m_sceneEdges

◆ m_sceneEdgeSlot

QVector<qint32> SWMM2DMeshLayer::m_sceneEdgeSlot

Flat BC slot (mesh::edgeSlot(cell, edgeLocal)) for each entry of m_sceneEdges; -1 when no slot could be resolved. Parallel vector rather than a field on SceneEdge: SceneEdge is 40 bytes and an extra int pads it to 48, whereas this costs exactly 4 bytes per edge and leaves the hot struct's cache behaviour alone.

m_sceneEdges is deduplicated and buildMeshHeavyGeom is first-writer- wins, which is exactly right here: a boundary edge belongs to one triangle and keeps its own slot, while an interior edge is pushed twice but both its slots are Wall by construction.

◆ m_sceneNodes

QVector<SceneNode> SWMM2DMeshLayer::m_sceneNodes

◆ m_sceneTris

QVector<SceneTri> SWMM2DMeshLayer::m_sceneTris

◆ m_triBBoxes

QVector<QRectF> SWMM2DMeshLayer::m_triBBoxes

parallel to m_sceneTris

◆ m_triGrid

MeshSpatialGrid SWMM2DMeshLayer::m_triGrid

◆ m_trisBySizeDesc

QVector<int> SWMM2DMeshLayer::m_trisBySizeDesc

◆ m_zMax

double SWMM2DMeshLayer::m_zMax = 0.0

◆ m_zMin

double SWMM2DMeshLayer::m_zMin = 0.0

Property Documentation

◆ contourColor

QColor SWMM2DMeshLayer::contourColor
readwrite

◆ contourIntervalCount

int SWMM2DMeshLayer::contourIntervalCount
readwrite

◆ contourLineWidth

double SWMM2DMeshLayer::contourLineWidth
readwrite

◆ edgeZoomMinCellPx

double SWMM2DMeshLayer::edgeZoomMinCellPx
readwrite

◆ filledContours

bool SWMM2DMeshLayer::filledContours
readwrite

◆ filledContoursOpacity

double SWMM2DMeshLayer::filledContoursOpacity
readwrite

◆ hillshadeAltitude

double SWMM2DMeshLayer::hillshadeAltitude
readwrite

◆ hillshadeAzimuth

double SWMM2DMeshLayer::hillshadeAzimuth
readwrite

◆ hillshadeMinLit

double SWMM2DMeshLayer::hillshadeMinLit
readwrite

◆ hillshadeZExag

double SWMM2DMeshLayer::hillshadeZExag
readwrite

◆ showContours

bool SWMM2DMeshLayer::showContours
readwrite

◆ showEdges

bool SWMM2DMeshLayer::showEdges
readwrite

◆ showMeshNodes

bool SWMM2DMeshLayer::showMeshNodes
readwrite

◆ sourcePath

QString SWMM2DMeshLayer::sourcePath
read

◆ triangleCount

int SWMM2DMeshLayer::triangleCount
read

◆ vertexCount

int SWMM2DMeshLayer::vertexCount
read

◆ vertexZoomMinCellPx

double SWMM2DMeshLayer::vertexZoomMinCellPx
readwrite

The documentation for this class was generated from the following files: