@pascal-app/core 0.8.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/events/bus.d.ts +67 -13
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/scene-registry/item-clip-registry.d.ts +18 -0
- package/dist/hooks/scene-registry/item-clip-registry.d.ts.map +1 -0
- package/dist/hooks/scene-registry/item-clip-registry.js +10 -0
- package/dist/hooks/scene-registry/scene-registry.d.ts +14 -23
- package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.js +59 -26
- package/dist/hooks/scene-registry/scene-registry.test.d.ts +2 -0
- package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +1 -0
- package/dist/hooks/scene-registry/scene-registry.test.js +26 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +14 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.js +51 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +2 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +366 -0
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +79 -11
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +508 -141
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +28 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +109 -18
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +2 -0
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +363 -0
- package/dist/index.d.ts +36 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -6
- package/dist/lib/level-name.d.ts +4 -0
- package/dist/lib/level-name.d.ts.map +1 -0
- package/dist/lib/level-name.js +10 -0
- package/dist/lib/measurement-geometry.d.ts +19 -0
- package/dist/lib/measurement-geometry.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.js +232 -0
- package/dist/lib/measurement-geometry.test.d.ts +2 -0
- package/dist/lib/measurement-geometry.test.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.test.js +102 -0
- package/dist/lib/polygon-geometry.d.ts +0 -1
- package/dist/lib/polygon-geometry.d.ts.map +1 -1
- package/dist/lib/polygon-geometry.js +0 -18
- package/dist/lib/polygon-relations.d.ts +10 -0
- package/dist/lib/polygon-relations.d.ts.map +1 -0
- package/dist/lib/polygon-relations.js +73 -0
- package/dist/lib/selection-proxy.d.ts +4 -0
- package/dist/lib/selection-proxy.d.ts.map +1 -0
- package/dist/lib/selection-proxy.js +12 -0
- package/dist/lib/slab-polygon.d.ts +31 -2
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +525 -31
- package/dist/lib/slab-polygon.test.d.ts +2 -0
- package/dist/lib/slab-polygon.test.d.ts.map +1 -0
- package/dist/lib/slab-polygon.test.js +635 -0
- package/dist/lib/slots.d.ts +14 -0
- package/dist/lib/slots.d.ts.map +1 -0
- package/dist/lib/slots.js +26 -0
- package/dist/lib/space-detection-pause.test.d.ts +2 -0
- package/dist/lib/space-detection-pause.test.d.ts.map +1 -0
- package/dist/lib/space-detection-pause.test.js +42 -0
- package/dist/lib/space-detection.d.ts +54 -2
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +599 -124
- package/dist/lib/space-detection.test.d.ts +2 -0
- package/dist/lib/space-detection.test.d.ts.map +1 -0
- package/dist/lib/space-detection.test.js +376 -0
- package/dist/lib/wall-distance.d.ts +60 -0
- package/dist/lib/wall-distance.d.ts.map +1 -0
- package/dist/lib/wall-distance.js +85 -0
- package/dist/lib/zone-quantities.d.ts +21 -0
- package/dist/lib/zone-quantities.d.ts.map +1 -0
- package/dist/lib/zone-quantities.js +183 -0
- package/dist/lib/zone-quantities.test.d.ts +2 -0
- package/dist/lib/zone-quantities.test.d.ts.map +1 -0
- package/dist/lib/zone-quantities.test.js +82 -0
- package/dist/material-library.d.ts +20 -1
- package/dist/material-library.d.ts.map +1 -1
- package/dist/material-library.js +3737 -200
- package/dist/registry/__bench__/relations-resolver.bench.d.ts +15 -0
- package/dist/registry/__bench__/relations-resolver.bench.d.ts.map +1 -0
- package/dist/registry/__bench__/relations-resolver.bench.js +170 -0
- package/dist/registry/handles.d.ts +394 -0
- package/dist/registry/handles.d.ts.map +1 -0
- package/dist/registry/handles.js +24 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +4 -0
- package/dist/registry/registry.d.ts +136 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +282 -0
- package/dist/registry/registry.test.d.ts +2 -0
- package/dist/registry/registry.test.d.ts.map +1 -0
- package/dist/registry/registry.test.js +196 -0
- package/dist/registry/relations-resolver.d.ts +42 -0
- package/dist/registry/relations-resolver.d.ts.map +1 -0
- package/dist/registry/relations-resolver.js +77 -0
- package/dist/registry/relations-resolver.test.d.ts +2 -0
- package/dist/registry/relations-resolver.test.d.ts.map +1 -0
- package/dist/registry/relations-resolver.test.js +183 -0
- package/dist/registry/scene-api.d.ts +44 -0
- package/dist/registry/scene-api.d.ts.map +1 -0
- package/dist/registry/scene-api.js +111 -0
- package/dist/registry/scene-api.test.d.ts +2 -0
- package/dist/registry/scene-api.test.d.ts.map +1 -0
- package/dist/registry/scene-api.test.js +183 -0
- package/dist/registry/subtree.d.ts +67 -0
- package/dist/registry/subtree.d.ts.map +1 -0
- package/dist/registry/subtree.js +123 -0
- package/dist/registry/subtree.test.d.ts +2 -0
- package/dist/registry/subtree.test.d.ts.map +1 -0
- package/dist/registry/subtree.test.js +163 -0
- package/dist/registry/types.d.ts +2099 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +1 -0
- package/dist/schema/index.d.ts +35 -4
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +32 -4
- package/dist/schema/material.d.ts +13 -2
- package/dist/schema/material.d.ts.map +1 -1
- package/dist/schema/material.js +17 -5
- package/dist/schema/material.test.d.ts +2 -0
- package/dist/schema/material.test.d.ts.map +1 -0
- package/dist/schema/material.test.js +43 -0
- package/dist/schema/nodes/box-vent.d.ts +74 -0
- package/dist/schema/nodes/box-vent.d.ts.map +1 -0
- package/dist/schema/nodes/box-vent.js +63 -0
- package/dist/schema/nodes/building.d.ts +1 -1
- package/dist/schema/nodes/building.d.ts.map +1 -1
- package/dist/schema/nodes/building.js +3 -2
- package/dist/schema/nodes/cabinet.d.ts +534 -0
- package/dist/schema/nodes/cabinet.d.ts.map +1 -0
- package/dist/schema/nodes/cabinet.js +137 -0
- package/dist/schema/nodes/ceiling.d.ts +5 -2
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +5 -1
- package/dist/schema/nodes/chimney.d.ts +158 -0
- package/dist/schema/nodes/chimney.d.ts.map +1 -0
- package/dist/schema/nodes/chimney.js +67 -0
- package/dist/schema/nodes/column.d.ts +600 -7
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +589 -6
- package/dist/schema/nodes/cupola.d.ts +66 -0
- package/dist/schema/nodes/cupola.d.ts.map +1 -0
- package/dist/schema/nodes/cupola.js +28 -0
- package/dist/schema/nodes/door.d.ts +13 -5
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +12 -0
- package/dist/schema/nodes/dormer.d.ts +228 -0
- package/dist/schema/nodes/dormer.d.ts.map +1 -0
- package/dist/schema/nodes/dormer.js +119 -0
- package/dist/schema/nodes/downspout.d.ts +75 -0
- package/dist/schema/nodes/downspout.d.ts.map +1 -0
- package/dist/schema/nodes/downspout.js +63 -0
- package/dist/schema/nodes/duct-fitting.d.ts +91 -0
- package/dist/schema/nodes/duct-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/duct-fitting.js +92 -0
- package/dist/schema/nodes/duct-segment.d.ts +61 -0
- package/dist/schema/nodes/duct-segment.d.ts.map +1 -0
- package/dist/schema/nodes/duct-segment.js +73 -0
- package/dist/schema/nodes/duct-terminal.d.ts +57 -0
- package/dist/schema/nodes/duct-terminal.d.ts.map +1 -0
- package/dist/schema/nodes/duct-terminal.js +51 -0
- package/dist/schema/nodes/elevator.d.ts +106 -0
- package/dist/schema/nodes/elevator.d.ts.map +1 -0
- package/dist/schema/nodes/elevator.js +57 -0
- package/dist/schema/nodes/eyebrow-vent.d.ts +68 -0
- package/dist/schema/nodes/eyebrow-vent.d.ts.map +1 -0
- package/dist/schema/nodes/eyebrow-vent.js +40 -0
- package/dist/schema/nodes/fence.d.ts +19 -2
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +27 -2
- package/dist/schema/nodes/gutter.d.ts +84 -0
- package/dist/schema/nodes/gutter.d.ts.map +1 -0
- package/dist/schema/nodes/gutter.js +76 -0
- package/dist/schema/nodes/hvac-equipment.d.ts +63 -0
- package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -0
- package/dist/schema/nodes/hvac-equipment.js +55 -0
- package/dist/schema/nodes/item.d.ts +12 -0
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +20 -0
- package/dist/schema/nodes/level.d.ts +1 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +4 -0
- package/dist/schema/nodes/lineset.d.ts +42 -0
- package/dist/schema/nodes/lineset.d.ts.map +1 -0
- package/dist/schema/nodes/lineset.js +38 -0
- package/dist/schema/nodes/liquid-line.d.ts +34 -0
- package/dist/schema/nodes/liquid-line.d.ts.map +1 -0
- package/dist/schema/nodes/liquid-line.js +24 -0
- package/dist/schema/nodes/measurement.d.ts +306 -0
- package/dist/schema/nodes/measurement.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.js +87 -0
- package/dist/schema/nodes/measurement.test.d.ts +2 -0
- package/dist/schema/nodes/measurement.test.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.test.js +139 -0
- package/dist/schema/nodes/pipe-fitting.d.ts +56 -0
- package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-fitting.js +45 -0
- package/dist/schema/nodes/pipe-segment.d.ts +48 -0
- package/dist/schema/nodes/pipe-segment.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-segment.js +36 -0
- package/dist/schema/nodes/pipe-trap.d.ts +43 -0
- package/dist/schema/nodes/pipe-trap.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-trap.js +36 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +2 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +1 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.js +205 -0
- package/dist/schema/nodes/ridge-vent.d.ts +82 -0
- package/dist/schema/nodes/ridge-vent.d.ts.map +1 -0
- package/dist/schema/nodes/ridge-vent.js +248 -0
- package/dist/schema/nodes/roof-segment-shape.d.ts +90 -0
- package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.js +318 -0
- package/dist/schema/nodes/roof-segment-shape.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.test.js +175 -0
- package/dist/schema/nodes/roof-segment-surface.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-surface.test.js +48 -0
- package/dist/schema/nodes/roof-segment-trim.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-trim.test.js +107 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts +101 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.js +330 -0
- package/dist/schema/nodes/roof-segment-walls.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.test.js +92 -0
- package/dist/schema/nodes/roof-segment.d.ts +273 -3
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +539 -3
- package/dist/schema/nodes/roof.d.ts +8 -8
- package/dist/schema/nodes/roof.d.ts.map +1 -1
- package/dist/schema/nodes/roof.js +4 -16
- package/dist/schema/nodes/shelf.d.ts +106 -0
- package/dist/schema/nodes/shelf.d.ts.map +1 -0
- package/dist/schema/nodes/shelf.js +90 -0
- package/dist/schema/nodes/site.d.ts +1 -122
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/site.js +2 -6
- package/dist/schema/nodes/skylight.d.ts +279 -0
- package/dist/schema/nodes/skylight.d.ts.map +1 -0
- package/dist/schema/nodes/skylight.js +152 -0
- package/dist/schema/nodes/slab.d.ts +5 -2
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +5 -1
- package/dist/schema/nodes/solar-panel.d.ts +117 -0
- package/dist/schema/nodes/solar-panel.d.ts.map +1 -0
- package/dist/schema/nodes/solar-panel.js +47 -0
- package/dist/schema/nodes/stair-segment.d.ts +4 -4
- package/dist/schema/nodes/stair.d.ts +13 -12
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +3 -0
- package/dist/schema/nodes/surface-hole-metadata.d.ts +2 -0
- package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -1
- package/dist/schema/nodes/surface-hole-metadata.js +3 -1
- package/dist/schema/nodes/turbine-vent.d.ts +68 -0
- package/dist/schema/nodes/turbine-vent.d.ts.map +1 -0
- package/dist/schema/nodes/turbine-vent.js +41 -0
- package/dist/schema/nodes/wall.d.ts +245 -6
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +257 -0
- package/dist/schema/nodes/wall.test.d.ts +2 -0
- package/dist/schema/nodes/wall.test.d.ts.map +1 -0
- package/dist/schema/nodes/wall.test.js +208 -0
- package/dist/schema/nodes/window.d.ts +11 -3
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +12 -0
- package/dist/schema/nodes/zone.d.ts +2 -0
- package/dist/schema/nodes/zone.d.ts.map +1 -1
- package/dist/schema/nodes/zone.js +6 -0
- package/dist/schema/scene-material.d.ts +41 -0
- package/dist/schema/scene-material.d.ts.map +1 -0
- package/dist/schema/scene-material.js +9 -0
- package/dist/schema/types.d.ts +2850 -655
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +49 -0
- package/dist/services/alignment-anchors.d.ts +100 -0
- package/dist/services/alignment-anchors.d.ts.map +1 -0
- package/dist/services/alignment-anchors.js +312 -0
- package/dist/services/alignment-anchors.test.d.ts +2 -0
- package/dist/services/alignment-anchors.test.d.ts.map +1 -0
- package/dist/services/alignment-anchors.test.js +383 -0
- package/dist/services/alignment.d.ts +131 -0
- package/dist/services/alignment.d.ts.map +1 -0
- package/dist/services/alignment.js +171 -0
- package/dist/services/alignment.test.d.ts +2 -0
- package/dist/services/alignment.test.d.ts.map +1 -0
- package/dist/services/alignment.test.js +92 -0
- package/dist/services/drag-session.d.ts +47 -0
- package/dist/services/drag-session.d.ts.map +1 -0
- package/dist/services/drag-session.js +100 -0
- package/dist/services/drag-session.test.d.ts +2 -0
- package/dist/services/drag-session.test.d.ts.map +1 -0
- package/dist/services/drag-session.test.js +219 -0
- package/dist/services/hosting.d.ts +88 -0
- package/dist/services/hosting.d.ts.map +1 -0
- package/dist/services/hosting.js +131 -0
- package/dist/services/hosting.test.d.ts +2 -0
- package/dist/services/hosting.test.d.ts.map +1 -0
- package/dist/services/hosting.test.js +230 -0
- package/dist/services/index.d.ts +13 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +12 -0
- package/dist/services/level-height.d.ts +28 -0
- package/dist/services/level-height.d.ts.map +1 -0
- package/dist/services/level-height.js +62 -0
- package/dist/services/movement.d.ts +48 -0
- package/dist/services/movement.d.ts.map +1 -0
- package/dist/services/movement.js +65 -0
- package/dist/services/movement.test.d.ts +2 -0
- package/dist/services/movement.test.d.ts.map +1 -0
- package/dist/services/movement.test.js +133 -0
- package/dist/services/opening-guides.d.ts +141 -0
- package/dist/services/opening-guides.d.ts.map +1 -0
- package/dist/services/opening-guides.js +267 -0
- package/dist/services/opening-guides.test.d.ts +2 -0
- package/dist/services/opening-guides.test.d.ts.map +1 -0
- package/dist/services/opening-guides.test.js +208 -0
- package/dist/services/port-connectivity.d.ts +115 -0
- package/dist/services/port-connectivity.d.ts.map +1 -0
- package/dist/services/port-connectivity.js +300 -0
- package/dist/services/port-connectivity.test.d.ts +2 -0
- package/dist/services/port-connectivity.test.d.ts.map +1 -0
- package/dist/services/port-connectivity.test.js +297 -0
- package/dist/services/riser-diagram.d.ts +40 -0
- package/dist/services/riser-diagram.d.ts.map +1 -0
- package/dist/services/riser-diagram.js +110 -0
- package/dist/services/riser-diagram.test.d.ts +2 -0
- package/dist/services/riser-diagram.test.d.ts.map +1 -0
- package/dist/services/riser-diagram.test.js +66 -0
- package/dist/services/single-undo-dance.test.d.ts +2 -0
- package/dist/services/single-undo-dance.test.d.ts.map +1 -0
- package/dist/services/single-undo-dance.test.js +210 -0
- package/dist/services/snap.d.ts +80 -0
- package/dist/services/snap.d.ts.map +1 -0
- package/dist/services/snap.js +140 -0
- package/dist/services/snap.test.d.ts +2 -0
- package/dist/services/snap.test.d.ts.map +1 -0
- package/dist/services/snap.test.js +137 -0
- package/dist/services/system-graph.d.ts +30 -0
- package/dist/services/system-graph.d.ts.map +1 -0
- package/dist/services/system-graph.js +164 -0
- package/dist/services/system-graph.test.d.ts +2 -0
- package/dist/services/system-graph.test.d.ts.map +1 -0
- package/dist/services/system-graph.test.js +138 -0
- package/dist/services/validate-dwv.d.ts +32 -0
- package/dist/services/validate-dwv.d.ts.map +1 -0
- package/dist/services/validate-dwv.js +118 -0
- package/dist/services/validate-dwv.test.d.ts +2 -0
- package/dist/services/validate-dwv.test.d.ts.map +1 -0
- package/dist/services/validate-dwv.test.js +109 -0
- package/dist/solar-panel-presets.d.ts +17 -0
- package/dist/solar-panel-presets.d.ts.map +1 -0
- package/dist/solar-panel-presets.js +43 -0
- package/dist/store/actions/node-actions.d.ts +14 -2
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +585 -15
- package/dist/store/actions/node-mutation-sanitize.test.d.ts +2 -0
- package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +1 -0
- package/dist/store/actions/node-mutation-sanitize.test.js +147 -0
- package/dist/store/actions/reparent.test.d.ts +2 -0
- package/dist/store/actions/reparent.test.d.ts.map +1 -0
- package/dist/store/actions/reparent.test.js +212 -0
- package/dist/store/actions/ridge-vent-update.test.d.ts +2 -0
- package/dist/store/actions/ridge-vent-update.test.d.ts.map +1 -0
- package/dist/store/actions/ridge-vent-update.test.js +264 -0
- package/dist/store/history-control.d.ts +11 -0
- package/dist/store/history-control.d.ts.map +1 -1
- package/dist/store/history-control.js +33 -0
- package/dist/store/use-interactive.d.ts +39 -0
- package/dist/store/use-interactive.d.ts.map +1 -1
- package/dist/store/use-interactive.js +75 -0
- package/dist/store/use-live-node-overrides.d.ts +22 -0
- package/dist/store/use-live-node-overrides.d.ts.map +1 -0
- package/dist/store/use-live-node-overrides.js +59 -0
- package/dist/store/use-scene-dirty-tracking.test.d.ts +2 -0
- package/dist/store/use-scene-dirty-tracking.test.d.ts.map +1 -0
- package/dist/store/use-scene-dirty-tracking.test.js +68 -0
- package/dist/store/use-scene-elevator-migration.test.d.ts +2 -0
- package/dist/store/use-scene-elevator-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-elevator-migration.test.js +109 -0
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts +2 -0
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +1 -0
- package/dist/store/use-scene-measurement-roundtrip.test.js +97 -0
- package/dist/store/use-scene-plugins.test.d.ts +2 -0
- package/dist/store/use-scene-plugins.test.d.ts.map +1 -0
- package/dist/store/use-scene-plugins.test.js +51 -0
- package/dist/store/use-scene-wall-slot-migration.test.d.ts +2 -0
- package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-wall-slot-migration.test.js +210 -0
- package/dist/store/use-scene-window-migration.test.d.ts +2 -0
- package/dist/store/use-scene-window-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-window-migration.test.js +85 -0
- package/dist/store/use-scene.d.ts +28 -2
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +546 -49
- package/dist/systems/elevator/elevator-dispatch.d.ts +12 -0
- package/dist/systems/elevator/elevator-dispatch.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-dispatch.js +57 -0
- package/dist/systems/elevator/elevator-geometry.d.ts +15 -0
- package/dist/systems/elevator/elevator-geometry.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-geometry.js +50 -0
- package/dist/systems/elevator/elevator-opening-sync.d.ts +6 -0
- package/dist/systems/elevator/elevator-opening-sync.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-opening-sync.js +218 -0
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts +2 -0
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-opening-sync.test.js +146 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts +2 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-opening-system.js +48 -0
- package/dist/systems/elevator/elevator-runtime-system.d.ts +2 -0
- package/dist/systems/elevator/elevator-runtime-system.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-runtime-system.js +8 -0
- package/dist/systems/elevator/elevator-runtime.d.ts +18 -0
- package/dist/systems/elevator/elevator-runtime.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-runtime.js +225 -0
- package/dist/systems/elevator/elevator-runtime.test.d.ts +2 -0
- package/dist/systems/elevator/elevator-runtime.test.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-runtime.test.js +64 -0
- package/dist/systems/elevator/elevator-service.d.ts +19 -0
- package/dist/systems/elevator/elevator-service.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-service.js +111 -0
- package/dist/systems/fence/fence-centerline.d.ts +12 -0
- package/dist/systems/fence/fence-centerline.d.ts.map +1 -0
- package/dist/systems/fence/fence-centerline.js +37 -0
- package/dist/systems/fence/fence-spline.d.ts +39 -0
- package/dist/systems/fence/fence-spline.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.js +196 -0
- package/dist/systems/fence/fence-spline.test.d.ts +2 -0
- package/dist/systems/fence/fence-spline.test.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.test.js +136 -0
- package/dist/systems/stair/stair-footprint.d.ts +44 -0
- package/dist/systems/stair/stair-footprint.d.ts.map +1 -0
- package/dist/systems/stair/stair-footprint.js +178 -0
- package/dist/systems/stair/stair-opening-preview.d.ts +2447 -0
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-preview.js +93 -0
- package/dist/systems/stair/stair-opening-preview.test.d.ts +2 -0
- package/dist/systems/stair/stair-opening-preview.test.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-preview.test.js +80 -0
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.js +155 -147
- package/dist/systems/stair/stair-opening-sync.test.js +424 -2
- package/dist/systems/stair/stair-opening-system.d.ts +2 -0
- package/dist/systems/stair/stair-opening-system.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-system.js +104 -0
- package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
- package/dist/systems/wall/wall-mitering.js +38 -2
- package/dist/systems/wall/wall-mitering.test.d.ts +2 -0
- package/dist/systems/wall/wall-mitering.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-mitering.test.js +63 -0
- package/dist/systems/wall/wall-move.d.ts +48 -0
- package/dist/systems/wall/wall-move.d.ts.map +1 -0
- package/dist/systems/wall/wall-move.js +193 -0
- package/dist/utils/clone-scene-graph.d.ts +7 -4
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +29 -7
- package/dist/utils/clone-scene-graph.test.d.ts +2 -0
- package/dist/utils/clone-scene-graph.test.d.ts.map +1 -0
- package/dist/utils/clone-scene-graph.test.js +62 -0
- package/dist/utils/heal-scene-graph.d.ts +18 -0
- package/dist/utils/heal-scene-graph.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.js +90 -0
- package/dist/utils/heal-scene-graph.test.d.ts +2 -0
- package/dist/utils/heal-scene-graph.test.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.test.js +88 -0
- package/dist/validation/validate-build-json.d.ts +44 -0
- package/dist/validation/validate-build-json.d.ts.map +1 -0
- package/dist/validation/validate-build-json.js +256 -0
- package/package.json +11 -4
|
@@ -3,11 +3,91 @@ import { z } from 'zod';
|
|
|
3
3
|
import { BaseNode, nodeType, objectId } from '../base';
|
|
4
4
|
import { MaterialSchema } from '../material';
|
|
5
5
|
export const RoofType = z.enum(['hip', 'gable', 'shed', 'gambrel', 'dutch', 'mansard', 'flat']);
|
|
6
|
+
export const MIN_ROOF_SEGMENT_TRIM_SPAN = 0.1;
|
|
7
|
+
const DEFAULT_ROOF_SEGMENT_WIDTH = 8;
|
|
8
|
+
const DEFAULT_ROOF_SEGMENT_DEPTH = 6;
|
|
9
|
+
export const RoofSegmentTrim = z
|
|
10
|
+
.object({
|
|
11
|
+
left: z.number().min(0).default(0),
|
|
12
|
+
right: z.number().min(0).default(0),
|
|
13
|
+
front: z.number().min(0).default(0),
|
|
14
|
+
back: z.number().min(0).default(0),
|
|
15
|
+
frontLeft: z.number().min(0).default(0),
|
|
16
|
+
frontRight: z.number().min(0).default(0),
|
|
17
|
+
backLeft: z.number().min(0).default(0),
|
|
18
|
+
backRight: z.number().min(0).default(0),
|
|
19
|
+
frontLeftX: z.number().min(0).default(0),
|
|
20
|
+
frontLeftZ: z.number().min(0).default(0),
|
|
21
|
+
frontRightX: z.number().min(0).default(0),
|
|
22
|
+
frontRightZ: z.number().min(0).default(0),
|
|
23
|
+
backLeftX: z.number().min(0).default(0),
|
|
24
|
+
backLeftZ: z.number().min(0).default(0),
|
|
25
|
+
backRightX: z.number().min(0).default(0),
|
|
26
|
+
backRightZ: z.number().min(0).default(0),
|
|
27
|
+
})
|
|
28
|
+
.default({
|
|
29
|
+
left: 0,
|
|
30
|
+
right: 0,
|
|
31
|
+
front: 0,
|
|
32
|
+
back: 0,
|
|
33
|
+
frontLeft: 0,
|
|
34
|
+
frontRight: 0,
|
|
35
|
+
backLeft: 0,
|
|
36
|
+
backRight: 0,
|
|
37
|
+
frontLeftX: 0,
|
|
38
|
+
frontLeftZ: 0,
|
|
39
|
+
frontRightX: 0,
|
|
40
|
+
frontRightZ: 0,
|
|
41
|
+
backLeftX: 0,
|
|
42
|
+
backLeftZ: 0,
|
|
43
|
+
backRightX: 0,
|
|
44
|
+
backRightZ: 0,
|
|
45
|
+
});
|
|
46
|
+
// Default shape ratios. Tuning these used to require editing the geometry
|
|
47
|
+
// code in two places; they are now schema fields with these defaults.
|
|
48
|
+
export const ROOF_SHAPE_DEFAULTS = {
|
|
49
|
+
/** Gambrel: lower (steep) face occupies this fraction of the horizontal half-depth. */
|
|
50
|
+
gambrelLowerWidthRatio: 0.5,
|
|
51
|
+
/** Gambrel: lower (steep) face rises this fraction of the way to the peak. */
|
|
52
|
+
gambrelLowerHeightRatio: 0.6,
|
|
53
|
+
/** Mansard: steep face occupies this fraction of `min(width, depth)`. */
|
|
54
|
+
mansardSteepWidthRatio: 0.15,
|
|
55
|
+
/** Mansard: steep face rises this fraction of the way to the peak. */
|
|
56
|
+
mansardSteepHeightRatio: 0.7,
|
|
57
|
+
/** Dutch: hip face occupies this fraction of `min(width, depth)`. */
|
|
58
|
+
dutchHipWidthRatio: 0.25,
|
|
59
|
+
/** Dutch: hip face rises this fraction of the way to the peak. */
|
|
60
|
+
dutchHipHeightRatio: 0.5,
|
|
61
|
+
/** Dutch: gable waist span along the ridge axis, as a fraction of the max span. */
|
|
62
|
+
dutchWaistLengthRatio: 0.98,
|
|
63
|
+
/**
|
|
64
|
+
* Dutch: how far the gablet's barge board extends outward past the gablet
|
|
65
|
+
* end-wall, along the ridge axis, in metres. 0 disables the rake. The board
|
|
66
|
+
* lies in the gablet's slope planes (coplanar with the main Dutch slopes)
|
|
67
|
+
* and overhangs the lower hip skirt; the gablet end-wall itself stays put.
|
|
68
|
+
*/
|
|
69
|
+
dutchGabletRake: 0.48,
|
|
70
|
+
/** Dutch: thickness of the top gable rake slab. */
|
|
71
|
+
dutchTopRakeThickness: 0.21,
|
|
72
|
+
};
|
|
6
73
|
export const RoofSegmentNode = BaseNode.extend({
|
|
7
74
|
id: objectId('rseg'),
|
|
8
75
|
type: nodeType('roof-segment'),
|
|
76
|
+
// Catch-all material — splatted across all 4 slots in the renderer
|
|
77
|
+
// when no role-specific override is set. Kept for back-compat with
|
|
78
|
+
// older scenes; new paint operations should prefer the role fields.
|
|
9
79
|
material: MaterialSchema.optional(),
|
|
10
80
|
materialPreset: z.string().optional(),
|
|
81
|
+
// Role-specific overrides mirror the parent roof's surface roles.
|
|
82
|
+
// When set they win over the segment's catch-all `material` and over
|
|
83
|
+
// the parent roof's role / catch-all materials. Resolution order:
|
|
84
|
+
// segment role → segment catch-all → roof role → roof catch-all.
|
|
85
|
+
topMaterial: MaterialSchema.optional(),
|
|
86
|
+
topMaterialPreset: z.string().optional(),
|
|
87
|
+
edgeMaterial: MaterialSchema.optional(),
|
|
88
|
+
edgeMaterialPreset: z.string().optional(),
|
|
89
|
+
wallMaterial: MaterialSchema.optional(),
|
|
90
|
+
wallMaterialPreset: z.string().optional(),
|
|
11
91
|
position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
|
12
92
|
// Rotation around Y axis in radians
|
|
13
93
|
rotation: z.number().default(0),
|
|
@@ -16,23 +96,479 @@ export const RoofSegmentNode = BaseNode.extend({
|
|
|
16
96
|
// Footprint dimensions
|
|
17
97
|
width: z.number().default(8),
|
|
18
98
|
depth: z.number().default(6),
|
|
19
|
-
//
|
|
99
|
+
// Segment-local distances trimmed from each footprint side. The trim
|
|
100
|
+
// boundary is projected vertically through the roof volume, so the
|
|
101
|
+
// resulting edge follows the actual sloped roof surfaces.
|
|
102
|
+
trim: RoofSegmentTrim,
|
|
103
|
+
// Wall height beneath the roof
|
|
20
104
|
wallHeight: z.number().default(0.5),
|
|
21
|
-
|
|
105
|
+
// Roof pitch in degrees — angle of the primary slope face.
|
|
106
|
+
// For gable/hip/shed this is the only slope; for gambrel/mansard/dutch
|
|
107
|
+
// it is the steep (lower) slope. The overall peak height is derived
|
|
108
|
+
// from pitch + footprint + roofType via getActiveRoofHeight().
|
|
109
|
+
pitch: z.number().min(0).max(85).default(40),
|
|
22
110
|
// Structure thicknesses
|
|
23
111
|
wallThickness: z.number().default(0.1),
|
|
24
112
|
deckThickness: z.number().default(0.1),
|
|
25
113
|
overhang: z.number().default(0.3),
|
|
26
114
|
shingleThickness: z.number().default(0.05),
|
|
115
|
+
// Shape-specific ratios. Only the pair matching `roofType` is read; the
|
|
116
|
+
// rest are inert. Defined on every segment so the panel can flip
|
|
117
|
+
// roofType without losing the previous shape's tuning.
|
|
118
|
+
gambrelLowerWidthRatio: z
|
|
119
|
+
.number()
|
|
120
|
+
.min(0.1)
|
|
121
|
+
.max(0.9)
|
|
122
|
+
.default(ROOF_SHAPE_DEFAULTS.gambrelLowerWidthRatio),
|
|
123
|
+
gambrelLowerHeightRatio: z
|
|
124
|
+
.number()
|
|
125
|
+
.min(0.1)
|
|
126
|
+
.max(0.9)
|
|
127
|
+
.default(ROOF_SHAPE_DEFAULTS.gambrelLowerHeightRatio),
|
|
128
|
+
mansardSteepWidthRatio: z
|
|
129
|
+
.number()
|
|
130
|
+
.min(0.05)
|
|
131
|
+
.max(0.45)
|
|
132
|
+
.default(ROOF_SHAPE_DEFAULTS.mansardSteepWidthRatio),
|
|
133
|
+
mansardSteepHeightRatio: z
|
|
134
|
+
.number()
|
|
135
|
+
.min(0.1)
|
|
136
|
+
.max(0.9)
|
|
137
|
+
.default(ROOF_SHAPE_DEFAULTS.mansardSteepHeightRatio),
|
|
138
|
+
dutchHipWidthRatio: z
|
|
139
|
+
.number()
|
|
140
|
+
.min(0.05)
|
|
141
|
+
.max(0.45)
|
|
142
|
+
.default(ROOF_SHAPE_DEFAULTS.dutchHipWidthRatio),
|
|
143
|
+
dutchHipHeightRatio: z
|
|
144
|
+
.number()
|
|
145
|
+
.min(0.1)
|
|
146
|
+
.max(0.9)
|
|
147
|
+
.default(ROOF_SHAPE_DEFAULTS.dutchHipHeightRatio),
|
|
148
|
+
dutchWaistLengthRatio: z
|
|
149
|
+
.number()
|
|
150
|
+
.min(0.1)
|
|
151
|
+
.max(1)
|
|
152
|
+
.default(ROOF_SHAPE_DEFAULTS.dutchWaistLengthRatio),
|
|
153
|
+
dutchGabletRake: z.number().min(0).max(3).default(ROOF_SHAPE_DEFAULTS.dutchGabletRake),
|
|
154
|
+
dutchTopRakeThickness: z
|
|
155
|
+
.number()
|
|
156
|
+
.min(0.01)
|
|
157
|
+
.max(0.5)
|
|
158
|
+
.default(ROOF_SHAPE_DEFAULTS.dutchTopRakeThickness),
|
|
159
|
+
// Hosted accessories — chimney, dormer, skylight, box-vent,
|
|
160
|
+
// ridge-vent, solar-panel, gutter. Each accessory's `parentId` points back
|
|
161
|
+
// here; the segment renderer mounts them recursively via
|
|
162
|
+
// `<NodeRenderer>` so they inherit the segment's transform stack.
|
|
163
|
+
// Required for `createNode(child, segmentId)` to append the child
|
|
164
|
+
// to this array — see
|
|
165
|
+
// `wiki/architecture/node-definitions.md` ("Host kinds need a
|
|
166
|
+
// `children` field on the schema").
|
|
167
|
+
children: z.array(z.string()).default([]),
|
|
27
168
|
}).describe(dedent `
|
|
28
169
|
Roof segment node - an individual roof module within a roof group.
|
|
29
170
|
Each segment generates a complete architectural volume (walls + roof).
|
|
30
171
|
Multiple segments can be combined to form complex roof shapes.
|
|
31
172
|
- roofType: hip, gable, shed, gambrel, dutch, mansard, flat
|
|
32
173
|
- width/depth: footprint dimensions
|
|
174
|
+
- trim: segment-local side cut distances
|
|
33
175
|
- wallHeight: height of walls below the roof
|
|
34
|
-
-
|
|
176
|
+
- pitch: roof slope in degrees (angle of the primary slope face)
|
|
35
177
|
- wallThickness/deckThickness: structural thicknesses
|
|
36
178
|
- overhang: eave overhang distance
|
|
37
179
|
- shingleThickness: outer shingle layer thickness
|
|
180
|
+
- gambrelLowerWidthRatio / gambrelLowerHeightRatio: kink position on gambrel roofs
|
|
181
|
+
- mansardSteepWidthRatio / mansardSteepHeightRatio: waist position on mansard roofs
|
|
182
|
+
- dutchHipWidthRatio / dutchHipHeightRatio: hip-to-gable split on dutch roofs
|
|
183
|
+
- dutchWaistLengthRatio: gable waist span along the ridge axis
|
|
184
|
+
- dutchGabletRake: gablet barge-board overhang past the gablet end-wall (m, 0 = none)
|
|
185
|
+
- dutchTopRakeThickness: thickness of the top gable rake slab
|
|
38
186
|
`);
|
|
187
|
+
function finiteNonNegative(value) {
|
|
188
|
+
return typeof value === 'number' && Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
189
|
+
}
|
|
190
|
+
function finitePositive(value, fallback) {
|
|
191
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
192
|
+
}
|
|
193
|
+
function normalizeTrimAxis(start, end, span) {
|
|
194
|
+
const maxTotal = Math.max(0, finiteNonNegative(span) - MIN_ROOF_SEGMENT_TRIM_SPAN);
|
|
195
|
+
let a = Math.min(finiteNonNegative(start), maxTotal);
|
|
196
|
+
let b = Math.min(finiteNonNegative(end), maxTotal);
|
|
197
|
+
const total = a + b;
|
|
198
|
+
if (total > maxTotal && total > 0) {
|
|
199
|
+
const scale = maxTotal / total;
|
|
200
|
+
a *= scale;
|
|
201
|
+
b *= scale;
|
|
202
|
+
}
|
|
203
|
+
return [a, b];
|
|
204
|
+
}
|
|
205
|
+
export function normalizeRoofSegmentTrim(node) {
|
|
206
|
+
const trim = node.trim ?? {};
|
|
207
|
+
const [left, right] = normalizeTrimAxis(trim.left, trim.right, node.width);
|
|
208
|
+
const [back, front] = normalizeTrimAxis(trim.back, trim.front, node.depth);
|
|
209
|
+
const maxWidthDiagonal = Math.max(0, finiteNonNegative(node.width) - left - right);
|
|
210
|
+
const maxDepthDiagonal = Math.max(0, finiteNonNegative(node.depth) - front - back);
|
|
211
|
+
const maxWidthPair = Math.max(0, maxWidthDiagonal - MIN_ROOF_SEGMENT_TRIM_SPAN);
|
|
212
|
+
const maxDepthPair = Math.max(0, maxDepthDiagonal - MIN_ROOF_SEGMENT_TRIM_SPAN);
|
|
213
|
+
let [frontLeftX, frontLeftZ] = normalizeCornerAxisTrim(trim.frontLeft, trim.frontLeftX, trim.frontLeftZ, maxWidthPair, maxDepthPair);
|
|
214
|
+
let [frontRightX, frontRightZ] = normalizeCornerAxisTrim(trim.frontRight, trim.frontRightX, trim.frontRightZ, maxWidthPair, maxDepthPair);
|
|
215
|
+
let [backLeftX, backLeftZ] = normalizeCornerAxisTrim(trim.backLeft, trim.backLeftX, trim.backLeftZ, maxWidthPair, maxDepthPair);
|
|
216
|
+
let [backRightX, backRightZ] = normalizeCornerAxisTrim(trim.backRight, trim.backRightX, trim.backRightZ, maxWidthPair, maxDepthPair);
|
|
217
|
+
for (let i = 0; i < 3; i += 1) {
|
|
218
|
+
;
|
|
219
|
+
[frontLeftX, frontRightX] = normalizeTrimPair(frontLeftX, frontRightX, maxWidthPair);
|
|
220
|
+
[backLeftX, backRightX] = normalizeTrimPair(backLeftX, backRightX, maxWidthPair);
|
|
221
|
+
[frontLeftZ, backLeftZ] = normalizeTrimPair(frontLeftZ, backLeftZ, maxDepthPair);
|
|
222
|
+
[frontRightZ, backRightZ] = normalizeTrimPair(frontRightZ, backRightZ, maxDepthPair);
|
|
223
|
+
}
|
|
224
|
+
const frontLeft = Math.min(frontLeftX, frontLeftZ);
|
|
225
|
+
const frontRight = Math.min(frontRightX, frontRightZ);
|
|
226
|
+
const backLeft = Math.min(backLeftX, backLeftZ);
|
|
227
|
+
const backRight = Math.min(backRightX, backRightZ);
|
|
228
|
+
return {
|
|
229
|
+
left,
|
|
230
|
+
right,
|
|
231
|
+
front,
|
|
232
|
+
back,
|
|
233
|
+
frontLeft,
|
|
234
|
+
frontRight,
|
|
235
|
+
backLeft,
|
|
236
|
+
backRight,
|
|
237
|
+
frontLeftX,
|
|
238
|
+
frontLeftZ,
|
|
239
|
+
frontRightX,
|
|
240
|
+
frontRightZ,
|
|
241
|
+
backLeftX,
|
|
242
|
+
backLeftZ,
|
|
243
|
+
backRightX,
|
|
244
|
+
backRightZ,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function normalizeTrimPair(a, b, maxTotal) {
|
|
248
|
+
const total = a + b;
|
|
249
|
+
if (total <= maxTotal || total <= 0)
|
|
250
|
+
return [a, b];
|
|
251
|
+
const scale = maxTotal / total;
|
|
252
|
+
return [a * scale, b * scale];
|
|
253
|
+
}
|
|
254
|
+
function normalizeCornerAxisTrim(scalar, axisX, axisZ, maxX, maxZ) {
|
|
255
|
+
const x = finiteNonNegative(axisX);
|
|
256
|
+
const z = finiteNonNegative(axisZ);
|
|
257
|
+
const fallback = finiteNonNegative(scalar);
|
|
258
|
+
if (x > 0 || z > 0) {
|
|
259
|
+
return [Math.min(x, maxX), Math.min(z, maxZ)];
|
|
260
|
+
}
|
|
261
|
+
return [Math.min(fallback, maxX), Math.min(fallback, maxZ)];
|
|
262
|
+
}
|
|
263
|
+
function getDutchUpperShellBounds(node) {
|
|
264
|
+
const metrics = getDutchRoofMetrics(node);
|
|
265
|
+
const width = finitePositive(node.width, DEFAULT_ROOF_SEGMENT_WIDTH);
|
|
266
|
+
const depth = finitePositive(node.depth, DEFAULT_ROOF_SEGMENT_DEPTH);
|
|
267
|
+
const rake = node.dutchGabletRake ?? ROOF_SHAPE_DEFAULTS.dutchGabletRake;
|
|
268
|
+
const rakeReach = metrics.axis === 'x'
|
|
269
|
+
? Math.min(Math.max(0, rake), Math.max(0, width / 2 - metrics.waistHalfX) * 0.98)
|
|
270
|
+
: Math.min(Math.max(0, rake), Math.max(0, depth / 2 - metrics.waistHalfZ) * 0.98);
|
|
271
|
+
return {
|
|
272
|
+
...metrics,
|
|
273
|
+
upperHalfX: metrics.axis === 'x' ? metrics.waistHalfX + rakeReach : metrics.waistHalfX,
|
|
274
|
+
upperHalfZ: metrics.axis === 'x' ? metrics.waistHalfZ : metrics.waistHalfZ + rakeReach,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function withRatioDefaults(input) {
|
|
278
|
+
return {
|
|
279
|
+
...input,
|
|
280
|
+
width: finitePositive(input.width, DEFAULT_ROOF_SEGMENT_WIDTH),
|
|
281
|
+
depth: finitePositive(input.depth, DEFAULT_ROOF_SEGMENT_DEPTH),
|
|
282
|
+
gambrelLowerWidthRatio: input.gambrelLowerWidthRatio ?? ROOF_SHAPE_DEFAULTS.gambrelLowerWidthRatio,
|
|
283
|
+
gambrelLowerHeightRatio: input.gambrelLowerHeightRatio ?? ROOF_SHAPE_DEFAULTS.gambrelLowerHeightRatio,
|
|
284
|
+
mansardSteepWidthRatio: input.mansardSteepWidthRatio ?? ROOF_SHAPE_DEFAULTS.mansardSteepWidthRatio,
|
|
285
|
+
mansardSteepHeightRatio: input.mansardSteepHeightRatio ?? ROOF_SHAPE_DEFAULTS.mansardSteepHeightRatio,
|
|
286
|
+
dutchHipWidthRatio: input.dutchHipWidthRatio ?? ROOF_SHAPE_DEFAULTS.dutchHipWidthRatio,
|
|
287
|
+
dutchHipHeightRatio: input.dutchHipHeightRatio ?? ROOF_SHAPE_DEFAULTS.dutchHipHeightRatio,
|
|
288
|
+
dutchWaistLengthRatio: input.dutchWaistLengthRatio ?? ROOF_SHAPE_DEFAULTS.dutchWaistLengthRatio,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
export function getDutchRoofMetrics(input) {
|
|
292
|
+
const width = finitePositive(input.width, DEFAULT_ROOF_SEGMENT_WIDTH);
|
|
293
|
+
const depth = finitePositive(input.depth, DEFAULT_ROOF_SEGMENT_DEPTH);
|
|
294
|
+
const inset = Math.min(width, depth) * (input.dutchHipWidthRatio ?? ROOF_SHAPE_DEFAULTS.dutchHipWidthRatio);
|
|
295
|
+
const waistLengthRatio = input.dutchWaistLengthRatio ?? ROOF_SHAPE_DEFAULTS.dutchWaistLengthRatio;
|
|
296
|
+
if (width >= depth) {
|
|
297
|
+
const waistHalfX = Math.max(0, (width / 2 - inset) * waistLengthRatio);
|
|
298
|
+
const waistHalfZ = Math.max(0, depth / 2 - inset);
|
|
299
|
+
return {
|
|
300
|
+
axis: 'x',
|
|
301
|
+
inset,
|
|
302
|
+
waistHalfX,
|
|
303
|
+
waistHalfZ,
|
|
304
|
+
ridgeStart: [-waistHalfX, 0],
|
|
305
|
+
ridgeEnd: [waistHalfX, 0],
|
|
306
|
+
shoulderInsetAlongDepth: Math.max(0, depth / 2 - waistHalfZ),
|
|
307
|
+
shoulderInsetAlongWidth: Math.max(0, width / 2 - waistHalfX),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
const waistHalfX = Math.max(0, width / 2 - inset);
|
|
311
|
+
const waistHalfZ = Math.max(0, (depth / 2 - inset) * waistLengthRatio);
|
|
312
|
+
return {
|
|
313
|
+
axis: 'z',
|
|
314
|
+
inset,
|
|
315
|
+
waistHalfX,
|
|
316
|
+
waistHalfZ,
|
|
317
|
+
ridgeStart: [0, waistHalfZ],
|
|
318
|
+
ridgeEnd: [0, -waistHalfZ],
|
|
319
|
+
shoulderInsetAlongDepth: Math.max(0, depth / 2 - waistHalfZ),
|
|
320
|
+
shoulderInsetAlongWidth: Math.max(0, width / 2 - waistHalfX),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function getPrimarySlopeRun(input) {
|
|
324
|
+
const min = Math.min(input.width, input.depth);
|
|
325
|
+
switch (input.roofType) {
|
|
326
|
+
case 'shed':
|
|
327
|
+
return input.depth;
|
|
328
|
+
case 'gable':
|
|
329
|
+
return input.depth / 2;
|
|
330
|
+
case 'gambrel':
|
|
331
|
+
return (input.depth / 2) * input.gambrelLowerWidthRatio;
|
|
332
|
+
case 'mansard':
|
|
333
|
+
return min * input.mansardSteepWidthRatio;
|
|
334
|
+
case 'dutch':
|
|
335
|
+
return min * input.dutchHipWidthRatio;
|
|
336
|
+
default:
|
|
337
|
+
return min / 2;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// Fraction of the overall peak height that is taken up by the primary slope.
|
|
341
|
+
function getPrimarySlopeRiseFraction(input) {
|
|
342
|
+
switch (input.roofType) {
|
|
343
|
+
case 'gambrel':
|
|
344
|
+
return input.gambrelLowerHeightRatio;
|
|
345
|
+
case 'mansard':
|
|
346
|
+
return input.mansardSteepHeightRatio;
|
|
347
|
+
case 'dutch':
|
|
348
|
+
return input.dutchHipHeightRatio;
|
|
349
|
+
default:
|
|
350
|
+
return 1;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* One stop for the slope math every roof-segment consumer needs. Builds
|
|
355
|
+
* `run`, `rise`, the trig triple, and the overall peak height from the
|
|
356
|
+
* segment's pitch + footprint + roofType. Before this helper existed,
|
|
357
|
+
* the table was duplicated in three places (the brush builder, the
|
|
358
|
+
* skylight surface-frame routine, and the segment-hit raycaster) and
|
|
359
|
+
* silently drifted when a new roof type was added.
|
|
360
|
+
*/
|
|
361
|
+
export function getSegmentSlopeFrame(node) {
|
|
362
|
+
const ratios = withRatioDefaults(node);
|
|
363
|
+
const run = getPrimarySlopeRun(ratios);
|
|
364
|
+
// `!(pitch > 0)` (not `pitch <= 0`) so a missing/NaN pitch — e.g. a segment
|
|
365
|
+
// from an older migration that only set `roofHeight`, or stale persisted data —
|
|
366
|
+
// resolves to a flat frame instead of computing `Math.tan(NaN)` → NaN geometry,
|
|
367
|
+
// which poisons the merged-roof CSG ("Coplanar clip not handled" + NaN positions).
|
|
368
|
+
if (node.roofType === 'flat' || !(node.pitch > 0)) {
|
|
369
|
+
return { run, rise: 0, tanTheta: 0, cosTheta: 1, sinTheta: 0, activeRh: 0 };
|
|
370
|
+
}
|
|
371
|
+
const pitchRad = (node.pitch * Math.PI) / 180;
|
|
372
|
+
const tanTheta = Math.tan(pitchRad);
|
|
373
|
+
const cosTheta = Math.cos(pitchRad) || 1;
|
|
374
|
+
const sinTheta = Math.sin(pitchRad);
|
|
375
|
+
const rise = run * tanTheta;
|
|
376
|
+
const activeRh = rise / getPrimarySlopeRiseFraction(ratios);
|
|
377
|
+
return { run, rise, tanTheta, cosTheta, sinTheta, activeRh };
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* The eave-to-peak height of the assembled segment, derived from pitch +
|
|
381
|
+
* footprint + roofType. Replaces the legacy `roofHeight` field on the node.
|
|
382
|
+
*/
|
|
383
|
+
export function getActiveRoofHeight(node) {
|
|
384
|
+
return getSegmentSlopeFrame(node).activeRh;
|
|
385
|
+
}
|
|
386
|
+
export function getRoofSegmentVisibleTopBounds(segment) {
|
|
387
|
+
const { activeRh, cosTheta, sinTheta } = getSegmentSlopeFrame(segment);
|
|
388
|
+
const width = finitePositive(segment.width, DEFAULT_ROOF_SEGMENT_WIDTH);
|
|
389
|
+
const depth = finitePositive(segment.depth, DEFAULT_ROOF_SEGMENT_DEPTH);
|
|
390
|
+
const trim = normalizeRoofSegmentTrim({ ...segment, width, depth });
|
|
391
|
+
const horizontalOverhang = finiteNonNegative(segment.overhang) * cosTheta;
|
|
392
|
+
const deckExt = finiteNonNegative(segment.wallThickness) / 2 + horizontalOverhang;
|
|
393
|
+
const shingleOverhang = finiteNonNegative(segment.shingleThickness) * sinTheta;
|
|
394
|
+
let xExt = deckExt;
|
|
395
|
+
let frontExt = deckExt;
|
|
396
|
+
let backExt = deckExt;
|
|
397
|
+
if (segment.roofType === 'hip' ||
|
|
398
|
+
segment.roofType === 'mansard' ||
|
|
399
|
+
segment.roofType === 'dutch') {
|
|
400
|
+
xExt += shingleOverhang;
|
|
401
|
+
frontExt += shingleOverhang;
|
|
402
|
+
backExt += shingleOverhang;
|
|
403
|
+
}
|
|
404
|
+
else if (segment.roofType === 'gable' || segment.roofType === 'gambrel') {
|
|
405
|
+
frontExt += shingleOverhang;
|
|
406
|
+
backExt += shingleOverhang;
|
|
407
|
+
}
|
|
408
|
+
else if (segment.roofType === 'shed' && activeRh > 0) {
|
|
409
|
+
frontExt += shingleOverhang;
|
|
410
|
+
}
|
|
411
|
+
let minX = trim.left > 0 ? -width / 2 + trim.left : -width / 2 - xExt;
|
|
412
|
+
let maxX = trim.right > 0 ? width / 2 - trim.right : width / 2 + xExt;
|
|
413
|
+
let minZ = trim.back > 0 ? -depth / 2 + trim.back : -depth / 2 - backExt;
|
|
414
|
+
let maxZ = trim.front > 0 ? depth / 2 - trim.front : depth / 2 + frontExt;
|
|
415
|
+
if (trim.frontLeftX > 0 && trim.frontLeftZ > 0 && maxZ - trim.frontLeftZ < 0) {
|
|
416
|
+
minX = Math.max(minX, minX + (trim.frontLeftX * (trim.frontLeftZ - maxZ)) / trim.frontLeftZ);
|
|
417
|
+
}
|
|
418
|
+
if (trim.backLeftX > 0 && trim.backLeftZ > 0 && minZ + trim.backLeftZ > 0) {
|
|
419
|
+
minX = Math.max(minX, minX + (trim.backLeftX * (trim.backLeftZ + minZ)) / trim.backLeftZ);
|
|
420
|
+
}
|
|
421
|
+
if (trim.frontRightX > 0 && trim.frontRightZ > 0 && maxZ - trim.frontRightZ < 0) {
|
|
422
|
+
maxX = Math.min(maxX, maxX - (trim.frontRightX * (trim.frontRightZ - maxZ)) / trim.frontRightZ);
|
|
423
|
+
}
|
|
424
|
+
if (trim.backRightX > 0 && trim.backRightZ > 0 && minZ + trim.backRightZ > 0) {
|
|
425
|
+
maxX = Math.min(maxX, maxX - (trim.backRightX * (trim.backRightZ + minZ)) / trim.backRightZ);
|
|
426
|
+
}
|
|
427
|
+
if (trim.frontLeftX > 0 && trim.frontLeftZ > 0 && minX + trim.frontLeftX > 0) {
|
|
428
|
+
maxZ = Math.min(maxZ, maxZ - (trim.frontLeftZ * (trim.frontLeftX + minX)) / trim.frontLeftX);
|
|
429
|
+
}
|
|
430
|
+
if (trim.frontRightX > 0 && trim.frontRightZ > 0 && maxX - trim.frontRightX < 0) {
|
|
431
|
+
maxZ = Math.min(maxZ, maxZ - (trim.frontRightZ * (trim.frontRightX - maxX)) / trim.frontRightX);
|
|
432
|
+
}
|
|
433
|
+
if (trim.backLeftX > 0 && trim.backLeftZ > 0 && minX + trim.backLeftX > 0) {
|
|
434
|
+
minZ = Math.max(minZ, minZ + (trim.backLeftZ * (trim.backLeftX + minX)) / trim.backLeftX);
|
|
435
|
+
}
|
|
436
|
+
if (trim.backRightX > 0 && trim.backRightZ > 0 && maxX - trim.backRightX < 0) {
|
|
437
|
+
minZ = Math.max(minZ, minZ + (trim.backRightZ * (trim.backRightX - maxX)) / trim.backRightX);
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
minX,
|
|
441
|
+
maxX,
|
|
442
|
+
minZ,
|
|
443
|
+
maxZ,
|
|
444
|
+
width: Math.max(0.01, maxX - minX),
|
|
445
|
+
depth: Math.max(0.01, maxZ - minZ),
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
/** Segment-local surface height used by roof accessory placement and hit disambiguation. */
|
|
449
|
+
export function getRoofSegmentSurfaceY(node, localX, localZ) {
|
|
450
|
+
const slopeFrame = getSegmentSlopeFrame(node);
|
|
451
|
+
const activeRh = slopeFrame.activeRh;
|
|
452
|
+
const peakY = node.wallHeight + activeRh;
|
|
453
|
+
if (activeRh === 0)
|
|
454
|
+
return node.wallHeight;
|
|
455
|
+
if (node.roofType === 'gable' || node.roofType === 'gambrel' || node.roofType === 'mansard') {
|
|
456
|
+
const t = node.depth > 0 ? Math.abs(localZ) / (node.depth / 2) : 0;
|
|
457
|
+
return peakY - t * activeRh;
|
|
458
|
+
}
|
|
459
|
+
if (node.roofType === 'dutch') {
|
|
460
|
+
const hipHeightRatio = node.dutchHipHeightRatio ?? ROOF_SHAPE_DEFAULTS.dutchHipHeightRatio;
|
|
461
|
+
const metrics = getDutchUpperShellBounds(node);
|
|
462
|
+
const lowerRise = activeRh * hipHeightRatio;
|
|
463
|
+
if (metrics.axis === 'x') {
|
|
464
|
+
const waistHalfZ = Math.max(0.0001, metrics.waistHalfZ);
|
|
465
|
+
if (Math.abs(localX) <= metrics.upperHalfX && Math.abs(localZ) <= waistHalfZ) {
|
|
466
|
+
const upperRise = activeRh * (1 - hipHeightRatio);
|
|
467
|
+
const upperTan = upperRise / waistHalfZ;
|
|
468
|
+
return peakY - Math.abs(localZ) * upperTan;
|
|
469
|
+
}
|
|
470
|
+
const xProgressDenom = Math.max(0.0001, node.width / 2 - metrics.waistHalfX);
|
|
471
|
+
const zProgressDenom = Math.max(0.0001, node.depth / 2 - waistHalfZ);
|
|
472
|
+
const xProgress = Math.max(0, Math.abs(localX) - metrics.waistHalfX) / xProgressDenom;
|
|
473
|
+
const zProgress = Math.max(0, Math.abs(localZ) - waistHalfZ) / zProgressDenom;
|
|
474
|
+
return node.wallHeight + lowerRise * (1 - Math.min(1, Math.max(xProgress, zProgress)));
|
|
475
|
+
}
|
|
476
|
+
const waistHalfX = Math.max(0.0001, metrics.waistHalfX);
|
|
477
|
+
if (Math.abs(localX) <= waistHalfX && Math.abs(localZ) <= metrics.upperHalfZ) {
|
|
478
|
+
const upperRise = activeRh * (1 - hipHeightRatio);
|
|
479
|
+
const upperRun = waistHalfX;
|
|
480
|
+
const upperTan = upperRise / upperRun;
|
|
481
|
+
return peakY - Math.abs(localX) * upperTan;
|
|
482
|
+
}
|
|
483
|
+
const xProgressDenom = Math.max(0.0001, node.width / 2 - waistHalfX);
|
|
484
|
+
const zProgressDenom = Math.max(0.0001, node.depth / 2 - metrics.waistHalfZ);
|
|
485
|
+
const xProgress = Math.max(0, Math.abs(localX) - waistHalfX) / xProgressDenom;
|
|
486
|
+
const zProgress = Math.max(0, Math.abs(localZ) - metrics.waistHalfZ) / zProgressDenom;
|
|
487
|
+
return node.wallHeight + lowerRise * (1 - Math.min(1, Math.max(xProgress, zProgress)));
|
|
488
|
+
}
|
|
489
|
+
if (node.roofType === 'shed') {
|
|
490
|
+
const t = (localZ + node.depth / 2) / (node.depth || 1);
|
|
491
|
+
return peakY - t * activeRh;
|
|
492
|
+
}
|
|
493
|
+
if (node.roofType === 'hip') {
|
|
494
|
+
const fx = node.width > 0 ? Math.abs(localX) / (node.width / 2) : 0;
|
|
495
|
+
const fz = node.depth > 0 ? Math.abs(localZ) / (node.depth / 2) : 0;
|
|
496
|
+
return peakY - Math.max(fx, fz) * activeRh;
|
|
497
|
+
}
|
|
498
|
+
const t = node.depth > 0 ? Math.abs(localZ) / (node.depth / 2) : 0;
|
|
499
|
+
return peakY - t * activeRh;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Inverse of `getActiveRoofHeight` — recover the pitch a legacy
|
|
503
|
+
* `roofHeight` value would correspond to. Used by the scene migration.
|
|
504
|
+
* Ratio overrides are optional and default to the shape defaults.
|
|
505
|
+
*/
|
|
506
|
+
export function getPitchFromActiveRoofHeight(input) {
|
|
507
|
+
if (input.roofType === 'flat' || input.roofHeight <= 0)
|
|
508
|
+
return 0;
|
|
509
|
+
const ratios = withRatioDefaults(input);
|
|
510
|
+
const run = getPrimarySlopeRun(ratios);
|
|
511
|
+
if (run <= 0)
|
|
512
|
+
return 0;
|
|
513
|
+
const rise = input.roofHeight * getPrimarySlopeRiseFraction(ratios);
|
|
514
|
+
return (Math.atan2(rise, run) * 180) / Math.PI;
|
|
515
|
+
}
|
|
516
|
+
function getLegacyRoofSegmentSurfaceMaterial(node) {
|
|
517
|
+
return {
|
|
518
|
+
material: node.material,
|
|
519
|
+
materialPreset: typeof node.materialPreset === 'string' ? node.materialPreset : undefined,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Resolve the segment-level material for one of the three surface roles.
|
|
524
|
+
* Falls back through: role-specific field → catch-all `material`. Pass the
|
|
525
|
+
* parent roof to `parentFallback` when you want the roof's role material
|
|
526
|
+
* to fill in for an unset segment slot — typical from the renderer.
|
|
527
|
+
*/
|
|
528
|
+
export function getEffectiveSegmentSurfaceMaterial(node, role, parentFallback) {
|
|
529
|
+
if (role === 'top') {
|
|
530
|
+
if (node.topMaterial !== undefined || typeof node.topMaterialPreset === 'string') {
|
|
531
|
+
return {
|
|
532
|
+
material: node.topMaterial,
|
|
533
|
+
materialPreset: typeof node.topMaterialPreset === 'string' ? node.topMaterialPreset : undefined,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
else if (role === 'edge') {
|
|
538
|
+
if (node.edgeMaterial !== undefined || typeof node.edgeMaterialPreset === 'string') {
|
|
539
|
+
return {
|
|
540
|
+
material: node.edgeMaterial,
|
|
541
|
+
materialPreset: typeof node.edgeMaterialPreset === 'string' ? node.edgeMaterialPreset : undefined,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else if (role === 'wall') {
|
|
546
|
+
if (node.wallMaterial !== undefined || typeof node.wallMaterialPreset === 'string') {
|
|
547
|
+
return {
|
|
548
|
+
material: node.wallMaterial,
|
|
549
|
+
materialPreset: typeof node.wallMaterialPreset === 'string' ? node.wallMaterialPreset : undefined,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
const legacy = getLegacyRoofSegmentSurfaceMaterial(node);
|
|
554
|
+
if (legacy.material !== undefined || legacy.materialPreset !== undefined)
|
|
555
|
+
return legacy;
|
|
556
|
+
return parentFallback ?? { material: undefined, materialPreset: undefined };
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Returns true when the segment has any segment-level material override —
|
|
560
|
+
* either the legacy catch-all or any of the three role-specific fields.
|
|
561
|
+
* Used by `RoofRenderer` and `updateMergedRoofGeometry` to decide whether
|
|
562
|
+
* the segment should be drawn as its own mesh or folded into the merged
|
|
563
|
+
* shell.
|
|
564
|
+
*/
|
|
565
|
+
export function hasSegmentMaterialOverride(node) {
|
|
566
|
+
return (node.material !== undefined ||
|
|
567
|
+
typeof node.materialPreset === 'string' ||
|
|
568
|
+
node.topMaterial !== undefined ||
|
|
569
|
+
typeof node.topMaterialPreset === 'string' ||
|
|
570
|
+
node.edgeMaterial !== undefined ||
|
|
571
|
+
typeof node.edgeMaterialPreset === 'string' ||
|
|
572
|
+
node.wallMaterial !== undefined ||
|
|
573
|
+
typeof node.wallMaterialPreset === 'string');
|
|
574
|
+
}
|
|
@@ -25,7 +25,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
25
25
|
type: z.ZodDefault<z.ZodLiteral<"roof">>;
|
|
26
26
|
material: z.ZodOptional<z.ZodObject<{
|
|
27
27
|
id: z.ZodOptional<z.ZodString>;
|
|
28
|
-
preset: z.ZodOptional<z.ZodEnum<{
|
|
28
|
+
preset: z.ZodOptional<z.ZodCatch<z.ZodEnum<{
|
|
29
29
|
custom: "custom";
|
|
30
30
|
white: "white";
|
|
31
31
|
brick: "brick";
|
|
@@ -36,7 +36,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
36
36
|
plaster: "plaster";
|
|
37
37
|
tile: "tile";
|
|
38
38
|
marble: "marble";
|
|
39
|
-
}
|
|
39
|
+
}>>>;
|
|
40
40
|
properties: z.ZodOptional<z.ZodObject<{
|
|
41
41
|
color: z.ZodDefault<z.ZodString>;
|
|
42
42
|
roughness: z.ZodDefault<z.ZodNumber>;
|
|
@@ -58,7 +58,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
58
58
|
materialPreset: z.ZodOptional<z.ZodString>;
|
|
59
59
|
topMaterial: z.ZodOptional<z.ZodObject<{
|
|
60
60
|
id: z.ZodOptional<z.ZodString>;
|
|
61
|
-
preset: z.ZodOptional<z.ZodEnum<{
|
|
61
|
+
preset: z.ZodOptional<z.ZodCatch<z.ZodEnum<{
|
|
62
62
|
custom: "custom";
|
|
63
63
|
white: "white";
|
|
64
64
|
brick: "brick";
|
|
@@ -69,7 +69,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
69
69
|
plaster: "plaster";
|
|
70
70
|
tile: "tile";
|
|
71
71
|
marble: "marble";
|
|
72
|
-
}
|
|
72
|
+
}>>>;
|
|
73
73
|
properties: z.ZodOptional<z.ZodObject<{
|
|
74
74
|
color: z.ZodDefault<z.ZodString>;
|
|
75
75
|
roughness: z.ZodDefault<z.ZodNumber>;
|
|
@@ -91,7 +91,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
91
91
|
topMaterialPreset: z.ZodOptional<z.ZodString>;
|
|
92
92
|
edgeMaterial: z.ZodOptional<z.ZodObject<{
|
|
93
93
|
id: z.ZodOptional<z.ZodString>;
|
|
94
|
-
preset: z.ZodOptional<z.ZodEnum<{
|
|
94
|
+
preset: z.ZodOptional<z.ZodCatch<z.ZodEnum<{
|
|
95
95
|
custom: "custom";
|
|
96
96
|
white: "white";
|
|
97
97
|
brick: "brick";
|
|
@@ -102,7 +102,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
102
102
|
plaster: "plaster";
|
|
103
103
|
tile: "tile";
|
|
104
104
|
marble: "marble";
|
|
105
|
-
}
|
|
105
|
+
}>>>;
|
|
106
106
|
properties: z.ZodOptional<z.ZodObject<{
|
|
107
107
|
color: z.ZodDefault<z.ZodString>;
|
|
108
108
|
roughness: z.ZodDefault<z.ZodNumber>;
|
|
@@ -124,7 +124,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
124
124
|
edgeMaterialPreset: z.ZodOptional<z.ZodString>;
|
|
125
125
|
wallMaterial: z.ZodOptional<z.ZodObject<{
|
|
126
126
|
id: z.ZodOptional<z.ZodString>;
|
|
127
|
-
preset: z.ZodOptional<z.ZodEnum<{
|
|
127
|
+
preset: z.ZodOptional<z.ZodCatch<z.ZodEnum<{
|
|
128
128
|
custom: "custom";
|
|
129
129
|
white: "white";
|
|
130
130
|
brick: "brick";
|
|
@@ -135,7 +135,7 @@ export declare const RoofNode: z.ZodObject<{
|
|
|
135
135
|
plaster: "plaster";
|
|
136
136
|
tile: "tile";
|
|
137
137
|
marble: "marble";
|
|
138
|
-
}
|
|
138
|
+
}>>>;
|
|
139
139
|
properties: z.ZodOptional<z.ZodObject<{
|
|
140
140
|
color: z.ZodDefault<z.ZodString>;
|
|
141
141
|
roughness: z.ZodDefault<z.ZodNumber>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/roof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,cAAc,IAAI,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAIvE,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;AAC7D,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyBpB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAS/C,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,uBAAuB,GAC5B,uBAAuB,
|
|
1
|
+
{"version":3,"file":"roof.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/roof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,cAAc,IAAI,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAIvE,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;AAC7D,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyBpB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAS/C,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,uBAAuB,GAC5B,uBAAuB,CAoCzB"}
|
|
@@ -58,21 +58,9 @@ export function getEffectiveRoofSurfaceMaterial(node, role) {
|
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
materialPreset: typeof node.wallMaterialPreset === 'string' ? node.wallMaterialPreset : undefined,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (role === 'wall') {
|
|
70
|
-
if (node.edgeMaterial !== undefined || typeof node.edgeMaterialPreset === 'string') {
|
|
71
|
-
return {
|
|
72
|
-
material: node.edgeMaterial,
|
|
73
|
-
materialPreset: typeof node.edgeMaterialPreset === 'string' ? node.edgeMaterialPreset : undefined,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
61
|
+
// No cross-role fallback: an unset role resolves only to the legacy
|
|
62
|
+
// catch-all (which covers all three roles for back-compat) and otherwise
|
|
63
|
+
// to the caller's theme default. Painting one surface must never bleed
|
|
64
|
+
// onto the others.
|
|
77
65
|
return getLegacyRoofSurfaceMaterial(node);
|
|
78
66
|
}
|