@pascal-app/core 0.8.0 → 0.9.2
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/dist/events/bus.d.ts +67 -13
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/scene-registry/item-clip-registry.d.ts +18 -0
- package/dist/hooks/scene-registry/item-clip-registry.d.ts.map +1 -0
- package/dist/hooks/scene-registry/item-clip-registry.js +10 -0
- package/dist/hooks/scene-registry/scene-registry.d.ts +14 -23
- package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.js +59 -26
- package/dist/hooks/scene-registry/scene-registry.test.d.ts +2 -0
- package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +1 -0
- package/dist/hooks/scene-registry/scene-registry.test.js +26 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +14 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.js +51 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +2 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +366 -0
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +79 -11
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +508 -141
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +28 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +109 -18
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +2 -0
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +363 -0
- package/dist/index.d.ts +36 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -6
- package/dist/lib/level-name.d.ts +4 -0
- package/dist/lib/level-name.d.ts.map +1 -0
- package/dist/lib/level-name.js +10 -0
- package/dist/lib/measurement-geometry.d.ts +19 -0
- package/dist/lib/measurement-geometry.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.js +232 -0
- package/dist/lib/measurement-geometry.test.d.ts +2 -0
- package/dist/lib/measurement-geometry.test.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.test.js +102 -0
- package/dist/lib/polygon-geometry.d.ts +0 -1
- package/dist/lib/polygon-geometry.d.ts.map +1 -1
- package/dist/lib/polygon-geometry.js +0 -18
- package/dist/lib/polygon-relations.d.ts +10 -0
- package/dist/lib/polygon-relations.d.ts.map +1 -0
- package/dist/lib/polygon-relations.js +73 -0
- package/dist/lib/selection-proxy.d.ts +4 -0
- package/dist/lib/selection-proxy.d.ts.map +1 -0
- package/dist/lib/selection-proxy.js +12 -0
- package/dist/lib/slab-polygon.d.ts +31 -2
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +525 -31
- package/dist/lib/slab-polygon.test.d.ts +2 -0
- package/dist/lib/slab-polygon.test.d.ts.map +1 -0
- package/dist/lib/slab-polygon.test.js +635 -0
- package/dist/lib/slots.d.ts +14 -0
- package/dist/lib/slots.d.ts.map +1 -0
- package/dist/lib/slots.js +26 -0
- package/dist/lib/space-detection-pause.test.d.ts +2 -0
- package/dist/lib/space-detection-pause.test.d.ts.map +1 -0
- package/dist/lib/space-detection-pause.test.js +42 -0
- package/dist/lib/space-detection.d.ts +54 -2
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +599 -124
- package/dist/lib/space-detection.test.d.ts +2 -0
- package/dist/lib/space-detection.test.d.ts.map +1 -0
- package/dist/lib/space-detection.test.js +376 -0
- package/dist/lib/wall-distance.d.ts +60 -0
- package/dist/lib/wall-distance.d.ts.map +1 -0
- package/dist/lib/wall-distance.js +85 -0
- package/dist/lib/zone-quantities.d.ts +21 -0
- package/dist/lib/zone-quantities.d.ts.map +1 -0
- package/dist/lib/zone-quantities.js +183 -0
- package/dist/lib/zone-quantities.test.d.ts +2 -0
- package/dist/lib/zone-quantities.test.d.ts.map +1 -0
- package/dist/lib/zone-quantities.test.js +82 -0
- package/dist/material-library.d.ts +20 -1
- package/dist/material-library.d.ts.map +1 -1
- package/dist/material-library.js +3737 -200
- package/dist/registry/__bench__/relations-resolver.bench.d.ts +15 -0
- package/dist/registry/__bench__/relations-resolver.bench.d.ts.map +1 -0
- package/dist/registry/__bench__/relations-resolver.bench.js +170 -0
- package/dist/registry/handles.d.ts +394 -0
- package/dist/registry/handles.d.ts.map +1 -0
- package/dist/registry/handles.js +24 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +4 -0
- package/dist/registry/registry.d.ts +136 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +282 -0
- package/dist/registry/registry.test.d.ts +2 -0
- package/dist/registry/registry.test.d.ts.map +1 -0
- package/dist/registry/registry.test.js +196 -0
- package/dist/registry/relations-resolver.d.ts +42 -0
- package/dist/registry/relations-resolver.d.ts.map +1 -0
- package/dist/registry/relations-resolver.js +77 -0
- package/dist/registry/relations-resolver.test.d.ts +2 -0
- package/dist/registry/relations-resolver.test.d.ts.map +1 -0
- package/dist/registry/relations-resolver.test.js +183 -0
- package/dist/registry/scene-api.d.ts +44 -0
- package/dist/registry/scene-api.d.ts.map +1 -0
- package/dist/registry/scene-api.js +111 -0
- package/dist/registry/scene-api.test.d.ts +2 -0
- package/dist/registry/scene-api.test.d.ts.map +1 -0
- package/dist/registry/scene-api.test.js +183 -0
- package/dist/registry/subtree.d.ts +67 -0
- package/dist/registry/subtree.d.ts.map +1 -0
- package/dist/registry/subtree.js +123 -0
- package/dist/registry/subtree.test.d.ts +2 -0
- package/dist/registry/subtree.test.d.ts.map +1 -0
- package/dist/registry/subtree.test.js +163 -0
- package/dist/registry/types.d.ts +2099 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +1 -0
- package/dist/schema/index.d.ts +35 -4
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +32 -4
- package/dist/schema/material.d.ts +13 -2
- package/dist/schema/material.d.ts.map +1 -1
- package/dist/schema/material.js +17 -5
- package/dist/schema/material.test.d.ts +2 -0
- package/dist/schema/material.test.d.ts.map +1 -0
- package/dist/schema/material.test.js +43 -0
- package/dist/schema/nodes/box-vent.d.ts +74 -0
- package/dist/schema/nodes/box-vent.d.ts.map +1 -0
- package/dist/schema/nodes/box-vent.js +63 -0
- package/dist/schema/nodes/building.d.ts +1 -1
- package/dist/schema/nodes/building.d.ts.map +1 -1
- package/dist/schema/nodes/building.js +3 -2
- package/dist/schema/nodes/cabinet.d.ts +534 -0
- package/dist/schema/nodes/cabinet.d.ts.map +1 -0
- package/dist/schema/nodes/cabinet.js +137 -0
- package/dist/schema/nodes/ceiling.d.ts +5 -2
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +5 -1
- package/dist/schema/nodes/chimney.d.ts +158 -0
- package/dist/schema/nodes/chimney.d.ts.map +1 -0
- package/dist/schema/nodes/chimney.js +67 -0
- package/dist/schema/nodes/column.d.ts +600 -7
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +589 -6
- package/dist/schema/nodes/cupola.d.ts +66 -0
- package/dist/schema/nodes/cupola.d.ts.map +1 -0
- package/dist/schema/nodes/cupola.js +28 -0
- package/dist/schema/nodes/door.d.ts +13 -5
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +12 -0
- package/dist/schema/nodes/dormer.d.ts +228 -0
- package/dist/schema/nodes/dormer.d.ts.map +1 -0
- package/dist/schema/nodes/dormer.js +119 -0
- package/dist/schema/nodes/downspout.d.ts +75 -0
- package/dist/schema/nodes/downspout.d.ts.map +1 -0
- package/dist/schema/nodes/downspout.js +63 -0
- package/dist/schema/nodes/duct-fitting.d.ts +91 -0
- package/dist/schema/nodes/duct-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/duct-fitting.js +92 -0
- package/dist/schema/nodes/duct-segment.d.ts +61 -0
- package/dist/schema/nodes/duct-segment.d.ts.map +1 -0
- package/dist/schema/nodes/duct-segment.js +73 -0
- package/dist/schema/nodes/duct-terminal.d.ts +57 -0
- package/dist/schema/nodes/duct-terminal.d.ts.map +1 -0
- package/dist/schema/nodes/duct-terminal.js +51 -0
- package/dist/schema/nodes/elevator.d.ts +106 -0
- package/dist/schema/nodes/elevator.d.ts.map +1 -0
- package/dist/schema/nodes/elevator.js +57 -0
- package/dist/schema/nodes/eyebrow-vent.d.ts +68 -0
- package/dist/schema/nodes/eyebrow-vent.d.ts.map +1 -0
- package/dist/schema/nodes/eyebrow-vent.js +40 -0
- package/dist/schema/nodes/fence.d.ts +19 -2
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +27 -2
- package/dist/schema/nodes/gutter.d.ts +84 -0
- package/dist/schema/nodes/gutter.d.ts.map +1 -0
- package/dist/schema/nodes/gutter.js +76 -0
- package/dist/schema/nodes/hvac-equipment.d.ts +63 -0
- package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -0
- package/dist/schema/nodes/hvac-equipment.js +55 -0
- package/dist/schema/nodes/item.d.ts +12 -0
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +20 -0
- package/dist/schema/nodes/level.d.ts +1 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +4 -0
- package/dist/schema/nodes/lineset.d.ts +42 -0
- package/dist/schema/nodes/lineset.d.ts.map +1 -0
- package/dist/schema/nodes/lineset.js +38 -0
- package/dist/schema/nodes/liquid-line.d.ts +34 -0
- package/dist/schema/nodes/liquid-line.d.ts.map +1 -0
- package/dist/schema/nodes/liquid-line.js +24 -0
- package/dist/schema/nodes/measurement.d.ts +306 -0
- package/dist/schema/nodes/measurement.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.js +87 -0
- package/dist/schema/nodes/measurement.test.d.ts +2 -0
- package/dist/schema/nodes/measurement.test.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.test.js +139 -0
- package/dist/schema/nodes/pipe-fitting.d.ts +56 -0
- package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-fitting.js +45 -0
- package/dist/schema/nodes/pipe-segment.d.ts +48 -0
- package/dist/schema/nodes/pipe-segment.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-segment.js +36 -0
- package/dist/schema/nodes/pipe-trap.d.ts +43 -0
- package/dist/schema/nodes/pipe-trap.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-trap.js +36 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +2 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +1 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.js +205 -0
- package/dist/schema/nodes/ridge-vent.d.ts +82 -0
- package/dist/schema/nodes/ridge-vent.d.ts.map +1 -0
- package/dist/schema/nodes/ridge-vent.js +248 -0
- package/dist/schema/nodes/roof-segment-shape.d.ts +90 -0
- package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.js +318 -0
- package/dist/schema/nodes/roof-segment-shape.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.test.js +175 -0
- package/dist/schema/nodes/roof-segment-surface.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-surface.test.js +48 -0
- package/dist/schema/nodes/roof-segment-trim.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-trim.test.js +107 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts +101 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.js +330 -0
- package/dist/schema/nodes/roof-segment-walls.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.test.js +92 -0
- package/dist/schema/nodes/roof-segment.d.ts +273 -3
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +539 -3
- package/dist/schema/nodes/roof.d.ts +8 -8
- package/dist/schema/nodes/roof.d.ts.map +1 -1
- package/dist/schema/nodes/roof.js +4 -16
- package/dist/schema/nodes/shelf.d.ts +106 -0
- package/dist/schema/nodes/shelf.d.ts.map +1 -0
- package/dist/schema/nodes/shelf.js +90 -0
- package/dist/schema/nodes/site.d.ts +1 -122
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/site.js +2 -6
- package/dist/schema/nodes/skylight.d.ts +279 -0
- package/dist/schema/nodes/skylight.d.ts.map +1 -0
- package/dist/schema/nodes/skylight.js +152 -0
- package/dist/schema/nodes/slab.d.ts +5 -2
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +5 -1
- package/dist/schema/nodes/solar-panel.d.ts +117 -0
- package/dist/schema/nodes/solar-panel.d.ts.map +1 -0
- package/dist/schema/nodes/solar-panel.js +47 -0
- package/dist/schema/nodes/stair-segment.d.ts +4 -4
- package/dist/schema/nodes/stair.d.ts +13 -12
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +3 -0
- package/dist/schema/nodes/surface-hole-metadata.d.ts +2 -0
- package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -1
- package/dist/schema/nodes/surface-hole-metadata.js +3 -1
- package/dist/schema/nodes/turbine-vent.d.ts +68 -0
- package/dist/schema/nodes/turbine-vent.d.ts.map +1 -0
- package/dist/schema/nodes/turbine-vent.js +41 -0
- package/dist/schema/nodes/wall.d.ts +245 -6
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +257 -0
- package/dist/schema/nodes/wall.test.d.ts +2 -0
- package/dist/schema/nodes/wall.test.d.ts.map +1 -0
- package/dist/schema/nodes/wall.test.js +208 -0
- package/dist/schema/nodes/window.d.ts +11 -3
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +12 -0
- package/dist/schema/nodes/zone.d.ts +2 -0
- package/dist/schema/nodes/zone.d.ts.map +1 -1
- package/dist/schema/nodes/zone.js +6 -0
- package/dist/schema/scene-material.d.ts +41 -0
- package/dist/schema/scene-material.d.ts.map +1 -0
- package/dist/schema/scene-material.js +9 -0
- package/dist/schema/types.d.ts +2850 -655
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +49 -0
- package/dist/services/alignment-anchors.d.ts +100 -0
- package/dist/services/alignment-anchors.d.ts.map +1 -0
- package/dist/services/alignment-anchors.js +312 -0
- package/dist/services/alignment-anchors.test.d.ts +2 -0
- package/dist/services/alignment-anchors.test.d.ts.map +1 -0
- package/dist/services/alignment-anchors.test.js +383 -0
- package/dist/services/alignment.d.ts +131 -0
- package/dist/services/alignment.d.ts.map +1 -0
- package/dist/services/alignment.js +171 -0
- package/dist/services/alignment.test.d.ts +2 -0
- package/dist/services/alignment.test.d.ts.map +1 -0
- package/dist/services/alignment.test.js +92 -0
- package/dist/services/drag-session.d.ts +47 -0
- package/dist/services/drag-session.d.ts.map +1 -0
- package/dist/services/drag-session.js +100 -0
- package/dist/services/drag-session.test.d.ts +2 -0
- package/dist/services/drag-session.test.d.ts.map +1 -0
- package/dist/services/drag-session.test.js +219 -0
- package/dist/services/hosting.d.ts +88 -0
- package/dist/services/hosting.d.ts.map +1 -0
- package/dist/services/hosting.js +131 -0
- package/dist/services/hosting.test.d.ts +2 -0
- package/dist/services/hosting.test.d.ts.map +1 -0
- package/dist/services/hosting.test.js +230 -0
- package/dist/services/index.d.ts +13 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +12 -0
- package/dist/services/level-height.d.ts +28 -0
- package/dist/services/level-height.d.ts.map +1 -0
- package/dist/services/level-height.js +62 -0
- package/dist/services/movement.d.ts +48 -0
- package/dist/services/movement.d.ts.map +1 -0
- package/dist/services/movement.js +65 -0
- package/dist/services/movement.test.d.ts +2 -0
- package/dist/services/movement.test.d.ts.map +1 -0
- package/dist/services/movement.test.js +133 -0
- package/dist/services/opening-guides.d.ts +141 -0
- package/dist/services/opening-guides.d.ts.map +1 -0
- package/dist/services/opening-guides.js +267 -0
- package/dist/services/opening-guides.test.d.ts +2 -0
- package/dist/services/opening-guides.test.d.ts.map +1 -0
- package/dist/services/opening-guides.test.js +208 -0
- package/dist/services/port-connectivity.d.ts +115 -0
- package/dist/services/port-connectivity.d.ts.map +1 -0
- package/dist/services/port-connectivity.js +300 -0
- package/dist/services/port-connectivity.test.d.ts +2 -0
- package/dist/services/port-connectivity.test.d.ts.map +1 -0
- package/dist/services/port-connectivity.test.js +297 -0
- package/dist/services/riser-diagram.d.ts +40 -0
- package/dist/services/riser-diagram.d.ts.map +1 -0
- package/dist/services/riser-diagram.js +110 -0
- package/dist/services/riser-diagram.test.d.ts +2 -0
- package/dist/services/riser-diagram.test.d.ts.map +1 -0
- package/dist/services/riser-diagram.test.js +66 -0
- package/dist/services/single-undo-dance.test.d.ts +2 -0
- package/dist/services/single-undo-dance.test.d.ts.map +1 -0
- package/dist/services/single-undo-dance.test.js +210 -0
- package/dist/services/snap.d.ts +80 -0
- package/dist/services/snap.d.ts.map +1 -0
- package/dist/services/snap.js +140 -0
- package/dist/services/snap.test.d.ts +2 -0
- package/dist/services/snap.test.d.ts.map +1 -0
- package/dist/services/snap.test.js +137 -0
- package/dist/services/system-graph.d.ts +30 -0
- package/dist/services/system-graph.d.ts.map +1 -0
- package/dist/services/system-graph.js +164 -0
- package/dist/services/system-graph.test.d.ts +2 -0
- package/dist/services/system-graph.test.d.ts.map +1 -0
- package/dist/services/system-graph.test.js +138 -0
- package/dist/services/validate-dwv.d.ts +32 -0
- package/dist/services/validate-dwv.d.ts.map +1 -0
- package/dist/services/validate-dwv.js +118 -0
- package/dist/services/validate-dwv.test.d.ts +2 -0
- package/dist/services/validate-dwv.test.d.ts.map +1 -0
- package/dist/services/validate-dwv.test.js +109 -0
- package/dist/solar-panel-presets.d.ts +17 -0
- package/dist/solar-panel-presets.d.ts.map +1 -0
- package/dist/solar-panel-presets.js +43 -0
- package/dist/store/actions/node-actions.d.ts +14 -2
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +585 -15
- package/dist/store/actions/node-mutation-sanitize.test.d.ts +2 -0
- package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +1 -0
- package/dist/store/actions/node-mutation-sanitize.test.js +147 -0
- package/dist/store/actions/reparent.test.d.ts +2 -0
- package/dist/store/actions/reparent.test.d.ts.map +1 -0
- package/dist/store/actions/reparent.test.js +212 -0
- package/dist/store/actions/ridge-vent-update.test.d.ts +2 -0
- package/dist/store/actions/ridge-vent-update.test.d.ts.map +1 -0
- package/dist/store/actions/ridge-vent-update.test.js +264 -0
- package/dist/store/history-control.d.ts +11 -0
- package/dist/store/history-control.d.ts.map +1 -1
- package/dist/store/history-control.js +33 -0
- package/dist/store/use-interactive.d.ts +39 -0
- package/dist/store/use-interactive.d.ts.map +1 -1
- package/dist/store/use-interactive.js +75 -0
- package/dist/store/use-live-node-overrides.d.ts +22 -0
- package/dist/store/use-live-node-overrides.d.ts.map +1 -0
- package/dist/store/use-live-node-overrides.js +59 -0
- package/dist/store/use-scene-dirty-tracking.test.d.ts +2 -0
- package/dist/store/use-scene-dirty-tracking.test.d.ts.map +1 -0
- package/dist/store/use-scene-dirty-tracking.test.js +68 -0
- package/dist/store/use-scene-elevator-migration.test.d.ts +2 -0
- package/dist/store/use-scene-elevator-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-elevator-migration.test.js +109 -0
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts +2 -0
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +1 -0
- package/dist/store/use-scene-measurement-roundtrip.test.js +97 -0
- package/dist/store/use-scene-plugins.test.d.ts +2 -0
- package/dist/store/use-scene-plugins.test.d.ts.map +1 -0
- package/dist/store/use-scene-plugins.test.js +51 -0
- package/dist/store/use-scene-wall-slot-migration.test.d.ts +2 -0
- package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-wall-slot-migration.test.js +210 -0
- package/dist/store/use-scene-window-migration.test.d.ts +2 -0
- package/dist/store/use-scene-window-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-window-migration.test.js +85 -0
- package/dist/store/use-scene.d.ts +28 -2
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +546 -49
- package/dist/systems/elevator/elevator-dispatch.d.ts +12 -0
- package/dist/systems/elevator/elevator-dispatch.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-dispatch.js +57 -0
- package/dist/systems/elevator/elevator-geometry.d.ts +15 -0
- package/dist/systems/elevator/elevator-geometry.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-geometry.js +50 -0
- package/dist/systems/elevator/elevator-opening-sync.d.ts +6 -0
- package/dist/systems/elevator/elevator-opening-sync.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-opening-sync.js +218 -0
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts +2 -0
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-opening-sync.test.js +146 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts +2 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-opening-system.js +48 -0
- package/dist/systems/elevator/elevator-runtime-system.d.ts +2 -0
- package/dist/systems/elevator/elevator-runtime-system.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-runtime-system.js +8 -0
- package/dist/systems/elevator/elevator-runtime.d.ts +18 -0
- package/dist/systems/elevator/elevator-runtime.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-runtime.js +225 -0
- package/dist/systems/elevator/elevator-runtime.test.d.ts +2 -0
- package/dist/systems/elevator/elevator-runtime.test.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-runtime.test.js +64 -0
- package/dist/systems/elevator/elevator-service.d.ts +19 -0
- package/dist/systems/elevator/elevator-service.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-service.js +111 -0
- package/dist/systems/fence/fence-centerline.d.ts +12 -0
- package/dist/systems/fence/fence-centerline.d.ts.map +1 -0
- package/dist/systems/fence/fence-centerline.js +37 -0
- package/dist/systems/fence/fence-spline.d.ts +39 -0
- package/dist/systems/fence/fence-spline.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.js +196 -0
- package/dist/systems/fence/fence-spline.test.d.ts +2 -0
- package/dist/systems/fence/fence-spline.test.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.test.js +136 -0
- package/dist/systems/stair/stair-footprint.d.ts +44 -0
- package/dist/systems/stair/stair-footprint.d.ts.map +1 -0
- package/dist/systems/stair/stair-footprint.js +178 -0
- package/dist/systems/stair/stair-opening-preview.d.ts +2447 -0
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-preview.js +93 -0
- package/dist/systems/stair/stair-opening-preview.test.d.ts +2 -0
- package/dist/systems/stair/stair-opening-preview.test.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-preview.test.js +80 -0
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.js +155 -147
- package/dist/systems/stair/stair-opening-sync.test.js +424 -2
- package/dist/systems/stair/stair-opening-system.d.ts +2 -0
- package/dist/systems/stair/stair-opening-system.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-system.js +104 -0
- package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
- package/dist/systems/wall/wall-mitering.js +38 -2
- package/dist/systems/wall/wall-mitering.test.d.ts +2 -0
- package/dist/systems/wall/wall-mitering.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-mitering.test.js +63 -0
- package/dist/systems/wall/wall-move.d.ts +48 -0
- package/dist/systems/wall/wall-move.d.ts.map +1 -0
- package/dist/systems/wall/wall-move.js +193 -0
- package/dist/utils/clone-scene-graph.d.ts +7 -4
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +29 -7
- package/dist/utils/clone-scene-graph.test.d.ts +2 -0
- package/dist/utils/clone-scene-graph.test.d.ts.map +1 -0
- package/dist/utils/clone-scene-graph.test.js +62 -0
- package/dist/utils/heal-scene-graph.d.ts +18 -0
- package/dist/utils/heal-scene-graph.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.js +90 -0
- package/dist/utils/heal-scene-graph.test.d.ts +2 -0
- package/dist/utils/heal-scene-graph.test.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.test.js +88 -0
- package/dist/validation/validate-build-json.d.ts +44 -0
- package/dist/validation/validate-build-json.d.ts.map +1 -0
- package/dist/validation/validate-build-json.js +256 -0
- package/package.json +11 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stair-opening-preview.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC7E,OAA6B,EAAE,KAAK,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAGpE,KAAK,oBAAoB,GAAG;IAC1B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAA;CACtC,CAAA;AAoBD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,EAClD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,WAYvC;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,EAClD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwBvC;AAED,wBAAgB,qCAAqC;;mBAUlC,oBAAoB,EAAE;;EAiCxC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import useLiveNodeOverrides, {} from '../../store/use-live-node-overrides';
|
|
2
|
+
import useScene from '../../store/use-scene';
|
|
3
|
+
const SURFACE_OPENING_FIELDS = ['holes', 'holeMetadata'];
|
|
4
|
+
function isSurface(node) {
|
|
5
|
+
return node?.type === 'slab' || node?.type === 'ceiling';
|
|
6
|
+
}
|
|
7
|
+
function isStairOpeningInputNode(node) {
|
|
8
|
+
return node?.type === 'stair' || node?.type === 'stair-segment';
|
|
9
|
+
}
|
|
10
|
+
function omitPreviewSurfaceFields(override) {
|
|
11
|
+
const next = { ...override };
|
|
12
|
+
for (const field of SURFACE_OPENING_FIELDS) {
|
|
13
|
+
delete next[field];
|
|
14
|
+
}
|
|
15
|
+
return next;
|
|
16
|
+
}
|
|
17
|
+
export function hasLiveStairOpeningInputs(nodes, liveTransforms, liveOverrides, previewSurfaceIds) {
|
|
18
|
+
for (const nodeId of liveTransforms.keys()) {
|
|
19
|
+
if (nodes[nodeId]?.type === 'stair')
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
for (const [nodeId, override] of liveOverrides) {
|
|
23
|
+
if (previewSurfaceIds.has(nodeId))
|
|
24
|
+
continue;
|
|
25
|
+
if (Object.keys(override).length > 0 && isStairOpeningInputNode(nodes[nodeId]))
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
export function getNodesWithLiveStairOpeningInputs(nodes, liveTransforms, liveOverrides, previewSurfaceIds) {
|
|
31
|
+
const nextNodes = { ...nodes };
|
|
32
|
+
for (const [nodeId, override] of liveOverrides) {
|
|
33
|
+
const node = nextNodes[nodeId];
|
|
34
|
+
if (!node)
|
|
35
|
+
continue;
|
|
36
|
+
const values = previewSurfaceIds.has(nodeId) ? omitPreviewSurfaceFields(override) : override;
|
|
37
|
+
if (Object.keys(values).length === 0)
|
|
38
|
+
continue;
|
|
39
|
+
nextNodes[nodeId] = { ...node, ...values };
|
|
40
|
+
}
|
|
41
|
+
for (const [nodeId, transform] of liveTransforms) {
|
|
42
|
+
const node = nextNodes[nodeId];
|
|
43
|
+
if (node?.type !== 'stair')
|
|
44
|
+
continue;
|
|
45
|
+
nextNodes[nodeId] = {
|
|
46
|
+
...node,
|
|
47
|
+
position: transform.position,
|
|
48
|
+
rotation: transform.rotation,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return nextNodes;
|
|
52
|
+
}
|
|
53
|
+
export function createSurfaceOpeningPreviewController() {
|
|
54
|
+
const previewSurfaceIds = new Set();
|
|
55
|
+
const clearSurface = (id) => {
|
|
56
|
+
useLiveNodeOverrides.getState().clearFields(id, SURFACE_OPENING_FIELDS);
|
|
57
|
+
useScene.getState().markDirty(id);
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
previewSurfaceIds,
|
|
61
|
+
apply(updates) {
|
|
62
|
+
const scene = useScene.getState();
|
|
63
|
+
const nextSurfaceIds = new Set();
|
|
64
|
+
for (const update of updates) {
|
|
65
|
+
const node = scene.nodes[update.id];
|
|
66
|
+
if (!isSurface(node))
|
|
67
|
+
continue;
|
|
68
|
+
if (!('holes' in update.data || 'holeMetadata' in update.data))
|
|
69
|
+
continue;
|
|
70
|
+
nextSurfaceIds.add(update.id);
|
|
71
|
+
useLiveNodeOverrides.getState().set(update.id, {
|
|
72
|
+
holes: update.data.holes ?? [],
|
|
73
|
+
holeMetadata: update.data.holeMetadata ?? [],
|
|
74
|
+
});
|
|
75
|
+
scene.markDirty(update.id);
|
|
76
|
+
}
|
|
77
|
+
for (const id of previewSurfaceIds) {
|
|
78
|
+
if (!nextSurfaceIds.has(id))
|
|
79
|
+
clearSurface(id);
|
|
80
|
+
}
|
|
81
|
+
previewSurfaceIds.clear();
|
|
82
|
+
for (const id of nextSurfaceIds) {
|
|
83
|
+
previewSurfaceIds.add(id);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
clear() {
|
|
87
|
+
for (const id of previewSurfaceIds) {
|
|
88
|
+
clearSurface(id);
|
|
89
|
+
}
|
|
90
|
+
previewSurfaceIds.clear();
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stair-opening-preview.test.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-preview.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { BuildingNode, LevelNode, SlabNode, StairNode, StairSegmentNode } from '../../schema';
|
|
3
|
+
import { getNodesWithLiveStairOpeningInputs, hasLiveStairOpeningInputs, } from './stair-opening-preview';
|
|
4
|
+
import { syncAutoStairOpenings } from './stair-opening-sync';
|
|
5
|
+
describe('stair opening previews', () => {
|
|
6
|
+
test('computes auto openings from live stair transforms', () => {
|
|
7
|
+
const building = BuildingNode.parse({ name: 'Building' });
|
|
8
|
+
const ground = LevelNode.parse({ name: 'Ground', level: 0, parentId: building.id });
|
|
9
|
+
const upper = LevelNode.parse({ name: 'Upper', level: 1, parentId: building.id });
|
|
10
|
+
const slab = SlabNode.parse({
|
|
11
|
+
name: 'Upper Slab',
|
|
12
|
+
parentId: upper.id,
|
|
13
|
+
polygon: [
|
|
14
|
+
[0, 0],
|
|
15
|
+
[5, 0],
|
|
16
|
+
[5, 4],
|
|
17
|
+
[0, 4],
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
const segment = StairSegmentNode.parse({
|
|
21
|
+
parentId: 'stair_live',
|
|
22
|
+
width: 1,
|
|
23
|
+
length: 3,
|
|
24
|
+
height: 2.5,
|
|
25
|
+
stepCount: 12,
|
|
26
|
+
});
|
|
27
|
+
const stair = StairNode.parse({
|
|
28
|
+
id: 'stair_live',
|
|
29
|
+
name: 'Live Stair',
|
|
30
|
+
parentId: ground.id,
|
|
31
|
+
position: [1, 0, 0.2],
|
|
32
|
+
stairType: 'straight',
|
|
33
|
+
fromLevelId: ground.id,
|
|
34
|
+
toLevelId: upper.id,
|
|
35
|
+
slabOpeningMode: 'destination',
|
|
36
|
+
children: [segment.id],
|
|
37
|
+
});
|
|
38
|
+
const nodes = Object.fromEntries([building, ground, upper, slab, stair, { ...segment, parentId: stair.id }].map((node) => [
|
|
39
|
+
node.id,
|
|
40
|
+
node,
|
|
41
|
+
]));
|
|
42
|
+
const liveTransforms = new Map([
|
|
43
|
+
[stair.id, { position: [3, 0, 0.2], rotation: 0 }],
|
|
44
|
+
]);
|
|
45
|
+
const liveOverrides = new Map();
|
|
46
|
+
expect(hasLiveStairOpeningInputs(nodes, liveTransforms, liveOverrides, new Set())).toBe(true);
|
|
47
|
+
const previewNodes = getNodesWithLiveStairOpeningInputs(nodes, liveTransforms, liveOverrides, new Set());
|
|
48
|
+
const updates = syncAutoStairOpenings(previewNodes);
|
|
49
|
+
const hole = updates.find((update) => update.id === slab.id)?.data.holes?.[0];
|
|
50
|
+
expect(hole).toBeDefined();
|
|
51
|
+
expect(Math.max(...hole.map(([x]) => x))).toBeGreaterThan(3.4);
|
|
52
|
+
});
|
|
53
|
+
test('ignores its own live surface overrides as preview inputs', () => {
|
|
54
|
+
const slab = SlabNode.parse({
|
|
55
|
+
polygon: [
|
|
56
|
+
[0, 0],
|
|
57
|
+
[4, 0],
|
|
58
|
+
[4, 4],
|
|
59
|
+
[0, 4],
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
const nodes = { [slab.id]: slab };
|
|
63
|
+
const liveOverrides = new Map([
|
|
64
|
+
[
|
|
65
|
+
slab.id,
|
|
66
|
+
{
|
|
67
|
+
holes: [
|
|
68
|
+
[
|
|
69
|
+
[1, 1],
|
|
70
|
+
[2, 1],
|
|
71
|
+
[2, 2],
|
|
72
|
+
[1, 2],
|
|
73
|
+
],
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
]);
|
|
78
|
+
expect(hasLiveStairOpeningInputs(nodes, new Map(), liveOverrides, new Set([slab.id]))).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stair-opening-sync.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stair-opening-sync.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,QAAQ,EAIT,MAAM,cAAc,CAAA;AA0qBrB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;QAQvC,SAAS;UAAQ,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC;IAqG5E"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { resolveLevelId } from '../../hooks/spatial-grid/spatial-grid-sync';
|
|
1
|
+
import { resolveBuildingForLevel, resolveLevelId } from '../../hooks/spatial-grid/spatial-grid-sync';
|
|
2
|
+
import { polygonContainsPolygon, polygonsOverlap } from '../../lib/polygon-relations';
|
|
2
3
|
import { DEFAULT_WALL_HEIGHT } from '../wall/wall-footprint';
|
|
4
|
+
import { computeSegmentTransforms, rotateXZ } from './stair-footprint';
|
|
3
5
|
const CURVED_STAIR_SLAB_OPENING_RATIO = 0.8;
|
|
4
6
|
const STRAIGHT_STAIR_TARGET_THRESHOLD_MIN = 0.35;
|
|
5
7
|
const STAIR_SLAB_OPENING_TIGHTENING = 0;
|
|
@@ -30,99 +32,100 @@ function metadataEqual(left, right) {
|
|
|
30
32
|
if (left.length !== right.length)
|
|
31
33
|
return false;
|
|
32
34
|
return left.every((entry, index) => entry.source === right[index]?.source &&
|
|
35
|
+
(entry.elevatorId ?? null) === (right[index]?.elevatorId ?? null) &&
|
|
33
36
|
(entry.stairId ?? null) === (right[index]?.stairId ?? null));
|
|
34
37
|
}
|
|
35
38
|
function normalizeExistingMetadata(holes, metadata) {
|
|
36
39
|
return holes.map((_, index) => metadata?.[index] ?? { source: 'manual' });
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
const centroid = polygon.reduce((acc, [x, z]) => {
|
|
43
|
-
acc.x += x;
|
|
44
|
-
acc.z += z;
|
|
45
|
-
return acc;
|
|
46
|
-
}, { x: 0, z: 0 });
|
|
47
|
-
centroid.x /= Math.max(polygon.length, 1);
|
|
48
|
-
centroid.z /= Math.max(polygon.length, 1);
|
|
49
|
-
return polygon.map(([x, z]) => {
|
|
50
|
-
const dx = x - centroid.x;
|
|
51
|
-
const dz = z - centroid.z;
|
|
52
|
-
const length = Math.hypot(dx, dz);
|
|
53
|
-
if (length < 1e-6) {
|
|
54
|
-
return [x, z];
|
|
55
|
-
}
|
|
56
|
-
const scale = Math.max(0.1, (length + offset) / length);
|
|
57
|
-
return [centroid.x + dx * scale, centroid.z + dz * scale];
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
function rotateXZ(x, z, angle) {
|
|
61
|
-
const cos = Math.cos(angle);
|
|
62
|
-
const sin = Math.sin(angle);
|
|
63
|
-
return [x * cos + z * sin, -x * sin + z * cos];
|
|
64
|
-
}
|
|
65
|
-
function computeSegmentTransforms(segments) {
|
|
66
|
-
const transforms = [];
|
|
67
|
-
let currentX = 0;
|
|
68
|
-
let currentY = 0;
|
|
69
|
-
let currentZ = 0;
|
|
70
|
-
let currentRot = 0;
|
|
71
|
-
for (let index = 0; index < segments.length; index++) {
|
|
72
|
-
const segment = segments[index];
|
|
73
|
-
if (!segment)
|
|
74
|
-
continue;
|
|
75
|
-
if (index === 0) {
|
|
76
|
-
transforms.push({
|
|
77
|
-
position: [currentX, currentY, currentZ],
|
|
78
|
-
rotation: currentRot,
|
|
79
|
-
});
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
const previous = segments[index - 1];
|
|
83
|
-
if (!previous)
|
|
84
|
-
continue;
|
|
85
|
-
let attachX = 0;
|
|
86
|
-
let attachZ = 0;
|
|
87
|
-
let rotationDelta = 0;
|
|
88
|
-
switch (segment.attachmentSide) {
|
|
89
|
-
case 'front':
|
|
90
|
-
attachX = 0;
|
|
91
|
-
attachZ = previous.length;
|
|
92
|
-
break;
|
|
93
|
-
case 'left':
|
|
94
|
-
attachX = previous.width / 2;
|
|
95
|
-
attachZ = previous.length / 2;
|
|
96
|
-
rotationDelta = Math.PI / 2;
|
|
97
|
-
break;
|
|
98
|
-
case 'right':
|
|
99
|
-
attachX = -previous.width / 2;
|
|
100
|
-
attachZ = previous.length / 2;
|
|
101
|
-
rotationDelta = -Math.PI / 2;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
const [deltaX, deltaZ] = rotateXZ(attachX, attachZ, currentRot);
|
|
105
|
-
currentX += deltaX;
|
|
106
|
-
currentY += previous.height;
|
|
107
|
-
currentZ += deltaZ;
|
|
108
|
-
currentRot += rotationDelta;
|
|
109
|
-
transforms.push({
|
|
110
|
-
position: [currentX, currentY, currentZ],
|
|
111
|
-
rotation: currentRot,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
return transforms;
|
|
115
|
-
}
|
|
41
|
+
// (Removing expandPolygonRadially in favor of geometric expansion inside the polygon generators)
|
|
42
|
+
// `rotateXZ` + `computeSegmentTransforms` are shared with the alignment-anchor
|
|
43
|
+
// footprint via `./stair-footprint` so both derive the chain identically.
|
|
116
44
|
function getLevelNumber(levelId, nodes) {
|
|
117
45
|
if (!levelId)
|
|
118
46
|
return undefined;
|
|
119
47
|
const node = nodes[levelId];
|
|
120
48
|
return node?.type === 'level' ? node.level : undefined;
|
|
121
49
|
}
|
|
50
|
+
function getLevelBuildingId(levelId, nodes) {
|
|
51
|
+
if (!levelId)
|
|
52
|
+
return null;
|
|
53
|
+
return resolveBuildingForLevel(levelId, nodes);
|
|
54
|
+
}
|
|
55
|
+
function normalizeLevelId(levelId, nodes) {
|
|
56
|
+
if (!levelId)
|
|
57
|
+
return null;
|
|
58
|
+
return nodes[levelId]?.type === 'level' ? levelId : null;
|
|
59
|
+
}
|
|
60
|
+
function getBuildingLevels(buildingId, nodes) {
|
|
61
|
+
const building = buildingId ? nodes[buildingId] : null;
|
|
62
|
+
if (building?.type !== 'building')
|
|
63
|
+
return [];
|
|
64
|
+
const levels = new Map();
|
|
65
|
+
for (const childId of building.children ?? []) {
|
|
66
|
+
const child = nodes[childId];
|
|
67
|
+
if (child?.type === 'level')
|
|
68
|
+
levels.set(child.id, child);
|
|
69
|
+
}
|
|
70
|
+
for (const candidate of Object.values(nodes)) {
|
|
71
|
+
if (candidate?.type === 'level' && candidate.parentId === building.id) {
|
|
72
|
+
levels.set(candidate.id, candidate);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return Array.from(levels.values()).sort((left, right) => left.level - right.level);
|
|
76
|
+
}
|
|
77
|
+
function inferSourceLevelForDestination(destinationLevelId, nodes) {
|
|
78
|
+
if (!destinationLevelId)
|
|
79
|
+
return null;
|
|
80
|
+
const destination = nodes[destinationLevelId];
|
|
81
|
+
if (destination?.type !== 'level')
|
|
82
|
+
return null;
|
|
83
|
+
const buildingId = getLevelBuildingId(destinationLevelId, nodes);
|
|
84
|
+
return (getBuildingLevels(buildingId, nodes)
|
|
85
|
+
.filter((level) => level.level < destination.level)
|
|
86
|
+
.at(-1)?.id ?? null);
|
|
87
|
+
}
|
|
88
|
+
function inferDestinationLevelForSource(sourceLevelId, nodes) {
|
|
89
|
+
if (!sourceLevelId)
|
|
90
|
+
return null;
|
|
91
|
+
const source = nodes[sourceLevelId];
|
|
92
|
+
if (source?.type !== 'level')
|
|
93
|
+
return null;
|
|
94
|
+
const buildingId = getLevelBuildingId(sourceLevelId, nodes);
|
|
95
|
+
return (getBuildingLevels(buildingId, nodes).find((level) => level.level > source.level)?.id ?? null);
|
|
96
|
+
}
|
|
97
|
+
function levelsShareBuilding(leftLevelId, rightLevelId, nodes) {
|
|
98
|
+
if (!(leftLevelId && rightLevelId))
|
|
99
|
+
return true;
|
|
100
|
+
const leftBuildingId = getLevelBuildingId(leftLevelId, nodes);
|
|
101
|
+
const rightBuildingId = getLevelBuildingId(rightLevelId, nodes);
|
|
102
|
+
return !(leftBuildingId && rightBuildingId && leftBuildingId !== rightBuildingId);
|
|
103
|
+
}
|
|
104
|
+
function isInStairBuildingScope(stair, surfaceLevelId, nodes) {
|
|
105
|
+
const { fromLevelId, toLevelId } = getResolvedStairLevelIds(stair, nodes);
|
|
106
|
+
const fromBuildingId = getLevelBuildingId(fromLevelId, nodes);
|
|
107
|
+
const toBuildingId = getLevelBuildingId(toLevelId, nodes);
|
|
108
|
+
const surfaceBuildingId = getLevelBuildingId(surfaceLevelId, nodes);
|
|
109
|
+
if (fromBuildingId && toBuildingId && fromBuildingId !== toBuildingId)
|
|
110
|
+
return false;
|
|
111
|
+
if (fromBuildingId && surfaceBuildingId && fromBuildingId !== surfaceBuildingId)
|
|
112
|
+
return false;
|
|
113
|
+
if (toBuildingId && surfaceBuildingId && toBuildingId !== surfaceBuildingId)
|
|
114
|
+
return false;
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
122
117
|
function getResolvedStairLevelIds(stair, nodes) {
|
|
123
|
-
const parentLevelId = resolveLevelId(stair, nodes);
|
|
124
|
-
const
|
|
125
|
-
const
|
|
118
|
+
const parentLevelId = normalizeLevelId(resolveLevelId(stair, nodes), nodes);
|
|
119
|
+
const explicitToLevelId = normalizeLevelId(stair.toLevelId, nodes);
|
|
120
|
+
const fromLevelId = normalizeLevelId(stair.fromLevelId, nodes) ??
|
|
121
|
+
parentLevelId ??
|
|
122
|
+
inferSourceLevelForDestination(explicitToLevelId, nodes);
|
|
123
|
+
const explicitToLevelIsUsable = explicitToLevelId &&
|
|
124
|
+
explicitToLevelId !== fromLevelId &&
|
|
125
|
+
levelsShareBuilding(fromLevelId, explicitToLevelId, nodes);
|
|
126
|
+
const toLevelId = explicitToLevelIsUsable
|
|
127
|
+
? explicitToLevelId
|
|
128
|
+
: inferDestinationLevelForSource(fromLevelId, nodes);
|
|
126
129
|
return { fromLevelId, toLevelId };
|
|
127
130
|
}
|
|
128
131
|
function resolveStraightSegments(stair, nodes) {
|
|
@@ -179,7 +182,7 @@ function getStraightSegmentSlicePolygon(stair, layout, startAlong, endAlong) {
|
|
|
179
182
|
}
|
|
180
183
|
function getStraightFlightOpeningDepth(stair, segment) {
|
|
181
184
|
const treadDepth = Math.max(0.2, segment.length / Math.max(segment.stepCount || stair.stepCount || 10, 1));
|
|
182
|
-
return Math.min(segment.length, Math.max(treadDepth *
|
|
185
|
+
return Math.min(segment.length, Math.max(treadDepth * 10, segment.length * 0.8, 3.0));
|
|
183
186
|
}
|
|
184
187
|
function polygonArea(points) {
|
|
185
188
|
let area = 0;
|
|
@@ -192,34 +195,8 @@ function polygonArea(points) {
|
|
|
192
195
|
}
|
|
193
196
|
return area / 2;
|
|
194
197
|
}
|
|
195
|
-
function
|
|
196
|
-
|
|
197
|
-
if (Math.abs(cross) > tolerance)
|
|
198
|
-
return false;
|
|
199
|
-
const dot = (point[0] - a[0]) * (b[0] - a[0]) + (point[1] - a[1]) * (b[1] - a[1]);
|
|
200
|
-
if (dot < -tolerance)
|
|
201
|
-
return false;
|
|
202
|
-
const lenSq = (b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2;
|
|
203
|
-
return dot <= lenSq + tolerance;
|
|
204
|
-
}
|
|
205
|
-
function pointInPolygon(point, polygon) {
|
|
206
|
-
if (polygon.length < 3)
|
|
207
|
-
return false;
|
|
208
|
-
let inside = false;
|
|
209
|
-
const [x, z] = point;
|
|
210
|
-
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
211
|
-
const a = polygon[i];
|
|
212
|
-
const b = polygon[j];
|
|
213
|
-
if (pointOnSegment(point, a, b))
|
|
214
|
-
return true;
|
|
215
|
-
const intersects = a[1] > z !== b[1] > z && x < ((b[0] - a[0]) * (z - a[1])) / (b[1] - a[1]) + a[0];
|
|
216
|
-
if (intersects)
|
|
217
|
-
inside = !inside;
|
|
218
|
-
}
|
|
219
|
-
return inside;
|
|
220
|
-
}
|
|
221
|
-
function polygonContainsPolygon(outer, inner) {
|
|
222
|
-
return inner.every((point) => pointInPolygon(point, outer));
|
|
198
|
+
function isCoveredByExistingHole(existingHoles, autoHole) {
|
|
199
|
+
return existingHoles.some((existingHole) => polygonContainsPolygon(existingHole, autoHole));
|
|
223
200
|
}
|
|
224
201
|
function getAxisAlignedRectFromPolygon(polygon) {
|
|
225
202
|
if (polygon.length < 4)
|
|
@@ -318,13 +295,15 @@ function buildUnionPolygonsFromRects(rects) {
|
|
|
318
295
|
}
|
|
319
296
|
return polygons;
|
|
320
297
|
}
|
|
321
|
-
function getCurvedOpeningPolygon(stair) {
|
|
298
|
+
function getCurvedOpeningPolygon(stair, offset = 0) {
|
|
322
299
|
const width = Math.max(stair.width ?? 1, 0.4);
|
|
323
|
-
const innerRadius = Math.max(0.
|
|
324
|
-
const outerRadius = innerRadius + width;
|
|
300
|
+
const innerRadius = Math.max(0.01, (stair.innerRadius ?? 0.9) - offset);
|
|
301
|
+
const outerRadius = (stair.innerRadius ?? 0.9) + width + offset;
|
|
325
302
|
const totalSweep = stair.sweepAngle ?? Math.PI / 2;
|
|
326
|
-
const
|
|
327
|
-
Math.max(
|
|
303
|
+
const baseOpeningSweep = Math.abs(totalSweep) *
|
|
304
|
+
Math.max(CURVED_STAIR_SLAB_OPENING_RATIO, 1 / Math.max(stair.stepCount ?? 1, 1));
|
|
305
|
+
const angleOffset = offset / Math.max(innerRadius, 0.1);
|
|
306
|
+
const openingSweep = Math.sign(totalSweep || 1) * Math.min(Math.abs(totalSweep), baseOpeningSweep + angleOffset * 2);
|
|
328
307
|
const startAngle = totalSweep / 2 - openingSweep;
|
|
329
308
|
const endAngle = totalSweep / 2;
|
|
330
309
|
const segmentCount = Math.max(10, Math.min(32, Math.ceil(Math.abs(openingSweep) / (Math.PI / 24) + Math.max(stair.stepCount ?? 1, 1) * 0.5)));
|
|
@@ -342,21 +321,21 @@ function getCurvedOpeningPolygon(stair) {
|
|
|
342
321
|
}
|
|
343
322
|
return [...outerPoints, ...innerPoints];
|
|
344
323
|
}
|
|
345
|
-
function getSpiralOpeningPolygon(stair) {
|
|
346
|
-
const radius = Math.max(0.05, stair.innerRadius ?? 0.9) + Math.max(stair.width ?? 1, 0.4);
|
|
324
|
+
function getSpiralOpeningPolygon(stair, offset = 0) {
|
|
325
|
+
const radius = Math.max(0.05, stair.innerRadius ?? 0.9) + Math.max(stair.width ?? 1, 0.4) + offset;
|
|
347
326
|
const segmentCount = 48;
|
|
348
327
|
return Array.from({ length: segmentCount }).map((_, index) => {
|
|
349
328
|
const angle = (index / segmentCount) * Math.PI * 2;
|
|
350
329
|
return toWorldPlanPoint(stair, Math.cos(angle) * radius, Math.sin(angle) * radius);
|
|
351
330
|
});
|
|
352
331
|
}
|
|
353
|
-
function getStraightOpeningPolygonsForSurface(stair, nodes, targetElevation) {
|
|
332
|
+
function getStraightOpeningPolygonsForSurface(stair, nodes, targetElevation, openingOffsetOverride) {
|
|
354
333
|
const layouts = getStraightStairLayouts(stair, nodes);
|
|
355
334
|
if (layouts.length === 0)
|
|
356
335
|
return [];
|
|
357
336
|
const riserHeight = (stair.totalRise ?? 2.5) / Math.max(stair.stepCount ?? 10, 1);
|
|
358
337
|
const targetThreshold = Math.max(riserHeight * 2, STRAIGHT_STAIR_TARGET_THRESHOLD_MIN);
|
|
359
|
-
const openingOffset = Math.max(stair.openingOffset ?? 0, 0);
|
|
338
|
+
const openingOffset = Math.max(openingOffsetOverride ?? stair.openingOffset ?? 0, 0);
|
|
360
339
|
const openingRects = [];
|
|
361
340
|
for (let index = 0; index < layouts.length; index += 1) {
|
|
362
341
|
const layout = layouts[index];
|
|
@@ -409,20 +388,37 @@ function getStraightOpeningPolygonsForSurface(stair, nodes, targetElevation) {
|
|
|
409
388
|
}
|
|
410
389
|
return fallbackLayout ? [getStraightSegmentFootprintPolygon(stair, fallbackLayout)] : [];
|
|
411
390
|
}
|
|
412
|
-
function getStairOpeningPolygons(stair, nodes, targetElevation) {
|
|
391
|
+
function getStairOpeningPolygons(stair, nodes, targetElevation, openingOffsetOverride) {
|
|
413
392
|
if ((stair.slabOpeningMode ?? 'none') !== 'destination') {
|
|
414
393
|
return [];
|
|
415
394
|
}
|
|
395
|
+
const openingOffset = Math.max(openingOffsetOverride ?? stair.openingOffset ?? 0, 0);
|
|
416
396
|
if (stair.stairType === 'curved') {
|
|
417
|
-
return [
|
|
397
|
+
return [
|
|
398
|
+
getCurvedOpeningPolygon(stair, Math.max(openingOffset - STAIR_SLAB_OPENING_TIGHTENING, 0)),
|
|
399
|
+
];
|
|
418
400
|
}
|
|
419
401
|
if (stair.stairType === 'spiral') {
|
|
420
|
-
|
|
402
|
+
const offset = Math.max(openingOffset - STAIR_SLAB_OPENING_TIGHTENING, 0);
|
|
403
|
+
return [getSpiralOpeningPolygon(stair, offset)];
|
|
421
404
|
}
|
|
422
405
|
if (typeof targetElevation === 'number') {
|
|
423
|
-
return getStraightOpeningPolygonsForSurface(stair, nodes, targetElevation);
|
|
406
|
+
return getStraightOpeningPolygonsForSurface(stair, nodes, targetElevation, openingOffset);
|
|
424
407
|
}
|
|
425
|
-
return getStraightOpeningPolygonsForSurface(stair, nodes, Math.max(...getStraightStairLayouts(stair, nodes).map((layout) => layout.topElevation), 0));
|
|
408
|
+
return getStraightOpeningPolygonsForSurface(stair, nodes, Math.max(...getStraightStairLayouts(stair, nodes).map((layout) => layout.topElevation), 0), openingOffset);
|
|
409
|
+
}
|
|
410
|
+
function getApplicableStairOpeningPolygons(stair, nodes, targetElevation, surfacePolygon) {
|
|
411
|
+
const configuredOffset = Math.max(stair.openingOffset ?? 0, 0);
|
|
412
|
+
const polygons = getStairOpeningPolygons(stair, nodes, targetElevation, configuredOffset);
|
|
413
|
+
const overlappingPolygons = polygons.filter((polygon) => polygonsOverlap(surfacePolygon, polygon));
|
|
414
|
+
if (overlappingPolygons.length === polygons.length || configuredOffset <= 1e-6) {
|
|
415
|
+
return overlappingPolygons;
|
|
416
|
+
}
|
|
417
|
+
const fallbackPolygons = getStairOpeningPolygons(stair, nodes, targetElevation, 0);
|
|
418
|
+
const overlappingFallbackPolygons = fallbackPolygons.filter((polygon) => polygonsOverlap(surfacePolygon, polygon));
|
|
419
|
+
return overlappingFallbackPolygons.length === fallbackPolygons.length
|
|
420
|
+
? overlappingFallbackPolygons
|
|
421
|
+
: overlappingPolygons;
|
|
426
422
|
}
|
|
427
423
|
function getTargetSlabElevationForStair(stair, slab, slabLevelId, nodes) {
|
|
428
424
|
const { fromLevelId } = getResolvedStairLevelIds(stair, nodes);
|
|
@@ -451,6 +447,8 @@ function shouldApplyStairToSlab(stair, slabLevelId, nodes) {
|
|
|
451
447
|
const fromLevel = getLevelNumber(fromLevelId, nodes);
|
|
452
448
|
const toLevel = getLevelNumber(toLevelId, nodes);
|
|
453
449
|
const slabLevel = getLevelNumber(slabLevelId, nodes);
|
|
450
|
+
if (!isInStairBuildingScope(stair, slabLevelId, nodes))
|
|
451
|
+
return false;
|
|
454
452
|
if (slabLevel === undefined) {
|
|
455
453
|
return toLevelId === slabLevelId;
|
|
456
454
|
}
|
|
@@ -466,6 +464,8 @@ function shouldApplyStairToCeiling(stair, ceilingLevelId, nodes) {
|
|
|
466
464
|
const fromLevel = getLevelNumber(fromLevelId, nodes);
|
|
467
465
|
const toLevel = getLevelNumber(toLevelId, nodes);
|
|
468
466
|
const ceilingLevel = getLevelNumber(ceilingLevelId, nodes);
|
|
467
|
+
if (!isInStairBuildingScope(stair, ceilingLevelId, nodes))
|
|
468
|
+
return false;
|
|
469
469
|
if (ceilingLevel === undefined) {
|
|
470
470
|
return fromLevelId === ceilingLevelId;
|
|
471
471
|
}
|
|
@@ -485,24 +485,28 @@ export function syncAutoStairOpenings(nodes) {
|
|
|
485
485
|
const slabLevelId = resolveLevelId(slab, nodes);
|
|
486
486
|
const existingHoles = slab.holes ?? [];
|
|
487
487
|
const existingMetadata = normalizeExistingMetadata(existingHoles, slab.holeMetadata);
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
.filter((entry) => entry.source !== 'stair')
|
|
491
|
-
|
|
488
|
+
const preservedHoles = existingHoles
|
|
489
|
+
.map((polygon, index) => ({ metadata: existingMetadata[index], polygon }))
|
|
490
|
+
.filter((entry) => entry.metadata.source !== 'stair');
|
|
491
|
+
const preservedHolePolygons = preservedHoles.map((entry) => entry.polygon);
|
|
492
492
|
const stairHoles = stairs
|
|
493
493
|
.filter((stair) => shouldApplyStairToSlab(stair, slabLevelId, nodes))
|
|
494
|
-
.flatMap((stair) =>
|
|
495
|
-
polygon
|
|
496
|
-
? polygon
|
|
497
|
-
: expandPolygonFromCentroid(polygon, Math.max((stair.openingOffset ?? 0) - STAIR_SLAB_OPENING_TIGHTENING, 0)),
|
|
494
|
+
.flatMap((stair) => getApplicableStairOpeningPolygons(stair, nodes, getTargetSlabElevationForStair(stair, slab, slabLevelId, nodes), slab.polygon).map((polygon) => ({
|
|
495
|
+
polygon,
|
|
498
496
|
metadata: {
|
|
499
497
|
source: 'stair',
|
|
500
498
|
stairId: stair.id,
|
|
501
499
|
},
|
|
502
500
|
})))
|
|
503
|
-
.filter((hole) =>
|
|
504
|
-
const nextHoles = [
|
|
505
|
-
|
|
501
|
+
.filter((hole) => !isCoveredByExistingHole(preservedHolePolygons, hole.polygon));
|
|
502
|
+
const nextHoles = [
|
|
503
|
+
...preservedHoles.map((hole) => hole.polygon),
|
|
504
|
+
...stairHoles.map((hole) => hole.polygon),
|
|
505
|
+
];
|
|
506
|
+
const nextMetadata = [
|
|
507
|
+
...preservedHoles.map((hole) => ({ ...hole.metadata })),
|
|
508
|
+
...stairHoles.map((hole) => hole.metadata),
|
|
509
|
+
];
|
|
506
510
|
if (!(polygonsEqual(existingHoles, nextHoles) && metadataEqual(existingMetadata, nextMetadata))) {
|
|
507
511
|
updates.push({
|
|
508
512
|
id: slab.id,
|
|
@@ -517,24 +521,28 @@ export function syncAutoStairOpenings(nodes) {
|
|
|
517
521
|
const ceilingLevelId = resolveLevelId(ceiling, nodes);
|
|
518
522
|
const existingHoles = ceiling.holes ?? [];
|
|
519
523
|
const existingMetadata = normalizeExistingMetadata(existingHoles, ceiling.holeMetadata);
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
.filter((entry) => entry.source !== 'stair')
|
|
523
|
-
|
|
524
|
+
const preservedHoles = existingHoles
|
|
525
|
+
.map((polygon, index) => ({ metadata: existingMetadata[index], polygon }))
|
|
526
|
+
.filter((entry) => entry.metadata.source !== 'stair');
|
|
527
|
+
const preservedHolePolygons = preservedHoles.map((entry) => entry.polygon);
|
|
524
528
|
const stairHoles = stairs
|
|
525
529
|
.filter((stair) => shouldApplyStairToCeiling(stair, ceilingLevelId, nodes))
|
|
526
|
-
.flatMap((stair) =>
|
|
527
|
-
polygon
|
|
528
|
-
? polygon
|
|
529
|
-
: expandPolygonFromCentroid(polygon, Math.max((stair.openingOffset ?? 0) - STAIR_SLAB_OPENING_TIGHTENING, 0)),
|
|
530
|
+
.flatMap((stair) => getApplicableStairOpeningPolygons(stair, nodes, getTargetCeilingElevationForStair(stair, ceiling, ceilingLevelId, nodes), ceiling.polygon).map((polygon) => ({
|
|
531
|
+
polygon,
|
|
530
532
|
metadata: {
|
|
531
533
|
source: 'stair',
|
|
532
534
|
stairId: stair.id,
|
|
533
535
|
},
|
|
534
536
|
})))
|
|
535
|
-
.filter((hole) =>
|
|
536
|
-
const nextHoles = [
|
|
537
|
-
|
|
537
|
+
.filter((hole) => !isCoveredByExistingHole(preservedHolePolygons, hole.polygon));
|
|
538
|
+
const nextHoles = [
|
|
539
|
+
...preservedHoles.map((hole) => hole.polygon),
|
|
540
|
+
...stairHoles.map((hole) => hole.polygon),
|
|
541
|
+
];
|
|
542
|
+
const nextMetadata = [
|
|
543
|
+
...preservedHoles.map((hole) => ({ ...hole.metadata })),
|
|
544
|
+
...stairHoles.map((hole) => hole.metadata),
|
|
545
|
+
];
|
|
538
546
|
if (!(polygonsEqual(existingHoles, nextHoles) && metadataEqual(existingMetadata, nextMetadata))) {
|
|
539
547
|
updates.push({
|
|
540
548
|
id: ceiling.id,
|