@pascal-app/nodes 1.0.3 → 1.0.4
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/block/definition.d.ts.map +1 -1
- package/dist/block/definition.js +18 -3
- package/dist/block/floorplan.d.ts +11 -1
- package/dist/block/floorplan.d.ts.map +1 -1
- package/dist/block/floorplan.js +81 -13
- package/dist/block/geometry.d.ts +2 -2
- package/dist/block/geometry.d.ts.map +1 -1
- package/dist/block/geometry.js +39 -24
- package/dist/block/hosted-edit.d.ts.map +1 -1
- package/dist/block/hosted-edit.js +25 -0
- package/dist/block/material-slots.d.ts +1 -3
- package/dist/block/material-slots.d.ts.map +1 -1
- package/dist/block/material-slots.js +1 -11
- package/dist/block/paint.d.ts.map +1 -1
- package/dist/block/paint.js +4 -10
- package/dist/block/panel.d.ts.map +1 -1
- package/dist/block/panel.js +8 -3
- package/dist/block/selection.d.ts.map +1 -1
- package/dist/block/selection.js +2 -2
- package/dist/box-vent/definition.d.ts.map +1 -1
- package/dist/box-vent/definition.js +2 -5
- package/dist/box-vent/panel.d.ts.map +1 -1
- package/dist/box-vent/panel.js +5 -28
- package/dist/cabinet/countertop-layout.d.ts +13 -2
- package/dist/cabinet/countertop-layout.d.ts.map +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +1 -2
- package/dist/cabinet/floorplan.d.ts.map +1 -1
- package/dist/cabinet/floorplan.js +125 -28
- package/dist/cabinet/geometry/shared.d.ts +1 -2
- package/dist/cabinet/geometry/shared.d.ts.map +1 -1
- package/dist/cabinet/geometry/shared.js +1 -2
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +8 -5
- package/dist/cabinet/run-ops.d.ts +13 -2
- package/dist/cabinet/run-ops.d.ts.map +1 -1
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +22 -24
- package/dist/cabinet/wall-snap.d.ts.map +1 -1
- package/dist/cabinet/wall-snap.js +8 -8
- package/dist/ceiling/boundary-editor.d.ts.map +1 -1
- package/dist/ceiling/boundary-editor.js +5 -3
- package/dist/ceiling/definition.d.ts +4 -4
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +15 -15
- package/dist/ceiling/floorplan-affordances.d.ts +84 -4
- package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
- package/dist/ceiling/floorplan-affordances.js +0 -1
- package/dist/ceiling/floorplan-move.d.ts.map +1 -1
- package/dist/ceiling/floorplan-move.js +0 -1
- package/dist/ceiling/floorplan.d.ts +1 -1
- package/dist/ceiling/floorplan.d.ts.map +1 -1
- package/dist/ceiling/floorplan.js +2 -1
- package/dist/ceiling/height-bounds.d.ts +19 -0
- package/dist/ceiling/height-bounds.d.ts.map +1 -0
- package/dist/ceiling/height-bounds.js +24 -0
- package/dist/ceiling/hole-editor.d.ts.map +1 -1
- package/dist/ceiling/hole-editor.js +3 -4
- package/dist/ceiling/materials.d.ts +1 -1
- package/dist/ceiling/materials.d.ts.map +1 -1
- package/dist/ceiling/materials.js +10 -3
- package/dist/ceiling/paint.d.ts +2 -8
- package/dist/ceiling/paint.d.ts.map +1 -1
- package/dist/ceiling/paint.js +121 -24
- package/dist/ceiling/panel.d.ts.map +1 -1
- package/dist/ceiling/panel.js +40 -23
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +41 -5
- package/dist/chimney/move-tool.d.ts.map +1 -1
- package/dist/chimney/move-tool.js +8 -2
- package/dist/chimney/paint.d.ts.map +1 -1
- package/dist/chimney/paint.js +3 -10
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +24 -2
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +5 -0
- package/dist/column/floorplan.d.ts +1 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +47 -2
- package/dist/column/hosted-resize.d.ts +101 -2
- package/dist/column/hosted-resize.d.ts.map +1 -1
- package/dist/column/panel.d.ts.map +1 -1
- package/dist/column/panel.js +147 -146
- package/dist/column/renderer.d.ts.map +1 -1
- package/dist/column/renderer.js +6 -4
- package/dist/column/surface.d.ts.map +1 -1
- package/dist/column/surface.js +7 -0
- package/dist/construction-dimension/floorplan.js +7 -3
- package/dist/cupola/definition.d.ts.map +1 -1
- package/dist/cupola/definition.js +2 -8
- package/dist/cupola/panel.d.ts.map +1 -1
- package/dist/cupola/panel.js +5 -23
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +12 -3
- package/dist/door/door-math.d.ts +5 -10
- package/dist/door/door-math.d.ts.map +1 -1
- package/dist/door/door-math.js +14 -15
- package/dist/door/floorplan-move.d.ts.map +1 -1
- package/dist/door/floorplan-move.js +3 -1
- package/dist/door/floorplan.d.ts.map +1 -1
- package/dist/door/floorplan.js +55 -21
- package/dist/door/mechanism.d.ts +4 -0
- package/dist/door/mechanism.d.ts.map +1 -0
- package/dist/door/mechanism.js +24 -0
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +72 -48
- package/dist/door/paint.d.ts.map +1 -1
- package/dist/door/paint.js +3 -0
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +34 -259
- package/dist/door/placement.d.ts +45 -0
- package/dist/door/placement.d.ts.map +1 -0
- package/dist/door/placement.js +51 -0
- package/dist/door/preview.d.ts.map +1 -1
- package/dist/door/preview.js +2 -0
- package/dist/door/renderer.d.ts.map +1 -1
- package/dist/door/renderer.js +3 -2
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +92 -21
- package/dist/dormer/csg-geometry.d.ts.map +1 -1
- package/dist/dormer/csg-geometry.js +2 -0
- package/dist/dormer/paint.d.ts.map +1 -1
- package/dist/dormer/paint.js +2 -5
- package/dist/dormer/panel.d.ts.map +1 -1
- package/dist/dormer/panel.js +4 -14
- package/dist/downspout/definition.d.ts.map +1 -1
- package/dist/downspout/definition.js +2 -2
- package/dist/duct-fitting/definition.d.ts.map +1 -1
- package/dist/duct-fitting/definition.js +2 -1
- package/dist/duct-fitting/geometry.d.ts.map +1 -1
- package/dist/duct-fitting/geometry.js +1 -1
- package/dist/duct-fitting/move-tool.d.ts.map +1 -1
- package/dist/duct-fitting/move-tool.js +8 -2
- package/dist/duct-segment/definition.d.ts.map +1 -1
- package/dist/duct-segment/definition.js +2 -2
- package/dist/duct-segment/geometry.d.ts.map +1 -1
- package/dist/duct-segment/geometry.js +1 -1
- package/dist/duct-segment/move-tool.d.ts.map +1 -1
- package/dist/duct-segment/move-tool.js +8 -2
- package/dist/elevator/definition.d.ts.map +1 -1
- package/dist/elevator/definition.js +1 -2
- package/dist/elevator/panel.d.ts.map +1 -1
- package/dist/elevator/panel.js +5 -27
- package/dist/elevator/parametrics.js +1 -1
- package/dist/elevator/renderer.d.ts.map +1 -1
- package/dist/elevator/renderer.js +3 -4
- package/dist/eyebrow-vent/definition.d.ts.map +1 -1
- package/dist/eyebrow-vent/definition.js +2 -5
- package/dist/eyebrow-vent/paint.d.ts.map +1 -1
- package/dist/eyebrow-vent/paint.js +3 -6
- package/dist/eyebrow-vent/panel.d.ts.map +1 -1
- package/dist/eyebrow-vent/panel.js +5 -23
- package/dist/fence/actions/move-endpoint.d.ts +1 -1
- package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
- package/dist/fence/actions/move-endpoint.js +2 -1
- package/dist/fence/definition.d.ts +2 -1
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +83 -28
- package/dist/fence/drafting.d.ts +36 -0
- package/dist/fence/drafting.d.ts.map +1 -0
- package/dist/fence/drafting.js +210 -0
- package/dist/fence/feature-tool.d.ts +4 -0
- package/dist/fence/feature-tool.d.ts.map +1 -0
- package/dist/fence/feature-tool.js +140 -0
- package/dist/fence/features.d.ts +2 -0
- package/dist/fence/features.d.ts.map +1 -0
- package/dist/fence/features.js +12 -0
- package/dist/fence/floorplan-affordances.d.ts.map +1 -1
- package/dist/fence/floorplan-affordances.js +2 -1
- package/dist/fence/floorplan.d.ts +2 -3
- package/dist/fence/floorplan.d.ts.map +1 -1
- package/dist/fence/floorplan.js +131 -71
- package/dist/fence/geometry-parts.d.ts +50 -0
- package/dist/fence/geometry-parts.d.ts.map +1 -0
- package/dist/fence/geometry-parts.js +1144 -0
- package/dist/fence/geometry.d.ts +2 -3
- package/dist/fence/geometry.d.ts.map +1 -1
- package/dist/fence/geometry.js +84 -7
- package/dist/fence/index.d.ts +1 -0
- package/dist/fence/index.d.ts.map +1 -1
- package/dist/fence/index.js +1 -0
- package/dist/fence/inspector-editors.d.ts +15 -0
- package/dist/fence/inspector-editors.d.ts.map +1 -1
- package/dist/fence/inspector-editors.js +128 -3
- package/dist/fence/lift.d.ts.map +1 -1
- package/dist/fence/lift.js +5 -2
- package/dist/fence/move-tool.js +2 -1
- package/dist/fence/panel-model.d.ts +4 -0
- package/dist/fence/panel-model.d.ts.map +1 -0
- package/dist/fence/panel-model.js +12 -0
- package/dist/fence/parametrics.d.ts +0 -12
- package/dist/fence/parametrics.d.ts.map +1 -1
- package/dist/fence/parametrics.js +185 -18
- package/dist/fence/system.d.ts.map +1 -1
- package/dist/fence/system.js +141 -31
- package/dist/fence/tool.d.ts.map +1 -1
- package/dist/fence/tool.js +256 -47
- package/dist/fence-feature/actions.d.ts +7 -0
- package/dist/fence-feature/actions.d.ts.map +1 -0
- package/dist/fence-feature/actions.js +26 -0
- package/dist/fence-feature/definition.d.ts +4 -0
- package/dist/fence-feature/definition.d.ts.map +1 -0
- package/dist/fence-feature/definition.js +112 -0
- package/dist/fence-feature/floorplan-affordances.d.ts +3 -0
- package/dist/fence-feature/floorplan-affordances.d.ts.map +1 -0
- package/dist/fence-feature/floorplan-affordances.js +37 -0
- package/dist/fence-feature/floorplan.d.ts +4 -0
- package/dist/fence-feature/floorplan.d.ts.map +1 -0
- package/dist/fence-feature/floorplan.js +120 -0
- package/dist/fence-feature/geometry.d.ts +5 -0
- package/dist/fence-feature/geometry.d.ts.map +1 -0
- package/dist/fence-feature/geometry.js +43 -0
- package/dist/fence-feature/handles.d.ts +5 -0
- package/dist/fence-feature/handles.d.ts.map +1 -0
- package/dist/fence-feature/handles.js +84 -0
- package/dist/fence-feature/inspector.d.ts +6 -0
- package/dist/fence-feature/inspector.d.ts.map +1 -0
- package/dist/fence-feature/inspector.js +214 -0
- package/dist/fence-feature/interaction.d.ts +3 -0
- package/dist/fence-feature/interaction.d.ts.map +1 -0
- package/dist/fence-feature/interaction.js +41 -0
- package/dist/fence-feature/move-session.d.ts +9 -0
- package/dist/fence-feature/move-session.d.ts.map +1 -0
- package/dist/fence-feature/move-session.js +48 -0
- package/dist/fence-feature/move-tool.d.ts +5 -0
- package/dist/fence-feature/move-tool.d.ts.map +1 -0
- package/dist/fence-feature/move-tool.js +58 -0
- package/dist/fence-feature/pick-target.d.ts +7 -0
- package/dist/fence-feature/pick-target.d.ts.map +1 -0
- package/dist/fence-feature/pick-target.js +52 -0
- package/dist/floor-opening/definition.d.ts +3 -0
- package/dist/floor-opening/definition.d.ts.map +1 -0
- package/dist/floor-opening/definition.js +41 -0
- package/dist/floor-opening/floorplan.d.ts +156 -0
- package/dist/floor-opening/floorplan.d.ts.map +1 -0
- package/dist/floor-opening/floorplan.js +63 -0
- package/dist/gutter/definition.d.ts.map +1 -1
- package/dist/gutter/definition.js +2 -2
- package/dist/imported-mesh/definition.d.ts.map +1 -1
- package/dist/imported-mesh/definition.js +2 -0
- package/dist/imported-mesh/geometry.d.ts +1 -1
- package/dist/imported-mesh/geometry.d.ts.map +1 -1
- package/dist/imported-mesh/geometry.js +40 -12
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -2
- package/dist/item/authored-face-host.d.ts +10 -0
- package/dist/item/authored-face-host.d.ts.map +1 -0
- package/dist/item/authored-face-host.js +87 -0
- package/dist/item/authored-params.d.ts +15 -0
- package/dist/item/authored-params.d.ts.map +1 -0
- package/dist/item/authored-params.js +72 -0
- package/dist/item/definition.d.ts +2 -2
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +33 -4
- package/dist/item/floorplan.d.ts +1 -1
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +35 -5
- package/dist/item/index.d.ts +1 -0
- package/dist/item/index.d.ts.map +1 -1
- package/dist/item/index.js +1 -0
- package/dist/item/model-loader.d.ts +2 -0
- package/dist/item/model-loader.d.ts.map +1 -1
- package/dist/item/model-loader.js +55 -23
- package/dist/item/move-tool.js +4 -4
- package/dist/item/paint.d.ts.map +1 -1
- package/dist/item/paint.js +5 -24
- package/dist/item/panel.d.ts +1 -3
- package/dist/item/panel.d.ts.map +1 -1
- package/dist/item/panel.js +20 -24
- package/dist/item/placement-notice.d.ts +14 -0
- package/dist/item/placement-notice.d.ts.map +1 -0
- package/dist/item/placement-notice.js +38 -0
- package/dist/item/plan-symbols.d.ts +67 -0
- package/dist/item/plan-symbols.d.ts.map +1 -0
- package/dist/item/plan-symbols.js +407 -0
- package/dist/item/renderer.d.ts +10 -0
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +64 -38
- package/dist/item/script-param-defaults.d.ts +12 -0
- package/dist/item/script-param-defaults.d.ts.map +1 -0
- package/dist/item/script-param-defaults.js +34 -0
- package/dist/lean-to-extension/definition.d.ts.map +1 -1
- package/dist/lean-to-extension/definition.js +1 -2
- package/dist/lean-to-extension/geometry.d.ts.map +1 -1
- package/dist/lean-to-extension/geometry.js +1 -1
- package/dist/lean-to-extension/layout.d.ts.map +1 -1
- package/dist/lean-to-extension/layout.js +2 -3
- package/dist/lean-to-extension/placement-validation.d.ts.map +1 -1
- package/dist/lean-to-extension/placement-validation.js +5 -5
- package/dist/lean-to-extension/tool.d.ts.map +1 -1
- package/dist/lean-to-extension/tool.js +5 -5
- package/dist/lineset/move-tool.d.ts.map +1 -1
- package/dist/lineset/move-tool.js +8 -2
- package/dist/liquid-line/move-tool.d.ts.map +1 -1
- package/dist/liquid-line/move-tool.js +8 -2
- package/dist/measurement/definition.js +1 -1
- package/dist/pipe-fitting/move-tool.d.ts.map +1 -1
- package/dist/pipe-fitting/move-tool.js +8 -2
- package/dist/pipe-segment/move-tool.d.ts.map +1 -1
- package/dist/pipe-segment/move-tool.js +8 -2
- package/dist/procedural-item/animation.d.ts +8 -0
- package/dist/procedural-item/animation.d.ts.map +1 -0
- package/dist/procedural-item/animation.js +116 -0
- package/dist/procedural-item/definition.d.ts.map +1 -1
- package/dist/procedural-item/definition.js +74 -8
- package/dist/procedural-item/geometry.d.ts +5 -1
- package/dist/procedural-item/geometry.d.ts.map +1 -1
- package/dist/procedural-item/geometry.js +239 -15
- package/dist/procedural-item/renderer.d.ts.map +1 -1
- package/dist/procedural-item/renderer.js +272 -23
- package/dist/ridge-vent/panel.d.ts.map +1 -1
- package/dist/ridge-vent/panel.js +5 -23
- package/dist/ridge-vent/renderer.d.ts.map +1 -1
- package/dist/ridge-vent/renderer.js +9 -8
- package/dist/roof/definition.d.ts.map +1 -1
- package/dist/roof/definition.js +4 -1
- package/dist/roof/floorplan.d.ts +8 -0
- package/dist/roof/floorplan.d.ts.map +1 -1
- package/dist/roof/floorplan.js +194 -18
- package/dist/roof/panel-model.d.ts.map +1 -1
- package/dist/roof/panel-model.js +10 -6
- package/dist/roof/panel.d.ts.map +1 -1
- package/dist/roof/panel.js +3 -10
- package/dist/roof/renderer.d.ts.map +1 -1
- package/dist/roof/renderer.js +5 -2
- package/dist/roof-segment/panel.d.ts.map +1 -1
- package/dist/roof-segment/panel.js +5 -24
- package/dist/roof-segment/renderer.d.ts.map +1 -1
- package/dist/roof-segment/renderer.js +17 -8
- package/dist/separator/definition.d.ts +3 -0
- package/dist/separator/definition.d.ts.map +1 -0
- package/dist/separator/definition.js +39 -0
- package/dist/separator/renderer.d.ts +5 -0
- package/dist/separator/renderer.d.ts.map +1 -0
- package/dist/separator/renderer.js +36 -0
- package/dist/shared/duct-body-paint.d.ts +0 -4
- package/dist/shared/duct-body-paint.d.ts.map +1 -1
- package/dist/shared/duct-body-paint.js +1 -5
- package/dist/shared/item-interaction-actions.d.ts +6 -0
- package/dist/shared/item-interaction-actions.d.ts.map +1 -0
- package/dist/shared/item-interaction-actions.js +27 -0
- package/dist/shared/item-interactions.d.ts +9 -0
- package/dist/shared/item-interactions.d.ts.map +1 -0
- package/dist/shared/item-interactions.js +74 -0
- package/dist/shared/item-light-placement.d.ts +2 -0
- package/dist/shared/item-light-placement.d.ts.map +1 -0
- package/dist/shared/item-light-placement.js +3 -0
- package/dist/shared/move-roof-tool.js +2 -1
- package/dist/shared/node-batch/batchable.d.ts +12 -0
- package/dist/shared/node-batch/batchable.d.ts.map +1 -0
- package/dist/shared/node-batch/batchable.js +41 -0
- package/dist/shared/node-batch/candidates.d.ts +7 -5
- package/dist/shared/node-batch/candidates.d.ts.map +1 -1
- package/dist/shared/node-batch/candidates.js +43 -59
- package/dist/shared/node-batch/release.d.ts +8 -0
- package/dist/shared/node-batch/release.d.ts.map +1 -0
- package/dist/shared/node-batch/release.js +16 -0
- package/dist/shared/node-batch/system.d.ts.map +1 -1
- package/dist/shared/node-batch/system.js +17 -12
- package/dist/shared/node-batch/types.d.ts +4 -1
- package/dist/shared/node-batch/types.d.ts.map +1 -1
- package/dist/shared/opening-documentation.d.ts +13 -1
- package/dist/shared/opening-documentation.d.ts.map +1 -1
- package/dist/shared/opening-documentation.js +245 -59
- package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
- package/dist/shared/opening-guides-runtime.js +17 -14
- package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.js +3 -3
- package/dist/shared/opening-plane-offset.d.ts +23 -0
- package/dist/shared/opening-plane-offset.d.ts.map +1 -0
- package/dist/shared/opening-plane-offset.js +24 -0
- package/dist/shared/polygon-centroid-move.d.ts.map +1 -1
- package/dist/shared/polygon-centroid-move.js +4 -1
- package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
- package/dist/shared/polygon-vertex-affordance.js +19 -15
- package/dist/shared/run-hangers.d.ts.map +1 -1
- package/dist/shared/run-hangers.js +5 -4
- package/dist/shared/scripted-opening-handles.d.ts +18 -0
- package/dist/shared/scripted-opening-handles.d.ts.map +1 -0
- package/dist/shared/scripted-opening-handles.js +53 -0
- package/dist/shared/scripted-opening.d.ts +25 -0
- package/dist/shared/scripted-opening.d.ts.map +1 -0
- package/dist/shared/scripted-opening.js +72 -0
- package/dist/shared/slot-paint.d.ts +14 -2
- package/dist/shared/slot-paint.d.ts.map +1 -1
- package/dist/shared/slot-paint.js +29 -29
- package/dist/shared/surface-paint.d.ts.map +1 -1
- package/dist/shared/surface-paint.js +2 -5
- package/dist/shared/swap-preview-material.d.ts +11 -0
- package/dist/shared/swap-preview-material.d.ts.map +1 -0
- package/dist/shared/swap-preview-material.js +16 -0
- package/dist/shared/system-checks.d.ts.map +1 -1
- package/dist/shared/system-checks.js +5 -3
- package/dist/shared/wall-attach-target.d.ts +3 -10
- package/dist/shared/wall-attach-target.d.ts.map +1 -1
- package/dist/shared/wall-attach-target.js +3 -63
- package/dist/shared/wall-opening-ceiling.d.ts +5 -15
- package/dist/shared/wall-opening-ceiling.d.ts.map +1 -1
- package/dist/shared/wall-opening-ceiling.js +10 -18
- package/dist/shelf/definition.d.ts.map +1 -1
- package/dist/shelf/definition.js +1 -1
- package/dist/shelf/geometry.d.ts.map +1 -1
- package/dist/shelf/geometry.js +1 -2
- package/dist/shelf/paint.d.ts.map +1 -1
- package/dist/shelf/paint.js +4 -10
- package/dist/site/line-ribbon.d.ts +31 -0
- package/dist/site/line-ribbon.d.ts.map +1 -0
- package/dist/site/line-ribbon.js +117 -0
- package/dist/site/lot-mask.d.ts +18 -0
- package/dist/site/lot-mask.d.ts.map +1 -0
- package/dist/site/lot-mask.js +35 -0
- package/dist/site/panel.d.ts +10 -0
- package/dist/site/panel.d.ts.map +1 -0
- package/dist/site/panel.js +155 -0
- package/dist/site/parametrics.d.ts +7 -0
- package/dist/site/parametrics.d.ts.map +1 -1
- package/dist/site/parametrics.js +8 -0
- package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
- package/dist/site/recessed-slab-ground-holes.js +5 -2
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +150 -19
- package/dist/site/setbacks.d.ts +33 -0
- package/dist/site/setbacks.d.ts.map +1 -0
- package/dist/site/setbacks.js +204 -0
- package/dist/site/terrain-geometry.d.ts +28 -1
- package/dist/site/terrain-geometry.d.ts.map +1 -1
- package/dist/site/terrain-geometry.js +78 -4
- package/dist/site/terrain-holes.d.ts +15 -0
- package/dist/site/terrain-holes.d.ts.map +1 -0
- package/dist/site/terrain-holes.js +74 -0
- package/dist/site/terrain-mesh.d.ts +9 -2
- package/dist/site/terrain-mesh.d.ts.map +1 -1
- package/dist/site/terrain-mesh.js +36 -9
- package/dist/site/terrain-renderer.d.ts +9 -2
- package/dist/site/terrain-renderer.d.ts.map +1 -1
- package/dist/site/terrain-renderer.js +14 -4
- package/dist/slab/boundary-editor.d.ts +1 -1
- package/dist/slab/boundary-editor.d.ts.map +1 -1
- package/dist/slab/boundary-editor.js +13 -13
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +19 -3
- package/dist/slab/dependency-tracker.d.ts.map +1 -1
- package/dist/slab/dependency-tracker.js +67 -7
- package/dist/slab/elevation-limit.d.ts.map +1 -1
- package/dist/slab/elevation-limit.js +2 -2
- package/dist/slab/floorplan-affordances.d.ts +176 -4
- package/dist/slab/floorplan-affordances.d.ts.map +1 -1
- package/dist/slab/floorplan-affordances.js +0 -1
- package/dist/slab/floorplan-move.d.ts.map +1 -1
- package/dist/slab/floorplan-move.js +3 -4
- package/dist/slab/floorplan.d.ts +7 -0
- package/dist/slab/floorplan.d.ts.map +1 -1
- package/dist/slab/floorplan.js +22 -5
- package/dist/slab/geometry.d.ts.map +1 -1
- package/dist/slab/geometry.js +186 -76
- package/dist/slab/move-tool.js +7 -6
- package/dist/slab/paint.d.ts +18 -5
- package/dist/slab/paint.d.ts.map +1 -1
- package/dist/slab/paint.js +458 -9
- package/dist/slab/panel.d.ts.map +1 -1
- package/dist/slab/panel.js +28 -9
- package/dist/slab/placement-ownership.d.ts +2 -1
- package/dist/slab/placement-ownership.d.ts.map +1 -1
- package/dist/slab/placement-ownership.js +2 -2
- package/dist/slab/surface-split.d.ts +24 -0
- package/dist/slab/surface-split.d.ts.map +1 -0
- package/dist/slab/surface-split.js +389 -0
- package/dist/slab/tool.d.ts.map +1 -1
- package/dist/slab/tool.js +3 -3
- package/dist/stair/baluster-geometry.d.ts +21 -0
- package/dist/stair/baluster-geometry.d.ts.map +1 -0
- package/dist/stair/baluster-geometry.js +74 -0
- package/dist/stair/baluster-guard.d.ts +50 -0
- package/dist/stair/baluster-guard.d.ts.map +1 -0
- package/dist/stair/baluster-guard.js +71 -0
- package/dist/stair/boards-guard.d.ts +37 -0
- package/dist/stair/boards-guard.d.ts.map +1 -0
- package/dist/stair/boards-guard.js +61 -0
- package/dist/stair/cable-guard.d.ts +39 -0
- package/dist/stair/cable-guard.d.ts.map +1 -0
- package/dist/stair/cable-guard.js +105 -0
- package/dist/stair/construction-controls.d.ts +15 -0
- package/dist/stair/construction-controls.d.ts.map +1 -0
- package/dist/stair/construction-controls.js +29 -0
- package/dist/stair/continuous-railings.d.ts +10 -0
- package/dist/stair/continuous-railings.d.ts.map +1 -0
- package/dist/stair/continuous-railings.js +159 -0
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +16 -37
- package/dist/stair/documentation.d.ts +1 -1
- package/dist/stair/documentation.d.ts.map +1 -1
- package/dist/stair/documentation.js +10 -17
- package/dist/stair/floorplan-affordances.d.ts.map +1 -1
- package/dist/stair/floorplan-affordances.js +9 -25
- package/dist/stair/floorplan.d.ts +1 -23
- package/dist/stair/floorplan.d.ts.map +1 -1
- package/dist/stair/floorplan.js +102 -86
- package/dist/stair/glass-guard.d.ts +72 -0
- package/dist/stair/glass-guard.d.ts.map +1 -0
- package/dist/stair/glass-guard.js +167 -0
- package/dist/stair/guard-path.d.ts +119 -0
- package/dist/stair/guard-path.d.ts.map +1 -0
- package/dist/stair/guard-path.js +208 -0
- package/dist/stair/materials.d.ts +11 -0
- package/dist/stair/materials.d.ts.map +1 -0
- package/dist/stair/materials.js +51 -0
- package/dist/stair/metal-guard.d.ts +38 -0
- package/dist/stair/metal-guard.d.ts.map +1 -0
- package/dist/stair/metal-guard.js +79 -0
- package/dist/stair/paint.d.ts +32 -0
- package/dist/stair/paint.d.ts.map +1 -1
- package/dist/stair/paint.js +75 -36
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +154 -17
- package/dist/stair/parametrics.d.ts +1 -1
- package/dist/stair/parametrics.d.ts.map +1 -1
- package/dist/stair/parametrics.js +32 -15
- package/dist/stair/plan-entry.d.ts +31 -0
- package/dist/stair/plan-entry.d.ts.map +1 -0
- package/dist/stair/plan-entry.js +325 -0
- package/dist/stair/post-and-rail-guard.d.ts +31 -0
- package/dist/stair/post-and-rail-guard.d.ts.map +1 -0
- package/dist/stair/post-and-rail-guard.js +63 -0
- package/dist/stair/railing-controls.d.ts +9 -0
- package/dist/stair/railing-controls.d.ts.map +1 -0
- package/dist/stair/railing-controls.js +49 -0
- package/dist/stair/renderer.d.ts.map +1 -1
- package/dist/stair/renderer.js +259 -259
- package/dist/stair/use-stair-render-data.d.ts +317 -0
- package/dist/stair/use-stair-render-data.d.ts.map +1 -0
- package/dist/stair/use-stair-render-data.js +73 -0
- package/dist/stair-segment/definition.d.ts.map +1 -1
- package/dist/stair-segment/definition.js +51 -10
- package/dist/stair-segment/panel.d.ts.map +1 -1
- package/dist/stair-segment/panel.js +36 -42
- package/dist/stair-segment/parametrics.d.ts +1 -1
- package/dist/stair-segment/parametrics.d.ts.map +1 -1
- package/dist/stair-segment/parametrics.js +21 -8
- package/dist/stair-segment/renderer.d.ts.map +1 -1
- package/dist/stair-segment/renderer.js +16 -28
- package/dist/turbine-vent/definition.d.ts.map +1 -1
- package/dist/turbine-vent/definition.js +2 -5
- package/dist/turbine-vent/paint.d.ts.map +1 -1
- package/dist/turbine-vent/paint.js +2 -5
- package/dist/turbine-vent/panel.d.ts.map +1 -1
- package/dist/turbine-vent/panel.js +5 -23
- package/dist/unit/unit-panel.d.ts.map +1 -1
- package/dist/unit/unit-panel.js +6 -1
- package/dist/wall/actions.d.ts.map +1 -1
- package/dist/wall/actions.js +7 -2
- package/dist/wall/construction-dimensions.js +8 -5
- package/dist/wall/contextual-dimensions.js +4 -4
- package/dist/wall/curtain-wall-materials.d.ts +1 -1
- package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
- package/dist/wall/curtain-wall-materials.js +2 -2
- package/dist/wall/curve-tool.d.ts.map +1 -1
- package/dist/wall/curve-tool.js +4 -0
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +41 -17
- package/dist/wall/floorplan-move.d.ts +1 -1
- package/dist/wall/floorplan-move.d.ts.map +1 -1
- package/dist/wall/floorplan-move.js +20 -83
- package/dist/wall/floorplan-tool.d.ts.map +1 -1
- package/dist/wall/floorplan-tool.js +10 -11
- package/dist/wall/floorplan.d.ts +3 -1
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +184 -21
- package/dist/wall/measurement.d.ts.map +1 -1
- package/dist/wall/measurement.js +5 -5
- package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
- package/dist/wall/move-endpoint-tool.js +20 -7
- package/dist/wall/move-shared.d.ts.map +1 -1
- package/dist/wall/move-shared.js +11 -7
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +118 -148
- package/dist/wall/paint.d.ts +26 -15
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +306 -117
- package/dist/wall/panel-model.d.ts +18 -0
- package/dist/wall/panel-model.d.ts.map +1 -1
- package/dist/wall/panel-model.js +77 -19
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +217 -41
- package/dist/wall/parametrics.d.ts.map +1 -1
- package/dist/wall/parametrics.js +3 -0
- package/dist/wall/rectangle-command.d.ts +111 -12
- package/dist/wall/rectangle-command.d.ts.map +1 -1
- package/dist/wall/rectangle-tool.d.ts.map +1 -1
- package/dist/wall/rectangle-tool.js +26 -8
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +4 -2
- package/dist/wall/split-floorplan-layer.d.ts.map +1 -1
- package/dist/wall/split-floorplan-layer.js +7 -7
- package/dist/wall/split-session.d.ts.map +1 -1
- package/dist/wall/split-session.js +7 -1
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +36 -4
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +105 -49
- package/dist/wall/treatment-level-data.d.ts +3 -2
- package/dist/wall/treatment-level-data.d.ts.map +1 -1
- package/dist/wall/treatment-level-data.js +17 -13
- package/dist/wall/treatments.d.ts +10 -10
- package/dist/wall/treatments.d.ts.map +1 -1
- package/dist/wall/treatments.js +67 -54
- package/dist/wall/wall-batch-system.d.ts +7 -0
- package/dist/wall/wall-batch-system.d.ts.map +1 -1
- package/dist/wall/wall-batch-system.js +35 -3
- package/dist/wall/wall-batch.d.ts +6 -0
- package/dist/wall/wall-batch.d.ts.map +1 -1
- package/dist/wall/wall-batch.js +7 -1
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +12 -4
- package/dist/window/floorplan-move.d.ts.map +1 -1
- package/dist/window/floorplan-move.js +3 -1
- package/dist/window/floorplan.d.ts.map +1 -1
- package/dist/window/floorplan.js +145 -60
- package/dist/window/mechanism.d.ts +4 -0
- package/dist/window/mechanism.d.ts.map +1 -0
- package/dist/window/mechanism.js +20 -0
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +79 -48
- package/dist/window/paint.d.ts.map +1 -1
- package/dist/window/paint.js +3 -0
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +32 -88
- package/dist/window/placement.d.ts +23 -0
- package/dist/window/placement.d.ts.map +1 -0
- package/dist/window/placement.js +66 -0
- package/dist/window/preview.d.ts.map +1 -1
- package/dist/window/preview.js +2 -0
- package/dist/window/renderer.d.ts.map +1 -1
- package/dist/window/renderer.js +3 -2
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +96 -24
- package/dist/window/window-math.d.ts +6 -14
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +14 -20
- package/dist/zone/contextual-dimensions.d.ts.map +1 -1
- package/dist/zone/contextual-dimensions.js +6 -28
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +3 -3
- package/dist/zone/floorplan-affordances.d.ts +200 -0
- package/dist/zone/floorplan-affordances.d.ts.map +1 -1
- package/dist/zone/floorplan.d.ts +1 -1
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +93 -53
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +3 -14
- package/dist/zone/quick-measurement.d.ts +2 -2
- package/dist/zone/quick-measurement.d.ts.map +1 -1
- package/dist/zone/quick-measurement.js +6 -5
- package/dist/zone/renderer.d.ts +1 -1
- package/dist/zone/renderer.d.ts.map +1 -1
- package/dist/zone/renderer.js +58 -146
- package/dist/zone/room-clear-dimensions.js +3 -3
- package/dist/zone/room-documentation.d.ts.map +1 -1
- package/dist/zone/room-documentation.js +2 -6
- package/package.json +11 -11
- package/dist/block/slots.d.ts +0 -4
- package/dist/block/slots.d.ts.map +0 -1
- package/dist/block/slots.js +0 -17
- package/dist/cabinet/slots.d.ts +0 -4
- package/dist/cabinet/slots.d.ts.map +0 -1
- package/dist/cabinet/slots.js +0 -24
- package/dist/ceiling/slots.d.ts +0 -6
- package/dist/ceiling/slots.d.ts.map +0 -1
- package/dist/ceiling/slots.js +0 -7
- package/dist/column/slots.d.ts +0 -9
- package/dist/column/slots.d.ts.map +0 -1
- package/dist/column/slots.js +0 -19
- package/dist/door/slots.d.ts +0 -9
- package/dist/door/slots.d.ts.map +0 -1
- package/dist/door/slots.js +0 -20
- package/dist/elevator/slots.d.ts +0 -8
- package/dist/elevator/slots.d.ts.map +0 -1
- package/dist/elevator/slots.js +0 -17
- package/dist/fence/slots.d.ts +0 -10
- package/dist/fence/slots.d.ts.map +0 -1
- package/dist/fence/slots.js +0 -23
- package/dist/item/__fixtures__/main-floorplan.d.ts +0 -26
- package/dist/item/__fixtures__/main-floorplan.d.ts.map +0 -1
- package/dist/item/__fixtures__/main-floorplan.js +0 -297
- package/dist/lean-to-extension/slots.d.ts +0 -5
- package/dist/lean-to-extension/slots.d.ts.map +0 -1
- package/dist/lean-to-extension/slots.js +0 -15
- package/dist/shelf/slots.d.ts +0 -9
- package/dist/shelf/slots.d.ts.map +0 -1
- package/dist/shelf/slots.js +0 -30
- package/dist/slab/slots.d.ts +0 -10
- package/dist/slab/slots.d.ts.map +0 -1
- package/dist/slab/slots.js +0 -20
- package/dist/stair/floor-stack.d.ts +0 -10
- package/dist/stair/floor-stack.d.ts.map +0 -1
- package/dist/stair/floor-stack.js +0 -115
- package/dist/stair/slots.d.ts +0 -7
- package/dist/stair/slots.d.ts.map +0 -1
- package/dist/stair/slots.js +0 -13
- package/dist/wall/drawing-mode.d.ts +0 -12
- package/dist/wall/drawing-mode.d.ts.map +0 -1
- package/dist/wall/drawing-mode.js +0 -38
- package/dist/wall/slots.d.ts +0 -10
- package/dist/wall/slots.d.ts.map +0 -1
- package/dist/wall/slots.js +0 -92
- package/dist/window/slots.d.ts +0 -5
- package/dist/window/slots.d.ts.map +0 -1
- package/dist/window/slots.js +0 -11
|
@@ -219,70 +219,10 @@ export function snapLocalXToNeighbors(args) {
|
|
|
219
219
|
return bestDelta === null ? null : localX + bestDelta;
|
|
220
220
|
}
|
|
221
221
|
/**
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
* wall-mounted item)? AABB test in the wall's local face plane. `ignoreId`
|
|
225
|
-
* excludes the moving node itself. Returns `true` (blocked) if the wall is
|
|
226
|
-
* gone.
|
|
227
|
-
*
|
|
228
|
-
* Single source of truth for door + window placement collision — door-math and
|
|
229
|
-
* window-math had byte-identical copies of this. Y conventions differ per kind
|
|
230
|
-
* (items store bottom Y; doors/windows store centre Y), handled inline.
|
|
222
|
+
* Whether a wall-hosted opening would overlap another child of its wall. The rule lives in
|
|
223
|
+
* core, shared with every agent surface (`planWallOpening`); re-exported for the tools here.
|
|
231
224
|
*/
|
|
232
|
-
export
|
|
233
|
-
const wallNode = nodes[wallId];
|
|
234
|
-
if (!wallNode)
|
|
235
|
-
return true;
|
|
236
|
-
const halfW = width / 2;
|
|
237
|
-
const halfH = height / 2;
|
|
238
|
-
const newBottom = clampedY - halfH;
|
|
239
|
-
const newTop = clampedY + halfH;
|
|
240
|
-
const newLeft = clampedX - halfW;
|
|
241
|
-
const newRight = clampedX + halfW;
|
|
242
|
-
for (const childId of Array.isArray(wallNode.children) ? wallNode.children : []) {
|
|
243
|
-
if (childId === ignoreId)
|
|
244
|
-
continue;
|
|
245
|
-
const child = nodes[childId];
|
|
246
|
-
if (!child || child.metadata.isTransient)
|
|
247
|
-
continue;
|
|
248
|
-
let childLeft;
|
|
249
|
-
let childRight;
|
|
250
|
-
let childBottom;
|
|
251
|
-
let childTop;
|
|
252
|
-
if (child.type === 'item') {
|
|
253
|
-
const item = child;
|
|
254
|
-
if (item.asset.attachTo !== 'wall' && item.asset.attachTo !== 'wall-side')
|
|
255
|
-
continue;
|
|
256
|
-
const [w, h] = getScaledDimensions(item);
|
|
257
|
-
childLeft = item.position[0] - w / 2;
|
|
258
|
-
childRight = item.position[0] + w / 2;
|
|
259
|
-
childBottom = item.position[1]; // items store bottom Y
|
|
260
|
-
childTop = item.position[1] + h;
|
|
261
|
-
}
|
|
262
|
-
else if (child.type === 'window') {
|
|
263
|
-
const win = child;
|
|
264
|
-
childLeft = win.position[0] - win.width / 2;
|
|
265
|
-
childRight = win.position[0] + win.width / 2;
|
|
266
|
-
childBottom = win.position[1] - win.height / 2; // windows store centre Y
|
|
267
|
-
childTop = win.position[1] + win.height / 2;
|
|
268
|
-
}
|
|
269
|
-
else if (child.type === 'door') {
|
|
270
|
-
const door = child;
|
|
271
|
-
childLeft = door.position[0] - door.width / 2;
|
|
272
|
-
childRight = door.position[0] + door.width / 2;
|
|
273
|
-
childBottom = door.position[1] - door.height / 2; // doors store centre Y
|
|
274
|
-
childTop = door.position[1] + door.height / 2;
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
const xOverlap = newLeft < childRight && newRight > childLeft;
|
|
280
|
-
const yOverlap = newBottom < childTop && newTop > childBottom;
|
|
281
|
-
if (xOverlap && yOverlap)
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
225
|
+
export { hasWallChildOverlap } from '@pascal-app/core/building';
|
|
286
226
|
/**
|
|
287
227
|
* Resolve the placement state from the raw collision result and whether the
|
|
288
228
|
* user is force-placing (held Alt). Force-place lifts the collision block, so the
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type AnyNode, type AnyNodeId, type
|
|
1
|
+
import { type AnyNode, type AnyNodeId, type DoorNode } from '@pascal-app/core';
|
|
2
|
+
import { resolveWallOpeningCeiling } from '@pascal-app/core/building';
|
|
2
3
|
/**
|
|
3
4
|
* Structural subset of `SceneApi` the opening-cap readers need — matches
|
|
4
5
|
* both handle-descriptor callbacks (which receive the full SceneApi) and
|
|
@@ -8,23 +9,12 @@ export type WallCeilingSceneReader = {
|
|
|
8
9
|
get: (id: AnyNodeId) => unknown;
|
|
9
10
|
nodes: () => Readonly<Record<AnyNodeId, AnyNode>>;
|
|
10
11
|
};
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
* resolved top (storey plane for plane-bound walls, stored height for
|
|
14
|
-
* explicit ones) minus the wall's elected slab base. Wall-local Y = 0 sits
|
|
15
|
-
* at the elected base (where the viewer positions the wall mesh), so this
|
|
16
|
-
* is the ceiling an opening's top edge must stay under.
|
|
17
|
-
*
|
|
18
|
-
* Uses the same slab election as the viewer's WallSystem
|
|
19
|
-
* (`spatialGridManager.getSlabSupportForWall`) so the cap agrees with the
|
|
20
|
-
* rendered wall; headless callers with an empty spatial grid elect base 0
|
|
21
|
-
* and fall back to the full storey height.
|
|
22
|
-
*/
|
|
23
|
-
export declare function resolveWallOpeningCeiling(wall: WallNode, nodes: Readonly<Record<AnyNodeId, AnyNode>>): number;
|
|
12
|
+
/** The ceiling an opening's top edge must stay under: the shared rule in core. */
|
|
13
|
+
export { resolveWallOpeningCeiling };
|
|
24
14
|
/**
|
|
25
15
|
* Height cap for a wall-hosted opening's resize handles. Infinity only when
|
|
26
16
|
* the opening is unhosted (no wallId, or the wall is gone) — roof-hosted
|
|
27
17
|
* openings clamp elsewhere.
|
|
28
18
|
*/
|
|
29
|
-
export declare function readHostWallCeiling(wallId: string | null | undefined, scene: WallCeilingSceneReader): number;
|
|
19
|
+
export declare function readHostWallCeiling(wallId: string | null | undefined, scene: WallCeilingSceneReader, opening?: Pick<DoorNode, 'position' | 'width' | 'height'>): number;
|
|
30
20
|
//# sourceMappingURL=wall-opening-ceiling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wall-opening-ceiling.d.ts","sourceRoot":"","sources":["../../src/shared/wall-opening-ceiling.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"wall-opening-ceiling.d.ts","sourceRoot":"","sources":["../../src/shared/wall-opening-ceiling.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,QAAQ,EAId,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAErE;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAA;IAC/B,KAAK,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;CAClD,CAAA;AAED,kFAAkF;AAClF,OAAO,EAAE,yBAAyB,EAAE,CAAA;AAEpC;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC,GACxD,MAAM,CASR"}
|
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* explicit ones) minus the wall's elected slab base. Wall-local Y = 0 sits
|
|
6
|
-
* at the elected base (where the viewer positions the wall mesh), so this
|
|
7
|
-
* is the ceiling an opening's top edge must stay under.
|
|
8
|
-
*
|
|
9
|
-
* Uses the same slab election as the viewer's WallSystem
|
|
10
|
-
* (`spatialGridManager.getSlabSupportForWall`) so the cap agrees with the
|
|
11
|
-
* rendered wall; headless callers with an empty spatial grid elect base 0
|
|
12
|
-
* and fall back to the full storey height.
|
|
13
|
-
*/
|
|
14
|
-
export function resolveWallOpeningCeiling(wall, nodes) {
|
|
15
|
-
return getWallEffectiveHeightForNodes(wall, nodes);
|
|
16
|
-
}
|
|
1
|
+
import { getOpeningFloorDatum, wallSupportForNodes, } from '@pascal-app/core';
|
|
2
|
+
import { resolveWallOpeningCeiling } from '@pascal-app/core/building';
|
|
3
|
+
/** The ceiling an opening's top edge must stay under: the shared rule in core. */
|
|
4
|
+
export { resolveWallOpeningCeiling };
|
|
17
5
|
/**
|
|
18
6
|
* Height cap for a wall-hosted opening's resize handles. Infinity only when
|
|
19
7
|
* the opening is unhosted (no wallId, or the wall is gone) — roof-hosted
|
|
20
8
|
* openings clamp elsewhere.
|
|
21
9
|
*/
|
|
22
|
-
export function readHostWallCeiling(wallId, scene) {
|
|
10
|
+
export function readHostWallCeiling(wallId, scene, opening) {
|
|
23
11
|
if (!wallId)
|
|
24
12
|
return Number.POSITIVE_INFINITY;
|
|
25
13
|
const wall = scene.get(wallId);
|
|
26
14
|
if (!wall)
|
|
27
15
|
return Number.POSITIVE_INFINITY;
|
|
28
|
-
|
|
16
|
+
const nodes = scene.nodes();
|
|
17
|
+
const lift = opening
|
|
18
|
+
? getOpeningFloorDatum(wall, opening, nodes) - wallSupportForNodes(wall, nodes).elevation
|
|
19
|
+
: 0;
|
|
20
|
+
return resolveWallOpeningCeiling(wall, nodes) - lift;
|
|
29
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/shelf/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAA8B,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/shelf/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAA8B,MAAM,kBAAkB,CAAA;AAUpG,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA2HpC,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAyJ5D,CAAA"}
|
package/dist/shelf/definition.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { shelfSlots } from '@pascal-app/core';
|
|
1
2
|
import { restingFloorplanAffectedIds } from '../shared/resting-surface-plan';
|
|
2
3
|
import { sanitizeShelfDimensions } from './dimensions';
|
|
3
4
|
import { buildShelfFloorplan } from './floorplan';
|
|
@@ -7,7 +8,6 @@ import { buildShelfGeometry, shelfRowSurfaceYs } from './geometry';
|
|
|
7
8
|
import { shelfPaint } from './paint';
|
|
8
9
|
import { shelfParametrics } from './parametrics';
|
|
9
10
|
import { ShelfNode } from './schema';
|
|
10
|
-
import { shelfSlots } from './slots';
|
|
11
11
|
const SIDE_HANDLE_OFFSET = 0.18;
|
|
12
12
|
const HEIGHT_HANDLE_OFFSET = 0.22;
|
|
13
13
|
const ROTATE_CORNER_OFFSET = 0.32;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/shelf/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/shelf/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EAKrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAe,KAAK,EAAuB,MAAM,OAAO,CAAA;AAE/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAyEzC,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,EAClB,GAAG,CAAC,EAAE,eAAe,EACrB,OAAO,GAAE,aAA0B,GAClC,KAAK,CAkCP;AAySD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAM3D"}
|
package/dist/shelf/geometry.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { SHELF_BOARD_INSET as BOARD_INSET, getMaterialPresetByRef, shelfBoardDimensions, } from '@pascal-app/core';
|
|
1
|
+
import { SHELF_BOARD_INSET as BOARD_INSET, getMaterialPresetByRef, SHELF_SLOT_DEFAULT_COLOR, shelfBoardDimensions, } from '@pascal-app/core';
|
|
2
2
|
import { applyMaterialPresetToMaterials, createDefaultMaterial, createMaterial, resolveMaterialRef, } from '@pascal-app/viewer';
|
|
3
3
|
import { BoxGeometry, Group, Mesh } from 'three';
|
|
4
4
|
import { sanitizeShelfDimensions } from './dimensions';
|
|
5
|
-
import { SHELF_SLOT_DEFAULT_COLOR } from './slots';
|
|
6
5
|
function getShelfSlotMaterial(node, slotId, materials, shading) {
|
|
7
6
|
const ref = node.slots?.[slotId];
|
|
8
7
|
if (ref) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/shelf/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EAOrB,MAAM,kBAAkB,CAAA;AAmLzB,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/shelf/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EAOrB,MAAM,kBAAkB,CAAA;AAmLzB,eAAO,MAAM,UAAU,EAAE,eAoBxB,CAAA"}
|
package/dist/shelf/paint.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { generateSceneMaterialId,
|
|
1
|
+
import { generateSceneMaterialId, slotPaintMaterial, toSceneMaterialRef, useScene, } from '@pascal-app/core';
|
|
2
2
|
import { createMaterial, createMaterialFromPresetRef, useViewer } from '@pascal-app/viewer';
|
|
3
3
|
function deepEqual(a, b) {
|
|
4
4
|
if (Object.is(a, b))
|
|
@@ -162,15 +162,9 @@ export const shelfPaint = {
|
|
|
162
162
|
applyPreview: ({ role, root, material, materialPreset }) => applyShelfPreview(role, root, material, materialPreset),
|
|
163
163
|
getEffectiveMaterial: ({ node, role }) => {
|
|
164
164
|
const shelf = node;
|
|
165
|
-
const
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
return { material: undefined, materialPreset: shelf.slots?.[role] };
|
|
169
|
-
}
|
|
170
|
-
const sceneMaterial = useScene.getState().materials[parsed.id];
|
|
171
|
-
if (sceneMaterial)
|
|
172
|
-
return { material: sceneMaterial.material, materialPreset: undefined };
|
|
173
|
-
}
|
|
165
|
+
const painted = slotPaintMaterial(shelf.slots?.[role], useScene.getState().materials);
|
|
166
|
+
if (painted)
|
|
167
|
+
return painted;
|
|
174
168
|
// No (or dangling) slot ref — surface the legacy whole-shelf paint the
|
|
175
169
|
// geometry builder still falls back to, so the picker matches what renders.
|
|
176
170
|
if (shelf.materialPreset || shelf.material) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A patterned RIBBON along a draped polyline — the way a property line or a
|
|
3
|
+
* setback line is drawn on the ground in 3D. WebGL ignores line widths, so
|
|
4
|
+
* a thick line is a flat mesh: the polyline (already draped on the terrain
|
|
5
|
+
* by `buildDrapedPolyline`) is walked by arc length, the on / off pattern
|
|
6
|
+
* is unrolled along it (metres: dash, gap, dot, gap, dot, gap — the
|
|
7
|
+
* standard property line; dash, gap — a setback), and every "on" run
|
|
8
|
+
* becomes quads `width` wide lying flat in the XZ plane at the draped
|
|
9
|
+
* height. Pure; the renderer wraps the geometry in a mesh.
|
|
10
|
+
*
|
|
11
|
+
* The property line draws dark and thick in the standard dash-dot-dot
|
|
12
|
+
* pattern; the setbacks draw black and dashed.
|
|
13
|
+
*/
|
|
14
|
+
import { type TerrainField } from '@pascal-app/core';
|
|
15
|
+
import { BufferGeometry } from 'three';
|
|
16
|
+
/** The standard property line: a long dash, two dots (metres). */
|
|
17
|
+
export declare const PROPERTY_LINE_PATTERN: readonly number[];
|
|
18
|
+
/** A setback line: dashed. */
|
|
19
|
+
export declare const SETBACK_LINE_PATTERN: readonly number[];
|
|
20
|
+
/**
|
|
21
|
+
* Re-drape a ribbon on a changed field: every vertex keeps its XZ and takes
|
|
22
|
+
* the ground's height there plus `lift` (a sculpt stroke mid-flight).
|
|
23
|
+
*/
|
|
24
|
+
export declare function updateRibbonHeights(geometry: BufferGeometry, field: TerrainField | null, lift: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Build the ribbon. `positions` is the draped polyline (xyz per vertex,
|
|
27
|
+
* consecutive, NOT closed — pass the closing vertex yourself); `pattern`
|
|
28
|
+
* alternates on / off lengths in metres; `width` is the ribbon's full width.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildPatternedRibbon(positions: Float32Array, pattern: readonly number[], width: number, step?: number): BufferGeometry;
|
|
31
|
+
//# sourceMappingURL=line-ribbon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-ribbon.d.ts","sourceRoot":"","sources":["../../src/site/line-ribbon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAmB,cAAc,EAAE,MAAM,OAAO,CAAA;AAEvD,kEAAkE;AAClE,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAAqC,CAAA;AACxF,8BAA8B;AAC9B,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAe,CAAA;AAyBjE;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,IAAI,EAAE,MAAM,GACX,IAAI,CAWN;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,IAAI,SAAO,GACV,cAAc,CAmDhB"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A patterned RIBBON along a draped polyline — the way a property line or a
|
|
3
|
+
* setback line is drawn on the ground in 3D. WebGL ignores line widths, so
|
|
4
|
+
* a thick line is a flat mesh: the polyline (already draped on the terrain
|
|
5
|
+
* by `buildDrapedPolyline`) is walked by arc length, the on / off pattern
|
|
6
|
+
* is unrolled along it (metres: dash, gap, dot, gap, dot, gap — the
|
|
7
|
+
* standard property line; dash, gap — a setback), and every "on" run
|
|
8
|
+
* becomes quads `width` wide lying flat in the XZ plane at the draped
|
|
9
|
+
* height. Pure; the renderer wraps the geometry in a mesh.
|
|
10
|
+
*
|
|
11
|
+
* The property line draws dark and thick in the standard dash-dot-dot
|
|
12
|
+
* pattern; the setbacks draw black and dashed.
|
|
13
|
+
*/
|
|
14
|
+
import { surfaceHeightAt } from '@pascal-app/core';
|
|
15
|
+
import { BufferAttribute, BufferGeometry } from 'three';
|
|
16
|
+
/** The standard property line: a long dash, two dots (metres). */
|
|
17
|
+
export const PROPERTY_LINE_PATTERN = [3.0, 0.6, 0.35, 0.6, 0.35, 0.6];
|
|
18
|
+
/** A setback line: dashed. */
|
|
19
|
+
export const SETBACK_LINE_PATTERN = [1.2, 0.6];
|
|
20
|
+
/** The draped polyline's vertices, xyz per vertex. */
|
|
21
|
+
function vertexAt(positions, i) {
|
|
22
|
+
return [positions[i * 3] ?? 0, positions[i * 3 + 1] ?? 0, positions[i * 3 + 2] ?? 0];
|
|
23
|
+
}
|
|
24
|
+
/** Point at arc length `s` along the polyline (plan length), with the local XZ direction. */
|
|
25
|
+
function sample(positions, cum, s) {
|
|
26
|
+
const count = cum.length;
|
|
27
|
+
let i = 0;
|
|
28
|
+
while (i + 1 < count - 1 && cum[i + 1] < s)
|
|
29
|
+
i++;
|
|
30
|
+
const a = vertexAt(positions, i);
|
|
31
|
+
const b = vertexAt(positions, Math.min(count - 1, i + 1));
|
|
32
|
+
const seg = cum[i + 1] - cum[i];
|
|
33
|
+
const t = seg > 1e-9 ? Math.max(0, Math.min(1, (s - cum[i]) / seg)) : 0;
|
|
34
|
+
const p = [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
|
|
35
|
+
const dx = b[0] - a[0];
|
|
36
|
+
const dz = b[2] - a[2];
|
|
37
|
+
const len = Math.hypot(dx, dz) || 1;
|
|
38
|
+
return { p, d: [dx / len, dz / len] };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Re-drape a ribbon on a changed field: every vertex keeps its XZ and takes
|
|
42
|
+
* the ground's height there plus `lift` (a sculpt stroke mid-flight).
|
|
43
|
+
*/
|
|
44
|
+
export function updateRibbonHeights(geometry, field, lift) {
|
|
45
|
+
const attribute = geometry.getAttribute('position');
|
|
46
|
+
if (!attribute)
|
|
47
|
+
return;
|
|
48
|
+
const array = attribute.array;
|
|
49
|
+
for (let i = 0; i < attribute.count; i++) {
|
|
50
|
+
const x = array[i * 3] ?? 0;
|
|
51
|
+
const z = array[i * 3 + 2] ?? 0;
|
|
52
|
+
array[i * 3 + 1] = field ? surfaceHeightAt(field, x, z) + lift : lift;
|
|
53
|
+
}
|
|
54
|
+
attribute.needsUpdate = true;
|
|
55
|
+
geometry.computeBoundingSphere();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the ribbon. `positions` is the draped polyline (xyz per vertex,
|
|
59
|
+
* consecutive, NOT closed — pass the closing vertex yourself); `pattern`
|
|
60
|
+
* alternates on / off lengths in metres; `width` is the ribbon's full width.
|
|
61
|
+
*/
|
|
62
|
+
export function buildPatternedRibbon(positions, pattern, width, step = 0.25) {
|
|
63
|
+
const count = Math.floor(positions.length / 3);
|
|
64
|
+
const geometry = new BufferGeometry();
|
|
65
|
+
if (count < 2 || pattern.length < 2)
|
|
66
|
+
return geometry;
|
|
67
|
+
// cumulative PLAN arc length per vertex
|
|
68
|
+
const cum = [0];
|
|
69
|
+
for (let i = 1; i < count; i++) {
|
|
70
|
+
const a = vertexAt(positions, i - 1);
|
|
71
|
+
const b = vertexAt(positions, i);
|
|
72
|
+
cum.push(cum[i - 1] + Math.hypot(b[0] - a[0], b[2] - a[2]));
|
|
73
|
+
}
|
|
74
|
+
const total = cum[count - 1];
|
|
75
|
+
if (total < 1e-6)
|
|
76
|
+
return geometry;
|
|
77
|
+
const period = pattern.reduce((s, v) => s + v, 0);
|
|
78
|
+
if (period <= 0)
|
|
79
|
+
return geometry;
|
|
80
|
+
const verts = [];
|
|
81
|
+
const index = [];
|
|
82
|
+
const half = width / 2;
|
|
83
|
+
// walk the pattern along the line; each "on" run is a strip of quads
|
|
84
|
+
let s = 0;
|
|
85
|
+
let k = 0;
|
|
86
|
+
while (s < total) {
|
|
87
|
+
const len = pattern[k % pattern.length];
|
|
88
|
+
const on = k % 2 === 0;
|
|
89
|
+
const s0 = s;
|
|
90
|
+
const s1 = Math.min(total, s + len);
|
|
91
|
+
if (on && s1 - s0 > 1e-6) {
|
|
92
|
+
// subdivide the run so it follows corners and the drape
|
|
93
|
+
const n = Math.max(1, Math.ceil((s1 - s0) / step));
|
|
94
|
+
const base = verts.length / 3;
|
|
95
|
+
for (let j = 0; j <= n; j++) {
|
|
96
|
+
const { p, d } = sample(positions, cum, s0 + ((s1 - s0) * j) / n);
|
|
97
|
+
// the ribbon's normal in plan is the line direction turned 90°
|
|
98
|
+
const nx = -d[1] * half;
|
|
99
|
+
const nz = d[0] * half;
|
|
100
|
+
verts.push(p[0] + nx, p[1], p[2] + nz, p[0] - nx, p[1], p[2] - nz);
|
|
101
|
+
}
|
|
102
|
+
for (let j = 0; j < n; j++) {
|
|
103
|
+
const a = base + j * 2;
|
|
104
|
+
index.push(a, a + 1, a + 2, a + 1, a + 3, a + 2);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
s = s1;
|
|
108
|
+
k++;
|
|
109
|
+
if (k > 100000)
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
geometry.setAttribute('position', new BufferAttribute(new Float32Array(verts), 3));
|
|
113
|
+
geometry.setIndex(index);
|
|
114
|
+
geometry.computeVertexNormals();
|
|
115
|
+
geometry.computeBoundingSphere();
|
|
116
|
+
return geometry;
|
|
117
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Material } from 'three';
|
|
2
|
+
import type { Node } from 'three/webgpu';
|
|
3
|
+
type Point = readonly [number, number];
|
|
4
|
+
/**
|
|
5
|
+
* True for a fragment inside the lot polygon (even-odd crossing count on its
|
|
6
|
+
* local x, z). Unrolled edge by edge into the graph: a parcel has tens of
|
|
7
|
+
* corners, so a loop and a uniform array would buy nothing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function insideLotNode(polygon: ReadonlyArray<Point>): Node<"bool">;
|
|
10
|
+
/**
|
|
11
|
+
* The ground material cut to the lot: the terrain field is the padded,
|
|
12
|
+
* north-up box around the parcel, and only the parcel itself is ground the
|
|
13
|
+
* project owns. Per fragment, so the edge is the property line exactly and
|
|
14
|
+
* follows a sculpt stroke with no rebuild; the shadow pass honours the mask too.
|
|
15
|
+
*/
|
|
16
|
+
export declare function lotMaskedMaterial(material: Material, polygon: ReadonlyArray<Point>): Material;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=lot-mask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lot-mask.d.ts","sourceRoot":"","sources":["../../src/site/lot-mask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAErC,OAAO,KAAK,EAAE,IAAI,EAAgB,MAAM,cAAc,CAAA;AAEtD,KAAK,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAEtC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,gBAgB1D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,QAAQ,CAI7F"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { float, mod, positionLocal, select } from 'three/tsl';
|
|
2
|
+
/**
|
|
3
|
+
* True for a fragment inside the lot polygon (even-odd crossing count on its
|
|
4
|
+
* local x, z). Unrolled edge by edge into the graph: a parcel has tens of
|
|
5
|
+
* corners, so a loop and a uniform array would buy nothing.
|
|
6
|
+
*/
|
|
7
|
+
export function insideLotNode(polygon) {
|
|
8
|
+
const at = positionLocal.xz;
|
|
9
|
+
let crossings = float(0);
|
|
10
|
+
for (let i = 0; i < polygon.length; i++) {
|
|
11
|
+
const [ax, az] = polygon[i];
|
|
12
|
+
const [bx, bz] = polygon[(i + 1) % polygon.length];
|
|
13
|
+
if (az === bz)
|
|
14
|
+
continue;
|
|
15
|
+
const slope = (bx - ax) / (bz - az);
|
|
16
|
+
const crossesAt = at.y.sub(az).mul(slope).add(ax);
|
|
17
|
+
const crosses = at.y
|
|
18
|
+
.greaterThanEqual(Math.min(az, bz))
|
|
19
|
+
.and(at.y.lessThan(Math.max(az, bz)))
|
|
20
|
+
.and(at.x.lessThan(crossesAt));
|
|
21
|
+
crossings = crossings.add(select(crosses, float(1), float(0)));
|
|
22
|
+
}
|
|
23
|
+
return mod(crossings, float(2)).greaterThan(0.5);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The ground material cut to the lot: the terrain field is the padded,
|
|
27
|
+
* north-up box around the parcel, and only the parcel itself is ground the
|
|
28
|
+
* project owns. Per fragment, so the edge is the property line exactly and
|
|
29
|
+
* follows a sculpt stroke with no rebuild; the shadow pass honours the mask too.
|
|
30
|
+
*/
|
|
31
|
+
export function lotMaskedMaterial(material, polygon) {
|
|
32
|
+
const masked = material.clone();
|
|
33
|
+
masked.maskNode = insideLotNode(polygon);
|
|
34
|
+
return masked;
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site inspector — address → real parcel, plus the zoning inputs the site
|
|
3
|
+
* plan draws from. Mounted through `siteParametrics.customPanel`.
|
|
4
|
+
*
|
|
5
|
+
* The address lookup goes through the host's parcel provider
|
|
6
|
+
* (`setParcelProvider`) and is hidden when the host has none.
|
|
7
|
+
*/
|
|
8
|
+
export declare function SiteNodePanel(): import("react").JSX.Element | null;
|
|
9
|
+
export default SiteNodePanel;
|
|
10
|
+
//# sourceMappingURL=panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/site/panel.tsx"],"names":[],"mappings":"AA6BA;;;;;;GAMG;AACH,wBAAgB,aAAa,uCA8T5B;AAWD,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useScene } from '@pascal-app/core';
|
|
4
|
+
import { ActionButton, ActionGroup, describeSiteEdges, dropInLot, PanelSection, PanelWrapper, useParcelProvider, } from '@pascal-app/editor';
|
|
5
|
+
import { useViewer } from '@pascal-app/viewer';
|
|
6
|
+
import { MapPin, Search } from 'lucide-react';
|
|
7
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
8
|
+
const METRES_PER_FOOT = 0.3048;
|
|
9
|
+
/**
|
|
10
|
+
* Site inspector — address → real parcel, plus the zoning inputs the site
|
|
11
|
+
* plan draws from. Mounted through `siteParametrics.customPanel`.
|
|
12
|
+
*
|
|
13
|
+
* The address lookup goes through the host's parcel provider
|
|
14
|
+
* (`setParcelProvider`) and is hidden when the host has none.
|
|
15
|
+
*/
|
|
16
|
+
export function SiteNodePanel() {
|
|
17
|
+
const selectedId = useViewer((s) => s.selection.selectedIds[0]);
|
|
18
|
+
// The selected site node, else THE site node: the sidebar's Site header
|
|
19
|
+
// mounts this panel directly, where nothing may be selected.
|
|
20
|
+
const node = useScene((s) => {
|
|
21
|
+
const selected = selectedId
|
|
22
|
+
? s.nodes[selectedId]
|
|
23
|
+
: undefined;
|
|
24
|
+
if (selected?.type === 'site')
|
|
25
|
+
return selected;
|
|
26
|
+
for (const id of s.rootNodeIds) {
|
|
27
|
+
const n = s.nodes[id];
|
|
28
|
+
if (n?.type === 'site')
|
|
29
|
+
return n;
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
});
|
|
33
|
+
const [query, setQuery] = useState('');
|
|
34
|
+
const [suggestions, setSuggestions] = useState([]);
|
|
35
|
+
const [picked, setPicked] = useState(null);
|
|
36
|
+
const [status, setStatus] = useState(null);
|
|
37
|
+
const [busy, setBusy] = useState(false);
|
|
38
|
+
const requestSeq = useRef(0);
|
|
39
|
+
const parcelProvider = useParcelProvider();
|
|
40
|
+
const update = useCallback((patch) => {
|
|
41
|
+
if (!node)
|
|
42
|
+
return;
|
|
43
|
+
useScene.getState().updateNode(node.id, patch);
|
|
44
|
+
}, [node]);
|
|
45
|
+
// Seed the address box from the node so reopening the panel shows what the
|
|
46
|
+
// lot was resolved from.
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (!node?.address)
|
|
49
|
+
return;
|
|
50
|
+
const parts = [node.address.street, node.address.city, node.address.state, node.address.zip];
|
|
51
|
+
setQuery((current) => current || parts.filter(Boolean).join(', '));
|
|
52
|
+
}, [node?.address]);
|
|
53
|
+
// Debounced autocomplete. `seq` guards against an earlier response landing
|
|
54
|
+
// after a later one.
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const q = query.trim();
|
|
57
|
+
if (!parcelProvider || q.length < 4 || picked) {
|
|
58
|
+
setSuggestions([]);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const seq = ++requestSeq.current;
|
|
62
|
+
const timer = setTimeout(() => {
|
|
63
|
+
parcelProvider('autocomplete', { q })
|
|
64
|
+
.then((data) => {
|
|
65
|
+
if (seq !== requestSeq.current)
|
|
66
|
+
return;
|
|
67
|
+
const list = data?.suggestions;
|
|
68
|
+
setSuggestions(Array.isArray(list) ? list : []);
|
|
69
|
+
})
|
|
70
|
+
.catch(() => {
|
|
71
|
+
if (seq === requestSeq.current)
|
|
72
|
+
setSuggestions([]);
|
|
73
|
+
});
|
|
74
|
+
}, 300);
|
|
75
|
+
return () => clearTimeout(timer);
|
|
76
|
+
}, [parcelProvider, query, picked]);
|
|
77
|
+
const edges = useMemo(() => describeSiteEdges(node ?? null), [node]);
|
|
78
|
+
// One engine for every path (Lot panel, Generate, here): resolve the
|
|
79
|
+
// parcel, map the streets, pick the street-facing edge, default the
|
|
80
|
+
// setbacks when the site has none, re-centre a building that fell outside
|
|
81
|
+
// the new ring. See @pascal-app/editor `dropInLot`.
|
|
82
|
+
const findParcel = useCallback(async () => {
|
|
83
|
+
if (!node)
|
|
84
|
+
return;
|
|
85
|
+
const address = query.trim();
|
|
86
|
+
if (!address) {
|
|
87
|
+
setStatus('Type an address first.');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
setBusy(true);
|
|
91
|
+
setStatus('Looking up the parcel and the streets around it…');
|
|
92
|
+
try {
|
|
93
|
+
const result = await dropInLot({
|
|
94
|
+
address,
|
|
95
|
+
...(picked?.lat != null && picked?.lng != null
|
|
96
|
+
? { latitude: picked.lat, longitude: picked.lng, state: picked.state }
|
|
97
|
+
: {}),
|
|
98
|
+
street: picked?.line1,
|
|
99
|
+
city: picked?.city,
|
|
100
|
+
zip: picked?.postcode,
|
|
101
|
+
}, { siteId: node.id });
|
|
102
|
+
setStatus(result.message);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
setStatus(error instanceof Error ? error.message : 'Parcel lookup failed.');
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
setBusy(false);
|
|
109
|
+
}
|
|
110
|
+
}, [node, picked, query]);
|
|
111
|
+
if (!node)
|
|
112
|
+
return null;
|
|
113
|
+
const setbacks = node.setbacks;
|
|
114
|
+
const setbackField = (key, label, optional = false) => (_jsxs("label", { className: "flex items-center justify-between gap-3 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsxs("span", { className: "flex items-center gap-1", children: [_jsx("input", { className: "w-20 rounded-md border border-border/70 bg-background px-2 py-1 text-right text-foreground", defaultValue: setbacks?.[key] != null
|
|
115
|
+
? String(Math.round((setbacks[key] / METRES_PER_FOOT) * 10) / 10)
|
|
116
|
+
: '', inputMode: "decimal", onFocus: (event) => event.target.select(), onBlur: (event) => {
|
|
117
|
+
const raw = event.target.value.trim();
|
|
118
|
+
if (raw === '' && optional) {
|
|
119
|
+
const next = { ...(setbacks ?? { front: 0, rear: 0, side: 0 }) };
|
|
120
|
+
delete next[key];
|
|
121
|
+
update({ setbacks: next });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const feet = Number(raw);
|
|
125
|
+
if (!Number.isFinite(feet) || feet < 0)
|
|
126
|
+
return;
|
|
127
|
+
update({
|
|
128
|
+
setbacks: {
|
|
129
|
+
...(setbacks ?? { front: 0, rear: 0, side: 0 }),
|
|
130
|
+
[key]: feet * METRES_PER_FOOT,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}, placeholder: optional ? 'side' : '0' }, `${key}-${setbacks?.[key] ?? 'none'}`), _jsx("span", { className: "text-muted-foreground text-xs", children: "ft" })] })] }, key));
|
|
134
|
+
return (_jsxs(PanelWrapper, { title: "Site", children: [parcelProvider ? (_jsxs(PanelSection, { title: "Address", children: [_jsxs("label", { className: "space-y-1 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Street address" }), _jsx("input", { className: "w-full rounded-md border border-border/70 bg-background px-2 py-1.5 text-foreground", onChange: (event) => {
|
|
135
|
+
setQuery(event.target.value);
|
|
136
|
+
setPicked(null);
|
|
137
|
+
}, placeholder: "1200 W Cass St, Tampa, FL", value: query })] }), suggestions.length > 0 ? (_jsx("ul", { className: "max-h-44 space-y-0.5 overflow-y-auto rounded-md border border-border/70 bg-card p-1", children: suggestions.map((s) => (_jsx("li", { children: _jsxs("button", { className: "flex w-full items-start gap-2 rounded px-2 py-1.5 text-left text-foreground text-xs hover:bg-muted", onClick: () => {
|
|
138
|
+
setPicked(s);
|
|
139
|
+
setQuery(s.label ?? [s.line1, s.line2].filter(Boolean).join(', '));
|
|
140
|
+
setSuggestions([]);
|
|
141
|
+
}, type: "button", children: [_jsx(MapPin, { className: "mt-0.5 size-3 shrink-0 text-muted-foreground" }), _jsx("span", { children: s.label ?? [s.line1, s.line2].filter(Boolean).join(', ') })] }) }, `${s.label}-${s.lat}-${s.lng}`))) })) : null, _jsx(ActionGroup, { children: _jsx(ActionButton, { disabled: busy, icon: _jsx(Search, { className: "size-4" }), label: busy ? 'Finding…' : 'Find parcel', onClick: findParcel }) }), status ? _jsx("p", { className: "text-muted-foreground text-xs", children: status }) : null] })) : null, node.parcel ? (_jsxs(PanelSection, { title: "Parcel", children: [_jsx(Row, { label: "APN", value: node.parcel.apn || '—' }), _jsx(Row, { label: "County", value: node.parcel.county || '—' }), _jsx(Row, { label: "Lot area", value: node.parcel.lotAreaSqFt
|
|
142
|
+
? `${Math.round(node.parcel.lotAreaSqFt).toLocaleString()} sq ft`
|
|
143
|
+
: '—' }), _jsx(Row, { label: "Source", value: node.parcel.layer || node.parcel.source || '—' }), node.parcel.notes?.length ? (_jsx("p", { className: "text-muted-foreground text-xs leading-snug", children: node.parcel.notes.join(' ') })) : null] })) : null, _jsxs(PanelSection, { title: "Setbacks", children: [setbackField('front', 'Front'), setbackField('side', 'Side'), setbackField('rear', 'Rear'), setbackField('left', 'Left (override)', true), setbackField('right', 'Right (override)', true), _jsxs("label", { className: "space-y-1 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Source / citation" }), _jsx("input", { className: "w-full rounded-md border border-border/70 bg-background px-2 py-1.5 text-foreground", defaultValue: node.setbacksSource ?? '', onBlur: (event) => update({ setbacksSource: event.target.value || undefined }), placeholder: "e.g. Tampa LDC \u00A727-156" }, node.setbacksSource ?? '')] }), _jsxs("label", { className: "space-y-1 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Zone" }), _jsx("input", { className: "w-full rounded-md border border-border/70 bg-background px-2 py-1.5 text-foreground", defaultValue: node.zone ?? '', onBlur: (event) => update({ zone: event.target.value || undefined }), placeholder: "e.g. RS-60" }, node.zone ?? '')] })] }), _jsxs(PanelSection, { title: "Terrain", children: [_jsxs("label", { className: "space-y-1 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Contour interval (site plan and 3D)" }), _jsxs("select", { className: "w-full rounded-md border border-border/70 bg-background px-2 py-1.5 text-foreground", onChange: (event) => update({ contourIntervalIn: Number(event.target.value) }), value: String(node.contourIntervalIn ?? 12), children: [_jsx("option", { value: "0", children: "none" }), _jsx("option", { value: "6", children: "every 6 in" }), _jsx("option", { value: "12", children: "every 12 in" }), _jsx("option", { value: "24", children: "every 24 in" })] })] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx("input", { checked: node.contours3d ?? false, onChange: (event) => update({ contours3d: event.target.checked }), type: "checkbox" }), _jsx("span", { className: "text-muted-foreground", children: "Show the contour lines in 3D" })] }), node.terrainContours ? (_jsxs("p", { className: "text-muted-foreground text-xs", children: [node.terrainContours.lines.length, " surveyed lines at ", node.terrainContours.intervalFt, ' ', "ft (", node.terrainContours.datum, ") \u2014 ", node.terrainContours.source ?? 'survey'] })) : (_jsx("p", { className: "text-muted-foreground text-xs", children: "No surveyed lines \u2014 contours are drawn from the sculpted ground." }))] }), _jsxs(PanelSection, { title: "Orientation", children: [_jsxs("label", { className: "space-y-1 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "Front (street) edge" }), _jsxs("select", { className: "w-full rounded-md border border-border/70 bg-background px-2 py-1.5 text-foreground", onChange: (event) => update({
|
|
144
|
+
frontEdge: event.target.value === '' ? undefined : Number(event.target.value),
|
|
145
|
+
}), value: node.frontEdge == null ? '' : String(node.frontEdge), children: [_jsx("option", { value: "", children: "Auto \u2014 most north-facing edge" }), edges.map((edge) => (_jsx("option", { value: String(edge.index), children: edge.label }, edge.index)))] })] }), _jsxs("label", { className: "flex items-center justify-between gap-3 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: "North rotation" }), _jsxs("span", { className: "flex items-center gap-1", children: [_jsx("input", { className: "w-20 rounded-md border border-border/70 bg-background px-2 py-1 text-right text-foreground", defaultValue: String(Math.round((((node.northRotation ?? 0) * 180) / Math.PI) * 10) / 10), inputMode: "decimal", onFocus: (event) => event.target.select(), onBlur: (event) => {
|
|
146
|
+
const deg = Number(event.target.value.trim());
|
|
147
|
+
if (!Number.isFinite(deg))
|
|
148
|
+
return;
|
|
149
|
+
update({ northRotation: (deg * Math.PI) / 180 });
|
|
150
|
+
} }, String(node.northRotation ?? 0)), _jsx("span", { className: "text-muted-foreground text-xs", children: "\u00B0" })] })] })] })] }));
|
|
151
|
+
}
|
|
152
|
+
function Row({ label, value }) {
|
|
153
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-3 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsx("span", { className: "truncate font-medium text-foreground", children: value })] }));
|
|
154
|
+
}
|
|
155
|
+
export default SiteNodePanel;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import type { ParametricDescriptor, SiteNode } from '@pascal-app/core';
|
|
2
|
+
/**
|
|
3
|
+
* Inspector descriptor for site.
|
|
4
|
+
*
|
|
5
|
+
* `customPanel` mounts `<SitePanel>` — address autocomplete, the parcel
|
|
6
|
+
* lookup, setbacks and the front-edge picker need async network state and
|
|
7
|
+
* feet↔metres conversion that the auto-derived field kinds don't cover.
|
|
8
|
+
*/
|
|
2
9
|
export declare const siteParametrics: ParametricDescriptor<SiteNode>;
|
|
3
10
|
//# sourceMappingURL=parametrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/site/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEtE,eAAO,MAAM,eAAe,EAAE,oBAAoB,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/site/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEtE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,oBAAoB,CAAC,QAAQ,CAG1D,CAAA"}
|