@kerros/viewer 0.0.0-stage → 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +31 -2
- package/dist/adapters/basemap.js +11 -0
- package/dist/adapters/basemap.js.map +1 -0
- package/dist/adapters/persistence.js +121 -0
- package/dist/adapters/persistence.js.map +1 -0
- package/dist/adapters/status.js +18 -0
- package/dist/adapters/status.js.map +1 -0
- package/dist/components/ElevatorPanel.js +120 -0
- package/dist/components/ElevatorPanel.js.map +1 -0
- package/dist/components/Icons.js +57 -0
- package/dist/components/Icons.js.map +1 -0
- package/dist/components/Inspector.js +1184 -0
- package/dist/components/Inspector.js.map +1 -0
- package/dist/components/NavigatePanel.js +301 -0
- package/dist/components/NavigatePanel.js.map +1 -0
- package/dist/components/NavigationGraph.js +234 -0
- package/dist/components/NavigationGraph.js.map +1 -0
- package/dist/components/StructureExplorer.js +510 -0
- package/dist/components/StructureExplorer.js.map +1 -0
- package/dist/components/StructureView.js +286 -0
- package/dist/components/StructureView.js.map +1 -0
- package/dist/components/controls.js +170 -0
- package/dist/components/controls.js.map +1 -0
- package/dist/components/graphLayout.js +27 -0
- package/dist/components/graphLayout.js.map +1 -0
- package/dist/host.js +169 -0
- package/dist/host.js.map +1 -0
- package/dist/i18n.js +88 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.js +171 -0
- package/dist/index.js.map +1 -0
- package/dist/map/CabinMaterials.js +81 -0
- package/dist/map/CabinMaterials.js.map +1 -0
- package/dist/map/CabinMirror.js +43 -0
- package/dist/map/CabinMirror.js.map +1 -0
- package/dist/map/Doors.js +80 -0
- package/dist/map/Doors.js.map +1 -0
- package/dist/map/ElevatorCabin.js +93 -0
- package/dist/map/ElevatorCabin.js.map +1 -0
- package/dist/map/FixtureLights.js +117 -0
- package/dist/map/FixtureLights.js.map +1 -0
- package/dist/map/MapCanvas.js +2161 -0
- package/dist/map/MapCanvas.js.map +1 -0
- package/dist/map/Passenger.js +69 -0
- package/dist/map/Passenger.js.map +1 -0
- package/dist/map/SceneLayer.js +1534 -0
- package/dist/map/SceneLayer.js.map +1 -0
- package/dist/map/UndergroundContext.js +153 -0
- package/dist/map/UndergroundContext.js.map +1 -0
- package/dist/map/ambience.js +194 -0
- package/dist/map/ambience.js.map +1 -0
- package/dist/map/architecture.js +305 -0
- package/dist/map/architecture.js.map +1 -0
- package/dist/map/bathMusic.js +92 -0
- package/dist/map/bathMusic.js.map +1 -0
- package/dist/map/cameraAim.js +33 -0
- package/dist/map/cameraAim.js.map +1 -0
- package/dist/map/elevators.js +56 -0
- package/dist/map/elevators.js.map +1 -0
- package/dist/map/excavation.js +52 -0
- package/dist/map/excavation.js.map +1 -0
- package/dist/map/exteriors.js +25 -0
- package/dist/map/exteriors.js.map +1 -0
- package/dist/map/features.js +218 -0
- package/dist/map/features.js.map +1 -0
- package/dist/map/fences.js +29 -0
- package/dist/map/fences.js.map +1 -0
- package/dist/map/journey.js +112 -0
- package/dist/map/journey.js.map +1 -0
- package/dist/map/levels.js +6 -0
- package/dist/map/levels.js.map +1 -0
- package/dist/map/lighting.js +142 -0
- package/dist/map/lighting.js.map +1 -0
- package/dist/map/loadBasemap.js +26 -0
- package/dist/map/loadBasemap.js.map +1 -0
- package/dist/map/materials.js +183 -0
- package/dist/map/materials.js.map +1 -0
- package/dist/map/poolLighting.js +39 -0
- package/dist/map/poolLighting.js.map +1 -0
- package/dist/map/projection.js +24 -0
- package/dist/map/projection.js.map +1 -0
- package/dist/map/rampGeometry.js +38 -0
- package/dist/map/rampGeometry.js.map +1 -0
- package/dist/map/route.js +107 -0
- package/dist/map/route.js.map +1 -0
- package/dist/map/stairSurfaces.js +115 -0
- package/dist/map/stairSurfaces.js.map +1 -0
- package/dist/map/surfaces.js +136 -0
- package/dist/map/surfaces.js.map +1 -0
- package/dist/map/textures.js +95 -0
- package/dist/map/textures.js.map +1 -0
- package/dist/map/underground.js +34 -0
- package/dist/map/underground.js.map +1 -0
- package/dist/map/walk.js +433 -0
- package/dist/map/walk.js.map +1 -0
- package/dist/map/walkContext.js +46 -0
- package/dist/map/walkContext.js.map +1 -0
- package/dist/map/walkDimensions.js +7 -0
- package/dist/map/walkDimensions.js.map +1 -0
- package/dist/map/walkJourney.js +85 -0
- package/dist/map/walkJourney.js.map +1 -0
- package/dist/map/walkSurfaces.js +106 -0
- package/dist/map/walkSurfaces.js.map +1 -0
- package/dist/map/wallJoins.js +70 -0
- package/dist/map/wallJoins.js.map +1 -0
- package/dist/map/water.js +274 -0
- package/dist/map/water.js.map +1 -0
- package/dist/model/authoring.js +80 -0
- package/dist/model/authoring.js.map +1 -0
- package/dist/model/boundaries.js +548 -0
- package/dist/model/boundaries.js.map +1 -0
- package/dist/model/coverage.js +30 -0
- package/dist/model/coverage.js.map +1 -0
- package/dist/model/document.js +52 -0
- package/dist/model/document.js.map +1 -0
- package/dist/model/doors.js +47 -0
- package/dist/model/doors.js.map +1 -0
- package/dist/model/factory.js +56 -0
- package/dist/model/factory.js.map +1 -0
- package/dist/model/geometry.js +394 -0
- package/dist/model/geometry.js.map +1 -0
- package/dist/model/inference.js +182 -0
- package/dist/model/inference.js.map +1 -0
- package/dist/model/materials.js +11 -0
- package/dist/model/materials.js.map +1 -0
- package/dist/model/mutations.js +157 -0
- package/dist/model/mutations.js.map +1 -0
- package/dist/model/navigation.js +275 -0
- package/dist/model/navigation.js.map +1 -0
- package/dist/model/ontology.js +109 -0
- package/dist/model/ontology.js.map +1 -0
- package/dist/model/passages.js +5 -0
- package/dist/model/passages.js.map +1 -0
- package/dist/model/portals.js +42 -0
- package/dist/model/portals.js.map +1 -0
- package/dist/model/precision.js +11 -0
- package/dist/model/precision.js.map +1 -0
- package/dist/model/project.js +17 -0
- package/dist/model/project.js.map +1 -0
- package/dist/model/ramps.js +10 -0
- package/dist/model/ramps.js.map +1 -0
- package/dist/model/roomNavigation.js +87 -0
- package/dist/model/roomNavigation.js.map +1 -0
- package/dist/model/routeClearance.js +72 -0
- package/dist/model/routeClearance.js.map +1 -0
- package/dist/model/spaces.js +104 -0
- package/dist/model/spaces.js.map +1 -0
- package/dist/model/stairGeometry.js +40 -0
- package/dist/model/stairGeometry.js.map +1 -0
- package/dist/model/stairTraversal.js +48 -0
- package/dist/model/stairTraversal.js.map +1 -0
- package/dist/model/topology.js +63 -0
- package/dist/model/topology.js.map +1 -0
- package/dist/model/types.js +35 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validate.js +240 -0
- package/dist/model/validate.js.map +1 -0
- package/dist/model/vertical.js +129 -0
- package/dist/model/vertical.js.map +1 -0
- package/dist/model/walls.js +71 -0
- package/dist/model/walls.js.map +1 -0
- package/dist/styles.css +4931 -0
- package/dist/theme/index.js +34 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/types/adapters/basemap.d.ts +2 -0
- package/dist/types/adapters/persistence.d.ts +29 -0
- package/dist/types/adapters/status.d.ts +4 -0
- package/dist/types/components/ElevatorPanel.d.ts +18 -0
- package/dist/types/components/Icons.d.ts +8 -0
- package/dist/types/components/Inspector.d.ts +38 -0
- package/dist/types/components/NavigatePanel.d.ts +27 -0
- package/dist/types/components/NavigationGraph.d.ts +10 -0
- package/dist/types/components/StructureExplorer.d.ts +8 -0
- package/dist/types/components/StructureView.d.ts +22 -0
- package/dist/types/components/controls.d.ts +52 -0
- package/dist/types/components/graphLayout.d.ts +9 -0
- package/dist/types/i18n.d.ts +85 -0
- package/dist/types/import/analysisPreview.d.ts +27 -0
- package/dist/types/import/brief.d.ts +22 -0
- package/dist/types/import/checkpoint.d.ts +49 -0
- package/dist/types/import/instructions.d.ts +7 -0
- package/dist/types/import/usage.d.ts +10 -0
- package/dist/types/map/CabinMaterials.d.ts +18 -0
- package/dist/types/map/CabinMirror.d.ts +13 -0
- package/dist/types/map/Doors.d.ts +11 -0
- package/dist/types/map/ElevatorCabin.d.ts +20 -0
- package/dist/types/map/FixtureLights.d.ts +35 -0
- package/dist/types/map/MapCanvas.d.ts +87 -0
- package/dist/types/map/Passenger.d.ts +18 -0
- package/dist/types/map/SceneLayer.d.ts +306 -0
- package/dist/types/map/UndergroundContext.d.ts +18 -0
- package/dist/types/map/ambience.d.ts +29 -0
- package/dist/types/map/architecture.d.ts +8 -0
- package/dist/types/map/bathMusic.d.ts +14 -0
- package/dist/types/map/cameraAim.d.ts +20 -0
- package/dist/types/map/elevators.d.ts +16 -0
- package/dist/types/map/excavation.d.ts +9 -0
- package/dist/types/map/exteriors.d.ts +3 -0
- package/dist/types/map/features.d.ts +33 -0
- package/dist/types/map/fences.d.ts +4 -0
- package/dist/types/map/journey.d.ts +36 -0
- package/dist/types/map/levels.d.ts +4 -0
- package/dist/types/map/lighting.d.ts +103 -0
- package/dist/types/map/loadBasemap.d.ts +4 -0
- package/dist/types/map/materials.d.ts +38 -0
- package/dist/types/map/poolLighting.d.ts +11 -0
- package/dist/types/map/projection.d.ts +9 -0
- package/dist/types/map/rampGeometry.d.ts +8 -0
- package/dist/types/map/route.d.ts +59 -0
- package/dist/types/map/stairSurfaces.d.ts +29 -0
- package/dist/types/map/surfaces.d.ts +36 -0
- package/dist/types/map/textures.d.ts +8 -0
- package/dist/types/map/underground.d.ts +30 -0
- package/dist/types/map/walk.d.ts +232 -0
- package/dist/types/map/walkContext.d.ts +11 -0
- package/dist/types/map/walkDimensions.d.ts +5 -0
- package/dist/types/map/walkJourney.d.ts +33 -0
- package/dist/types/map/walkSurfaces.d.ts +27 -0
- package/dist/types/map/wallJoins.d.ts +6 -0
- package/dist/types/map/water.d.ts +12 -0
- package/dist/types/model/authoring.d.ts +38 -0
- package/dist/types/model/boundaries.d.ts +41 -0
- package/dist/types/model/coverage.d.ts +8 -0
- package/dist/types/model/document.d.ts +9 -0
- package/dist/types/model/doors.d.ts +19 -0
- package/dist/types/model/factory.d.ts +5 -0
- package/dist/types/model/geometry.d.ts +99 -0
- package/dist/types/model/host.d.ts +154 -0
- package/dist/types/model/inference.d.ts +46 -0
- package/dist/types/model/live.d.ts +60 -0
- package/dist/types/model/materials.d.ts +28 -0
- package/dist/types/model/mutations.d.ts +178 -0
- package/dist/types/model/navigation.d.ts +70 -0
- package/dist/types/model/ontology.d.ts +43 -0
- package/dist/types/model/passages.d.ts +2 -0
- package/dist/types/model/portals.d.ts +9 -0
- package/dist/types/model/precision.d.ts +11 -0
- package/dist/types/model/project.d.ts +8 -0
- package/dist/types/model/ramps.d.ts +7 -0
- package/dist/types/model/roomNavigation.d.ts +15 -0
- package/dist/types/model/routeClearance.d.ts +11 -0
- package/dist/types/model/spaces.d.ts +46 -0
- package/dist/types/model/stairGeometry.d.ts +27 -0
- package/dist/types/model/stairTraversal.d.ts +8 -0
- package/dist/types/model/topology.d.ts +14 -0
- package/dist/types/model/types.d.ts +369 -0
- package/dist/types/model/validate.d.ts +38 -0
- package/dist/types/model/vertical.d.ts +145 -0
- package/dist/types/model/walls.d.ts +71 -0
- package/dist/types/schema/index.d.ts +25 -0
- package/dist/types/theme/index.d.ts +55 -0
- package/dist/types/viewer/FloorViewer.d.ts +76 -0
- package/dist/types/viewer/ViewerWorkspace.d.ts +2 -0
- package/dist/types/viewer/host.d.ts +11 -0
- package/dist/types/viewer/index.d.ts +2 -0
- package/dist/types/viewer/panels.d.ts +12 -0
- package/dist/viewer/FloorViewer.js +104 -0
- package/dist/viewer/FloorViewer.js.map +1 -0
- package/dist/viewer/ViewerWorkspace.js +370 -0
- package/dist/viewer/ViewerWorkspace.js.map +1 -0
- package/dist/viewer/panels.js +35 -0
- package/dist/viewer/panels.js.map +1 -0
- package/package.json +52 -4
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import te from "polygon-clipping";
|
|
2
|
+
import { validateRings as he } from "./validate.js";
|
|
3
|
+
import { uid as F, isArea as V } from "./types.js";
|
|
4
|
+
import { openRing as B, distance as v, pointInRing as H, closeRing as z, ringArea as C, footprint as U, segmentProjection as L, removeBarrier as ge, centroid as ne, rectangle as me, addBarrier as Ie } from "./geometry.js";
|
|
5
|
+
import { GEOMETRY_EPS as w, MIN_RING_EDGE as K, MIN_FACE_AREA as re, CLIP_SCALE as R, MIN_WALL_LENGTH as pe, MIN_SPACE_AREA as oe } from "./precision.js";
|
|
6
|
+
const E = (e) => [...e.barriers, ...e.virtualBoundaries ?? []], Be = (e) => {
|
|
7
|
+
var t;
|
|
8
|
+
return ((t = e.geometry) == null ? void 0 : t.mode) === "boundaries";
|
|
9
|
+
}, T = (e, t) => {
|
|
10
|
+
const r = e.junctions.find((s) => s.id === t.startId), i = e.junctions.find((s) => s.id === t.endId);
|
|
11
|
+
if (!r || !i) throw new Error("A space boundary references a missing junction.");
|
|
12
|
+
return [r.position, i.position];
|
|
13
|
+
}, se = (e) => [...e].reverse().map((t) => ({ edgeId: t.edgeId, reversed: !t.reversed })), _ = (e) => e.reduce((t, r, i) => {
|
|
14
|
+
const s = e[(i + 1) % e.length];
|
|
15
|
+
return t + r[0] * s[1] - s[0] * r[1];
|
|
16
|
+
}, 0) / 2, j = (e) => C(e[0]) - e.slice(1).reduce((t, r) => t + C(r), 0), ie = (e) => e.reduce((t, r) => t + j(r), 0), de = (e) => e.map(
|
|
17
|
+
(t) => z(t).map(
|
|
18
|
+
(r) => [Math.round(r[0] * R) / R, Math.round(r[1] * R) / R]
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
function W(e, ...t) {
|
|
22
|
+
const r = (d) => d.map((g) => z(g).map((a) => [Math.round(a[0] * R), Math.round(a[1] * R)])), i = r(e), s = t.map(r);
|
|
23
|
+
let n;
|
|
24
|
+
try {
|
|
25
|
+
n = te.difference(i, ...s);
|
|
26
|
+
} catch {
|
|
27
|
+
n = [i];
|
|
28
|
+
for (const d of s) {
|
|
29
|
+
if (!n.length) break;
|
|
30
|
+
n = te.difference(n, d);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return n.map(
|
|
34
|
+
(d) => d.map(
|
|
35
|
+
(g) => g.map(
|
|
36
|
+
(a) => [Math.round(a[0] / R * 1e10) / 1e10, Math.round(a[1] / R * 1e10) / 1e10]
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function ae(e, t, r) {
|
|
42
|
+
var i;
|
|
43
|
+
for (const s of e.objects)
|
|
44
|
+
((i = s.geometry) == null ? void 0 : i.mode) === "boundaries" && (s.geometry.loops = s.geometry.loops.map(
|
|
45
|
+
(n) => n.flatMap((d) => d.edgeId !== t ? [d] : d.reversed ? se(r) : r)
|
|
46
|
+
));
|
|
47
|
+
}
|
|
48
|
+
function N(e, t, r) {
|
|
49
|
+
const i = new Map(E(e).map((s) => [s.id, s]));
|
|
50
|
+
return t.map((s) => {
|
|
51
|
+
if (s.length < 3) throw new Error("A space boundary must form a closed loop.");
|
|
52
|
+
const n = [];
|
|
53
|
+
for (let d = 0; d < s.length; d++) {
|
|
54
|
+
const g = s[d], a = s[(d + 1) % s.length], u = i.get(g.edgeId), c = i.get(a.edgeId);
|
|
55
|
+
if (!u || !c || u.floorId !== r || c.floorId !== r)
|
|
56
|
+
throw new Error("A space boundary references a missing edge or another floor.");
|
|
57
|
+
if ((g.reversed ? u.startId : u.endId) !== (a.reversed ? c.endId : c.startId))
|
|
58
|
+
throw new Error("Space boundary edges must share their junctions in order.");
|
|
59
|
+
n.push(T(e, u)[g.reversed ? 1 : 0]);
|
|
60
|
+
}
|
|
61
|
+
return z(n);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function ce(e, t, r) {
|
|
65
|
+
const [i, s] = T(e, t), n = v(i, s), d = r.filter((l) => l.t > w / n && l.t < 1 - w / n).sort((l, o) => l.t - o.t), g = d.filter((l, o) => o === 0 || l.id !== d[o - 1].id);
|
|
66
|
+
if (!g.length) return;
|
|
67
|
+
const a = [{ t: 0, id: t.startId }, ...g, { t: 1, id: t.endId }], u = e.objects.filter((l) => l.barrierId === t.id);
|
|
68
|
+
for (const l of g)
|
|
69
|
+
for (const o of u)
|
|
70
|
+
if (Math.abs((o.offset ?? 0) - l.t * n) < o.width / 2 - w)
|
|
71
|
+
throw new Error("A junction cannot split an opening.");
|
|
72
|
+
const c = "kind" in t, f = a.slice(1).map((l, o) => {
|
|
73
|
+
const m = a[o];
|
|
74
|
+
if ((l.t - m.t) * n < (c ? pe : K) - w)
|
|
75
|
+
throw new Error(
|
|
76
|
+
`That crossing would leave a boundary segment too short. "${"name" in t ? t.name : t.id}" would be ${((l.t - m.t) * n).toFixed(4)} m long.`
|
|
77
|
+
);
|
|
78
|
+
return { ...t, id: o === 0 ? t.id : F(), startId: m.id, endId: l.id };
|
|
79
|
+
});
|
|
80
|
+
for (const l of u) {
|
|
81
|
+
const o = (l.offset ?? 0) / n, m = a.slice(1).findIndex((h) => o <= h.t + w);
|
|
82
|
+
l.barrierId = f[m].id, l.offset = (l.offset ?? 0) - a[m].t * n;
|
|
83
|
+
}
|
|
84
|
+
ae(
|
|
85
|
+
e,
|
|
86
|
+
t.id,
|
|
87
|
+
f.map((l) => ({ edgeId: l.id }))
|
|
88
|
+
), Object.assign(t, f[0]), c ? e.barriers.push(...f.slice(1)) : (e.virtualBoundaries ?? (e.virtualBoundaries = [])).push(...f.slice(1));
|
|
89
|
+
}
|
|
90
|
+
function G(e, t) {
|
|
91
|
+
const r = E(e).filter((o) => o.floorId === t), i = e.junctions.filter((o) => o.floorId === t), s = /* @__PURE__ */ new Map(), n = [];
|
|
92
|
+
for (const o of i) {
|
|
93
|
+
const m = n.find((h) => v(h.position, o.position) <= w);
|
|
94
|
+
m ? s.set(o.id, m.id) : n.push(o);
|
|
95
|
+
}
|
|
96
|
+
for (const o of r)
|
|
97
|
+
o.startId = s.get(o.startId) ?? o.startId, o.endId = s.get(o.endId) ?? o.endId;
|
|
98
|
+
e.junctions = e.junctions.filter((o) => !s.has(o.id));
|
|
99
|
+
const d = new Map(e.junctions.map((o) => [o.id, o.position])), g = r.map((o) => ({
|
|
100
|
+
points: [d.get(o.startId), d.get(o.endId)],
|
|
101
|
+
box: D([d.get(o.startId), d.get(o.endId)])
|
|
102
|
+
})), a = /* @__PURE__ */ new Map(), u = (o, m) => {
|
|
103
|
+
const [h, I] = T(e, o), p = L(m, h, I);
|
|
104
|
+
let y = e.junctions.find((x) => x.floorId === t && v(x.position, m) <= w);
|
|
105
|
+
y || (y = { id: F(), floorId: t, position: m }, e.junctions.push(y));
|
|
106
|
+
const b = a.get(o.id) ?? [];
|
|
107
|
+
b.push({ t: p.t, id: y.id }), a.set(o.id, b);
|
|
108
|
+
};
|
|
109
|
+
for (let o = 0; o < r.length; o++)
|
|
110
|
+
for (let m = o + 1; m < r.length; m++) {
|
|
111
|
+
if (!fe(g[o].box, g[m].box)) continue;
|
|
112
|
+
const h = r[o], I = r[m], [p, y] = g[o].points, [b, x] = g[m].points, A = y[0] - p[0], k = y[1] - p[1], $ = x[0] - b[0], S = x[1] - b[1], O = A * S - k * $;
|
|
113
|
+
if (!(h.startId === I.startId || h.startId === I.endId || h.endId === I.startId || h.endId === I.endId) && Math.abs(O) > 1e-12 * Math.hypot(A, k) * Math.hypot($, S)) {
|
|
114
|
+
const M = ((b[0] - p[0]) * S - (b[1] - p[1]) * $) / O, Z = ((b[0] - p[0]) * k - (b[1] - p[1]) * A) / O;
|
|
115
|
+
if (M >= -w / Math.hypot(A, k) && M <= 1 + w / Math.hypot(A, k) && Z >= -w / Math.hypot($, S) && Z <= 1 + w / Math.hypot($, S)) {
|
|
116
|
+
const ee = [p[0] + Math.max(0, Math.min(1, M)) * A, p[1] + Math.max(0, Math.min(1, M)) * k];
|
|
117
|
+
u(h, ee), u(I, ee);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
for (const M of [p, y])
|
|
121
|
+
L(M, b, x).distance <= w && (u(h, M), u(I, M));
|
|
122
|
+
for (const M of [b, x])
|
|
123
|
+
L(M, p, y).distance <= w && (u(h, M), u(I, M));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (const o of r) ce(e, o, a.get(o.id) ?? []);
|
|
127
|
+
const c = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set();
|
|
128
|
+
for (const o of E(e).filter((m) => m.floorId === t)) {
|
|
129
|
+
const m = [o.startId, o.endId].sort().join("|"), h = c.get(m);
|
|
130
|
+
if (!h) {
|
|
131
|
+
c.set(m, o);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const I = o.startId !== h.startId;
|
|
135
|
+
ae(e, o.id, [{ edgeId: h.id, reversed: I }]);
|
|
136
|
+
for (const p of e.objects.filter((y) => y.barrierId === o.id))
|
|
137
|
+
p.barrierId = h.id, I && (p.offset = v(...T(e, h)) - (p.offset ?? 0), p.kind === "door" && (p.doorHinge = p.doorHinge === "right" ? "left" : "right", p.doorSwing = p.doorSwing === -1 ? 1 : -1));
|
|
138
|
+
f.add(o.id);
|
|
139
|
+
}
|
|
140
|
+
e.barriers = e.barriers.filter((o) => !f.has(o.id)), e.virtualBoundaries && (e.virtualBoundaries = e.virtualBoundaries.filter((o) => !f.has(o.id)));
|
|
141
|
+
const l = new Set(E(e).flatMap((o) => [o.startId, o.endId]));
|
|
142
|
+
e.junctions = e.junctions.filter((o) => !s.has(o.id) || l.has(o.id));
|
|
143
|
+
}
|
|
144
|
+
function P(e, t) {
|
|
145
|
+
const r = E(e).filter((o) => o.floorId === t), i = /* @__PURE__ */ new Map();
|
|
146
|
+
for (const o of r)
|
|
147
|
+
for (const [m, h] of [
|
|
148
|
+
[o.startId, o.endId],
|
|
149
|
+
[o.endId, o.startId]
|
|
150
|
+
]) {
|
|
151
|
+
const I = i.get(m) ?? [];
|
|
152
|
+
I.push({ edge: o, to: h }), i.set(m, I);
|
|
153
|
+
}
|
|
154
|
+
const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Set();
|
|
155
|
+
let g = 0;
|
|
156
|
+
const a = (o, m) => {
|
|
157
|
+
s.set(o, ++g), n.set(o, g);
|
|
158
|
+
for (const { edge: h, to: I } of i.get(o) ?? [])
|
|
159
|
+
h.id !== m && (s.has(I) ? n.set(o, Math.min(n.get(o), s.get(I))) : (a(I, h.id), n.set(o, Math.min(n.get(o), n.get(I))), n.get(I) > s.get(o) && d.add(h.id)));
|
|
160
|
+
};
|
|
161
|
+
for (const o of i.keys()) s.has(o) || a(o);
|
|
162
|
+
const u = new Map(e.junctions.map((o) => [o.id, o.position]));
|
|
163
|
+
for (const [o, m] of i) {
|
|
164
|
+
const h = u.get(o);
|
|
165
|
+
i.set(
|
|
166
|
+
o,
|
|
167
|
+
m.filter((I) => !d.has(I.edge.id)).sort((I, p) => {
|
|
168
|
+
const y = u.get(I.to), b = u.get(p.to);
|
|
169
|
+
return Math.atan2(y[1] - h[1], y[0] - h[0]) - Math.atan2(b[1] - h[1], b[0] - h[0]);
|
|
170
|
+
})
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
const c = /* @__PURE__ */ new Set(), f = [];
|
|
174
|
+
for (const o of r.filter((m) => !d.has(m.id)))
|
|
175
|
+
for (const m of [!1, !0]) {
|
|
176
|
+
let h = { edgeId: o.id, reversed: m }, I = o;
|
|
177
|
+
const p = `${o.id}:${m}`, y = [], b = [];
|
|
178
|
+
if (!c.has(p)) {
|
|
179
|
+
for (let x = 0; x <= r.length * 2; x++) {
|
|
180
|
+
const A = `${h.edgeId}:${!!h.reversed}`;
|
|
181
|
+
if (c.has(A)) break;
|
|
182
|
+
c.add(A), y.push(h);
|
|
183
|
+
const k = h.reversed ? I.endId : I.startId, $ = h.reversed ? I.startId : I.endId;
|
|
184
|
+
b.push(u.get(k));
|
|
185
|
+
const S = i.get($), O = S.findIndex((M) => M.edge.id === I.id);
|
|
186
|
+
if (I = S[(O + S.length - 1) % S.length].edge, h = { edgeId: I.id, reversed: I.endId === $ }, `${h.edgeId}:${!!h.reversed}` === p) break;
|
|
187
|
+
}
|
|
188
|
+
_(b) >= re && f.push({ loop: y, ring: z(b) });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const l = f.map(
|
|
192
|
+
(o, m) => {
|
|
193
|
+
var h;
|
|
194
|
+
return (h = f.map((I, p) => ({ j: p, candidate: I })).filter(
|
|
195
|
+
({ candidate: I, j: p }) => p !== m && C(I.ring) > C(o.ring) + w && o.ring.every((y) => H(y, I.ring)) && !o.loop.some((y) => I.loop.some((b) => b.edgeId === y.edgeId))
|
|
196
|
+
).sort((I, p) => C(I.candidate.ring) - C(p.candidate.ring))[0]) == null ? void 0 : h.j;
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
return f.map((o, m) => {
|
|
200
|
+
const h = f.filter((I, p) => l[p] === m);
|
|
201
|
+
return {
|
|
202
|
+
loops: [o.loop, ...h.map((I) => se(I.loop))],
|
|
203
|
+
rings: [o.ring, ...h.map((I) => z([...B(I.ring)].reverse()))]
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function we(e, t) {
|
|
208
|
+
const r = new Map(e.junctions.map((s) => [s.id, s.position])), i = e.barriers.filter((s) => s.floorId === t).map((s) => ({
|
|
209
|
+
points: [r.get(s.startId), r.get(s.endId)],
|
|
210
|
+
thickness: s.thickness
|
|
211
|
+
}));
|
|
212
|
+
for (let s = 0; s < i.length; s++) {
|
|
213
|
+
let n = !0;
|
|
214
|
+
for (; n; ) {
|
|
215
|
+
n = !1;
|
|
216
|
+
for (let d = s + 1; d < i.length; d++) {
|
|
217
|
+
const g = i[s], a = i[d];
|
|
218
|
+
if (g.thickness !== a.thickness) continue;
|
|
219
|
+
const [u, c] = g.points, [f, l] = a.points, o = v(u, c), m = v(f, l);
|
|
220
|
+
if (Math.abs((c[0] - u[0]) * (l[1] - f[1]) - (c[1] - u[1]) * (l[0] - f[0])) > w * o * m) continue;
|
|
221
|
+
const h = [
|
|
222
|
+
[u, f, c, l],
|
|
223
|
+
[u, l, c, f],
|
|
224
|
+
[c, f, u, l],
|
|
225
|
+
[c, l, u, f]
|
|
226
|
+
].find(([I, p]) => v(I, p) <= w);
|
|
227
|
+
if (h) {
|
|
228
|
+
g.points = [h[2], h[3]], i.splice(d, 1), n = !0;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return i.map(({ points: [s, n], thickness: d }) => {
|
|
235
|
+
(s[0] > n[0] || s[0] === n[0] && s[1] > n[1]) && ([s, n] = [n, s]);
|
|
236
|
+
const g = v(s, n);
|
|
237
|
+
return de([
|
|
238
|
+
me(
|
|
239
|
+
[(s[0] + n[0]) / 2, (s[1] + n[1]) / 2],
|
|
240
|
+
g + d,
|
|
241
|
+
d,
|
|
242
|
+
Math.atan2(n[1] - s[1], n[0] - s[0]) * 180 / Math.PI
|
|
243
|
+
)
|
|
244
|
+
]);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function ye(e) {
|
|
248
|
+
const t = [];
|
|
249
|
+
for (const r of B(e)) (!t.length || v(t.at(-1), r) >= w) && t.push(r);
|
|
250
|
+
return t.length > 1 && v(t[0], t.at(-1)) < w && t.pop(), z(t);
|
|
251
|
+
}
|
|
252
|
+
const D = (e) => {
|
|
253
|
+
let t = 1 / 0, r = 1 / 0, i = -1 / 0, s = -1 / 0;
|
|
254
|
+
for (const [n, d] of e)
|
|
255
|
+
t = Math.min(t, n), r = Math.min(r, d), i = Math.max(i, n), s = Math.max(s, d);
|
|
256
|
+
return { minX: t, minY: r, maxX: i, maxY: s };
|
|
257
|
+
}, fe = (e, t) => e.minX <= t.maxX + w && e.maxX + w >= t.minX && e.minY <= t.maxY + w && e.maxY + w >= t.minY;
|
|
258
|
+
function q(e) {
|
|
259
|
+
const t = /* @__PURE__ */ new Map();
|
|
260
|
+
return (r, i, s = !1) => {
|
|
261
|
+
let n = t.get(r);
|
|
262
|
+
n || (n = we(e, r).map((a) => ({ rings: a, box: D(a[0]) })), t.set(r, n));
|
|
263
|
+
const d = D(i[0]), g = n.filter((a) => fe(a.box, d)).map((a) => a.rings);
|
|
264
|
+
return be(i, g, s);
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function be(e, t, r = !1) {
|
|
268
|
+
const i = t.length ? W(e, ...t) : [de(e)], s = i.filter((n) => j(n) >= oe);
|
|
269
|
+
if (!s.length && r) return [];
|
|
270
|
+
if (!s.length)
|
|
271
|
+
throw new Error(
|
|
272
|
+
`A space needs at least ${oe} m² of usable area. Largest region after subtracting walls: ${Math.max(0, ...i.map((n) => j(n))).toFixed(3)} m².`
|
|
273
|
+
);
|
|
274
|
+
if (s.length !== 1)
|
|
275
|
+
throw new Error(
|
|
276
|
+
`The wall would leave ${s.length} disconnected usable regions (${s.map((n) => j(n).toFixed(2)).join(", ")} m²). Extend it to a boundary to divide the space.`
|
|
277
|
+
);
|
|
278
|
+
return s[0].map(ye);
|
|
279
|
+
}
|
|
280
|
+
function Q(e, t) {
|
|
281
|
+
var r;
|
|
282
|
+
return ((r = t.geometry) == null ? void 0 : r.mode) !== "boundaries" ? U(t) : q(e)(t.floorId, N(e, t.geometry.loops, t.floorId));
|
|
283
|
+
}
|
|
284
|
+
function Y(e, t) {
|
|
285
|
+
e.rings = t, e.position = ne(t[0]), e.rotation = 0;
|
|
286
|
+
const r = t[0].map((s) => s[0]), i = t[0].map((s) => s[1]);
|
|
287
|
+
e.width = Math.max(...r) - Math.min(...r), e.depth = Math.max(...i) - Math.min(...i);
|
|
288
|
+
}
|
|
289
|
+
function ve(e, t, r) {
|
|
290
|
+
if (!V(t.kind)) throw new Error("Only a drawn area can use shared boundaries.");
|
|
291
|
+
t.geometry = { mode: "boundaries", loops: structuredClone(r.loops) }, Y(t, Q(e, t));
|
|
292
|
+
}
|
|
293
|
+
function ke(e, t, r) {
|
|
294
|
+
return P(e, t).filter((i) => H(r, i.rings[0]) && !i.rings.slice(1).some((s) => H(r, s))).sort((i, s) => j(i.rings) - j(s.rings))[0] ?? null;
|
|
295
|
+
}
|
|
296
|
+
function J(e, t, r) {
|
|
297
|
+
const i = e.junctions.find((n) => n.floorId === t && v(n.position, r) <= w);
|
|
298
|
+
if (i) return i.id;
|
|
299
|
+
const s = F();
|
|
300
|
+
return e.junctions.push({ id: s, floorId: t, position: r }), s;
|
|
301
|
+
}
|
|
302
|
+
function X(e, t, r, i) {
|
|
303
|
+
if (v(r, i) < K) throw new Error("A space boundary is too short.");
|
|
304
|
+
const s = J(e, t, r), n = J(e, t, i), d = E(e).find(
|
|
305
|
+
(a) => a.floorId === t && (a.startId === s && a.endId === n || a.startId === n && a.endId === s)
|
|
306
|
+
);
|
|
307
|
+
if (d) return d.id;
|
|
308
|
+
const g = F();
|
|
309
|
+
return (e.virtualBoundaries ?? (e.virtualBoundaries = [])).push({ id: g, floorId: t, startId: s, endId: n }), g;
|
|
310
|
+
}
|
|
311
|
+
function $e(e, t, r, i) {
|
|
312
|
+
const s = v(r, i);
|
|
313
|
+
if (s < K) throw new Error("A space boundary is too short.");
|
|
314
|
+
const n = (d) => Math.abs((i[0] - r[0]) * (d[1] - r[1]) - (i[1] - r[1]) * (d[0] - r[0])) / s <= w;
|
|
315
|
+
for (const d of [...e.barriers].filter((g) => g.floorId === t)) {
|
|
316
|
+
const [g, a] = T(e, d);
|
|
317
|
+
if (!n(g) || !n(a)) continue;
|
|
318
|
+
const u = [r, i].flatMap((c) => {
|
|
319
|
+
const f = L(c, g, a);
|
|
320
|
+
return f.distance <= w && f.t > 0 && f.t < 1 ? [{ t: f.t, id: J(e, t, f.point) }] : [];
|
|
321
|
+
});
|
|
322
|
+
ce(e, d, u);
|
|
323
|
+
}
|
|
324
|
+
for (const d of [...e.barriers].filter((g) => g.floorId === t))
|
|
325
|
+
T(e, d).every((g) => L(g, r, i).distance <= w) && ((e.virtualBoundaries ?? (e.virtualBoundaries = [])).push({ id: d.id, floorId: t, startId: d.startId, endId: d.endId }), ge(e, d.id));
|
|
326
|
+
return X(e, t, r, i);
|
|
327
|
+
}
|
|
328
|
+
function Re(e, t, r = "outline") {
|
|
329
|
+
var n;
|
|
330
|
+
const i = e.objects.find((d) => d.id === t);
|
|
331
|
+
if (!i || !V(i.kind)) throw new Error("Select an area to connect to boundaries.");
|
|
332
|
+
if (r === "walls") {
|
|
333
|
+
G(e, i.floorId);
|
|
334
|
+
const d = U(i), g = j(d), a = P(e, i.floorId).map((c) => ({
|
|
335
|
+
region: c,
|
|
336
|
+
overlap: g - ie(W(d, c.rings))
|
|
337
|
+
})).filter((c) => c.overlap > w).sort((c, f) => f.overlap - c.overlap);
|
|
338
|
+
if (a.length > 1 && Math.abs(a[0].overlap - a[1].overlap) < w)
|
|
339
|
+
throw new Error("More than one region matches this outline. Use Space from walls inside the intended region.");
|
|
340
|
+
const u = (n = a[0]) == null ? void 0 : n.region;
|
|
341
|
+
if (!u) throw new Error("No closed wall boundary surrounds this space.");
|
|
342
|
+
ve(e, i, u);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const s = U(i).map((d, g) => {
|
|
346
|
+
let a = B(d);
|
|
347
|
+
return _(a) > 0 != (g === 0) && (a = [...a].reverse()), a.map((u, c) => {
|
|
348
|
+
const f = a[(c + 1) % a.length], l = X(e, i.floorId, u, f), o = E(e).find((m) => m.id === l);
|
|
349
|
+
return { edgeId: l, reversed: v(T(e, o)[0], u) > w };
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
i.geometry = { mode: "boundaries", loops: s }, G(e, i.floorId), Y(i, Q(e, i));
|
|
353
|
+
}
|
|
354
|
+
function Te(e, t) {
|
|
355
|
+
const r = e.objects.find((i) => i.id === t);
|
|
356
|
+
r && (r.geometry = { mode: "independent" });
|
|
357
|
+
}
|
|
358
|
+
function _e(e, t, r) {
|
|
359
|
+
var n;
|
|
360
|
+
if (((n = t.geometry) == null ? void 0 : n.mode) !== "boundaries") throw new Error("Select a space with shared boundaries.");
|
|
361
|
+
let i = B(r);
|
|
362
|
+
_(i) > 0 && (i = [...i].reverse());
|
|
363
|
+
const s = i.map((d, g) => {
|
|
364
|
+
const a = X(e, t.floorId, d, i[(g + 1) % i.length]), u = E(e).find((c) => c.id === a);
|
|
365
|
+
return { edgeId: a, reversed: v(T(e, u)[0], d) > w };
|
|
366
|
+
});
|
|
367
|
+
t.geometry.loops.push(s);
|
|
368
|
+
}
|
|
369
|
+
function Ce(e, t, r, i, s = !0) {
|
|
370
|
+
var f;
|
|
371
|
+
if (((f = t.geometry) == null ? void 0 : f.mode) !== "boundaries") throw new Error("This space has no shared boundaries.");
|
|
372
|
+
const n = v(r, i);
|
|
373
|
+
if (n < w) throw new Error("Draw a line across the space.");
|
|
374
|
+
const d = (i[0] - r[0]) / n, g = (i[1] - r[1]) / n, a = [];
|
|
375
|
+
for (const l of N(e, t.geometry.loops, t.floorId)) {
|
|
376
|
+
const o = B(l);
|
|
377
|
+
for (let m = 0; m < o.length; m++) {
|
|
378
|
+
const h = o[m], I = o[(m + 1) % o.length], p = I[0] - h[0], y = I[1] - h[1], b = d * y - g * p;
|
|
379
|
+
if (Math.abs(b) < 1e-12) continue;
|
|
380
|
+
const x = ((h[0] - r[0]) * g - (h[1] - r[1]) * d) / b;
|
|
381
|
+
x >= -w && x <= 1 + w && a.push(((h[0] - r[0]) * y - (h[1] - r[1]) * p) / b);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
a.sort((l, o) => l - o);
|
|
385
|
+
const u = a.filter((l, o) => o === 0 || l - a[o - 1] > w);
|
|
386
|
+
for (let l = 0; l + 1 < u.length; l += 2) {
|
|
387
|
+
const o = [r[0] + u[l] * d, r[1] + u[l] * g], m = [r[0] + u[l + 1] * d, r[1] + u[l + 1] * g];
|
|
388
|
+
if (s) {
|
|
389
|
+
const h = Ie(e, o, m, t.floorId, "wall");
|
|
390
|
+
h && (h.name = "Partition", h.thickness = 0.18);
|
|
391
|
+
} else X(e, t.floorId, o, m);
|
|
392
|
+
}
|
|
393
|
+
G(e, t.floorId);
|
|
394
|
+
const c = le(e);
|
|
395
|
+
if (!c.length) throw new Error("The cut must divide the space into usable regions.");
|
|
396
|
+
return c[0];
|
|
397
|
+
}
|
|
398
|
+
function ze(e, t, r) {
|
|
399
|
+
var u, c;
|
|
400
|
+
if (((u = t.geometry) == null ? void 0 : u.mode) !== "boundaries" || ((c = r.geometry) == null ? void 0 : c.mode) !== "boundaries")
|
|
401
|
+
throw new Error("Connect both spaces to shared boundaries before merging their boundaries.");
|
|
402
|
+
const i = t.geometry.loops.flat(), s = r.geometry.loops.flat(), n = new Set(
|
|
403
|
+
i.filter((f) => s.some((l) => l.edgeId === f.edgeId && !!l.reversed != !!f.reversed)).map((f) => f.edgeId)
|
|
404
|
+
);
|
|
405
|
+
if (!n.size) return !1;
|
|
406
|
+
if (e.barriers.some((f) => n.has(f.id))) throw new Error("Remove the dividing wall before merging these spaces.");
|
|
407
|
+
const d = new Map(E(e).map((f) => [f.id, f])), g = [...i, ...s].filter((f) => !n.has(f.edgeId)), a = [];
|
|
408
|
+
for (; g.length; ) {
|
|
409
|
+
const f = [g.shift()], l = d.get(f[0].edgeId), o = f[0].reversed ? l.endId : l.startId;
|
|
410
|
+
let m = f[0].reversed ? l.startId : l.endId;
|
|
411
|
+
for (; m !== o; ) {
|
|
412
|
+
const h = g.findIndex((y) => {
|
|
413
|
+
const b = d.get(y.edgeId);
|
|
414
|
+
return (y.reversed ? b.endId : b.startId) === m;
|
|
415
|
+
});
|
|
416
|
+
if (h < 0) throw new Error("The merged space boundary is not closed.");
|
|
417
|
+
const I = g.splice(h, 1)[0], p = d.get(I.edgeId);
|
|
418
|
+
f.push(I), m = I.reversed ? p.startId : p.endId;
|
|
419
|
+
}
|
|
420
|
+
a.push(f);
|
|
421
|
+
}
|
|
422
|
+
return a.sort(
|
|
423
|
+
(f, l) => _(B(N(e, [l], t.floorId)[0])) - _(B(N(e, [f], t.floorId)[0]))
|
|
424
|
+
), t.geometry = { mode: "boundaries", loops: a }, e.virtualBoundaries = (e.virtualBoundaries ?? []).filter(
|
|
425
|
+
(f) => !n.has(f.id) || e.objects.some(
|
|
426
|
+
(l) => {
|
|
427
|
+
var o;
|
|
428
|
+
return l.id !== r.id && ((o = l.geometry) == null ? void 0 : o.mode) === "boundaries" && l.geometry.loops.some((m) => m.some((h) => h.edgeId === f.id));
|
|
429
|
+
}
|
|
430
|
+
)
|
|
431
|
+
), Y(t, Q(e, t)), !0;
|
|
432
|
+
}
|
|
433
|
+
function Me(e, t) {
|
|
434
|
+
e.objects.some(
|
|
435
|
+
(r) => {
|
|
436
|
+
var i;
|
|
437
|
+
return ((i = r.geometry) == null ? void 0 : i.mode) === "boundaries" && r.geometry.loops.some((s) => s.some((n) => n.edgeId === t.id));
|
|
438
|
+
}
|
|
439
|
+
) && ((e.virtualBoundaries ?? []).some((r) => r.id === t.id) || (e.virtualBoundaries ?? (e.virtualBoundaries = [])).push({ id: t.id, floorId: t.floorId, startId: t.startId, endId: t.endId }));
|
|
440
|
+
}
|
|
441
|
+
function le(e, t) {
|
|
442
|
+
var n;
|
|
443
|
+
const r = [], i = /* @__PURE__ */ new Map(), s = q(e);
|
|
444
|
+
for (const d of [...e.objects]) {
|
|
445
|
+
if (((n = d.geometry) == null ? void 0 : n.mode) !== "boundaries") continue;
|
|
446
|
+
const g = N(e, d.geometry.loops, d.floorId);
|
|
447
|
+
if (t && !t.has(d.floorId)) {
|
|
448
|
+
Y(d, s(d.floorId, g));
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
i.has(d.floorId) || i.set(d.floorId, P(e, d.floorId));
|
|
452
|
+
const a = i.get(d.floorId).filter((c) => ie(W(c.rings, g)) < w);
|
|
453
|
+
if (!a.length) throw new Error("The space boundaries no longer form a closed region.");
|
|
454
|
+
a.sort((c, f) => j(f.rings) - j(c.rings));
|
|
455
|
+
const u = a.map((c) => ({ region: c, rings: s(d.floorId, c.rings, a.length > 1) })).filter((c) => c.rings.length).sort((c, f) => j(f.rings) - j(c.rings));
|
|
456
|
+
if (!u.length) throw new Error("The walls would remove all usable area from this space.");
|
|
457
|
+
for (let c = 0; c < u.length; c++) {
|
|
458
|
+
const f = c === 0 ? d : { ...structuredClone(d), id: F(), name: `${d.name} ${c + 1}`, feedId: void 0 };
|
|
459
|
+
if (f.geometry = { mode: "boundaries", loops: structuredClone(u[c].region.loops) }, Y(f, u[c].rings), c > 0) {
|
|
460
|
+
e.objects.push(f), r.push(f.id);
|
|
461
|
+
for (const l of e.zones ?? []) l.spaceIds.includes(d.id) && l.spaceIds.push(f.id);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return r;
|
|
466
|
+
}
|
|
467
|
+
function Ne(e, t) {
|
|
468
|
+
for (const a of ["barriers", "junctions", "objects", "virtualBoundaries", "zones"]) {
|
|
469
|
+
const u = t[a];
|
|
470
|
+
u && (Object.isFrozen(u) || u.some((c) => Object.isFrozen(c))) && Object.assign(t, { [a]: structuredClone(u) });
|
|
471
|
+
}
|
|
472
|
+
const r = E(t), i = new Set(r.map((a) => a.id));
|
|
473
|
+
for (const a of E(e))
|
|
474
|
+
if (!i.has(a.id) && (Me(t, a), (t.virtualBoundaries ?? []).some((u) => u.id === a.id))) {
|
|
475
|
+
for (const u of [a.startId, a.endId])
|
|
476
|
+
if (!t.junctions.some((c) => c.id === u)) {
|
|
477
|
+
const c = e.junctions.find((f) => f.id === u);
|
|
478
|
+
c && t.junctions.push(structuredClone(c));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
const s = (a, u) => JSON.stringify([
|
|
482
|
+
E(a).filter((c) => c.floorId === u).map((c) => [c.id, c.startId, c.endId]),
|
|
483
|
+
a.junctions.filter((c) => c.floorId === u).map((c) => [c.id, c.position])
|
|
484
|
+
]), n = new Set(E(t).map((a) => a.floorId));
|
|
485
|
+
for (const a of n) s(e, a) !== s(t, a) && G(t, a);
|
|
486
|
+
const d = (a, u) => JSON.stringify(
|
|
487
|
+
E(a).filter((c) => c.floorId === u).map((c) => [c.id, c.startId, c.endId])
|
|
488
|
+
), g = new Set([...n].filter((a) => d(e, a) !== d(t, a)));
|
|
489
|
+
le(t, g);
|
|
490
|
+
}
|
|
491
|
+
function Oe(e) {
|
|
492
|
+
const t = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Map(), i = q(e), s = (n) => n.flat().map((d) => `${d.edgeId}:${!!d.reversed}`).sort().join("|");
|
|
493
|
+
for (const n of e.objects) {
|
|
494
|
+
if (n.geometry === void 0) continue;
|
|
495
|
+
if (!n.geometry || !["independent", "boundaries"].includes(n.geometry.mode))
|
|
496
|
+
throw new Error("Unknown space geometry mode.");
|
|
497
|
+
if (n.geometry.mode === "independent") continue;
|
|
498
|
+
if (!V(n.kind) || !Array.isArray(n.geometry.loops) || !n.geometry.loops.length || n.geometry.loops.some(
|
|
499
|
+
(f) => !Array.isArray(f) || f.some(
|
|
500
|
+
(l) => !l || typeof l.edgeId != "string" || l.reversed !== void 0 && typeof l.reversed != "boolean"
|
|
501
|
+
)
|
|
502
|
+
))
|
|
503
|
+
throw new Error("Malformed space boundary loops.");
|
|
504
|
+
const d = N(e, n.geometry.loops, n.floorId), g = he(d, w, re);
|
|
505
|
+
if (g) throw new Error(g);
|
|
506
|
+
if (_(B(d[0])) <= 0 || d.slice(1).some((f) => _(B(f)) >= 0))
|
|
507
|
+
throw new Error("Space boundary loops must keep the space on their left.");
|
|
508
|
+
if (r.has(n.floorId) || r.set(n.floorId, new Set(P(e, n.floorId).map((f) => s(f.loops)))), !r.get(n.floorId).has(s(n.geometry.loops)))
|
|
509
|
+
throw new Error("A connected space must follow one face of the boundary network.");
|
|
510
|
+
for (const f of n.geometry.loops)
|
|
511
|
+
for (const l of f) {
|
|
512
|
+
const o = `${l.edgeId}:${!!l.reversed}`;
|
|
513
|
+
if (t.has(o)) throw new Error("Two spaces cannot occupy the same side of a shared boundary.");
|
|
514
|
+
t.add(o);
|
|
515
|
+
}
|
|
516
|
+
const a = i(n.floorId, d);
|
|
517
|
+
if (!n.rings || a.length !== n.rings.length || a.some(
|
|
518
|
+
(f, l) => f.length !== n.rings[l].length || f.some((o, m) => v(o, n.rings[l][m]) > w)
|
|
519
|
+
))
|
|
520
|
+
throw new Error("The space footprint is stale. Update it through a geometry transaction.");
|
|
521
|
+
const u = a[0].map((f) => f[0]), c = a[0].map((f) => f[1]);
|
|
522
|
+
if (v(n.position, ne(a[0])) > w || Math.abs(n.width - (Math.max(...u) - Math.min(...u))) > w || Math.abs(n.depth - (Math.max(...c) - Math.min(...c))) > w || n.rotation !== 0)
|
|
523
|
+
throw new Error("A boundary-driven space has stale calculated dimensions.");
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
export {
|
|
527
|
+
_e as addBoundaryHole,
|
|
528
|
+
X as addVirtualBoundary,
|
|
529
|
+
ve as bindSpaceToRegion,
|
|
530
|
+
E as boundaryEdges,
|
|
531
|
+
ke as boundaryRegionAt,
|
|
532
|
+
P as boundaryRegions,
|
|
533
|
+
N as boundaryRings,
|
|
534
|
+
Re as connectSpace,
|
|
535
|
+
Q as derivedSpaceRings,
|
|
536
|
+
Te as disconnectSpace,
|
|
537
|
+
$e as drawVirtualBoundary,
|
|
538
|
+
Be as followsBoundaries,
|
|
539
|
+
ze as mergeBoundaryGeometry,
|
|
540
|
+
G as normalizeBoundaries,
|
|
541
|
+
Me as preserveBoundary,
|
|
542
|
+
le as refreshBoundarySpaces,
|
|
543
|
+
ae as replaceBoundaryUses,
|
|
544
|
+
Ce as splitBoundarySpace,
|
|
545
|
+
Ne as synchronizeGeometry,
|
|
546
|
+
Oe as validateSpaceBoundaries
|
|
547
|
+
};
|
|
548
|
+
//# sourceMappingURL=boundaries.js.map
|