@expofp/wayfinding-compiler 0.0.0-bootstrap.0

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.
Files changed (110) hide show
  1. package/README.md +446 -0
  2. package/dist/index.d.ts +14 -0
  3. package/dist/index.js +3 -0
  4. package/dist/lib/attach.d.ts +43 -0
  5. package/dist/lib/attach.js +199 -0
  6. package/dist/lib/axes.d.ts +76 -0
  7. package/dist/lib/axes.js +103 -0
  8. package/dist/lib/blockers.d.ts +134 -0
  9. package/dist/lib/blockers.js +289 -0
  10. package/dist/lib/cell-array.d.ts +14 -0
  11. package/dist/lib/cell-array.js +25 -0
  12. package/dist/lib/centering.d.ts +14 -0
  13. package/dist/lib/centering.js +88 -0
  14. package/dist/lib/compile-layer.d.ts +41 -0
  15. package/dist/lib/compile-layer.js +241 -0
  16. package/dist/lib/compile-wayfinding.d.ts +90 -0
  17. package/dist/lib/compile-wayfinding.js +203 -0
  18. package/dist/lib/connect.d.ts +35 -0
  19. package/dist/lib/connect.js +206 -0
  20. package/dist/lib/diagnostics.d.ts +190 -0
  21. package/dist/lib/diagnostics.js +634 -0
  22. package/dist/lib/doorways.d.ts +78 -0
  23. package/dist/lib/doorways.js +331 -0
  24. package/dist/lib/emit-network.d.ts +47 -0
  25. package/dist/lib/emit-network.js +105 -0
  26. package/dist/lib/emit-v1.d.ts +31 -0
  27. package/dist/lib/emit-v1.js +56 -0
  28. package/dist/lib/entries.d.ts +123 -0
  29. package/dist/lib/entries.js +448 -0
  30. package/dist/lib/floor-grids.d.ts +48 -0
  31. package/dist/lib/floor-grids.js +185 -0
  32. package/dist/lib/framing.d.ts +20 -0
  33. package/dist/lib/framing.js +187 -0
  34. package/dist/lib/geom/boolean-ops.d.ts +21 -0
  35. package/dist/lib/geom/boolean-ops.js +1 -0
  36. package/dist/lib/geom/clipper2-ops.d.ts +7 -0
  37. package/dist/lib/geom/clipper2-ops.js +50 -0
  38. package/dist/lib/geom/footprint.d.ts +26 -0
  39. package/dist/lib/geom/footprint.js +203 -0
  40. package/dist/lib/geom/frames.d.ts +116 -0
  41. package/dist/lib/geom/frames.js +233 -0
  42. package/dist/lib/geom/mesh-outline.d.ts +13 -0
  43. package/dist/lib/geom/mesh-outline.js +90 -0
  44. package/dist/lib/geom/normalize.d.ts +28 -0
  45. package/dist/lib/geom/normalize.js +118 -0
  46. package/dist/lib/geom/point-key.d.ts +16 -0
  47. package/dist/lib/geom/point-key.js +15 -0
  48. package/dist/lib/geom/primitives.d.ts +105 -0
  49. package/dist/lib/geom/primitives.js +184 -0
  50. package/dist/lib/geom/split-crossings.d.ts +14 -0
  51. package/dist/lib/geom/split-crossings.js +171 -0
  52. package/dist/lib/geom/types.d.ts +9 -0
  53. package/dist/lib/geom/types.js +1 -0
  54. package/dist/lib/geom/walls.d.ts +31 -0
  55. package/dist/lib/geom/walls.js +71 -0
  56. package/dist/lib/graph-invariants.d.ts +49 -0
  57. package/dist/lib/graph-invariants.js +129 -0
  58. package/dist/lib/graph-types.d.ts +143 -0
  59. package/dist/lib/graph-types.js +7 -0
  60. package/dist/lib/grid-network.d.ts +20 -0
  61. package/dist/lib/grid-network.js +349 -0
  62. package/dist/lib/lattice-map.d.ts +19 -0
  63. package/dist/lib/lattice-map.js +92 -0
  64. package/dist/lib/lattice-network.d.ts +32 -0
  65. package/dist/lib/lattice-network.js +289 -0
  66. package/dist/lib/mask.d.ts +54 -0
  67. package/dist/lib/mask.js +210 -0
  68. package/dist/lib/min-heap.d.ts +24 -0
  69. package/dist/lib/min-heap.js +73 -0
  70. package/dist/lib/network-build.d.ts +21 -0
  71. package/dist/lib/network-build.js +4 -0
  72. package/dist/lib/network-graph.d.ts +80 -0
  73. package/dist/lib/network-graph.js +467 -0
  74. package/dist/lib/network-setup.d.ts +50 -0
  75. package/dist/lib/network-setup.js +76 -0
  76. package/dist/lib/network-sizes.d.ts +29 -0
  77. package/dist/lib/network-sizes.js +22 -0
  78. package/dist/lib/network-store.d.ts +173 -0
  79. package/dist/lib/network-store.js +430 -0
  80. package/dist/lib/openings.d.ts +54 -0
  81. package/dist/lib/openings.js +387 -0
  82. package/dist/lib/place-path.d.ts +47 -0
  83. package/dist/lib/place-path.js +346 -0
  84. package/dist/lib/post-passes.d.ts +31 -0
  85. package/dist/lib/post-passes.js +305 -0
  86. package/dist/lib/reachability.d.ts +58 -0
  87. package/dist/lib/reachability.js +220 -0
  88. package/dist/lib/report.d.ts +49 -0
  89. package/dist/lib/report.js +374 -0
  90. package/dist/lib/router.d.ts +111 -0
  91. package/dist/lib/router.js +388 -0
  92. package/dist/lib/runs.d.ts +92 -0
  93. package/dist/lib/runs.js +232 -0
  94. package/dist/lib/scale.d.ts +58 -0
  95. package/dist/lib/scale.js +185 -0
  96. package/dist/lib/steiner-network.d.ts +19 -0
  97. package/dist/lib/steiner-network.js +183 -0
  98. package/dist/lib/strip.d.ts +43 -0
  99. package/dist/lib/strip.js +200 -0
  100. package/dist/lib/stubs.d.ts +84 -0
  101. package/dist/lib/stubs.js +316 -0
  102. package/dist/lib/transitions.d.ts +72 -0
  103. package/dist/lib/transitions.js +191 -0
  104. package/dist/lib/types.d.ts +126 -0
  105. package/dist/lib/types.js +1 -0
  106. package/dist/lib/validate-source.d.ts +41 -0
  107. package/dist/lib/validate-source.js +133 -0
  108. package/dist/lib/walkable.d.ts +104 -0
  109. package/dist/lib/walkable.js +140 -0
  110. package/package.json +37 -0
