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
meshstaticgeometrybuffers.h
Go to the documentation of this file.
1
35#ifndef OPENSWMM_RENDER_MESHSTATICGEOMETRYBUFFERS_H
36#define OPENSWMM_RENDER_MESHSTATICGEOMETRYBUFFERS_H
37
38#include <QPointF>
39#include <QVector>
40#include <QtGlobal>
41
42#include <algorithm>
43#include <cstddef>
44#include <utility>
45#include <vector>
46
47namespace OpenSWMM::Render
48{
49
51{
52public:
53 struct Vec2
54 {
55 float x = 0.0f;
56 float y = 0.0f;
57 };
58
59 static constexpr quint64 kNoRevision = ~quint64(0);
60
61 void clear()
62 {
63 m_positions.clear();
64 m_triIndices.clear();
65 m_triCell.clear();
66 m_edgeEndpoints.clear();
67 m_revision = kNoRevision;
68 m_anchorX = m_anchorY = 0.0;
69 }
70
71 [[nodiscard]] bool isBuilt() const { return m_revision != kNoRevision; }
72 [[nodiscard]] quint64 revision() const { return m_revision; }
73 [[nodiscard]] double anchorX() const { return m_anchorX; }
74 [[nodiscard]] double anchorY() const { return m_anchorY; }
75
76 [[nodiscard]] const std::vector<Vec2> &positions() const { return m_positions; }
77 [[nodiscard]] const std::vector<quint32> &triIndices() const { return m_triIndices; }
82 [[nodiscard]] const std::vector<quint32> &triCell() const { return m_triCell; }
85 [[nodiscard]] const std::vector<quint32> &edgeEndpoints() const { return m_edgeEndpoints; }
86
87 [[nodiscard]] qint64 vertexCount() const { return qint64(m_positions.size()); }
88 [[nodiscard]] qint64 triangleCount() const { return qint64(m_triIndices.size() / 3); }
89 [[nodiscard]] qint64 edgeCount() const { return qint64(m_edgeEndpoints.size() / 2); }
90
107 template <typename TriAccessor>
108 bool ensureBuilt(quint64 geomRevision,
109 double anchorX, double anchorY,
110 const QVector<QPointF> &vertices,
111 qint64 triCount,
112 TriAccessor &&triAccessor,
113 bool buildEdges = false)
114 {
115 // A triangle is a 3-vertex cell whose fan is itself.
116 return ensureBuiltCells(
117 geomRevision, anchorX, anchorY, vertices, triCount,
118 [&](qint64 i, int poly[4], int &nv, int fan[2][3], int &nFan) {
119 int v0 = -1, v1 = -1, v2 = -1;
120 triAccessor(i, v0, v1, v2);
121 poly[0] = v0; poly[1] = v1; poly[2] = v2; poly[3] = -1;
122 nv = 3;
123 fan[0][0] = v0; fan[0][1] = v1; fan[0][2] = v2;
124 nFan = 1;
125 },
126 buildEdges);
127 }
128
143 template <typename CellAccessor>
144 bool ensureBuiltCells(quint64 geomRevision,
145 double anchorX, double anchorY,
146 const QVector<QPointF> &vertices,
147 qint64 cellCount,
148 CellAccessor &&cellAccessor,
149 bool buildEdges = false)
150 {
151 if (m_revision == geomRevision
152 && (!buildEdges || !m_edgeEndpoints.empty() || cellCount == 0))
153 return false;
154
155 m_anchorX = anchorX;
156 m_anchorY = anchorY;
157
158 m_positions.clear();
159 m_positions.reserve(size_t(vertices.size()));
160 for (const QPointF &p : vertices)
161 m_positions.push_back(Vec2{float(p.x() - anchorX),
162 float(p.y() - anchorY)});
163
164 const int nVerts = int(vertices.size());
165 m_triIndices.clear();
166 m_triIndices.reserve(size_t(cellCount) * 3);
167 m_triCell.clear();
168 m_triCell.reserve(size_t(cellCount));
169
170 // Undirected dedup via sorted (lo,hi) keys — from the polygon
171 // boundary, not the fan.
172 std::vector<quint64> keys;
173 if (buildEdges) keys.reserve(size_t(cellCount) * 3);
174 auto pushKey = [&keys](int u, int v) {
175 if (u == v) return;
176 const quint32 lo = quint32(std::min(u, v));
177 const quint32 hi = quint32(std::max(u, v));
178 keys.push_back((quint64(lo) << 32) | quint64(hi));
179 };
180
181 for (qint64 i = 0; i < cellCount; ++i) {
182 int poly[4] = {-1, -1, -1, -1};
183 int fan[2][3] = {{-1, -1, -1}, {-1, -1, -1}};
184 int nv = 0, nFan = 0;
185 cellAccessor(i, poly, nv, fan, nFan);
186 if (nv < 3 || nv > 4 || nFan < 1 || nFan > 2) continue;
187 bool valid = true;
188 for (int k = 0; k < nv; ++k)
189 if (poly[k] < 0 || poly[k] >= nVerts) { valid = false; break; }
190 if (!valid) continue; // drop invalid cells — indices stay valid
191 for (int s = 0; s < nFan; ++s) {
192 m_triIndices.push_back(quint32(fan[s][0]));
193 m_triIndices.push_back(quint32(fan[s][1]));
194 m_triIndices.push_back(quint32(fan[s][2]));
195 m_triCell.push_back(quint32(i));
196 }
197 if (buildEdges)
198 for (int k = 0; k < nv; ++k)
199 pushKey(poly[k], poly[(k + 1) % nv]);
200 }
201
202 m_edgeEndpoints.clear();
203 if (buildEdges) {
204 std::sort(keys.begin(), keys.end());
205 keys.erase(std::unique(keys.begin(), keys.end()), keys.end());
206 m_edgeEndpoints.reserve(keys.size() * 2);
207 for (quint64 k : keys) {
208 m_edgeEndpoints.push_back(quint32(k >> 32));
209 m_edgeEndpoints.push_back(quint32(k & 0xffffffffu));
210 }
211 }
212
213 m_revision = geomRevision;
214 return true;
215 }
216
217private:
218 std::vector<Vec2> m_positions;
219 std::vector<quint32> m_triIndices;
220 std::vector<quint32> m_triCell;
221 std::vector<quint32> m_edgeEndpoints;
222 quint64 m_revision = kNoRevision;
223 double m_anchorX = 0.0;
224 double m_anchorY = 0.0;
225};
226
227} // namespace OpenSWMM::Render
228
229#endif // OPENSWMM_RENDER_MESHSTATICGEOMETRYBUFFERS_H
Definition meshstaticgeometrybuffers.h:51
void clear()
Definition meshstaticgeometrybuffers.h:61
double anchorX() const
Definition meshstaticgeometrybuffers.h:73
double anchorY() const
Definition meshstaticgeometrybuffers.h:74
qint64 vertexCount() const
Definition meshstaticgeometrybuffers.h:87
bool isBuilt() const
Definition meshstaticgeometrybuffers.h:71
static constexpr quint64 kNoRevision
Definition meshstaticgeometrybuffers.h:59
qint64 edgeCount() const
Definition meshstaticgeometrybuffers.h:89
quint64 revision() const
Definition meshstaticgeometrybuffers.h:72
const std::vector< Vec2 > & positions() const
Definition meshstaticgeometrybuffers.h:76
qint64 triangleCount() const
Definition meshstaticgeometrybuffers.h:88
const std::vector< quint32 > & edgeEndpoints() const
Definition meshstaticgeometrybuffers.h:85
const std::vector< quint32 > & triIndices() const
Definition meshstaticgeometrybuffers.h:77
const std::vector< quint32 > & triCell() const
Definition meshstaticgeometrybuffers.h:82
bool ensureBuiltCells(quint64 geomRevision, double anchorX, double anchorY, const QVector< QPointF > &vertices, qint64 cellCount, CellAccessor &&cellAccessor, bool buildEdges=false)
Definition meshstaticgeometrybuffers.h:144
bool ensureBuilt(quint64 geomRevision, double anchorX, double anchorY, const QVector< QPointF > &vertices, qint64 triCount, TriAccessor &&triAccessor, bool buildEdges=false)
Definition meshstaticgeometrybuffers.h:108
size_t i
Definition contourjob.cpp:27
double s
Scene px per model length unit.
Definition inletdrawingview.cpp:82
ArrowPlacement p
Definition linesymbollayer.cpp:27
int k
Definition mesh2dresultsexport.cpp:549
int nv
Definition meshenginesync.cpp:32
Definition gisrasterlayer.h:40
QVector< int > v
pool vertex indices
Definition pslgminsize.cpp:159
Definition meshstaticgeometrybuffers.h:54
float x
Definition meshstaticgeometrybuffers.h:55
float y
Definition meshstaticgeometrybuffers.h:56