@pascal-app/nodes 0.1.1 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/dist/building/definition.js +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +809 -72
- package/dist/cabinet/geometry.d.ts.map +1 -1
- package/dist/cabinet/geometry.js +4 -0
- package/dist/cabinet/move-frame.js +3 -3
- package/dist/cabinet/panel.d.ts.map +1 -1
- package/dist/cabinet/panel.js +1 -0
- package/dist/cabinet/placement-snap.d.ts +8 -0
- package/dist/cabinet/placement-snap.d.ts.map +1 -0
- package/dist/cabinet/placement-snap.js +19 -0
- package/dist/cabinet/presets.js +8 -8
- package/dist/cabinet/quick-actions.d.ts.map +1 -1
- package/dist/cabinet/quick-actions.js +9 -3
- package/dist/cabinet/resize-limits.d.ts +11 -0
- package/dist/cabinet/resize-limits.d.ts.map +1 -0
- package/dist/cabinet/resize-limits.js +22 -0
- package/dist/cabinet/run-layout.d.ts +8 -2
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +59 -7
- package/dist/cabinet/run-ops.d.ts +44 -3
- package/dist/cabinet/run-ops.d.ts.map +1 -1
- package/dist/cabinet/run-ops.js +646 -110
- package/dist/cabinet/run-panel.d.ts +2 -1
- package/dist/cabinet/run-panel.d.ts.map +1 -1
- package/dist/cabinet/run-panel.js +38 -4
- package/dist/cabinet/stack-transitions.js +4 -4
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +95 -17
- package/dist/cabinet/wall-snap.d.ts.map +1 -1
- package/dist/cabinet/wall-snap.js +2 -6
- package/dist/ceiling/boundary-editor.d.ts.map +1 -1
- package/dist/ceiling/boundary-editor.js +2 -2
- package/dist/ceiling/definition.d.ts +1 -1
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +36 -5
- package/dist/ceiling/floorplan-affordances.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts.map +1 -1
- package/dist/ceiling/floorplan-move.js +5 -4
- package/dist/ceiling/hole-editor.d.ts.map +1 -1
- package/dist/ceiling/hole-editor.js +2 -2
- package/dist/ceiling/move-tool.d.ts.map +1 -1
- package/dist/ceiling/move-tool.js +4 -3
- package/dist/ceiling/panel.d.ts.map +1 -1
- package/dist/ceiling/panel.js +65 -3
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +6 -2
- package/dist/ceiling/tool.d.ts.map +1 -1
- package/dist/ceiling/tool.js +12 -1
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +1 -0
- package/dist/chimney/tool.d.ts.map +1 -1
- package/dist/chimney/tool.js +16 -1
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +14 -2
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +19 -14
- package/dist/column/floorplan-move.d.ts.map +1 -1
- package/dist/column/floorplan-move.js +7 -2
- package/dist/column/floorplan.d.ts +9 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +59 -4
- package/dist/column/tool.d.ts.map +1 -1
- package/dist/column/tool.js +33 -7
- package/dist/construction-dimension/definition.d.ts +4 -0
- package/dist/construction-dimension/definition.d.ts.map +1 -0
- package/dist/construction-dimension/definition.js +83 -0
- package/dist/construction-dimension/drawing-coordination.d.ts +7 -0
- package/dist/construction-dimension/drawing-coordination.d.ts.map +1 -0
- package/dist/construction-dimension/drawing-coordination.js +54 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts +4 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-affordances.js +114 -0
- package/dist/construction-dimension/floorplan-tool.d.ts +21 -0
- package/dist/construction-dimension/floorplan-tool.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-tool.js +557 -0
- package/dist/construction-dimension/floorplan.d.ts +3 -0
- package/dist/construction-dimension/floorplan.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan.js +457 -0
- package/dist/construction-dimension/geometry.d.ts +31 -0
- package/dist/construction-dimension/geometry.d.ts.map +1 -0
- package/dist/construction-dimension/geometry.js +144 -0
- package/dist/construction-dimension/index.d.ts +4 -0
- package/dist/construction-dimension/index.d.ts.map +1 -0
- package/dist/construction-dimension/index.js +3 -0
- package/dist/construction-dimension/panel.d.ts +2 -0
- package/dist/construction-dimension/panel.d.ts.map +1 -0
- package/dist/construction-dimension/panel.js +128 -0
- package/dist/construction-dimension/parametrics.d.ts +3 -0
- package/dist/construction-dimension/parametrics.d.ts.map +1 -0
- package/dist/construction-dimension/parametrics.js +4 -0
- package/dist/construction-dimension/schema.d.ts +2 -0
- package/dist/construction-dimension/schema.d.ts.map +1 -0
- package/dist/construction-dimension/schema.js +1 -0
- package/dist/door/contextual-dimensions.d.ts +3 -0
- package/dist/door/contextual-dimensions.d.ts.map +1 -0
- package/dist/door/contextual-dimensions.js +7 -0
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +13 -8
- package/dist/door/floorplan-affordances.d.ts +2 -5
- package/dist/door/floorplan-affordances.d.ts.map +1 -1
- package/dist/door/floorplan-affordances.js +9 -18
- package/dist/door/floorplan.d.ts +3 -4
- package/dist/door/floorplan.d.ts.map +1 -1
- package/dist/door/floorplan.js +88 -6
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +2 -2
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +3 -1
- package/dist/door/schema.d.ts +1 -1
- package/dist/door/schema.d.ts.map +1 -1
- package/dist/door/schema.js +1 -1
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +63 -6
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +1 -0
- package/dist/dormer/tool.d.ts.map +1 -1
- package/dist/dormer/tool.js +23 -1
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +20 -9
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +9 -6
- package/dist/elevator/floorplan-affordances.d.ts +2 -6
- package/dist/elevator/floorplan-affordances.d.ts.map +1 -1
- package/dist/elevator/floorplan-affordances.js +13 -12
- package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
- package/dist/fence/actions/move-endpoint.js +29 -1
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +74 -14
- package/dist/fence/floorplan-affordances.d.ts.map +1 -1
- package/dist/fence/floorplan-affordances.js +48 -11
- package/dist/fence/floorplan-move.d.ts.map +1 -1
- package/dist/fence/floorplan-move.js +38 -3
- package/dist/fence/geometry.d.ts.map +1 -1
- package/dist/fence/geometry.js +15 -1
- package/dist/fence/lift.d.ts +38 -0
- package/dist/fence/lift.d.ts.map +1 -0
- package/dist/fence/lift.js +51 -0
- package/dist/fence/move-tool.d.ts.map +1 -1
- package/dist/fence/move-tool.js +25 -5
- package/dist/fence/system.d.ts +3 -0
- package/dist/fence/system.d.ts.map +1 -0
- package/dist/fence/system.js +46 -0
- package/dist/fence/tool.d.ts.map +1 -1
- package/dist/fence/tool.js +103 -32
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +8 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +7 -1
- package/dist/item/floorplan-move.d.ts.map +1 -1
- package/dist/item/floorplan-move.js +50 -43
- package/dist/item/floorplan.d.ts +1 -0
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +49 -0
- package/dist/item/renderer.d.ts +3 -0
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +96 -8
- package/dist/level/definition.d.ts.map +1 -1
- package/dist/level/definition.js +7 -3
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +5 -1
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +7 -1
- package/dist/measurement/definition.d.ts.map +1 -1
- package/dist/measurement/definition.js +5 -0
- package/dist/measurement/floorplan.d.ts.map +1 -1
- package/dist/measurement/floorplan.js +11 -10
- package/dist/measurement/index.d.ts +1 -1
- package/dist/measurement/index.d.ts.map +1 -1
- package/dist/measurement/index.js +1 -1
- package/dist/measurement/resolve.d.ts +5 -0
- package/dist/measurement/resolve.d.ts.map +1 -1
- package/dist/measurement/resolve.js +2 -2
- package/dist/measurement/surface-query.js +5 -5
- package/dist/measurement/tool.d.ts +6 -1
- package/dist/measurement/tool.d.ts.map +1 -1
- package/dist/measurement/tool.js +7 -11
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +22 -19
- package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
- package/dist/roof-segment/floorplan-affordances.js +14 -8
- package/dist/shared/construction-dimension-standards.d.ts +34 -0
- package/dist/shared/construction-dimension-standards.d.ts.map +1 -0
- package/dist/shared/construction-dimension-standards.js +18 -0
- package/dist/shared/construction-length.d.ts +10 -0
- package/dist/shared/construction-length.d.ts.map +1 -0
- package/dist/shared/construction-length.js +57 -0
- package/dist/shared/dimension-string.d.ts +20 -0
- package/dist/shared/dimension-string.d.ts.map +1 -0
- package/dist/shared/dimension-string.js +19 -0
- package/dist/shared/draft-axis-guides.d.ts +36 -0
- package/dist/shared/draft-axis-guides.d.ts.map +1 -0
- package/dist/shared/draft-axis-guides.js +107 -0
- package/dist/shared/move-roof-tool.d.ts.map +1 -1
- package/dist/shared/move-roof-tool.js +17 -3
- package/dist/shared/opening-documentation-fields.d.ts +16 -0
- package/dist/shared/opening-documentation-fields.d.ts.map +1 -0
- package/dist/shared/opening-documentation-fields.js +54 -0
- package/dist/shared/opening-documentation.d.ts +47 -0
- package/dist/shared/opening-documentation.d.ts.map +1 -0
- package/dist/shared/opening-documentation.js +300 -0
- package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
- package/dist/shared/opening-guides-runtime.js +3 -2
- package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.js +14 -5
- package/dist/shared/wall-opening-ceiling.d.ts +30 -0
- package/dist/shared/wall-opening-ceiling.d.ts.map +1 -0
- package/dist/shared/wall-opening-ceiling.js +29 -0
- package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
- package/dist/shelf/floorplan-affordances.js +10 -5
- package/dist/shelf/floorplan-move.d.ts +2 -16
- package/dist/shelf/floorplan-move.d.ts.map +1 -1
- package/dist/shelf/floorplan-move.js +19 -40
- package/dist/shelf/tool.d.ts.map +1 -1
- package/dist/shelf/tool.js +8 -3
- package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
- package/dist/site/recessed-slab-ground-holes.js +1 -4
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +118 -28
- package/dist/site/terrain-drape.d.ts +91 -0
- package/dist/site/terrain-drape.d.ts.map +1 -0
- package/dist/site/terrain-drape.js +205 -0
- package/dist/site/terrain-geometry.d.ts +131 -0
- package/dist/site/terrain-geometry.d.ts.map +1 -0
- package/dist/site/terrain-geometry.js +259 -0
- package/dist/site/terrain-mesh.d.ts +49 -0
- package/dist/site/terrain-mesh.d.ts.map +1 -0
- package/dist/site/terrain-mesh.js +122 -0
- package/dist/site/terrain-renderer.d.ts +28 -0
- package/dist/site/terrain-renderer.d.ts.map +1 -0
- package/dist/site/terrain-renderer.js +69 -0
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +1 -0
- package/dist/skylight/tool.d.ts.map +1 -1
- package/dist/skylight/tool.js +16 -1
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +87 -10
- package/dist/slab/elevation-limit.d.ts +43 -0
- package/dist/slab/elevation-limit.d.ts.map +1 -0
- package/dist/slab/elevation-limit.js +124 -0
- package/dist/slab/floorplan-affordances.d.ts +16 -0
- package/dist/slab/floorplan-affordances.d.ts.map +1 -1
- package/dist/slab/geometry.d.ts.map +1 -1
- package/dist/slab/geometry.js +98 -5
- package/dist/slab/panel.d.ts.map +1 -1
- package/dist/slab/panel.js +82 -4
- package/dist/slab/parametrics.d.ts +1 -1
- package/dist/slab/parametrics.d.ts.map +1 -1
- package/dist/slab/parametrics.js +13 -1
- package/dist/slab/placement-ownership.d.ts +3 -0
- package/dist/slab/placement-ownership.d.ts.map +1 -0
- package/dist/slab/placement-ownership.js +3 -0
- package/dist/slab/quick-measurement.d.ts.map +1 -1
- package/dist/slab/quick-measurement.js +3 -2
- package/dist/slab/system.d.ts.map +1 -1
- package/dist/slab/system.js +14 -4
- package/dist/slab/tool.d.ts.map +1 -1
- package/dist/slab/tool.js +81 -23
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +1 -0
- package/dist/solar-panel/tool.d.ts.map +1 -1
- package/dist/solar-panel/tool.js +17 -1
- package/dist/spawn/definition.d.ts.map +1 -1
- package/dist/spawn/definition.js +1 -0
- package/dist/spawn/floorplan-affordances.d.ts.map +1 -1
- package/dist/spawn/floorplan-affordances.js +7 -4
- package/dist/spawn/floorplan-move.d.ts.map +1 -1
- package/dist/spawn/floorplan-move.js +8 -6
- package/dist/spawn/renderer.d.ts +4 -0
- package/dist/spawn/renderer.d.ts.map +1 -1
- package/dist/spawn/renderer.js +32 -18
- package/dist/spawn/tool.d.ts +2 -2
- package/dist/spawn/tool.d.ts.map +1 -1
- package/dist/spawn/tool.js +78 -11
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +15 -7
- package/dist/stair/destination.d.ts +16 -0
- package/dist/stair/destination.d.ts.map +1 -0
- package/dist/stair/destination.js +24 -0
- package/dist/stair/documentation.d.ts +8 -0
- package/dist/stair/documentation.d.ts.map +1 -0
- package/dist/stair/documentation.js +245 -0
- package/dist/stair/floor-stack.d.ts.map +1 -1
- package/dist/stair/floor-stack.js +38 -0
- package/dist/stair/floorplan-affordances.d.ts.map +1 -1
- package/dist/stair/floorplan-affordances.js +28 -9
- package/dist/stair/floorplan-move.d.ts +3 -5
- package/dist/stair/floorplan-move.d.ts.map +1 -1
- package/dist/stair/floorplan-move.js +14 -16
- package/dist/stair/floorplan.d.ts.map +1 -1
- package/dist/stair/floorplan.js +27 -14
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +35 -2
- package/dist/stair/renderer.d.ts.map +1 -1
- package/dist/stair/renderer.js +4 -3
- package/dist/structural-grid/coordination.d.ts +16 -0
- package/dist/structural-grid/coordination.d.ts.map +1 -0
- package/dist/structural-grid/coordination.js +105 -0
- package/dist/structural-grid/definition.d.ts +4 -0
- package/dist/structural-grid/definition.d.ts.map +1 -0
- package/dist/structural-grid/definition.js +51 -0
- package/dist/structural-grid/floorplan-tool.d.ts +16 -0
- package/dist/structural-grid/floorplan-tool.d.ts.map +1 -0
- package/dist/structural-grid/floorplan-tool.js +183 -0
- package/dist/structural-grid/floorplan.d.ts +3 -0
- package/dist/structural-grid/floorplan.d.ts.map +1 -0
- package/dist/structural-grid/floorplan.js +61 -0
- package/dist/structural-grid/index.d.ts +2 -0
- package/dist/structural-grid/index.d.ts.map +1 -0
- package/dist/structural-grid/index.js +1 -0
- package/dist/structural-grid/schema.d.ts +2 -0
- package/dist/structural-grid/schema.d.ts.map +1 -0
- package/dist/structural-grid/schema.js +1 -0
- package/dist/wall/construction-dimensions.d.ts +32 -0
- package/dist/wall/construction-dimensions.d.ts.map +1 -0
- package/dist/wall/construction-dimensions.js +1031 -0
- package/dist/wall/contextual-dimensions.d.ts +13 -0
- package/dist/wall/contextual-dimensions.d.ts.map +1 -0
- package/dist/wall/contextual-dimensions.js +221 -0
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +20 -1
- package/dist/wall/floorplan-affordances.d.ts.map +1 -1
- package/dist/wall/floorplan-affordances.js +23 -8
- package/dist/wall/floorplan-overrides.d.ts +9 -6
- package/dist/wall/floorplan-overrides.d.ts.map +1 -1
- package/dist/wall/floorplan-overrides.js +20 -11
- package/dist/wall/floorplan.d.ts +12 -3
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +121 -79
- package/dist/wall/measurement.d.ts.map +1 -1
- package/dist/wall/measurement.js +17 -4
- package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
- package/dist/wall/move-endpoint-tool.js +74 -27
- package/dist/wall/move-shared.d.ts.map +1 -1
- package/dist/wall/move-shared.js +3 -2
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +15 -3
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +10 -6
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +32 -5
- package/dist/wall/parametrics.d.ts.map +1 -1
- package/dist/wall/parametrics.js +2 -0
- package/dist/wall/preview.d.ts +8 -0
- package/dist/wall/preview.d.ts.map +1 -0
- package/dist/wall/preview.js +39 -0
- package/dist/wall/quick-measurement.d.ts.map +1 -1
- package/dist/wall/quick-measurement.js +3 -2
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +7 -5
- package/dist/wall/system.d.ts +1 -1
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +37 -2
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +148 -96
- package/dist/wall/treatment-level-data.d.ts +14 -0
- package/dist/wall/treatment-level-data.d.ts.map +1 -0
- package/dist/wall/treatment-level-data.js +31 -0
- package/dist/wall/treatments.d.ts +8 -2
- package/dist/wall/treatments.d.ts.map +1 -1
- package/dist/wall/treatments.js +58 -15
- package/dist/window/contextual-dimensions.d.ts +3 -0
- package/dist/window/contextual-dimensions.d.ts.map +1 -0
- package/dist/window/contextual-dimensions.js +7 -0
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +15 -10
- package/dist/window/floorplan-affordances.d.ts +2 -5
- package/dist/window/floorplan-affordances.d.ts.map +1 -1
- package/dist/window/floorplan-affordances.js +9 -15
- package/dist/window/floorplan-move.d.ts.map +1 -1
- package/dist/window/floorplan-move.js +1 -1
- package/dist/window/floorplan.d.ts.map +1 -1
- package/dist/window/floorplan.js +7 -1
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +3 -3
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +4 -1
- package/dist/window/schema.d.ts +1 -1
- package/dist/window/schema.d.ts.map +1 -1
- package/dist/window/schema.js +1 -1
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +64 -7
- package/dist/window/window-math.d.ts +7 -3
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +8 -3
- package/dist/zone/contextual-dimensions.d.ts +3 -0
- package/dist/zone/contextual-dimensions.d.ts.map +1 -0
- package/dist/zone/contextual-dimensions.js +43 -0
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +9 -1
- package/dist/zone/floorplan-affordances.d.ts +36 -0
- package/dist/zone/floorplan-affordances.d.ts.map +1 -1
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +59 -3
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +48 -4
- package/dist/zone/room-clear-dimensions.d.ts +3 -0
- package/dist/zone/room-clear-dimensions.d.ts.map +1 -0
- package/dist/zone/room-clear-dimensions.js +406 -0
- package/dist/zone/room-documentation.d.ts +11 -0
- package/dist/zone/room-documentation.d.ts.map +1 -0
- package/dist/zone/room-documentation.js +97 -0
- package/package.json +7 -7
package/dist/wall/tool.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { calculateLevelMiters, collectAlignmentAnchors, emitter, getWallMiterBoundaryPoints, resolveAlignment, resolveBuildingForLevel, useScene, wallClosesRoom, } from '@pascal-app/core';
|
|
3
|
-
import { CursorSphere, chainEndJoinsExistingWall, createWallOnCurrentLevel, EDITOR_LAYER, formatAngleRadians, formatLinearMeasurement, getAngleArcToSegmentReference, getAngleToSegmentReference, getSegmentAngleReferenceAtPoint, isAlignmentGuideActive, isAngleSnapActive, isMagneticSnapActive, markToolCancelConsumed, snapWallDraftPointDetailed, triggerSFX, useAlignmentGuides, useEditor, useSegmentDraftChain, useWallSnapIndicator, WALL_CONNECT_SNAP_RADIUS, WALL_JOIN_SNAP_RADIUS, } from '@pascal-app/editor';
|
|
2
|
+
import { calculateLevelMiters, collectAlignmentAnchors, DEFAULT_LEVEL_HEIGHT, emitter, getWallMiterBoundaryPoints, resolveAlignment, resolveBuildingForLevel, sceneRegistry, useScene, wallClosesRoom, } from '@pascal-app/core';
|
|
3
|
+
import { CursorSphere, chainEndJoinsExistingWall, clearPlacementSurface, createWallOnCurrentLevel, EDITOR_LAYER, formatAngleRadians, formatLinearMeasurement, getAngleArcToSegmentReference, getAngleToSegmentReference, getSegmentAngleReferenceAtPoint, isAlignmentGuideActive, isAngleSnapActive, isMagneticSnapActive, markToolCancelConsumed, publishHorizontalConstructionPlane, publishPlacementSurface, resampleTerrainConstructionPlane, resolveEventConstructionPlane, resolvePointerSupportSurface, snapWallDraftPointDetailed, triggerSFX, useAlignmentGuides, useEditor, useFloorplanDraftPreview, useSegmentDraftChain, useWallSnapIndicator, WALL_CONNECT_SNAP_RADIUS, WALL_JOIN_SNAP_RADIUS, } from '@pascal-app/editor';
|
|
4
4
|
import { getSceneTheme, useViewer } from '@pascal-app/viewer';
|
|
5
|
-
import {
|
|
6
|
-
import { useEffect,
|
|
7
|
-
import { BoxGeometry,
|
|
5
|
+
import { useThree } from '@react-three/fiber';
|
|
6
|
+
import { useEffect, useRef, useState } from 'react';
|
|
7
|
+
import { BoxGeometry, DoubleSide, Vector3 } from 'three';
|
|
8
|
+
import { DraftAngleArc, DraftAxisGuides, DraftMeasurementLabel, getNearestAxisAngleLabel, } from '../shared/draft-axis-guides';
|
|
8
9
|
/**
|
|
9
10
|
* Phase 5 Stage D — wall placement tool (kind-owned).
|
|
10
11
|
*
|
|
@@ -18,7 +19,6 @@ import { BoxGeometry, BufferGeometry, DoubleSide, Vector3 } from 'three';
|
|
|
18
19
|
*
|
|
19
20
|
* Mounted via `def.tool` from `wall/definition.ts`.
|
|
20
21
|
*/
|
|
21
|
-
const WALL_HEIGHT = 2.5;
|
|
22
22
|
const DRAFT_WALL_THICKNESS = 0.1;
|
|
23
23
|
/** Figma-style alignment-snap threshold (meters), matching the move tools. */
|
|
24
24
|
const ALIGNMENT_THRESHOLD_M = 0.08;
|
|
@@ -29,19 +29,12 @@ const DRAFT_ANGLE_LABEL_Y_OFFSET = 0.08;
|
|
|
29
29
|
const DRAFT_ANGLE_ARC_Y_OFFSET = 0.012;
|
|
30
30
|
const DRAFT_ANGLE_ARC_MIN_RADIUS = 0.32;
|
|
31
31
|
const DRAFT_ANGLE_ARC_MAX_RADIUS = 0.72;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const DRAFT_AXIS_ANGLE_LABEL_Y_OFFSET = 0.16;
|
|
39
|
-
const DRAFT_AXIS_ANGLE_ARC_MIN_RADIUS = 0.36;
|
|
40
|
-
const DRAFT_AXIS_ANGLE_ARC_MAX_RADIUS = 0.82;
|
|
41
|
-
const AXIS_ANGLE_REFERENCES = [
|
|
42
|
-
{ vector: [1, 0], orientation: 'axis' },
|
|
43
|
-
{ vector: [0, 1], orientation: 'axis' },
|
|
44
|
-
];
|
|
32
|
+
// Grid-plane surface publish (pointer-decided): scratch + constant normal so
|
|
33
|
+
// per-move publishes don't allocate.
|
|
34
|
+
const SURFACE_UP = new Vector3(0, 1, 0);
|
|
35
|
+
const surfacePointScratch = new Vector3();
|
|
36
|
+
const wallSurfaceWorldScratch = new Vector3();
|
|
37
|
+
const wallSurfaceLocalScratch = new Vector3();
|
|
45
38
|
function clamp(value, min, max) {
|
|
46
39
|
return Math.min(max, Math.max(min, value));
|
|
47
40
|
}
|
|
@@ -58,43 +51,6 @@ function isWithinWallJoinSnapRadius(point, vertex) {
|
|
|
58
51
|
const dz = point[1] - vertex.z;
|
|
59
52
|
return dx * dx + dz * dz <= WALL_JOIN_SNAP_RADIUS * WALL_JOIN_SNAP_RADIUS;
|
|
60
53
|
}
|
|
61
|
-
function getNearestAxisAngleLabel(start, end, y) {
|
|
62
|
-
const dx = end[0] - start[0];
|
|
63
|
-
const dz = end[1] - start[1];
|
|
64
|
-
const length = Math.hypot(dx, dz);
|
|
65
|
-
if (length < 0.01)
|
|
66
|
-
return null;
|
|
67
|
-
const draftVector = [dx, dz];
|
|
68
|
-
const axisCandidates = [];
|
|
69
|
-
for (const reference of AXIS_ANGLE_REFERENCES) {
|
|
70
|
-
const angle = getAngleToSegmentReference(draftVector, reference);
|
|
71
|
-
const arc = getAngleArcToSegmentReference(draftVector, reference);
|
|
72
|
-
if (!(angle === null || arc === null)) {
|
|
73
|
-
axisCandidates.push({ angle, arc });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const nearestAxisAngle = axisCandidates.sort((a, b) => a.angle - b.angle)[0];
|
|
77
|
-
if (!nearestAxisAngle)
|
|
78
|
-
return null;
|
|
79
|
-
const radius = clamp(length * 0.22, DRAFT_AXIS_ANGLE_ARC_MIN_RADIUS, DRAFT_AXIS_ANGLE_ARC_MAX_RADIUS);
|
|
80
|
-
const { angle, arc } = nearestAxisAngle;
|
|
81
|
-
return {
|
|
82
|
-
id: 'axis',
|
|
83
|
-
label: formatAngleRadians(angle),
|
|
84
|
-
position: [
|
|
85
|
-
start[0] + Math.cos(arc.midAngle) * (radius + 0.16),
|
|
86
|
-
y + DRAFT_AXIS_ANGLE_LABEL_Y_OFFSET,
|
|
87
|
-
start[1] + Math.sin(arc.midAngle) * (radius + 0.16),
|
|
88
|
-
],
|
|
89
|
-
arc: {
|
|
90
|
-
center: start,
|
|
91
|
-
radius,
|
|
92
|
-
startAngle: arc.startAngle,
|
|
93
|
-
endAngle: arc.endAngle,
|
|
94
|
-
y: y + DRAFT_AXIS_ANGLE_ARC_Y_OFFSET,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
54
|
function toWallPlanPoint(point) {
|
|
99
55
|
return [point.x, point.y];
|
|
100
56
|
}
|
|
@@ -340,13 +296,23 @@ function getBelowLevelWalls() {
|
|
|
340
296
|
export const WallTool = () => {
|
|
341
297
|
const unit = useViewer((state) => state.unit);
|
|
342
298
|
const isDark = useViewer((state) => getSceneTheme(state.sceneTheme).appearance === 'dark');
|
|
299
|
+
const activeLevelId = useViewer((state) => state.selection.levelId);
|
|
300
|
+
const activeLevelHeight = useScene((state) => {
|
|
301
|
+
const level = activeLevelId ? state.nodes[activeLevelId] : undefined;
|
|
302
|
+
return level?.type === 'level' ? (level.height ?? DEFAULT_LEVEL_HEIGHT) : DEFAULT_LEVEL_HEIGHT;
|
|
303
|
+
});
|
|
343
304
|
// A placed wall preset seeds `toolDefaults.wall` (height / thickness …)
|
|
344
305
|
// before the tool mounts, so the draft preview is drawn at the preset's
|
|
345
306
|
// dimensions rather than the generic fallbacks — matching the wall that
|
|
346
307
|
// will be created. Read through refs so the live event handlers below see
|
|
347
308
|
// the latest values without re-subscribing.
|
|
348
309
|
const wallDefaults = useEditor((s) => s.toolDefaults.wall);
|
|
349
|
-
|
|
310
|
+
// Camera for the pointer-support resolution (deck top vs floor) — read
|
|
311
|
+
// through a ref so the event handlers below see the live camera.
|
|
312
|
+
const camera = useThree((state) => state.camera);
|
|
313
|
+
const cameraRef = useRef(camera);
|
|
314
|
+
cameraRef.current = camera;
|
|
315
|
+
const previewHeight = typeof wallDefaults?.height === 'number' ? wallDefaults.height : activeLevelHeight;
|
|
350
316
|
const previewThickness = typeof wallDefaults?.thickness === 'number' ? wallDefaults.thickness : DRAFT_WALL_THICKNESS;
|
|
351
317
|
const previewHeightRef = useRef(previewHeight);
|
|
352
318
|
previewHeightRef.current = previewHeight;
|
|
@@ -361,6 +327,7 @@ export const WallTool = () => {
|
|
|
361
327
|
// the "segment tees into an existing wall" chain-termination test, so
|
|
362
328
|
// snapping onto the chain's own segments never reads as a join.
|
|
363
329
|
const chainWallIds = useRef([]);
|
|
330
|
+
const constructionPlane = useRef(null);
|
|
364
331
|
const buildingState = useRef(0);
|
|
365
332
|
const [draftMeasurement, setDraftMeasurement] = useState(null);
|
|
366
333
|
const [axisGuide, setAxisGuide] = useState(null);
|
|
@@ -409,10 +376,70 @@ export const WallTool = () => {
|
|
|
409
376
|
? [point[0] + ar.snap.dx, point[1] + ar.snap.dz]
|
|
410
377
|
: point;
|
|
411
378
|
};
|
|
379
|
+
// The walking surface the pointer actually aims at (deck top when over
|
|
380
|
+
// the deck, floor/ground underneath it) — only for genuine 3D pointer
|
|
381
|
+
// events. The 2D floor plan emits synthetic grid events with no camera
|
|
382
|
+
// ray behind them; those keep the uncapped max election and leave the
|
|
383
|
+
// grid plane alone.
|
|
384
|
+
const pointedSurfaceFor = (event) => event.nativeEvent?.target instanceof HTMLCanvasElement
|
|
385
|
+
? resolvePointerSupportSurface(cameraRef.current, event.position, {
|
|
386
|
+
includeNodeTopSurfaces: true,
|
|
387
|
+
})
|
|
388
|
+
: null;
|
|
389
|
+
const snappedWallConstructionPlane = (targetWallIds, walls) => {
|
|
390
|
+
const activeWallIds = new Set(walls.map((wall) => wall.id));
|
|
391
|
+
const targetIds = targetWallIds.filter((id) => activeWallIds.has(id));
|
|
392
|
+
if (targetIds.length === 0)
|
|
393
|
+
return null;
|
|
394
|
+
const buildingId = useViewer.getState().selection.buildingId;
|
|
395
|
+
const buildingMesh = buildingId ? sceneRegistry.nodes.get(buildingId) : undefined;
|
|
396
|
+
const currentLevelId = useViewer.getState().selection.levelId;
|
|
397
|
+
const levelMesh = currentLevelId
|
|
398
|
+
? sceneRegistry.nodes.get(currentLevelId)
|
|
399
|
+
: undefined;
|
|
400
|
+
let resolved = null;
|
|
401
|
+
for (const id of targetIds) {
|
|
402
|
+
const targetWall = walls.find((wall) => wall.id === id);
|
|
403
|
+
if (!targetWall)
|
|
404
|
+
continue;
|
|
405
|
+
const wallMesh = sceneRegistry.nodes.get(id);
|
|
406
|
+
if (!wallMesh)
|
|
407
|
+
continue;
|
|
408
|
+
wallMesh.getWorldPosition(wallSurfaceWorldScratch);
|
|
409
|
+
const worldY = wallSurfaceWorldScratch.y;
|
|
410
|
+
wallSurfaceLocalScratch.copy(wallSurfaceWorldScratch);
|
|
411
|
+
if (buildingMesh)
|
|
412
|
+
buildingMesh.worldToLocal(wallSurfaceLocalScratch);
|
|
413
|
+
const localY = wallSurfaceLocalScratch.y;
|
|
414
|
+
wallSurfaceLocalScratch.copy(wallSurfaceWorldScratch);
|
|
415
|
+
if (levelMesh)
|
|
416
|
+
levelMesh.worldToLocal(wallSurfaceLocalScratch);
|
|
417
|
+
const elevation = wallSurfaceLocalScratch.y;
|
|
418
|
+
if (resolved &&
|
|
419
|
+
(Math.abs(resolved.worldY - worldY) > 1e-4 ||
|
|
420
|
+
Math.abs((resolved.elevation ?? elevation) - elevation) > 1e-4 ||
|
|
421
|
+
resolved.supportSlabId !== (targetWall.supportSlabId ?? null))) {
|
|
422
|
+
// An ambiguous junction at different elevations transfers no plane.
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
resolved = {
|
|
426
|
+
localY,
|
|
427
|
+
worldY,
|
|
428
|
+
elevation,
|
|
429
|
+
supportSlabId: targetWall.supportSlabId ?? null,
|
|
430
|
+
sourceNodeId: targetWall.id,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
return resolved;
|
|
434
|
+
};
|
|
412
435
|
const stopDrafting = () => {
|
|
413
436
|
buildingState.current = 0;
|
|
437
|
+
constructionPlane.current = null;
|
|
414
438
|
chainFirstVertex.current = null;
|
|
415
439
|
chainWallIds.current = [];
|
|
440
|
+
const draftPreview = useFloorplanDraftPreview.getState();
|
|
441
|
+
draftPreview.setWallDraftStart(null);
|
|
442
|
+
draftPreview.setWallDraftEnd(null);
|
|
416
443
|
if (wallPreviewRef.current) {
|
|
417
444
|
wallPreviewRef.current.visible = false;
|
|
418
445
|
}
|
|
@@ -421,16 +448,31 @@ export const WallTool = () => {
|
|
|
421
448
|
useAlignmentGuides.getState().clear();
|
|
422
449
|
useWallSnapIndicator.getState().clear();
|
|
423
450
|
useSegmentDraftChain.getState().clear('wall');
|
|
451
|
+
clearPlacementSurface();
|
|
424
452
|
};
|
|
425
453
|
const onGridMove = (event) => {
|
|
426
454
|
if (!(cursorRef.current && wallPreviewRef.current))
|
|
427
455
|
return;
|
|
456
|
+
// Ride the grid event plane on the pointed surface: aiming at an
|
|
457
|
+
// elevated deck lifts the plane to the deck top, so the draft's XZ
|
|
458
|
+
// lands where the cursor points and the preview/cursor Y
|
|
459
|
+
// (`event.localPosition[1]`) sits at the base the committed wall
|
|
460
|
+
// will elect. Aiming past the deck edge drops it back to the floor.
|
|
461
|
+
const pointed = buildingState.current === 0 ? pointedSurfaceFor(event) : null;
|
|
462
|
+
if (constructionPlane.current) {
|
|
463
|
+
publishHorizontalConstructionPlane(event, constructionPlane.current);
|
|
464
|
+
}
|
|
465
|
+
else if (pointed) {
|
|
466
|
+
publishPlacementSurface(surfacePointScratch.set(event.position[0], pointed.worldY, event.position[2]), SURFACE_UP);
|
|
467
|
+
}
|
|
428
468
|
const walls = getCurrentLevelWalls();
|
|
429
469
|
// Add walls on the floor below as extra snap references so the new wall
|
|
430
470
|
// can align with the level beneath it. Kept separate from `walls` so the
|
|
431
471
|
// measurement HUD only reports against the active level.
|
|
432
472
|
const snapWalls = [...walls, ...getBelowLevelWalls()];
|
|
433
|
-
const localPoint =
|
|
473
|
+
const localPoint = pointed?.localPoint
|
|
474
|
+
? [pointed.localPoint[0], pointed.localPoint[2]]
|
|
475
|
+
: [event.localPosition[0], event.localPosition[2]];
|
|
434
476
|
// Snapping is governed entirely by the snapping mode (grid / lines /
|
|
435
477
|
// angles / off). `'off'` is the bypass — there is no Shift hold-to-bypass.
|
|
436
478
|
const angleLocked = buildingState.current === 1 && isAngleSnapActive();
|
|
@@ -451,10 +493,15 @@ export const WallTool = () => {
|
|
|
451
493
|
: null);
|
|
452
494
|
if (buildingState.current === 1) {
|
|
453
495
|
const snappedLocal = gridPosition;
|
|
454
|
-
|
|
496
|
+
const draftY = constructionPlane.current?.localY ?? event.localPosition[1];
|
|
497
|
+
endingPoint.current.set(snappedLocal[0], draftY, snappedLocal[1]);
|
|
498
|
+
const draftPreview = useFloorplanDraftPreview.getState();
|
|
499
|
+
draftPreview.setWallDraftStart([startingPoint.current.x, startingPoint.current.z]);
|
|
500
|
+
draftPreview.setWallDraftEnd(snappedLocal);
|
|
455
501
|
cursorRef.current.position.copy(endingPoint.current);
|
|
456
502
|
setAxisGuide({
|
|
457
503
|
origin: [startingPoint.current.x, startingPoint.current.z],
|
|
504
|
+
endOrigin: snappedLocal,
|
|
458
505
|
y: startingPoint.current.y,
|
|
459
506
|
angleLabel: getNearestAxisAngleLabel([startingPoint.current.x, startingPoint.current.z], snappedLocal, startingPoint.current.y),
|
|
460
507
|
});
|
|
@@ -468,7 +515,8 @@ export const WallTool = () => {
|
|
|
468
515
|
setDraftMeasurement(getDraftMeasurementState([startingPoint.current.x, startingPoint.current.z], snappedLocal, walls, unit, startingPoint.current.y, previewHeightRef.current));
|
|
469
516
|
}
|
|
470
517
|
else {
|
|
471
|
-
|
|
518
|
+
const hoverPlane = resampleTerrainConstructionPlane(resolveEventConstructionPlane(event, pointed), gridPosition);
|
|
519
|
+
cursorRef.current.position.set(gridPosition[0], hoverPlane.localY, gridPosition[1]);
|
|
472
520
|
setDraftMeasurement(null);
|
|
473
521
|
setAxisGuide(null);
|
|
474
522
|
}
|
|
@@ -482,21 +530,37 @@ export const WallTool = () => {
|
|
|
482
530
|
}
|
|
483
531
|
const walls = getCurrentLevelWalls();
|
|
484
532
|
const snapWalls = [...walls, ...getBelowLevelWalls()];
|
|
485
|
-
const
|
|
533
|
+
const pointed = buildingState.current === 0 ? pointedSurfaceFor(event) : null;
|
|
534
|
+
const localClick = pointed?.localPoint
|
|
535
|
+
? [pointed.localPoint[0], pointed.localPoint[2]]
|
|
536
|
+
: [event.localPosition[0], event.localPosition[2]];
|
|
486
537
|
if (buildingState.current === 0) {
|
|
487
|
-
const
|
|
538
|
+
const snapResult = snapWallDraftPointDetailed({
|
|
488
539
|
point: localClick,
|
|
489
540
|
walls: snapWalls,
|
|
490
541
|
magnetic: isMagneticSnapActive(),
|
|
491
|
-
})
|
|
542
|
+
});
|
|
543
|
+
const snappedStart = alignPoint(snapResult.point);
|
|
544
|
+
const resolvedPlane = (pointed?.sourceNodeId
|
|
545
|
+
? resolveEventConstructionPlane(event, pointed)
|
|
546
|
+
: pointMatches(snappedStart, snapResult.point)
|
|
547
|
+
? snappedWallConstructionPlane(snapResult.targetWallIds, walls)
|
|
548
|
+
: null) ?? resolveEventConstructionPlane(event, pointed);
|
|
549
|
+
const plane = resampleTerrainConstructionPlane(resolvedPlane, snappedStart);
|
|
550
|
+
constructionPlane.current = plane;
|
|
551
|
+
publishHorizontalConstructionPlane(event, plane);
|
|
492
552
|
gridPosition = snappedStart;
|
|
493
|
-
startingPoint.current.set(snappedStart[0],
|
|
553
|
+
startingPoint.current.set(snappedStart[0], plane.localY, snappedStart[1]);
|
|
494
554
|
chainFirstVertex.current = startingPoint.current.clone();
|
|
495
555
|
endingPoint.current.copy(startingPoint.current);
|
|
496
556
|
buildingState.current = 1;
|
|
557
|
+
const draftPreview = useFloorplanDraftPreview.getState();
|
|
558
|
+
draftPreview.setWallDraftStart(snappedStart);
|
|
559
|
+
draftPreview.setWallDraftEnd(snappedStart);
|
|
497
560
|
setAxisGuide({
|
|
498
561
|
origin: snappedStart,
|
|
499
|
-
|
|
562
|
+
endOrigin: null,
|
|
563
|
+
y: plane.localY,
|
|
500
564
|
angleLabel: null,
|
|
501
565
|
});
|
|
502
566
|
triggerSFX('sfx:structure-build-start');
|
|
@@ -523,7 +587,12 @@ export const WallTool = () => {
|
|
|
523
587
|
if (dx * dx + dz * dz < 0.01 * 0.01)
|
|
524
588
|
return;
|
|
525
589
|
// Both start and end are building-local ✓
|
|
526
|
-
const createdWall = createWallOnCurrentLevel([startingPoint.current.x, startingPoint.current.z], snappedEnd
|
|
590
|
+
const createdWall = createWallOnCurrentLevel([startingPoint.current.x, startingPoint.current.z], snappedEnd, {
|
|
591
|
+
supportCap: constructionPlane.current?.elevation ?? null,
|
|
592
|
+
preferredSupportSlabId: constructionPlane.current?.supportSlabId ?? null,
|
|
593
|
+
constructionElevation: constructionPlane.current?.elevation ?? null,
|
|
594
|
+
constructionHeight: previewHeightRef.current,
|
|
595
|
+
});
|
|
527
596
|
if (!createdWall)
|
|
528
597
|
return;
|
|
529
598
|
chainWallIds.current.push(createdWall.id);
|
|
@@ -558,13 +627,19 @@ export const WallTool = () => {
|
|
|
558
627
|
// chains its next segment from the same point (its own snap
|
|
559
628
|
// pipeline can resolve a slightly different endpoint).
|
|
560
629
|
useSegmentDraftChain.getState().setChainStart('wall', [nextStart[0], nextStart[1]]);
|
|
561
|
-
|
|
630
|
+
const draftY = constructionPlane.current?.localY ?? event.localPosition[1];
|
|
631
|
+
startingPoint.current.set(nextStart[0], draftY, nextStart[1]);
|
|
562
632
|
endingPoint.current.copy(startingPoint.current);
|
|
633
|
+
const draftPreview = useFloorplanDraftPreview.getState();
|
|
634
|
+
draftPreview.setWallDraftEnd(null);
|
|
635
|
+
draftPreview.setWallDraftStart(nextStart);
|
|
636
|
+
draftPreview.setWallDraftEnd(nextStart);
|
|
563
637
|
cursorRef.current?.position.copy(startingPoint.current);
|
|
564
638
|
buildingState.current = 1;
|
|
565
639
|
setAxisGuide({
|
|
566
640
|
origin: nextStart,
|
|
567
|
-
|
|
641
|
+
endOrigin: null,
|
|
642
|
+
y: draftY,
|
|
568
643
|
angleLabel: null,
|
|
569
644
|
});
|
|
570
645
|
// Hide the preview until the next `onGridMove` writes the
|
|
@@ -591,38 +666,15 @@ export const WallTool = () => {
|
|
|
591
666
|
emitter.off('grid:move', onGridMove);
|
|
592
667
|
emitter.off('grid:click', onGridClick);
|
|
593
668
|
emitter.off('tool:cancel', onCancel);
|
|
669
|
+
clearPlacementSurface();
|
|
594
670
|
useAlignmentGuides.getState().clear();
|
|
595
671
|
useWallSnapIndicator.getState().clear();
|
|
596
672
|
useSegmentDraftChain.getState().clear('wall');
|
|
673
|
+
const draftPreview = useFloorplanDraftPreview.getState();
|
|
674
|
+
draftPreview.setWallDraftStart(null);
|
|
675
|
+
draftPreview.setWallDraftEnd(null);
|
|
597
676
|
};
|
|
598
677
|
}, [unit]);
|
|
599
|
-
return (_jsxs("group", { children: [_jsx(
|
|
678
|
+
return (_jsxs("group", { children: [_jsx(DraftAxisGuides, { guide: axisGuide, labelColor: measurementColor, labelShadowColor: measurementShadowColor }), _jsx(CursorSphere, { height: previewHeight, ref: cursorRef }), _jsxs("mesh", { layers: EDITOR_LAYER, ref: wallPreviewRef, renderOrder: 1, visible: false, children: [_jsx("shapeGeometry", {}), _jsx("meshBasicMaterial", { color: "#818cf8", depthTest: false, depthWrite: false, opacity: 0.5, side: DoubleSide, transparent: true })] }), draftMeasurement && (_jsxs(_Fragment, { children: [_jsx(DraftMeasurementLabel, { color: measurementColor, label: draftMeasurement.lengthLabel, position: draftMeasurement.lengthPosition, shadowColor: measurementShadowColor }), draftMeasurement.angleLabels.map((angleLabel) => (_jsxs("group", { children: [_jsx(DraftAngleArc, { arc: angleLabel.arc, color: measurementColor }), _jsx(DraftMeasurementLabel, { color: measurementColor, label: angleLabel.label, position: angleLabel.position, shadowColor: measurementShadowColor })] }, angleLabel.id)))] }))] }));
|
|
600
679
|
};
|
|
601
|
-
function WallAxisGuides({ guide, labelColor, labelShadowColor, }) {
|
|
602
|
-
if (!guide)
|
|
603
|
-
return null;
|
|
604
|
-
const [x, z] = guide.origin;
|
|
605
|
-
return (_jsxs(_Fragment, { children: [_jsxs("group", { position: [x, guide.y + DRAFT_AXIS_GUIDE_Y_OFFSET, z], children: [_jsx(WallAxisGuideLine, { axis: "x" }), _jsx(WallAxisGuideLine, { axis: "z" })] }), guide.angleLabel && (_jsxs(_Fragment, { children: [_jsx(DraftAngleArc, { arc: guide.angleLabel.arc, color: "#818cf8" }), _jsx(DraftMeasurementLabel, { color: labelColor, label: guide.angleLabel.label, position: guide.angleLabel.position, shadowColor: labelShadowColor })] }))] }));
|
|
606
|
-
}
|
|
607
|
-
function WallAxisGuideLine({ axis }) {
|
|
608
|
-
return (_jsxs("mesh", { frustumCulled: false, layers: EDITOR_LAYER, renderOrder: 0, rotation: [0, axis === 'z' ? Math.PI / 2 : 0, 0], children: [_jsx("boxGeometry", { args: [DRAFT_AXIS_GUIDE_LENGTH, DRAFT_AXIS_GUIDE_HEIGHT, DRAFT_AXIS_GUIDE_WIDTH] }), _jsx("meshBasicMaterial", { color: "#818cf8", depthTest: false, depthWrite: false, opacity: 0.36, transparent: true })] }));
|
|
609
|
-
}
|
|
610
|
-
function DraftAngleArc({ arc, color }) {
|
|
611
|
-
const geometry = useMemo(() => {
|
|
612
|
-
const segmentCount = Math.max(8, Math.ceil((Math.abs(arc.endAngle - arc.startAngle) / Math.PI) * DRAFT_ANGLE_ARC_SEGMENTS));
|
|
613
|
-
const points = Array.from({ length: segmentCount + 1 }, (_, index) => {
|
|
614
|
-
const t = index / segmentCount;
|
|
615
|
-
const angle = arc.startAngle + (arc.endAngle - arc.startAngle) * t;
|
|
616
|
-
return new Vector3(arc.center[0] + Math.cos(angle) * arc.radius, arc.y, arc.center[1] + Math.sin(angle) * arc.radius);
|
|
617
|
-
});
|
|
618
|
-
return new BufferGeometry().setFromPoints(points);
|
|
619
|
-
}, [arc]);
|
|
620
|
-
return (_jsx("line", { frustumCulled: false, geometry: geometry, layers: EDITOR_LAYER, renderOrder: 2, children: _jsx("lineBasicNodeMaterial", { color: color, depthTest: false, depthWrite: false, linewidth: 2, opacity: 0.95, transparent: true }) }));
|
|
621
|
-
}
|
|
622
|
-
function DraftMeasurementLabel({ color, label, position, shadowColor, }) {
|
|
623
|
-
return (_jsx(Html, { center: true, position: position, style: { pointerEvents: 'none', userSelect: 'none' }, zIndexRange: [100, 0], children: _jsx("div", { className: "whitespace-nowrap font-bold font-mono text-[15px]", style: {
|
|
624
|
-
color,
|
|
625
|
-
textShadow: `-1.5px -1.5px 0 ${shadowColor}, 1.5px -1.5px 0 ${shadowColor}, -1.5px 1.5px 0 ${shadowColor}, 1.5px 1.5px 0 ${shadowColor}, 0 0 4px ${shadowColor}, 0 0 4px ${shadowColor}`,
|
|
626
|
-
}, children: label }) }));
|
|
627
|
-
}
|
|
628
680
|
export default WallTool;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type WallMiterData, type WallNode } from '@pascal-app/core';
|
|
2
|
+
export type WallTreatmentLevelData = {
|
|
3
|
+
walls: readonly WallNode[];
|
|
4
|
+
miterDataByProud: ReadonlyMap<number, WallMiterData>;
|
|
5
|
+
};
|
|
6
|
+
export declare function buildWallTreatmentLevelData(walls: readonly WallNode[], proudOffsets: readonly number[]): WallTreatmentLevelData;
|
|
7
|
+
export declare function treatmentMiterDataForProud(levelData: WallTreatmentLevelData, proud: number): WallMiterData | undefined;
|
|
8
|
+
type WallTreatmentLevelDataState = {
|
|
9
|
+
byLevelId: ReadonlyMap<string, WallTreatmentLevelData>;
|
|
10
|
+
setLevelData: (levelId: string, data: WallTreatmentLevelData) => void;
|
|
11
|
+
};
|
|
12
|
+
export declare const useWallTreatmentLevelData: import("zustand").UseBoundStore<import("zustand").StoreApi<WallTreatmentLevelDataState>>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=treatment-level-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treatment-level-data.d.ts","sourceRoot":"","sources":["../../src/wall/treatment-level-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAA;AASzB,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC1B,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACrD,CAAA;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,sBAAsB,CAgBxB;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,MAAM,GACZ,aAAa,GAAG,SAAS,CAE3B;AAED,KAAK,2BAA2B,GAAG;IACjC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAA;IACtD,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAA;CACtE,CAAA;AAED,eAAO,MAAM,yBAAyB,0FAQnC,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { calculateLevelMiters, getWallThickness, } from '@pascal-app/core';
|
|
2
|
+
import { create } from 'zustand';
|
|
3
|
+
const PROUD_KEY_PRECISION = 1e6;
|
|
4
|
+
function proudKey(proud) {
|
|
5
|
+
return Math.round(proud * PROUD_KEY_PRECISION) / PROUD_KEY_PRECISION;
|
|
6
|
+
}
|
|
7
|
+
export function buildWallTreatmentLevelData(walls, proudOffsets) {
|
|
8
|
+
const uniqueProudOffsets = new Set([0, ...proudOffsets.map(proudKey)]);
|
|
9
|
+
const miterDataByProud = new Map();
|
|
10
|
+
for (const proud of uniqueProudOffsets) {
|
|
11
|
+
const adjustedWalls = proud === 0
|
|
12
|
+
? [...walls]
|
|
13
|
+
: walls.map((wall) => ({
|
|
14
|
+
...wall,
|
|
15
|
+
thickness: getWallThickness(wall) + proud * 2,
|
|
16
|
+
}));
|
|
17
|
+
miterDataByProud.set(proud, calculateLevelMiters(adjustedWalls));
|
|
18
|
+
}
|
|
19
|
+
return { walls, miterDataByProud };
|
|
20
|
+
}
|
|
21
|
+
export function treatmentMiterDataForProud(levelData, proud) {
|
|
22
|
+
return levelData.miterDataByProud.get(proudKey(proud));
|
|
23
|
+
}
|
|
24
|
+
export const useWallTreatmentLevelData = create((set) => ({
|
|
25
|
+
byLevelId: new Map(),
|
|
26
|
+
setLevelData: (levelId, data) => set((state) => {
|
|
27
|
+
const byLevelId = new Map(state.byLevelId);
|
|
28
|
+
byLevelId.set(levelId, data);
|
|
29
|
+
return { byLevelId };
|
|
30
|
+
}),
|
|
31
|
+
}));
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { type SceneMaterial, type SceneMaterialId, type WallNode } from '@pascal-app/core';
|
|
1
|
+
import { type SceneMaterial, type SceneMaterialId, type WallNode, type WallTrimConfig } from '@pascal-app/core';
|
|
2
2
|
import { type RenderShading } from '@pascal-app/viewer';
|
|
3
3
|
import * as THREE from 'three';
|
|
4
|
+
import { type WallTreatmentLevelData } from './treatment-level-data';
|
|
4
5
|
type OpeningLike = {
|
|
5
6
|
type: string;
|
|
6
7
|
width?: number;
|
|
7
8
|
height?: number;
|
|
8
9
|
position?: [number, number, number];
|
|
9
10
|
};
|
|
11
|
+
type TrimKind = 'skirting' | 'crown' | 'chairRail';
|
|
12
|
+
type WallSide = 'interior' | 'exterior';
|
|
10
13
|
type SceneMaterials = Record<SceneMaterialId, SceneMaterial>;
|
|
11
14
|
type WallTreatmentSlotId = 'skirtingInterior' | 'skirtingExterior' | 'crownInterior' | 'crownExterior' | 'chairRailInterior' | 'chairRailExterior';
|
|
15
|
+
export declare function wallTreatmentProudOffsets(node: WallNode): number[];
|
|
16
|
+
export declare function buildTrimGeometry(node: WallNode, side: WallSide, trim: WallTrimConfig, kind: TrimKind, childrenNodes: OpeningLike[], levelData: WallTreatmentLevelData): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap> | null;
|
|
12
17
|
export declare function createWallExtraSlotMaterials(node: WallNode, shading: RenderShading, sceneMaterials: SceneMaterials): {
|
|
13
18
|
skirtingInterior: THREE.Material<THREE.MaterialEventMap>;
|
|
14
19
|
skirtingExterior: THREE.Material<THREE.MaterialEventMap>;
|
|
@@ -17,9 +22,10 @@ export declare function createWallExtraSlotMaterials(node: WallNode, shading: Re
|
|
|
17
22
|
chairRailInterior: THREE.Material<THREE.MaterialEventMap>;
|
|
18
23
|
chairRailExterior: THREE.Material<THREE.MaterialEventMap>;
|
|
19
24
|
};
|
|
20
|
-
export declare const WallTreatments: import("react").MemoExoticComponent<({ node, childrenNodes, materials, }: {
|
|
25
|
+
export declare const WallTreatments: import("react").MemoExoticComponent<({ node, childrenNodes, levelData, materials, }: {
|
|
21
26
|
node: WallNode;
|
|
22
27
|
childrenNodes: OpeningLike[];
|
|
28
|
+
levelData: WallTreatmentLevelData;
|
|
23
29
|
materials: Record<WallTreatmentSlotId, THREE.Material>;
|
|
24
30
|
}) => import("react").JSX.Element>;
|
|
25
31
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treatments.d.ts","sourceRoot":"","sources":["../../src/wall/treatments.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"treatments.d.ts","sourceRoot":"","sources":["../../src/wall/treatments.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,eAAe,EAMpB,KAAK,QAAQ,EAEb,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAA8B,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAMhG,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC,CAAA;AAED,KAAK,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,CAAA;AAClD,KAAK,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAA;AACvC,KAAK,cAAc,GAAG,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;AAE5D,KAAK,mBAAmB,GACpB,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,mBAAmB,CAAA;AAmNvB,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAoBlE;AAuND,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,QAAQ,EACd,aAAa,EAAE,WAAW,EAAE,EAC5B,SAAS,EAAE,sBAAsB,2FAsDlC;AAkBD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,EACtB,cAAc,EAAE,cAAc;;;;;;;EAU/B;AAED,eAAO,MAAM,cAAc,uFAKxB;IACD,IAAI,EAAE,QAAQ,CAAA;IACd,aAAa,EAAE,WAAW,EAAE,CAAA;IAC5B,SAAS,EAAE,sBAAsB,CAAA;IACjC,SAAS,EAAE,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;CACvD,iCAmEC,CAAA"}
|
package/dist/wall/treatments.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { getWallCurveFrameAt, getWallThickness, isCurvedWall, WALL_CHAIR_RAIL_DEFAULT, WALL_CROWN_DEFAULT, WALL_SKIRTING_DEFAULT, WALL_SURFACE_SLOT_DEFAULTS, } from '@pascal-app/core';
|
|
3
|
+
import { getWallCurveFrameAt, getWallMiterBoundaryPoints, getWallThickness, isCurvedWall, useScene, WALL_CHAIR_RAIL_DEFAULT, WALL_CROWN_DEFAULT, WALL_SKIRTING_DEFAULT, WALL_SURFACE_SLOT_DEFAULTS, } from '@pascal-app/core';
|
|
4
4
|
import { baseMaterial, createMaterialFromPresetRef, resolveMaterialRef, } from '@pascal-app/viewer';
|
|
5
5
|
import { memo, useEffect, useMemo } from 'react';
|
|
6
6
|
import * as THREE from 'three';
|
|
7
7
|
import { mergeGeometries as mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
8
|
+
import { resolveWallOpeningCeiling } from '../shared/wall-opening-ceiling';
|
|
9
|
+
import { treatmentMiterDataForProud } from './treatment-level-data';
|
|
8
10
|
const CURVE_SEGMENTS = 24;
|
|
9
11
|
const MIN_SLICE_PROUD = 0.0005;
|
|
10
12
|
const EPS = 1e-6;
|
|
@@ -219,6 +221,27 @@ function resolveTrimProfile(kind, trim) {
|
|
|
219
221
|
TRIM_PROFILES[kind][defaultProfile] ??
|
|
220
222
|
TRIM_PROFILES[kind].flat);
|
|
221
223
|
}
|
|
224
|
+
export function wallTreatmentProudOffsets(node) {
|
|
225
|
+
const offsets = new Set();
|
|
226
|
+
const configs = [
|
|
227
|
+
['skirting', node.skirting],
|
|
228
|
+
['crown', node.crown],
|
|
229
|
+
['chairRail', node.chairRail],
|
|
230
|
+
];
|
|
231
|
+
for (const [kind, rawConfig] of configs) {
|
|
232
|
+
const trim = { ...TRIM_KIND_CONFIG[kind].defaultConfig, ...(rawConfig ?? {}) };
|
|
233
|
+
if (!trim.enabled)
|
|
234
|
+
continue;
|
|
235
|
+
const profile = resolveTrimProfile(kind, trim);
|
|
236
|
+
if (!profile)
|
|
237
|
+
continue;
|
|
238
|
+
for (let index = 0; index < profile.samples; index += 1) {
|
|
239
|
+
const t = (index + 0.5) / profile.samples;
|
|
240
|
+
offsets.add(Math.max(MIN_SLICE_PROUD, trim.proud * profile.proudAt(t)));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return [...offsets];
|
|
244
|
+
}
|
|
222
245
|
function resolveTreatmentSideSign(node, side) {
|
|
223
246
|
if (side === 'interior') {
|
|
224
247
|
if (node.frontSide === 'interior')
|
|
@@ -261,8 +284,24 @@ function buildSidePolyline(node, side, offset) {
|
|
|
261
284
|
}
|
|
262
285
|
return points;
|
|
263
286
|
}
|
|
287
|
+
function buildMiteredSidePolyline(node, levelData, side, offset) {
|
|
288
|
+
if (isCurvedWall(node))
|
|
289
|
+
return buildSidePolyline(node, side, offset);
|
|
290
|
+
const sideSign = resolveTreatmentSideSign(node, side);
|
|
291
|
+
const toLocal = wallToLocalTransform(node);
|
|
292
|
+
const proud = offset - getWallThickness(node) / 2;
|
|
293
|
+
const boundarySource = treatmentMiterDataForProud(levelData, proud);
|
|
294
|
+
if (!boundarySource)
|
|
295
|
+
return buildSidePolyline(node, side, offset);
|
|
296
|
+
const boundary = getWallMiterBoundaryPoints({ ...node, thickness: offset * 2 }, boundarySource);
|
|
297
|
+
if (!boundary)
|
|
298
|
+
return buildSidePolyline(node, side, offset);
|
|
299
|
+
const start = sideSign > 0 ? boundary.startLeft : boundary.startRight;
|
|
300
|
+
const end = sideSign > 0 ? boundary.endLeft : boundary.endRight;
|
|
301
|
+
return [toLocal(start.x, start.y), toLocal(end.x, end.y)];
|
|
302
|
+
}
|
|
264
303
|
function clipPolyline(points, x0, x1) {
|
|
265
|
-
if (points.length < 2 || x1 - x0 <= EPS)
|
|
304
|
+
if (points.length < 2 || (x0 !== undefined && x1 !== undefined && x1 - x0 <= EPS))
|
|
266
305
|
return [];
|
|
267
306
|
const out = [];
|
|
268
307
|
for (let index = 0; index < points.length - 1; index += 1) {
|
|
@@ -272,8 +311,9 @@ function clipPolyline(points, x0, x1) {
|
|
|
272
311
|
continue;
|
|
273
312
|
const minX = Math.min(a.x, b.x);
|
|
274
313
|
const maxX = Math.max(a.x, b.x);
|
|
275
|
-
if (maxX < x0 - EPS || minX > x1 + EPS)
|
|
314
|
+
if ((x0 !== undefined && maxX < x0 - EPS) || (x1 !== undefined && minX > x1 + EPS)) {
|
|
276
315
|
continue;
|
|
316
|
+
}
|
|
277
317
|
const pushPointAt = (x) => {
|
|
278
318
|
if (Math.abs(b.x - a.x) <= EPS) {
|
|
279
319
|
return { x, z: a.z };
|
|
@@ -284,8 +324,8 @@ function clipPolyline(points, x0, x1) {
|
|
|
284
324
|
z: a.z + (b.z - a.z) * t,
|
|
285
325
|
};
|
|
286
326
|
};
|
|
287
|
-
const start = minX < x0 ? pushPointAt(x0) : a;
|
|
288
|
-
const end = maxX > x1 ? pushPointAt(x1) : b;
|
|
327
|
+
const start = x0 !== undefined && minX < x0 ? pushPointAt(x0) : a;
|
|
328
|
+
const end = x1 !== undefined && maxX > x1 ? pushPointAt(x1) : b;
|
|
289
329
|
if (out.length === 0 ||
|
|
290
330
|
Math.hypot(out[out.length - 1].x - start.x, out[out.length - 1].z - start.z) > EPS) {
|
|
291
331
|
out.push(start);
|
|
@@ -396,8 +436,8 @@ function mergeGeometries(geometries) {
|
|
|
396
436
|
return merged;
|
|
397
437
|
return null;
|
|
398
438
|
}
|
|
399
|
-
function buildTrimGeometry(node, side, trim, kind, childrenNodes) {
|
|
400
|
-
const wallHeight = node
|
|
439
|
+
export function buildTrimGeometry(node, side, trim, kind, childrenNodes, levelData) {
|
|
440
|
+
const wallHeight = resolveWallOpeningCeiling(node, useScene.getState().nodes);
|
|
401
441
|
const height = trim.height;
|
|
402
442
|
const yBottom = kind === 'crown'
|
|
403
443
|
? Math.max(0, wallHeight - height)
|
|
@@ -405,11 +445,12 @@ function buildTrimGeometry(node, side, trim, kind, childrenNodes) {
|
|
|
405
445
|
? Math.max(0, Math.min(wallHeight - height, trim.offsetY ?? WALL_CHAIR_RAIL_DEFAULT.offsetY ?? 0.9))
|
|
406
446
|
: 0;
|
|
407
447
|
const thickness = getWallThickness(node);
|
|
408
|
-
const inner =
|
|
448
|
+
const inner = buildMiteredSidePolyline(node, levelData, side, thickness / 2);
|
|
409
449
|
if (inner.length < 2)
|
|
410
450
|
return null;
|
|
451
|
+
const wallLength = Math.hypot(node.end[0] - node.start[0], node.end[1] - node.start[1]);
|
|
411
452
|
const openingRanges = trimOpeningRanges(node, childrenNodes, yBottom, height);
|
|
412
|
-
const fullRanges = [[
|
|
453
|
+
const fullRanges = [[0, wallLength]];
|
|
413
454
|
const runs = subtractOpeningRanges(fullRanges, openingRanges);
|
|
414
455
|
if (runs.length === 0)
|
|
415
456
|
return null;
|
|
@@ -419,14 +460,16 @@ function buildTrimGeometry(node, side, trim, kind, childrenNodes) {
|
|
|
419
460
|
return null;
|
|
420
461
|
const sliceHeight = height / profile.samples;
|
|
421
462
|
for (const [runStart, runEnd] of runs) {
|
|
422
|
-
const
|
|
463
|
+
const clipStart = runStart > EPS ? runStart : undefined;
|
|
464
|
+
const clipEnd = runEnd < wallLength - EPS ? runEnd : undefined;
|
|
465
|
+
const innerRun = clipPolyline(inner, clipStart, clipEnd);
|
|
423
466
|
if (innerRun.length < 2)
|
|
424
467
|
continue;
|
|
425
468
|
for (let index = 0; index < profile.samples; index += 1) {
|
|
426
469
|
const t = (index + 0.5) / profile.samples;
|
|
427
470
|
const proud = Math.max(MIN_SLICE_PROUD, trim.proud * profile.proudAt(t));
|
|
428
|
-
const outerRun =
|
|
429
|
-
const outerClipped = clipPolyline(outerRun,
|
|
471
|
+
const outerRun = buildMiteredSidePolyline(node, levelData, side, thickness / 2 + proud);
|
|
472
|
+
const outerClipped = clipPolyline(outerRun, clipStart, clipEnd);
|
|
430
473
|
if (outerClipped.length < 2)
|
|
431
474
|
continue;
|
|
432
475
|
const slice = buildTrimSliceGeometry(outerClipped, innerRun, sliceHeight, yBottom + index * sliceHeight);
|
|
@@ -459,7 +502,7 @@ export function createWallExtraSlotMaterials(node, shading, sceneMaterials) {
|
|
|
459
502
|
chairRailExterior: resolveWallSlotMaterial(node, 'chairRailExterior', shading, sceneMaterials),
|
|
460
503
|
};
|
|
461
504
|
}
|
|
462
|
-
export const WallTreatments = memo(function WallTreatments({ node, childrenNodes, materials, }) {
|
|
505
|
+
export const WallTreatments = memo(function WallTreatments({ node, childrenNodes, levelData, materials, }) {
|
|
463
506
|
const fallbackMaterial = materials.skirtingInterior ??
|
|
464
507
|
materials.skirtingExterior ??
|
|
465
508
|
materials.crownInterior ??
|
|
@@ -481,7 +524,7 @@ export const WallTreatments = memo(function WallTreatments({ node, childrenNodes
|
|
|
481
524
|
? ['interior', 'exterior']
|
|
482
525
|
: [trim.sides];
|
|
483
526
|
for (const side of sides) {
|
|
484
|
-
const geometry = buildTrimGeometry(node, side, trim, kind, childrenNodes);
|
|
527
|
+
const geometry = buildTrimGeometry(node, side, trim, kind, childrenNodes, levelData);
|
|
485
528
|
if (!geometry)
|
|
486
529
|
continue;
|
|
487
530
|
const slotId = TRIM_KIND_CONFIG[kind].slots[side];
|
|
@@ -494,7 +537,7 @@ export const WallTreatments = memo(function WallTreatments({ node, childrenNodes
|
|
|
494
537
|
}
|
|
495
538
|
}
|
|
496
539
|
return out;
|
|
497
|
-
}, [childrenNodes, fallbackMaterial, materials, node]);
|
|
540
|
+
}, [childrenNodes, fallbackMaterial, levelData, materials, node]);
|
|
498
541
|
useEffect(() => () => {
|
|
499
542
|
for (const entry of trimEntries)
|
|
500
543
|
entry.geometry.dispose();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextual-dimensions.d.ts","sourceRoot":"","sources":["../../src/window/contextual-dimensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAGtF,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,eAAe,GACnB,iBAAiB,GAAG,IAAI,CAK1B"}
|