@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
package/dist/roof/floorplan.js
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
|
-
import { roofPlanOverlapEntryOwns, subtractPolygonsFromPolygon, unionPolygons, } from '@pascal-app/core';
|
|
1
|
+
import { getRoofSegmentVisibleTopBounds, roofPlanOverlapEntryOwns, subtractPolygonsFromPolygon, unionPolygons, } from '@pascal-app/core';
|
|
2
|
+
import { floorplanGeometryMetadata, readFloorplanContext } from '@pascal-app/editor';
|
|
2
3
|
import { getConicalRoofPlanFootprint, getRoofSegmentPlanLinework } from '../roof-segment/floorplan';
|
|
4
|
+
/**
|
|
5
|
+
* `roof-segment.pitch` is stored in DEGREES; a roof plan is annotated as the
|
|
6
|
+
* rise over a 12 run. 30.256° → tan 0.5833 × 12 → 7.00 → '7:12'. Rounded to
|
|
7
|
+
* the nearest half, so a modelled pitch a hair off a standard slope still
|
|
8
|
+
* reads as the slope the framer will cut. Returns '' for a flat roof, which
|
|
9
|
+
* has no slope to annotate.
|
|
10
|
+
*/
|
|
11
|
+
export function roofPitchLabel(pitchDeg) {
|
|
12
|
+
if (!Number.isFinite(pitchDeg) || pitchDeg <= 0)
|
|
13
|
+
return '';
|
|
14
|
+
const rise = Math.tan((pitchDeg * Math.PI) / 180) * 12;
|
|
15
|
+
if (!Number.isFinite(rise) || rise <= 0)
|
|
16
|
+
return '';
|
|
17
|
+
const rounded = Math.round(rise * 2) / 2;
|
|
18
|
+
return `${Number.isInteger(rounded) ? rounded : rounded.toFixed(1)}:12`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* One down-slope arrow per roof PLANE, in segment-local coordinates
|
|
22
|
+
* (lx = width axis, lz = depth axis) — the same local space
|
|
23
|
+
* `getRoofSegmentPlanLinework` returns ridges and hips in:
|
|
24
|
+
*
|
|
25
|
+
* gable / gambrel two planes falling away from the centre ridge (±lz)
|
|
26
|
+
* shed one plane, high eave at −lz falling to +lz
|
|
27
|
+
* hip / mansard / four planes, one off each eave
|
|
28
|
+
* dutch
|
|
29
|
+
* flat none
|
|
30
|
+
*
|
|
31
|
+
* Arrows run from just off the ridge to just short of the eave so the head
|
|
32
|
+
* lands inside the roof outline rather than on it.
|
|
33
|
+
*/
|
|
34
|
+
function slopeArrows(node) {
|
|
35
|
+
const hw = Math.max(node.width, 0.01) / 2;
|
|
36
|
+
const hd = Math.max(node.depth, 0.01) / 2;
|
|
37
|
+
const along = (run) => ({ near: run * 0.14, far: run * 0.86 });
|
|
38
|
+
switch (node.roofType) {
|
|
39
|
+
case 'flat':
|
|
40
|
+
return [];
|
|
41
|
+
case 'shed':
|
|
42
|
+
// Unchanged from the linework builder: the 3D shed falls −lz → +lz.
|
|
43
|
+
return [{ tail: [0, -hd * 0.55], head: [0, hd * 0.55] }];
|
|
44
|
+
case 'gable':
|
|
45
|
+
case 'gambrel': {
|
|
46
|
+
const z = along(hd);
|
|
47
|
+
return [
|
|
48
|
+
{ tail: [-hw * 0.35, z.near], head: [-hw * 0.35, z.far] },
|
|
49
|
+
{ tail: [hw * 0.35, -z.near], head: [hw * 0.35, -z.far] },
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
default: {
|
|
53
|
+
const z = along(hd);
|
|
54
|
+
const x = along(hw);
|
|
55
|
+
return [
|
|
56
|
+
{ tail: [0, z.near], head: [0, z.far] },
|
|
57
|
+
{ tail: [0, -z.near], head: [0, -z.far] },
|
|
58
|
+
{ tail: [x.near, 0], head: [x.far, 0] },
|
|
59
|
+
{ tail: [-x.near, 0], head: [-x.far, 0] },
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
3
64
|
function overlapEntry(entry, ctx) {
|
|
4
65
|
const supportSegment = entry.roof.support?.kind === 'roof'
|
|
5
66
|
? ctx.resolve(entry.roof.support.roofSegmentId)
|
|
@@ -17,7 +78,7 @@ function overlapEntry(entry, ctx) {
|
|
|
17
78
|
};
|
|
18
79
|
}
|
|
19
80
|
/** A segment's footprint + ridge/hip/break/slope linework, in world plan coords. */
|
|
20
|
-
function buildSegPlan(roof, seg) {
|
|
81
|
+
function buildSegPlan(roof, seg, drafting) {
|
|
21
82
|
const cosRoof = Math.cos(-roof.rotation);
|
|
22
83
|
const sinRoof = Math.sin(-roof.rotation);
|
|
23
84
|
const segCx = roof.position[0] + seg.position[0] * cosRoof - seg.position[2] * sinRoof;
|
|
@@ -39,17 +100,42 @@ function buildSegPlan(roof, seg) {
|
|
|
39
100
|
const footprint = seg.roofType === 'conical'
|
|
40
101
|
? getConicalRoofPlanFootprint(seg).map(([x, z]) => tp(x, z))
|
|
41
102
|
: [tp(-hw, -hd), tp(hw, -hd), tp(hw, hd), tp(-hw, hd)];
|
|
103
|
+
const ridges = lw.ridges.map(mapSeg);
|
|
104
|
+
const hips = lw.hips.map(mapSeg);
|
|
105
|
+
const breaks = lw.breaks.map(mapSeg);
|
|
106
|
+
if (!drafting) {
|
|
107
|
+
const slopes = lw.slope
|
|
108
|
+
? [
|
|
109
|
+
{
|
|
110
|
+
tail: tp(lw.slope.tail[0], lw.slope.tail[1]),
|
|
111
|
+
head: tp(lw.slope.head[0], lw.slope.head[1]),
|
|
112
|
+
pitch: '',
|
|
113
|
+
},
|
|
114
|
+
]
|
|
115
|
+
: [];
|
|
116
|
+
return { footprint, eave: footprint, ridges, hips, breaks, slopes };
|
|
117
|
+
}
|
|
118
|
+
// The drip edge: core's own visible-top bounds, which add the horizontal
|
|
119
|
+
// component of `overhang` (plus half the wall thickness and, on the sloped
|
|
120
|
+
// faces, the shingle projection) to the footprint on each side.
|
|
121
|
+
const edge = getRoofSegmentVisibleTopBounds(seg);
|
|
122
|
+
const pitch = roofPitchLabel(seg.pitch);
|
|
42
123
|
return {
|
|
43
124
|
footprint,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
125
|
+
eave: [
|
|
126
|
+
tp(edge.minX, edge.minZ),
|
|
127
|
+
tp(edge.maxX, edge.minZ),
|
|
128
|
+
tp(edge.maxX, edge.maxZ),
|
|
129
|
+
tp(edge.minX, edge.maxZ),
|
|
130
|
+
],
|
|
131
|
+
ridges,
|
|
132
|
+
hips,
|
|
133
|
+
breaks,
|
|
134
|
+
slopes: slopeArrows(seg).map((arrow) => ({
|
|
135
|
+
tail: tp(arrow.tail[0], arrow.tail[1]),
|
|
136
|
+
head: tp(arrow.head[0], arrow.head[1]),
|
|
137
|
+
pitch,
|
|
138
|
+
})),
|
|
53
139
|
};
|
|
54
140
|
}
|
|
55
141
|
function pointInPolygon(point, polygon) {
|
|
@@ -126,10 +212,13 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
126
212
|
const segments = ctx.children.filter((c) => c.type === 'roof-segment');
|
|
127
213
|
if (segments.length === 0)
|
|
128
214
|
return null;
|
|
215
|
+
// Eave outlines, an arrow per plane, pitch tags and the 'roof-plan' role are
|
|
216
|
+
// sheet drafting; the editor plan keeps its outline, linework and one arrow.
|
|
217
|
+
const drafting = readFloorplanContext(ctx).drafting;
|
|
129
218
|
const entries = segments.map((segment) => ({
|
|
130
219
|
roof: node,
|
|
131
220
|
segment,
|
|
132
|
-
plan: buildSegPlan(node, segment),
|
|
221
|
+
plan: buildSegPlan(node, segment, drafting),
|
|
133
222
|
}));
|
|
134
223
|
for (const sibling of ctx.siblings) {
|
|
135
224
|
if (sibling.type !== 'roof')
|
|
@@ -138,7 +227,7 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
138
227
|
const segment = ctx.resolve(childId);
|
|
139
228
|
if (segment?.type !== 'roof-segment')
|
|
140
229
|
continue;
|
|
141
|
-
entries.push({ roof: sibling, segment, plan: buildSegPlan(sibling, segment) });
|
|
230
|
+
entries.push({ roof: sibling, segment, plan: buildSegPlan(sibling, segment, drafting) });
|
|
142
231
|
}
|
|
143
232
|
}
|
|
144
233
|
const currentEntries = entries.filter((entry) => entry.roof.id === node.id);
|
|
@@ -156,11 +245,15 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
156
245
|
plan: entry.plan,
|
|
157
246
|
cutters,
|
|
158
247
|
footprints: subtractPolygonsFromPolygon(entry.plan.footprint, cutters),
|
|
248
|
+
eaves: subtractPolygonsFromPolygon(entry.plan.eave, cutters),
|
|
249
|
+
/** True when the drip edge is far enough outside the wall line to draw. */
|
|
250
|
+
hasOverhang: drafting && polygonSpread(entry.plan.eave) - polygonSpread(entry.plan.footprint) > 0.04,
|
|
159
251
|
};
|
|
160
252
|
});
|
|
161
253
|
const rings = unionPolygons(visiblePlans.flatMap(({ footprints }) => footprints));
|
|
162
254
|
if (rings.length === 0)
|
|
163
255
|
return null;
|
|
256
|
+
const eaveRings = unionPolygons(visiblePlans.flatMap(({ eaves, hasOverhang }) => (hasOverhang ? eaves : [])));
|
|
164
257
|
const view = ctx.viewState;
|
|
165
258
|
const palette = view?.palette;
|
|
166
259
|
const showSelectedChrome = (view?.selected ?? false) || (view?.highlighted ?? false);
|
|
@@ -168,6 +261,13 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
168
261
|
const eaveWidth = showSelectedChrome ? 0.04 : 0.03;
|
|
169
262
|
const ridgeWidth = showSelectedChrome ? 0.05 : 0.038;
|
|
170
263
|
const hipWidth = showSelectedChrome ? 0.04 : 0.026;
|
|
264
|
+
const overhangWidth = showSelectedChrome ? 0.03 : 0.022;
|
|
265
|
+
// Drafted, two strata: the REFERENCE a floor plan always carries (the dashed
|
|
266
|
+
// overhang line — the roof flying past the walls) and the ROOF PLAN
|
|
267
|
+
// proper (outline, ridges, hips, arrows, pitches), which is the
|
|
268
|
+
// 'roof-plan' annotation — off over a floor plan until the Roof plan
|
|
269
|
+
// layer is on, the roof is selected, or the sheet IS the roof plan.
|
|
270
|
+
const reference = [];
|
|
171
271
|
const children = [];
|
|
172
272
|
const pushLine = (a, b, width) => {
|
|
173
273
|
children.push({
|
|
@@ -182,7 +282,25 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
182
282
|
pointerEvents: 'none',
|
|
183
283
|
});
|
|
184
284
|
};
|
|
185
|
-
//
|
|
285
|
+
// The drip edge — the roof's actual outer boundary, overhang included —
|
|
286
|
+
// drawn DASHED under the wall line so the two never read as one edge. This
|
|
287
|
+
// is the convention every roof plan uses: solid where the roof meets the
|
|
288
|
+
// structure, dashed where it flies past it.
|
|
289
|
+
for (const ring of eaveRings) {
|
|
290
|
+
if (ring.length < 3)
|
|
291
|
+
continue;
|
|
292
|
+
reference.push({
|
|
293
|
+
kind: 'polygon',
|
|
294
|
+
points: ring.map(([x, z]) => [x, z]),
|
|
295
|
+
fill: 'none',
|
|
296
|
+
stroke: ink,
|
|
297
|
+
strokeWidth: overhangWidth,
|
|
298
|
+
strokeDasharray: '0.28 0.16',
|
|
299
|
+
strokeLinejoin: 'miter',
|
|
300
|
+
pointerEvents: 'none',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
// Merged outline (wall line under the roof).
|
|
186
304
|
for (const ring of rings) {
|
|
187
305
|
if (ring.length < 3)
|
|
188
306
|
continue;
|
|
@@ -212,9 +330,11 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
212
330
|
pushLine(visible[0], visible[1], ridgeWidth);
|
|
213
331
|
}
|
|
214
332
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
333
|
+
// One down-slope arrow per roof plane, each tagged with the pitch in
|
|
334
|
+
// 12ths — the annotation a roof plan is read for. The arrow points the
|
|
335
|
+
// way water runs; the tag is the number the framer cuts to.
|
|
336
|
+
for (const slope of plan.slopes) {
|
|
337
|
+
const visibleSlope = clipLineByCutters([slope.tail, slope.head], cutters).at(-1);
|
|
218
338
|
if (!visibleSlope)
|
|
219
339
|
continue;
|
|
220
340
|
const [visibleTail, visibleHead] = visibleSlope;
|
|
@@ -239,7 +359,63 @@ export function buildRoofFloorplan(node, ctx) {
|
|
|
239
359
|
strokeLinejoin: 'round',
|
|
240
360
|
pointerEvents: 'none',
|
|
241
361
|
});
|
|
362
|
+
if (!slope.pitch || len < PITCH_LABEL_MIN_RUN)
|
|
363
|
+
continue;
|
|
364
|
+
// Set beside the shaft, clear of it, at the arrow's midpoint. The
|
|
365
|
+
// perpendicular is chosen so the tag always sits ABOVE its arrow (and
|
|
366
|
+
// to its right where the arrow runs vertically), so opposing slopes of
|
|
367
|
+
// the same roof do not put their tags on opposite sides.
|
|
368
|
+
let px = uz;
|
|
369
|
+
let pz = -ux;
|
|
370
|
+
if (pz > 1e-6 || (Math.abs(pz) <= 1e-6 && px < 0)) {
|
|
371
|
+
px = -px;
|
|
372
|
+
pz = -pz;
|
|
373
|
+
}
|
|
374
|
+
const mx = (visibleTail[0] + visibleHead[0]) / 2 + px * PITCH_LABEL_OFFSET;
|
|
375
|
+
const mz = (visibleTail[1] + visibleHead[1]) / 2 + pz * PITCH_LABEL_OFFSET;
|
|
376
|
+
children.push({
|
|
377
|
+
kind: 'text',
|
|
378
|
+
x: mx,
|
|
379
|
+
y: mz,
|
|
380
|
+
text: slope.pitch,
|
|
381
|
+
fontSize: PITCH_LABEL_FONT_SIZE,
|
|
382
|
+
fill: ink,
|
|
383
|
+
stroke: '#ffffff',
|
|
384
|
+
strokeWidth: PITCH_LABEL_FONT_SIZE * 0.3,
|
|
385
|
+
paintOrder: 'stroke',
|
|
386
|
+
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
387
|
+
fontWeight: 600,
|
|
388
|
+
textAnchor: 'middle',
|
|
389
|
+
dominantBaseline: 'central',
|
|
390
|
+
upright: true,
|
|
391
|
+
metadata: floorplanGeometryMetadata({ annotationRole: 'roof-pitch' }),
|
|
392
|
+
});
|
|
242
393
|
}
|
|
243
394
|
}
|
|
244
|
-
|
|
395
|
+
if (!drafting)
|
|
396
|
+
return children.length > 0 ? { kind: 'group', children } : null;
|
|
397
|
+
if (reference.length === 0 && children.length === 0)
|
|
398
|
+
return null;
|
|
399
|
+
// A selected / highlighted roof shows its plan whatever the layer says —
|
|
400
|
+
// the user is looking at the roof.
|
|
401
|
+
const plan = showSelectedChrome
|
|
402
|
+
? { kind: 'group', children }
|
|
403
|
+
: {
|
|
404
|
+
kind: 'group',
|
|
405
|
+
children,
|
|
406
|
+
metadata: floorplanGeometryMetadata({ annotationRole: 'roof-plan' }),
|
|
407
|
+
};
|
|
408
|
+
return { kind: 'group', children: children.length > 0 ? [...reference, plan] : reference };
|
|
409
|
+
}
|
|
410
|
+
/** Longest edge of a polygon's bounding box — how the overhang test compares. */
|
|
411
|
+
function polygonSpread(polygon) {
|
|
412
|
+
if (polygon.length === 0)
|
|
413
|
+
return 0;
|
|
414
|
+
const xs = polygon.map(([x]) => x);
|
|
415
|
+
const zs = polygon.map(([, z]) => z);
|
|
416
|
+
return Math.max(...xs) - Math.min(...xs) + (Math.max(...zs) - Math.min(...zs));
|
|
245
417
|
}
|
|
418
|
+
const PITCH_LABEL_FONT_SIZE = 0.22;
|
|
419
|
+
const PITCH_LABEL_OFFSET = 0.24;
|
|
420
|
+
/** Below this arrow length the tag would sit on top of its own arrowhead. */
|
|
421
|
+
const PITCH_LABEL_MIN_RUN = 0.6;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel-model.d.ts","sourceRoot":"","sources":["../../src/roof/panel-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAEL,KAAK,cAAc,EAIpB,MAAM,oBAAoB,CAAA;AAG3B,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"panel-model.d.ts","sourceRoot":"","sources":["../../src/roof/panel-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAEL,KAAK,cAAc,EAIpB,MAAM,oBAAoB,CAAA;AAG3B,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,QAAQ,CAyJnD,CAAA"}
|
package/dist/roof/panel-model.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nodeRegistry, useScene, } from '@pascal-app/core';
|
|
2
|
-
import {
|
|
2
|
+
import { duplicateNodeAndPickUp, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
3
3
|
import { useViewer } from '@pascal-app/viewer';
|
|
4
4
|
export const roofPanelModel = {
|
|
5
5
|
rows({ node, nodes, update }) {
|
|
@@ -28,7 +28,12 @@ export const roofPanelModel = {
|
|
|
28
28
|
kind: 'action',
|
|
29
29
|
section: 'Segments',
|
|
30
30
|
label: 'Draw Segment',
|
|
31
|
-
|
|
31
|
+
// Arming a tool ends the selection; the roof tool draws into the roof
|
|
32
|
+
// selected while it is armed, so hand it this one explicitly.
|
|
33
|
+
onSelect: () => {
|
|
34
|
+
activate('roof');
|
|
35
|
+
select(node.id);
|
|
36
|
+
},
|
|
32
37
|
});
|
|
33
38
|
for (const axis of [0, 1, 2])
|
|
34
39
|
rows.push({
|
|
@@ -124,10 +129,9 @@ export const roofPanelModel = {
|
|
|
124
129
|
id: 'duplicate',
|
|
125
130
|
label: 'Duplicate',
|
|
126
131
|
onSelect: () => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
duplicateRoofSubtree(node.id, { mode: 'move' });
|
|
132
|
+
const live = useScene.getState().nodes[node.id];
|
|
133
|
+
if (live)
|
|
134
|
+
duplicateNodeAndPickUp(live);
|
|
131
135
|
},
|
|
132
136
|
},
|
|
133
137
|
{
|
package/dist/roof/panel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof/panel.tsx"],"names":[],"mappings":"AAmCA,MAAM,CAAC,OAAO,UAAU,SAAS,
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof/panel.tsx"],"names":[],"mappings":"AAmCA,MAAM,CAAC,OAAO,UAAU,SAAS,uCAogBhC"}
|
package/dist/roof/panel.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useScene, } from '@pascal-app/core';
|
|
4
|
-
import { ActionButton, ActionGroup, commitParametricNodeFields,
|
|
4
|
+
import { ActionButton, ActionGroup, commitParametricNodeFields, duplicateNodeAndPickUp, formatLinearMeasurement, PanelSection, PanelWrapper, SegmentedControl, SliderControl, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { Copy, Move, Plus, Trash2 } from 'lucide-react';
|
|
7
7
|
import { useCallback, useState } from 'react';
|
|
@@ -124,15 +124,8 @@ export default function RoofPanel() {
|
|
|
124
124
|
setSelection({ selectedIds: [segmentId] });
|
|
125
125
|
}, [setSelection]);
|
|
126
126
|
const handleDuplicate = useCallback(() => {
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
triggerSFX('sfx:item-pick');
|
|
130
|
-
try {
|
|
131
|
-
duplicateRoofSubtree(node.id, { mode: 'move' });
|
|
132
|
-
}
|
|
133
|
-
catch (e) {
|
|
134
|
-
console.error('Failed to duplicate roof', e);
|
|
135
|
-
}
|
|
127
|
+
if (node)
|
|
128
|
+
duplicateNodeAndPickUp(node);
|
|
136
129
|
}, [node]);
|
|
137
130
|
const handleMove = useCallback(() => {
|
|
138
131
|
if (node) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/roof/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,QAAQ,EAKd,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/roof/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,QAAQ,EAKd,MAAM,kBAAkB,CAAA;AAczB,eAAO,MAAM,YAAY,GAAI,mBAAmB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,gCA8HjE,CAAA;AAED,eAAe,YAAY,CAAA"}
|
package/dist/roof/renderer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { hasSegmentMaterialOverride, useLiveNodeOverrides, useRegistry, useScene, } from '@pascal-app/core';
|
|
4
|
-
import { getRoofMaterialArray, NodeRenderer, useNodeEvents, useViewer } from '@pascal-app/viewer';
|
|
4
|
+
import { getRoofMaterialArray, levelWallCladdingRef, NodeRenderer, useNodeEvents, useViewer, } from '@pascal-app/viewer';
|
|
5
5
|
import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
|
|
6
6
|
import { useShallow } from 'zustand/react/shallow';
|
|
7
7
|
import { createPlaceholderGeometry } from '../shared/placeholder-geometry';
|
|
@@ -65,7 +65,10 @@ export const RoofRenderer = ({ node: rawNode }) => {
|
|
|
65
65
|
}));
|
|
66
66
|
// 4 groups map 1:1 to the roof's 4-material array (see getRoofMaterialArray).
|
|
67
67
|
const placeholderGeometry = useMemo(() => createPlaceholderGeometry(4), []);
|
|
68
|
-
|
|
68
|
+
// The gable band is clad like the walls below it (their assemblies).
|
|
69
|
+
const wallCladdingRef = useScene((state) => levelWallCladdingRef(state.nodes, node));
|
|
70
|
+
const sceneMaterials = useScene((state) => state.materials);
|
|
71
|
+
const customMaterial = useMemo(() => getRoofMaterialArray(node, shading, textures, colorPreset, sceneTheme, wallCladdingRef, sceneMaterials), [node, shading, textures, colorPreset, sceneTheme, wallCladdingRef, sceneMaterials]);
|
|
69
72
|
const material = debugColors
|
|
70
73
|
? getRoofDebugMaterials(shading)
|
|
71
74
|
: customMaterial || getRoofMaterials(shading, textures, colorPreset);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof-segment/panel.tsx"],"names":[],"mappings":"AAkGA,MAAM,CAAC,OAAO,UAAU,gBAAgB,
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof-segment/panel.tsx"],"names":[],"mappings":"AAkGA,MAAM,CAAC,OAAO,UAAU,gBAAgB,uCAknBvC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { createDefaultRidgeVentsForSegment, getConicalRoofCoverage, isAutoGutterEnabled, isAutoRidgeVentEnabled, isDefaultRidgeVentNode, normalizeRoofSegmentTrim, ROOF_SHAPE_DEFAULTS,
|
|
4
|
-
import { ActionButton, ActionGroup, PanelSection, PanelWrapper, SegmentedControl, SliderControl, ToggleControl, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
3
|
+
import { createDefaultRidgeVentsForSegment, getConicalRoofCoverage, isAutoGutterEnabled, isAutoRidgeVentEnabled, isDefaultRidgeVentNode, normalizeRoofSegmentTrim, ROOF_SHAPE_DEFAULTS, useScene, } from '@pascal-app/core';
|
|
4
|
+
import { ActionButton, ActionGroup, duplicateNodeAndPickUp, PanelSection, PanelWrapper, SegmentedControl, SliderControl, ToggleControl, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { Check, Copy, Move, Pencil, RotateCcw, Trash2 } from 'lucide-react';
|
|
7
7
|
import { useCallback } from 'react';
|
|
@@ -146,28 +146,9 @@ export default function RoofSegmentPanel() {
|
|
|
146
146
|
}
|
|
147
147
|
}, [node, setRoofHostDragArmedId, setSelection, updateNode]);
|
|
148
148
|
const handleDuplicate = useCallback(() => {
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
let duplicateInfo = structuredClone(node);
|
|
153
|
-
delete duplicateInfo.id;
|
|
154
|
-
duplicateInfo.metadata = { ...duplicateInfo.metadata, isNew: true };
|
|
155
|
-
// Offset slightly so it's visible
|
|
156
|
-
duplicateInfo.position = [
|
|
157
|
-
duplicateInfo.position[0] + 1,
|
|
158
|
-
duplicateInfo.position[1],
|
|
159
|
-
duplicateInfo.position[2] + 1,
|
|
160
|
-
];
|
|
161
|
-
try {
|
|
162
|
-
const duplicate = RoofSegmentNodeSchema.parse(duplicateInfo);
|
|
163
|
-
useScene.getState().createNode(duplicate, duplicate.parentId);
|
|
164
|
-
setSelection({ selectedIds: [] });
|
|
165
|
-
setMovingNode(duplicate);
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
console.error('Failed to duplicate roof segment', e);
|
|
169
|
-
}
|
|
170
|
-
}, [node, setSelection, setMovingNode]);
|
|
149
|
+
if (node)
|
|
150
|
+
duplicateNodeAndPickUp(node);
|
|
151
|
+
}, [node]);
|
|
171
152
|
const handleMove = useCallback(() => {
|
|
172
153
|
if (node) {
|
|
173
154
|
triggerSFX('sfx:item-pick');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/roof-segment/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/roof-segment/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;AAczB,eAAO,MAAM,mBAAmB,GAAI,UAAU;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,gCAyHtE,CAAA;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { getEffectiveRoofSurfaceMaterial, getEffectiveSegmentSurfaceMaterial, useRegistry, useScene, } from '@pascal-app/core';
|
|
4
|
-
import { createMaterial,
|
|
5
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
4
|
+
import { createMaterial, getRoofMaterialArray, levelWallCladdingRef, resolveMaterialRef, useNodeEvents, useViewer, } from '@pascal-app/viewer';
|
|
5
|
+
import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
|
|
6
6
|
import * as THREE from 'three';
|
|
7
7
|
import { getRoofDebugMaterials, getRoofMaterials } from '../roof/roof-materials';
|
|
8
8
|
import { createPlaceholderGeometry } from '../shared/placeholder-geometry';
|
|
9
9
|
export const RoofSegmentRenderer = ({ node }) => {
|
|
10
10
|
const ref = useRef(null);
|
|
11
11
|
const nodes = useScene((state) => state.nodes);
|
|
12
|
+
const sceneMaterials = useScene((state) => state.materials);
|
|
12
13
|
useRegistry(node.id, 'roof-segment', ref);
|
|
14
|
+
// The renderer loads lazily, so the scene-load dirty mark can be consumed
|
|
15
|
+
// before this mesh registers. A painted segment is built only from its own
|
|
16
|
+
// mesh (the merged shell skips it), so it would keep its empty placeholder.
|
|
17
|
+
useLayoutEffect(() => {
|
|
18
|
+
useScene.getState().markDirty(node.id);
|
|
19
|
+
}, [node.id]);
|
|
13
20
|
const handlers = useNodeEvents(node, 'roof-segment');
|
|
14
21
|
const debugColors = useViewer((s) => s.debugColors);
|
|
15
22
|
const shading = useViewer((s) => s.shading);
|
|
@@ -33,16 +40,16 @@ export const RoofSegmentRenderer = ({ node }) => {
|
|
|
33
40
|
// slot 1 → 'wall' (deck top & shingle eave bands)
|
|
34
41
|
// slot 2 → 'wall' (interior)
|
|
35
42
|
// slot 3 → 'top' (shingle / roof surface)
|
|
43
|
+
// The gable band is clad like the walls below it (their assemblies).
|
|
44
|
+
const wallCladdingRef = useScene((state) => parentNode ? levelWallCladdingRef(state.nodes, parentNode) : null);
|
|
36
45
|
// biome-ignore lint/correctness/useExhaustiveDependencies: deps deliberately list the build inputs; depending on the whole object would rebuild on unrelated field changes.
|
|
37
46
|
const customMaterial = useMemo(() => {
|
|
38
47
|
const resolveSlot = (role) => {
|
|
39
48
|
const parentSpec = parentNode ? getEffectiveRoofSurfaceMaterial(parentNode, role) : undefined;
|
|
40
49
|
const spec = getEffectiveSegmentSurfaceMaterial(node, role, parentSpec);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return resolved;
|
|
45
|
-
}
|
|
50
|
+
const resolved = resolveMaterialRef(spec.materialPreset, sceneMaterials, shading);
|
|
51
|
+
if (resolved)
|
|
52
|
+
return resolved;
|
|
46
53
|
if (spec.material !== undefined) {
|
|
47
54
|
return createMaterial(spec.material, shading);
|
|
48
55
|
}
|
|
@@ -51,7 +58,7 @@ export const RoofSegmentRenderer = ({ node }) => {
|
|
|
51
58
|
// Themed parent-roof array (per-role scene-theme colours) — used both as the
|
|
52
59
|
// full fallback and to fill any individual untextured slot below.
|
|
53
60
|
const themedArray = parentNode
|
|
54
|
-
? getRoofMaterialArray(parentNode, shading, textures, colorPreset, sceneTheme)
|
|
61
|
+
? getRoofMaterialArray(parentNode, shading, textures, colorPreset, sceneTheme, wallCladdingRef, sceneMaterials)
|
|
55
62
|
: null;
|
|
56
63
|
const edge = resolveSlot('edge');
|
|
57
64
|
const wall = resolveSlot('wall');
|
|
@@ -71,10 +78,12 @@ export const RoofSegmentRenderer = ({ node }) => {
|
|
|
71
78
|
node.topMaterial,
|
|
72
79
|
node.topMaterialPreset,
|
|
73
80
|
node.edgeMaterial,
|
|
81
|
+
wallCladdingRef,
|
|
74
82
|
node.edgeMaterialPreset,
|
|
75
83
|
node.wallMaterial,
|
|
76
84
|
node.wallMaterialPreset,
|
|
77
85
|
parentNode,
|
|
86
|
+
sceneMaterials,
|
|
78
87
|
shading,
|
|
79
88
|
textures,
|
|
80
89
|
colorPreset,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/separator/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErE,eAAO,MAAM,mBAAmB,EAAE,cAAc,CAAC,OAAO,aAAa,CAqCpE,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { SeparatorNode } from '@pascal-app/core';
|
|
2
|
+
export const separatorDefinition = {
|
|
3
|
+
kind: 'separator',
|
|
4
|
+
bake: 'strip',
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
schema: SeparatorNode,
|
|
7
|
+
category: 'structure',
|
|
8
|
+
defaults: () => {
|
|
9
|
+
const { id: _id, type: _type, ...rest } = SeparatorNode.parse({ start: [0, 0], end: [1, 0] });
|
|
10
|
+
return rest;
|
|
11
|
+
},
|
|
12
|
+
capabilities: {
|
|
13
|
+
selectable: { hitVolume: 'bbox' },
|
|
14
|
+
duplicable: false,
|
|
15
|
+
deletable: true,
|
|
16
|
+
presettable: false,
|
|
17
|
+
},
|
|
18
|
+
dirtyTracking: false,
|
|
19
|
+
rendersChildren: false,
|
|
20
|
+
renderer: { kind: 'parametric', module: () => import('./renderer') },
|
|
21
|
+
floorplan: (node) => ({
|
|
22
|
+
kind: 'line',
|
|
23
|
+
x1: node.start[0],
|
|
24
|
+
y1: node.start[1],
|
|
25
|
+
x2: node.end[0],
|
|
26
|
+
y2: node.end[1],
|
|
27
|
+
stroke: '#818cf8',
|
|
28
|
+
strokeWidth: 2,
|
|
29
|
+
strokeDasharray: '6 4',
|
|
30
|
+
vectorEffect: 'non-scaling-stroke',
|
|
31
|
+
pointerEvents: 'stroke',
|
|
32
|
+
}),
|
|
33
|
+
presentation: {
|
|
34
|
+
icon: { kind: 'iconify', name: 'lucide:split' },
|
|
35
|
+
label: 'Separator',
|
|
36
|
+
hidden: true,
|
|
37
|
+
actionMenu: false,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/separator/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAyB,MAAM,kBAAkB,CAAA;AAU5E,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,+BAgD1E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRegistry, useScene } from '@pascal-app/core';
|
|
4
|
+
import { useEditor } from '@pascal-app/editor';
|
|
5
|
+
import { useNodeEvents, useViewer } from '@pascal-app/viewer';
|
|
6
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
7
|
+
import { BufferGeometry, Float32BufferAttribute } from 'three';
|
|
8
|
+
import { LineBasicNodeMaterial, MeshBasicNodeMaterial } from 'three/webgpu';
|
|
9
|
+
const separatorMaterial = new LineBasicNodeMaterial({ color: '#818cf8', depthWrite: false });
|
|
10
|
+
const hitMaterial = new MeshBasicNodeMaterial({ transparent: true, opacity: 0, depthWrite: false });
|
|
11
|
+
export default function SeparatorRenderer({ node }) {
|
|
12
|
+
const ref = useRef(null);
|
|
13
|
+
useRegistry(node.id, 'separator', ref);
|
|
14
|
+
const roomId = useEditor((s) => s.room?.zoneId);
|
|
15
|
+
const viewerRoomId = useViewer((s) => s.selection.zoneId);
|
|
16
|
+
const zone = useScene((s) => {
|
|
17
|
+
const id = roomId ?? viewerRoomId;
|
|
18
|
+
return id ? s.nodes[id] : undefined;
|
|
19
|
+
});
|
|
20
|
+
const visible = zone?.type === 'zone' && zone.boundarySeparatorIds.includes(node.id);
|
|
21
|
+
const events = useNodeEvents(node, 'separator');
|
|
22
|
+
const y = zone?.type === 'zone' ? (zone.floor?.elevation ?? 0.05) + 0.02 : 0.07;
|
|
23
|
+
const dx = node.end[0] - node.start[0], dz = node.end[1] - node.start[1];
|
|
24
|
+
const length = Math.hypot(dx, dz);
|
|
25
|
+
const geometry = useMemo(() => {
|
|
26
|
+
const positions = [];
|
|
27
|
+
if (Number.isFinite(length)) {
|
|
28
|
+
for (let distance = 0; distance < length; distance += 0.25) {
|
|
29
|
+
positions.push(distance, 0, 0, Math.min(distance + 0.15, length), 0, 0);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return new BufferGeometry().setAttribute('position', new Float32BufferAttribute(positions, 3));
|
|
33
|
+
}, [length]);
|
|
34
|
+
useEffect(() => () => geometry.dispose(), [geometry]);
|
|
35
|
+
return (_jsx("group", { ref: ref, visible: visible, children: visible && (_jsxs(_Fragment, { children: [_jsx("lineSegments", { geometry: geometry, material: separatorMaterial, position: [node.start[0], y, node.start[1]], rotation: [0, -Math.atan2(dz, dx), 0], raycast: () => { } }), _jsx("mesh", { ...events, material: hitMaterial, position: [(node.start[0] + node.end[0]) / 2, y, (node.start[1] + node.end[1]) / 2], rotation: [0, -Math.atan2(dz, dx), 0], children: _jsx("boxGeometry", { args: [length, 0.03, 0.1] }) })] })) }));
|
|
36
|
+
}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import type { SlotDeclaration } from '@pascal-app/core';
|
|
2
|
-
export declare const DUCT_BODY_SLOT_ID = "body";
|
|
3
|
-
export declare const DUCT_BODY_SLOT_DEFAULT = "#ffffff";
|
|
4
|
-
export declare function ductBodySlots(): SlotDeclaration[];
|
|
5
1
|
export declare const ductBodyPaint: import("@pascal-app/core").PaintCapability;
|
|
6
2
|
//# sourceMappingURL=duct-body-paint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duct-body-paint.d.ts","sourceRoot":"","sources":["../../src/shared/duct-body-paint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"duct-body-paint.d.ts","sourceRoot":"","sources":["../../src/shared/duct-body-paint.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,4CAMxB,CAAA"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
+
import { DUCT_BODY_SLOT_ID } from '@pascal-app/core';
|
|
1
2
|
import { createSlotPaintCapability, previewGeometrySlot } from './slot-paint';
|
|
2
|
-
export const DUCT_BODY_SLOT_ID = 'body';
|
|
3
|
-
export const DUCT_BODY_SLOT_DEFAULT = '#ffffff';
|
|
4
|
-
export function ductBodySlots() {
|
|
5
|
-
return [{ slotId: DUCT_BODY_SLOT_ID, label: 'Body', default: DUCT_BODY_SLOT_DEFAULT }];
|
|
6
|
-
}
|
|
7
3
|
export const ductBodyPaint = createSlotPaintCapability({
|
|
8
4
|
resolveRole: ({ hitObject }) => {
|
|
9
5
|
const slotId = hitObject?.userData?.slotId;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The light switch for a single selected item or procedural item. Play/Stop
|
|
3
|
+
* comes from the action menu's `capabilities.mechanism` button.
|
|
4
|
+
*/
|
|
5
|
+
export default function ItemInteractionActions(): import("react").JSX.Element | null;
|
|
6
|
+
//# sourceMappingURL=item-interaction-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-interaction-actions.d.ts","sourceRoot":"","sources":["../../src/shared/item-interaction-actions.tsx"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,uCAsB7C"}
|