@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AA6CnB,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA6ClB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAC7C,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACzC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
|
package/dist/schema/types.js
CHANGED
|
@@ -1,41 +1,90 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
|
+
import { BoxVentNode } from './nodes/box-vent';
|
|
2
3
|
import { BuildingNode } from './nodes/building';
|
|
4
|
+
import { CabinetModuleNode, CabinetNode } from './nodes/cabinet';
|
|
3
5
|
import { CeilingNode } from './nodes/ceiling';
|
|
6
|
+
import { ChimneyNode } from './nodes/chimney';
|
|
4
7
|
import { ColumnNode } from './nodes/column';
|
|
8
|
+
import { CupolaNode } from './nodes/cupola';
|
|
5
9
|
import { DoorNode } from './nodes/door';
|
|
10
|
+
import { DormerNode } from './nodes/dormer';
|
|
11
|
+
import { DownspoutNode } from './nodes/downspout';
|
|
12
|
+
import { DuctFittingNode } from './nodes/duct-fitting';
|
|
13
|
+
import { DuctSegmentNode } from './nodes/duct-segment';
|
|
14
|
+
import { DuctTerminalNode } from './nodes/duct-terminal';
|
|
15
|
+
import { ElevatorNode } from './nodes/elevator';
|
|
16
|
+
import { EyebrowVentNode } from './nodes/eyebrow-vent';
|
|
6
17
|
import { FenceNode } from './nodes/fence';
|
|
7
18
|
import { GuideNode } from './nodes/guide';
|
|
19
|
+
import { GutterNode } from './nodes/gutter';
|
|
20
|
+
import { HvacEquipmentNode } from './nodes/hvac-equipment';
|
|
8
21
|
import { ItemNode } from './nodes/item';
|
|
9
22
|
import { LevelNode } from './nodes/level';
|
|
23
|
+
import { LinesetNode } from './nodes/lineset';
|
|
24
|
+
import { LiquidLineNode } from './nodes/liquid-line';
|
|
25
|
+
import { MeasurementNode } from './nodes/measurement';
|
|
26
|
+
import { PipeFittingNode } from './nodes/pipe-fitting';
|
|
27
|
+
import { PipeSegmentNode } from './nodes/pipe-segment';
|
|
28
|
+
import { PipeTrapNode } from './nodes/pipe-trap';
|
|
29
|
+
import { RidgeVentNode } from './nodes/ridge-vent';
|
|
10
30
|
import { RoofNode } from './nodes/roof';
|
|
11
31
|
import { RoofSegmentNode } from './nodes/roof-segment';
|
|
12
32
|
import { ScanNode } from './nodes/scan';
|
|
33
|
+
import { ShelfNode } from './nodes/shelf';
|
|
13
34
|
import { SiteNode } from './nodes/site';
|
|
35
|
+
import { SkylightNode } from './nodes/skylight';
|
|
14
36
|
import { SlabNode } from './nodes/slab';
|
|
37
|
+
import { SolarPanelNode } from './nodes/solar-panel';
|
|
15
38
|
import { SpawnNode } from './nodes/spawn';
|
|
16
39
|
import { StairNode } from './nodes/stair';
|
|
17
40
|
import { StairSegmentNode } from './nodes/stair-segment';
|
|
41
|
+
import { TurbineVentNode } from './nodes/turbine-vent';
|
|
18
42
|
import { WallNode } from './nodes/wall';
|
|
19
43
|
import { WindowNode } from './nodes/window';
|
|
20
44
|
import { ZoneNode } from './nodes/zone';
|
|
21
45
|
export const AnyNode = z.discriminatedUnion('type', [
|
|
22
46
|
SiteNode,
|
|
23
47
|
BuildingNode,
|
|
48
|
+
ElevatorNode,
|
|
24
49
|
LevelNode,
|
|
25
50
|
ColumnNode,
|
|
26
51
|
WallNode,
|
|
27
52
|
FenceNode,
|
|
53
|
+
CabinetNode,
|
|
54
|
+
CabinetModuleNode,
|
|
28
55
|
ItemNode,
|
|
29
56
|
ZoneNode,
|
|
30
57
|
SlabNode,
|
|
31
58
|
CeilingNode,
|
|
32
59
|
RoofNode,
|
|
33
60
|
RoofSegmentNode,
|
|
61
|
+
ShelfNode,
|
|
34
62
|
StairNode,
|
|
35
63
|
StairSegmentNode,
|
|
36
64
|
ScanNode,
|
|
37
65
|
GuideNode,
|
|
66
|
+
MeasurementNode,
|
|
38
67
|
SpawnNode,
|
|
39
68
|
WindowNode,
|
|
40
69
|
DoorNode,
|
|
70
|
+
BoxVentNode,
|
|
71
|
+
RidgeVentNode,
|
|
72
|
+
TurbineVentNode,
|
|
73
|
+
CupolaNode,
|
|
74
|
+
EyebrowVentNode,
|
|
75
|
+
GutterNode,
|
|
76
|
+
ChimneyNode,
|
|
77
|
+
SolarPanelNode,
|
|
78
|
+
SkylightNode,
|
|
79
|
+
DormerNode,
|
|
80
|
+
DownspoutNode,
|
|
81
|
+
DuctSegmentNode,
|
|
82
|
+
DuctFittingNode,
|
|
83
|
+
DuctTerminalNode,
|
|
84
|
+
HvacEquipmentNode,
|
|
85
|
+
LinesetNode,
|
|
86
|
+
LiquidLineNode,
|
|
87
|
+
PipeSegmentNode,
|
|
88
|
+
PipeFittingNode,
|
|
89
|
+
PipeTrapNode,
|
|
41
90
|
]);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node → alignment-anchor adapters.
|
|
3
|
+
*
|
|
4
|
+
* `alignment.ts` is pure geometry and knows nothing about nodes. This
|
|
5
|
+
* module bridges the scene graph to it: it reads a floor-placed kind's
|
|
6
|
+
* footprint from the registry and turns it into the bbox anchors the
|
|
7
|
+
* resolver matches against. Kept out of `alignment.ts` so that file stays
|
|
8
|
+
* registry-free.
|
|
9
|
+
*
|
|
10
|
+
* All coordinates are XZ meters in the same frame as `node.position`
|
|
11
|
+
* (building-local for nodes inside a building). The 3D move producer works
|
|
12
|
+
* entirely in that frame, so the resulting guides line up with the cursor.
|
|
13
|
+
*/
|
|
14
|
+
import type { AnyNode } from '../schema/types';
|
|
15
|
+
import { type AlignmentAnchor } from './alignment';
|
|
16
|
+
export type FootprintAABB = {
|
|
17
|
+
minX: number;
|
|
18
|
+
minZ: number;
|
|
19
|
+
maxX: number;
|
|
20
|
+
maxZ: number;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Axis-aligned XZ bounding box of a rotated rectangle centred at
|
|
24
|
+
* `position`. Mirrors the rotated-corner math the spatial-grid manager
|
|
25
|
+
* uses (`getItemFootprint`) so alignment anchors coincide with the
|
|
26
|
+
* footprint used for collision / slab elevation.
|
|
27
|
+
*/
|
|
28
|
+
export declare function footprintAABBFrom(position: readonly [number, number, number], dimensions: readonly [number, number, number], rotationY: number): FootprintAABB;
|
|
29
|
+
/** XZ footprint AABB of a floor-placed node at its current position, or
|
|
30
|
+
* null for kinds without a usable footprint. */
|
|
31
|
+
export declare function footprintAABB(node: AnyNode): FootprintAABB | null;
|
|
32
|
+
/** XZ footprint AABB of a floor-placed node relocated so its centre sits at
|
|
33
|
+
* the proposed (x, z). `rotationY` overrides the node's footprint rotation
|
|
34
|
+
* (R/T bumps it before the scene commit lands). Null when no footprint. */
|
|
35
|
+
export declare function footprintAABBAt(node: AnyNode, x: number, z: number, rotationY?: number): FootprintAABB | null;
|
|
36
|
+
/**
|
|
37
|
+
* Corner anchors for the moving node's footprint relocated so its centre
|
|
38
|
+
* sits at the proposed (x, z). Corners only — the moving item aligns by its
|
|
39
|
+
* edges, never its centreline. Returns [] when the kind has no footprint.
|
|
40
|
+
*/
|
|
41
|
+
export declare function movingFootprintAnchors(node: AnyNode, x: number, z: number, rotationY?: number): AlignmentAnchor[];
|
|
42
|
+
/**
|
|
43
|
+
* Corner anchors for a moving node relocated to the proposed plan position.
|
|
44
|
+
* Covers both the centred-box path (`floorPlaced.footprint` /
|
|
45
|
+
* `alignmentFootprint: box`) and explicit AABB footprints such as stairs,
|
|
46
|
+
* whose occupied plan bounds depend on children or curved/spiral geometry.
|
|
47
|
+
*/
|
|
48
|
+
export declare function movingAlignmentAnchors(node: AnyNode, nodes: Readonly<Record<string, AnyNode>> | undefined, x: number, z: number, rotationY?: number): AlignmentAnchor[];
|
|
49
|
+
/**
|
|
50
|
+
* Alignment anchors for a wall segment: the two centerline endpoints + chord
|
|
51
|
+
* midpoint, plus — when `thickness` is known — four **face** corner anchors,
|
|
52
|
+
* each endpoint offset by ±thickness/2 perpendicular to the wall axis.
|
|
53
|
+
*
|
|
54
|
+
* The face anchors are what let a footprint align to a wall's *face* rather
|
|
55
|
+
* than its centerline: for an axis-aligned wall the two same-side face
|
|
56
|
+
* anchors share a constant X (vertical wall) or Z (horizontal wall) running
|
|
57
|
+
* the wall's full length, so the point-to-point resolver snaps a moving
|
|
58
|
+
* corner flush to the face anywhere along the wall (the perpendicular
|
|
59
|
+
* tie-break connects the guide to the nearer face endpoint). A diagonal wall
|
|
60
|
+
* gets only its face/centerline endpoints — point-to-point can't represent a
|
|
61
|
+
* sloped face line; that's an accepted v1 limitation.
|
|
62
|
+
*
|
|
63
|
+
* Curve offset is ignored — endpoints are exact and the chord midpoint is
|
|
64
|
+
* good enough for v1. Coordinates are the wall's `start` / `end`
|
|
65
|
+
* (building-local XZ meters).
|
|
66
|
+
*/
|
|
67
|
+
export declare function wallSegmentAnchors(id: string, start: readonly [number, number], end: readonly [number, number], thickness?: number): AlignmentAnchor[];
|
|
68
|
+
/** Each vertex of a polygon (slab / ceiling footprint) as a `corner` anchor. */
|
|
69
|
+
export declare function polygonAnchors(id: string, points: readonly (readonly [number, number])[]): AlignmentAnchor[];
|
|
70
|
+
/**
|
|
71
|
+
* Alignment anchors a node contributes to the candidate pool, dispatched by
|
|
72
|
+
* kind: walls / fences → segment endpoints + midpoint; slabs / ceilings →
|
|
73
|
+
* polygon vertices; everything else → the corners of its plan bounding box
|
|
74
|
+
* (`alignmentAABB`, which covers floor-placed kinds, the elevator's
|
|
75
|
+
* alignment box, and the stair's chain / sector footprint). Kinds with no
|
|
76
|
+
* usable footprint contribute nothing.
|
|
77
|
+
*
|
|
78
|
+
* `nodes` is needed only by kinds whose footprint walks siblings / children
|
|
79
|
+
* (a straight stair's `stair-segment` chain); every other kind derives its
|
|
80
|
+
* anchors from `node` alone.
|
|
81
|
+
*/
|
|
82
|
+
export declare function nodeAlignmentAnchors(node: AnyNode, nodes?: Readonly<Record<string, AnyNode>>): AlignmentAnchor[];
|
|
83
|
+
/**
|
|
84
|
+
* Anchors from every alignable node except `excludeId` — the unified
|
|
85
|
+
* candidate pool every move / placement tool resolves against, so any
|
|
86
|
+
* draggable object can align to any other (items, walls, fences, slabs,
|
|
87
|
+
* ceilings, columns).
|
|
88
|
+
*
|
|
89
|
+
* When `levelId` is given, nodes that belong to a *different* level are
|
|
90
|
+
* dropped. Alignment is XZ-only, so without this a node directly below on
|
|
91
|
+
* another floor (e.g. the ground floor while you place on the first) would
|
|
92
|
+
* snap and draw a guide even though the two sit at different heights.
|
|
93
|
+
* Building-/site-scoped nodes with no level ancestor (e.g. an elevator
|
|
94
|
+
* shaft, which is parented to the building and spans every floor) resolve to
|
|
95
|
+
* null and stay in the pool so they align on any floor. The 2D floor-plan
|
|
96
|
+
* deliberately omits the filter — aligning a wall to the one directly below
|
|
97
|
+
* in plan is the whole point of the reference floor.
|
|
98
|
+
*/
|
|
99
|
+
export declare function collectAlignmentAnchors(nodes: Readonly<Record<string, AnyNode>>, excludeId: string, levelId?: string | null): AlignmentAnchor[];
|
|
100
|
+
//# sourceMappingURL=alignment-anchors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alignment-anchors.d.ts","sourceRoot":"","sources":["../../src/services/alignment-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,aAAa,CAAA;AAErE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC3C,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7C,SAAS,EAAE,MAAM,GAChB,aAAa,CA4Bf;AAwDD;iDACiD;AACjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAKjE;AAED;;4EAE4E;AAC5E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,OAAO,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,aAAa,GAAG,IAAI,CAItB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAInB;AAoBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACpD,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAuBnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAwBnB;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAC7C,eAAe,EAAE,CAEnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,eAAe,EAAE,CAqDnB;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,eAAe,EAAE,CAWnB"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node → alignment-anchor adapters.
|
|
3
|
+
*
|
|
4
|
+
* `alignment.ts` is pure geometry and knows nothing about nodes. This
|
|
5
|
+
* module bridges the scene graph to it: it reads a floor-placed kind's
|
|
6
|
+
* footprint from the registry and turns it into the bbox anchors the
|
|
7
|
+
* resolver matches against. Kept out of `alignment.ts` so that file stays
|
|
8
|
+
* registry-free.
|
|
9
|
+
*
|
|
10
|
+
* All coordinates are XZ meters in the same frame as `node.position`
|
|
11
|
+
* (building-local for nodes inside a building). The 3D move producer works
|
|
12
|
+
* entirely in that frame, so the resulting guides line up with the cursor.
|
|
13
|
+
*/
|
|
14
|
+
import { nodeRegistry } from '../registry';
|
|
15
|
+
import { DEFAULT_WALL_THICKNESS } from '../systems/wall/wall-footprint';
|
|
16
|
+
import { bboxCornerAnchors } from './alignment';
|
|
17
|
+
/**
|
|
18
|
+
* Axis-aligned XZ bounding box of a rotated rectangle centred at
|
|
19
|
+
* `position`. Mirrors the rotated-corner math the spatial-grid manager
|
|
20
|
+
* uses (`getItemFootprint`) so alignment anchors coincide with the
|
|
21
|
+
* footprint used for collision / slab elevation.
|
|
22
|
+
*/
|
|
23
|
+
export function footprintAABBFrom(position, dimensions, rotationY) {
|
|
24
|
+
const [x, , z] = position;
|
|
25
|
+
const [w, , d] = dimensions;
|
|
26
|
+
const halfW = w / 2;
|
|
27
|
+
const halfD = d / 2;
|
|
28
|
+
const cos = Math.cos(rotationY);
|
|
29
|
+
const sin = Math.sin(rotationY);
|
|
30
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
31
|
+
let minZ = Number.POSITIVE_INFINITY;
|
|
32
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
33
|
+
let maxZ = Number.NEGATIVE_INFINITY;
|
|
34
|
+
for (const [lx, lz] of [
|
|
35
|
+
[-halfW, -halfD],
|
|
36
|
+
[halfW, -halfD],
|
|
37
|
+
[halfW, halfD],
|
|
38
|
+
[-halfW, halfD],
|
|
39
|
+
]) {
|
|
40
|
+
const wx = x + (lx * cos - lz * sin);
|
|
41
|
+
const wz = z + (lx * sin + lz * cos);
|
|
42
|
+
if (wx < minX)
|
|
43
|
+
minX = wx;
|
|
44
|
+
if (wx > maxX)
|
|
45
|
+
maxX = wx;
|
|
46
|
+
if (wz < minZ)
|
|
47
|
+
minZ = wz;
|
|
48
|
+
if (wz > maxZ)
|
|
49
|
+
maxZ = wz;
|
|
50
|
+
}
|
|
51
|
+
return { minX, minZ, maxX, maxZ };
|
|
52
|
+
}
|
|
53
|
+
/** The relocatable box footprint for a node, or null when it has none
|
|
54
|
+
* (walls / slabs / polygon kinds) or the kind's predicate excludes it
|
|
55
|
+
* (e.g. a wall-attached item that doesn't rest on the floor).
|
|
56
|
+
*
|
|
57
|
+
* Box footprints come from one of two capabilities: `floorPlaced` (kinds
|
|
58
|
+
* whose Y is also slab-lifted — columns, items) or `alignmentFootprint`
|
|
59
|
+
* with a `box` shape (kinds that align by their footprint but aren't
|
|
60
|
+
* floor-coupled — the elevator's outer shaft). A kind whose
|
|
61
|
+
* `alignmentFootprint` is an `aabb` (stair) has no centred box, so it's
|
|
62
|
+
* resolved directly in `nodeAlignmentAnchors`, not here. */
|
|
63
|
+
function floorFootprint(node) {
|
|
64
|
+
const capabilities = nodeRegistry.get(node.type)?.capabilities;
|
|
65
|
+
const floorPlaced = capabilities?.floorPlaced;
|
|
66
|
+
// `footprint` is optional now that floor-placed kinds may instead declare
|
|
67
|
+
// composite `footprints` (e.g. stairs); those have no single centred box
|
|
68
|
+
// here, so fall through to `alignmentFootprint`.
|
|
69
|
+
if (floorPlaced?.footprint) {
|
|
70
|
+
if (floorPlaced.applies && !floorPlaced.applies(node))
|
|
71
|
+
return null;
|
|
72
|
+
return floorPlaced.footprint(node);
|
|
73
|
+
}
|
|
74
|
+
const alignment = capabilities?.alignmentFootprint?.(node);
|
|
75
|
+
if (alignment?.shape === 'box') {
|
|
76
|
+
return { dimensions: alignment.dimensions, rotation: alignment.rotation };
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* XZ bounding box a node occupies in plan, unifying the two non-structural
|
|
82
|
+
* sources: a relocatable box (`floorFootprint`, covering floor-placed kinds
|
|
83
|
+
* and the elevator's alignment box) and a kind that hands back an explicit
|
|
84
|
+
* `aabb` because its plan shape isn't a centred rectangle (stair). Returns
|
|
85
|
+
* null for kinds with neither.
|
|
86
|
+
*/
|
|
87
|
+
function alignmentAABB(node, nodes) {
|
|
88
|
+
const box = footprintAABB(node);
|
|
89
|
+
if (box)
|
|
90
|
+
return box;
|
|
91
|
+
const alignment = nodeRegistry.get(node.type)?.capabilities?.alignmentFootprint?.(node, nodes);
|
|
92
|
+
if (alignment?.shape === 'aabb') {
|
|
93
|
+
return {
|
|
94
|
+
minX: alignment.minX,
|
|
95
|
+
minZ: alignment.minZ,
|
|
96
|
+
maxX: alignment.maxX,
|
|
97
|
+
maxZ: alignment.maxZ,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/** XZ footprint AABB of a floor-placed node at its current position, or
|
|
103
|
+
* null for kinds without a usable footprint. */
|
|
104
|
+
export function footprintAABB(node) {
|
|
105
|
+
const fp = floorFootprint(node);
|
|
106
|
+
if (!fp)
|
|
107
|
+
return null;
|
|
108
|
+
const position = node.position ?? [0, 0, 0];
|
|
109
|
+
return footprintAABBFrom(position, fp.dimensions, fp.rotation[1] ?? 0);
|
|
110
|
+
}
|
|
111
|
+
/** XZ footprint AABB of a floor-placed node relocated so its centre sits at
|
|
112
|
+
* the proposed (x, z). `rotationY` overrides the node's footprint rotation
|
|
113
|
+
* (R/T bumps it before the scene commit lands). Null when no footprint. */
|
|
114
|
+
export function footprintAABBAt(node, x, z, rotationY) {
|
|
115
|
+
const fp = floorFootprint(node);
|
|
116
|
+
if (!fp)
|
|
117
|
+
return null;
|
|
118
|
+
return footprintAABBFrom([x, 0, z], fp.dimensions, rotationY ?? fp.rotation[1] ?? 0);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Corner anchors for the moving node's footprint relocated so its centre
|
|
122
|
+
* sits at the proposed (x, z). Corners only — the moving item aligns by its
|
|
123
|
+
* edges, never its centreline. Returns [] when the kind has no footprint.
|
|
124
|
+
*/
|
|
125
|
+
export function movingFootprintAnchors(node, x, z, rotationY) {
|
|
126
|
+
const aabb = footprintAABBAt(node, x, z, rotationY);
|
|
127
|
+
if (!aabb)
|
|
128
|
+
return [];
|
|
129
|
+
return bboxCornerAnchors(node.id, aabb.minX, aabb.minZ, aabb.maxX, aabb.maxZ);
|
|
130
|
+
}
|
|
131
|
+
function relocatedPlanNode(node, x, z, rotationY) {
|
|
132
|
+
const position = node.position;
|
|
133
|
+
const y = Array.isArray(position) && typeof position[1] === 'number' ? position[1] : 0;
|
|
134
|
+
const relocated = {
|
|
135
|
+
...node,
|
|
136
|
+
position: [x, y, z],
|
|
137
|
+
};
|
|
138
|
+
if (rotationY !== undefined && 'rotation' in node) {
|
|
139
|
+
const rotation = node.rotation;
|
|
140
|
+
relocated.rotation = Array.isArray(rotation)
|
|
141
|
+
? [rotation[0] ?? 0, rotationY, rotation[2] ?? 0]
|
|
142
|
+
: rotationY;
|
|
143
|
+
}
|
|
144
|
+
return relocated;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Corner anchors for a moving node relocated to the proposed plan position.
|
|
148
|
+
* Covers both the centred-box path (`floorPlaced.footprint` /
|
|
149
|
+
* `alignmentFootprint: box`) and explicit AABB footprints such as stairs,
|
|
150
|
+
* whose occupied plan bounds depend on children or curved/spiral geometry.
|
|
151
|
+
*/
|
|
152
|
+
export function movingAlignmentAnchors(node, nodes, x, z, rotationY) {
|
|
153
|
+
const box = footprintAABBAt(node, x, z, rotationY);
|
|
154
|
+
if (box)
|
|
155
|
+
return bboxCornerAnchors(node.id, box.minX, box.minZ, box.maxX, box.maxZ);
|
|
156
|
+
const alignment = nodeRegistry
|
|
157
|
+
.get(node.type)
|
|
158
|
+
?.capabilities?.alignmentFootprint?.(relocatedPlanNode(node, x, z, rotationY), nodes);
|
|
159
|
+
if (alignment?.shape === 'box') {
|
|
160
|
+
const aabb = footprintAABBFrom([x, 0, z], alignment.dimensions, alignment.rotation[1] ?? 0);
|
|
161
|
+
return bboxCornerAnchors(node.id, aabb.minX, aabb.minZ, aabb.maxX, aabb.maxZ);
|
|
162
|
+
}
|
|
163
|
+
if (alignment?.shape === 'aabb') {
|
|
164
|
+
return bboxCornerAnchors(node.id, alignment.minX, alignment.minZ, alignment.maxX, alignment.maxZ);
|
|
165
|
+
}
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Alignment anchors for a wall segment: the two centerline endpoints + chord
|
|
170
|
+
* midpoint, plus — when `thickness` is known — four **face** corner anchors,
|
|
171
|
+
* each endpoint offset by ±thickness/2 perpendicular to the wall axis.
|
|
172
|
+
*
|
|
173
|
+
* The face anchors are what let a footprint align to a wall's *face* rather
|
|
174
|
+
* than its centerline: for an axis-aligned wall the two same-side face
|
|
175
|
+
* anchors share a constant X (vertical wall) or Z (horizontal wall) running
|
|
176
|
+
* the wall's full length, so the point-to-point resolver snaps a moving
|
|
177
|
+
* corner flush to the face anywhere along the wall (the perpendicular
|
|
178
|
+
* tie-break connects the guide to the nearer face endpoint). A diagonal wall
|
|
179
|
+
* gets only its face/centerline endpoints — point-to-point can't represent a
|
|
180
|
+
* sloped face line; that's an accepted v1 limitation.
|
|
181
|
+
*
|
|
182
|
+
* Curve offset is ignored — endpoints are exact and the chord midpoint is
|
|
183
|
+
* good enough for v1. Coordinates are the wall's `start` / `end`
|
|
184
|
+
* (building-local XZ meters).
|
|
185
|
+
*/
|
|
186
|
+
export function wallSegmentAnchors(id, start, end, thickness) {
|
|
187
|
+
const anchors = [
|
|
188
|
+
{ nodeId: id, kind: 'corner', x: start[0], z: start[1] },
|
|
189
|
+
{ nodeId: id, kind: 'corner', x: end[0], z: end[1] },
|
|
190
|
+
{ nodeId: id, kind: 'center', x: (start[0] + end[0]) / 2, z: (start[1] + end[1]) / 2 },
|
|
191
|
+
];
|
|
192
|
+
if (thickness && thickness > 0) {
|
|
193
|
+
const dx = end[0] - start[0];
|
|
194
|
+
const dz = end[1] - start[1];
|
|
195
|
+
const len = Math.hypot(dx, dz);
|
|
196
|
+
if (len > 1e-6) {
|
|
197
|
+
// Perpendicular to the wall axis, scaled to half-thickness.
|
|
198
|
+
const half = thickness / 2;
|
|
199
|
+
const px = (-dz / len) * half;
|
|
200
|
+
const pz = (dx / len) * half;
|
|
201
|
+
for (const [bx, bz] of [start, end]) {
|
|
202
|
+
anchors.push({ nodeId: id, kind: 'corner', x: bx + px, z: bz + pz });
|
|
203
|
+
anchors.push({ nodeId: id, kind: 'corner', x: bx - px, z: bz - pz });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return anchors;
|
|
208
|
+
}
|
|
209
|
+
/** Each vertex of a polygon (slab / ceiling footprint) as a `corner` anchor. */
|
|
210
|
+
export function polygonAnchors(id, points) {
|
|
211
|
+
return points.map(([x, z]) => ({ nodeId: id, kind: 'corner', x, z }));
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Alignment anchors a node contributes to the candidate pool, dispatched by
|
|
215
|
+
* kind: walls / fences → segment endpoints + midpoint; slabs / ceilings →
|
|
216
|
+
* polygon vertices; everything else → the corners of its plan bounding box
|
|
217
|
+
* (`alignmentAABB`, which covers floor-placed kinds, the elevator's
|
|
218
|
+
* alignment box, and the stair's chain / sector footprint). Kinds with no
|
|
219
|
+
* usable footprint contribute nothing.
|
|
220
|
+
*
|
|
221
|
+
* `nodes` is needed only by kinds whose footprint walks siblings / children
|
|
222
|
+
* (a straight stair's `stair-segment` chain); every other kind derives its
|
|
223
|
+
* anchors from `node` alone.
|
|
224
|
+
*/
|
|
225
|
+
export function nodeAlignmentAnchors(node, nodes) {
|
|
226
|
+
if (node.type === 'wall' || node.type === 'fence') {
|
|
227
|
+
const seg = node;
|
|
228
|
+
// Wall thickness is schema-optional (falls back to the geometry default);
|
|
229
|
+
// fence always carries one. Either way, pass it through so faces align.
|
|
230
|
+
return wallSegmentAnchors(seg.id, seg.start, seg.end, seg.thickness ?? DEFAULT_WALL_THICKNESS);
|
|
231
|
+
}
|
|
232
|
+
if (node.type === 'slab' || node.type === 'ceiling') {
|
|
233
|
+
const poly = node.polygon;
|
|
234
|
+
return poly ? polygonAnchors(node.id, poly) : [];
|
|
235
|
+
}
|
|
236
|
+
const anchors = [];
|
|
237
|
+
// Box footprint (items, columns, shelves, stairs, …).
|
|
238
|
+
const aabb = alignmentAABB(node, nodes);
|
|
239
|
+
if (aabb) {
|
|
240
|
+
anchors.push(...bboxCornerAnchors(node.id, aabb.minX, aabb.minZ, aabb.maxX, aabb.maxZ));
|
|
241
|
+
}
|
|
242
|
+
// Polyline kinds (duct / pipe / lineset): every path vertex is an anchor,
|
|
243
|
+
// so anything dragged snaps to a run's ends and bends.
|
|
244
|
+
const path = node.path;
|
|
245
|
+
if (Array.isArray(path)) {
|
|
246
|
+
for (const p of path) {
|
|
247
|
+
anchors.push({ nodeId: node.id, kind: 'corner', x: p[0], z: p[2] });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Typed ports (fittings, equipment, terminals, run ends): connection points
|
|
251
|
+
// are natural alignment targets — line a new run up with an existing collar.
|
|
252
|
+
const ports = nodeRegistry.get(node.type)?.ports?.(node);
|
|
253
|
+
if (ports) {
|
|
254
|
+
for (const port of ports) {
|
|
255
|
+
anchors.push({ nodeId: node.id, kind: 'corner', x: port.position[0], z: port.position[2] });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Position-based kinds with no footprint (e.g. duct fittings): the origin
|
|
259
|
+
// itself is a useful centre anchor.
|
|
260
|
+
if (!aabb) {
|
|
261
|
+
const position = node.position;
|
|
262
|
+
if (Array.isArray(position)) {
|
|
263
|
+
anchors.push({ nodeId: node.id, kind: 'center', x: position[0], z: position[2] });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return anchors;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Resolve the level a node belongs to by walking its `parentId` chain, or
|
|
270
|
+
* null when it isn't under a level. Inlined here (rather than importing the
|
|
271
|
+
* spatial-grid `resolveLevelId`) to keep this services module free of
|
|
272
|
+
* hook / store dependencies.
|
|
273
|
+
*/
|
|
274
|
+
function resolveNodeLevelId(node, nodes) {
|
|
275
|
+
let current = node;
|
|
276
|
+
while (current) {
|
|
277
|
+
if (current.type === 'level')
|
|
278
|
+
return current.id;
|
|
279
|
+
current = current.parentId ? nodes[current.parentId] : undefined;
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Anchors from every alignable node except `excludeId` — the unified
|
|
285
|
+
* candidate pool every move / placement tool resolves against, so any
|
|
286
|
+
* draggable object can align to any other (items, walls, fences, slabs,
|
|
287
|
+
* ceilings, columns).
|
|
288
|
+
*
|
|
289
|
+
* When `levelId` is given, nodes that belong to a *different* level are
|
|
290
|
+
* dropped. Alignment is XZ-only, so without this a node directly below on
|
|
291
|
+
* another floor (e.g. the ground floor while you place on the first) would
|
|
292
|
+
* snap and draw a guide even though the two sit at different heights.
|
|
293
|
+
* Building-/site-scoped nodes with no level ancestor (e.g. an elevator
|
|
294
|
+
* shaft, which is parented to the building and spans every floor) resolve to
|
|
295
|
+
* null and stay in the pool so they align on any floor. The 2D floor-plan
|
|
296
|
+
* deliberately omits the filter — aligning a wall to the one directly below
|
|
297
|
+
* in plan is the whole point of the reference floor.
|
|
298
|
+
*/
|
|
299
|
+
export function collectAlignmentAnchors(nodes, excludeId, levelId) {
|
|
300
|
+
const anchors = [];
|
|
301
|
+
for (const node of Object.values(nodes)) {
|
|
302
|
+
if (!node || node.id === excludeId)
|
|
303
|
+
continue;
|
|
304
|
+
if (levelId) {
|
|
305
|
+
const nodeLevelId = resolveNodeLevelId(node, nodes);
|
|
306
|
+
if (nodeLevelId !== null && nodeLevelId !== levelId)
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
anchors.push(...nodeAlignmentAnchors(node, nodes));
|
|
310
|
+
}
|
|
311
|
+
return anchors;
|
|
312
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alignment-anchors.test.d.ts","sourceRoot":"","sources":["../../src/services/alignment-anchors.test.ts"],"names":[],"mappings":""}
|