@pascal-app/core 0.9.2 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -10
- package/dist/events/bus.d.ts +21 -2
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +17 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.js +61 -8
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +116 -66
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +316 -441
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +46 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +193 -12
- package/dist/hooks/spatial-grid/support-host-id.d.ts +3 -0
- package/dist/hooks/spatial-grid/support-host-id.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/support-host-id.js +2 -0
- package/dist/hooks/spatial-grid/support-host-patch.d.ts +51 -0
- package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/support-host-patch.js +164 -0
- package/dist/index.d.ts +23 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -10
- package/dist/lib/measurement-geometry.d.ts +4 -0
- package/dist/lib/measurement-geometry.d.ts.map +1 -1
- package/dist/lib/measurement-geometry.js +27 -10
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +33 -1
- package/dist/lib/space-detection.d.ts +15 -4
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +174 -88
- package/dist/lib/terrain-brush.d.ts +163 -0
- package/dist/lib/terrain-brush.d.ts.map +1 -0
- package/dist/lib/terrain-brush.js +359 -0
- package/dist/lib/terrain-codec.d.ts +51 -0
- package/dist/lib/terrain-codec.d.ts.map +1 -0
- package/dist/lib/terrain-codec.js +167 -0
- package/dist/lib/terrain-field.d.ts +150 -0
- package/dist/lib/terrain-field.d.ts.map +1 -0
- package/dist/lib/terrain-field.js +248 -0
- package/dist/lib/terrain-raycast.d.ts +44 -0
- package/dist/lib/terrain-raycast.d.ts.map +1 -0
- package/dist/lib/terrain-raycast.js +188 -0
- package/dist/lib/terrain-source.d.ts +60 -0
- package/dist/lib/terrain-source.d.ts.map +1 -0
- package/dist/lib/terrain-source.js +90 -0
- package/dist/lib/terrain-support.d.ts +60 -0
- package/dist/lib/terrain-support.d.ts.map +1 -0
- package/dist/lib/terrain-support.js +150 -0
- package/dist/lib/zone-quantities.d.ts +1 -1
- package/dist/lib/zone-quantities.d.ts.map +1 -1
- package/dist/lib/zone-quantities.js +311 -66
- package/dist/material-library.d.ts +9 -1
- package/dist/material-library.d.ts.map +1 -1
- package/dist/material-library.js +56 -4
- package/dist/registry/handles.d.ts +16 -1
- package/dist/registry/handles.d.ts.map +1 -1
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/subtree.d.ts.map +1 -1
- package/dist/registry/subtree.js +5 -2
- package/dist/registry/types.d.ts +64 -1
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/schema/index.d.ts +6 -3
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +6 -3
- package/dist/schema/nodes/cabinet.d.ts +2 -0
- package/dist/schema/nodes/cabinet.d.ts.map +1 -1
- package/dist/schema/nodes/cabinet.js +4 -2
- package/dist/schema/nodes/ceiling.d.ts +1 -1
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +7 -1
- package/dist/schema/nodes/column.d.ts +1 -0
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +2 -0
- package/dist/schema/nodes/construction-dimension.d.ts +195 -0
- package/dist/schema/nodes/construction-dimension.d.ts.map +1 -0
- package/dist/schema/nodes/construction-dimension.js +151 -0
- package/dist/schema/nodes/door.d.ts +29 -0
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +20 -0
- package/dist/schema/nodes/duct-terminal.d.ts +1 -0
- package/dist/schema/nodes/duct-terminal.d.ts.map +1 -1
- package/dist/schema/nodes/duct-terminal.js +2 -0
- package/dist/schema/nodes/fence.d.ts +2 -0
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +8 -0
- package/dist/schema/nodes/hvac-equipment.d.ts +1 -0
- package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -1
- package/dist/schema/nodes/hvac-equipment.js +2 -0
- package/dist/schema/nodes/item.d.ts +1 -0
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +13 -0
- package/dist/schema/nodes/level.d.ts +2 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +12 -33
- package/dist/schema/nodes/shelf.d.ts +1 -0
- package/dist/schema/nodes/shelf.d.ts.map +1 -1
- package/dist/schema/nodes/shelf.js +2 -0
- package/dist/schema/nodes/site.d.ts +9 -0
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/site.js +8 -6
- package/dist/schema/nodes/slab.d.ts +5 -0
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +14 -2
- package/dist/schema/nodes/spawn.d.ts +1 -0
- package/dist/schema/nodes/spawn.d.ts.map +1 -1
- package/dist/schema/nodes/spawn.js +2 -0
- package/dist/schema/nodes/stair.d.ts +3 -1
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +8 -1
- package/dist/schema/nodes/structural-grid.d.ts +27 -0
- package/dist/schema/nodes/structural-grid.d.ts.map +1 -0
- package/dist/schema/nodes/structural-grid.js +17 -0
- package/dist/schema/nodes/wall.d.ts +5 -2
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +13 -4
- package/dist/schema/nodes/window.d.ts +29 -0
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +18 -0
- package/dist/schema/nodes/zone.d.ts +20 -0
- package/dist/schema/nodes/zone.d.ts.map +1 -1
- package/dist/schema/nodes/zone.js +15 -0
- package/dist/schema/terrain.d.ts +28 -0
- package/dist/schema/terrain.d.ts.map +1 -0
- package/dist/schema/terrain.js +30 -0
- package/dist/schema/types.d.ts +211 -3
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +4 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts +80 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts.map +1 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.js +89 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -1
- package/dist/services/level-height.d.ts +8 -9
- package/dist/services/level-height.d.ts.map +1 -1
- package/dist/services/level-height.js +48 -16
- package/dist/services/storey.d.ts +103 -0
- package/dist/services/storey.d.ts.map +1 -0
- package/dist/services/storey.js +296 -0
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +47 -3
- package/dist/store/history-control.d.ts +20 -0
- package/dist/store/history-control.d.ts.map +1 -1
- package/dist/store/history-control.js +110 -13
- package/dist/store/use-live-terrain.d.ts +65 -0
- package/dist/store/use-live-terrain.d.ts.map +1 -0
- package/dist/store/use-live-terrain.js +31 -0
- package/dist/store/use-live-transforms.d.ts +8 -0
- package/dist/store/use-live-transforms.d.ts.map +1 -1
- package/dist/store/use-scene.d.ts +31 -2
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +638 -8
- package/dist/systems/elevator/elevator-opening-system.d.ts +1 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-opening-system.js +27 -21
- package/dist/systems/elevator/elevator-service.d.ts +0 -2
- package/dist/systems/elevator/elevator-service.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-service.js +2 -24
- package/dist/systems/slab/slab-placement.d.ts +11 -0
- package/dist/systems/slab/slab-placement.d.ts.map +1 -0
- package/dist/systems/slab/slab-placement.js +14 -0
- package/dist/systems/slab/slab-support.d.ts +137 -0
- package/dist/systems/slab/slab-support.d.ts.map +1 -0
- package/dist/systems/slab/slab-support.js +557 -0
- package/dist/systems/stair/stair-opening-preview.d.ts +1060 -935
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.js +18 -15
- package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-system.js +32 -4
- package/dist/systems/stair/stair-rise.d.ts +22 -0
- package/dist/systems/stair/stair-rise.d.ts.map +1 -0
- package/dist/systems/stair/stair-rise.js +79 -0
- package/dist/systems/wall/wall-curve.d.ts +10 -0
- package/dist/systems/wall/wall-curve.d.ts.map +1 -1
- package/dist/systems/wall/wall-curve.js +1 -1
- package/dist/systems/wall/wall-mitering.js +6 -6
- package/dist/systems/wall/wall-top.d.ts +40 -0
- package/dist/systems/wall/wall-top.d.ts.map +1 -0
- package/dist/systems/wall/wall-top.js +46 -0
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +34 -3
- package/dist/utils/heal-scene-graph.d.ts +1 -1
- package/dist/utils/heal-scene-graph.d.ts.map +1 -1
- package/dist/utils/heal-scene-graph.js +25 -9
- package/dist/validation/validate-build-json.d.ts +2 -0
- package/dist/validation/validate-build-json.d.ts.map +1 -1
- package/dist/validation/validate-build-json.js +59 -3
- package/package.json +2 -2
- package/dist/hooks/scene-registry/scene-registry.test.d.ts +0 -2
- package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +0 -1
- package/dist/hooks/scene-registry/scene-registry.test.js +0 -26
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +0 -2
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +0 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +0 -366
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +0 -2
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +0 -1
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +0 -363
- package/dist/lib/measurement-geometry.test.d.ts +0 -2
- package/dist/lib/measurement-geometry.test.d.ts.map +0 -1
- package/dist/lib/measurement-geometry.test.js +0 -102
- package/dist/lib/slab-polygon.test.d.ts +0 -2
- package/dist/lib/slab-polygon.test.d.ts.map +0 -1
- package/dist/lib/slab-polygon.test.js +0 -635
- package/dist/lib/space-detection-pause.test.d.ts +0 -2
- package/dist/lib/space-detection-pause.test.d.ts.map +0 -1
- package/dist/lib/space-detection-pause.test.js +0 -42
- package/dist/lib/space-detection.test.d.ts +0 -2
- package/dist/lib/space-detection.test.d.ts.map +0 -1
- package/dist/lib/space-detection.test.js +0 -376
- package/dist/lib/zone-quantities.test.d.ts +0 -2
- package/dist/lib/zone-quantities.test.d.ts.map +0 -1
- package/dist/lib/zone-quantities.test.js +0 -82
- package/dist/registry/registry.test.d.ts +0 -2
- package/dist/registry/registry.test.d.ts.map +0 -1
- package/dist/registry/registry.test.js +0 -196
- package/dist/registry/relations-resolver.test.d.ts +0 -2
- package/dist/registry/relations-resolver.test.d.ts.map +0 -1
- package/dist/registry/relations-resolver.test.js +0 -183
- package/dist/registry/scene-api.test.d.ts +0 -2
- package/dist/registry/scene-api.test.d.ts.map +0 -1
- package/dist/registry/scene-api.test.js +0 -183
- package/dist/registry/subtree.test.d.ts +0 -2
- package/dist/registry/subtree.test.d.ts.map +0 -1
- package/dist/registry/subtree.test.js +0 -163
- package/dist/schema/asset-url.test.d.ts +0 -2
- package/dist/schema/asset-url.test.d.ts.map +0 -1
- package/dist/schema/asset-url.test.js +0 -134
- package/dist/schema/material.test.d.ts +0 -2
- package/dist/schema/material.test.d.ts.map +0 -1
- package/dist/schema/material.test.js +0 -43
- package/dist/schema/nodes/measurement.test.d.ts +0 -2
- package/dist/schema/nodes/measurement.test.d.ts.map +0 -1
- package/dist/schema/nodes/measurement.test.js +0 -139
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +0 -2
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +0 -1
- package/dist/schema/nodes/ridge-vent-defaults.test.js +0 -205
- package/dist/schema/nodes/roof-segment-shape.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-shape.test.js +0 -175
- package/dist/schema/nodes/roof-segment-surface.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-surface.test.js +0 -48
- package/dist/schema/nodes/roof-segment-trim.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-trim.test.js +0 -107
- package/dist/schema/nodes/roof-segment-walls.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-walls.test.js +0 -92
- package/dist/schema/nodes/wall.test.d.ts +0 -2
- package/dist/schema/nodes/wall.test.d.ts.map +0 -1
- package/dist/schema/nodes/wall.test.js +0 -208
- package/dist/services/alignment-anchors.test.d.ts +0 -2
- package/dist/services/alignment-anchors.test.d.ts.map +0 -1
- package/dist/services/alignment-anchors.test.js +0 -383
- package/dist/services/alignment.test.d.ts +0 -2
- package/dist/services/alignment.test.d.ts.map +0 -1
- package/dist/services/alignment.test.js +0 -92
- package/dist/services/drag-session.test.d.ts +0 -2
- package/dist/services/drag-session.test.d.ts.map +0 -1
- package/dist/services/drag-session.test.js +0 -219
- package/dist/services/hosting.test.d.ts +0 -2
- package/dist/services/hosting.test.d.ts.map +0 -1
- package/dist/services/hosting.test.js +0 -230
- package/dist/services/movement.test.d.ts +0 -2
- package/dist/services/movement.test.d.ts.map +0 -1
- package/dist/services/movement.test.js +0 -133
- package/dist/services/opening-guides.test.d.ts +0 -2
- package/dist/services/opening-guides.test.d.ts.map +0 -1
- package/dist/services/opening-guides.test.js +0 -208
- package/dist/services/port-connectivity.test.d.ts +0 -2
- package/dist/services/port-connectivity.test.d.ts.map +0 -1
- package/dist/services/port-connectivity.test.js +0 -297
- package/dist/services/riser-diagram.test.d.ts +0 -2
- package/dist/services/riser-diagram.test.d.ts.map +0 -1
- package/dist/services/riser-diagram.test.js +0 -66
- package/dist/services/single-undo-dance.test.d.ts +0 -2
- package/dist/services/single-undo-dance.test.d.ts.map +0 -1
- package/dist/services/single-undo-dance.test.js +0 -210
- package/dist/services/snap.test.d.ts +0 -2
- package/dist/services/snap.test.d.ts.map +0 -1
- package/dist/services/snap.test.js +0 -137
- package/dist/services/system-graph.test.d.ts +0 -2
- package/dist/services/system-graph.test.d.ts.map +0 -1
- package/dist/services/system-graph.test.js +0 -138
- package/dist/services/validate-dwv.test.d.ts +0 -2
- package/dist/services/validate-dwv.test.d.ts.map +0 -1
- package/dist/services/validate-dwv.test.js +0 -109
- package/dist/store/actions/node-mutation-sanitize.test.d.ts +0 -2
- package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +0 -1
- package/dist/store/actions/node-mutation-sanitize.test.js +0 -147
- package/dist/store/actions/reparent.test.d.ts +0 -2
- package/dist/store/actions/reparent.test.d.ts.map +0 -1
- package/dist/store/actions/reparent.test.js +0 -212
- package/dist/store/actions/ridge-vent-update.test.d.ts +0 -2
- package/dist/store/actions/ridge-vent-update.test.d.ts.map +0 -1
- package/dist/store/actions/ridge-vent-update.test.js +0 -264
- package/dist/store/use-scene-dirty-tracking.test.d.ts +0 -2
- package/dist/store/use-scene-dirty-tracking.test.d.ts.map +0 -1
- package/dist/store/use-scene-dirty-tracking.test.js +0 -68
- package/dist/store/use-scene-elevator-migration.test.d.ts +0 -2
- package/dist/store/use-scene-elevator-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-elevator-migration.test.js +0 -109
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts +0 -2
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +0 -1
- package/dist/store/use-scene-measurement-roundtrip.test.js +0 -97
- package/dist/store/use-scene-plugins.test.d.ts +0 -2
- package/dist/store/use-scene-plugins.test.d.ts.map +0 -1
- package/dist/store/use-scene-plugins.test.js +0 -51
- package/dist/store/use-scene-wall-slot-migration.test.d.ts +0 -2
- package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-wall-slot-migration.test.js +0 -210
- package/dist/store/use-scene-window-migration.test.d.ts +0 -2
- package/dist/store/use-scene-window-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-window-migration.test.js +0 -85
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts +0 -2
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-opening-sync.test.js +0 -146
- package/dist/systems/elevator/elevator-runtime.test.d.ts +0 -2
- package/dist/systems/elevator/elevator-runtime.test.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-runtime.test.js +0 -64
- package/dist/systems/fence/fence-spline.test.d.ts +0 -2
- package/dist/systems/fence/fence-spline.test.d.ts.map +0 -1
- package/dist/systems/fence/fence-spline.test.js +0 -136
- package/dist/systems/stair/stair-opening-preview.test.d.ts +0 -2
- package/dist/systems/stair/stair-opening-preview.test.d.ts.map +0 -1
- package/dist/systems/stair/stair-opening-preview.test.js +0 -80
- package/dist/systems/stair/stair-opening-sync.test.d.ts +0 -2
- package/dist/systems/stair/stair-opening-sync.test.d.ts.map +0 -1
- package/dist/systems/stair/stair-opening-sync.test.js +0 -485
- package/dist/systems/wall/wall-mitering.test.d.ts +0 -2
- package/dist/systems/wall/wall-mitering.test.d.ts.map +0 -1
- package/dist/systems/wall/wall-mitering.test.js +0 -63
- package/dist/utils/clone-scene-graph.test.d.ts +0 -2
- package/dist/utils/clone-scene-graph.test.d.ts.map +0 -1
- package/dist/utils/clone-scene-graph.test.js +0 -62
- package/dist/utils/heal-scene-graph.test.d.ts +0 -2
- package/dist/utils/heal-scene-graph.test.d.ts.map +0 -1
- package/dist/utils/heal-scene-graph.test.js +0 -88
|
@@ -1 +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
|
|
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"}
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AA8qBrB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;QAQvC,SAAS;UAAQ,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC;IAqG5E"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { resolveBuildingForLevel, resolveLevelId } from '../../hooks/spatial-grid/spatial-grid-sync';
|
|
2
2
|
import { polygonContainsPolygon, polygonsOverlap } from '../../lib/polygon-relations';
|
|
3
|
-
import {
|
|
3
|
+
import { resolveCeilingHeight } from '../../services/level-height';
|
|
4
|
+
import { getLevelElevations } from '../../services/storey';
|
|
4
5
|
import { computeSegmentTransforms, rotateXZ } from './stair-footprint';
|
|
6
|
+
import { resolveStairTotalRise } from './stair-rise';
|
|
5
7
|
const CURVED_STAIR_SLAB_OPENING_RATIO = 0.8;
|
|
6
8
|
const STRAIGHT_STAIR_TARGET_THRESHOLD_MIN = 0.35;
|
|
7
9
|
const STAIR_SLAB_OPENING_TIGHTENING = 0;
|
|
@@ -333,7 +335,7 @@ function getStraightOpeningPolygonsForSurface(stair, nodes, targetElevation, ope
|
|
|
333
335
|
const layouts = getStraightStairLayouts(stair, nodes);
|
|
334
336
|
if (layouts.length === 0)
|
|
335
337
|
return [];
|
|
336
|
-
const riserHeight = (stair
|
|
338
|
+
const riserHeight = resolveStairTotalRise(stair, nodes) / Math.max(stair.stepCount ?? 10, 1);
|
|
337
339
|
const targetThreshold = Math.max(riserHeight * 2, STRAIGHT_STAIR_TARGET_THRESHOLD_MIN);
|
|
338
340
|
const openingOffset = Math.max(openingOffsetOverride ?? stair.openingOffset ?? 0, 0);
|
|
339
341
|
const openingRects = [];
|
|
@@ -422,25 +424,26 @@ function getApplicableStairOpeningPolygons(stair, nodes, targetElevation, surfac
|
|
|
422
424
|
}
|
|
423
425
|
function getTargetSlabElevationForStair(stair, slab, slabLevelId, nodes) {
|
|
424
426
|
const { fromLevelId } = getResolvedStairLevelIds(stair, nodes);
|
|
425
|
-
const
|
|
426
|
-
const
|
|
427
|
-
|
|
427
|
+
const elevations = getLevelElevations(nodes);
|
|
428
|
+
const fromElevation = fromLevelId ? elevations.get(fromLevelId) : undefined;
|
|
429
|
+
const slabElevation = elevations.get(slabLevelId);
|
|
430
|
+
if (!fromElevation || !slabElevation || fromElevation.buildingId !== slabElevation.buildingId) {
|
|
428
431
|
return slab.elevation ?? 0.05;
|
|
429
432
|
}
|
|
430
|
-
return (
|
|
431
|
-
(slab.elevation ?? 0.05) -
|
|
432
|
-
(stair.position[1] ?? 0));
|
|
433
|
+
return (slabElevation.baseY - fromElevation.baseY + (slab.elevation ?? 0.05) - (stair.position[1] ?? 0));
|
|
433
434
|
}
|
|
434
435
|
function getTargetCeilingElevationForStair(stair, ceiling, ceilingLevelId, nodes) {
|
|
435
436
|
const { fromLevelId } = getResolvedStairLevelIds(stair, nodes);
|
|
436
|
-
const
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
|
|
437
|
+
const elevations = getLevelElevations(nodes);
|
|
438
|
+
const fromElevation = fromLevelId ? elevations.get(fromLevelId) : undefined;
|
|
439
|
+
const ceilingElevation = elevations.get(ceilingLevelId);
|
|
440
|
+
const ceilingHeight = resolveCeilingHeight(ceiling, nodes);
|
|
441
|
+
if (!fromElevation ||
|
|
442
|
+
!ceilingElevation ||
|
|
443
|
+
fromElevation.buildingId !== ceilingElevation.buildingId) {
|
|
444
|
+
return ceilingHeight;
|
|
440
445
|
}
|
|
441
|
-
return
|
|
442
|
-
(ceiling.height ?? DEFAULT_WALL_HEIGHT) -
|
|
443
|
-
(stair.position[1] ?? 0));
|
|
446
|
+
return ceilingElevation.baseY - fromElevation.baseY + ceilingHeight - (stair.position[1] ?? 0);
|
|
444
447
|
}
|
|
445
448
|
function shouldApplyStairToSlab(stair, slabLevelId, nodes) {
|
|
446
449
|
const { fromLevelId, toLevelId } = getResolvedStairLevelIds(stair, nodes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stair-opening-system.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-system.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stair-opening-system.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-system.tsx"],"names":[],"mappings":"AA4CA,eAAO,MAAM,kBAAkB,YAoH9B,CAAA"}
|
|
@@ -6,6 +6,7 @@ import useLiveTransforms from '../../store/use-live-transforms';
|
|
|
6
6
|
import useScene from '../../store/use-scene';
|
|
7
7
|
import { createSurfaceOpeningPreviewController, getNodesWithLiveStairOpeningInputs, hasLiveStairOpeningInputs, } from './stair-opening-preview';
|
|
8
8
|
import { syncAutoStairOpenings } from './stair-opening-sync';
|
|
9
|
+
import { syncStairRises } from './stair-rise';
|
|
9
10
|
function isOpeningRelevantNode(node) {
|
|
10
11
|
return (node?.type === 'building' ||
|
|
11
12
|
node?.type === 'ceiling' ||
|
|
@@ -77,15 +78,41 @@ export const StairOpeningSystem = () => {
|
|
|
77
78
|
}
|
|
78
79
|
applyPreviewUpdates(syncAutoStairOpenings(getNodesWithLiveStairOpeningInputs(nodes, liveTransforms, liveOverrides, previewSurfaceIds)));
|
|
79
80
|
};
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
const runAutoSync = () => {
|
|
82
|
+
// Rise first: straight stairs converge their flight heights to the
|
|
83
|
+
// resolved rise (level height or deck elevation), and the opening pass
|
|
84
|
+
// reads those segment heights — so it must run against the post-rise
|
|
85
|
+
// nodes.
|
|
86
|
+
applyUpdates(syncStairRises(useScene.getState().nodes));
|
|
87
|
+
applyUpdates(syncAutoStairOpenings(useScene.getState().nodes));
|
|
88
|
+
};
|
|
89
|
+
let disposed = false;
|
|
90
|
+
let autoSyncQueued = false;
|
|
91
|
+
const scheduleAutoSync = () => {
|
|
92
|
+
if (autoSyncQueued)
|
|
93
|
+
return;
|
|
94
|
+
autoSyncQueued = true;
|
|
95
|
+
// One microtask later so every other scene-store listener for the
|
|
96
|
+
// triggering transition (and, at mount, the editor's spatial-grid
|
|
97
|
+
// init) runs first — the spatial-grid sync in particular. The
|
|
98
|
+
// deck-attached rise elects the stair's floor-stack base elevation
|
|
99
|
+
// through the spatial grid; syncing before the grid listener would
|
|
100
|
+
// rescale flights against the pre-transition slab state.
|
|
101
|
+
queueMicrotask(() => {
|
|
102
|
+
autoSyncQueued = false;
|
|
103
|
+
if (disposed)
|
|
104
|
+
return;
|
|
105
|
+
runAutoSync();
|
|
106
|
+
refreshLivePreview();
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
scheduleAutoSync();
|
|
82
110
|
const unsubscribeScene = useScene.subscribe((state, prevState) => {
|
|
83
111
|
if (syncingAutoOpeningsRef.current)
|
|
84
112
|
return;
|
|
85
113
|
if (!hasOpeningRelevantNodeChange(state.nodes, prevState.nodes))
|
|
86
114
|
return;
|
|
87
|
-
|
|
88
|
-
refreshLivePreview();
|
|
115
|
+
scheduleAutoSync();
|
|
89
116
|
});
|
|
90
117
|
const unsubscribeLiveTransforms = useLiveTransforms.subscribe(() => {
|
|
91
118
|
refreshLivePreview();
|
|
@@ -94,6 +121,7 @@ export const StairOpeningSystem = () => {
|
|
|
94
121
|
refreshLivePreview();
|
|
95
122
|
});
|
|
96
123
|
return () => {
|
|
124
|
+
disposed = true;
|
|
97
125
|
unsubscribeScene();
|
|
98
126
|
unsubscribeLiveTransforms();
|
|
99
127
|
unsubscribeLiveOverrides();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AnyNode, AnyNodeId, StairNode } from '../../schema';
|
|
2
|
+
export declare function resolveStairTotalRise(stair: StairNode, nodes: Record<string, AnyNode>): number;
|
|
3
|
+
/**
|
|
4
|
+
* Keeps straight stairs' flight segments in step with the resolved rise.
|
|
5
|
+
* Straight-stair geometry derives from per-segment heights (not from
|
|
6
|
+
* `resolveStairTotalRise`), so level-height and deck-elevation changes must
|
|
7
|
+
* write through to the flight segments — curved/spiral stairs read the
|
|
8
|
+
* resolved rise directly and need no sync.
|
|
9
|
+
*
|
|
10
|
+
* Scope: stairs whose total the system owns — follows-mode stairs (absent
|
|
11
|
+
* `totalRise`, tracking their level or their deck) and deck-attached stairs
|
|
12
|
+
* (an explicit rise converges to the typed value). A detached stair with an
|
|
13
|
+
* explicit `totalRise` is the one place hand-edited segment chains are
|
|
14
|
+
* legitimate, so it is never touched. Flight heights scale proportionally
|
|
15
|
+
* (landings keep theirs); returns `updateNodes` patches, empty when every
|
|
16
|
+
* stair is already in step.
|
|
17
|
+
*/
|
|
18
|
+
export declare function syncStairRises(nodes: Record<string, AnyNode>): Array<{
|
|
19
|
+
id: AnyNodeId;
|
|
20
|
+
data: Partial<AnyNode>;
|
|
21
|
+
}>;
|
|
22
|
+
//# sourceMappingURL=stair-rise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stair-rise.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-rise.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAA;AAInF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CA+B9F;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,KAAK,CAAC;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAgClD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getFloorStackedPosition } from '../../hooks/spatial-grid/floor-placed-elevation';
|
|
2
|
+
import { DEFAULT_LEVEL_HEIGHT } from '../../services/level-height';
|
|
3
|
+
import { getStoredLevelHeight } from '../../services/storey';
|
|
4
|
+
export function resolveStairTotalRise(stair, nodes) {
|
|
5
|
+
if (stair.totalRise !== undefined)
|
|
6
|
+
return stair.totalRise;
|
|
7
|
+
const level = Object.values(nodes).find((node) => node.type === 'level' && node.children.includes(stair.id));
|
|
8
|
+
if (stair.deckSlabId) {
|
|
9
|
+
const deck = nodes[stair.deckSlabId];
|
|
10
|
+
// The deck's `elevation` IS its walking surface (level-local), but the
|
|
11
|
+
// stair's own base may be lifted onto a floor slab by the floor-stack
|
|
12
|
+
// (`FloorElevationSystem` / `syncStairGroupElevation` put the group at
|
|
13
|
+
// `position[1] + elected slab elevation`). The rise is measured from
|
|
14
|
+
// that base, so subtract it — electing the base exactly the way the
|
|
15
|
+
// visual systems do (persisted `supportSlabId` honored, uncapped
|
|
16
|
+
// election otherwise) keeps base + rise landing precisely on the deck's
|
|
17
|
+
// walking surface. A stale reference (deck gone) falls through to the
|
|
18
|
+
// level-derived rise.
|
|
19
|
+
if (deck?.type === 'slab') {
|
|
20
|
+
const baseElevation = getFloorStackedPosition({
|
|
21
|
+
node: stair,
|
|
22
|
+
nodes,
|
|
23
|
+
position: stair.position,
|
|
24
|
+
rotation: stair.rotation,
|
|
25
|
+
levelId: level?.id ?? null,
|
|
26
|
+
})[1];
|
|
27
|
+
return (deck.elevation ?? 0.05) - baseElevation;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return level?.type === 'level' ? getStoredLevelHeight(level) : DEFAULT_LEVEL_HEIGHT;
|
|
31
|
+
}
|
|
32
|
+
const RISE_SYNC_EPSILON = 1e-4;
|
|
33
|
+
/**
|
|
34
|
+
* Keeps straight stairs' flight segments in step with the resolved rise.
|
|
35
|
+
* Straight-stair geometry derives from per-segment heights (not from
|
|
36
|
+
* `resolveStairTotalRise`), so level-height and deck-elevation changes must
|
|
37
|
+
* write through to the flight segments — curved/spiral stairs read the
|
|
38
|
+
* resolved rise directly and need no sync.
|
|
39
|
+
*
|
|
40
|
+
* Scope: stairs whose total the system owns — follows-mode stairs (absent
|
|
41
|
+
* `totalRise`, tracking their level or their deck) and deck-attached stairs
|
|
42
|
+
* (an explicit rise converges to the typed value). A detached stair with an
|
|
43
|
+
* explicit `totalRise` is the one place hand-edited segment chains are
|
|
44
|
+
* legitimate, so it is never touched. Flight heights scale proportionally
|
|
45
|
+
* (landings keep theirs); returns `updateNodes` patches, empty when every
|
|
46
|
+
* stair is already in step.
|
|
47
|
+
*/
|
|
48
|
+
export function syncStairRises(nodes) {
|
|
49
|
+
const updates = [];
|
|
50
|
+
for (const node of Object.values(nodes)) {
|
|
51
|
+
if (node.type !== 'stair' || node.stairType !== 'straight')
|
|
52
|
+
continue;
|
|
53
|
+
const deck = node.deckSlabId ? nodes[node.deckSlabId] : undefined;
|
|
54
|
+
if (node.totalRise !== undefined && deck?.type !== 'slab')
|
|
55
|
+
continue;
|
|
56
|
+
const segments = (node.children ?? [])
|
|
57
|
+
.map((childId) => nodes[childId])
|
|
58
|
+
.filter((child) => child?.type === 'stair-segment');
|
|
59
|
+
const flights = segments.filter((segment) => segment.segmentType === 'stair');
|
|
60
|
+
if (flights.length === 0)
|
|
61
|
+
continue;
|
|
62
|
+
const landingRise = segments
|
|
63
|
+
.filter((segment) => segment.segmentType !== 'stair')
|
|
64
|
+
.reduce((sum, segment) => sum + segment.height, 0);
|
|
65
|
+
const flightRise = flights.reduce((sum, segment) => sum + segment.height, 0);
|
|
66
|
+
const targetFlightRise = resolveStairTotalRise(node, nodes) - landingRise;
|
|
67
|
+
if (targetFlightRise <= 0)
|
|
68
|
+
continue;
|
|
69
|
+
if (Math.abs(flightRise - targetFlightRise) <= RISE_SYNC_EPSILON)
|
|
70
|
+
continue;
|
|
71
|
+
for (const flight of flights) {
|
|
72
|
+
const height = flightRise > RISE_SYNC_EPSILON
|
|
73
|
+
? flight.height * (targetFlightRise / flightRise)
|
|
74
|
+
: targetFlightRise / flights.length;
|
|
75
|
+
updates.push({ id: flight.id, data: { height } });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return updates;
|
|
79
|
+
}
|
|
@@ -34,6 +34,16 @@ export declare function getWallChordFrame(wall: WallCurveLike): {
|
|
|
34
34
|
};
|
|
35
35
|
length: number;
|
|
36
36
|
};
|
|
37
|
+
export declare function getWallArcData(wall: WallCurveLike): {
|
|
38
|
+
center: {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
};
|
|
42
|
+
radius: number;
|
|
43
|
+
startAngle: number;
|
|
44
|
+
delta: number;
|
|
45
|
+
direction: number;
|
|
46
|
+
} | null;
|
|
37
47
|
export declare function getWallCurveFrameAt(wall: WallCurveLike, t: number): CurveFrame;
|
|
38
48
|
export declare function getWallMidpointHandlePoint(wall: WallCurveLike): Point2D;
|
|
39
49
|
export declare function sampleWallCenterline(wall: WallCurveLike, segments?: number): Point2D[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wall-curve.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-curve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAK9C,KAAK,aAAa,GAAG,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,aAAa,CAAC,CAAA;AAEhF,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAcD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE5D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,UAErD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,UAExD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,UAE5D;AAWD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAG3E;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,UAI5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,WAE/C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa;;;;;;;;;;;;;EA6BpD;
|
|
1
|
+
{"version":3,"file":"wall-curve.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-curve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAK9C,KAAK,aAAa,GAAG,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,aAAa,CAAC,CAAA;AAEhF,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAcD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE5D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,UAErD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,UAExD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,UAE5D;AAWD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAG3E;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,UAI5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,WAE/C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa;;;;;;;;;;;;;EA6BpD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa;;;;;;;;;SA2BjD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAwC9E;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,aAAa,WAE7D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,SAA0B,aAM3F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,SAA0B,UASzF;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,aAAa,GAAG,WAAW,CAAC,EAC/E,QAAQ,SAA0B,EAClC,cAAc,CAAC,EAAE,yBAAyB,aA2B3C"}
|
|
@@ -71,7 +71,7 @@ export function getWallChordFrame(wall) {
|
|
|
71
71
|
length,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
function getWallArcData(wall) {
|
|
74
|
+
export function getWallArcData(wall) {
|
|
75
75
|
const chord = getWallChordFrame(wall);
|
|
76
76
|
const sagitta = getClampedWallCurveOffset(wall);
|
|
77
77
|
if (Math.abs(sagitta) <= CURVE_EPSILON || chord.length < CURVE_EPSILON) {
|
|
@@ -117,10 +117,8 @@ function getWallBoundaryFrame(wall, endType) {
|
|
|
117
117
|
const point = endType === 'start'
|
|
118
118
|
? { x: wall.start[0], y: wall.start[1] }
|
|
119
119
|
: { x: wall.end[0], y: wall.end[1] };
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
: { x: wall.start[0] - wall.end[0], y: wall.start[1] - wall.end[1] };
|
|
123
|
-
const length = Math.hypot(vector.x, vector.y);
|
|
120
|
+
const direction = { x: wall.end[0] - wall.start[0], y: wall.end[1] - wall.start[1] };
|
|
121
|
+
const length = Math.hypot(direction.x, direction.y);
|
|
124
122
|
if (length < 1e-9) {
|
|
125
123
|
return {
|
|
126
124
|
point,
|
|
@@ -130,8 +128,10 @@ function getWallBoundaryFrame(wall, endType) {
|
|
|
130
128
|
}
|
|
131
129
|
return {
|
|
132
130
|
point,
|
|
133
|
-
tangent:
|
|
134
|
-
|
|
131
|
+
tangent: endType === 'start'
|
|
132
|
+
? { x: direction.x / length, y: direction.y / length }
|
|
133
|
+
: { x: -direction.x / length, y: -direction.y / length },
|
|
134
|
+
normal: { x: -direction.y / length, y: direction.x / length },
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
137
|
function calculateJunctionIntersections(junction, getThickness) {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { WallNode } from '../../schema/nodes/wall';
|
|
2
|
+
/**
|
|
3
|
+
* Minimum wall body height in meters. Governs both the wall height
|
|
4
|
+
* arrow's lower drag bound and the slab-elevation clamp: a slab may not
|
|
5
|
+
* rise past `storeyHeight - MIN_WALL_HEIGHT` while a plane-bound wall
|
|
6
|
+
* elects it as its base, or the wall's extrusion (plane minus base)
|
|
7
|
+
* would collapse below this minimum.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MIN_WALL_HEIGHT = 0.5;
|
|
10
|
+
/**
|
|
11
|
+
* Wall-top inversion (vertical building model): a wall with no stored
|
|
12
|
+
* `height` is plane-bound — its top sits at the storey plane (level-local
|
|
13
|
+
* Y = the level's stored height), so a slab lifting the wall's base makes
|
|
14
|
+
* the wall shorter, never taller, and no gap can open at the top of a
|
|
15
|
+
* level. A wall WITH `height` is an explicit exception (half wall,
|
|
16
|
+
* parapet) and keeps the legacy semantics: the top rides a raised elected
|
|
17
|
+
* base (`electedBase + height`), while a zero or sunken slab base leaves
|
|
18
|
+
* the top at `height` (the legacy negative-slab constraint). Explicit
|
|
19
|
+
* ground-hosted walls are the terrain exception: `height` is always body
|
|
20
|
+
* height, including below datum, so sculpting cannot stretch the wall.
|
|
21
|
+
*
|
|
22
|
+
* Returns the top in level-local Y (same frame as `electedBase`).
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveWallTop(wall: Pick<WallNode, 'height' | 'supportSlabId'>, storeyHeight: number, electedBase: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Extruded height of the wall body: {@link resolveWallTop} minus the
|
|
27
|
+
* elected base. Base convention: the elected slab-support elevation itself
|
|
28
|
+
* — the viewer computes `effectiveBaseElevation = min(baseElevation,
|
|
29
|
+
* slabElevation)` and defaults `baseElevation` to the elected elevation,
|
|
30
|
+
* so with only the election in hand the two coincide. Fill-down below the
|
|
31
|
+
* elected base (`baseSegments`) is a geometry detail the extruder handles
|
|
32
|
+
* separately and never changes where the top sits.
|
|
33
|
+
*
|
|
34
|
+
* Equivalently: the wall-local Y of the wall's top, measured from the wall
|
|
35
|
+
* mesh origin (which sits at `electedBase`). May be non-positive when a
|
|
36
|
+
* slab reaches the storey plane; callers own the degenerate-geometry
|
|
37
|
+
* policy.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveWallEffectiveHeight(wall: Pick<WallNode, 'height' | 'supportSlabId'>, storeyHeight: number, electedBase: number): number;
|
|
40
|
+
//# sourceMappingURL=wall-top.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-top.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-top.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,MAAM,CAAA;AAElC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAAC,EAChD,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAIR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAAC,EAChD,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimum wall body height in meters. Governs both the wall height
|
|
3
|
+
* arrow's lower drag bound and the slab-elevation clamp: a slab may not
|
|
4
|
+
* rise past `storeyHeight - MIN_WALL_HEIGHT` while a plane-bound wall
|
|
5
|
+
* elects it as its base, or the wall's extrusion (plane minus base)
|
|
6
|
+
* would collapse below this minimum.
|
|
7
|
+
*/
|
|
8
|
+
export const MIN_WALL_HEIGHT = 0.5;
|
|
9
|
+
/**
|
|
10
|
+
* Wall-top inversion (vertical building model): a wall with no stored
|
|
11
|
+
* `height` is plane-bound — its top sits at the storey plane (level-local
|
|
12
|
+
* Y = the level's stored height), so a slab lifting the wall's base makes
|
|
13
|
+
* the wall shorter, never taller, and no gap can open at the top of a
|
|
14
|
+
* level. A wall WITH `height` is an explicit exception (half wall,
|
|
15
|
+
* parapet) and keeps the legacy semantics: the top rides a raised elected
|
|
16
|
+
* base (`electedBase + height`), while a zero or sunken slab base leaves
|
|
17
|
+
* the top at `height` (the legacy negative-slab constraint). Explicit
|
|
18
|
+
* ground-hosted walls are the terrain exception: `height` is always body
|
|
19
|
+
* height, including below datum, so sculpting cannot stretch the wall.
|
|
20
|
+
*
|
|
21
|
+
* Returns the top in level-local Y (same frame as `electedBase`).
|
|
22
|
+
*/
|
|
23
|
+
export function resolveWallTop(wall, storeyHeight, electedBase) {
|
|
24
|
+
if (wall.height == null)
|
|
25
|
+
return storeyHeight;
|
|
26
|
+
if (wall.supportSlabId === 'ground')
|
|
27
|
+
return electedBase + wall.height;
|
|
28
|
+
return electedBase > 0 ? electedBase + wall.height : wall.height;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Extruded height of the wall body: {@link resolveWallTop} minus the
|
|
32
|
+
* elected base. Base convention: the elected slab-support elevation itself
|
|
33
|
+
* — the viewer computes `effectiveBaseElevation = min(baseElevation,
|
|
34
|
+
* slabElevation)` and defaults `baseElevation` to the elected elevation,
|
|
35
|
+
* so with only the election in hand the two coincide. Fill-down below the
|
|
36
|
+
* elected base (`baseSegments`) is a geometry detail the extruder handles
|
|
37
|
+
* separately and never changes where the top sits.
|
|
38
|
+
*
|
|
39
|
+
* Equivalently: the wall-local Y of the wall's top, measured from the wall
|
|
40
|
+
* mesh origin (which sits at `electedBase`). May be non-positive when a
|
|
41
|
+
* slab reaches the storey plane; callers own the degenerate-geometry
|
|
42
|
+
* policy.
|
|
43
|
+
*/
|
|
44
|
+
export function resolveWallEffectiveHeight(wall, storeyHeight, electedBase) {
|
|
45
|
+
return resolveWallTop(wall, storeyHeight, electedBase) - electedBase;
|
|
46
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/clone-scene-graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clone-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/clone-scene-graph.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAErE,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACjC,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAC9C,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC5B,CAAA;AAUD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAuIlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,OAAO,EAAE,SAAS,GACjB;IAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IAAC,UAAU,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAsG/E;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,qBAA0B,GAClC,UAAU,CAqEZ"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GROUND_SUPPORT_ID } from '../hooks/spatial-grid/floor-placed-elevation';
|
|
2
|
+
import { remapConstructionDimensionReferences, remapMeasurementReferences, } from '../lib/measurement-geometry';
|
|
2
3
|
import { generateId } from '../schema/base';
|
|
3
4
|
/**
|
|
4
5
|
* Extracts the type prefix from a node ID (e.g., "wall_abc123" -> "wall")
|
|
@@ -29,7 +30,7 @@ export function cloneSceneGraph(sceneGraph) {
|
|
|
29
30
|
const clonedNodes = {};
|
|
30
31
|
for (const [oldId, node] of Object.entries(nodes)) {
|
|
31
32
|
const newId = idMap.get(oldId);
|
|
32
|
-
|
|
33
|
+
let clonedNode = structuredClone({ ...node, id: newId });
|
|
33
34
|
// Remap parentId
|
|
34
35
|
if (clonedNode.parentId && typeof clonedNode.parentId === 'string') {
|
|
35
36
|
clonedNode.parentId = (idMap.get(clonedNode.parentId) ?? null);
|
|
@@ -63,9 +64,24 @@ export function cloneSceneGraph(sceneGraph) {
|
|
|
63
64
|
;
|
|
64
65
|
clonedNode.roofSegmentId = idMap.get(clonedNode.roofSegmentId);
|
|
65
66
|
}
|
|
67
|
+
// Remap supportSlabId (persisted slab-support hosts). The 'ground'
|
|
68
|
+
// sentinel is not a node id — keep it as-is.
|
|
69
|
+
if ('supportSlabId' in clonedNode &&
|
|
70
|
+
typeof clonedNode.supportSlabId === 'string' &&
|
|
71
|
+
clonedNode.supportSlabId !== GROUND_SUPPORT_ID) {
|
|
72
|
+
;
|
|
73
|
+
clonedNode.supportSlabId = idMap.get(clonedNode.supportSlabId);
|
|
74
|
+
}
|
|
75
|
+
if ('deckSlabId' in clonedNode && typeof clonedNode.deckSlabId === 'string') {
|
|
76
|
+
;
|
|
77
|
+
clonedNode.deckSlabId = idMap.get(clonedNode.deckSlabId);
|
|
78
|
+
}
|
|
66
79
|
if (clonedNode.type === 'measurement') {
|
|
67
80
|
clonedNode.measurement = remapMeasurementReferences(clonedNode.measurement, idMap);
|
|
68
81
|
}
|
|
82
|
+
if (clonedNode.type === 'construction-dimension') {
|
|
83
|
+
clonedNode = remapConstructionDimensionReferences(clonedNode, idMap);
|
|
84
|
+
}
|
|
69
85
|
clonedNodes[newId] = clonedNode;
|
|
70
86
|
}
|
|
71
87
|
// Remap root node IDs
|
|
@@ -166,7 +182,7 @@ export function cloneLevelSubtree(nodes, levelId) {
|
|
|
166
182
|
continue;
|
|
167
183
|
const newId = idMap.get(oldId);
|
|
168
184
|
// JSON roundtrip: safely strips functions, Object3D, circular refs, etc.
|
|
169
|
-
|
|
185
|
+
let cloned = JSON.parse(JSON.stringify(node));
|
|
170
186
|
cloned.id = newId;
|
|
171
187
|
// Remap parentId — but only for descendants, not the level node itself
|
|
172
188
|
// (the level's parentId points to the building, which is outside the subtree)
|
|
@@ -201,9 +217,24 @@ export function cloneLevelSubtree(nodes, levelId) {
|
|
|
201
217
|
cloned.roofSegmentId =
|
|
202
218
|
idMap.get(cloned.roofSegmentId) ?? cloned.roofSegmentId;
|
|
203
219
|
}
|
|
220
|
+
// Remap supportSlabId when the host slab is inside the cloned subtree;
|
|
221
|
+
// preserve it otherwise (like wallId, the reference may point outside).
|
|
222
|
+
if ('supportSlabId' in cloned && typeof cloned.supportSlabId === 'string') {
|
|
223
|
+
;
|
|
224
|
+
cloned.supportSlabId =
|
|
225
|
+
idMap.get(cloned.supportSlabId) ?? cloned.supportSlabId;
|
|
226
|
+
}
|
|
227
|
+
if ('deckSlabId' in cloned && typeof cloned.deckSlabId === 'string') {
|
|
228
|
+
;
|
|
229
|
+
cloned.deckSlabId =
|
|
230
|
+
idMap.get(cloned.deckSlabId) ?? cloned.deckSlabId;
|
|
231
|
+
}
|
|
204
232
|
if (cloned.type === 'measurement') {
|
|
205
233
|
cloned.measurement = remapMeasurementReferences(cloned.measurement, idMap);
|
|
206
234
|
}
|
|
235
|
+
if (cloned.type === 'construction-dimension') {
|
|
236
|
+
cloned = remapConstructionDimensionReferences(cloned, idMap);
|
|
237
|
+
}
|
|
207
238
|
clonedNodes.push(cloned);
|
|
208
239
|
}
|
|
209
240
|
return { clonedNodes, newLevelId, idMap };
|
|
@@ -2,7 +2,7 @@ export interface HealSceneResult {
|
|
|
2
2
|
nodes: Record<string, unknown>;
|
|
3
3
|
/** Ids of zero-length walls that were dropped. */
|
|
4
4
|
droppedWallIds: string[];
|
|
5
|
-
/** Count of non-string (e.g. null) entries removed from `children` arrays. */
|
|
5
|
+
/** Count of invalid non-string (e.g. null) entries removed from `children` arrays. */
|
|
6
6
|
strippedChildRefs: number;
|
|
7
7
|
/**
|
|
8
8
|
* Count of child references removed because the child's `parentId` points at
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heal-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/heal-scene-graph.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,kDAAkD;IAClD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,
|
|
1
|
+
{"version":3,"file":"heal-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/heal-scene-graph.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,kDAAkD;IAClD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,sFAAsF;IACtF,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;OAGG;IACH,sBAAsB,EAAE,MAAM,CAAA;CAC/B;AAgBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CA2E9E"}
|
|
@@ -54,26 +54,42 @@ export function healSceneNodes(input) {
|
|
|
54
54
|
const dropped = new Set(droppedWallIds);
|
|
55
55
|
let strippedChildRefs = 0;
|
|
56
56
|
let strippedStaleChildRefs = 0;
|
|
57
|
-
// Pass 2: clean `children` arrays — drop non-string entries (the
|
|
58
|
-
// bug), references to walls we just removed, same-array duplicates,
|
|
59
|
-
// stale references whose child's `parentId` names a different parent.
|
|
57
|
+
// Pass 2: clean `children` arrays — drop invalid non-string entries (the
|
|
58
|
+
// `[null]` bug), references to walls we just removed, same-array duplicates,
|
|
59
|
+
// and stale references whose child's `parentId` names a different parent.
|
|
60
|
+
// Legacy sites embedded full child objects; keep those for migrateNodes to
|
|
61
|
+
// flatten after healing instead of disconnecting the entire building.
|
|
60
62
|
const nodes = {};
|
|
61
63
|
for (const [id, node] of Object.entries(kept)) {
|
|
62
64
|
const children = node?.children;
|
|
63
65
|
if (Array.isArray(children)) {
|
|
64
66
|
const seen = new Set();
|
|
65
|
-
const cleaned = children.filter((
|
|
66
|
-
|
|
67
|
+
const cleaned = children.filter((child) => {
|
|
68
|
+
const embeddedSiteChildId = node.type === 'site' &&
|
|
69
|
+
child &&
|
|
70
|
+
typeof child === 'object' &&
|
|
71
|
+
typeof child.id === 'string'
|
|
72
|
+
? child.id
|
|
73
|
+
: null;
|
|
74
|
+
if (embeddedSiteChildId) {
|
|
75
|
+
if (seen.has(embeddedSiteChildId)) {
|
|
76
|
+
strippedStaleChildRefs++;
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
seen.add(embeddedSiteChildId);
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (typeof child !== 'string' || dropped.has(child)) {
|
|
67
83
|
strippedChildRefs++;
|
|
68
84
|
return false;
|
|
69
85
|
}
|
|
70
|
-
if (seen.has(
|
|
86
|
+
if (seen.has(child)) {
|
|
71
87
|
strippedStaleChildRefs++;
|
|
72
88
|
return false;
|
|
73
89
|
}
|
|
74
|
-
seen.add(
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
90
|
+
seen.add(child);
|
|
91
|
+
const childNode = kept[child];
|
|
92
|
+
if (childNode && typeof childNode.parentId === 'string' && childNode.parentId !== id) {
|
|
77
93
|
strippedStaleChildRefs++;
|
|
78
94
|
return false;
|
|
79
95
|
}
|
|
@@ -9,6 +9,8 @@ export type ValidationIssue = {
|
|
|
9
9
|
export type BuildStats = {
|
|
10
10
|
total: number;
|
|
11
11
|
byType: Partial<Record<AnyNodeType, number>>;
|
|
12
|
+
/** Kinds outside the static schema union but registered at runtime (plugins). */
|
|
13
|
+
pluginTypes: Record<string, number>;
|
|
12
14
|
unknownTypes: Record<string, number>;
|
|
13
15
|
floorAreaM2: number;
|
|
14
16
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-build-json.d.ts","sourceRoot":"","sources":["../../src/validation/validate-build-json.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validate-build-json.d.ts","sourceRoot":"","sources":["../../src/validation/validate-build-json.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG3D,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAAA;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5C,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B,KAAK,EAAE,UAAU,CAAA;IACjB,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,YAAY,EAAE,WAAW,EAAE,CAAA;IAC3B,gBAAgB,EAAE,MAAM,CAAA;CACzB,CAAA;AA8BD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CA8SzE"}
|