@pascal-app/nodes 1.0.0 → 1.0.3
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 +4 -1
- package/dist/block/face-host.d.ts.map +1 -1
- package/dist/block/face-host.js +19 -2
- package/dist/block/hosted-edit.d.ts +13 -0
- package/dist/block/hosted-edit.d.ts.map +1 -0
- package/dist/block/hosted-edit.js +205 -0
- package/dist/block/last-operation.d.ts +1 -1
- package/dist/block/last-operation.d.ts.map +1 -1
- package/dist/block/last-operation.js +6 -4
- package/dist/block/modal-session.d.ts +2 -1
- package/dist/block/modal-session.d.ts.map +1 -1
- package/dist/block/modal-session.js +2 -2
- package/dist/block/selection.d.ts.map +1 -1
- package/dist/block/selection.js +82 -24
- package/dist/block/surface.d.ts +4 -0
- package/dist/block/surface.d.ts.map +1 -0
- package/dist/block/surface.js +54 -0
- package/dist/block/use-block-face-operation.d.ts +2 -2
- package/dist/block/use-block-face-operation.d.ts.map +1 -1
- package/dist/block/use-block-face-operation.js +25 -11
- package/dist/box-vent/definition.d.ts.map +1 -1
- package/dist/box-vent/definition.js +1 -0
- package/dist/box-vent/panel.js +4 -4
- package/dist/building/renderer.d.ts.map +1 -1
- package/dist/building/renderer.js +1 -1
- package/dist/cabinet/appliance-layout.d.ts +26 -0
- package/dist/cabinet/appliance-layout.d.ts.map +1 -0
- package/dist/cabinet/appliance-layout.js +52 -0
- package/dist/cabinet/countertop-layout.d.ts +173 -0
- package/dist/cabinet/countertop-layout.d.ts.map +1 -0
- package/dist/cabinet/countertop-layout.js +80 -0
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +17 -8
- package/dist/cabinet/geometry/cooktop.d.ts.map +1 -1
- package/dist/cabinet/geometry/cooktop.js +2 -2
- package/dist/cabinet/geometry/run.d.ts.map +1 -1
- package/dist/cabinet/geometry/run.js +10 -71
- package/dist/cabinet/geometry/sink.d.ts +2 -12
- package/dist/cabinet/geometry/sink.d.ts.map +1 -1
- package/dist/cabinet/geometry/sink.js +8 -39
- package/dist/cabinet/hosted-resize.d.ts +5 -0
- package/dist/cabinet/hosted-resize.d.ts.map +1 -0
- package/dist/cabinet/hosted-resize.js +14 -0
- package/dist/cabinet/placement-snap.d.ts.map +1 -1
- package/dist/cabinet/placement-snap.js +4 -2
- package/dist/cabinet/run-layout.d.ts +8 -1
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +22 -14
- package/dist/cabinet/run-ops.d.ts +3 -3
- package/dist/cabinet/run-ops.js +3 -3
- package/dist/cabinet/run-panel.d.ts +1 -1
- package/dist/cabinet/run-panel.d.ts.map +1 -1
- package/dist/cabinet/run-panel.js +16 -7
- package/dist/cabinet/surfaces.d.ts +5 -0
- package/dist/cabinet/surfaces.d.ts.map +1 -0
- package/dist/cabinet/surfaces.js +113 -0
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +8 -4
- package/dist/cabinet/tree-structure.d.ts.map +1 -1
- package/dist/cabinet/tree-structure.js +10 -9
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +6 -1
- package/dist/ceiling/floorplan-affordances.d.ts +4 -4
- package/dist/ceiling/panel.js +1 -1
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +3 -2
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +1 -0
- package/dist/chimney/panel.js +9 -9
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +10 -3
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +6 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +23 -11
- package/dist/column/hosted-resize.d.ts +116 -0
- package/dist/column/hosted-resize.d.ts.map +1 -0
- package/dist/column/hosted-resize.js +9 -0
- package/dist/column/panel.d.ts.map +1 -1
- package/dist/column/panel.js +6 -3
- package/dist/column/renderer.d.ts.map +1 -1
- package/dist/column/renderer.js +25 -103
- package/dist/column/shape.d.ts +22 -0
- package/dist/column/shape.d.ts.map +1 -0
- package/dist/column/shape.js +120 -0
- package/dist/column/surface.d.ts +4 -0
- package/dist/column/surface.d.ts.map +1 -0
- package/dist/column/surface.js +66 -0
- package/dist/cupola/definition.d.ts.map +1 -1
- package/dist/cupola/definition.js +1 -0
- package/dist/cupola/panel.js +1 -1
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +40 -1
- package/dist/door/door-math.d.ts +1 -1
- package/dist/door/door-math.d.ts.map +1 -1
- package/dist/door/door-math.js +7 -10
- package/dist/door/floorplan-affordances.d.ts.map +1 -1
- package/dist/door/floorplan-affordances.js +8 -12
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +3 -4
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +28 -57
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +20 -2
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +1 -0
- package/dist/dormer/panel-position-section.js +2 -2
- package/dist/dormer/panel.js +1 -1
- package/dist/downspout/definition.d.ts.map +1 -1
- package/dist/downspout/definition.js +1 -0
- package/dist/duct-segment/parametrics.d.ts.map +1 -1
- package/dist/duct-segment/parametrics.js +5 -1
- package/dist/duct-segment/tool.d.ts +1 -0
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +21 -8
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +77 -8
- package/dist/elevator/definition.d.ts.map +1 -1
- package/dist/elevator/definition.js +2 -0
- package/dist/elevator/parametrics.d.ts.map +1 -1
- package/dist/elevator/parametrics.js +98 -1
- package/dist/eyebrow-vent/definition.d.ts.map +1 -1
- package/dist/eyebrow-vent/definition.js +1 -0
- package/dist/eyebrow-vent/panel.js +1 -1
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +1 -0
- package/dist/fence/inspector-editors.js +1 -1
- package/dist/fence/tool.js +2 -2
- package/dist/guide/definition.d.ts.map +1 -1
- package/dist/guide/definition.js +1 -0
- package/dist/gutter/definition.d.ts.map +1 -1
- package/dist/gutter/definition.js +1 -0
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +8 -2
- package/dist/imported-mesh/definition.d.ts +5 -0
- package/dist/imported-mesh/definition.d.ts.map +1 -0
- package/dist/imported-mesh/definition.js +38 -0
- package/dist/imported-mesh/floorplan.d.ts +4 -0
- package/dist/imported-mesh/floorplan.d.ts.map +1 -0
- package/dist/imported-mesh/floorplan.js +34 -0
- package/dist/imported-mesh/geometry.d.ts +5 -0
- package/dist/imported-mesh/geometry.d.ts.map +1 -0
- package/dist/imported-mesh/geometry.js +34 -0
- package/dist/imported-mesh/index.d.ts +4 -0
- package/dist/imported-mesh/index.d.ts.map +1 -0
- package/dist/imported-mesh/index.js +3 -0
- package/dist/imported-mesh/schema.d.ts +2 -0
- package/dist/imported-mesh/schema.d.ts.map +1 -0
- package/dist/imported-mesh/schema.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/item/__fixtures__/main-floorplan.d.ts +26 -0
- package/dist/item/__fixtures__/main-floorplan.d.ts.map +1 -0
- package/dist/item/__fixtures__/main-floorplan.js +297 -0
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +3 -1
- package/dist/item/floorplan-move.d.ts +9 -1
- package/dist/item/floorplan-move.d.ts.map +1 -1
- package/dist/item/floorplan-move.js +231 -99
- package/dist/item/floorplan.d.ts +22 -0
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +72 -2
- package/dist/item/move-tool.d.ts +1 -1
- package/dist/item/move-tool.d.ts.map +1 -1
- package/dist/item/move-tool.js +15 -7
- package/dist/item/panel.js +1 -1
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +8 -2
- package/dist/level/renderer.js +1 -1
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +1 -0
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +5 -1
- package/dist/measurement/definition.d.ts.map +1 -1
- package/dist/measurement/definition.js +1 -0
- package/dist/pipe-segment/parametrics.d.ts.map +1 -1
- package/dist/pipe-segment/parametrics.js +5 -1
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +14 -3
- package/dist/pipe-trap/tool.d.ts.map +1 -1
- package/dist/pipe-trap/tool.js +7 -8
- package/dist/procedural-item/definition.d.ts +4 -0
- package/dist/procedural-item/definition.d.ts.map +1 -0
- package/dist/procedural-item/definition.js +257 -0
- package/dist/procedural-item/geometry.d.ts +31 -0
- package/dist/procedural-item/geometry.d.ts.map +1 -0
- package/dist/procedural-item/geometry.js +88 -0
- package/dist/procedural-item/index.d.ts +3 -0
- package/dist/procedural-item/index.d.ts.map +1 -0
- package/dist/procedural-item/index.js +2 -0
- package/dist/procedural-item/move-session.d.ts +15 -0
- package/dist/procedural-item/move-session.d.ts.map +1 -0
- package/dist/procedural-item/move-session.js +197 -0
- package/dist/procedural-item/move-tool.d.ts +5 -0
- package/dist/procedural-item/move-tool.d.ts.map +1 -0
- package/dist/procedural-item/move-tool.js +193 -0
- package/dist/procedural-item/renderer.d.ts +5 -0
- package/dist/procedural-item/renderer.d.ts.map +1 -0
- package/dist/procedural-item/renderer.js +66 -0
- package/dist/ridge-vent/definition.d.ts.map +1 -1
- package/dist/ridge-vent/definition.js +1 -0
- package/dist/ridge-vent/panel.js +4 -4
- package/dist/roof/definition.d.ts.map +1 -1
- package/dist/roof/definition.js +4 -1
- package/dist/roof/panel-model.d.ts +4 -0
- package/dist/roof/panel-model.d.ts.map +1 -0
- package/dist/roof/panel-model.js +151 -0
- package/dist/roof/panel.d.ts.map +1 -1
- package/dist/roof/panel.js +9 -8
- package/dist/roof/parametrics.d.ts.map +1 -1
- package/dist/roof/parametrics.js +16 -1
- package/dist/roof-segment/definition.d.ts.map +1 -1
- package/dist/roof-segment/definition.js +1 -0
- package/dist/roof-segment/panel.d.ts.map +1 -1
- package/dist/roof-segment/panel.js +5 -5
- package/dist/roof-segment/parametrics.d.ts.map +1 -1
- package/dist/roof-segment/parametrics.js +176 -1
- package/dist/scan/definition.d.ts.map +1 -1
- package/dist/scan/definition.js +1 -0
- package/dist/shared/automatic-run-end-cap.d.ts +1 -0
- package/dist/shared/automatic-run-end-cap.d.ts.map +1 -1
- package/dist/shared/automatic-run-end-cap.js +10 -0
- package/dist/shared/commit-opening-move.d.ts +4 -0
- package/dist/shared/commit-opening-move.d.ts.map +1 -0
- package/dist/shared/commit-opening-move.js +9 -0
- package/dist/shared/curtain-opening-limits.d.ts +14 -0
- package/dist/shared/curtain-opening-limits.d.ts.map +1 -0
- package/dist/shared/curtain-opening-limits.js +53 -0
- package/dist/shared/distribution-run-tool.d.ts +10 -0
- package/dist/shared/distribution-run-tool.d.ts.map +1 -1
- package/dist/shared/distribution-run-tool.js +56 -11
- package/dist/shared/draft-axis-guides.d.ts +0 -6
- package/dist/shared/draft-axis-guides.d.ts.map +1 -1
- package/dist/shared/draft-axis-guides.js +1 -8
- package/dist/shared/hosted-resize.d.ts +12 -0
- package/dist/shared/hosted-resize.d.ts.map +1 -0
- package/dist/shared/hosted-resize.js +166 -0
- package/dist/shared/opening-grid-follow.d.ts +8 -0
- package/dist/shared/opening-grid-follow.d.ts.map +1 -0
- package/dist/shared/opening-grid-follow.js +12 -0
- package/dist/shared/opening-property-preview-host.d.ts +3 -0
- package/dist/shared/opening-property-preview-host.d.ts.map +1 -0
- package/dist/shared/opening-property-preview-host.js +21 -0
- package/dist/shared/opening-property-preview.d.ts +19 -0
- package/dist/shared/opening-property-preview.d.ts.map +1 -0
- package/dist/shared/opening-property-preview.js +99 -0
- package/dist/shared/panel-fields.d.ts +15 -0
- package/dist/shared/panel-fields.d.ts.map +1 -0
- package/dist/shared/panel-fields.js +31 -0
- package/dist/shared/resting-surface-plan.d.ts +4 -0
- package/dist/shared/resting-surface-plan.d.ts.map +1 -0
- package/dist/shared/resting-surface-plan.js +53 -0
- package/dist/shared/surface-counterparts.d.ts +12 -0
- package/dist/shared/surface-counterparts.d.ts.map +1 -0
- package/dist/shared/surface-counterparts.js +27 -0
- package/dist/shared/wall-attach-target.d.ts +1 -0
- package/dist/shared/wall-attach-target.d.ts.map +1 -1
- package/dist/shared/wall-attach-target.js +4 -1
- package/dist/shared/wall-event-from-grid.d.ts +5 -0
- package/dist/shared/wall-event-from-grid.d.ts.map +1 -0
- package/dist/shared/wall-event-from-grid.js +36 -0
- package/dist/shelf/definition.d.ts.map +1 -1
- package/dist/shelf/definition.js +5 -2
- package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
- package/dist/shelf/floorplan-affordances.js +5 -3
- package/dist/shelf/floorplan-move.d.ts.map +1 -1
- package/dist/shelf/floorplan-move.js +3 -2
- package/dist/shelf/floorplan.d.ts.map +1 -1
- package/dist/shelf/floorplan.js +9 -2
- package/dist/shelf/geometry.d.ts.map +1 -1
- package/dist/shelf/geometry.js +2 -10
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +9 -2
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +1 -0
- package/dist/skylight/panel.js +6 -6
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +4 -0
- package/dist/slab/panel.js +1 -1
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +1 -0
- package/dist/solar-panel/panel.js +2 -2
- package/dist/spawn/definition.d.ts.map +1 -1
- package/dist/spawn/definition.js +1 -0
- package/dist/spawn/panel.js +1 -1
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +2 -0
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +9 -7
- package/dist/stair/parametrics.d.ts.map +1 -1
- package/dist/stair/parametrics.js +164 -1
- package/dist/stair-segment/definition.d.ts.map +1 -1
- package/dist/stair-segment/definition.js +1 -0
- package/dist/stair-segment/panel.js +4 -4
- package/dist/stair-segment/parametrics.d.ts.map +1 -1
- package/dist/stair-segment/parametrics.js +81 -1
- package/dist/turbine-vent/definition.d.ts.map +1 -1
- package/dist/turbine-vent/definition.js +1 -0
- package/dist/turbine-vent/panel.js +1 -1
- package/dist/unit/definition.d.ts +10 -0
- package/dist/unit/definition.d.ts.map +1 -0
- package/dist/unit/definition.js +38 -0
- package/dist/unit/index.d.ts +2 -0
- package/dist/unit/index.d.ts.map +1 -0
- package/dist/unit/index.js +1 -0
- package/dist/unit/parametrics.d.ts +3 -0
- package/dist/unit/parametrics.d.ts.map +1 -0
- package/dist/unit/parametrics.js +4 -0
- package/dist/unit/schema.d.ts +2 -0
- package/dist/unit/schema.d.ts.map +1 -0
- package/dist/unit/schema.js +1 -0
- package/dist/unit/unit-panel.d.ts +5 -0
- package/dist/unit/unit-panel.d.ts.map +1 -0
- package/dist/unit/unit-panel.js +61 -0
- package/dist/wall/actions.d.ts +3 -0
- package/dist/wall/actions.d.ts.map +1 -0
- package/dist/wall/actions.js +56 -0
- package/dist/wall/curtain-opening-frame.d.ts +14 -0
- package/dist/wall/curtain-opening-frame.d.ts.map +1 -0
- package/dist/wall/curtain-opening-frame.js +111 -0
- package/dist/wall/curtain-panel-highlight.d.ts +3 -0
- package/dist/wall/curtain-panel-highlight.d.ts.map +1 -0
- package/dist/wall/curtain-panel-highlight.js +113 -0
- package/dist/wall/curtain-wall-adapter.d.ts +3 -0
- package/dist/wall/curtain-wall-adapter.d.ts.map +1 -0
- package/dist/wall/curtain-wall-adapter.js +55 -0
- package/dist/wall/curtain-wall-floorplan.d.ts +3 -0
- package/dist/wall/curtain-wall-floorplan.d.ts.map +1 -0
- package/dist/wall/curtain-wall-floorplan.js +91 -0
- package/dist/wall/curtain-wall-geometry.d.ts +4 -0
- package/dist/wall/curtain-wall-geometry.d.ts.map +1 -0
- package/dist/wall/curtain-wall-geometry.js +226 -0
- package/dist/wall/curtain-wall-layout.d.ts +16 -0
- package/dist/wall/curtain-wall-layout.d.ts.map +1 -0
- package/dist/wall/curtain-wall-layout.js +176 -0
- package/dist/wall/curtain-wall-materials.d.ts +5 -0
- package/dist/wall/curtain-wall-materials.d.ts.map +1 -0
- package/dist/wall/curtain-wall-materials.js +55 -0
- package/dist/wall/curtain-wall-panel.d.ts +14 -0
- package/dist/wall/curtain-wall-panel.d.ts.map +1 -0
- package/dist/wall/curtain-wall-panel.js +167 -0
- package/dist/wall/curtain-wall-piece-geometry.d.ts +5 -0
- package/dist/wall/curtain-wall-piece-geometry.d.ts.map +1 -0
- package/dist/wall/curtain-wall-piece-geometry.js +220 -0
- package/dist/wall/curtain-wall-shadow.d.ts +4 -0
- package/dist/wall/curtain-wall-shadow.d.ts.map +1 -0
- package/dist/wall/curtain-wall-shadow.js +15 -0
- package/dist/wall/definition.d.ts +0 -15
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +65 -4
- package/dist/wall/drawing-mode.d.ts +12 -0
- package/dist/wall/drawing-mode.d.ts.map +1 -0
- package/dist/wall/drawing-mode.js +38 -0
- package/dist/wall/floorplan-tool.d.ts +4 -0
- package/dist/wall/floorplan-tool.d.ts.map +1 -0
- package/dist/wall/floorplan-tool.js +107 -0
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +6 -2
- package/dist/wall/length-patch.d.ts +3 -0
- package/dist/wall/length-patch.d.ts.map +1 -0
- package/dist/wall/length-patch.js +14 -0
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +23 -1
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +39 -4
- package/dist/wall/panel-model.d.ts +4 -0
- package/dist/wall/panel-model.d.ts.map +1 -0
- package/dist/wall/panel-model.js +117 -0
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +20 -24
- package/dist/wall/property-preview.d.ts +7 -0
- package/dist/wall/property-preview.d.ts.map +1 -0
- package/dist/wall/property-preview.js +31 -0
- package/dist/wall/rectangle-command.d.ts +149 -0
- package/dist/wall/rectangle-command.d.ts.map +1 -0
- package/dist/wall/rectangle-command.js +22 -0
- package/dist/wall/rectangle-tool.d.ts +2 -0
- package/dist/wall/rectangle-tool.d.ts.map +1 -0
- package/dist/wall/rectangle-tool.js +147 -0
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +7 -4
- package/dist/wall/slots.d.ts +2 -2
- package/dist/wall/slots.d.ts.map +1 -1
- package/dist/wall/slots.js +10 -2
- package/dist/wall/split-floorplan-layer.d.ts +4 -0
- package/dist/wall/split-floorplan-layer.d.ts.map +1 -0
- package/dist/wall/split-floorplan-layer.js +71 -0
- package/dist/wall/split-pointer.d.ts +3 -0
- package/dist/wall/split-pointer.d.ts.map +1 -0
- package/dist/wall/split-pointer.js +95 -0
- package/dist/wall/split-preview.d.ts +55 -0
- package/dist/wall/split-preview.d.ts.map +1 -0
- package/dist/wall/split-preview.js +106 -0
- package/dist/wall/split-session.d.ts +16 -0
- package/dist/wall/split-session.d.ts.map +1 -0
- package/dist/wall/split-session.js +138 -0
- package/dist/wall/split-store.d.ts +16 -0
- package/dist/wall/split-store.d.ts.map +1 -0
- package/dist/wall/split-store.js +6 -0
- package/dist/wall/split-tool.d.ts +10 -0
- package/dist/wall/split-tool.d.ts.map +1 -0
- package/dist/wall/split-tool.js +95 -0
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +3 -1
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +14 -6
- package/dist/wall/wall-batch-system.d.ts.map +1 -1
- package/dist/wall/wall-batch-system.js +3 -0
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +48 -1
- package/dist/window/floorplan-affordances.d.ts.map +1 -1
- package/dist/window/floorplan-affordances.js +8 -10
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +4 -6
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +22 -60
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +34 -2
- package/dist/window/window-math.d.ts +1 -1
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +8 -11
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +8 -1
- package/dist/zone/floorplan.d.ts +1 -3
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +43 -28
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +32 -44
- package/dist/zone/renderer.d.ts.map +1 -1
- package/dist/zone/renderer.js +21 -7
- package/dist/zone/unit-membership.d.ts +12 -0
- package/dist/zone/unit-membership.d.ts.map +1 -0
- package/dist/zone/unit-membership.js +22 -0
- package/package.json +15 -9
- package/dist/shared/opening-documentation-fields.d.ts +0 -16
- package/dist/shared/opening-documentation-fields.d.ts.map +0 -1
- package/dist/shared/opening-documentation-fields.js +0 -54
package/dist/door/move-tool.js
CHANGED
|
@@ -5,6 +5,7 @@ import { useViewer } from '@pascal-app/viewer';
|
|
|
5
5
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { BoxGeometry, EdgesGeometry, Vector3 } from 'three';
|
|
7
7
|
import { LineBasicNodeMaterial } from 'three/webgpu';
|
|
8
|
+
import { commitOpeningMove } from '../shared/commit-opening-move';
|
|
8
9
|
import { clearOpeningGuides3D, publishOpeningGuidesForWallEvent, } from '../shared/opening-guides-runtime';
|
|
9
10
|
import { beginOpeningMoveHistorySession } from '../shared/opening-move-history';
|
|
10
11
|
import { isWallMeshHidden, shouldIgnoreWallEventForOpeningMove, } from '../shared/opening-move-wall-gate';
|
|
@@ -451,14 +452,13 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
|
|
|
451
452
|
visible: original.visible,
|
|
452
453
|
});
|
|
453
454
|
history.commitStep(() => {
|
|
454
|
-
|
|
455
|
+
commitOpeningMove(movingDoorNode.id, {
|
|
455
456
|
position: [target.clampedX, target.clampedY, 0],
|
|
456
457
|
rotation: [0, target.itemRotation, 0],
|
|
457
458
|
side: target.side,
|
|
458
459
|
parentId: target.wallId,
|
|
459
460
|
wallId: target.wallId,
|
|
460
461
|
roofSegmentId: undefined,
|
|
461
|
-
metadata: {},
|
|
462
462
|
visible: true,
|
|
463
463
|
});
|
|
464
464
|
});
|
|
@@ -712,7 +712,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
|
|
|
712
712
|
visible: original.visible,
|
|
713
713
|
});
|
|
714
714
|
history.commitStep(() => {
|
|
715
|
-
|
|
715
|
+
commitOpeningMove(movingDoorNode.id, {
|
|
716
716
|
position: target.position,
|
|
717
717
|
rotation: [0, 0, 0],
|
|
718
718
|
side: 'front',
|
|
@@ -720,7 +720,6 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
|
|
|
720
720
|
wallId: undefined,
|
|
721
721
|
roofSegmentId: segmentId,
|
|
722
722
|
roofFace: target.face.id,
|
|
723
|
-
metadata: {},
|
|
724
723
|
visible: true,
|
|
725
724
|
});
|
|
726
725
|
});
|
package/dist/door/panel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/door/panel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/door/panel.tsx"],"names":[],"mappings":"AAyIA,MAAM,CAAC,OAAO,UAAU,SAAS,uCA+nChC"}
|
package/dist/door/panel.js
CHANGED
|
@@ -4,8 +4,10 @@ import { DoorNode, useInteractive, useScene } from '@pascal-app/core';
|
|
|
4
4
|
import { ActionButton, ActionGroup, cn, PanelSection, PanelWrapper, SegmentedControl, SliderControl, ToggleControl, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { Copy, DoorOpen, FlipHorizontal2, Move, Trash2 } from 'lucide-react';
|
|
7
|
-
import { useCallback,
|
|
8
|
-
import {
|
|
7
|
+
import { useCallback, useEffect, useMemo } from 'react';
|
|
8
|
+
import { constrainCurtainOpening, curtainOpeningLimits } from '../shared/curtain-opening-limits';
|
|
9
|
+
import { createOpeningPropertyPreview } from '../shared/opening-property-preview';
|
|
10
|
+
import { openingPropertyPreviewHost } from '../shared/opening-property-preview-host';
|
|
9
11
|
import { scaleHandleHeight } from './door-math';
|
|
10
12
|
const doorTypeOptions = [
|
|
11
13
|
{ label: 'Hinged', value: 'hinged', available: true },
|
|
@@ -106,7 +108,10 @@ export default function DoorPanel() {
|
|
|
106
108
|
const setSelection = useViewer((s) => s.setSelection);
|
|
107
109
|
const deleteNode = useScene((s) => s.deleteNode);
|
|
108
110
|
const setMovingNode = useEditor((s) => s.setMovingNode);
|
|
109
|
-
const
|
|
111
|
+
const preview = useMemo(() => selectedId
|
|
112
|
+
? createOpeningPropertyPreview(selectedId, openingPropertyPreviewHost)
|
|
113
|
+
: null, [selectedId]);
|
|
114
|
+
useEffect(() => () => preview?.cancel(), [preview]);
|
|
110
115
|
const node = useScene((s) => selectedId ? s.nodes[selectedId] : undefined);
|
|
111
116
|
// Panel slider-drag fix recipe (plans/editor-node-registry.md). Without
|
|
112
117
|
// it, the 29+ SliderControls in this panel would loop on drag.
|
|
@@ -116,6 +121,7 @@ export default function DoorPanel() {
|
|
|
116
121
|
const liveNode = useScene.getState().nodes[selectedId];
|
|
117
122
|
if (liveNode?.type !== 'door')
|
|
118
123
|
return;
|
|
124
|
+
updates = constrainCurtainOpening(liveNode, updates, useScene.getState().nodes);
|
|
119
125
|
const hasChange = Object.entries(updates).some(([key, value]) => {
|
|
120
126
|
const currentValue = liveNode[key];
|
|
121
127
|
return !isSameDoorValue(currentValue, value);
|
|
@@ -131,43 +137,8 @@ export default function DoorPanel() {
|
|
|
131
137
|
if (liveNode.parentId)
|
|
132
138
|
scene.dirtyNodes.add(liveNode.parentId);
|
|
133
139
|
}, [selectedId]);
|
|
134
|
-
const previewDoorUpdate =
|
|
135
|
-
|
|
136
|
-
return;
|
|
137
|
-
const liveNode = useScene.getState().nodes[selectedId];
|
|
138
|
-
if (liveNode?.type !== 'door')
|
|
139
|
-
return;
|
|
140
|
-
if (!(previewRef.current &&
|
|
141
|
-
previewRef.current.id === selectedId &&
|
|
142
|
-
previewRef.current.key === key)) {
|
|
143
|
-
previewRef.current = {
|
|
144
|
-
id: selectedId,
|
|
145
|
-
key,
|
|
146
|
-
value: liveNode[key],
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
if (isSameDoorValue(liveNode[key], value))
|
|
150
|
-
return;
|
|
151
|
-
liveNode[key] = value;
|
|
152
|
-
useScene.getState().dirtyNodes.add(selectedId);
|
|
153
|
-
}, [selectedId]);
|
|
154
|
-
const commitDoorPreview = useCallback((key, value) => {
|
|
155
|
-
if (!selectedId)
|
|
156
|
-
return;
|
|
157
|
-
const scene = useScene.getState();
|
|
158
|
-
const liveNode = scene.nodes[selectedId];
|
|
159
|
-
const preview = previewRef.current;
|
|
160
|
-
if (liveNode?.type === 'door' && preview?.id === selectedId && preview.key === key) {
|
|
161
|
-
;
|
|
162
|
-
liveNode[key] = preview.value;
|
|
163
|
-
scene.dirtyNodes.add(selectedId);
|
|
164
|
-
}
|
|
165
|
-
previewRef.current = null;
|
|
166
|
-
useScene
|
|
167
|
-
.getState()
|
|
168
|
-
.updateNode(selectedId, { [key]: value });
|
|
169
|
-
scene.dirtyNodes.add(selectedId);
|
|
170
|
-
}, [selectedId]);
|
|
140
|
+
const previewDoorUpdate = (key, value) => preview?.preview({ [key]: value });
|
|
141
|
+
const commitDoorPreview = (key, value) => preview?.commit({ [key]: value });
|
|
171
142
|
const handleClose = useCallback(() => {
|
|
172
143
|
setSelection({ selectedIds: [] });
|
|
173
144
|
}, [setSelection]);
|
|
@@ -254,6 +225,12 @@ export default function DoorPanel() {
|
|
|
254
225
|
};
|
|
255
226
|
if (!(node && node.type === 'door' && selectedId))
|
|
256
227
|
return null;
|
|
228
|
+
const limits = curtainOpeningLimits(node, useScene.getState().nodes);
|
|
229
|
+
const heightUpdates = (height) => ({
|
|
230
|
+
height,
|
|
231
|
+
position: [node.position[0], height / 2, node.position[2]],
|
|
232
|
+
handleHeight: scaleHandleHeight(node.handleHeight, node.height, height),
|
|
233
|
+
});
|
|
257
234
|
const hSum = node.segments.reduce((s, seg) => s + seg.heightRatio, 0);
|
|
258
235
|
const normHeights = node.segments.map((seg) => seg.heightRatio / hSum);
|
|
259
236
|
const isOpening = node.openingKind === 'opening';
|
|
@@ -478,19 +455,13 @@ export default function DoorPanel() {
|
|
|
478
455
|
? 'border-orange-400/60 bg-orange-400/10 text-foreground'
|
|
479
456
|
: 'border-border/50 bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground', !option.available &&
|
|
480
457
|
'cursor-not-allowed opacity-45 hover:bg-[#2C2C2E] hover:text-muted-foreground'), disabled: !option.available, onClick: () => handleUpdate(getDoorTypeUpdates(option.value)), type: "button", children: [_jsx(DoorOpen, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate font-medium", children: option.label })] }, option.value));
|
|
481
|
-
}) }))] }),
|
|
458
|
+
}) }))] }), _jsxs(PanelSection, { title: "Position", children: [_jsx(SliderControl, { label: _jsxs(_Fragment, { children: ["X", _jsx("sub", { className: "ml-[1px] text-[11px] opacity-70", children: "wall" })] }), max: 10, min: -10, onChange: (v) => handleUpdate({ position: [v, node.position[1], node.position[2]] }), precision: 2, step: 0.1, unit: "m", value: node.position[0] }), showFlipSide && (_jsx("div", { className: "px-1 pt-2 pb-1", children: _jsx(ActionButton, { className: "w-full", icon: _jsx(FlipHorizontal2, { className: "h-4 w-4" }), label: "Flip Side", onClick: handleFlip }) }))] }), showFoldSection && (_jsxs(PanelSection, { title: "Fold", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Panels" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ leafCount: v === '2' ? 2 : 4 }), options: [
|
|
482
459
|
{ label: '2', value: '2' },
|
|
483
460
|
{ label: '4', value: '4' },
|
|
484
461
|
], value: node.leafCount === 2 ? '2' : '4' })] }) }), _jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) })] })), showSlideSection && (_jsxs(PanelSection, { title: "Slide", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: doorType === 'pocket' ? 'Pocket' : doorType === 'barn' ? 'Rail' : 'Panel' }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ slideDirection: v }), options: [
|
|
485
462
|
{ label: 'Left', value: 'left' },
|
|
486
463
|
{ label: 'Right', value: 'right' },
|
|
487
|
-
], value: node.slideDirection ?? 'left' })] }) }), _jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) })] })), showGarageSection && (_jsxs(PanelSection, { title: "Garage", children: [_jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) }), isSectionalGarageDoor && (_jsx(SliderControl, { label: "Panels", max: 8, min: 3, onChange: (v) => handleUpdate({ garagePanelCount: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: node.garagePanelCount ?? 4 }))] })), _jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: maxDoorWidth, min: 0.5, onChange: (v) =>
|
|
488
|
-
height: v,
|
|
489
|
-
position: [node.position[0], v / 2, node.position[2]],
|
|
490
|
-
// Keep the handle at the same relative height as the door resizes,
|
|
491
|
-
// matching the height-resize arrow.
|
|
492
|
-
handleHeight: scaleHandleHeight(node.handleHeight, node.height, v),
|
|
493
|
-
}), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(node.height * 100) / 100 })] }), showDoorShapeSection && (_jsxs(PanelSection, { title: "Top Shape", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({
|
|
464
|
+
], value: node.slideDirection ?? 'left' })] }) }), _jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) })] })), showGarageSection && (_jsxs(PanelSection, { title: "Garage", children: [_jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) }), isSectionalGarageDoor && (_jsx(SliderControl, { label: "Panels", max: 8, min: 3, onChange: (v) => handleUpdate({ garagePanelCount: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: node.garagePanelCount ?? 4 }))] })), _jsxs(PanelSection, { title: "Dimensions", children: [limits && (_jsx("p", { className: "text-[11px] text-muted-foreground", children: "Size is limited to the wall, including clearance for the opening frame." })), _jsx(SliderControl, { label: "Width", max: Math.min(maxDoorWidth, limits?.width ?? Infinity), min: Math.min(0.5, limits?.width ?? 0.5), onChange: (v) => previewDoorUpdate('width', v), onCommit: (v) => commitDoorPreview('width', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.01, unit: "m", value: node.width }), _jsx(SliderControl, { label: "Height", max: limits?.height ?? 1000, min: Math.min(1, limits?.height ?? 1), onChange: (v) => preview?.preview(heightUpdates(v)), onCommit: (v) => preview?.commit(heightUpdates(v)), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.01, unit: "m", value: node.height })] }), showDoorShapeSection && (_jsxs(PanelSection, { title: "Top Shape", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({
|
|
494
465
|
openingShape: v,
|
|
495
466
|
...(v === 'rounded'
|
|
496
467
|
? {
|
|
@@ -508,10 +479,10 @@ export default function DoorPanel() {
|
|
|
508
479
|
], value: doorShape }) }), doorShape === 'rounded' && (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ openingRadiusMode: v }), options: [
|
|
509
480
|
{ label: 'All', value: 'all' },
|
|
510
481
|
{ label: 'Individual', value: 'individual' },
|
|
511
|
-
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), precision: 2, step: 0.05, unit: "m", value:
|
|
482
|
+
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: cornerRadius })) : (_jsx(_Fragment, { children: [
|
|
512
483
|
['Top Left', 0],
|
|
513
484
|
['Top Right', 1],
|
|
514
|
-
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), precision: 2, step: 0.05, unit: "m", value:
|
|
485
|
+
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: openingTopRadii[index] ?? 0 }, label))) })), _jsx(SliderControl, { label: "Reveal Radius", max: 0.08, min: 0, onChange: (v) => previewDoorUpdate('openingRevealRadius', v), onCommit: (v) => commitDoorPreview('openingRevealRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 3, step: 0.005, unit: "m", value: openingRevealRadius })] })), doorShape === 'arch' && (_jsx(SliderControl, { label: "Arch Height", max: node.height, min: 0.05, onChange: (v) => previewDoorUpdate('archHeight', v), onCommit: (v) => commitDoorPreview('archHeight', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: archHeight }))] })), showOpeningShapeSection && (_jsxs(PanelSection, { title: "Opening Shape", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({
|
|
515
486
|
openingShape: v,
|
|
516
487
|
...(v === 'rounded'
|
|
517
488
|
? { openingRadiusMode, openingTopRadii, cornerRadius, openingRevealRadius }
|
|
@@ -524,19 +495,19 @@ export default function DoorPanel() {
|
|
|
524
495
|
], value: openingShape }) }), openingShape === 'rounded' && (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ openingRadiusMode: v }), options: [
|
|
525
496
|
{ label: 'All', value: 'all' },
|
|
526
497
|
{ label: 'Individual', value: 'individual' },
|
|
527
|
-
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), precision: 2, step: 0.05, unit: "m", value:
|
|
498
|
+
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: cornerRadius })) : (_jsx(_Fragment, { children: [
|
|
528
499
|
['Top Left', 0],
|
|
529
500
|
['Top Right', 1],
|
|
530
|
-
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), precision: 2, step: 0.05, unit: "m", value:
|
|
501
|
+
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: openingTopRadii[index] ?? 0 }, label))) })), _jsx(SliderControl, { label: "Reveal Radius", max: 0.08, min: 0, onChange: (v) => previewDoorUpdate('openingRevealRadius', v), onCommit: (v) => commitDoorPreview('openingRevealRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 3, step: 0.005, unit: "m", value: openingRevealRadius })] })), openingShape === 'arch' && (_jsx(SliderControl, { label: "Arch Height", max: node.height, min: 0.05, onChange: (v) => previewDoorUpdate('archHeight', v), onCommit: (v) => commitDoorPreview('archHeight', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: archHeight }))] })), !isCutoutOnly && (_jsxs(_Fragment, { children: [showFrameSection && (_jsxs(PanelSection, { title: "Frame", children: [_jsx(SliderControl, { label: "Thickness", max: 0.2, min: 0.01, onChange: (v) => handleUpdate({ frameThickness: v }), precision: 3, step: 0.01, unit: "m", value: node.frameThickness }), _jsx(SliderControl, { label: "Depth", max: 0.3, min: 0.01, onChange: (v) => handleUpdate({ frameDepth: v }), precision: 3, step: 0.01, unit: "m", value: node.frameDepth })] })), showContentPaddingSection && (_jsxs(PanelSection, { title: "Content Padding", children: [_jsx(SliderControl, { label: "Horizontal", max: 0.2, min: 0, onChange: (v) => handleUpdate({ contentPadding: [v, node.contentPadding[1]] }), precision: 3, step: 0.005, unit: "m", value: node.contentPadding[0] }), _jsx(SliderControl, { label: "Vertical", max: 0.2, min: 0, onChange: (v) => handleUpdate({ contentPadding: [node.contentPadding[0], v] }), precision: 3, step: 0.005, unit: "m", value: node.contentPadding[1] })] })), showSwingSection && (_jsx(PanelSection, { title: "Swing", children: _jsxs("div", { className: "flex flex-col gap-2 px-1 pb-1", children: [supportsHingeSide && (_jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Hinges Side" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ hingesSide: v }), options: [
|
|
531
502
|
{ label: 'Left', value: 'left' },
|
|
532
503
|
{ label: 'Right', value: 'right' },
|
|
533
504
|
], value: node.hingesSide })] })), _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Direction" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ swingDirection: v }), options: [
|
|
534
505
|
{ label: 'Inward', value: 'inward' },
|
|
535
506
|
{ label: 'Outward', value: 'outward' },
|
|
536
|
-
], value: node.swingDirection })] })] }) })), showThresholdSection && (_jsxs(PanelSection, { title: "Threshold", children: [_jsx(ToggleControl, { checked: node.threshold, label: "Enable Threshold", onChange: (checked) => handleUpdate({ threshold: checked }) }), node.threshold && (_jsx("div", { className: "mt-1 flex flex-col gap-1", children: _jsx(SliderControl, { label: "Height", max: 0.1, min: 0.005, onChange: (v) => handleUpdate({ thresholdHeight: v }), precision: 3, step: 0.005, unit: "m", value:
|
|
507
|
+
], value: node.swingDirection })] })] }) })), showThresholdSection && (_jsxs(PanelSection, { title: "Threshold", children: [_jsx(ToggleControl, { checked: node.threshold, label: "Enable Threshold", onChange: (checked) => handleUpdate({ threshold: checked }) }), node.threshold && (_jsx("div", { className: "mt-1 flex flex-col gap-1", children: _jsx(SliderControl, { label: "Height", max: 0.1, min: 0.005, onChange: (v) => handleUpdate({ thresholdHeight: v }), precision: 3, step: 0.005, unit: "m", value: node.thresholdHeight }) }))] })), showHandleSection && (_jsxs(PanelSection, { title: "Handle", children: [isSwingDoor && (_jsx(ToggleControl, { checked: node.handle, label: "Enable Handle", onChange: (checked) => handleUpdate({ handle: checked }) })), (node.handle || !isSwingDoor) && (_jsxs("div", { className: "mt-1 flex flex-col gap-1", children: [_jsx(SliderControl, { label: "Height", max: node.height - 0.1, min: 0.5, onChange: (v) => handleUpdate({ handleHeight: v }), precision: 2, step: 0.05, unit: "m", value: node.handleHeight }), supportsHandleSide && (_jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Handle Side" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ handleSide: v }), options: [
|
|
537
508
|
{ label: 'Left', value: 'left' },
|
|
538
509
|
{ label: 'Right', value: 'right' },
|
|
539
|
-
], value: node.handleSide })] }))] }))] })), showHardwareSection && (_jsxs(PanelSection, { title: "Hardware", children: [_jsx(ToggleControl, { checked: node.doorCloser, label: "Door Closer", onChange: (checked) => handleUpdate({ doorCloser: checked }) }), _jsx(ToggleControl, { checked: node.panicBar, label: "Panic Bar", onChange: (checked) => handleUpdate({ panicBar: checked }) }), node.panicBar && (_jsx("div", { className: "mt-1 flex flex-col gap-1", children: _jsx(SliderControl, { label: "Bar Height", max: node.height - 0.1, min: 0.5, onChange: (v) => handleUpdate({ panicBarHeight: v }), precision: 2, step: 0.05, unit: "m", value:
|
|
510
|
+
], value: node.handleSide })] }))] }))] })), showHardwareSection && (_jsxs(PanelSection, { title: "Hardware", children: [_jsx(ToggleControl, { checked: node.doorCloser, label: "Door Closer", onChange: (checked) => handleUpdate({ doorCloser: checked }) }), _jsx(ToggleControl, { checked: node.panicBar, label: "Panic Bar", onChange: (checked) => handleUpdate({ panicBar: checked }) }), node.panicBar && (_jsx("div", { className: "mt-1 flex flex-col gap-1", children: _jsx(SliderControl, { label: "Bar Height", max: node.height - 0.1, min: 0.5, onChange: (v) => handleUpdate({ panicBarHeight: v }), precision: 2, step: 0.05, unit: "m", value: node.panicBarHeight }) }))] })), showSegmentsSection && (_jsxs(PanelSection, { title: "Segments", children: [node.segments.map((seg, i) => {
|
|
540
511
|
const numCols = seg.columnRatios.length;
|
|
541
512
|
const colSum = seg.columnRatios.reduce((a, b) => a + b, 0);
|
|
542
513
|
const normCols = seg.columnRatios.map((r) => r / colSum);
|
|
@@ -554,13 +525,13 @@ export default function DoorPanel() {
|
|
|
554
525
|
}, precision: 0, step: 1, value: numCols }), numCols > 1 && (_jsxs("div", { className: "mt-1 border-border/50 border-t pt-1", children: [normCols.map((ratio, ci) => (_jsx(SliderControl, { label: `C${ci + 1}`, max: 95, min: 5, onChange: (v) => setSegmentColumnRatio(i, ci, v / 100), precision: 1, step: 1, unit: "%", value: Math.round(ratio * 100 * 10) / 10 }, `c-${ci}`))), _jsx(SliderControl, { label: "Divider", max: 0.1, min: 0.005, onChange: (v) => {
|
|
555
526
|
const updated = node.segments.map((s, idx) => idx === i ? { ...s, dividerThickness: v } : s);
|
|
556
527
|
handleUpdate({ segments: updated });
|
|
557
|
-
}, precision: 3, step: 0.005, unit: "m", value:
|
|
528
|
+
}, precision: 3, step: 0.005, unit: "m", value: seg.dividerThickness })] })), seg.type === 'panel' && (_jsxs("div", { className: "mt-1 border-border/50 border-t pt-1", children: [_jsx(SliderControl, { label: "Inset", max: 0.1, min: 0, onChange: (v) => {
|
|
558
529
|
const updated = node.segments.map((s, idx) => idx === i ? { ...s, panelInset: v } : s);
|
|
559
530
|
handleUpdate({ segments: updated });
|
|
560
|
-
}, precision: 3, step: 0.005, unit: "m", value:
|
|
531
|
+
}, precision: 3, step: 0.005, unit: "m", value: seg.panelInset }), _jsx(SliderControl, { label: "Depth", max: 0.1, min: 0, onChange: (v) => {
|
|
561
532
|
const updated = node.segments.map((s, idx) => idx === i ? { ...s, panelDepth: v } : s);
|
|
562
533
|
handleUpdate({ segments: updated });
|
|
563
|
-
}, precision: 3, step: 0.005, unit: "m", value:
|
|
534
|
+
}, precision: 3, step: 0.005, unit: "m", value: seg.panelDepth })] }))] }, i));
|
|
564
535
|
}), _jsxs("div", { className: "flex gap-1.5 px-1 pt-1", children: [_jsx(ActionButton, { label: "+ Add Segment", onClick: () => {
|
|
565
536
|
const updated = [
|
|
566
537
|
...node.segments,
|
package/dist/door/tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/door/tool.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/door/tool.tsx"],"names":[],"mappings":"AAqEA;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAwtBrB,CAAA;AAED,eAAe,QAAQ,CAAA"}
|
package/dist/door/tool.js
CHANGED
|
@@ -5,6 +5,7 @@ import { useViewer } from '@pascal-app/viewer';
|
|
|
5
5
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { BoxGeometry, EdgesGeometry, Vector3 } from 'three';
|
|
7
7
|
import { LineBasicNodeMaterial } from 'three/webgpu';
|
|
8
|
+
import { shouldFollowOpeningGrid, shouldHandleOpeningHostLeave, } from '../shared/opening-grid-follow';
|
|
8
9
|
import { clearOpeningGuides3D, publishOpeningGuidesForWallEvent, } from '../shared/opening-guides-runtime';
|
|
9
10
|
import { getRoofWallOpeningCursorPose, resolveRoofWallOpeningTarget, worldToSelectedBuildingLocal, } from '../shared/roof-wall-opening-placement';
|
|
10
11
|
import { collectWallOpeningAlignmentCandidates, resolveWallSlideAlignment, } from '../shared/wall-opening-alignment';
|
|
@@ -385,7 +386,17 @@ const DoorTool = () => {
|
|
|
385
386
|
commitDoorAtWall(event.node, clampedX, clampedY, side, itemRotation);
|
|
386
387
|
event.stopPropagation();
|
|
387
388
|
};
|
|
388
|
-
|
|
389
|
+
// XR runtimes deliver selectend as a grid click, but do not replay the
|
|
390
|
+
// R3F wall pointer-up event. Commit the latest valid wall hover so a
|
|
391
|
+
// controller/hand release places the opening on the wall it visibly hit.
|
|
392
|
+
const onXRGridClick = (event) => {
|
|
393
|
+
if (event.nativeEvent?.pointerType !== 'xr' || !lastWallEvent)
|
|
394
|
+
return;
|
|
395
|
+
onWallClick(lastWallEvent);
|
|
396
|
+
};
|
|
397
|
+
const onWallLeave = (event) => {
|
|
398
|
+
if (!shouldHandleOpeningHostLeave(event.nativeEvent))
|
|
399
|
+
return;
|
|
389
400
|
if (hostKind !== 'wall')
|
|
390
401
|
return;
|
|
391
402
|
lastWallEvent = null;
|
|
@@ -404,7 +415,12 @@ const DoorTool = () => {
|
|
|
404
415
|
// timeStamp) — it owns the frame and has snapped the draft, so skip the
|
|
405
416
|
// floor follow this tick.
|
|
406
417
|
const ts = event.nativeEvent?.timeStamp ?? -1;
|
|
407
|
-
if (
|
|
418
|
+
if (!shouldFollowOpeningGrid({
|
|
419
|
+
eventTime: ts,
|
|
420
|
+
hasActiveHost: hostKind !== null,
|
|
421
|
+
lastHostEventTime: lastMeshEventTime,
|
|
422
|
+
pointerType: event.nativeEvent?.pointerType,
|
|
423
|
+
}))
|
|
408
424
|
return;
|
|
409
425
|
// Fresh floor-only frame: the cursor is off any wall/roof. Drop any draft
|
|
410
426
|
// and free-follow the cursor with the invalid (unplaceable) ghost.
|
|
@@ -575,6 +591,7 @@ const DoorTool = () => {
|
|
|
575
591
|
emitter.on('wall:enter', onWallHover);
|
|
576
592
|
emitter.on('wall:move', onWallHover);
|
|
577
593
|
emitter.on('wall:click', onWallClick);
|
|
594
|
+
emitter.on('grid:click', onXRGridClick);
|
|
578
595
|
emitter.on('wall:leave', onWallLeave);
|
|
579
596
|
emitter.on('roof:enter', onRoofHover);
|
|
580
597
|
emitter.on('roof:move', onRoofHover);
|
|
@@ -599,6 +616,7 @@ const DoorTool = () => {
|
|
|
599
616
|
emitter.off('wall:enter', onWallHover);
|
|
600
617
|
emitter.off('wall:move', onWallHover);
|
|
601
618
|
emitter.off('wall:click', onWallClick);
|
|
619
|
+
emitter.off('grid:click', onXRGridClick);
|
|
602
620
|
emitter.off('wall:leave', onWallLeave);
|
|
603
621
|
emitter.off('roof:enter', onRoofHover);
|
|
604
622
|
emitter.off('roof:move', onRoofHover);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/dormer/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAqPrC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,OAAO,UAAU,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/dormer/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAqPrC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,OAAO,UAAU,CA+E9D,CAAA"}
|
|
@@ -141,12 +141,12 @@ export function DormerPositionSection({ node, segment, roof, selectedId, preview
|
|
|
141
141
|
return;
|
|
142
142
|
const local = worldToSegLocal(newWorldX, worldZ_now, segment);
|
|
143
143
|
previewProp({ position: [local.localX, py ?? 0, local.localZ] });
|
|
144
|
-
}, onCommit: (newWorldX) => commitWorldPosition(newWorldX, worldZ_now), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value:
|
|
144
|
+
}, onCommit: (newWorldX) => commitWorldPosition(newWorldX, worldZ_now), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: worldX_now }), _jsx(SliderControl, { label: "Z", max: Math.round(worldMaxZ * 10) / 10, min: Math.round(worldMinZ * 10) / 10, onChange: (newWorldZ) => {
|
|
145
145
|
if (!segment)
|
|
146
146
|
return;
|
|
147
147
|
const local = worldToSegLocal(worldX_now, newWorldZ, segment);
|
|
148
148
|
previewProp({ position: [local.localX, py ?? 0, local.localZ] });
|
|
149
|
-
}, onCommit: (newWorldZ) => commitWorldPosition(worldX_now, newWorldZ), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value:
|
|
149
|
+
}, onCommit: (newWorldZ) => commitWorldPosition(worldX_now, newWorldZ), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: worldZ_now }), _jsx(SliderControl, { label: "Rotation", max: 180, min: -180, onChange: (degrees) => {
|
|
150
150
|
const newWorldRot = (degrees * Math.PI) / 180;
|
|
151
151
|
let ancestorWorldY = 0;
|
|
152
152
|
if (segment) {
|
package/dist/dormer/panel.js
CHANGED
|
@@ -202,7 +202,7 @@ export default function DormerPanel() {
|
|
|
202
202
|
return (_jsx("button", { className: cn('flex min-h-10 items-center justify-center rounded-lg border px-2 py-2 text-center text-xs transition-colors', isSelected
|
|
203
203
|
? 'border-orange-400/60 bg-orange-400/10 text-foreground'
|
|
204
204
|
: 'border-border/50 bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground'), onClick: () => setSection(option.value), type: "button", children: _jsx("span", { className: "truncate font-medium", children: option.label }) }, option.value));
|
|
205
|
-
}) }) }), section === 'dormer' && (_jsxs(_Fragment, { children: [_jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.5, onChange: (v) => previewProp({ width: v }), onCommit: (v) => commitProp({ width: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value:
|
|
205
|
+
}) }) }), section === 'dormer' && (_jsxs(_Fragment, { children: [_jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.5, onChange: (v) => previewProp({ width: v }), onCommit: (v) => commitProp({ width: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.width }), _jsx(SliderControl, { label: "Depth", max: 1000, min: 0.5, onChange: (v) => previewProp({ depth: v }), onCommit: (v) => commitProp({ depth: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.depth }), _jsx(SliderControl, { label: "Wall Height", max: 1000, min: 0, onChange: (v) => previewProp({ height: v }), onCommit: (v) => commitProp({ height: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.height }), _jsx(SliderControl, { label: node.roofType === 'shed' ? 'Pitch Rise' : 'Roof Height', max: 3, min: 0, onChange: (v) => previewProp({ roofHeight: v }), onCommit: (v) => commitProp({ roofHeight: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.roofHeight })] }), _jsx(PanelSection, { title: "Roof Type", children: _jsx("div", { className: "grid grid-cols-3 gap-1.5 px-1 pt-1", children: ROOF_TYPE_OPTIONS.map((option) => {
|
|
206
206
|
const isSelected = node.roofType === option.value;
|
|
207
207
|
return (_jsx("button", { className: cn('flex min-h-10 items-center justify-center rounded-lg border px-2 py-2 text-xs transition-colors', isSelected
|
|
208
208
|
? 'border-orange-400/60 bg-orange-400/10 text-foreground'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/downspout/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAiIxC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,cAAc,CAAC,OAAO,aAAa,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/downspout/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAiIxC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,cAAc,CAAC,OAAO,aAAa,CA6DpE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/duct-segment/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,oBAAoB,EAAY,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/duct-segment/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,oBAAoB,EAAY,MAAM,kBAAkB,CAAA;AAM5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AA0E/C,eAAO,MAAM,sBAAsB,EAAE,oBAAoB,CAAC,eAAe,CAiJxE,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useScene } from '@pascal-app/core';
|
|
2
2
|
import { Vector3 } from 'three';
|
|
3
3
|
import { getDuctFittingPorts } from '../duct-fitting/ports';
|
|
4
|
+
import { findAutomaticRunEndCapIds } from '../shared/automatic-run-end-cap';
|
|
4
5
|
import { fittingDeletionPlansForRun } from '../shared/fitting-deletion-cleanup';
|
|
5
6
|
import { rollToContinueAcrossElbow } from './geometry';
|
|
6
7
|
/** A run endpoint sitting this close to a collar counts as mated. */
|
|
@@ -95,7 +96,10 @@ export const ductSegmentParametrics = {
|
|
|
95
96
|
return out;
|
|
96
97
|
},
|
|
97
98
|
onDelete: (duct, nodes, _pendingDeleteIds, requestedDeleteIds) => fittingDeletionPlansForRun(duct, nodes, requestedDeleteIds, true).flatMap((plan) => plan.updates),
|
|
98
|
-
onDeleteCascade: (duct, nodes, _pendingDeleteIds, requestedDeleteIds) =>
|
|
99
|
+
onDeleteCascade: (duct, nodes, _pendingDeleteIds, requestedDeleteIds) => [
|
|
100
|
+
...findAutomaticRunEndCapIds(duct.id, nodes, 'duct-fitting'),
|
|
101
|
+
...fittingDeletionPlansForRun(duct, nodes, requestedDeleteIds, false).flatMap((plan) => plan.deleteFitting ? [plan.fittingId, ...plan.cascadeDeleteIds] : []),
|
|
102
|
+
],
|
|
99
103
|
trailingSection: () => import('../shared/run-hanger-inspector'),
|
|
100
104
|
groups: [
|
|
101
105
|
{
|
|
@@ -8,6 +8,7 @@ type DraftProfile = {
|
|
|
8
8
|
width: number;
|
|
9
9
|
height: number;
|
|
10
10
|
};
|
|
11
|
+
export declare function ductSurfaceClearanceM(profile: DraftProfile, wall?: boolean): number;
|
|
11
12
|
/** The full set of nodes a drawn segment produces. The drawn `ducts`
|
|
12
13
|
* (and any trunk `tails` from a tee / cross split) are previewed by the
|
|
13
14
|
* duct ghost already; `fittings` are the auto-inserted elbow / tee /
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-segment/tool.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAuBtF,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAYpG,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-segment/tool.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAuBtF,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAYpG,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAA;AA2IxB,qEAAqE;AACrE,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAUjF;AAgDD;;;;;6BAK6B;AAC7B,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,OAAO,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;CACxB,CAAA;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,EAAE,SAAS,GAAG,IAAI,EACzB,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,UAAQ,EACnB,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,EAC3C,WAAW,GAAE,QAAQ,GAAG,QAAmB,GAC1C,YAAY,GAAG,IAAI,CAsLrB;AAED,QAAA,MAAM,eAAe,0CAoRpB,CAAA;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -56,6 +56,7 @@ import { rectSectionAxes, rollToContinueAcrossElbow } from './geometry';
|
|
|
56
56
|
*/
|
|
57
57
|
const DUCT_DIAMETERS_IN = [4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20];
|
|
58
58
|
const BODY_SNAP_RADIUS_M = 0.35;
|
|
59
|
+
const DUCT_WALL_STANDOFF_M = 0.01;
|
|
59
60
|
/** Angle step (radians) for the XZ angle lock — 45°. */
|
|
60
61
|
/**
|
|
61
62
|
* Cross-section roll for a new rect run leaving `port` along `newDir`,
|
|
@@ -134,6 +135,13 @@ function getConnectionPorts(levelId, nodes) {
|
|
|
134
135
|
levelId: levelId ?? undefined,
|
|
135
136
|
}).filter((port) => !isRunEndCapPort(port, nodes));
|
|
136
137
|
}
|
|
138
|
+
export function ductSurfaceClearanceM(profile, wall = false) {
|
|
139
|
+
return (runSectionHalfSizeM(profile.shape === 'round'
|
|
140
|
+
? profile.diameter
|
|
141
|
+
: wall
|
|
142
|
+
? Math.max(profile.width, profile.height)
|
|
143
|
+
: profile.height) + (wall && profile.shape !== 'round' ? DUCT_WALL_STANDOFF_M : 0));
|
|
144
|
+
}
|
|
137
145
|
/**
|
|
138
146
|
* Profile to inherit when the segment start snaps onto `port` — joining
|
|
139
147
|
* means continuing that thing: a rect trunk end keeps its W×H, a round
|
|
@@ -382,6 +390,7 @@ export function planDuctDraw(start, end, startPort, startBody, endPort, endBody,
|
|
|
382
390
|
}
|
|
383
391
|
const DuctSegmentTool = () => {
|
|
384
392
|
const { activeLevelId, sceneApi, unit } = useRegistryToolContext();
|
|
393
|
+
const toolDefaults = useEditor((s) => s.toolDefaults['duct-segment']);
|
|
385
394
|
const cursorRef = useRef(null);
|
|
386
395
|
const continuationSeedRef = useRef(currentDuctContinuationSeed());
|
|
387
396
|
const continuationSeed = continuationSeedRef.current;
|
|
@@ -425,11 +434,7 @@ const DuctSegmentTool = () => {
|
|
|
425
434
|
: null,
|
|
426
435
|
getPorts: () => getConnectionPorts(activeLevelId, sceneApi.nodes()),
|
|
427
436
|
findBody: (point) => findNearestRunBody3D(point, BODY_SNAP_RADIUS_M, { levelId: activeLevelId ?? undefined }),
|
|
428
|
-
surfaceClearance: (surface) => surface
|
|
429
|
-
? runSectionHalfSizeM(profileRef.current.shape === 'round'
|
|
430
|
-
? profileRef.current.diameter
|
|
431
|
-
: profileRef.current.height)
|
|
432
|
-
: 0,
|
|
437
|
+
surfaceClearance: (surface) => surface ? ductSurfaceClearanceM(profileRef.current, surface.kind === 'wall') : 0,
|
|
433
438
|
minimumSegmentLength: 0.08,
|
|
434
439
|
inheritFromConnection: ({ port }) => {
|
|
435
440
|
if (!port)
|
|
@@ -447,9 +452,7 @@ const DuctSegmentTool = () => {
|
|
|
447
452
|
return null;
|
|
448
453
|
const attachDuct = (node) => {
|
|
449
454
|
const wallAttachment = surfaceTarget?.kind === 'wall'
|
|
450
|
-
? createRunWallAttachment(surfaceTarget.hostId, surfaceTarget.side, node.path[0], node.path.at(-1), surfaceTarget, profileRef.current
|
|
451
|
-
? runSectionHalfSizeM(profileRef.current.diameter)
|
|
452
|
-
: runSectionHalfSizeM(profileRef.current.height))
|
|
455
|
+
? createRunWallAttachment(surfaceTarget.hostId, surfaceTarget.side, node.path[0], node.path.at(-1), surfaceTarget, ductSurfaceClearanceM(profileRef.current, true))
|
|
453
456
|
: undefined;
|
|
454
457
|
return { ...node, wallAttachment };
|
|
455
458
|
};
|
|
@@ -521,6 +524,16 @@ const DuctSegmentTool = () => {
|
|
|
521
524
|
}
|
|
522
525
|
},
|
|
523
526
|
});
|
|
527
|
+
useEffect(() => {
|
|
528
|
+
if (!toolDefaults)
|
|
529
|
+
return;
|
|
530
|
+
setProfile((current) => ({
|
|
531
|
+
shape: toolDefaults.shape ?? current.shape,
|
|
532
|
+
diameter: toolDefaults.diameter ?? current.diameter,
|
|
533
|
+
width: toolDefaults.width ?? current.width,
|
|
534
|
+
height: toolDefaults.height ?? current.height,
|
|
535
|
+
}));
|
|
536
|
+
}, [toolDefaults]);
|
|
524
537
|
const previewPlan = useMemo(() => {
|
|
525
538
|
if (!(activeLevelId && run.start && run.cursor))
|
|
526
539
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-terminal/tool.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-terminal/tool.tsx"],"names":[],"mappings":"AAmJA;;;;;;;;;GASG;AACH,QAAA,MAAM,gBAAgB,0CAyYrB,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|