@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { heightAtSample, normalAt } from '@pascal-app/core';
|
|
1
|
+
import { heightAt, heightAtSample, normalAt, } from '@pascal-app/core';
|
|
2
2
|
/**
|
|
3
3
|
* Builds the terrain mesh buffers from a `TerrainField`.
|
|
4
4
|
*
|
|
@@ -39,7 +39,7 @@ export const HORIZON_PLANE_Y = -0.07;
|
|
|
39
39
|
* under the horizon disc. A metre reads as earth thickness from a grazing camera
|
|
40
40
|
* without being tall enough to poke out of a neighbouring excavation.
|
|
41
41
|
*/
|
|
42
|
-
const SKIRT_DROP = 1;
|
|
42
|
+
export const SKIRT_DROP = 1;
|
|
43
43
|
/** Vertex index of sample [c,r]. */
|
|
44
44
|
function vertexIndex(field, col, row) {
|
|
45
45
|
return row * field.cols + col;
|
|
@@ -148,13 +148,58 @@ function boundarySample(field, i) {
|
|
|
148
148
|
return { col: 2 * lastCol + lastRow - i, row: lastRow };
|
|
149
149
|
return { col: 0, row: 2 * (lastCol + lastRow) - i };
|
|
150
150
|
}
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
/**
|
|
152
|
+
* The base of the lot as a block: one flat level under the field's lowest
|
|
153
|
+
* point (and under the horizon plane), so the skirt along the property line
|
|
154
|
+
* reads as earth whose thickness follows the slope, and the horizon disc can
|
|
155
|
+
* sit just beneath it without cutting into the lot anywhere.
|
|
156
|
+
*/
|
|
157
|
+
export function terrainBlockBase(field) {
|
|
158
|
+
let minH = 0;
|
|
159
|
+
for (let i = 0; i < field.heights.length; i++) {
|
|
160
|
+
const h = field.heights[i] ?? 0;
|
|
161
|
+
if (h < minH)
|
|
162
|
+
minH = h;
|
|
163
|
+
}
|
|
164
|
+
return Math.min(minH * field.step, HORIZON_PLANE_Y) - SKIRT_DROP;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The lot's property line as the skirt walks it: counter-clockwise in x, z (the
|
|
168
|
+
* field perimeter's own direction, so one winding and one normal formula serve
|
|
169
|
+
* both), a point at least every half grid cell so the top edge follows the
|
|
170
|
+
* ground between samples. Empty when the polygon is not a ring.
|
|
171
|
+
*/
|
|
172
|
+
export function skirtRing(field, polygon) {
|
|
173
|
+
const points = polygon.filter(([x, z]) => Number.isFinite(x) && Number.isFinite(z));
|
|
174
|
+
if (points.length < 3 || field.cols < 2 || field.rows < 2)
|
|
175
|
+
return new Float32Array(0);
|
|
176
|
+
let area = 0;
|
|
177
|
+
for (let i = 0; i < points.length; i++) {
|
|
178
|
+
const [x0, z0] = points[i];
|
|
179
|
+
const [x1, z1] = points[(i + 1) % points.length];
|
|
180
|
+
area += x0 * z1 - x1 * z0;
|
|
181
|
+
}
|
|
182
|
+
const ordered = area > 0 ? points : [...points].reverse();
|
|
183
|
+
const step = field.spacing / 2;
|
|
184
|
+
const out = [];
|
|
185
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
186
|
+
const [ax, az] = ordered[i];
|
|
187
|
+
const [bx, bz] = ordered[(i + 1) % ordered.length];
|
|
188
|
+
const n = Math.max(1, Math.ceil(Math.hypot(bx - ax, bz - az) / step));
|
|
189
|
+
for (let k = 0; k < n; k++)
|
|
190
|
+
out.push(ax + ((bx - ax) * k) / n, az + ((bz - az) * k) / n);
|
|
191
|
+
}
|
|
192
|
+
return Float32Array.from(out);
|
|
193
|
+
}
|
|
194
|
+
export function buildTerrainSkirt(field, ring) {
|
|
195
|
+
const onRing = !!ring && ring.length >= 6;
|
|
196
|
+
const count = onRing ? ring.length / 2 : perimeterCount(field);
|
|
153
197
|
const vertices = count === 0 ? 0 : (count + 1) * 2;
|
|
154
198
|
const buffers = {
|
|
155
199
|
positions: new Float32Array(vertices * 3),
|
|
156
200
|
normals: new Float32Array(vertices * 3),
|
|
157
201
|
indices: new Uint32Array(count * 6),
|
|
202
|
+
...(onRing ? { ring: ring } : {}),
|
|
158
203
|
};
|
|
159
204
|
for (let i = 0; i < count; i++) {
|
|
160
205
|
const base = i * 6;
|
|
@@ -181,6 +226,10 @@ export function buildTerrainSkirt(field) {
|
|
|
181
226
|
* complexity because it saves 400 KB a dab; here there is nothing to save.
|
|
182
227
|
*/
|
|
183
228
|
export function updateTerrainSkirt(field, buffers) {
|
|
229
|
+
if (buffers.ring) {
|
|
230
|
+
updateRingSkirt(field, buffers, buffers.ring);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
184
233
|
const count = perimeterCount(field);
|
|
185
234
|
if (count === 0)
|
|
186
235
|
return;
|
|
@@ -204,6 +253,31 @@ export function updateTerrainSkirt(field, buffers) {
|
|
|
204
253
|
writeSkirtVertex(buffers, bottomIndex, x, Math.min(h, HORIZON_PLANE_Y) - SKIRT_DROP, z, nx, nz);
|
|
205
254
|
}
|
|
206
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* The property-line skirt: its top on the rendered ground (`heightAt`, the
|
|
258
|
+
* surface's own triangles), its bottom on the block's flat base — never above
|
|
259
|
+
* the ground it closes, so nothing stands proud of the lot from any side.
|
|
260
|
+
*/
|
|
261
|
+
function updateRingSkirt(field, buffers, ring) {
|
|
262
|
+
const count = ring.length / 2;
|
|
263
|
+
if (count < 3)
|
|
264
|
+
return;
|
|
265
|
+
const base = terrainBlockBase(field);
|
|
266
|
+
for (let i = 0; i <= count; i++) {
|
|
267
|
+
const at = i % count;
|
|
268
|
+
const x = ring[at * 2] ?? 0;
|
|
269
|
+
const z = ring[at * 2 + 1] ?? 0;
|
|
270
|
+
const prev = (at - 1 + count) % count;
|
|
271
|
+
const next = (at + 1) % count;
|
|
272
|
+
const tx = (ring[next * 2] ?? 0) - (ring[prev * 2] ?? 0);
|
|
273
|
+
const tz = (ring[next * 2 + 1] ?? 0) - (ring[prev * 2 + 1] ?? 0);
|
|
274
|
+
const tLength = Math.hypot(tx, tz) || 1;
|
|
275
|
+
const nx = tz / tLength;
|
|
276
|
+
const nz = -tx / tLength;
|
|
277
|
+
writeSkirtVertex(buffers, i * 2, x, heightAt(field, x, z), z, nx, nz);
|
|
278
|
+
writeSkirtVertex(buffers, i * 2 + 1, x, base, z, nx, nz);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
207
281
|
function writeSkirtVertex(buffers, index, x, y, z, nx, nz) {
|
|
208
282
|
buffers.positions[index * 3] = x;
|
|
209
283
|
buffers.positions[index * 3 + 1] = y;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Ring } from '@pascal-app/core';
|
|
2
|
+
import { BufferGeometry } from 'three';
|
|
3
|
+
import type { TerrainMeshBuffers } from './terrain-geometry';
|
|
4
|
+
type Sample = {
|
|
5
|
+
indices: number[];
|
|
6
|
+
weights: number[];
|
|
7
|
+
};
|
|
8
|
+
export type TerrainHoleBoundary = {
|
|
9
|
+
geometry: BufferGeometry;
|
|
10
|
+
samples: Sample[];
|
|
11
|
+
};
|
|
12
|
+
export declare function cutTerrainHoles(buffers: TerrainMeshBuffers, holes: Ring[]): TerrainHoleBoundary | null;
|
|
13
|
+
export declare function updateTerrainHoleBoundary(boundary: TerrainHoleBoundary, buffers: TerrainMeshBuffers): void;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=terrain-holes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain-holes.d.ts","sourceRoot":"","sources":["../../src/site/terrain-holes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,IAAI,EAAS,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAmB,cAAc,EAAyC,MAAM,OAAO,CAAA;AAC9F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE5D,KAAK,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AACtD,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAIjF,wBAAgB,eAAe,CAC7B,OAAO,EAAE,kBAAkB,EAC3B,KAAK,EAAE,IAAI,EAAE,GACZ,mBAAmB,GAAG,IAAI,CAkE5B;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,kBAAkB,GAC1B,IAAI,CAkBN"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { difference, union } from '@pascal-app/core';
|
|
2
|
+
import { BufferAttribute, BufferGeometry, DynamicDrawUsage, ShapeUtils, Vector2 } from 'three';
|
|
3
|
+
// Keep the regular grid's vertex layout for partial brush uploads. Only triangles
|
|
4
|
+
// crossing an excavation rim need additional vertices, interpolated on that grid.
|
|
5
|
+
export function cutTerrainHoles(buffers, holes) {
|
|
6
|
+
if (!holes.length)
|
|
7
|
+
return null;
|
|
8
|
+
const cutouts = union(holes);
|
|
9
|
+
const bounds = cutouts.map(({ outer }) => ({
|
|
10
|
+
minX: Math.min(...outer.map(([x]) => x)),
|
|
11
|
+
maxX: Math.max(...outer.map(([x]) => x)),
|
|
12
|
+
minZ: Math.min(...outer.map(([, z]) => z)),
|
|
13
|
+
maxZ: Math.max(...outer.map(([, z]) => z)),
|
|
14
|
+
}));
|
|
15
|
+
const kept = [], indices = [], samples = [];
|
|
16
|
+
for (let i = 0; i < buffers.indices.length; i += 3) {
|
|
17
|
+
const source = Array.from(buffers.indices.subarray(i, i + 3));
|
|
18
|
+
const triangle = source.map((id) => [
|
|
19
|
+
buffers.positions[id * 3],
|
|
20
|
+
buffers.positions[id * 3 + 2],
|
|
21
|
+
]);
|
|
22
|
+
const xs = triangle.map(([x]) => x), zs = triangle.map(([, z]) => z);
|
|
23
|
+
if (!bounds.some((box) => box.maxX > Math.min(...xs) &&
|
|
24
|
+
box.minX < Math.max(...xs) &&
|
|
25
|
+
box.maxZ > Math.min(...zs) &&
|
|
26
|
+
box.minZ < Math.max(...zs))) {
|
|
27
|
+
kept.push(...source);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const [a, b, c] = triangle;
|
|
31
|
+
const determinant = (b[1] - c[1]) * (a[0] - c[0]) + (c[0] - b[0]) * (a[1] - c[1]);
|
|
32
|
+
for (const polygon of difference(triangle, cutouts)) {
|
|
33
|
+
const contour = polygon.outer.map(([x, z]) => new Vector2(x, z));
|
|
34
|
+
const voids = polygon.holes.map((ring) => ring.map(([x, z]) => new Vector2(x, z)));
|
|
35
|
+
const offset = samples.length;
|
|
36
|
+
for (const { x, y: z } of [contour, ...voids].flat()) {
|
|
37
|
+
const wa = ((b[1] - c[1]) * (x - c[0]) + (c[0] - b[0]) * (z - c[1])) / determinant;
|
|
38
|
+
const wb = ((c[1] - a[1]) * (x - c[0]) + (a[0] - c[0]) * (z - c[1])) / determinant;
|
|
39
|
+
samples.push({ indices: source, weights: [wa, wb, 1 - wa - wb] });
|
|
40
|
+
}
|
|
41
|
+
for (const [a, b, c] of ShapeUtils.triangulateShape(contour, voids))
|
|
42
|
+
indices.push(offset + c, offset + b, offset + a);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
buffers.indices = new Uint32Array(kept);
|
|
46
|
+
const geometry = new BufferGeometry();
|
|
47
|
+
for (const name of ['position', 'normal'])
|
|
48
|
+
geometry.setAttribute(name, new BufferAttribute(new Float32Array(samples.length * 3), 3).setUsage(DynamicDrawUsage));
|
|
49
|
+
const uv = new Float32Array(samples.length * 2);
|
|
50
|
+
for (let i = 0; i < samples.length; i++)
|
|
51
|
+
for (let axis = 0; axis < 2; axis++)
|
|
52
|
+
uv[i * 2 + axis] = samples[i].indices.reduce((sum, id, j) => sum + buffers.uvs[id * 2 + axis] * samples[i].weights[j], 0);
|
|
53
|
+
geometry.setAttribute('uv', new BufferAttribute(uv, 2));
|
|
54
|
+
geometry.setIndex(indices);
|
|
55
|
+
const boundary = { geometry, samples };
|
|
56
|
+
updateTerrainHoleBoundary(boundary, buffers);
|
|
57
|
+
return boundary;
|
|
58
|
+
}
|
|
59
|
+
export function updateTerrainHoleBoundary(boundary, buffers) {
|
|
60
|
+
for (const [name, source] of [
|
|
61
|
+
['position', buffers.positions],
|
|
62
|
+
['normal', buffers.normals],
|
|
63
|
+
]) {
|
|
64
|
+
const attribute = boundary.geometry.getAttribute(name);
|
|
65
|
+
for (let i = 0; i < boundary.samples.length; i++) {
|
|
66
|
+
const sample = boundary.samples[i];
|
|
67
|
+
for (let axis = 0; axis < 3; axis++)
|
|
68
|
+
attribute.array[i * 3 + axis] = sample.indices.reduce((sum, id, j) => sum + source[id * 3 + axis] * sample.weights[j], 0);
|
|
69
|
+
}
|
|
70
|
+
attribute.needsUpdate = true;
|
|
71
|
+
}
|
|
72
|
+
boundary.geometry.normalizeNormals();
|
|
73
|
+
boundary.geometry.computeBoundingSphere();
|
|
74
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { HeightPatch, TerrainField } from '@pascal-app/core';
|
|
1
|
+
import type { HeightPatch, Ring, TerrainField } from '@pascal-app/core';
|
|
2
2
|
import { BufferGeometry } from 'three';
|
|
3
3
|
import { type TerrainMeshBuffers, type TerrainSkirtBuffers } from './terrain-geometry';
|
|
4
|
+
import { type TerrainHoleBoundary } from './terrain-holes';
|
|
4
5
|
/**
|
|
5
6
|
* The Three.js side of the terrain heightfield: owns the `BufferGeometry` and the
|
|
6
7
|
* dirty-rect upload.
|
|
@@ -20,6 +21,7 @@ import { type TerrainMeshBuffers, type TerrainSkirtBuffers } from './terrain-geo
|
|
|
20
21
|
/** A terrain geometry plus the CPU buffers backing it. */
|
|
21
22
|
export type TerrainGeometry = {
|
|
22
23
|
readonly geometry: BufferGeometry;
|
|
24
|
+
readonly holeBoundary: TerrainHoleBoundary | null;
|
|
23
25
|
readonly buffers: TerrainMeshBuffers;
|
|
24
26
|
/** Expands during live edits; a committed-field rebuild tightens it again. */
|
|
25
27
|
readonly heightBounds: {
|
|
@@ -32,7 +34,12 @@ export type TerrainGeometry = {
|
|
|
32
34
|
readonly buffers: TerrainSkirtBuffers;
|
|
33
35
|
};
|
|
34
36
|
};
|
|
35
|
-
|
|
37
|
+
/**
|
|
38
|
+
* `ring` (from `skirtRing`) runs the skirt along the lot's property line instead
|
|
39
|
+
* of the field's rectangle: the surface is cut to the lot by its material (see
|
|
40
|
+
* `lotMaskedMaterial`), and the skirt closes it as a block with a flat base.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createTerrainGeometry(field: TerrainField, holes?: Ring[], ring?: Float32Array | null): TerrainGeometry;
|
|
36
43
|
/**
|
|
37
44
|
* Push one patch to the GPU, touching only the affected rows.
|
|
38
45
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrain-mesh.d.ts","sourceRoot":"","sources":["../../src/site/terrain-mesh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"terrain-mesh.d.ts","sourceRoot":"","sources":["../../src/site/terrain-mesh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACvE,OAAO,EAAmB,cAAc,EAA4B,MAAM,OAAO,CAAA;AACjF,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAGzB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,iBAAiB,CAAA;AAExB;;;;;;;;;;;;;;;GAeG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACjD,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAA;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACrD,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAA;KAAE,CAAA;CAC7F,CAAA;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,YAAY,EACnB,KAAK,GAAE,IAAI,EAAO,EAClB,IAAI,GAAE,YAAY,GAAG,IAAW,GAC/B,eAAe,CAyCjB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,WAAW,GACjB,IAAI,CA+CN;AAoFD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAElF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAIpE"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { BufferAttribute, BufferGeometry, DynamicDrawUsage, Sphere } from 'three';
|
|
2
|
-
import { buildTerrainMesh, buildTerrainSkirt, HORIZON_PLANE_Y, patchUpdateRange, updateTerrainMesh, updateTerrainSkirt, } from './terrain-geometry';
|
|
3
|
-
|
|
2
|
+
import { buildTerrainMesh, buildTerrainSkirt, HORIZON_PLANE_Y, patchUpdateRange, SKIRT_DROP, updateTerrainMesh, updateTerrainSkirt, } from './terrain-geometry';
|
|
3
|
+
import { cutTerrainHoles, updateTerrainHoleBoundary, } from './terrain-holes';
|
|
4
|
+
/**
|
|
5
|
+
* `ring` (from `skirtRing`) runs the skirt along the lot's property line instead
|
|
6
|
+
* of the field's rectangle: the surface is cut to the lot by its material (see
|
|
7
|
+
* `lotMaskedMaterial`), and the skirt closes it as a block with a flat base.
|
|
8
|
+
*/
|
|
9
|
+
export function createTerrainGeometry(field, holes = [], ring = null) {
|
|
4
10
|
const buffers = buildTerrainMesh(field);
|
|
11
|
+
const holeBoundary = cutTerrainHoles(buffers, holes);
|
|
5
12
|
const geometry = new BufferGeometry();
|
|
6
13
|
geometry.setAttribute('position', new BufferAttribute(buffers.positions, 3).setUsage(DynamicDrawUsage));
|
|
7
14
|
geometry.setAttribute('normal', new BufferAttribute(buffers.normals, 3).setUsage(DynamicDrawUsage));
|
|
@@ -12,14 +19,17 @@ export function createTerrainGeometry(field) {
|
|
|
12
19
|
// A separate geometry, not extra vertices on the surface: the surface's dirty
|
|
13
20
|
// range is a row span over a `cols * rows` layout, and appending a perimeter ring
|
|
14
21
|
// to it would break that indexing for a saving of one draw call.
|
|
15
|
-
const skirtBuffers = buildTerrainSkirt(field);
|
|
22
|
+
const skirtBuffers = buildTerrainSkirt(field, ring);
|
|
16
23
|
const skirtGeometry = new BufferGeometry();
|
|
17
24
|
skirtGeometry.setAttribute('position', new BufferAttribute(skirtBuffers.positions, 3).setUsage(DynamicDrawUsage));
|
|
18
25
|
skirtGeometry.setAttribute('normal', new BufferAttribute(skirtBuffers.normals, 3).setUsage(DynamicDrawUsage));
|
|
19
26
|
skirtGeometry.setIndex(new BufferAttribute(skirtBuffers.indices, 1));
|
|
27
|
+
if (skirtBuffers.ring)
|
|
28
|
+
skirtGeometry.userData.ring = skirtBuffers.ring;
|
|
20
29
|
setSkirtBounds(skirtGeometry, field, span);
|
|
21
30
|
return {
|
|
22
31
|
geometry,
|
|
32
|
+
holeBoundary,
|
|
23
33
|
buffers,
|
|
24
34
|
heightBounds: span,
|
|
25
35
|
skirt: { geometry: skirtGeometry, buffers: skirtBuffers },
|
|
@@ -38,7 +48,10 @@ export function applyTerrainPatch(target, field, patch) {
|
|
|
38
48
|
if (!range)
|
|
39
49
|
return;
|
|
40
50
|
updateTerrainMesh(field, target.buffers, patch);
|
|
41
|
-
if (
|
|
51
|
+
if (target.holeBoundary)
|
|
52
|
+
updateTerrainHoleBoundary(target.holeBoundary, target.buffers);
|
|
53
|
+
if (target.skirt.buffers.ring ||
|
|
54
|
+
patch.col0 <= 0 ||
|
|
42
55
|
patch.row0 <= 0 ||
|
|
43
56
|
patch.col0 + patch.cols >= field.cols ||
|
|
44
57
|
patch.row0 + patch.rows >= field.rows) {
|
|
@@ -111,12 +124,25 @@ function setTerrainBounds(geometry, field, { minY, maxY }) {
|
|
|
111
124
|
* same reason the geometry does.
|
|
112
125
|
*/
|
|
113
126
|
function setSkirtBounds(geometry, field, { minY, maxY }) {
|
|
114
|
-
const low = Math.min(minY, HORIZON_PLANE_Y) -
|
|
127
|
+
const low = Math.min(minY, HORIZON_PLANE_Y) - SKIRT_DROP;
|
|
115
128
|
const high = Math.max(maxY, HORIZON_PLANE_Y);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
129
|
+
let minX = field.origin[0];
|
|
130
|
+
let minZ = field.origin[1];
|
|
131
|
+
let maxX = minX + (field.cols - 1) * field.spacing;
|
|
132
|
+
let maxZ = minZ + (field.rows - 1) * field.spacing;
|
|
133
|
+
const ring = geometry.userData.ring;
|
|
134
|
+
if (ring && ring.length >= 6) {
|
|
135
|
+
minX = maxX = ring[0] ?? 0;
|
|
136
|
+
minZ = maxZ = ring[1] ?? 0;
|
|
137
|
+
for (let i = 2; i < ring.length; i += 2) {
|
|
138
|
+
const x = ring[i] ?? 0;
|
|
139
|
+
const z = ring[i + 1] ?? 0;
|
|
140
|
+
minX = Math.min(minX, x);
|
|
141
|
+
maxX = Math.max(maxX, x);
|
|
142
|
+
minZ = Math.min(minZ, z);
|
|
143
|
+
maxZ = Math.max(maxZ, z);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
120
146
|
geometry.boundingSphere ??= new Sphere();
|
|
121
147
|
const sphere = geometry.boundingSphere;
|
|
122
148
|
sphere.center.set((minX + maxX) / 2, (low + high) / 2, (minZ + maxZ) / 2);
|
|
@@ -147,5 +173,6 @@ export function needsRebuild(target, field) {
|
|
|
147
173
|
}
|
|
148
174
|
export function disposeTerrainGeometry(target) {
|
|
149
175
|
target.geometry.dispose();
|
|
176
|
+
target.holeBoundary?.geometry.dispose();
|
|
150
177
|
target.skirt.geometry.dispose();
|
|
151
178
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type SiteNode } from '@pascal-app/core';
|
|
1
|
+
import { type Ring, type SiteNode } from '@pascal-app/core';
|
|
2
2
|
import type { Material } from 'three';
|
|
3
3
|
/**
|
|
4
4
|
* Renders the site's sculpted ground.
|
|
@@ -19,10 +19,17 @@ import type { Material } from 'three';
|
|
|
19
19
|
* the editor layer, but moving actual scene geometry there would exclude it from
|
|
20
20
|
* the MRT depth/normal pass and break the screen-space ink against it.
|
|
21
21
|
*/
|
|
22
|
-
export declare const TerrainRenderer: ({ material, site, }: {
|
|
22
|
+
export declare const TerrainRenderer: ({ material, site, holes, polygon, }: {
|
|
23
23
|
/** Owned by `SiteRenderer` so the ground material stays defined in one place. */
|
|
24
24
|
material: Material;
|
|
25
25
|
site: SiteNode;
|
|
26
|
+
holes: Ring[];
|
|
27
|
+
/**
|
|
28
|
+
* The lot's property line (live while it is being edited). With one, the
|
|
29
|
+
* ground is the lot alone — cut to the line, closed by a skirt down to a flat
|
|
30
|
+
* base — rather than the field's padded box.
|
|
31
|
+
*/
|
|
32
|
+
polygon?: ReadonlyArray<readonly [number, number]> | null;
|
|
26
33
|
}) => import("react").JSX.Element | null;
|
|
27
34
|
export default TerrainRenderer;
|
|
28
35
|
//# sourceMappingURL=terrain-renderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrain-renderer.d.ts","sourceRoot":"","sources":["../../src/site/terrain-renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,QAAQ,EAAkC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"terrain-renderer.d.ts","sourceRoot":"","sources":["../../src/site/terrain-renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAkC,MAAM,kBAAkB,CAAA;AAE3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAWrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe,GAAI,qCAK7B;IACD,iFAAiF;IACjF,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,IAAI,EAAE,CAAA;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAA;CAC1D,uCAoFA,CAAA;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { terrainFieldOf, useLiveTerrain } from '@pascal-app/core';
|
|
4
4
|
import { useEffect, useMemo, useRef } from 'react';
|
|
5
|
+
import { lotMaskedMaterial } from './lot-mask';
|
|
6
|
+
import { skirtRing } from './terrain-geometry';
|
|
5
7
|
import { applyTerrainPatch, createTerrainGeometry, disposeTerrainGeometry, needsRebuild, } from './terrain-mesh';
|
|
6
8
|
/**
|
|
7
9
|
* Renders the site's sculpted ground.
|
|
@@ -22,7 +24,7 @@ import { applyTerrainPatch, createTerrainGeometry, disposeTerrainGeometry, needs
|
|
|
22
24
|
* the editor layer, but moving actual scene geometry there would exclude it from
|
|
23
25
|
* the MRT depth/normal pass and break the screen-space ink against it.
|
|
24
26
|
*/
|
|
25
|
-
export const TerrainRenderer = ({ material, site, }) => {
|
|
27
|
+
export const TerrainRenderer = ({ material, site, holes, polygon, }) => {
|
|
26
28
|
const targetRef = useRef(null);
|
|
27
29
|
// Persisted terrain only — the live stroke is applied imperatively below, so a
|
|
28
30
|
// dab never triggers a React render.
|
|
@@ -31,8 +33,16 @@ export const TerrainRenderer = ({ material, site, }) => {
|
|
|
31
33
|
const field = useLiveTerrain.getState().fieldOf(site.id) ?? persistedField;
|
|
32
34
|
if (!field)
|
|
33
35
|
return null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const ring = polygon && polygon.length >= 3 ? skirtRing(field, polygon) : null;
|
|
37
|
+
return createTerrainGeometry(field, holes, ring && ring.length >= 6 ? ring : null);
|
|
38
|
+
}, [persistedField, site.id, holes, polygon]);
|
|
39
|
+
// The surface (and the cut edges round recessed slabs) stop at the property
|
|
40
|
+
// line; the skirt keeps the plain material — it *is* the line.
|
|
41
|
+
const surfaceMaterial = useMemo(() => (polygon && polygon.length >= 3 ? lotMaskedMaterial(material, polygon) : material), [material, polygon]);
|
|
42
|
+
useEffect(() => () => {
|
|
43
|
+
if (surfaceMaterial !== material)
|
|
44
|
+
surfaceMaterial.dispose();
|
|
45
|
+
}, [surfaceMaterial, material]);
|
|
36
46
|
targetRef.current = target;
|
|
37
47
|
useEffect(() => () => {
|
|
38
48
|
if (target)
|
|
@@ -64,6 +74,6 @@ export const TerrainRenderer = ({ material, site, }) => {
|
|
|
64
74
|
}, [site.id]);
|
|
65
75
|
if (!target)
|
|
66
76
|
return null;
|
|
67
|
-
return (_jsxs(_Fragment, { children: [_jsx("mesh", { castShadow: true, geometry: target.geometry, material: material, receiveShadow: true }), _jsx("mesh", { geometry: target.skirt.geometry, material: material, receiveShadow: true })] }));
|
|
77
|
+
return (_jsxs(_Fragment, { children: [_jsx("mesh", { castShadow: true, geometry: target.geometry, material: surfaceMaterial, receiveShadow: true }), target.holeBoundary && (_jsx("mesh", { castShadow: true, geometry: target.holeBoundary.geometry, material: surfaceMaterial, receiveShadow: true })), _jsx("mesh", { geometry: target.skirt.geometry, material: material, receiveShadow: true })] }));
|
|
68
78
|
};
|
|
69
79
|
export default TerrainRenderer;
|
|
@@ -3,7 +3,7 @@ import { type SlabNode } from '@pascal-app/core';
|
|
|
3
3
|
* Phase 5 Stage D — slab boundary editor (registry-driven).
|
|
4
4
|
*
|
|
5
5
|
* Thin wrapper around the shared `PolygonEditor`. Activates when a
|
|
6
|
-
* slab is selected in
|
|
6
|
+
* slab is selected in select mode (not currently editing a
|
|
7
7
|
* hole). The heavy lifting — vertex drag, edge slide, snap, history
|
|
8
8
|
* bracketing — lives in `PolygonEditor` itself.
|
|
9
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary-editor.d.ts","sourceRoot":"","sources":["../../src/slab/boundary-editor.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAkC,MAAM,kBAAkB,CAAA;AAehG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"boundary-editor.d.ts","sourceRoot":"","sources":["../../src/slab/boundary-editor.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAkC,MAAM,kBAAkB,CAAA;AAehG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;CAAE,CAwInE,CAAA;AAED,eAAe,kBAAkB,CAAA"}
|
|
@@ -8,7 +8,7 @@ import { useCallback, useEffect } from 'react';
|
|
|
8
8
|
* Phase 5 Stage D — slab boundary editor (registry-driven).
|
|
9
9
|
*
|
|
10
10
|
* Thin wrapper around the shared `PolygonEditor`. Activates when a
|
|
11
|
-
* slab is selected in
|
|
11
|
+
* slab is selected in select mode (not currently editing a
|
|
12
12
|
* hole). The heavy lifting — vertex drag, edge slide, snap, history
|
|
13
13
|
* bracketing — lives in `PolygonEditor` itself.
|
|
14
14
|
*
|
|
@@ -24,16 +24,18 @@ import { useCallback, useEffect } from 'react';
|
|
|
24
24
|
*/
|
|
25
25
|
export const SlabBoundaryEditor = ({ slabId }) => {
|
|
26
26
|
const slabNode = useScene((s) => s.nodes[slabId]);
|
|
27
|
-
const
|
|
27
|
+
const detachDerivedNode = useScene((s) => s.detachDerivedNode);
|
|
28
28
|
const markDirty = useScene((s) => s.markDirty);
|
|
29
29
|
const setSelection = useViewer((s) => s.setSelection);
|
|
30
30
|
const slab = slabNode?.type === 'slab' ? slabNode : null;
|
|
31
31
|
const slabLevelId = slab ? resolveLevelId(slab, useScene.getState().nodes) : null;
|
|
32
32
|
const handlePolygonChange = useCallback((newPolygon) => {
|
|
33
33
|
clearSlabSnapFeedback();
|
|
34
|
-
|
|
34
|
+
// Reshaping the boundary is the sanctioned conversion of a derived floor
|
|
35
|
+
// plate into an authored slab — the reconciler stops owning it here.
|
|
36
|
+
detachDerivedNode(slabId, { polygon: newPolygon });
|
|
35
37
|
setSelection({ selectedIds: [slabId] });
|
|
36
|
-
}, [slabId,
|
|
38
|
+
}, [slabId, detachDerivedNode, setSelection]);
|
|
37
39
|
const handlePolygonPreview = useCallback((preview) => {
|
|
38
40
|
if (preview) {
|
|
39
41
|
useLiveNodeOverrides.getState().set(slabId, {
|
|
@@ -110,15 +112,13 @@ export const SlabBoundaryEditor = ({ slabId }) => {
|
|
|
110
112
|
// Guarantee the override clears if the editor unmounts mid-drag
|
|
111
113
|
// (selection change, mode switch) so the slab mesh doesn't get stuck
|
|
112
114
|
// on a stale polygon.
|
|
113
|
-
useEffect(() => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
.endIf((s) => s.kind === 'reshaping' && s.reshape === 'boundary');
|
|
121
|
-
};
|
|
115
|
+
useEffect(() => () => {
|
|
116
|
+
clearSlabSnapFeedback();
|
|
117
|
+
useLiveNodeOverrides.getState().clear(slabId);
|
|
118
|
+
useScene.getState().markDirty(slabId);
|
|
119
|
+
useInteractionScope
|
|
120
|
+
.getState()
|
|
121
|
+
.endIf((s) => s.kind === 'reshaping' && s.reshape === 'boundary');
|
|
122
122
|
}, [slabId]);
|
|
123
123
|
if (!slab?.polygon || slab.polygon.length < 3)
|
|
124
124
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/slab/definition.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/slab/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,cAAc,EAMpB,MAAM,kBAAkB,CAAA;AA+BzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAyNnC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAyI1D,CAAA"}
|
package/dist/slab/definition.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { MIN_SLAB_THICKNESS, markSlabChangeDependents, pointInPolygon2D, syncStairRises, } from '@pascal-app/core';
|
|
1
|
+
import { liftedManualSlab, MIN_SLAB_THICKNESS, markSlabChangeDependents, pointInPolygon2D, slabSlots, syncStairRises, } from '@pascal-app/core';
|
|
2
2
|
import { clearStructuralElevationGuide, DRAFTING_SURFACE_EXTENSION_KEY, publishStructuralElevationGuide, resolveStructuralElevationSnap, } from '@pascal-app/editor';
|
|
3
|
+
import { surfaceBatchable } from '../shared/node-batch/batchable';
|
|
3
4
|
import { polygonMeasurementFeatures } from '../shared/polygon-measurement';
|
|
4
5
|
import { sameOutlineSurfaceCounterparts } from '../shared/surface-counterparts';
|
|
5
6
|
import { applySlabBaseElevationChange, applySlabThicknessChange, applySlabTopChange, getSlabBaseElevation, slabElevationUpperBound, } from './elevation-limit';
|
|
@@ -11,7 +12,6 @@ import { slabPaint } from './paint';
|
|
|
11
12
|
import { slabParametrics } from './parametrics';
|
|
12
13
|
import { slabQuickMeasurement } from './quick-measurement';
|
|
13
14
|
import { SlabNode } from './schema';
|
|
14
|
-
import { slabSlots } from './slots';
|
|
15
15
|
const HEIGHT_HANDLE_OFFSET = 0.22;
|
|
16
16
|
const MIN_SLAB_ELEVATION = -1;
|
|
17
17
|
function polygonVertexAverage(polygon) {
|
|
@@ -171,6 +171,11 @@ function slabBaseElevationHandle() {
|
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
173
|
function slabHandles(node) {
|
|
174
|
+
// A footprint's floor (base plate) has one control, its height above the
|
|
175
|
+
// ground, drawn by the editor's footprint height handle; room plates are
|
|
176
|
+
// reached through their room. Only user-drawn slabs keep these handles.
|
|
177
|
+
if (node.plateRole)
|
|
178
|
+
return [];
|
|
174
179
|
return node.recessed
|
|
175
180
|
? [slabRecessedDepthHandle()]
|
|
176
181
|
: [slabThicknessHandle(), slabBaseElevationHandle()];
|
|
@@ -220,9 +225,20 @@ export const slabDefinition = {
|
|
|
220
225
|
autoFromWalls: false,
|
|
221
226
|
}),
|
|
222
227
|
capabilities: {
|
|
228
|
+
batchable: surfaceBatchable,
|
|
223
229
|
selectable: { hitVolume: 'bbox' },
|
|
224
230
|
surfaces: {
|
|
225
|
-
top: {
|
|
231
|
+
top: {
|
|
232
|
+
height: (n) => n.elevation,
|
|
233
|
+
supportHeight: (node, x, z, context) => {
|
|
234
|
+
const slab = node;
|
|
235
|
+
if (slab.polygon.length < 3 ||
|
|
236
|
+
!pointInPolygon2D([x, z], slab.polygon, { includeBoundary: true }) ||
|
|
237
|
+
slab.holes.some((hole) => hole.length >= 3 && pointInPolygon2D([x, z], hole, { includeBoundary: false })))
|
|
238
|
+
return null;
|
|
239
|
+
return liftedManualSlab(context.nodes, slab).elevation;
|
|
240
|
+
},
|
|
241
|
+
},
|
|
226
242
|
},
|
|
227
243
|
duplicable: true,
|
|
228
244
|
deletable: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-tracker.d.ts","sourceRoot":"","sources":["../../src/slab/dependency-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"dependency-tracker.d.ts","sourceRoot":"","sources":["../../src/slab/dependency-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EAYf,MAAM,kBAAkB,CAAA;AAsBzB,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAwDxD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,SAAS,EAAE,CAoH7D"}
|