@pascal-app/nodes 0.1.1 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/dist/building/definition.js +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +809 -72
- package/dist/cabinet/geometry.d.ts.map +1 -1
- package/dist/cabinet/geometry.js +4 -0
- package/dist/cabinet/move-frame.js +3 -3
- package/dist/cabinet/panel.d.ts.map +1 -1
- package/dist/cabinet/panel.js +1 -0
- package/dist/cabinet/placement-snap.d.ts +8 -0
- package/dist/cabinet/placement-snap.d.ts.map +1 -0
- package/dist/cabinet/placement-snap.js +19 -0
- package/dist/cabinet/presets.js +8 -8
- package/dist/cabinet/quick-actions.d.ts.map +1 -1
- package/dist/cabinet/quick-actions.js +9 -3
- package/dist/cabinet/resize-limits.d.ts +11 -0
- package/dist/cabinet/resize-limits.d.ts.map +1 -0
- package/dist/cabinet/resize-limits.js +22 -0
- package/dist/cabinet/run-layout.d.ts +8 -2
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +59 -7
- package/dist/cabinet/run-ops.d.ts +44 -3
- package/dist/cabinet/run-ops.d.ts.map +1 -1
- package/dist/cabinet/run-ops.js +646 -110
- package/dist/cabinet/run-panel.d.ts +2 -1
- package/dist/cabinet/run-panel.d.ts.map +1 -1
- package/dist/cabinet/run-panel.js +38 -4
- package/dist/cabinet/stack-transitions.js +4 -4
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +95 -17
- package/dist/cabinet/wall-snap.d.ts.map +1 -1
- package/dist/cabinet/wall-snap.js +2 -6
- package/dist/ceiling/boundary-editor.d.ts.map +1 -1
- package/dist/ceiling/boundary-editor.js +2 -2
- package/dist/ceiling/definition.d.ts +1 -1
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +36 -5
- package/dist/ceiling/floorplan-affordances.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts.map +1 -1
- package/dist/ceiling/floorplan-move.js +5 -4
- package/dist/ceiling/hole-editor.d.ts.map +1 -1
- package/dist/ceiling/hole-editor.js +2 -2
- package/dist/ceiling/move-tool.d.ts.map +1 -1
- package/dist/ceiling/move-tool.js +4 -3
- package/dist/ceiling/panel.d.ts.map +1 -1
- package/dist/ceiling/panel.js +65 -3
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +6 -2
- package/dist/ceiling/tool.d.ts.map +1 -1
- package/dist/ceiling/tool.js +12 -1
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +1 -0
- package/dist/chimney/tool.d.ts.map +1 -1
- package/dist/chimney/tool.js +16 -1
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +14 -2
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +19 -14
- package/dist/column/floorplan-move.d.ts.map +1 -1
- package/dist/column/floorplan-move.js +7 -2
- package/dist/column/floorplan.d.ts +9 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +59 -4
- package/dist/column/tool.d.ts.map +1 -1
- package/dist/column/tool.js +33 -7
- package/dist/construction-dimension/definition.d.ts +4 -0
- package/dist/construction-dimension/definition.d.ts.map +1 -0
- package/dist/construction-dimension/definition.js +83 -0
- package/dist/construction-dimension/drawing-coordination.d.ts +7 -0
- package/dist/construction-dimension/drawing-coordination.d.ts.map +1 -0
- package/dist/construction-dimension/drawing-coordination.js +54 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts +4 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-affordances.js +114 -0
- package/dist/construction-dimension/floorplan-tool.d.ts +21 -0
- package/dist/construction-dimension/floorplan-tool.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-tool.js +557 -0
- package/dist/construction-dimension/floorplan.d.ts +3 -0
- package/dist/construction-dimension/floorplan.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan.js +457 -0
- package/dist/construction-dimension/geometry.d.ts +31 -0
- package/dist/construction-dimension/geometry.d.ts.map +1 -0
- package/dist/construction-dimension/geometry.js +144 -0
- package/dist/construction-dimension/index.d.ts +4 -0
- package/dist/construction-dimension/index.d.ts.map +1 -0
- package/dist/construction-dimension/index.js +3 -0
- package/dist/construction-dimension/panel.d.ts +2 -0
- package/dist/construction-dimension/panel.d.ts.map +1 -0
- package/dist/construction-dimension/panel.js +128 -0
- package/dist/construction-dimension/parametrics.d.ts +3 -0
- package/dist/construction-dimension/parametrics.d.ts.map +1 -0
- package/dist/construction-dimension/parametrics.js +4 -0
- package/dist/construction-dimension/schema.d.ts +2 -0
- package/dist/construction-dimension/schema.d.ts.map +1 -0
- package/dist/construction-dimension/schema.js +1 -0
- package/dist/door/contextual-dimensions.d.ts +3 -0
- package/dist/door/contextual-dimensions.d.ts.map +1 -0
- package/dist/door/contextual-dimensions.js +7 -0
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +13 -8
- package/dist/door/floorplan-affordances.d.ts +2 -5
- package/dist/door/floorplan-affordances.d.ts.map +1 -1
- package/dist/door/floorplan-affordances.js +9 -18
- package/dist/door/floorplan.d.ts +3 -4
- package/dist/door/floorplan.d.ts.map +1 -1
- package/dist/door/floorplan.js +88 -6
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +2 -2
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +3 -1
- package/dist/door/schema.d.ts +1 -1
- package/dist/door/schema.d.ts.map +1 -1
- package/dist/door/schema.js +1 -1
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +63 -6
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +1 -0
- package/dist/dormer/tool.d.ts.map +1 -1
- package/dist/dormer/tool.js +23 -1
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +20 -9
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +9 -6
- package/dist/elevator/floorplan-affordances.d.ts +2 -6
- package/dist/elevator/floorplan-affordances.d.ts.map +1 -1
- package/dist/elevator/floorplan-affordances.js +13 -12
- package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
- package/dist/fence/actions/move-endpoint.js +29 -1
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +67 -14
- package/dist/fence/floorplan-affordances.d.ts.map +1 -1
- package/dist/fence/floorplan-affordances.js +48 -11
- package/dist/fence/floorplan-move.d.ts.map +1 -1
- package/dist/fence/floorplan-move.js +38 -3
- package/dist/fence/geometry.d.ts.map +1 -1
- package/dist/fence/geometry.js +9 -1
- package/dist/fence/lift.d.ts +15 -0
- package/dist/fence/lift.d.ts.map +1 -0
- package/dist/fence/lift.js +23 -0
- package/dist/fence/move-tool.d.ts.map +1 -1
- package/dist/fence/move-tool.js +25 -5
- package/dist/fence/system.d.ts +3 -0
- package/dist/fence/system.d.ts.map +1 -0
- package/dist/fence/system.js +41 -0
- package/dist/fence/tool.d.ts.map +1 -1
- package/dist/fence/tool.js +103 -32
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +8 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +7 -1
- package/dist/item/floorplan-move.d.ts.map +1 -1
- package/dist/item/floorplan-move.js +50 -43
- package/dist/item/floorplan.d.ts +1 -0
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +49 -0
- package/dist/item/renderer.d.ts +3 -0
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +96 -8
- package/dist/level/definition.d.ts.map +1 -1
- package/dist/level/definition.js +7 -3
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +5 -1
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +7 -1
- package/dist/measurement/definition.d.ts.map +1 -1
- package/dist/measurement/definition.js +5 -0
- package/dist/measurement/floorplan.d.ts.map +1 -1
- package/dist/measurement/floorplan.js +11 -10
- package/dist/measurement/index.d.ts +1 -1
- package/dist/measurement/index.d.ts.map +1 -1
- package/dist/measurement/index.js +1 -1
- package/dist/measurement/resolve.d.ts +5 -0
- package/dist/measurement/resolve.d.ts.map +1 -1
- package/dist/measurement/resolve.js +2 -2
- package/dist/measurement/surface-query.js +5 -5
- package/dist/measurement/tool.d.ts +6 -1
- package/dist/measurement/tool.d.ts.map +1 -1
- package/dist/measurement/tool.js +7 -11
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +22 -19
- package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
- package/dist/roof-segment/floorplan-affordances.js +14 -8
- package/dist/shared/construction-dimension-standards.d.ts +34 -0
- package/dist/shared/construction-dimension-standards.d.ts.map +1 -0
- package/dist/shared/construction-dimension-standards.js +18 -0
- package/dist/shared/construction-length.d.ts +10 -0
- package/dist/shared/construction-length.d.ts.map +1 -0
- package/dist/shared/construction-length.js +57 -0
- package/dist/shared/dimension-string.d.ts +20 -0
- package/dist/shared/dimension-string.d.ts.map +1 -0
- package/dist/shared/dimension-string.js +19 -0
- package/dist/shared/draft-axis-guides.d.ts +36 -0
- package/dist/shared/draft-axis-guides.d.ts.map +1 -0
- package/dist/shared/draft-axis-guides.js +107 -0
- package/dist/shared/move-roof-tool.d.ts.map +1 -1
- package/dist/shared/move-roof-tool.js +17 -3
- package/dist/shared/opening-documentation-fields.d.ts +16 -0
- package/dist/shared/opening-documentation-fields.d.ts.map +1 -0
- package/dist/shared/opening-documentation-fields.js +54 -0
- package/dist/shared/opening-documentation.d.ts +47 -0
- package/dist/shared/opening-documentation.d.ts.map +1 -0
- package/dist/shared/opening-documentation.js +300 -0
- package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
- package/dist/shared/opening-guides-runtime.js +3 -2
- package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.js +14 -5
- package/dist/shared/wall-opening-ceiling.d.ts +30 -0
- package/dist/shared/wall-opening-ceiling.d.ts.map +1 -0
- package/dist/shared/wall-opening-ceiling.js +29 -0
- package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
- package/dist/shelf/floorplan-affordances.js +10 -5
- package/dist/shelf/floorplan-move.d.ts +2 -16
- package/dist/shelf/floorplan-move.d.ts.map +1 -1
- package/dist/shelf/floorplan-move.js +19 -40
- package/dist/shelf/tool.d.ts.map +1 -1
- package/dist/shelf/tool.js +8 -3
- package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
- package/dist/site/recessed-slab-ground-holes.js +1 -4
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +118 -28
- package/dist/site/terrain-drape.d.ts +91 -0
- package/dist/site/terrain-drape.d.ts.map +1 -0
- package/dist/site/terrain-drape.js +205 -0
- package/dist/site/terrain-geometry.d.ts +131 -0
- package/dist/site/terrain-geometry.d.ts.map +1 -0
- package/dist/site/terrain-geometry.js +259 -0
- package/dist/site/terrain-mesh.d.ts +49 -0
- package/dist/site/terrain-mesh.d.ts.map +1 -0
- package/dist/site/terrain-mesh.js +122 -0
- package/dist/site/terrain-renderer.d.ts +28 -0
- package/dist/site/terrain-renderer.d.ts.map +1 -0
- package/dist/site/terrain-renderer.js +69 -0
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +1 -0
- package/dist/skylight/tool.d.ts.map +1 -1
- package/dist/skylight/tool.js +16 -1
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +87 -10
- package/dist/slab/elevation-limit.d.ts +43 -0
- package/dist/slab/elevation-limit.d.ts.map +1 -0
- package/dist/slab/elevation-limit.js +124 -0
- package/dist/slab/floorplan-affordances.d.ts +16 -0
- package/dist/slab/floorplan-affordances.d.ts.map +1 -1
- package/dist/slab/geometry.d.ts.map +1 -1
- package/dist/slab/geometry.js +98 -5
- package/dist/slab/panel.d.ts.map +1 -1
- package/dist/slab/panel.js +82 -4
- package/dist/slab/parametrics.d.ts +1 -1
- package/dist/slab/parametrics.d.ts.map +1 -1
- package/dist/slab/parametrics.js +13 -1
- package/dist/slab/placement-ownership.d.ts +3 -0
- package/dist/slab/placement-ownership.d.ts.map +1 -0
- package/dist/slab/placement-ownership.js +3 -0
- package/dist/slab/quick-measurement.d.ts.map +1 -1
- package/dist/slab/quick-measurement.js +3 -2
- package/dist/slab/system.d.ts.map +1 -1
- package/dist/slab/system.js +14 -4
- package/dist/slab/tool.d.ts.map +1 -1
- package/dist/slab/tool.js +81 -23
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +1 -0
- package/dist/solar-panel/tool.d.ts.map +1 -1
- package/dist/solar-panel/tool.js +17 -1
- package/dist/spawn/definition.d.ts.map +1 -1
- package/dist/spawn/definition.js +1 -0
- package/dist/spawn/floorplan-affordances.d.ts.map +1 -1
- package/dist/spawn/floorplan-affordances.js +7 -4
- package/dist/spawn/floorplan-move.d.ts.map +1 -1
- package/dist/spawn/floorplan-move.js +8 -6
- package/dist/spawn/renderer.d.ts +4 -0
- package/dist/spawn/renderer.d.ts.map +1 -1
- package/dist/spawn/renderer.js +32 -18
- package/dist/spawn/tool.d.ts +2 -2
- package/dist/spawn/tool.d.ts.map +1 -1
- package/dist/spawn/tool.js +78 -11
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +15 -7
- package/dist/stair/destination.d.ts +16 -0
- package/dist/stair/destination.d.ts.map +1 -0
- package/dist/stair/destination.js +24 -0
- package/dist/stair/documentation.d.ts +8 -0
- package/dist/stair/documentation.d.ts.map +1 -0
- package/dist/stair/documentation.js +245 -0
- package/dist/stair/floor-stack.d.ts.map +1 -1
- package/dist/stair/floor-stack.js +38 -0
- package/dist/stair/floorplan-affordances.d.ts.map +1 -1
- package/dist/stair/floorplan-affordances.js +28 -9
- package/dist/stair/floorplan-move.d.ts +3 -5
- package/dist/stair/floorplan-move.d.ts.map +1 -1
- package/dist/stair/floorplan-move.js +14 -16
- package/dist/stair/floorplan.d.ts.map +1 -1
- package/dist/stair/floorplan.js +27 -14
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +35 -2
- package/dist/stair/renderer.d.ts.map +1 -1
- package/dist/stair/renderer.js +4 -3
- package/dist/structural-grid/coordination.d.ts +16 -0
- package/dist/structural-grid/coordination.d.ts.map +1 -0
- package/dist/structural-grid/coordination.js +105 -0
- package/dist/structural-grid/definition.d.ts +4 -0
- package/dist/structural-grid/definition.d.ts.map +1 -0
- package/dist/structural-grid/definition.js +51 -0
- package/dist/structural-grid/floorplan-tool.d.ts +16 -0
- package/dist/structural-grid/floorplan-tool.d.ts.map +1 -0
- package/dist/structural-grid/floorplan-tool.js +183 -0
- package/dist/structural-grid/floorplan.d.ts +3 -0
- package/dist/structural-grid/floorplan.d.ts.map +1 -0
- package/dist/structural-grid/floorplan.js +61 -0
- package/dist/structural-grid/index.d.ts +2 -0
- package/dist/structural-grid/index.d.ts.map +1 -0
- package/dist/structural-grid/index.js +1 -0
- package/dist/structural-grid/schema.d.ts +2 -0
- package/dist/structural-grid/schema.d.ts.map +1 -0
- package/dist/structural-grid/schema.js +1 -0
- package/dist/wall/construction-dimensions.d.ts +32 -0
- package/dist/wall/construction-dimensions.d.ts.map +1 -0
- package/dist/wall/construction-dimensions.js +1031 -0
- package/dist/wall/contextual-dimensions.d.ts +13 -0
- package/dist/wall/contextual-dimensions.d.ts.map +1 -0
- package/dist/wall/contextual-dimensions.js +221 -0
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +20 -1
- package/dist/wall/floorplan-affordances.d.ts.map +1 -1
- package/dist/wall/floorplan-affordances.js +23 -8
- package/dist/wall/floorplan-overrides.d.ts +9 -6
- package/dist/wall/floorplan-overrides.d.ts.map +1 -1
- package/dist/wall/floorplan-overrides.js +20 -11
- package/dist/wall/floorplan.d.ts +12 -3
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +121 -79
- package/dist/wall/measurement.d.ts.map +1 -1
- package/dist/wall/measurement.js +17 -4
- package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
- package/dist/wall/move-endpoint-tool.js +74 -27
- package/dist/wall/move-shared.d.ts.map +1 -1
- package/dist/wall/move-shared.js +3 -2
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +15 -3
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +10 -6
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +32 -5
- package/dist/wall/parametrics.d.ts.map +1 -1
- package/dist/wall/parametrics.js +2 -0
- package/dist/wall/preview.d.ts +8 -0
- package/dist/wall/preview.d.ts.map +1 -0
- package/dist/wall/preview.js +39 -0
- package/dist/wall/quick-measurement.d.ts.map +1 -1
- package/dist/wall/quick-measurement.js +3 -2
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +7 -5
- package/dist/wall/system.d.ts +1 -1
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +37 -2
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +148 -96
- package/dist/wall/treatment-level-data.d.ts +14 -0
- package/dist/wall/treatment-level-data.d.ts.map +1 -0
- package/dist/wall/treatment-level-data.js +31 -0
- package/dist/wall/treatments.d.ts +8 -2
- package/dist/wall/treatments.d.ts.map +1 -1
- package/dist/wall/treatments.js +58 -15
- package/dist/window/contextual-dimensions.d.ts +3 -0
- package/dist/window/contextual-dimensions.d.ts.map +1 -0
- package/dist/window/contextual-dimensions.js +7 -0
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +15 -10
- package/dist/window/floorplan-affordances.d.ts +2 -5
- package/dist/window/floorplan-affordances.d.ts.map +1 -1
- package/dist/window/floorplan-affordances.js +9 -15
- package/dist/window/floorplan-move.d.ts.map +1 -1
- package/dist/window/floorplan-move.js +1 -1
- package/dist/window/floorplan.d.ts.map +1 -1
- package/dist/window/floorplan.js +7 -1
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +3 -3
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +4 -1
- package/dist/window/schema.d.ts +1 -1
- package/dist/window/schema.d.ts.map +1 -1
- package/dist/window/schema.js +1 -1
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +64 -7
- package/dist/window/window-math.d.ts +7 -3
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +8 -3
- package/dist/zone/contextual-dimensions.d.ts +3 -0
- package/dist/zone/contextual-dimensions.d.ts.map +1 -0
- package/dist/zone/contextual-dimensions.js +43 -0
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +9 -1
- package/dist/zone/floorplan-affordances.d.ts +36 -0
- package/dist/zone/floorplan-affordances.d.ts.map +1 -1
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +59 -3
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +48 -4
- package/dist/zone/room-clear-dimensions.d.ts +3 -0
- package/dist/zone/room-clear-dimensions.d.ts.map +1 -0
- package/dist/zone/room-clear-dimensions.js +406 -0
- package/dist/zone/room-documentation.d.ts +11 -0
- package/dist/zone/room-documentation.d.ts.map +1 -0
- package/dist/zone/room-documentation.js +97 -0
- package/package.json +7 -7
package/dist/slab/panel.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
3
|
-
import { useScene } from '@pascal-app/core';
|
|
4
|
-
import { ActionButton, ActionGroup, holeEditScope, PanelSection, PanelWrapper, SliderControl, triggerSFX, useEditingHole, useEditor, useInteractionScope, } from '@pascal-app/editor';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { MIN_SLAB_THICKNESS, useScene } from '@pascal-app/core';
|
|
4
|
+
import { ActionButton, ActionGroup, holeEditScope, PanelSection, PanelWrapper, SegmentedControl, SliderControl, triggerSFX, useEditingHole, useEditor, useInteractionScope, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { Edit, Move, Plus, Trash2 } from 'lucide-react';
|
|
7
7
|
import { useCallback, useEffect, useRef } from 'react';
|
|
8
|
+
import { applySlabAnchorElevationChange, applySlabElevationPreset, applySlabRecessDepthChange, applySlabThicknessChange, applySlabTopChange, clampSlabElevation, getSlabAnchorElevation, getSlabBaseElevation, getSlabRecessDepth, } from './elevation-limit';
|
|
8
9
|
/**
|
|
9
10
|
* Phase 5 Stage E — slab inspector (kind-owned).
|
|
10
11
|
*
|
|
@@ -18,6 +19,7 @@ import { useCallback, useEffect, useRef } from 'react';
|
|
|
18
19
|
*/
|
|
19
20
|
export function SlabPanel() {
|
|
20
21
|
const selectedId = useViewer((s) => s.selection.selectedIds[0]);
|
|
22
|
+
const unit = useViewer((s) => s.unit);
|
|
21
23
|
const setSelection = useViewer((s) => s.setSelection);
|
|
22
24
|
const editingHole = useEditingHole();
|
|
23
25
|
const setMovingNode = useEditor((s) => s.setMovingNode);
|
|
@@ -32,6 +34,64 @@ export function SlabPanel() {
|
|
|
32
34
|
return;
|
|
33
35
|
useScene.getState().updateNode(selectedId, updates);
|
|
34
36
|
}, [selectedId]);
|
|
37
|
+
const handleElevationChange = useCallback((proposed) => {
|
|
38
|
+
const current = nodeRef.current;
|
|
39
|
+
if (!current)
|
|
40
|
+
return;
|
|
41
|
+
const { elevation } = clampSlabElevation(useScene.getState().nodes, current, proposed);
|
|
42
|
+
handleUpdate(applySlabTopChange(current, elevation));
|
|
43
|
+
}, [handleUpdate]);
|
|
44
|
+
const handleThicknessChange = useCallback((proposed) => {
|
|
45
|
+
const current = nodeRef.current;
|
|
46
|
+
if (!current)
|
|
47
|
+
return;
|
|
48
|
+
const base = getSlabBaseElevation(current);
|
|
49
|
+
const requested = applySlabThicknessChange(current, proposed);
|
|
50
|
+
const clamped = clampSlabElevation(useScene.getState().nodes, current, requested.elevation);
|
|
51
|
+
handleUpdate(applySlabThicknessChange(current, Math.max(MIN_SLAB_THICKNESS, clamped.elevation - base)));
|
|
52
|
+
}, [handleUpdate]);
|
|
53
|
+
const handleAnchorChange = useCallback((proposed) => {
|
|
54
|
+
const current = nodeRef.current;
|
|
55
|
+
if (!current)
|
|
56
|
+
return;
|
|
57
|
+
const patch = applySlabAnchorElevationChange(current, proposed);
|
|
58
|
+
const requestedTop = patch.elevation ?? current.elevation;
|
|
59
|
+
const { elevation } = clampSlabElevation(useScene.getState().nodes, current, requestedTop);
|
|
60
|
+
if (current.recessed) {
|
|
61
|
+
const delta = elevation - requestedTop;
|
|
62
|
+
handleUpdate({
|
|
63
|
+
...patch,
|
|
64
|
+
elevation,
|
|
65
|
+
recessedRimElevation: (patch.recessedRimElevation ?? proposed) + delta,
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
handleUpdate(applySlabAnchorElevationChange(current, elevation - current.thickness));
|
|
70
|
+
}, [handleUpdate]);
|
|
71
|
+
const handleRecessDepthChange = useCallback((proposed) => {
|
|
72
|
+
const current = nodeRef.current;
|
|
73
|
+
if (!current?.recessed)
|
|
74
|
+
return;
|
|
75
|
+
handleUpdate(applySlabRecessDepthChange(current, proposed));
|
|
76
|
+
}, [handleUpdate]);
|
|
77
|
+
const handleElevationPreset = useCallback((signedDepth) => {
|
|
78
|
+
const current = nodeRef.current;
|
|
79
|
+
if (!current)
|
|
80
|
+
return;
|
|
81
|
+
const anchor = getSlabAnchorElevation(current);
|
|
82
|
+
const requested = applySlabElevationPreset(current, signedDepth);
|
|
83
|
+
if (requested.recessed) {
|
|
84
|
+
handleUpdate(requested);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const requestedTop = requested.elevation ?? current.elevation;
|
|
88
|
+
const { elevation } = clampSlabElevation(useScene.getState().nodes, current, requestedTop);
|
|
89
|
+
const thickness = Math.max(MIN_SLAB_THICKNESS, elevation - anchor);
|
|
90
|
+
handleUpdate({ ...requested, elevation: anchor + thickness, thickness });
|
|
91
|
+
}, [handleUpdate]);
|
|
92
|
+
const handleTerrainModeChange = useCallback((mode) => {
|
|
93
|
+
handleUpdate({ fillToTerrain: mode === 'terrain' ? true : undefined });
|
|
94
|
+
}, [handleUpdate]);
|
|
35
95
|
const handleClose = useCallback(() => {
|
|
36
96
|
setSelection({ selectedIds: [] });
|
|
37
97
|
useInteractionScope
|
|
@@ -128,7 +188,25 @@ export function SlabPanel() {
|
|
|
128
188
|
return Math.abs(area) / 2;
|
|
129
189
|
};
|
|
130
190
|
const area = calculateArea(node.polygon);
|
|
131
|
-
|
|
191
|
+
// Clean preset values per display system; imperial stores exact meters
|
|
192
|
+
// for whole-inch offsets.
|
|
193
|
+
const elevationPresets = unit === 'imperial'
|
|
194
|
+
? [
|
|
195
|
+
{ label: 'Sunken (6")', elevation: -0.1524 },
|
|
196
|
+
{ label: 'Thin (1")', elevation: 0.0254 },
|
|
197
|
+
{ label: 'Standard (2")', elevation: 0.0508 },
|
|
198
|
+
{ label: 'Thick (6")', elevation: 0.1524 },
|
|
199
|
+
]
|
|
200
|
+
: [
|
|
201
|
+
{ label: 'Sunken (15cm)', elevation: -0.15 },
|
|
202
|
+
{ label: 'Thin (2cm)', elevation: 0.02 },
|
|
203
|
+
{ label: 'Standard (5cm)', elevation: 0.05 },
|
|
204
|
+
{ label: 'Thick (15cm)', elevation: 0.15 },
|
|
205
|
+
];
|
|
206
|
+
return (_jsxs(PanelWrapper, { icon: "/icons/floor.webp", onClose: handleClose, title: node.name || 'Slab', width: 320, children: [_jsxs(PanelSection, { title: "Elevation", children: [_jsx(SliderControl, { label: node.recessed ? 'Floor' : 'Surface', max: 6, min: -3, onChange: handleElevationChange, precision: 3, step: 0.01, unit: "m", value: Math.round(node.elevation * 1000) / 1000 }), _jsx(SliderControl, { label: node.recessed ? 'Rim' : 'Base', max: 6, min: -3, onChange: handleAnchorChange, precision: 3, step: 0.01, unit: "m", value: Math.round(getSlabAnchorElevation(node) * 1000) / 1000 }), node.recessed ? (_jsx(SliderControl, { label: "Depth", max: 2, min: MIN_SLAB_THICKNESS, onChange: handleRecessDepthChange, precision: 2, step: 0.01, unit: "m", value: Math.round(getSlabRecessDepth(node) * 100) / 100 })) : (_jsx(SliderControl, { label: "Thickness", max: 0.5, min: MIN_SLAB_THICKNESS, onChange: handleThicknessChange, precision: 2, step: 0.01, unit: "m", value: Math.round((node.thickness ?? 0.05) * 100) / 100 })), !node.recessed && (_jsxs(_Fragment, { children: [_jsx("div", { className: "px-1 font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Foundation" }), _jsx(SegmentedControl, { onChange: handleTerrainModeChange, options: [
|
|
207
|
+
{ label: 'Fixed', value: 'fixed' },
|
|
208
|
+
{ label: 'Follows terrain', value: 'terrain' },
|
|
209
|
+
], value: node.fillToTerrain ? 'terrain' : 'fixed' }), node.fillToTerrain && (_jsx("div", { className: "px-1 text-[11px] text-muted-foreground", children: "Extends the perimeter down to terrain. The flat surface, base, and thickness stay unchanged." }))] })), _jsx("div", { className: "mt-2 grid grid-cols-2 gap-1.5 px-1 pb-1", children: elevationPresets.map((preset) => (_jsx(ActionButton, { label: preset.label, onClick: () => handleElevationPreset(preset.elevation) }, preset.label))) })] }), _jsx(PanelSection, { title: "Info", children: _jsxs("div", { className: "flex items-center justify-between px-2 py-1 text-muted-foreground text-sm", children: [_jsx("span", { children: "Area" }), _jsxs("span", { className: "font-mono text-white", children: [area.toFixed(2), " m\u00B2"] })] }) }), _jsxs(PanelSection, { title: "Holes", children: [node.holes && node.holes.length > 0 ? (_jsx("div", { className: "flex flex-col gap-1 pb-2", children: node.holes.map((hole, index) => {
|
|
132
210
|
const holeArea = calculateArea(hole);
|
|
133
211
|
const isEditing = editingHole?.nodeId === selectedId && editingHole?.holeIndex === index;
|
|
134
212
|
const source = node.holeMetadata?.[index]?.source ?? 'manual';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/slab/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/slab/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,oBAAoB,CAAC,QAAQ,CAmB1D,CAAA"}
|
package/dist/slab/parametrics.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MIN_SLAB_THICKNESS } from '@pascal-app/core';
|
|
1
2
|
/**
|
|
2
3
|
* Inspector descriptor for slab.
|
|
3
4
|
*
|
|
@@ -12,7 +13,18 @@ export const slabParametrics = {
|
|
|
12
13
|
groups: [
|
|
13
14
|
{
|
|
14
15
|
label: 'Elevation',
|
|
15
|
-
fields: [
|
|
16
|
+
fields: [
|
|
17
|
+
{ key: 'elevation', kind: 'number', unit: 'm', min: -1, max: 1, step: 0.01 },
|
|
18
|
+
{
|
|
19
|
+
key: 'thickness',
|
|
20
|
+
kind: 'number',
|
|
21
|
+
unit: 'm',
|
|
22
|
+
min: MIN_SLAB_THICKNESS,
|
|
23
|
+
max: 0.5,
|
|
24
|
+
step: 0.01,
|
|
25
|
+
visibleIf: (n) => !n.recessed,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
16
28
|
},
|
|
17
29
|
],
|
|
18
30
|
customPanel: () => import('./panel'),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement-ownership.d.ts","sourceRoot":"","sources":["../../src/slab/placement-ownership.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,UAAU,CAAA;AAEvD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,EAC/B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quick-measurement.d.ts","sourceRoot":"","sources":["../../src/slab/quick-measurement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAOxE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG,sBAAsB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"quick-measurement.d.ts","sourceRoot":"","sources":["../../src/slab/quick-measurement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAOxE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG,sBAAsB,GAAG,IAAI,CAkClF"}
|
|
@@ -2,11 +2,12 @@ import { polygonBoundaryLength, polygonReportAnchor, polygonSurfaceArea, } from
|
|
|
2
2
|
export function slabQuickMeasurement(node) {
|
|
3
3
|
if (node.polygon.length < 3)
|
|
4
4
|
return null;
|
|
5
|
-
const
|
|
5
|
+
const elevation = node.elevation ?? 0.05;
|
|
6
|
+
const thickness = node.thickness ?? 0.05;
|
|
6
7
|
return {
|
|
7
8
|
title: node.name ?? 'Floor slab',
|
|
8
9
|
kindLabel: 'Floor slab',
|
|
9
|
-
anchor: polygonReportAnchor(node.polygon,
|
|
10
|
+
anchor: polygonReportAnchor(node.polygon, elevation + 0.04),
|
|
10
11
|
metrics: [
|
|
11
12
|
{
|
|
12
13
|
key: 'area',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/slab/system.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/slab/system.tsx"],"names":[],"mappings":"AAmEA,QAAA,MAAM,WAAW,YAmBhB,CAAA;AAED,eAAe,WAAW,CAAA"}
|
package/dist/slab/system.js
CHANGED
|
@@ -6,10 +6,10 @@ import { useEffect } from 'react';
|
|
|
6
6
|
* context — wall centerlines/thickness (exterior flush offsets) and sibling
|
|
7
7
|
* slab polygons (interior centerline seams) — none of which lives on the slab
|
|
8
8
|
* node itself. Store updates only dirty the node that changed, so a wall
|
|
9
|
-
* thickness edit
|
|
10
|
-
* slab meshes. Watch a per-level signature of those inputs
|
|
11
|
-
* slab on a level whose signature moved; `GeometrySystem` then
|
|
12
|
-
* them through `def.geometry` as usual.
|
|
9
|
+
* thickness edit, a neighbour slab add/remove/reshape, or a building transform
|
|
10
|
+
* would leave stale slab meshes. Watch a per-level signature of those inputs
|
|
11
|
+
* and dirty every slab on a level whose signature moved; `GeometrySystem` then
|
|
12
|
+
* rebuilds them through `def.geometry` as usual.
|
|
13
13
|
*/
|
|
14
14
|
function levelSlabContextSignatures(nodes) {
|
|
15
15
|
const partsByLevel = new Map();
|
|
@@ -35,6 +35,16 @@ function levelSlabContextSignatures(nodes) {
|
|
|
35
35
|
push(levelId, `s|${slab.id}|${slab.elevation ?? ''}|${slab.polygon.map(([x, z]) => `${x},${z}`).join(';')}`);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
for (const node of Object.values(nodes)) {
|
|
39
|
+
if (node.type !== 'building')
|
|
40
|
+
continue;
|
|
41
|
+
const transform = `${node.position.join(',')}|${node.rotation.join(',')}`;
|
|
42
|
+
for (const childId of node.children) {
|
|
43
|
+
const child = nodes[childId];
|
|
44
|
+
if (child?.type === 'level')
|
|
45
|
+
push(child.id, `b|${node.id}|${transform}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
38
48
|
const signatures = new Map();
|
|
39
49
|
for (const [levelId, parts] of partsByLevel.entries()) {
|
|
40
50
|
signatures.set(levelId, parts.sort().join('||'));
|
package/dist/slab/tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/slab/tool.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/slab/tool.tsx"],"names":[],"mappings":"AA4EA,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EA2T5B,CAAA;AAED,eAAe,QAAQ,CAAA"}
|
package/dist/slab/tool.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { DEFAULT_ANGLE_STEP, emitter, snapPointAlongAngleRay, snapPointToGrid, useScene, } from '@pascal-app/core';
|
|
4
|
-
import { CursorSphere, clearSlabSnapFeedback, EDITOR_LAYER, isAngleSnapActive, isGridSnapActive, markToolCancelConsumed, resolveSlabPlanPointSnap, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
3
|
+
import { DEFAULT_ANGLE_STEP, emitter, resolveSlabPlacementElevation, snapPointAlongAngleRay, snapPointToGrid, useScene, } from '@pascal-app/core';
|
|
4
|
+
import { CursorSphere, clearPlacementSurface, clearSlabSnapFeedback, EDITOR_LAYER, isAngleSnapActive, isGridSnapActive, markToolCancelConsumed, publishHorizontalConstructionPlane, publishPlacementSurface, resampleTerrainConstructionPlane, resolveEventConstructionPlane, resolveLevelConstructionPlane, resolvePointerSupportSurface, resolveSlabPlanPointSnap, triggerSFX, useEditor, useFloorplanDraftPreview, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
|
+
import { useThree } from '@react-three/fiber';
|
|
6
7
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
7
8
|
import { BufferGeometry, DoubleSide, Shape, Vector3 } from 'three';
|
|
9
|
+
import { shouldRegistryCommitSlab } from './placement-ownership';
|
|
8
10
|
import { SlabNode } from './schema';
|
|
9
11
|
/**
|
|
10
12
|
* Phase 5 Stage D — slab placement tool (kind-owned via `def.tool`).
|
|
@@ -18,14 +20,20 @@ import { SlabNode } from './schema';
|
|
|
18
20
|
* single pointer-down → drag-up.
|
|
19
21
|
*/
|
|
20
22
|
const Y_OFFSET = 0.02;
|
|
21
|
-
|
|
23
|
+
const SURFACE_UP = new Vector3(0, 1, 0);
|
|
24
|
+
const surfacePointScratch = new Vector3();
|
|
25
|
+
function commitSlabDrawing(levelId, points, baseElevation) {
|
|
22
26
|
const { createNode, nodes } = useScene.getState();
|
|
23
27
|
const slabCount = Object.values(nodes).filter((n) => n.type === 'slab').length;
|
|
24
28
|
const name = `Slab ${slabCount + 1}`;
|
|
25
29
|
// A placed slab preset seeds `toolDefaults.slab` (thickness, material, …)
|
|
26
30
|
// before the tool activates; the drawn polygon always wins.
|
|
27
31
|
const defaults = useEditor.getState().toolDefaults.slab ?? {};
|
|
28
|
-
const
|
|
32
|
+
const authored = SlabNode.parse({ ...defaults, name, polygon: points });
|
|
33
|
+
const slab = {
|
|
34
|
+
...authored,
|
|
35
|
+
elevation: resolveSlabPlacementElevation(authored, baseElevation),
|
|
36
|
+
};
|
|
29
37
|
createNode(slab, levelId);
|
|
30
38
|
triggerSFX('sfx:structure-build');
|
|
31
39
|
return slab.id;
|
|
@@ -36,33 +44,70 @@ export const SlabTool = () => {
|
|
|
36
44
|
const closingLineRef = useRef(null);
|
|
37
45
|
const currentLevelId = useViewer((s) => s.selection.levelId);
|
|
38
46
|
const setSelection = useViewer((s) => s.setSelection);
|
|
47
|
+
const slabDefaults = useEditor((s) => s.toolDefaults.slab);
|
|
48
|
+
const isRecessed = slabDefaults?.recessed === true;
|
|
49
|
+
const camera = useThree((state) => state.camera);
|
|
50
|
+
const cameraRef = useRef(camera);
|
|
51
|
+
cameraRef.current = camera;
|
|
39
52
|
const [points, setPoints] = useState([]);
|
|
40
53
|
const [cursorPosition, setCursorPosition] = useState([0, 0]);
|
|
41
54
|
const [snappedCursorPosition, setSnappedCursorPosition] = useState([0, 0]);
|
|
42
55
|
const [levelY, setLevelY] = useState(0);
|
|
43
56
|
const previousSnappedPointRef = useRef(null);
|
|
57
|
+
const constructionPlaneRef = useRef(null);
|
|
44
58
|
// Clear preset-seeded defaults on deactivation so a later manual slab draw
|
|
45
59
|
// isn't built with a stale preset's parameters. Unmount-only.
|
|
46
60
|
useEffect(() => () => useEditor.getState().setToolDefaults('slab', null), []);
|
|
47
|
-
useEffect(() => () =>
|
|
61
|
+
useEffect(() => () => {
|
|
62
|
+
clearSlabSnapFeedback();
|
|
63
|
+
clearPlacementSurface();
|
|
64
|
+
}, []);
|
|
48
65
|
// Publish the live vertex count so the HUD shows "Finish" only at ≥ 3 points.
|
|
49
66
|
useEffect(() => {
|
|
50
67
|
useEditor.getState().setDraftVertexCount(points.length);
|
|
51
68
|
}, [points.length]);
|
|
52
69
|
useEffect(() => () => useEditor.getState().setDraftVertexCount(0), []);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
useFloorplanDraftPreview.getState().setPolygonDraft('slab', points);
|
|
72
|
+
}, [points]);
|
|
73
|
+
useEffect(() => () => {
|
|
74
|
+
const draftPreview = useFloorplanDraftPreview.getState();
|
|
75
|
+
if (draftPreview.polygonDraftType === 'slab') {
|
|
76
|
+
draftPreview.setPolygonDraft(null, []);
|
|
77
|
+
}
|
|
78
|
+
draftPreview.setCursorPoint(null);
|
|
79
|
+
}, []);
|
|
53
80
|
useEffect(() => {
|
|
54
81
|
if (!currentLevelId)
|
|
55
82
|
return;
|
|
83
|
+
const pointedSurfaceFor = (event) => event.nativeEvent?.target instanceof HTMLCanvasElement
|
|
84
|
+
? resolvePointerSupportSurface(cameraRef.current, event.position)
|
|
85
|
+
: null;
|
|
86
|
+
const resetDraft = () => {
|
|
87
|
+
setPoints([]);
|
|
88
|
+
constructionPlaneRef.current = null;
|
|
89
|
+
previousSnappedPointRef.current = null;
|
|
90
|
+
clearSlabSnapFeedback();
|
|
91
|
+
clearPlacementSurface();
|
|
92
|
+
};
|
|
56
93
|
const onGridMove = (event) => {
|
|
57
94
|
if (!cursorRef.current)
|
|
58
95
|
return;
|
|
59
|
-
const
|
|
96
|
+
const pointed = points.length === 0 && !isRecessed ? pointedSurfaceFor(event) : null;
|
|
97
|
+
const plane = constructionPlaneRef.current ?? (isRecessed ? resolveLevelConstructionPlane() : null);
|
|
98
|
+
if (plane) {
|
|
99
|
+
publishHorizontalConstructionPlane(event, plane);
|
|
100
|
+
}
|
|
101
|
+
else if (pointed) {
|
|
102
|
+
publishPlacementSurface(surfacePointScratch.set(event.position[0], pointed.worldY, event.position[2]), SURFACE_UP);
|
|
103
|
+
}
|
|
104
|
+
const localPosition = pointed?.localPoint ?? event.localPosition;
|
|
105
|
+
const rawPoint = [localPosition[0], localPosition[2]];
|
|
60
106
|
// Slab drafting is the 'polygon' snap context (grid / lines / off — no
|
|
61
107
|
// angle, no Shift bypass; Shift cycles the mode, Off is the bypass).
|
|
62
108
|
const gridStep = isGridSnapActive() ? useEditor.getState().gridSnapStep : 0;
|
|
63
109
|
const gridPosition = [...snapPointToGrid(rawPoint, gridStep)];
|
|
64
110
|
setCursorPosition(gridPosition);
|
|
65
|
-
setLevelY(event.localPosition[1]);
|
|
66
111
|
const lastPoint = points[points.length - 1];
|
|
67
112
|
// Angle lock only when the mode asks for it (polygon never does today, but
|
|
68
113
|
// honour the flag so the behaviour follows the HUD).
|
|
@@ -74,6 +119,10 @@ export const SlabTool = () => {
|
|
|
74
119
|
fallbackPoint: orthoPoint,
|
|
75
120
|
levelId: currentLevelId,
|
|
76
121
|
}).point;
|
|
122
|
+
const hoverPlane = plane ??
|
|
123
|
+
resampleTerrainConstructionPlane(resolveEventConstructionPlane(event, pointed), displayPoint);
|
|
124
|
+
setLevelY(hoverPlane.localY);
|
|
125
|
+
useFloorplanDraftPreview.getState().setCursorPoint(displayPoint);
|
|
77
126
|
setSnappedCursorPosition(displayPoint);
|
|
78
127
|
if (points.length > 0 &&
|
|
79
128
|
previousSnappedPointRef.current &&
|
|
@@ -82,9 +131,9 @@ export const SlabTool = () => {
|
|
|
82
131
|
triggerSFX('sfx:grid-snap');
|
|
83
132
|
}
|
|
84
133
|
previousSnappedPointRef.current = displayPoint;
|
|
85
|
-
cursorRef.current.position.set(displayPoint[0],
|
|
134
|
+
cursorRef.current.position.set(displayPoint[0], hoverPlane.localY, displayPoint[1]);
|
|
86
135
|
};
|
|
87
|
-
const onGridClick = (
|
|
136
|
+
const onGridClick = (event) => {
|
|
88
137
|
if (!currentLevelId)
|
|
89
138
|
return;
|
|
90
139
|
const clickPoint = previousSnappedPointRef.current ?? cursorPosition;
|
|
@@ -93,12 +142,21 @@ export const SlabTool = () => {
|
|
|
93
142
|
firstPoint &&
|
|
94
143
|
Math.abs(clickPoint[0] - firstPoint[0]) < 0.25 &&
|
|
95
144
|
Math.abs(clickPoint[1] - firstPoint[1]) < 0.25) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
145
|
+
if (shouldRegistryCommitSlab(useEditor.getState().viewMode, 'grid')) {
|
|
146
|
+
const slabId = commitSlabDrawing(currentLevelId, points, constructionPlaneRef.current?.elevation ?? null);
|
|
147
|
+
setSelection({ selectedIds: [slabId] });
|
|
148
|
+
}
|
|
149
|
+
resetDraft();
|
|
100
150
|
}
|
|
101
151
|
else {
|
|
152
|
+
if (points.length === 0) {
|
|
153
|
+
const plane = isRecessed
|
|
154
|
+
? (resolveLevelConstructionPlane() ?? resolveEventConstructionPlane(event, null))
|
|
155
|
+
: resampleTerrainConstructionPlane(resolveEventConstructionPlane(event, pointedSurfaceFor(event)), clickPoint);
|
|
156
|
+
constructionPlaneRef.current = plane;
|
|
157
|
+
setLevelY(plane.localY);
|
|
158
|
+
publishHorizontalConstructionPlane(event, plane);
|
|
159
|
+
}
|
|
102
160
|
// Every non-closing vertex is a "start" tick; the closing click above
|
|
103
161
|
// fires the structure-build (end) cue.
|
|
104
162
|
triggerSFX('sfx:structure-build-start');
|
|
@@ -107,27 +165,27 @@ export const SlabTool = () => {
|
|
|
107
165
|
};
|
|
108
166
|
// Finish the polygon (Enter or double-click): commit once there are enough
|
|
109
167
|
// vertices. Closing near the first vertex (in onGridClick) is the third way.
|
|
110
|
-
const finishDrawing = () => {
|
|
168
|
+
const finishDrawing = (trigger) => {
|
|
111
169
|
if (points.length < 3)
|
|
112
170
|
return;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
171
|
+
if (shouldRegistryCommitSlab(useEditor.getState().viewMode, trigger)) {
|
|
172
|
+
const slabId = commitSlabDrawing(currentLevelId, points, constructionPlaneRef.current?.elevation ?? null);
|
|
173
|
+
setSelection({ selectedIds: [slabId] });
|
|
174
|
+
}
|
|
175
|
+
resetDraft();
|
|
117
176
|
};
|
|
118
177
|
const onGridDoubleClick = (_event) => {
|
|
119
|
-
finishDrawing();
|
|
178
|
+
finishDrawing('grid');
|
|
120
179
|
};
|
|
121
180
|
const onCancel = () => {
|
|
122
181
|
if (points.length > 0)
|
|
123
182
|
markToolCancelConsumed();
|
|
124
|
-
|
|
125
|
-
clearSlabSnapFeedback();
|
|
183
|
+
resetDraft();
|
|
126
184
|
};
|
|
127
185
|
const onKeyDown = (e) => {
|
|
128
186
|
if (e.key === 'Enter') {
|
|
129
187
|
e.preventDefault();
|
|
130
|
-
finishDrawing();
|
|
188
|
+
finishDrawing('keyboard');
|
|
131
189
|
}
|
|
132
190
|
};
|
|
133
191
|
document.addEventListener('keydown', onKeyDown);
|
|
@@ -142,7 +200,7 @@ export const SlabTool = () => {
|
|
|
142
200
|
emitter.off('grid:double-click', onGridDoubleClick);
|
|
143
201
|
emitter.off('tool:cancel', onCancel);
|
|
144
202
|
};
|
|
145
|
-
}, [currentLevelId, points, cursorPosition, setSelection]);
|
|
203
|
+
}, [currentLevelId, points, cursorPosition, isRecessed, setSelection]);
|
|
146
204
|
useEffect(() => {
|
|
147
205
|
if (!(mainLineRef.current && closingLineRef.current))
|
|
148
206
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/solar-panel/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAgNzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAAc,CAAC,OAAO,cAAc,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/solar-panel/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAgNzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAAc,CAAC,OAAO,cAAc,CAyDtE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/solar-panel/tool.tsx"],"names":[],"mappings":"AA4BA;;;;;;;GAOG;AACH,QAAA,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/solar-panel/tool.tsx"],"names":[],"mappings":"AA4BA;;;;;;;GAOG;AACH,QAAA,MAAM,cAAc,mCAoJnB,CAAA;AAED,eAAe,cAAc,CAAA"}
|
package/dist/solar-panel/tool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { emitter, SolarPanelNode, sceneRegistry, useScene, } from '@pascal-app/core';
|
|
4
|
-
import { triggerSFX } from '@pascal-app/editor';
|
|
4
|
+
import { triggerSFX, usePlacementPreview } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
import * as THREE from 'three';
|
|
@@ -67,6 +67,13 @@ const SolarPanelTool = () => {
|
|
|
67
67
|
setPreviewSurfaceQuat(surfaceQuatFromNormal(normal, new THREE.Quaternion()));
|
|
68
68
|
setPreviewYaw((event.node.rotation ?? 0) + (hit.segment.rotation ?? 0));
|
|
69
69
|
setPreviewPos(worldToBuildingLocal(wx, wy, wz));
|
|
70
|
+
usePlacementPreview.getState().set(SolarPanelNode.parse({
|
|
71
|
+
...previewNode,
|
|
72
|
+
parentId: hit.segment.id,
|
|
73
|
+
position: [hit.localX, hit.localY, hit.localZ],
|
|
74
|
+
roofSegmentId: hit.segment.id,
|
|
75
|
+
surfaceNormal: [normal.x, normal.y, normal.z],
|
|
76
|
+
}), hit.segment);
|
|
70
77
|
publishRoofSurfacePlacementGuides({
|
|
71
78
|
roof: event.node,
|
|
72
79
|
segment: hit.segment,
|
|
@@ -98,6 +105,9 @@ const SolarPanelTool = () => {
|
|
|
98
105
|
state.dirtyNodes.add(hit.segment.id);
|
|
99
106
|
setSelection({ selectedIds: [panel.id] });
|
|
100
107
|
triggerSFX('sfx:item-place');
|
|
108
|
+
const placementPreview = usePlacementPreview.getState();
|
|
109
|
+
if (placementPreview.node?.id === previewNode.id)
|
|
110
|
+
placementPreview.clear();
|
|
101
111
|
clearRoofSurfacePlacementGuides();
|
|
102
112
|
event.stopPropagation();
|
|
103
113
|
};
|
|
@@ -108,12 +118,18 @@ const SolarPanelTool = () => {
|
|
|
108
118
|
emitter.off('roof:move', updatePreview);
|
|
109
119
|
emitter.off('roof:enter', updatePreview);
|
|
110
120
|
emitter.off('roof:click', onClick);
|
|
121
|
+
const placementPreview = usePlacementPreview.getState();
|
|
122
|
+
if (placementPreview.node?.id === previewNode.id)
|
|
123
|
+
placementPreview.clear();
|
|
111
124
|
clearRoofSurfacePlacementGuides();
|
|
112
125
|
};
|
|
113
126
|
}, [activeBuildingId, setSelection, previewNode]);
|
|
114
127
|
return (_jsxs(_Fragment, { children: [_jsx(RoofAttachmentFallbackPreview, { activeBuildingId: activeBuildingId, ghost: _jsx(SolarPanelPreview, { node: previewNode, invalid: true }), onInvalidTarget: () => {
|
|
115
128
|
setPreviewPos(null);
|
|
116
129
|
setPreviewSurfaceQuat(null);
|
|
130
|
+
const placementPreview = usePlacementPreview.getState();
|
|
131
|
+
if (placementPreview.node?.id === previewNode.id)
|
|
132
|
+
placementPreview.clear();
|
|
117
133
|
clearRoofSurfacePlacementGuides();
|
|
118
134
|
} }), activeBuildingId && previewPos && previewSurfaceQuat && (_jsx("group", { position: previewPos, children: _jsx("group", { "rotation-y": previewYaw, children: _jsx("group", { quaternion: previewSurfaceQuat, children: _jsx(SolarPanelPreview, { node: previewNode }) }) }) }))] }));
|
|
119
135
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/spawn/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAA8B,MAAM,kBAAkB,CAAA;AAKpG,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA0CpC,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/spawn/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAA8B,MAAM,kBAAkB,CAAA;AAKpG,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA0CpC,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAuE5D,CAAA"}
|
package/dist/spawn/definition.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/spawn/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/spawn/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAA;AAIzB,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,SAAS,CA+BhE,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { useScene, } from '@pascal-app/core';
|
|
1
|
+
import { useLiveNodeOverrides, useScene, } from '@pascal-app/core';
|
|
2
|
+
import { isAngleSnapActive } from '@pascal-app/editor';
|
|
2
3
|
import { rotateAffordanceDelta } from '../shared/rotate-affordance';
|
|
3
4
|
export const spawnRotateAffordance = {
|
|
4
5
|
start({ node, initialPlanPoint }) {
|
|
@@ -10,20 +11,22 @@ export const spawnRotateAffordance = {
|
|
|
10
11
|
let lastRotation = initialRotation;
|
|
11
12
|
return {
|
|
12
13
|
affectedIds: [spawnId],
|
|
13
|
-
apply({ planPoint
|
|
14
|
+
apply({ planPoint }) {
|
|
14
15
|
const delta = rotateAffordanceDelta({
|
|
15
16
|
center: [cx, cz],
|
|
16
17
|
initialAngle,
|
|
17
18
|
planPoint,
|
|
18
|
-
free:
|
|
19
|
+
free: !isAngleSnapActive(),
|
|
19
20
|
});
|
|
20
21
|
lastRotation = initialRotation - delta;
|
|
21
|
-
|
|
22
|
+
useLiveNodeOverrides.getState().set(spawnId, { rotation: lastRotation });
|
|
23
|
+
useScene.getState().markDirty(spawnId);
|
|
22
24
|
},
|
|
23
25
|
canCommit() {
|
|
24
26
|
return true;
|
|
25
27
|
},
|
|
26
28
|
commit() {
|
|
29
|
+
useLiveNodeOverrides.getState().clear(spawnId);
|
|
27
30
|
useScene.getState().updateNode(spawnId, { rotation: lastRotation });
|
|
28
31
|
},
|
|
29
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floorplan-move.d.ts","sourceRoot":"","sources":["../../src/spawn/floorplan-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EAExB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"floorplan-move.d.ts","sourceRoot":"","sources":["../../src/spawn/floorplan-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EAExB,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AAGzB,eAAO,MAAM,wBAAwB,EAAE,mBAAmB,CAAC,SAAS,CA8BnE,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { snapScalar, useScene, } from '@pascal-app/core';
|
|
2
|
-
import { getSegmentGridStep } from '@pascal-app/editor';
|
|
1
|
+
import { snapScalar, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
|
|
2
|
+
import { getSegmentGridStep, isGridSnapActive } from '@pascal-app/editor';
|
|
3
3
|
export const spawnFloorplanMoveTarget = ({ node }) => {
|
|
4
4
|
const spawnId = node.id;
|
|
5
5
|
const startY = node.position[1];
|
|
@@ -7,14 +7,15 @@ export const spawnFloorplanMoveTarget = ({ node }) => {
|
|
|
7
7
|
let lastPosition = null;
|
|
8
8
|
const session = {
|
|
9
9
|
affectedIds: [spawnId],
|
|
10
|
-
apply({ planPoint
|
|
11
|
-
const step = getSegmentGridStep();
|
|
12
|
-
const snap = (value) => (
|
|
10
|
+
apply({ planPoint }) {
|
|
11
|
+
const step = isGridSnapActive() ? getSegmentGridStep() : 0;
|
|
12
|
+
const snap = (value) => (step > 0 ? snapScalar(value, step) : value);
|
|
13
13
|
const next = [snap(planPoint[0]), startY, snap(planPoint[1])];
|
|
14
14
|
if (lastPosition && lastPosition[0] === next[0] && lastPosition[2] === next[2])
|
|
15
15
|
return;
|
|
16
16
|
lastPosition = next;
|
|
17
|
-
|
|
17
|
+
useLiveNodeOverrides.getState().set(spawnId, { position: next });
|
|
18
|
+
useScene.getState().markDirty(spawnId);
|
|
18
19
|
},
|
|
19
20
|
canCommit() {
|
|
20
21
|
if (!lastPosition)
|
|
@@ -24,6 +25,7 @@ export const spawnFloorplanMoveTarget = ({ node }) => {
|
|
|
24
25
|
commit() {
|
|
25
26
|
if (!lastPosition)
|
|
26
27
|
return;
|
|
28
|
+
useLiveNodeOverrides.getState().clear(spawnId);
|
|
27
29
|
useScene.getState().updateNodes([{ id: spawnId, data: { position: lastPosition } }]);
|
|
28
30
|
},
|
|
29
31
|
};
|
package/dist/spawn/renderer.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { type SpawnNode } from '@pascal-app/core';
|
|
2
|
+
export declare const SpawnPreview: ({ layers, node }: {
|
|
3
|
+
layers?: number;
|
|
4
|
+
node: SpawnNode;
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
2
6
|
/**
|
|
3
7
|
* Registry-driven spawn renderer. Behaviorally identical to the legacy
|
|
4
8
|
* `@pascal-app/viewer/components/renderers/spawn/spawn-renderer.tsx` — same
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/spawn/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/spawn/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AAoGzB,eAAO,MAAM,YAAY,GAAI,kBAAkB;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,gCAElF,CAAA;AAED;;;;;;;;;GASG;AACH,QAAA,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,gCAsBnD,CAAA;AAED,eAAe,aAAa,CAAA"}
|