@@ -0,0 +1,140 @@
1
+ import { buildingOutlines } from '@expofp/wayfinding-geometry';
2
+ import { createClipper2Ops } from './geom/clipper2-ops.js';
3
+ import { boundsOf, boxesOverlap, pointInRing, pointSegmentDistance, signedArea, vertexMean, wound, } from './geom/primitives.js';
4
+ import { prepareWalls } from './geom/walls.js';
5
+ import { NODE_SNAP } from './graph-types.js';
6
+ /**
7
+ * Wall half-thickness in meters. Square caps extend each jamb by it, so a doorway narrows by twice
8
+ * this.
9
+ */
10
+ export const WALL_HALF_WIDTH = 0.12;
11
+ /**
12
+ * Footprints cut back to the walls that bound them: a room drawn as its bounding box keeps only its
13
+ * largest piece, so it does not overshoot its wall into the aisle. A footprint the walls leave
14
+ * whole is returned as is.
15
+ * @param ops Polygon boolean backend.
16
+ * @param footprints Obstacle rings, wound positive.
17
+ * @param strips The wall strips, one per wall segment.
18
+ * @returns One ring per footprint, in input order, and which of them the walls cut back.
19
+ */
20
+ function clipToOwnWalls(ops, footprints, strips) {
21
+ const stripBoxes = strips.map(boundsOf);
22
+ const clipped = footprints.map(() => false);
23
+ const rings = footprints.map((footprint, index) => {
24
+ const box = boundsOf(footprint);
25
+ // Only nearby strips: clipping against all of them costs minutes on a large hall.
26
+ const near = strips.filter((_, i) => boxesOverlap(stripBoxes[i], box));
27
+ if (!near.length)
28
+ return footprint;
29
+ const pieces = ops.difference([footprint], near);
30
+ if (pieces.length < 2)
31
+ return footprint;
32
+ clipped[index] = true;
33
+ return pieces.reduce((a, b) => (Math.abs(signedArea(b)) > Math.abs(signedArea(a)) ? b : a));
34
+ });
35
+ return { rings, clipped };
36
+ }
37
+ /**
38
+ * Whether a destination stands on a piece of floor: its middle or a corner lies inside it, or a
39
+ * corner lies on its boundary.
40
+ * @param piece The piece of floor.
41
+ * @param ring The destination's ring.
42
+ * @returns True when the destination stands on it.
43
+ */
44
+ export function standsOn(piece, ring) {
45
+ if (ring.length < 3)
46
+ return false;
47
+ if ([vertexMean(ring), ...ring].some((p) => pointInRing(piece, p)))
48
+ return true;
49
+ // A destination at the floor's edge is carved as a notch: its corners lie on the boundary.
50
+ return ring.some((p) => piece.some((a, i) => {
51
+ const b = piece[(i + 1) % piece.length];
52
+ return pointSegmentDistance(p[0], p[1], a[0], a[1], b[0], b[1]) < NODE_SNAP;
53
+ }));
54
+ }
55
+ /**
56
+ * Whether a point is inside the building: inside its outline and not in a courtyard.
57
+ * @param outline The building's outline, from {@link WalkableArea.outline}.
58
+ * @param point The point.
59
+ * @returns True inside.
60
+ */
61
+ export function inBuilding(outline, point) {
62
+ return outline.filter((ring) => pointInRing(ring, point)).length % 2 === 1;
63
+ }
64
+ /**
65
+ * The walls as strips wound positive, one per wall segment.
66
+ * @param ops Polygon boolean backend.
67
+ * @param segments The wall segments, loops' closing pieces included ({@link prepareWalls}).
68
+ * @param halfWidth Wall half-thickness in meters.
69
+ * @returns One strip per wall segment.
70
+ */
71
+ export function wallStripsOf(ops, segments, halfWidth) {
72
+ const strips = segments.flatMap((s) => ops.offsetSegments([
73
+ [s[0], s[1]],
74
+ [s[2], s[3]],
75
+ ], halfWidth));
76
+ // Positive winding: a NonZero union would cancel where two strips overlap.
77
+ return strips.map(wound);
78
+ }
79
+ /**
80
+ * Footprints cut back to the walls that bound them, in input order: the shapes the floor is carved
81
+ * with.
82
+ * @param obstacles The obstacle rings, in any winding.
83
+ * @param strips The wall strips, from {@link wallStripsOf}.
84
+ * @param ops Polygon boolean backend.
85
+ * @returns One ring per obstacle, in input order, and which of them the walls cut back.
86
+ */
87
+ export function carveFootprints(obstacles, strips, ops) {
88
+ const positive = obstacles.map(wound);
89
+ return clipToOwnWalls(ops, positive, strips);
90
+ }
91
+ /**
92
+ * The outer contours: the building outlines the walls draw, openings closed with no width limit. A
93
+ * bridge closing an outline borders the floor and is no wall.
94
+ * @param walls Cleaned wall centerlines with their closed/open flag.
95
+ * @returns The outlines, largest first, wound positive.
96
+ */
97
+ export function outerContoursOf(walls) {
98
+ const runs = walls.map(({ points, closed }) => (closed ? [...points, points[0]] : points).flat());
99
+ return buildingOutlines(runs).map((flat) => {
100
+ const ring = [];
101
+ for (let i = 0; i < flat.length; i += 2)
102
+ ring.push([flat[i], flat[i + 1]]);
103
+ return wound(ring);
104
+ });
105
+ }
106
+ /**
107
+ * Build one layer's walkable area:
108
+ *
109
+ * walkable = interior(outer contours) − ⋃(obstacles) − ⋃(wall strips)
110
+ * @param input One layer's walls (flat polylines) and obstacles from {@link carveFootprints}.
111
+ * @param ops Polygon boolean backend; defaults to clipper2, which is the only one there is.
112
+ * @param halfWidth Wall half-thickness in meters.
113
+ * @param shared The same walls already read and offset, when the caller holds them.
114
+ * @returns The walkable polygon with holes, plus diagnostic layers and stats.
115
+ */
116
+ export function buildWalkableArea(input, ops = createClipper2Ops(), halfWidth = WALL_HALF_WIDTH, shared) {
117
+ const prepared = shared?.walls ?? prepareWalls(input.walls);
118
+ const walls = [...prepared.runs];
119
+ const outerContours = shared?.contours ?? outerContoursOf(walls);
120
+ const base = ops.union(outerContours);
121
+ const strips = shared?.strips ?? wallStripsOf(ops, prepared.segments, halfWidth);
122
+ // One union instead of subtracting strips one by one; the overlay shows it too.
123
+ const mergedStrips = ops.union(strips);
124
+ // One union and one clip, not N clips (quadratic on a large floor).
125
+ const walkable = ops.difference(ops.difference(base, ops.union(input.obstacles)), mergedStrips);
126
+ const area = ops.area(walkable);
127
+ return {
128
+ rings: walkable,
129
+ outline: base,
130
+ wallStrips: mergedStrips,
131
+ wallLines: walls,
132
+ stats: {
133
+ walls: walls.length,
134
+ outerContours: outerContours.length,
135
+ rings: walkable.length,
136
+ area: +area.toFixed(1),
137
+ areaExact: area,
138
+ },
139
+ };
140
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@expofp/wayfinding-compiler",
3
+ "version": "0.0.0-bootstrap.0",
4
+ "type": "module",
5
+ "description": "ExpoFP SDK internal: compiles raw plan geometry into a wayfinding routing graph",
6
+ "homepage": "https://developer.expofp.com/",
7
+ "license": "MIT",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "sideEffects": false,
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ "./package.json": "./package.json",
17
+ ".": {
18
+ "@expofp/source": "./src/index.ts",
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "default": "./dist/index.js"
22
+ }
23
+ },
24
+ "dependencies": {
25
+ "clipper2-ts": "2.0.1-18",
26
+ "tslib": "^2.3.0",
27
+ "@expofp/wayfinding-geometry": "0.0.0-bootstrap.0"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "!**/*.tsbuildinfo",
32
+ "!**/*.map"
33
+ ],
34
+ "nx": {
35
+ "targets": {}
36
+ }
37
+ }