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
regionlimits.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2#pragma once
3#include "meshkit/job.hpp"
4#include "operation.hpp"
5#include <algorithm>
7{
8// AABB bounds intentionally over-refine concave/holed regions. Every footprint
9// touching a prescribed region receives its cap, even after a quad fallback.
11{
12 struct Entry {
14 double h;
15 };
16 struct Node {
18 int begin, end, left = -1, right = -1;
19 };
20 std::vector<Entry> entries;
21 std::vector<Node> nodes;
22 int build(int begin, int end, Work &work)
23 {
24 Box2 bounds = entries[begin].bounds;
25 for (int i = begin + 1; i < end; ++i) {
26 work.tick();
27 bounds = bounds.united(entries[i].bounds);
28 }
29 int at = int(nodes.size());
30 nodes.push_back({bounds, begin, end});
31 if (end - begin > 8) {
32 int middle = begin + (end - begin) / 2;
33 bool x = bounds.width() >= bounds.height();
34 std::nth_element(entries.begin() + begin, entries.begin() + middle,
35 entries.begin() + end, [&](const Entry &a, const Entry &b) {
36 work.tick();
37 return x ? a.bounds.center().x() < b.bounds.center().x()
38 : a.bounds.center().y() < b.bounds.center().y();
39 });
40 nodes[at].left = build(begin, middle, work);
41 nodes[at].right = build(middle, end, work);
42 }
43 return at;
44 }
45
46public:
47 RegionLimits(const std::vector<plan::QuadRegion> &regions, Work &work)
48 {
49 for (const auto &r : regions) {
50 work.tick();
51 if (!std::isfinite(r.spacing) || r.spacing < 0)
52 fail("region_size", "Region spacing must be finite and nonnegative.");
53 if (r.spacing > 0 && !r.ring.empty())
54 entries.push_back({r.ring.boundingRect(), r.spacing});
55 }
56 if (!entries.empty())
57 build(0, int(entries.size()), work);
58 }
59 double minimum(const Box2 &bounds, Work &work) const
60 {
61 double h = 0;
62 auto visit = [&](auto &&self, int at) -> void {
63 work.tick();
64 const auto &n = nodes[at];
65 if (!meets(bounds, n.bounds))
66 return;
67 if (n.left >= 0) {
68 self(self, n.left);
69 self(self, n.right);
70 return;
71 }
72 for (int i = n.begin; i < n.end; ++i)
73 if (meets(bounds, entries[i].bounds))
74 h = h > 0 ? std::min(h, entries[i].h) : entries[i].h;
75 };
76 if (!nodes.empty())
77 visit(visit, 0);
78 return h;
79 }
80};
81}
Definition geometry.hpp:59
Definition regionlimits.hpp:11
double minimum(const Box2 &bounds, Work &work) const
Definition regionlimits.hpp:59
RegionLimits(const std::vector< plan::QuadRegion > &regions, Work &work)
Definition regionlimits.hpp:47
int begin
Definition constraints.cpp:103
int end
Definition constraints.cpp:103
size_t i
Definition contourjob.cpp:30
int h
Definition mesh2dresultsexport.cpp:477
Definition file.hpp:21
void fail(std::string code, std::string message, RunStatus status=RunStatus::Infeasible)
Definition operation.hpp:17
bool meets(const Box2 &a, const Box2 &b)
Definition operation.hpp:77
Definition blocks.hpp:25
int right
Definition constraintaudit.cpp:162
int at
Definition constraintaudit.cpp:156
int left
Definition constraintaudit.cpp:162
Definition operation.hpp:22
void tick(std::uint64_t count=1)
Definition operation.hpp:36
double a
Definition terrainerrorfield.cpp:42
double b
Definition terrainerrorfield.cpp:42
int x
Definition terrainerrorfield.cpp:60
QVector< QPointF > nodes
Definition traceanalysislayer.cpp:163
QRectF bounds
Definition traceanalysislayer.cpp:165