@pascal-app/core 1.0.0-beta.5 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/capture/index.d.ts +3 -0
- package/dist/capture/index.d.ts.map +1 -0
- package/dist/capture/index.js +2 -0
- package/dist/capture/schema.d.ts +417 -0
- package/dist/capture/schema.d.ts.map +1 -0
- package/dist/capture/schema.js +350 -0
- package/dist/capture/source.d.ts +60 -0
- package/dist/capture/source.d.ts.map +1 -0
- package/dist/capture/source.js +254 -0
- package/dist/events/bus.d.ts +58 -7
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/events/hidden-wall-pointer-hold.d.ts +28 -0
- package/dist/events/hidden-wall-pointer-hold.d.ts.map +1 -0
- package/dist/events/hidden-wall-pointer-hold.js +37 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +4 -4
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.js +7 -12
- package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts +4 -0
- package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/floor-placed-footprints.js +7 -0
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +5 -8
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +23 -106
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +2931 -2
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +207 -30
- package/dist/hooks/spatial-grid/support-host-patch.d.ts +45 -1
- package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/support-host-patch.js +174 -9
- package/dist/hooks/spatial-grid/use-spatial-query.d.ts +1 -1
- package/dist/hooks/spatial-grid/use-spatial-query.js +1 -1
- package/dist/index.d.ts +74 -64
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -61
- package/dist/lib/asset-storage.d.ts.map +1 -1
- package/dist/lib/asset-storage.js +4 -1
- package/dist/lib/door-operation.d.ts +1 -1
- package/dist/lib/item-polygon-overlap.d.ts +6 -0
- package/dist/lib/item-polygon-overlap.d.ts.map +1 -0
- package/dist/lib/item-polygon-overlap.js +67 -0
- package/dist/lib/level-name.d.ts +1 -1
- package/dist/lib/measurement-geometry.d.ts +4 -4
- package/dist/lib/plan-footprint.d.ts +41 -0
- package/dist/lib/plan-footprint.d.ts.map +1 -0
- package/dist/lib/plan-footprint.js +58 -0
- package/dist/lib/polygon-union.d.ts +4 -0
- package/dist/lib/polygon-union.d.ts.map +1 -0
- package/dist/lib/polygon-union.js +306 -0
- package/dist/lib/roof-overlap.d.ts +32 -0
- package/dist/lib/roof-overlap.d.ts.map +1 -0
- package/dist/lib/roof-overlap.js +72 -0
- package/dist/lib/room-topology-index.d.ts +1 -1
- package/dist/lib/room-topology-index.js +1 -1
- package/dist/lib/selection-proxy.d.ts +1 -1
- package/dist/lib/slab-polygon.d.ts +36 -3
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +135 -29
- package/dist/lib/space-detection.d.ts +12 -1
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +58 -25
- package/dist/lib/terrain-brush.d.ts +1 -1
- package/dist/lib/terrain-brush.js +1 -1
- package/dist/lib/terrain-codec.d.ts +2 -2
- package/dist/lib/terrain-codec.js +1 -1
- package/dist/lib/terrain-raycast.d.ts +1 -1
- package/dist/lib/terrain-raycast.js +1 -1
- package/dist/lib/terrain-source.d.ts +3 -3
- package/dist/lib/terrain-source.js +3 -3
- package/dist/lib/terrain-support.d.ts +1 -1
- package/dist/lib/terrain-support.js +3 -3
- package/dist/lib/unit-containment.d.ts +19 -0
- package/dist/lib/unit-containment.d.ts.map +1 -0
- package/dist/lib/unit-containment.js +158 -0
- package/dist/lib/unit-report.d.ts +19 -0
- package/dist/lib/unit-report.d.ts.map +1 -0
- package/dist/lib/unit-report.js +36 -0
- package/dist/lib/wall-distance.d.ts +2 -2
- package/dist/lib/wall-distance.js +1 -1
- package/dist/lib/zone-quantities.d.ts +1 -1
- package/dist/lib/zone-quantities.js +7 -7
- package/dist/material-library.d.ts +1 -1
- package/dist/material-library.js +1 -1
- package/dist/procedural-items/fixtures.d.ts +261 -0
- package/dist/procedural-items/fixtures.d.ts.map +1 -0
- package/dist/procedural-items/fixtures.js +349 -0
- package/dist/procedural-items/index.d.ts +10 -0
- package/dist/procedural-items/index.d.ts.map +1 -0
- package/dist/procedural-items/index.js +9 -0
- package/dist/procedural-items/integration.d.ts +92 -0
- package/dist/procedural-items/integration.d.ts.map +1 -0
- package/dist/procedural-items/integration.js +19 -0
- package/dist/procedural-items/library-colors.d.ts +56 -0
- package/dist/procedural-items/library-colors.d.ts.map +1 -0
- package/dist/procedural-items/library-colors.js +84 -0
- package/dist/procedural-items/materials.d.ts +5 -0
- package/dist/procedural-items/materials.d.ts.map +1 -0
- package/dist/procedural-items/materials.js +47 -0
- package/dist/procedural-items/node.d.ts +280 -0
- package/dist/procedural-items/node.d.ts.map +1 -0
- package/dist/procedural-items/node.js +71 -0
- package/dist/procedural-items/placement.d.ts +7 -0
- package/dist/procedural-items/placement.d.ts.map +1 -0
- package/dist/procedural-items/placement.js +48 -0
- package/dist/procedural-items/query.d.ts +50 -0
- package/dist/procedural-items/query.d.ts.map +1 -0
- package/dist/procedural-items/query.js +298 -0
- package/dist/procedural-items/recipe.d.ts +144 -0
- package/dist/procedural-items/recipe.d.ts.map +1 -0
- package/dist/procedural-items/recipe.js +372 -0
- package/dist/procedural-items/spatial.d.ts +19 -0
- package/dist/procedural-items/spatial.d.ts.map +1 -0
- package/dist/procedural-items/spatial.js +39 -0
- package/dist/registry/__bench__/relations-resolver.bench.js +2 -2
- package/dist/registry/handles.d.ts +36 -7
- package/dist/registry/handles.d.ts.map +1 -1
- package/dist/registry/index.d.ts +6 -7
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +4 -5
- package/dist/registry/registry.d.ts +13 -6
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +37 -4
- package/dist/registry/relations-resolver.d.ts +2 -2
- package/dist/registry/relations-resolver.js +1 -1
- package/dist/registry/scene-api.d.ts +18 -2
- package/dist/registry/scene-api.d.ts.map +1 -1
- package/dist/registry/scene-api.js +50 -2
- package/dist/registry/subtree.d.ts +1 -1
- package/dist/registry/subtree.js +2 -2
- package/dist/registry/types.d.ts +246 -21
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry/use-registry-version.js +1 -1
- package/dist/registry/validate-relations.d.ts +4 -0
- package/dist/registry/validate-relations.d.ts.map +1 -0
- package/dist/registry/validate-relations.js +22 -0
- package/dist/schema/__bench__/node-parsers.bench.d.ts +24 -0
- package/dist/schema/__bench__/node-parsers.bench.d.ts.map +1 -0
- package/dist/schema/__bench__/node-parsers.bench.js +314 -0
- package/dist/schema/__fixtures__/node-fixtures.d.ts +28 -0
- package/dist/schema/__fixtures__/node-fixtures.d.ts.map +1 -0
- package/dist/schema/__fixtures__/node-fixtures.js +127 -0
- package/dist/schema/base.d.ts +1 -1
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/base.js +9 -2
- package/dist/schema/collections.d.ts +1 -1
- package/dist/schema/collections.js +1 -1
- package/dist/schema/compiled-node-parsers.d.ts +40 -0
- package/dist/schema/compiled-node-parsers.d.ts.map +1 -0
- package/dist/schema/compiled-node-parsers.js +95 -0
- package/dist/schema/index.d.ts +73 -66
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +65 -57
- package/dist/schema/material.d.ts +1 -0
- package/dist/schema/material.d.ts.map +1 -1
- package/dist/schema/material.js +2 -1
- package/dist/schema/nodes/automatic-downspout.d.ts +17 -0
- package/dist/schema/nodes/automatic-downspout.d.ts.map +1 -0
- package/dist/schema/nodes/automatic-downspout.js +237 -0
- package/dist/schema/nodes/block.d.ts +107 -0
- package/dist/schema/nodes/block.d.ts.map +1 -0
- package/dist/schema/nodes/block.js +206 -0
- package/dist/schema/nodes/box-vent.d.ts +8 -2
- package/dist/schema/nodes/box-vent.d.ts.map +1 -1
- package/dist/schema/nodes/box-vent.js +4 -2
- package/dist/schema/nodes/building.d.ts +2 -2
- package/dist/schema/nodes/building.d.ts.map +1 -1
- package/dist/schema/nodes/building.js +8 -5
- package/dist/schema/nodes/cabinet.d.ts +26 -4
- package/dist/schema/nodes/cabinet.d.ts.map +1 -1
- package/dist/schema/nodes/cabinet.js +29 -8
- package/dist/schema/nodes/ceiling.d.ts +2 -2
- package/dist/schema/nodes/ceiling.js +5 -5
- package/dist/schema/nodes/chimney.d.ts +2 -2
- package/dist/schema/nodes/chimney.js +2 -2
- package/dist/schema/nodes/column.d.ts +7 -6
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +3 -2
- package/dist/schema/nodes/construction-dimension.d.ts +1 -1
- package/dist/schema/nodes/construction-dimension.js +2 -2
- package/dist/schema/nodes/cupola.d.ts +9 -1
- package/dist/schema/nodes/cupola.d.ts.map +1 -1
- package/dist/schema/nodes/cupola.js +4 -2
- package/dist/schema/nodes/door.d.ts +1 -1
- package/dist/schema/nodes/door.js +2 -2
- package/dist/schema/nodes/dormer.d.ts +45 -2
- package/dist/schema/nodes/dormer.d.ts.map +1 -1
- package/dist/schema/nodes/dormer.js +133 -9
- package/dist/schema/nodes/downspout.d.ts +11 -1
- package/dist/schema/nodes/downspout.d.ts.map +1 -1
- package/dist/schema/nodes/downspout.js +26 -2
- package/dist/schema/nodes/duct-fitting.d.ts +18 -1
- package/dist/schema/nodes/duct-fitting.d.ts.map +1 -1
- package/dist/schema/nodes/duct-fitting.js +26 -5
- package/dist/schema/nodes/duct-segment.d.ts +23 -1
- package/dist/schema/nodes/duct-segment.d.ts.map +1 -1
- package/dist/schema/nodes/duct-segment.js +21 -1
- package/dist/schema/nodes/duct-terminal.d.ts +1 -1
- package/dist/schema/nodes/duct-terminal.js +1 -1
- package/dist/schema/nodes/elevator.d.ts +1 -1
- package/dist/schema/nodes/elevator.js +2 -2
- package/dist/schema/nodes/eyebrow-vent.d.ts +8 -2
- package/dist/schema/nodes/eyebrow-vent.d.ts.map +1 -1
- package/dist/schema/nodes/eyebrow-vent.js +4 -2
- package/dist/schema/nodes/fence.d.ts +1 -1
- package/dist/schema/nodes/fence.js +2 -2
- package/dist/schema/nodes/guide.d.ts +1 -1
- package/dist/schema/nodes/guide.js +2 -2
- package/dist/schema/nodes/gutter.d.ts +36 -2
- package/dist/schema/nodes/gutter.d.ts.map +1 -1
- package/dist/schema/nodes/gutter.js +310 -3
- package/dist/schema/nodes/hanger-overrides.d.ts +7 -0
- package/dist/schema/nodes/hanger-overrides.d.ts.map +1 -0
- package/dist/schema/nodes/hanger-overrides.js +6 -0
- package/dist/schema/nodes/hvac-equipment.d.ts +1 -1
- package/dist/schema/nodes/hvac-equipment.js +1 -1
- package/dist/schema/nodes/imported-mesh.d.ts +40 -0
- package/dist/schema/nodes/imported-mesh.d.ts.map +1 -0
- package/dist/schema/nodes/imported-mesh.js +27 -0
- package/dist/schema/nodes/item.d.ts +3 -2
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +8 -3
- package/dist/schema/nodes/lean-to-extension.d.ts +212 -0
- package/dist/schema/nodes/lean-to-extension.d.ts.map +1 -0
- package/dist/schema/nodes/lean-to-extension.js +114 -0
- package/dist/schema/nodes/level.d.ts +2 -2
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +1 -1
- package/dist/schema/nodes/lineset.d.ts +1 -1
- package/dist/schema/nodes/lineset.js +1 -1
- package/dist/schema/nodes/liquid-line.d.ts +1 -1
- package/dist/schema/nodes/liquid-line.js +1 -1
- package/dist/schema/nodes/measurement.d.ts +1 -1
- package/dist/schema/nodes/measurement.js +2 -2
- package/dist/schema/nodes/pipe-fitting.d.ts +10 -2
- package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -1
- package/dist/schema/nodes/pipe-fitting.js +7 -3
- package/dist/schema/nodes/pipe-segment.d.ts +24 -2
- package/dist/schema/nodes/pipe-segment.d.ts.map +1 -1
- package/dist/schema/nodes/pipe-segment.js +21 -1
- package/dist/schema/nodes/pipe-trap.d.ts +2 -2
- package/dist/schema/nodes/pipe-trap.js +1 -1
- package/dist/schema/nodes/ridge-vent.d.ts +2 -2
- package/dist/schema/nodes/ridge-vent.d.ts.map +1 -1
- package/dist/schema/nodes/ridge-vent.js +7 -4
- package/dist/schema/nodes/roof-segment-shape.d.ts +5 -1
- package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment-shape.js +65 -2
- package/dist/schema/nodes/roof-segment-walls.d.ts +4 -2
- package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment-walls.js +2 -2
- package/dist/schema/nodes/roof-segment.d.ts +42 -2
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +81 -4
- package/dist/schema/nodes/roof.d.ts +23 -2
- package/dist/schema/nodes/roof.d.ts.map +1 -1
- package/dist/schema/nodes/roof.js +17 -3
- package/dist/schema/nodes/scan.d.ts +19 -2
- package/dist/schema/nodes/scan.d.ts.map +1 -1
- package/dist/schema/nodes/scan.js +13 -3
- package/dist/schema/nodes/shelf.d.ts +3 -3
- package/dist/schema/nodes/shelf.d.ts.map +1 -1
- package/dist/schema/nodes/shelf.js +3 -4
- package/dist/schema/nodes/site.d.ts +1 -1
- package/dist/schema/nodes/site.js +2 -2
- package/dist/schema/nodes/skylight.d.ts +5 -5
- package/dist/schema/nodes/skylight.js +2 -2
- package/dist/schema/nodes/slab.d.ts +1 -1
- package/dist/schema/nodes/slab.js +3 -3
- package/dist/schema/nodes/solar-panel.d.ts +1 -1
- package/dist/schema/nodes/solar-panel.js +3 -3
- package/dist/schema/nodes/spawn.d.ts +1 -1
- package/dist/schema/nodes/spawn.js +1 -1
- package/dist/schema/nodes/stair-segment.d.ts +1 -1
- package/dist/schema/nodes/stair-segment.js +2 -2
- package/dist/schema/nodes/stair.d.ts +2 -2
- package/dist/schema/nodes/stair.js +3 -3
- package/dist/schema/nodes/structural-grid.d.ts +1 -1
- package/dist/schema/nodes/structural-grid.js +1 -1
- package/dist/schema/nodes/turbine-vent.d.ts +8 -2
- package/dist/schema/nodes/turbine-vent.d.ts.map +1 -1
- package/dist/schema/nodes/turbine-vent.js +4 -2
- package/dist/schema/nodes/unit.d.ts +33 -0
- package/dist/schema/nodes/unit.d.ts.map +1 -0
- package/dist/schema/nodes/unit.js +13 -0
- package/dist/schema/nodes/wall.d.ts +5 -5
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +13 -6
- package/dist/schema/nodes/window.d.ts +10 -3
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +6 -2
- package/dist/schema/nodes/zone.d.ts +2 -2
- package/dist/schema/nodes/zone.js +2 -2
- package/dist/schema/scene-material.js +2 -2
- package/dist/schema/types.d.ts +815 -118
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +79 -46
- package/dist/services/alignment-anchors.d.ts +6 -11
- package/dist/services/alignment-anchors.d.ts.map +1 -1
- package/dist/services/alignment-anchors.js +7 -34
- package/dist/services/drag-session.d.ts +4 -4
- package/dist/services/drag-session.js +1 -1
- package/dist/services/hosting.d.ts +4 -10
- package/dist/services/hosting.d.ts.map +1 -1
- package/dist/services/hosting.js +6 -16
- package/dist/services/index.d.ts +16 -13
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +16 -13
- package/dist/services/level-height.d.ts +2 -2
- package/dist/services/level-height.js +3 -3
- package/dist/services/movement.d.ts +3 -3
- package/dist/services/movement.js +2 -2
- package/dist/services/port-connectivity.d.ts +1 -1
- package/dist/services/port-connectivity.js +1 -1
- package/dist/services/riser-diagram.d.ts +1 -1
- package/dist/services/shelf-board.d.ts +5 -0
- package/dist/services/shelf-board.d.ts.map +1 -0
- package/dist/services/shelf-board.js +15 -0
- package/dist/services/storey.d.ts +2 -2
- package/dist/services/storey.js +2 -2
- package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts +13 -0
- package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts.map +1 -0
- package/dist/services/surface-hosting-procedural-parity.fixtures.js +4691 -0
- package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts +1060 -0
- package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts.map +1 -0
- package/dist/services/surface-hosting-shelf-parity.fixtures.js +3127 -0
- package/dist/services/surface-hosting.d.ts +88 -0
- package/dist/services/surface-hosting.d.ts.map +1 -0
- package/dist/services/surface-hosting.js +268 -0
- package/dist/services/surface-region.d.ts +8 -0
- package/dist/services/surface-region.d.ts.map +1 -0
- package/dist/services/surface-region.js +44 -0
- package/dist/services/system-graph.d.ts +12 -1
- package/dist/services/system-graph.d.ts.map +1 -1
- package/dist/services/system-graph.js +36 -6
- package/dist/services/validate-dwv.d.ts +1 -1
- package/dist/services/validate-dwv.js +1 -1
- package/dist/store/actions/node-actions.d.ts +9 -2
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +475 -24
- package/dist/store/history-control.d.ts +3 -3
- package/dist/store/history-invalidation.d.ts +3 -0
- package/dist/store/history-invalidation.d.ts.map +1 -0
- package/dist/store/history-invalidation.js +72 -0
- package/dist/store/scene-hydration.d.ts +5 -0
- package/dist/store/scene-hydration.d.ts.map +1 -0
- package/dist/store/scene-hydration.js +57 -0
- package/dist/store/use-interactive.d.ts +2 -2
- package/dist/store/use-live-terrain.d.ts +1 -1
- package/dist/store/use-scene.d.ts +7 -4
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +361 -87
- package/dist/systems/elevator/elevator-dispatch.d.ts +2 -2
- package/dist/systems/elevator/elevator-dispatch.js +1 -1
- package/dist/systems/elevator/elevator-geometry.d.ts +1 -1
- package/dist/systems/elevator/elevator-opening-sync.d.ts +1 -1
- package/dist/systems/elevator/elevator-opening-sync.js +2 -2
- package/dist/systems/elevator/elevator-opening-system.js +3 -3
- package/dist/systems/elevator/elevator-runtime.d.ts +3 -3
- package/dist/systems/elevator/elevator-runtime.js +3 -3
- package/dist/systems/elevator/elevator-service.d.ts +1 -1
- package/dist/systems/elevator/elevator-service.js +1 -1
- package/dist/systems/fence/fence-centerline.d.ts +2 -2
- package/dist/systems/fence/fence-centerline.js +2 -2
- package/dist/systems/fence/fence-spline.d.ts +2 -2
- package/dist/systems/roof/roof-elevation-system.d.ts +3 -0
- package/dist/systems/roof/roof-elevation-system.d.ts.map +1 -0
- package/dist/systems/roof/roof-elevation-system.js +94 -0
- package/dist/systems/roof/roof-elevation.d.ts +4 -0
- package/dist/systems/roof/roof-elevation.d.ts.map +1 -0
- package/dist/systems/roof/roof-elevation.js +95 -0
- package/dist/systems/roof/roof-footprint.d.ts +17 -0
- package/dist/systems/roof/roof-footprint.d.ts.map +1 -0
- package/dist/systems/roof/roof-footprint.js +83 -0
- package/dist/systems/slab/slab-placement.d.ts +1 -1
- package/dist/systems/slab/slab-support.d.ts +1 -1
- package/dist/systems/slab/slab-support.js +4 -4
- package/dist/systems/stair/stair-flight.d.ts +17 -0
- package/dist/systems/stair/stair-flight.d.ts.map +1 -0
- package/dist/systems/stair/stair-flight.js +27 -0
- package/dist/systems/stair/stair-footprint.d.ts +1 -1
- package/dist/systems/stair/stair-opening-preview.d.ts +1621 -1267
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-preview.js +2 -2
- package/dist/systems/stair/stair-opening-sync.d.ts +1 -1
- package/dist/systems/stair/stair-opening-sync.js +6 -6
- package/dist/systems/stair/stair-opening-system.d.ts +1 -0
- package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-system.js +100 -103
- package/dist/systems/stair/stair-rise.d.ts +1 -1
- package/dist/systems/stair/stair-rise.d.ts.map +1 -1
- package/dist/systems/stair/stair-rise.js +23 -24
- package/dist/systems/wall/wall-curve.d.ts +3 -2
- package/dist/systems/wall/wall-curve.d.ts.map +1 -1
- package/dist/systems/wall/wall-curve.js +73 -0
- package/dist/systems/wall/wall-footprint.d.ts +3 -2
- package/dist/systems/wall/wall-footprint.d.ts.map +1 -1
- package/dist/systems/wall/wall-footprint.js +3 -2
- package/dist/systems/wall/wall-mitering.d.ts +1 -1
- package/dist/systems/wall/wall-mitering.js +1 -1
- package/dist/systems/wall/wall-move.d.ts +1 -1
- package/dist/systems/wall/wall-top.d.ts +1 -1
- package/dist/systems/wall/wall-topology.d.ts +2 -2
- package/dist/systems/wall/wall-topology.js +4 -4
- package/dist/utils/clone-scene-graph.d.ts +3 -3
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +35 -3
- package/dist/utils/scene-migrations.d.ts +3 -3
- package/dist/utils/scene-migrations.js +3 -3
- package/dist/utils/vertical-scene-migration.js +5 -5
- package/dist/validation/validate-build-json.d.ts +7 -1
- package/dist/validation/validate-build-json.d.ts.map +1 -1
- package/dist/validation/validate-build-json.js +92 -4
- package/package.json +23 -5
- package/dist/systems/elevator/elevator-runtime-system.d.ts +0 -2
- package/dist/systems/elevator/elevator-runtime-system.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-runtime-system.js +0 -8
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure plan (XZ) footprint math — one source for spatial-grid collision and
|
|
3
|
+
* alignment anchors. The `@pascal-app/core/plan-footprint` subpath is the seam
|
|
4
|
+
* for a follow-up that consolidates MCP layout clearance onto these helpers.
|
|
5
|
+
*
|
|
6
|
+
* ## Invariant
|
|
7
|
+
* Callers share `planFootprintCorners` / `planFootprintAABB`. Do not invent a
|
|
8
|
+
* third rotation-aware plan AABB path beside this module.
|
|
9
|
+
*
|
|
10
|
+
* ## Gap call-site meanings (for the follow-up overlap helper)
|
|
11
|
+
* When an expand-then-intersect overlap check lands here, treat `gap` as
|
|
12
|
+
* **minimum free space** (expand each box by `gap`, then intersect):
|
|
13
|
+
* - Packing / furnish: typically `gap ≈ 0.08` for breathing room between items
|
|
14
|
+
* - check / verify collision: use `gap = 0` for true interpenetration only
|
|
15
|
+
* Do not share one default blindly across both questions.
|
|
16
|
+
*
|
|
17
|
+
* ## Scope
|
|
18
|
+
* Foundation only. Does not move door keep-outs, level ancestry, or furnish
|
|
19
|
+
* search into core. Item-scaled / attach-aware wrappers stay with callers
|
|
20
|
+
* until the MCP consolidation follow-up.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Four XZ corners of a centred footprint at `position`, rotated by Y
|
|
24
|
+
* rotation. Matches spatial-grid `getItemFootprint` convention:
|
|
25
|
+
* local +X maps with (cos, sin), local +Z with (-sin, cos) terms as used
|
|
26
|
+
* in the existing corner formula.
|
|
27
|
+
*/
|
|
28
|
+
export function planFootprintCorners(position, dimensions, rotationY, inset = 0) {
|
|
29
|
+
const [x, , z] = position;
|
|
30
|
+
const [w, , d] = dimensions;
|
|
31
|
+
const halfW = Math.max(0, w / 2 - inset);
|
|
32
|
+
const halfD = Math.max(0, d / 2 - inset);
|
|
33
|
+
const cos = Math.cos(rotationY);
|
|
34
|
+
const sin = Math.sin(rotationY);
|
|
35
|
+
return [
|
|
36
|
+
[x + (-halfW * cos + halfD * sin), z + (-halfW * sin - halfD * cos)],
|
|
37
|
+
[x + (halfW * cos + halfD * sin), z + (halfW * sin - halfD * cos)],
|
|
38
|
+
[x + (halfW * cos - halfD * sin), z + (halfW * sin + halfD * cos)],
|
|
39
|
+
[x + (-halfW * cos - halfD * sin), z + (-halfW * sin + halfD * cos)],
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Axis-aligned XZ extent of a footprint. Equivalent to the AABB of
|
|
44
|
+
* `planFootprintCorners` (no inset) and to spatial-grid `footprintBoundsXZ`.
|
|
45
|
+
*/
|
|
46
|
+
export function planFootprintAABB(position, dimensions, rotationY) {
|
|
47
|
+
const [width, , depth] = dimensions;
|
|
48
|
+
const cos = Math.abs(Math.cos(rotationY));
|
|
49
|
+
const sin = Math.abs(Math.sin(rotationY));
|
|
50
|
+
const rotatedW = width * cos + depth * sin;
|
|
51
|
+
const rotatedD = width * sin + depth * cos;
|
|
52
|
+
return {
|
|
53
|
+
minX: position[0] - rotatedW / 2,
|
|
54
|
+
maxX: position[0] + rotatedW / 2,
|
|
55
|
+
minZ: position[2] - rotatedD / 2,
|
|
56
|
+
maxZ: position[2] + rotatedD / 2,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polygon-union.d.ts","sourceRoot":"","sources":["../../src/lib/polygon-union.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AA6TtC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,CAShE;AA4CD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,CAkBjG"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
const EPSILON = 1e-7;
|
|
2
|
+
const KEY_SCALE = 1e6;
|
|
3
|
+
function pointsEqual(a, b, tolerance = EPSILON) {
|
|
4
|
+
return Math.hypot(a[0] - b[0], a[1] - b[1]) <= tolerance;
|
|
5
|
+
}
|
|
6
|
+
function pointKey(point) {
|
|
7
|
+
return `${Math.round(point[0] * KEY_SCALE)}:${Math.round(point[1] * KEY_SCALE)}`;
|
|
8
|
+
}
|
|
9
|
+
function interpolate(a, b, t) {
|
|
10
|
+
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
|
|
11
|
+
}
|
|
12
|
+
function cross(ax, ay, bx, by) {
|
|
13
|
+
return ax * by - ay * bx;
|
|
14
|
+
}
|
|
15
|
+
function polygonArea(points) {
|
|
16
|
+
let area = 0;
|
|
17
|
+
for (let i = 0; i < points.length; i++) {
|
|
18
|
+
const current = points[i];
|
|
19
|
+
const next = points[(i + 1) % points.length];
|
|
20
|
+
area += current[0] * next[1] - next[0] * current[1];
|
|
21
|
+
}
|
|
22
|
+
return area / 2;
|
|
23
|
+
}
|
|
24
|
+
function pointOnSegment(point, start, end) {
|
|
25
|
+
const dx = end[0] - start[0];
|
|
26
|
+
const dz = end[1] - start[1];
|
|
27
|
+
const crossValue = cross(point[0] - start[0], point[1] - start[1], dx, dz);
|
|
28
|
+
if (Math.abs(crossValue) > EPSILON)
|
|
29
|
+
return false;
|
|
30
|
+
const dot = (point[0] - start[0]) * (point[0] - end[0]) + (point[1] - start[1]) * (point[1] - end[1]);
|
|
31
|
+
return dot <= EPSILON;
|
|
32
|
+
}
|
|
33
|
+
function pointInPolygonOrOnBoundary(point, polygon) {
|
|
34
|
+
if (polygon.some((start, index) => pointOnSegment(point, start, polygon[(index + 1) % polygon.length]))) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return pointInPolygon(point, polygon);
|
|
38
|
+
}
|
|
39
|
+
function pointInPolygon(point, polygon) {
|
|
40
|
+
let inside = false;
|
|
41
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
42
|
+
const pi = polygon[i];
|
|
43
|
+
const pj = polygon[j];
|
|
44
|
+
if (pointOnSegment(point, pj, pi))
|
|
45
|
+
return false;
|
|
46
|
+
const intersects = pi[1] > point[1] !== pj[1] > point[1] &&
|
|
47
|
+
point[0] < ((pj[0] - pi[0]) * (point[1] - pi[1])) / (pj[1] - pi[1]) + pi[0];
|
|
48
|
+
if (intersects)
|
|
49
|
+
inside = !inside;
|
|
50
|
+
}
|
|
51
|
+
return inside;
|
|
52
|
+
}
|
|
53
|
+
function normalizeRing(ring) {
|
|
54
|
+
const normalized = [];
|
|
55
|
+
for (const [x, z] of ring) {
|
|
56
|
+
if (!Number.isFinite(x) || !Number.isFinite(z))
|
|
57
|
+
continue;
|
|
58
|
+
const point = [x, z];
|
|
59
|
+
const previous = normalized[normalized.length - 1];
|
|
60
|
+
if (!previous || !pointsEqual(previous, point)) {
|
|
61
|
+
normalized.push(point);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const first = normalized[0];
|
|
65
|
+
const last = normalized[normalized.length - 1];
|
|
66
|
+
if (first && last && pointsEqual(first, last)) {
|
|
67
|
+
normalized.pop();
|
|
68
|
+
}
|
|
69
|
+
if (normalized.length < 3 || Math.abs(polygonArea(normalized)) <= EPSILON)
|
|
70
|
+
return [];
|
|
71
|
+
return polygonArea(normalized) < 0 ? [...normalized].reverse() : normalized;
|
|
72
|
+
}
|
|
73
|
+
function addSplit(edge, t) {
|
|
74
|
+
if (t < -EPSILON || t > 1 + EPSILON)
|
|
75
|
+
return;
|
|
76
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
77
|
+
if (edge.splits.some((split) => Math.abs(split - clamped) <= EPSILON))
|
|
78
|
+
return;
|
|
79
|
+
edge.splits.push(clamped);
|
|
80
|
+
}
|
|
81
|
+
function parameterOnEdge(point, edge) {
|
|
82
|
+
const dx = edge.end[0] - edge.start[0];
|
|
83
|
+
const dz = edge.end[1] - edge.start[1];
|
|
84
|
+
const lengthSquared = dx * dx + dz * dz;
|
|
85
|
+
if (lengthSquared <= EPSILON)
|
|
86
|
+
return 0;
|
|
87
|
+
return ((point[0] - edge.start[0]) * dx + (point[1] - edge.start[1]) * dz) / lengthSquared;
|
|
88
|
+
}
|
|
89
|
+
function addIntersectionSplits(left, right) {
|
|
90
|
+
const rx = left.end[0] - left.start[0];
|
|
91
|
+
const rz = left.end[1] - left.start[1];
|
|
92
|
+
const sx = right.end[0] - right.start[0];
|
|
93
|
+
const sz = right.end[1] - right.start[1];
|
|
94
|
+
const qpx = right.start[0] - left.start[0];
|
|
95
|
+
const qpz = right.start[1] - left.start[1];
|
|
96
|
+
const denominator = cross(rx, rz, sx, sz);
|
|
97
|
+
const numerator = cross(qpx, qpz, rx, rz);
|
|
98
|
+
if (Math.abs(denominator) <= EPSILON) {
|
|
99
|
+
if (Math.abs(numerator) > EPSILON)
|
|
100
|
+
return;
|
|
101
|
+
for (const point of [left.start, left.end, right.start, right.end]) {
|
|
102
|
+
if (pointOnSegment(point, left.start, left.end) &&
|
|
103
|
+
pointOnSegment(point, right.start, right.end)) {
|
|
104
|
+
addSplit(left, parameterOnEdge(point, left));
|
|
105
|
+
addSplit(right, parameterOnEdge(point, right));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const t = cross(qpx, qpz, sx, sz) / denominator;
|
|
111
|
+
const u = cross(qpx, qpz, rx, rz) / denominator;
|
|
112
|
+
if (t < -EPSILON || t > 1 + EPSILON || u < -EPSILON || u > 1 + EPSILON)
|
|
113
|
+
return;
|
|
114
|
+
addSplit(left, t);
|
|
115
|
+
addSplit(right, u);
|
|
116
|
+
}
|
|
117
|
+
function buildEdges(polygons) {
|
|
118
|
+
const edges = [];
|
|
119
|
+
polygons.forEach((polygon, polygonIndex) => {
|
|
120
|
+
for (let i = 0; i < polygon.length; i++) {
|
|
121
|
+
edges.push({
|
|
122
|
+
start: polygon[i],
|
|
123
|
+
end: polygon[(i + 1) % polygon.length],
|
|
124
|
+
polygonIndex,
|
|
125
|
+
splits: [0, 1],
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
for (let i = 0; i < edges.length; i++) {
|
|
130
|
+
for (let j = i + 1; j < edges.length; j++) {
|
|
131
|
+
const left = edges[i];
|
|
132
|
+
const right = edges[j];
|
|
133
|
+
if (left.polygonIndex === right.polygonIndex)
|
|
134
|
+
continue;
|
|
135
|
+
addIntersectionSplits(left, right);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return edges;
|
|
139
|
+
}
|
|
140
|
+
function buildBoundarySegments(edges, polygons) {
|
|
141
|
+
const segments = [];
|
|
142
|
+
for (const edge of edges) {
|
|
143
|
+
const splits = [...edge.splits].sort((a, b) => a - b);
|
|
144
|
+
for (let i = 0; i < splits.length - 1; i++) {
|
|
145
|
+
const startT = splits[i];
|
|
146
|
+
const endT = splits[i + 1];
|
|
147
|
+
if (endT - startT <= EPSILON)
|
|
148
|
+
continue;
|
|
149
|
+
const start = interpolate(edge.start, edge.end, startT);
|
|
150
|
+
const end = interpolate(edge.start, edge.end, endT);
|
|
151
|
+
const mid = interpolate(edge.start, edge.end, (startT + endT) / 2);
|
|
152
|
+
const insideAnother = polygons.some((polygon, index) => index !== edge.polygonIndex && pointInPolygon(mid, polygon));
|
|
153
|
+
if (!insideAnother) {
|
|
154
|
+
segments.push({ start, end, used: false });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return removeDuplicateInteriorSegments(segments);
|
|
159
|
+
}
|
|
160
|
+
function segmentKey(segment) {
|
|
161
|
+
const start = pointKey(segment.start);
|
|
162
|
+
const end = pointKey(segment.end);
|
|
163
|
+
return start < end ? `${start}|${end}` : `${end}|${start}`;
|
|
164
|
+
}
|
|
165
|
+
function removeDuplicateInteriorSegments(segments) {
|
|
166
|
+
const groups = new Map();
|
|
167
|
+
for (const segment of segments) {
|
|
168
|
+
const key = segmentKey(segment);
|
|
169
|
+
const group = groups.get(key);
|
|
170
|
+
if (group) {
|
|
171
|
+
group.push(segment);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
groups.set(key, [segment]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const result = [];
|
|
178
|
+
for (const group of groups.values()) {
|
|
179
|
+
if (group.length === 1) {
|
|
180
|
+
result.push(group[0]);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const firstStart = pointKey(group[0].start);
|
|
184
|
+
const firstEnd = pointKey(group[0].end);
|
|
185
|
+
const hasOppositeDirection = group.some((segment) => pointKey(segment.start) === firstEnd && pointKey(segment.end) === firstStart);
|
|
186
|
+
if (!hasOppositeDirection) {
|
|
187
|
+
result.push(group[0]);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
function assembleRings(segments) {
|
|
193
|
+
const byStart = new Map();
|
|
194
|
+
for (const segment of segments) {
|
|
195
|
+
const key = pointKey(segment.start);
|
|
196
|
+
const group = byStart.get(key);
|
|
197
|
+
if (group) {
|
|
198
|
+
group.push(segment);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
byStart.set(key, [segment]);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const rings = [];
|
|
205
|
+
const nextBoundarySegment = (ring, candidates) => {
|
|
206
|
+
const previous = ring[ring.length - 2];
|
|
207
|
+
const current = ring[ring.length - 1];
|
|
208
|
+
const incomingX = current[0] - previous[0];
|
|
209
|
+
const incomingZ = current[1] - previous[1];
|
|
210
|
+
const reverseIncomingAngle = Math.atan2(-incomingZ, -incomingX);
|
|
211
|
+
const clockwiseTurn = (segment) => {
|
|
212
|
+
const outgoingAngle = Math.atan2(segment.end[1] - current[1], segment.end[0] - current[0]);
|
|
213
|
+
const turn = reverseIncomingAngle - outgoingAngle;
|
|
214
|
+
return ((turn % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);
|
|
215
|
+
};
|
|
216
|
+
return [...candidates].sort((left, right) => {
|
|
217
|
+
return (clockwiseTurn(left) - clockwiseTurn(right) ||
|
|
218
|
+
pointKey(left.end).localeCompare(pointKey(right.end)));
|
|
219
|
+
})[0];
|
|
220
|
+
};
|
|
221
|
+
for (const firstSegment of segments) {
|
|
222
|
+
if (firstSegment.used)
|
|
223
|
+
continue;
|
|
224
|
+
firstSegment.used = true;
|
|
225
|
+
const ring = [firstSegment.start, firstSegment.end];
|
|
226
|
+
const startKey = pointKey(firstSegment.start);
|
|
227
|
+
let currentKey = pointKey(firstSegment.end);
|
|
228
|
+
while (currentKey !== startKey) {
|
|
229
|
+
const candidates = byStart.get(currentKey)?.filter((segment) => !segment.used) ?? [];
|
|
230
|
+
const next = nextBoundarySegment(ring, candidates);
|
|
231
|
+
if (!next)
|
|
232
|
+
break;
|
|
233
|
+
next.used = true;
|
|
234
|
+
ring.push(next.end);
|
|
235
|
+
currentKey = pointKey(next.end);
|
|
236
|
+
}
|
|
237
|
+
if (currentKey !== startKey)
|
|
238
|
+
continue;
|
|
239
|
+
const last = ring[ring.length - 1];
|
|
240
|
+
if (last && pointsEqual(ring[0], last)) {
|
|
241
|
+
ring.pop();
|
|
242
|
+
}
|
|
243
|
+
const normalized = normalizeRing(ring);
|
|
244
|
+
if (normalized.length >= 3) {
|
|
245
|
+
rings.push(normalized);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return rings;
|
|
249
|
+
}
|
|
250
|
+
export function unionPolygons(polygons) {
|
|
251
|
+
const validPolygons = polygons.map(normalizeRing).filter((polygon) => polygon.length >= 3);
|
|
252
|
+
if (validPolygons.length <= 1)
|
|
253
|
+
return validPolygons;
|
|
254
|
+
const edges = buildEdges(validPolygons);
|
|
255
|
+
const segments = buildBoundarySegments(edges, validPolygons);
|
|
256
|
+
const rings = assembleRings(segments);
|
|
257
|
+
return rings.length > 0 ? rings : validPolygons;
|
|
258
|
+
}
|
|
259
|
+
function buildDifferenceBoundarySegments(edges, polygons) {
|
|
260
|
+
const subject = polygons[0];
|
|
261
|
+
const cutters = polygons.slice(1);
|
|
262
|
+
if (!subject)
|
|
263
|
+
return [];
|
|
264
|
+
const segments = [];
|
|
265
|
+
for (const edge of edges) {
|
|
266
|
+
const splits = [...edge.splits].sort((a, b) => a - b);
|
|
267
|
+
for (let i = 0; i < splits.length - 1; i++) {
|
|
268
|
+
const startT = splits[i];
|
|
269
|
+
const endT = splits[i + 1];
|
|
270
|
+
if (endT - startT <= EPSILON)
|
|
271
|
+
continue;
|
|
272
|
+
const start = interpolate(edge.start, edge.end, startT);
|
|
273
|
+
const end = interpolate(edge.start, edge.end, endT);
|
|
274
|
+
const mid = interpolate(edge.start, edge.end, (startT + endT) / 2);
|
|
275
|
+
if (edge.polygonIndex === 0) {
|
|
276
|
+
const insideCutter = cutters.some((cutter) => pointInPolygonOrOnBoundary(mid, cutter));
|
|
277
|
+
if (!insideCutter) {
|
|
278
|
+
segments.push({ start, end, used: false });
|
|
279
|
+
}
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
const insideSubject = pointInPolygon(mid, subject);
|
|
283
|
+
const insideAnotherCutter = cutters.some((cutter, cutterIndex) => cutterIndex !== edge.polygonIndex - 1 && pointInPolygonOrOnBoundary(mid, cutter));
|
|
284
|
+
if (insideSubject && !insideAnotherCutter) {
|
|
285
|
+
segments.push({ start: end, end: start, used: false });
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return removeDuplicateInteriorSegments(segments);
|
|
290
|
+
}
|
|
291
|
+
export function subtractPolygonsFromPolygon(subject, cutters) {
|
|
292
|
+
const validSubject = normalizeRing(subject);
|
|
293
|
+
if (validSubject.length < 3)
|
|
294
|
+
return [];
|
|
295
|
+
const validCutters = cutters.map(normalizeRing).filter((polygon) => polygon.length >= 3);
|
|
296
|
+
if (validCutters.length === 0)
|
|
297
|
+
return [validSubject];
|
|
298
|
+
const polygons = [validSubject, ...validCutters];
|
|
299
|
+
const edges = buildEdges(polygons);
|
|
300
|
+
const segments = buildDifferenceBoundarySegments(edges, polygons);
|
|
301
|
+
const rings = assembleRings(segments);
|
|
302
|
+
if (rings.length > 0)
|
|
303
|
+
return rings;
|
|
304
|
+
const fullyCovered = validSubject.every((point) => validCutters.some((cutter) => pointInPolygonOrOnBoundary(point, cutter)));
|
|
305
|
+
return fullyCovered ? [] : [validSubject];
|
|
306
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type RoofOverlapEntry = {
|
|
2
|
+
roofId: string;
|
|
3
|
+
segmentId: string;
|
|
4
|
+
supportRoofId?: string;
|
|
5
|
+
supportRoofSegmentId?: string;
|
|
6
|
+
roofType?: string;
|
|
7
|
+
width: number;
|
|
8
|
+
depth: number;
|
|
9
|
+
};
|
|
10
|
+
export type RoofPlanBounds = {
|
|
11
|
+
minX: number;
|
|
12
|
+
minZ: number;
|
|
13
|
+
maxX: number;
|
|
14
|
+
maxZ: number;
|
|
15
|
+
};
|
|
16
|
+
export type RoofPlanSegment = {
|
|
17
|
+
position: readonly [number, number, number];
|
|
18
|
+
rotation?: number;
|
|
19
|
+
width: number;
|
|
20
|
+
depth: number;
|
|
21
|
+
};
|
|
22
|
+
export type RoofPlan = {
|
|
23
|
+
position: readonly [number, number, number];
|
|
24
|
+
rotation?: number;
|
|
25
|
+
segments: readonly RoofPlanSegment[];
|
|
26
|
+
};
|
|
27
|
+
export declare function compareRoofOverlapIdentity(a: RoofOverlapEntry, b: RoofOverlapEntry): number;
|
|
28
|
+
export declare function roofOverlapEntryOwns(candidate: RoofOverlapEntry, current: RoofOverlapEntry, epsilon?: number): boolean;
|
|
29
|
+
export declare function roofPlanOverlapEntryOwns(candidate: RoofOverlapEntry, current: RoofOverlapEntry, epsilon?: number): boolean;
|
|
30
|
+
export declare function getRoofPlanBounds(roof: RoofPlan): RoofPlanBounds | null;
|
|
31
|
+
export declare function roofPlanBoundsOverlap(a: RoofPlanBounds, b: RoofPlanBounds, epsilon?: number): boolean;
|
|
32
|
+
//# sourceMappingURL=roof-overlap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roof-overlap.d.ts","sourceRoot":"","sources":["../../src/lib/roof-overlap.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAA;CACrC,CAAA;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAG3F;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,gBAAgB,EACzB,OAAO,SAAO,GACb,OAAO,CAiBT;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,gBAAgB,EACzB,OAAO,SAAO,GACb,OAAO,CAYT;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,GAAG,IAAI,CAmCvE;AAED,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,cAAc,EACjB,CAAC,EAAE,cAAc,EACjB,OAAO,SAAO,GACb,OAAO,CAOT"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export function compareRoofOverlapIdentity(a, b) {
|
|
2
|
+
const roofOrder = a.roofId.localeCompare(b.roofId);
|
|
3
|
+
return roofOrder !== 0 ? roofOrder : a.segmentId.localeCompare(b.segmentId);
|
|
4
|
+
}
|
|
5
|
+
export function roofOverlapEntryOwns(candidate, current, epsilon = 1e-6) {
|
|
6
|
+
const candidateIsMountedOnCurrent = candidate.supportRoofId === current.roofId ||
|
|
7
|
+
candidate.supportRoofSegmentId === current.segmentId;
|
|
8
|
+
if (candidateIsMountedOnCurrent)
|
|
9
|
+
return false;
|
|
10
|
+
const currentIsMountedOnCandidate = current.supportRoofId === candidate.roofId ||
|
|
11
|
+
current.supportRoofSegmentId === candidate.segmentId;
|
|
12
|
+
if (currentIsMountedOnCandidate)
|
|
13
|
+
return true;
|
|
14
|
+
const candidateArea = candidate.width * candidate.depth;
|
|
15
|
+
const currentArea = current.width * current.depth;
|
|
16
|
+
return (candidateArea > currentArea + epsilon ||
|
|
17
|
+
(Math.abs(candidateArea - currentArea) <= epsilon &&
|
|
18
|
+
compareRoofOverlapIdentity(candidate, current) < 0));
|
|
19
|
+
}
|
|
20
|
+
export function roofPlanOverlapEntryOwns(candidate, current, epsilon = 1e-6) {
|
|
21
|
+
const candidateIsMountedOnCurrent = candidate.supportRoofId === current.roofId ||
|
|
22
|
+
candidate.supportRoofSegmentId === current.segmentId;
|
|
23
|
+
if (candidateIsMountedOnCurrent)
|
|
24
|
+
return true;
|
|
25
|
+
const currentIsMountedOnCandidate = current.supportRoofId === candidate.roofId ||
|
|
26
|
+
current.supportRoofSegmentId === candidate.segmentId;
|
|
27
|
+
if (currentIsMountedOnCandidate)
|
|
28
|
+
return false;
|
|
29
|
+
return roofOverlapEntryOwns(candidate, current, epsilon);
|
|
30
|
+
}
|
|
31
|
+
export function getRoofPlanBounds(roof) {
|
|
32
|
+
if (roof.segments.length === 0)
|
|
33
|
+
return null;
|
|
34
|
+
const roofRotation = roof.rotation ?? 0;
|
|
35
|
+
const roofCos = Math.cos(roofRotation);
|
|
36
|
+
const roofSin = Math.sin(roofRotation);
|
|
37
|
+
const bounds = {
|
|
38
|
+
minX: Number.POSITIVE_INFINITY,
|
|
39
|
+
minZ: Number.POSITIVE_INFINITY,
|
|
40
|
+
maxX: Number.NEGATIVE_INFINITY,
|
|
41
|
+
maxZ: Number.NEGATIVE_INFINITY,
|
|
42
|
+
};
|
|
43
|
+
for (const segment of roof.segments) {
|
|
44
|
+
const segmentRotation = segment.rotation ?? 0;
|
|
45
|
+
const segmentCos = Math.cos(segmentRotation);
|
|
46
|
+
const segmentSin = Math.sin(segmentRotation);
|
|
47
|
+
const halfWidth = Math.max(0, segment.width) / 2;
|
|
48
|
+
const halfDepth = Math.max(0, segment.depth) / 2;
|
|
49
|
+
for (const [x, z] of [
|
|
50
|
+
[-halfWidth, -halfDepth],
|
|
51
|
+
[halfWidth, -halfDepth],
|
|
52
|
+
[halfWidth, halfDepth],
|
|
53
|
+
[-halfWidth, halfDepth],
|
|
54
|
+
]) {
|
|
55
|
+
const roofX = segment.position[0] + x * segmentCos + z * segmentSin;
|
|
56
|
+
const roofZ = segment.position[2] - x * segmentSin + z * segmentCos;
|
|
57
|
+
const worldX = roof.position[0] + roofX * roofCos + roofZ * roofSin;
|
|
58
|
+
const worldZ = roof.position[2] - roofX * roofSin + roofZ * roofCos;
|
|
59
|
+
bounds.minX = Math.min(bounds.minX, worldX);
|
|
60
|
+
bounds.minZ = Math.min(bounds.minZ, worldZ);
|
|
61
|
+
bounds.maxX = Math.max(bounds.maxX, worldX);
|
|
62
|
+
bounds.maxZ = Math.max(bounds.maxZ, worldZ);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return bounds;
|
|
66
|
+
}
|
|
67
|
+
export function roofPlanBoundsOverlap(a, b, epsilon = 1e-6) {
|
|
68
|
+
return !(a.maxX < b.minX - epsilon ||
|
|
69
|
+
b.maxX < a.minX - epsilon ||
|
|
70
|
+
a.maxZ < b.minZ - epsilon ||
|
|
71
|
+
b.maxZ < a.minZ - epsilon);
|
|
72
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyNode, AnyNodeId } from '../schema/types';
|
|
1
|
+
import type { AnyNode, AnyNodeId } from '../schema/types.js';
|
|
2
2
|
export declare function selectionProxyIdFromMetadata(metadata: unknown): AnyNodeId | null;
|
|
3
3
|
export declare function resolveSelectionProxyId(node: AnyNode, nodes: Readonly<Record<string, AnyNode | undefined>>): AnyNodeId;
|
|
4
4
|
//# sourceMappingURL=selection-proxy.d.ts.map
|
|
@@ -1,18 +1,36 @@
|
|
|
1
|
-
import type { GeometryContext } from '../registry/types';
|
|
2
|
-
import type { SlabNode, WallNode } from '../schema';
|
|
1
|
+
import type { GeometryContext } from '../registry/types.js';
|
|
2
|
+
import type { AnyNode, AnyNodeId, SlabNode, WallNode } from '../schema/index.js';
|
|
3
3
|
export type SlabPolygonContext = {
|
|
4
4
|
/** Walls on the slab's level. */
|
|
5
5
|
walls: WallNode[];
|
|
6
6
|
/** Other slabs on the same level — the slab itself must be excluded. */
|
|
7
7
|
siblingSlabs: SlabNode[];
|
|
8
8
|
};
|
|
9
|
+
/** [ax, az, bx, bz] segment in plan space. */
|
|
10
|
+
type Segment = [number, number, number, number];
|
|
11
|
+
/** A sibling slab edge and the direction of its polygon interior. */
|
|
12
|
+
type NeighborSegment = {
|
|
13
|
+
slab: SlabNode;
|
|
14
|
+
segment: Segment;
|
|
15
|
+
bounds: Bounds;
|
|
16
|
+
elevation: number;
|
|
17
|
+
/** Unit normal pointing into the sibling polygon at this edge. */
|
|
18
|
+
inwardX: number;
|
|
19
|
+
inwardZ: number;
|
|
20
|
+
};
|
|
9
21
|
/**
|
|
10
22
|
* Derive a {@link SlabPolygonContext} from a registry `GeometryContext`:
|
|
11
23
|
* sibling slabs come from `ctx.siblings` (same kind, same parent, self
|
|
12
24
|
* excluded) and walls from the parent level's children.
|
|
13
25
|
*/
|
|
14
26
|
export declare function slabPolygonContextFromGeometry(ctx: GeometryContext | undefined): SlabPolygonContext;
|
|
15
|
-
export declare function
|
|
27
|
+
export declare function slabPolygonContextForLevel(parent: AnyNode | null, resolve: (id: AnyNodeId) => AnyNode | undefined, fallbackSlabs?: SlabNode[]): SlabPolygonContext;
|
|
28
|
+
export declare function getRenderableSlabPolygon(slabNode: SlabNode, context: SlabPolygonContext | PreparedSlabPolygonContext): Array<[number, number]>;
|
|
29
|
+
type WallCandidate = {
|
|
30
|
+
wall: WallNode;
|
|
31
|
+
segments: Segment[];
|
|
32
|
+
halfThickness: number;
|
|
33
|
+
};
|
|
16
34
|
export type SlabEdgeWallBandSnap = {
|
|
17
35
|
wallId: WallNode['id'];
|
|
18
36
|
/** The candidate edge translated perpendicular onto the wall centerline. */
|
|
@@ -29,4 +47,19 @@ export type SlabEdgeWallBandSnap = {
|
|
|
29
47
|
export declare function snapSlabEdgeToWallBand(a: [number, number], b: [number, number], walls: readonly WallNode[], options?: {
|
|
30
48
|
maxLateral?: number;
|
|
31
49
|
}): SlabEdgeWallBandSnap | null;
|
|
50
|
+
type Bounds = [number, number, number, number];
|
|
51
|
+
export declare function scopeSlabPolygonContext(slab: SlabNode, context: PreparedSlabPolygonContext): PreparedSlabPolygonContext;
|
|
52
|
+
export declare function slabPolygonContextChanges(before: PreparedSlabPolygonContext, after: PreparedSlabPolygonContext): (slab: SlabNode) => boolean;
|
|
53
|
+
type PreparedWallCandidate = WallCandidate & {
|
|
54
|
+
bounds: Bounds;
|
|
55
|
+
};
|
|
56
|
+
type PreparedSlabPolygonContext = SlabPolygonContext & {
|
|
57
|
+
wallCache: WeakMap<WallNode, PreparedWallCandidate>;
|
|
58
|
+
neighborCache: WeakMap<SlabNode, NeighborSegment[]>;
|
|
59
|
+
wallCandidates: PreparedWallCandidate[];
|
|
60
|
+
neighborSegments: NeighborSegment[];
|
|
61
|
+
siblingBreakTolerance: number;
|
|
62
|
+
};
|
|
63
|
+
export declare function prepareSlabPolygonContext(context: SlabPolygonContext, previous?: PreparedSlabPolygonContext): PreparedSlabPolygonContext;
|
|
64
|
+
export {};
|
|
32
65
|
//# sourceMappingURL=slab-polygon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slab-polygon.d.ts","sourceRoot":"","sources":["../../src/lib/slab-polygon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"slab-polygon.d.ts","sourceRoot":"","sources":["../../src/lib/slab-polygon.ts"],"names":[],"mappings":"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"}
|