@pascal-app/nodes 1.0.3 → 1.0.5
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 +43 -0
- package/dist/agent-operations/index.d.ts +12 -0
- package/dist/agent-operations/index.d.ts.map +1 -0
- package/dist/agent-operations/index.js +6 -0
- package/dist/agent-tools/index.d.ts +50 -0
- package/dist/agent-tools/index.d.ts.map +1 -0
- package/dist/agent-tools/index.js +21 -0
- package/dist/block/commands.d.ts +2 -2
- package/dist/block/contextual-help.js +1 -1
- package/dist/block/definition.d.ts +1 -1
- package/dist/block/definition.d.ts.map +1 -1
- package/dist/block/definition.js +30 -15
- package/dist/block/edit-session.d.ts +2 -2
- package/dist/block/edit-session.d.ts.map +1 -1
- package/dist/block/edit-session.js +1 -1
- package/dist/block/face-host.js +1 -1
- package/dist/block/floorplan.d.ts +11 -1
- package/dist/block/floorplan.d.ts.map +1 -1
- package/dist/block/floorplan.js +81 -13
- package/dist/block/geometry-snap.d.ts +2 -2
- package/dist/block/geometry-snap.js +2 -2
- package/dist/block/geometry.d.ts +2 -2
- package/dist/block/geometry.d.ts.map +1 -1
- package/dist/block/geometry.js +39 -24
- package/dist/block/gesture-wheel.d.ts.map +1 -1
- package/dist/block/hosted-edit.d.ts +1 -1
- package/dist/block/hosted-edit.d.ts.map +1 -1
- package/dist/block/hosted-edit.js +28 -3
- package/dist/block/interaction-sfx.d.ts +1 -1
- package/dist/block/last-operation.d.ts +1 -1
- package/dist/block/last-operation.js +2 -2
- package/dist/block/material-slots.d.ts +1 -3
- package/dist/block/material-slots.d.ts.map +1 -1
- package/dist/block/material-slots.js +1 -11
- package/dist/block/modal-face-operation.d.ts +2 -2
- package/dist/block/modal-face-operation.js +1 -1
- package/dist/block/paint.d.ts.map +1 -1
- package/dist/block/paint.js +5 -11
- package/dist/block/panel.d.ts.map +1 -1
- package/dist/block/panel.js +15 -10
- package/dist/block/parametrics.d.ts +1 -1
- package/dist/block/parametrics.js +1 -1
- package/dist/block/preview.js +1 -1
- package/dist/block/selection-geometry.d.ts +1 -1
- package/dist/block/selection-geometry.js +1 -1
- package/dist/block/selection.d.ts.map +1 -1
- package/dist/block/selection.js +20 -20
- package/dist/block/tool.d.ts.map +1 -1
- package/dist/block/tool.js +3 -3
- package/dist/block/use-block-face-operation.d.ts +4 -4
- package/dist/block/use-block-face-operation.js +6 -6
- package/dist/box-vent/definition.d.ts +1 -1
- package/dist/box-vent/definition.d.ts.map +1 -1
- package/dist/box-vent/definition.js +11 -13
- package/dist/box-vent/geometry.d.ts.map +1 -1
- package/dist/box-vent/geometry.js +2 -2
- package/dist/box-vent/index.d.ts +3 -3
- package/dist/box-vent/index.js +3 -3
- package/dist/box-vent/move-tool.js +4 -4
- package/dist/box-vent/paint.js +2 -2
- package/dist/box-vent/panel.d.ts.map +1 -1
- package/dist/box-vent/panel.js +7 -30
- package/dist/box-vent/parametrics.d.ts +1 -1
- package/dist/box-vent/parametrics.js +1 -1
- package/dist/box-vent/preview.d.ts +1 -1
- package/dist/box-vent/preview.d.ts.map +1 -1
- package/dist/box-vent/preview.js +2 -2
- package/dist/box-vent/renderer.d.ts.map +1 -1
- package/dist/box-vent/renderer.js +3 -3
- package/dist/box-vent/tool.d.ts.map +1 -1
- package/dist/box-vent/tool.js +7 -7
- package/dist/building/definition.d.ts +1 -1
- package/dist/building/definition.d.ts.map +1 -1
- package/dist/building/definition.js +5 -4
- package/dist/building/index.d.ts +1 -1
- package/dist/building/index.js +1 -1
- package/dist/building/move-tool.d.ts.map +1 -1
- package/dist/building/move-tool.js +2 -3
- package/dist/building/renderer.d.ts.map +1 -1
- package/dist/cabinet/__bench__/geometry.d.ts +2 -0
- package/dist/cabinet/__bench__/geometry.d.ts.map +1 -0
- package/dist/cabinet/__bench__/geometry.js +21 -0
- package/dist/cabinet/appliance-layout.d.ts +1 -1
- package/dist/cabinet/appliance-layout.d.ts.map +1 -1
- package/dist/cabinet/compartment-card.d.ts +1 -1
- package/dist/cabinet/compartment-card.js +12 -12
- package/dist/cabinet/continuous-placement.d.ts +1 -1
- package/dist/cabinet/continuous-placement.js +2 -2
- package/dist/cabinet/countertop-layout.d.ts +64 -53
- package/dist/cabinet/countertop-layout.d.ts.map +1 -1
- package/dist/cabinet/countertop-layout.js +3 -3
- package/dist/cabinet/definition.d.ts +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +34 -30
- package/dist/cabinet/essential-controls.d.ts +7 -0
- package/dist/cabinet/essential-controls.d.ts.map +1 -0
- package/dist/cabinet/essential-controls.js +47 -0
- package/dist/cabinet/finish-operation.d.ts +9 -0
- package/dist/cabinet/finish-operation.d.ts.map +1 -0
- package/dist/cabinet/finish-operation.js +86 -0
- package/dist/cabinet/floorplan-move.js +3 -3
- package/dist/cabinet/floorplan.d.ts.map +1 -1
- package/dist/cabinet/floorplan.js +130 -33
- package/dist/cabinet/geometry/cooktop.d.ts +2 -2
- package/dist/cabinet/geometry/cooktop.d.ts.map +1 -1
- package/dist/cabinet/geometry/cooktop.js +55 -18
- package/dist/cabinet/geometry/dishwasher.d.ts +1 -1
- package/dist/cabinet/geometry/dishwasher.d.ts.map +1 -1
- package/dist/cabinet/geometry/dishwasher.js +5 -6
- package/dist/cabinet/geometry/fridge.d.ts +2 -2
- package/dist/cabinet/geometry/fridge.d.ts.map +1 -1
- package/dist/cabinet/geometry/fridge.js +49 -8
- package/dist/cabinet/geometry/fronts.d.ts +1 -1
- package/dist/cabinet/geometry/fronts.d.ts.map +1 -1
- package/dist/cabinet/geometry/fronts.js +22 -8
- package/dist/cabinet/geometry/hood.d.ts +2 -2
- package/dist/cabinet/geometry/hood.d.ts.map +1 -1
- package/dist/cabinet/geometry/hood.js +15 -3
- package/dist/cabinet/geometry/oven-microwave.d.ts +1 -1
- package/dist/cabinet/geometry/oven-microwave.d.ts.map +1 -1
- package/dist/cabinet/geometry/oven-microwave.js +46 -21
- package/dist/cabinet/geometry/pantry.d.ts +2 -2
- package/dist/cabinet/geometry/pantry.d.ts.map +1 -1
- package/dist/cabinet/geometry/pantry.js +11 -9
- package/dist/cabinet/geometry/run.d.ts.map +1 -1
- package/dist/cabinet/geometry/run.js +18 -8
- package/dist/cabinet/geometry/shared.d.ts +5 -4
- package/dist/cabinet/geometry/shared.d.ts.map +1 -1
- package/dist/cabinet/geometry/shared.js +78 -19
- package/dist/cabinet/geometry/sink.d.ts +2 -2
- package/dist/cabinet/geometry/sink.d.ts.map +1 -1
- package/dist/cabinet/geometry/sink.js +30 -12
- package/dist/cabinet/geometry.d.ts +1 -1
- package/dist/cabinet/geometry.d.ts.map +1 -1
- package/dist/cabinet/geometry.js +15 -11
- package/dist/cabinet/hosted-resize.d.ts +2 -2
- package/dist/cabinet/hosted-resize.d.ts.map +1 -1
- package/dist/cabinet/hosted-resize.js +3 -1
- package/dist/cabinet/index.d.ts +9 -5
- package/dist/cabinet/index.d.ts.map +1 -1
- package/dist/cabinet/index.js +9 -5
- package/dist/cabinet/insertion.d.ts.map +1 -1
- package/dist/cabinet/insertion.js +3 -1
- package/dist/cabinet/interaction.js +1 -1
- package/dist/cabinet/kitchen-catalog.d.ts +14 -0
- package/dist/cabinet/kitchen-catalog.d.ts.map +1 -0
- package/dist/cabinet/kitchen-catalog.js +62 -0
- package/dist/cabinet/kitchen-collection.d.ts +11 -0
- package/dist/cabinet/kitchen-collection.d.ts.map +1 -0
- package/dist/cabinet/kitchen-collection.js +19 -0
- package/dist/cabinet/kitchen-module-actions.d.ts +8 -0
- package/dist/cabinet/kitchen-module-actions.d.ts.map +1 -0
- package/dist/cabinet/kitchen-module-actions.js +117 -0
- package/dist/cabinet/kitchen-placement.d.ts +3 -0
- package/dist/cabinet/kitchen-placement.d.ts.map +1 -0
- package/dist/cabinet/kitchen-placement.js +16 -0
- package/dist/cabinet/move-frame.js +4 -4
- package/dist/cabinet/neighbor-placement.d.ts +335 -0
- package/dist/cabinet/neighbor-placement.d.ts.map +1 -0
- package/dist/cabinet/neighbor-placement.js +48 -0
- package/dist/cabinet/opening-clearance.d.ts +22 -0
- package/dist/cabinet/opening-clearance.d.ts.map +1 -0
- package/dist/cabinet/opening-clearance.js +158 -0
- package/dist/cabinet/paint.js +1 -1
- package/dist/cabinet/panel-visibility.js +2 -2
- package/dist/cabinet/panel.d.ts.map +1 -1
- package/dist/cabinet/panel.js +86 -77
- package/dist/cabinet/parametrics.js +3 -3
- package/dist/cabinet/placement-dimensions.js +2 -2
- package/dist/cabinet/placement-notice.d.ts +6 -0
- package/dist/cabinet/placement-notice.d.ts.map +1 -0
- package/dist/cabinet/placement-notice.js +34 -0
- package/dist/cabinet/placement-status.d.ts +2 -0
- package/dist/cabinet/placement-status.d.ts.map +1 -1
- package/dist/cabinet/placement-status.js +3 -1
- package/dist/cabinet/placement-type.d.ts.map +1 -1
- package/dist/cabinet/preset-width-debt.js +2 -2
- package/dist/cabinet/presets.d.ts +3 -1
- package/dist/cabinet/presets.d.ts.map +1 -1
- package/dist/cabinet/presets.js +27 -8
- package/dist/cabinet/quick-action-icons.js +1 -1
- package/dist/cabinet/quick-actions.js +7 -7
- package/dist/cabinet/resize-limits.d.ts.map +1 -1
- package/dist/cabinet/reveals.d.ts +16 -16
- package/dist/cabinet/reveals.d.ts.map +1 -1
- package/dist/cabinet/run-finishing.d.ts +168 -0
- package/dist/cabinet/run-finishing.d.ts.map +1 -0
- package/dist/cabinet/run-finishing.js +100 -0
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +28 -8
- package/dist/cabinet/run-ops.d.ts +61 -50
- package/dist/cabinet/run-ops.d.ts.map +1 -1
- package/dist/cabinet/run-ops.js +6 -6
- package/dist/cabinet/run-panel.d.ts +11 -0
- package/dist/cabinet/run-panel.d.ts.map +1 -1
- package/dist/cabinet/run-panel.js +43 -17
- package/dist/cabinet/scene-action.js +1 -1
- package/dist/cabinet/stack-transitions.d.ts +1 -1
- package/dist/cabinet/stack-transitions.js +2 -2
- package/dist/cabinet/stack.d.ts +60 -60
- package/dist/cabinet/stack.d.ts.map +1 -1
- package/dist/cabinet/stack.js +1 -1
- package/dist/cabinet/surfaces.js +3 -3
- package/dist/cabinet/system.d.ts.map +1 -1
- package/dist/cabinet/system.js +4 -4
- package/dist/cabinet/tool.d.ts +1 -2
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +228 -105
- package/dist/cabinet/validation.js +3 -3
- package/dist/cabinet/wall-snap.d.ts +1 -1
- package/dist/cabinet/wall-snap.d.ts.map +1 -1
- package/dist/cabinet/wall-snap.js +10 -10
- package/dist/ceiling/boundary-editor.d.ts.map +1 -1
- package/dist/ceiling/boundary-editor.js +5 -3
- package/dist/ceiling/definition.d.ts +5 -5
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +31 -29
- package/dist/ceiling/floorplan-affordances.d.ts +138 -58
- package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
- package/dist/ceiling/floorplan-affordances.js +1 -2
- package/dist/ceiling/floorplan-move.d.ts.map +1 -1
- package/dist/ceiling/floorplan-move.js +1 -2
- package/dist/ceiling/floorplan.d.ts +1 -1
- package/dist/ceiling/floorplan.d.ts.map +1 -1
- package/dist/ceiling/floorplan.js +2 -1
- package/dist/ceiling/height-bounds.d.ts +19 -0
- package/dist/ceiling/height-bounds.d.ts.map +1 -0
- package/dist/ceiling/height-bounds.js +24 -0
- package/dist/ceiling/hole-editor.d.ts.map +1 -1
- package/dist/ceiling/hole-editor.js +3 -4
- package/dist/ceiling/index.d.ts +2 -2
- package/dist/ceiling/index.js +2 -2
- package/dist/ceiling/materials.d.ts +8 -4
- package/dist/ceiling/materials.d.ts.map +1 -1
- package/dist/ceiling/materials.js +55 -21
- package/dist/ceiling/move-tool.d.ts.map +1 -1
- package/dist/ceiling/paint.d.ts +2 -8
- package/dist/ceiling/paint.d.ts.map +1 -1
- package/dist/ceiling/paint.js +112 -24
- package/dist/ceiling/panel.d.ts.map +1 -1
- package/dist/ceiling/panel.js +42 -25
- package/dist/ceiling/parametrics.d.ts +1 -1
- package/dist/ceiling/parametrics.js +1 -1
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +56 -21
- package/dist/ceiling/system.d.ts.map +1 -1
- package/dist/ceiling/tool.d.ts.map +1 -1
- package/dist/ceiling/tool.js +1 -1
- package/dist/chimney/definition.d.ts +1 -1
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +9 -8
- package/dist/chimney/floorplan.js +1 -1
- package/dist/chimney/holes.js +1 -1
- package/dist/chimney/index.d.ts +3 -3
- package/dist/chimney/index.js +3 -3
- package/dist/chimney/move-tool.d.ts.map +1 -1
- package/dist/chimney/move-tool.js +11 -5
- package/dist/chimney/paint.d.ts.map +1 -1
- package/dist/chimney/paint.js +3 -10
- package/dist/chimney/panel.js +4 -4
- package/dist/chimney/parametrics.d.ts +1 -1
- package/dist/chimney/parametrics.js +1 -1
- package/dist/chimney/presets.d.ts +1 -1
- package/dist/chimney/preview.d.ts.map +1 -1
- package/dist/chimney/preview.js +2 -2
- package/dist/chimney/renderer.d.ts.map +1 -1
- package/dist/chimney/renderer.js +4 -4
- package/dist/chimney/roof-trim.js +2 -2
- package/dist/chimney/tool.d.ts.map +1 -1
- package/dist/chimney/tool.js +6 -6
- package/dist/column/definition.d.ts +1 -1
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +39 -15
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +7 -2
- package/dist/column/floorplan-move.js +2 -2
- package/dist/column/floorplan.d.ts +1 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +48 -3
- package/dist/column/hosted-resize.d.ts +134 -29
- package/dist/column/hosted-resize.d.ts.map +1 -1
- package/dist/column/hosted-resize.js +1 -1
- package/dist/column/index.d.ts +1 -1
- package/dist/column/index.js +1 -1
- package/dist/column/paint.js +1 -1
- package/dist/column/panel.d.ts.map +1 -1
- package/dist/column/panel.js +152 -149
- package/dist/column/parametrics.d.ts +1 -1
- package/dist/column/parametrics.js +2 -2
- package/dist/column/renderer.d.ts.map +1 -1
- package/dist/column/renderer.js +8 -6
- package/dist/column/surface.d.ts.map +1 -1
- package/dist/column/surface.js +8 -1
- package/dist/column/tool.d.ts.map +1 -1
- package/dist/column/tool.js +3 -3
- package/dist/construction-dimension/definition.d.ts +1 -1
- package/dist/construction-dimension/definition.js +6 -6
- package/dist/construction-dimension/floorplan-affordances.js +1 -1
- package/dist/construction-dimension/floorplan-tool.d.ts.map +1 -1
- package/dist/construction-dimension/floorplan-tool.js +1 -1
- package/dist/construction-dimension/floorplan.js +11 -7
- package/dist/construction-dimension/index.d.ts +3 -3
- package/dist/construction-dimension/index.js +3 -3
- package/dist/construction-dimension/panel.js +1 -1
- package/dist/construction-dimension/parametrics.js +1 -1
- package/dist/cupola/definition.d.ts +1 -1
- package/dist/cupola/definition.d.ts.map +1 -1
- package/dist/cupola/definition.js +11 -16
- package/dist/cupola/geometry.d.ts.map +1 -1
- package/dist/cupola/geometry.js +1 -1
- package/dist/cupola/index.d.ts +3 -3
- package/dist/cupola/index.js +3 -3
- package/dist/cupola/move-tool.js +4 -4
- package/dist/cupola/paint.js +2 -2
- package/dist/cupola/panel.d.ts.map +1 -1
- package/dist/cupola/panel.js +6 -24
- package/dist/cupola/parametrics.d.ts +1 -1
- package/dist/cupola/parametrics.js +1 -1
- package/dist/cupola/preview.d.ts +1 -1
- package/dist/cupola/preview.d.ts.map +1 -1
- package/dist/cupola/preview.js +2 -2
- package/dist/cupola/renderer.d.ts.map +1 -1
- package/dist/cupola/renderer.js +3 -3
- package/dist/cupola/tool.d.ts.map +1 -1
- package/dist/cupola/tool.js +7 -7
- package/dist/door/contextual-dimensions.js +1 -1
- package/dist/door/definition.d.ts +1 -1
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +38 -25
- package/dist/door/door-math.d.ts +6 -11
- package/dist/door/door-math.d.ts.map +1 -1
- package/dist/door/door-math.js +15 -16
- package/dist/door/floorplan-affordances.js +2 -2
- package/dist/door/floorplan-move.d.ts.map +1 -1
- package/dist/door/floorplan-move.js +7 -5
- package/dist/door/floorplan.d.ts.map +1 -1
- package/dist/door/floorplan.js +57 -23
- package/dist/door/index.d.ts +2 -2
- package/dist/door/index.js +2 -2
- package/dist/door/mechanism.d.ts +4 -0
- package/dist/door/mechanism.d.ts.map +1 -0
- package/dist/door/mechanism.js +24 -0
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +82 -58
- package/dist/door/paint.d.ts.map +1 -1
- package/dist/door/paint.js +4 -1
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +43 -268
- package/dist/door/parametrics.d.ts +1 -1
- package/dist/door/parametrics.js +1 -1
- package/dist/door/placement.d.ts +45 -0
- package/dist/door/placement.d.ts.map +1 -0
- package/dist/door/placement.js +51 -0
- package/dist/door/preview.d.ts +1 -1
- package/dist/door/preview.d.ts.map +1 -1
- package/dist/door/preview.js +3 -1
- package/dist/door/renderer.d.ts.map +1 -1
- package/dist/door/renderer.js +4 -3
- package/dist/door/system.d.ts.map +1 -1
- package/dist/door/system.js +1 -1
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +99 -28
- package/dist/dormer/csg-geometry.d.ts.map +1 -1
- package/dist/dormer/csg-geometry.js +3 -1
- package/dist/dormer/definition.d.ts +1 -1
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +10 -9
- package/dist/dormer/index.d.ts +4 -4
- package/dist/dormer/index.js +3 -3
- package/dist/dormer/move-tool.d.ts.map +1 -1
- package/dist/dormer/move-tool.js +3 -3
- package/dist/dormer/paint.d.ts.map +1 -1
- package/dist/dormer/paint.js +2 -5
- package/dist/dormer/panel-actions-section.js +1 -1
- package/dist/dormer/panel-windows-section.js +1 -1
- package/dist/dormer/panel.d.ts.map +1 -1
- package/dist/dormer/panel.js +12 -22
- package/dist/dormer/parametrics.d.ts +1 -1
- package/dist/dormer/parametrics.js +1 -1
- package/dist/dormer/placement-guides.js +3 -3
- package/dist/dormer/preview.d.ts +1 -1
- package/dist/dormer/preview.d.ts.map +1 -1
- package/dist/dormer/preview.js +2 -2
- package/dist/dormer/renderer.d.ts +1 -1
- package/dist/dormer/renderer.d.ts.map +1 -1
- package/dist/dormer/renderer.js +2 -2
- package/dist/dormer/tool.d.ts.map +1 -1
- package/dist/dormer/tool.js +6 -6
- package/dist/dormer/use-dormer-placement.js +3 -3
- package/dist/downspout/definition.d.ts +1 -1
- package/dist/downspout/definition.d.ts.map +1 -1
- package/dist/downspout/definition.js +11 -10
- package/dist/downspout/geometry.d.ts +1 -1
- package/dist/downspout/geometry.js +2 -2
- package/dist/downspout/index.d.ts +3 -3
- package/dist/downspout/index.js +3 -3
- package/dist/downspout/parametrics.d.ts +1 -1
- package/dist/downspout/parametrics.js +1 -1
- package/dist/downspout/preview.d.ts +2 -2
- package/dist/downspout/preview.d.ts.map +1 -1
- package/dist/downspout/preview.js +3 -3
- package/dist/downspout/renderer.d.ts.map +1 -1
- package/dist/downspout/renderer.js +5 -5
- package/dist/downspout/routing.d.ts +2 -2
- package/dist/downspout/routing.d.ts.map +1 -1
- package/dist/downspout/routing.js +5 -4
- package/dist/downspout/system.d.ts.map +1 -1
- package/dist/downspout/tool.d.ts.map +1 -1
- package/dist/downspout/tool.js +7 -7
- package/dist/duct-fitting/accessory-geometry.js +1 -1
- package/dist/duct-fitting/definition.d.ts +1 -1
- package/dist/duct-fitting/definition.d.ts.map +1 -1
- package/dist/duct-fitting/definition.js +12 -11
- package/dist/duct-fitting/floorplan.d.ts +1 -1
- package/dist/duct-fitting/floorplan.js +5 -5
- package/dist/duct-fitting/geometry.d.ts +1 -1
- package/dist/duct-fitting/geometry.d.ts.map +1 -1
- package/dist/duct-fitting/geometry.js +4 -4
- package/dist/duct-fitting/index.d.ts +4 -4
- package/dist/duct-fitting/index.js +4 -4
- package/dist/duct-fitting/inspector-editors.d.ts +1 -1
- package/dist/duct-fitting/move-tool.d.ts.map +1 -1
- package/dist/duct-fitting/move-tool.js +12 -6
- package/dist/duct-fitting/parametrics.d.ts +1 -1
- package/dist/duct-fitting/parametrics.js +3 -3
- package/dist/duct-fitting/ports.d.ts +1 -1
- package/dist/duct-fitting/selection.d.ts.map +1 -1
- package/dist/duct-fitting/selection.js +8 -9
- package/dist/duct-fitting/tool.d.ts +1 -1
- package/dist/duct-fitting/tool.d.ts.map +1 -1
- package/dist/duct-fitting/tool.js +14 -15
- package/dist/duct-segment/continuation.d.ts +3 -3
- package/dist/duct-segment/continuation.d.ts.map +1 -1
- package/dist/duct-segment/continuation.js +2 -2
- package/dist/duct-segment/definition.d.ts +1 -1
- package/dist/duct-segment/definition.d.ts.map +1 -1
- package/dist/duct-segment/definition.js +14 -14
- package/dist/duct-segment/floorplan.d.ts +1 -1
- package/dist/duct-segment/floorplan.js +3 -3
- package/dist/duct-segment/geometry.d.ts +1 -1
- package/dist/duct-segment/geometry.d.ts.map +1 -1
- package/dist/duct-segment/geometry.js +2 -2
- package/dist/duct-segment/index.d.ts +3 -3
- package/dist/duct-segment/index.js +3 -3
- package/dist/duct-segment/move-tool.d.ts.map +1 -1
- package/dist/duct-segment/move-tool.js +16 -9
- package/dist/duct-segment/parametrics.d.ts +1 -1
- package/dist/duct-segment/parametrics.js +5 -5
- package/dist/duct-segment/selection.d.ts.map +1 -1
- package/dist/duct-segment/selection.js +13 -12
- package/dist/duct-segment/tool.d.ts +1 -2
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +22 -18
- package/dist/duct-terminal/definition.d.ts +1 -1
- package/dist/duct-terminal/definition.js +6 -6
- package/dist/duct-terminal/floorplan.d.ts +1 -1
- package/dist/duct-terminal/floorplan.js +1 -1
- package/dist/duct-terminal/geometry.d.ts +1 -1
- package/dist/duct-terminal/geometry.js +2 -2
- package/dist/duct-terminal/index.d.ts +4 -4
- package/dist/duct-terminal/index.js +4 -4
- package/dist/duct-terminal/parametrics.d.ts +1 -1
- package/dist/duct-terminal/ports.d.ts +1 -1
- package/dist/duct-terminal/ports.js +1 -1
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +11 -12
- package/dist/elevator/definition.d.ts +1 -1
- package/dist/elevator/definition.d.ts.map +1 -1
- package/dist/elevator/definition.js +8 -9
- package/dist/elevator/floorplan-affordances.js +1 -1
- package/dist/elevator/index.d.ts +1 -1
- package/dist/elevator/index.js +1 -1
- package/dist/elevator/paint.js +1 -1
- package/dist/elevator/panel.d.ts.map +1 -1
- package/dist/elevator/panel.js +14 -36
- package/dist/elevator/parametrics.js +2 -2
- package/dist/elevator/renderer.d.ts.map +1 -1
- package/dist/elevator/renderer.js +4 -5
- package/dist/elevator/system.js +1 -1
- package/dist/eyebrow-vent/definition.d.ts +1 -1
- package/dist/eyebrow-vent/definition.d.ts.map +1 -1
- package/dist/eyebrow-vent/definition.js +11 -13
- package/dist/eyebrow-vent/geometry.d.ts.map +1 -1
- package/dist/eyebrow-vent/geometry.js +1 -1
- package/dist/eyebrow-vent/index.d.ts +3 -3
- package/dist/eyebrow-vent/index.js +3 -3
- package/dist/eyebrow-vent/move-tool.js +4 -4
- package/dist/eyebrow-vent/paint.d.ts.map +1 -1
- package/dist/eyebrow-vent/paint.js +5 -8
- package/dist/eyebrow-vent/panel.d.ts.map +1 -1
- package/dist/eyebrow-vent/panel.js +6 -24
- package/dist/eyebrow-vent/parametrics.d.ts +1 -1
- package/dist/eyebrow-vent/parametrics.js +1 -1
- package/dist/eyebrow-vent/preview.d.ts +1 -1
- package/dist/eyebrow-vent/preview.d.ts.map +1 -1
- package/dist/eyebrow-vent/preview.js +2 -2
- package/dist/eyebrow-vent/renderer.d.ts.map +1 -1
- package/dist/eyebrow-vent/renderer.js +3 -3
- package/dist/eyebrow-vent/tool.d.ts.map +1 -1
- package/dist/eyebrow-vent/tool.js +7 -7
- package/dist/fence/actions/move-endpoint.d.ts +1 -1
- package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
- package/dist/fence/actions/move-endpoint.js +2 -1
- package/dist/fence/curve-tool.d.ts.map +1 -1
- package/dist/fence/definition.d.ts +3 -2
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +113 -43
- package/dist/fence/drafting.d.ts +42 -0
- package/dist/fence/drafting.d.ts.map +1 -0
- package/dist/fence/drafting.js +269 -0
- package/dist/fence/feature-tool.d.ts +4 -0
- package/dist/fence/feature-tool.d.ts.map +1 -0
- package/dist/fence/feature-tool.js +140 -0
- package/dist/fence/features.d.ts +2 -0
- package/dist/fence/features.d.ts.map +1 -0
- package/dist/fence/features.js +12 -0
- package/dist/fence/floorplan-affordances.d.ts.map +1 -1
- package/dist/fence/floorplan-affordances.js +2 -1
- package/dist/fence/floorplan.d.ts +2 -3
- package/dist/fence/floorplan.d.ts.map +1 -1
- package/dist/fence/floorplan.js +131 -71
- package/dist/fence/geometry-parts.d.ts +50 -0
- package/dist/fence/geometry-parts.d.ts.map +1 -0
- package/dist/fence/geometry-parts.js +1144 -0
- package/dist/fence/geometry.d.ts +2 -3
- package/dist/fence/geometry.d.ts.map +1 -1
- package/dist/fence/geometry.js +85 -8
- package/dist/fence/index.d.ts +3 -2
- package/dist/fence/index.d.ts.map +1 -1
- package/dist/fence/index.js +3 -2
- package/dist/fence/inspector-editors.d.ts +15 -0
- package/dist/fence/inspector-editors.d.ts.map +1 -1
- package/dist/fence/inspector-editors.js +128 -3
- package/dist/fence/lift.d.ts +3 -3
- package/dist/fence/lift.d.ts.map +1 -1
- package/dist/fence/lift.js +15 -3
- package/dist/fence/move-control-point-tool.d.ts.map +1 -1
- package/dist/fence/move-endpoint-tool.d.ts.map +1 -1
- package/dist/fence/move-endpoint-tool.js +4 -4
- package/dist/fence/move-tangent-tool.d.ts.map +1 -1
- package/dist/fence/move-tool.d.ts.map +1 -1
- package/dist/fence/move-tool.js +2 -1
- package/dist/fence/paint.js +1 -1
- package/dist/fence/panel-model.d.ts +4 -0
- package/dist/fence/panel-model.d.ts.map +1 -0
- package/dist/fence/panel-model.js +12 -0
- package/dist/fence/parametrics.d.ts +1 -13
- package/dist/fence/parametrics.d.ts.map +1 -1
- package/dist/fence/parametrics.js +185 -18
- package/dist/fence/system.d.ts.map +1 -1
- package/dist/fence/system.js +142 -32
- package/dist/fence/tool.d.ts.map +1 -1
- package/dist/fence/tool.js +339 -56
- package/dist/fence-feature/actions.d.ts +7 -0
- package/dist/fence-feature/actions.d.ts.map +1 -0
- package/dist/fence-feature/actions.js +26 -0
- package/dist/fence-feature/definition.d.ts +4 -0
- package/dist/fence-feature/definition.d.ts.map +1 -0
- package/dist/fence-feature/definition.js +116 -0
- package/dist/fence-feature/floorplan-affordances.d.ts +3 -0
- package/dist/fence-feature/floorplan-affordances.d.ts.map +1 -0
- package/dist/fence-feature/floorplan-affordances.js +37 -0
- package/dist/fence-feature/floorplan.d.ts +4 -0
- package/dist/fence-feature/floorplan.d.ts.map +1 -0
- package/dist/fence-feature/floorplan.js +120 -0
- package/dist/fence-feature/geometry.d.ts +5 -0
- package/dist/fence-feature/geometry.d.ts.map +1 -0
- package/dist/fence-feature/geometry.js +43 -0
- package/dist/fence-feature/handles.d.ts +5 -0
- package/dist/fence-feature/handles.d.ts.map +1 -0
- package/dist/fence-feature/handles.js +84 -0
- package/dist/fence-feature/inspector.d.ts +6 -0
- package/dist/fence-feature/inspector.d.ts.map +1 -0
- package/dist/fence-feature/inspector.js +214 -0
- package/dist/fence-feature/interaction.d.ts +3 -0
- package/dist/fence-feature/interaction.d.ts.map +1 -0
- package/dist/fence-feature/interaction.js +41 -0
- package/dist/fence-feature/move-session.d.ts +9 -0
- package/dist/fence-feature/move-session.d.ts.map +1 -0
- package/dist/fence-feature/move-session.js +48 -0
- package/dist/fence-feature/move-tool.d.ts +5 -0
- package/dist/fence-feature/move-tool.d.ts.map +1 -0
- package/dist/fence-feature/move-tool.js +58 -0
- package/dist/fence-feature/pick-target.d.ts +7 -0
- package/dist/fence-feature/pick-target.d.ts.map +1 -0
- package/dist/fence-feature/pick-target.js +52 -0
- package/dist/floor-opening/definition.d.ts +3 -0
- package/dist/floor-opening/definition.d.ts.map +1 -0
- package/dist/floor-opening/definition.js +41 -0
- package/dist/floor-opening/floorplan.d.ts +156 -0
- package/dist/floor-opening/floorplan.d.ts.map +1 -0
- package/dist/floor-opening/floorplan.js +63 -0
- package/dist/guide/definition.d.ts +1 -1
- package/dist/guide/definition.js +4 -4
- package/dist/guide/index.d.ts +1 -1
- package/dist/guide/index.js +1 -1
- package/dist/guide/renderer.d.ts.map +1 -1
- package/dist/guide/system.d.ts.map +1 -1
- package/dist/gutter/definition.d.ts +1 -1
- package/dist/gutter/definition.d.ts.map +1 -1
- package/dist/gutter/definition.js +12 -11
- package/dist/gutter/downspouts-panel.js +3 -3
- package/dist/gutter/eave-align.js +2 -2
- package/dist/gutter/eave-snap.d.ts.map +1 -1
- package/dist/gutter/eave-snap.js +2 -2
- package/dist/gutter/floorplan.d.ts.map +1 -1
- package/dist/gutter/floorplan.js +5 -4
- package/dist/gutter/geometry.d.ts +1 -1
- package/dist/gutter/geometry.js +3 -3
- package/dist/gutter/index.d.ts +3 -3
- package/dist/gutter/index.js +3 -3
- package/dist/gutter/move-tool.js +4 -4
- package/dist/gutter/outlet-lookup.d.ts +1 -1
- package/dist/gutter/outlet-lookup.js +1 -1
- package/dist/gutter/paint.js +1 -1
- package/dist/gutter/parametrics.d.ts +1 -1
- package/dist/gutter/parametrics.js +1 -1
- package/dist/gutter/preview.d.ts +1 -1
- package/dist/gutter/preview.d.ts.map +1 -1
- package/dist/gutter/preview.js +3 -3
- package/dist/gutter/renderer.d.ts.map +1 -1
- package/dist/gutter/renderer.js +6 -6
- package/dist/gutter/tool.d.ts.map +1 -1
- package/dist/gutter/tool.js +7 -7
- package/dist/hvac-equipment/definition.d.ts +1 -1
- package/dist/hvac-equipment/definition.js +6 -6
- package/dist/hvac-equipment/floorplan.d.ts +1 -1
- package/dist/hvac-equipment/floorplan.js +2 -2
- package/dist/hvac-equipment/geometry.d.ts +1 -1
- package/dist/hvac-equipment/geometry.js +2 -2
- package/dist/hvac-equipment/index.d.ts +4 -4
- package/dist/hvac-equipment/index.js +4 -4
- package/dist/hvac-equipment/parametrics.d.ts +1 -1
- package/dist/hvac-equipment/ports.d.ts +1 -1
- package/dist/hvac-equipment/ports.js +1 -1
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +7 -8
- package/dist/imported-mesh/definition.d.ts +1 -1
- package/dist/imported-mesh/definition.d.ts.map +1 -1
- package/dist/imported-mesh/definition.js +5 -3
- package/dist/imported-mesh/geometry.d.ts +1 -1
- package/dist/imported-mesh/geometry.d.ts.map +1 -1
- package/dist/imported-mesh/geometry.js +40 -12
- package/dist/imported-mesh/index.d.ts +3 -3
- package/dist/imported-mesh/index.js +3 -3
- package/dist/index.d.ts +65 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +122 -100
- package/dist/item/authored-face-host.d.ts +10 -0
- package/dist/item/authored-face-host.d.ts.map +1 -0
- package/dist/item/authored-face-host.js +87 -0
- package/dist/item/authored-params.d.ts +15 -0
- package/dist/item/authored-params.d.ts.map +1 -0
- package/dist/item/authored-params.js +72 -0
- package/dist/item/definition.d.ts +3 -3
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +46 -15
- package/dist/item/floorplan-move.js +4 -4
- package/dist/item/floorplan.d.ts +1 -1
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +36 -6
- package/dist/item/index.d.ts +3 -2
- package/dist/item/index.d.ts.map +1 -1
- package/dist/item/index.js +3 -2
- package/dist/item/model-loader.d.ts +7 -0
- package/dist/item/model-loader.d.ts.map +1 -1
- package/dist/item/model-loader.js +104 -23
- package/dist/item/move-tool.d.ts.map +1 -1
- package/dist/item/move-tool.js +4 -4
- package/dist/item/paint.d.ts.map +1 -1
- package/dist/item/paint.js +5 -24
- package/dist/item/panel.d.ts +1 -3
- package/dist/item/panel.d.ts.map +1 -1
- package/dist/item/panel.js +23 -27
- package/dist/item/parametrics.d.ts +1 -1
- package/dist/item/parametrics.js +1 -1
- package/dist/item/placement-notice.d.ts +14 -0
- package/dist/item/placement-notice.d.ts.map +1 -0
- package/dist/item/placement-notice.js +38 -0
- package/dist/item/plan-symbols.d.ts +67 -0
- package/dist/item/plan-symbols.d.ts.map +1 -0
- package/dist/item/plan-symbols.js +407 -0
- package/dist/item/renderer.d.ts +10 -0
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +78 -48
- package/dist/item/script-param-defaults.d.ts +12 -0
- package/dist/item/script-param-defaults.d.ts.map +1 -0
- package/dist/item/script-param-defaults.js +34 -0
- package/dist/item/system.d.ts.map +1 -1
- package/dist/item/system.js +7 -2
- package/dist/item/tool.d.ts.map +1 -1
- package/dist/item/tool.js +3 -3
- package/dist/item/wall-object-observations.d.ts +6 -0
- package/dist/item/wall-object-observations.d.ts.map +1 -0
- package/dist/item/wall-object-observations.js +260 -0
- package/dist/lean-to-extension/assembly.d.ts +2 -2
- package/dist/lean-to-extension/assembly.js +8 -8
- package/dist/lean-to-extension/canopy-joint.d.ts +1 -1
- package/dist/lean-to-extension/canopy-joint.js +1 -1
- package/dist/lean-to-extension/corner-joint.js +4 -4
- package/dist/lean-to-extension/definition.d.ts +1 -1
- package/dist/lean-to-extension/definition.d.ts.map +1 -1
- package/dist/lean-to-extension/definition.js +18 -18
- package/dist/lean-to-extension/floorplan-affordances.js +4 -4
- package/dist/lean-to-extension/floorplan-move.js +4 -4
- package/dist/lean-to-extension/floorplan-tool.d.ts.map +1 -1
- package/dist/lean-to-extension/floorplan-tool.js +7 -7
- package/dist/lean-to-extension/floorplan.js +5 -5
- package/dist/lean-to-extension/geometry.d.ts.map +1 -1
- package/dist/lean-to-extension/geometry.js +5 -5
- package/dist/lean-to-extension/index.d.ts +7 -7
- package/dist/lean-to-extension/index.js +7 -7
- package/dist/lean-to-extension/layout.d.ts +1 -1
- package/dist/lean-to-extension/layout.d.ts.map +1 -1
- package/dist/lean-to-extension/layout.js +6 -7
- package/dist/lean-to-extension/managed-preview.js +4 -4
- package/dist/lean-to-extension/move-tool.d.ts.map +1 -1
- package/dist/lean-to-extension/move-tool.js +5 -5
- package/dist/lean-to-extension/paint.js +1 -1
- package/dist/lean-to-extension/parametrics.js +1 -1
- package/dist/lean-to-extension/placement-validation.d.ts.map +1 -1
- package/dist/lean-to-extension/placement-validation.js +9 -9
- package/dist/lean-to-extension/placement.d.ts +1 -1
- package/dist/lean-to-extension/placement.js +6 -6
- package/dist/lean-to-extension/plan-footprint.js +2 -2
- package/dist/lean-to-extension/preview-geometry.js +1 -1
- package/dist/lean-to-extension/preview.d.ts.map +1 -1
- package/dist/lean-to-extension/preview.js +1 -1
- package/dist/lean-to-extension/renderer.d.ts.map +1 -1
- package/dist/lean-to-extension/renderer.js +1 -1
- package/dist/lean-to-extension/roof-attachment.d.ts.map +1 -1
- package/dist/lean-to-extension/roof-attachment.js +4 -4
- package/dist/lean-to-extension/system.d.ts.map +1 -1
- package/dist/lean-to-extension/system.js +10 -10
- package/dist/lean-to-extension/tool.d.ts.map +1 -1
- package/dist/lean-to-extension/tool.js +16 -16
- package/dist/level/definition.d.ts +1 -1
- package/dist/level/definition.d.ts.map +1 -1
- package/dist/level/definition.js +5 -4
- package/dist/level/index.d.ts +1 -1
- package/dist/level/index.js +1 -1
- package/dist/level/renderer.d.ts.map +1 -1
- package/dist/level/system.d.ts.map +1 -1
- package/dist/lineset/definition.d.ts +1 -1
- package/dist/lineset/definition.js +8 -8
- package/dist/lineset/floorplan.d.ts +1 -1
- package/dist/lineset/floorplan.js +1 -1
- package/dist/lineset/geometry.d.ts +1 -1
- package/dist/lineset/geometry.js +1 -1
- package/dist/lineset/index.d.ts +3 -3
- package/dist/lineset/index.js +3 -3
- package/dist/lineset/move-tool.d.ts.map +1 -1
- package/dist/lineset/move-tool.js +10 -4
- package/dist/lineset/parametrics.d.ts +1 -1
- package/dist/lineset/selection.d.ts.map +1 -1
- package/dist/lineset/selection.js +1 -1
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +7 -8
- package/dist/liquid-line/definition.d.ts +1 -1
- package/dist/liquid-line/definition.js +8 -8
- package/dist/liquid-line/floorplan.d.ts +1 -1
- package/dist/liquid-line/floorplan.js +1 -1
- package/dist/liquid-line/geometry.d.ts +1 -1
- package/dist/liquid-line/geometry.js +1 -1
- package/dist/liquid-line/index.d.ts +4 -4
- package/dist/liquid-line/index.js +4 -4
- package/dist/liquid-line/move-tool.d.ts.map +1 -1
- package/dist/liquid-line/move-tool.js +9 -3
- package/dist/liquid-line/parametrics.d.ts +1 -1
- package/dist/liquid-line/selection.d.ts.map +1 -1
- package/dist/liquid-line/selection.js +1 -1
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +9 -10
- package/dist/measurement/definition.d.ts +1 -1
- package/dist/measurement/definition.js +7 -7
- package/dist/measurement/edit.d.ts +1 -1
- package/dist/measurement/floorplan-affordance.js +2 -2
- package/dist/measurement/floorplan.js +2 -2
- package/dist/measurement/index.d.ts +2 -2
- package/dist/measurement/index.js +2 -2
- package/dist/measurement/renderer.d.ts.map +1 -1
- package/dist/measurement/renderer.js +2 -2
- package/dist/measurement/selection.d.ts.map +1 -1
- package/dist/measurement/selection.js +4 -4
- package/dist/measurement/smart-surface.d.ts +1 -1
- package/dist/measurement/smart-tool.d.ts.map +1 -1
- package/dist/measurement/smart-tool.js +2 -2
- package/dist/measurement/surface-query.js +1 -1
- package/dist/measurement/tool-router.js +2 -2
- package/dist/measurement/tool.d.ts +1 -1
- package/dist/measurement/tool.d.ts.map +1 -1
- package/dist/measurement/tool.js +3 -3
- package/dist/pipe-fitting/definition.d.ts +1 -1
- package/dist/pipe-fitting/definition.js +11 -11
- package/dist/pipe-fitting/floorplan.d.ts +1 -1
- package/dist/pipe-fitting/floorplan.js +4 -4
- package/dist/pipe-fitting/geometry.d.ts +1 -1
- package/dist/pipe-fitting/geometry.js +4 -4
- package/dist/pipe-fitting/index.d.ts +4 -4
- package/dist/pipe-fitting/index.js +4 -4
- package/dist/pipe-fitting/inline-insertion.d.ts +1 -1
- package/dist/pipe-fitting/inline-insertion.d.ts.map +1 -1
- package/dist/pipe-fitting/inline-insertion.js +1 -1
- package/dist/pipe-fitting/move-tool.d.ts.map +1 -1
- package/dist/pipe-fitting/move-tool.js +11 -5
- package/dist/pipe-fitting/parametrics.d.ts +1 -1
- package/dist/pipe-fitting/parametrics.js +1 -1
- package/dist/pipe-fitting/ports.d.ts +1 -1
- package/dist/pipe-fitting/ports.js +1 -1
- package/dist/pipe-fitting/selection.d.ts.map +1 -1
- package/dist/pipe-fitting/selection.js +6 -7
- package/dist/pipe-fitting/tool.d.ts +2 -2
- package/dist/pipe-fitting/tool.d.ts.map +1 -1
- package/dist/pipe-fitting/tool.js +15 -16
- package/dist/pipe-segment/continuation.d.ts +4 -4
- package/dist/pipe-segment/continuation.d.ts.map +1 -1
- package/dist/pipe-segment/continuation.js +1 -1
- package/dist/pipe-segment/definition.d.ts +1 -1
- package/dist/pipe-segment/definition.js +11 -11
- package/dist/pipe-segment/floorplan.d.ts +1 -1
- package/dist/pipe-segment/floorplan.js +3 -3
- package/dist/pipe-segment/geometry.d.ts +1 -1
- package/dist/pipe-segment/geometry.js +2 -2
- package/dist/pipe-segment/index.d.ts +3 -3
- package/dist/pipe-segment/index.js +3 -3
- package/dist/pipe-segment/move-tool.d.ts.map +1 -1
- package/dist/pipe-segment/move-tool.js +11 -5
- package/dist/pipe-segment/parametrics.d.ts +1 -1
- package/dist/pipe-segment/parametrics.js +3 -3
- package/dist/pipe-segment/selection.d.ts.map +1 -1
- package/dist/pipe-segment/selection.js +10 -9
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +13 -14
- package/dist/pipe-trap/definition.d.ts +1 -1
- package/dist/pipe-trap/definition.js +6 -6
- package/dist/pipe-trap/floorplan.d.ts +1 -1
- package/dist/pipe-trap/floorplan.js +1 -1
- package/dist/pipe-trap/geometry.d.ts +1 -1
- package/dist/pipe-trap/geometry.js +2 -2
- package/dist/pipe-trap/index.d.ts +4 -4
- package/dist/pipe-trap/index.js +4 -4
- package/dist/pipe-trap/parametrics.d.ts +1 -1
- package/dist/pipe-trap/ports.d.ts +1 -1
- package/dist/pipe-trap/ports.js +1 -1
- package/dist/pipe-trap/tool.d.ts.map +1 -1
- package/dist/pipe-trap/tool.js +7 -8
- package/dist/procedural-item/animation.d.ts +8 -0
- package/dist/procedural-item/animation.d.ts.map +1 -0
- package/dist/procedural-item/animation.js +116 -0
- package/dist/procedural-item/definition.d.ts.map +1 -1
- package/dist/procedural-item/definition.js +81 -13
- package/dist/procedural-item/geometry.d.ts +5 -1
- package/dist/procedural-item/geometry.d.ts.map +1 -1
- package/dist/procedural-item/geometry.js +239 -15
- package/dist/procedural-item/index.d.ts +2 -2
- package/dist/procedural-item/index.js +2 -2
- package/dist/procedural-item/move-session.d.ts +1 -1
- package/dist/procedural-item/move-session.js +2 -2
- package/dist/procedural-item/move-tool.js +3 -3
- package/dist/procedural-item/renderer.d.ts.map +1 -1
- package/dist/procedural-item/renderer.js +273 -24
- package/dist/ridge-vent/definition.d.ts +1 -1
- package/dist/ridge-vent/definition.d.ts.map +1 -1
- package/dist/ridge-vent/definition.js +9 -8
- package/dist/ridge-vent/geometry.js +1 -1
- package/dist/ridge-vent/index.d.ts +3 -3
- package/dist/ridge-vent/index.js +3 -3
- package/dist/ridge-vent/move-tool.js +5 -5
- package/dist/ridge-vent/panel.d.ts.map +1 -1
- package/dist/ridge-vent/panel.js +6 -24
- package/dist/ridge-vent/parametrics.d.ts +1 -1
- package/dist/ridge-vent/parametrics.js +1 -1
- package/dist/ridge-vent/preview.d.ts +1 -1
- package/dist/ridge-vent/preview.d.ts.map +1 -1
- package/dist/ridge-vent/preview.js +2 -2
- package/dist/ridge-vent/renderer.d.ts.map +1 -1
- package/dist/ridge-vent/renderer.js +14 -12
- package/dist/ridge-vent/tool.d.ts.map +1 -1
- package/dist/ridge-vent/tool.js +8 -8
- package/dist/roof/barrel-panel.d.ts +5 -0
- package/dist/roof/barrel-panel.d.ts.map +1 -0
- package/dist/roof/barrel-panel.js +17 -0
- package/dist/roof/conical-roof.d.ts +5 -1
- package/dist/roof/conical-roof.d.ts.map +1 -1
- package/dist/roof/conical-roof.js +19 -15
- package/dist/roof/definition.d.ts +1 -1
- package/dist/roof/definition.d.ts.map +1 -1
- package/dist/roof/definition.js +22 -11
- package/dist/roof/floorplan.d.ts +8 -0
- package/dist/roof/floorplan.d.ts.map +1 -1
- package/dist/roof/floorplan.js +202 -19
- package/dist/roof/glazed-geometry.d.ts +5 -0
- package/dist/roof/glazed-geometry.d.ts.map +1 -0
- package/dist/roof/glazed-geometry.js +27 -0
- package/dist/roof/glazed-materials.d.ts +14 -0
- package/dist/roof/glazed-materials.d.ts.map +1 -0
- package/dist/roof/glazed-materials.js +42 -0
- package/dist/roof/glazing-controls.d.ts +33 -0
- package/dist/roof/glazing-controls.d.ts.map +1 -0
- package/dist/roof/glazing-controls.js +50 -0
- package/dist/roof/glazing-panel-editor.d.ts +6 -0
- package/dist/roof/glazing-panel-editor.d.ts.map +1 -0
- package/dist/roof/glazing-panel-editor.js +44 -0
- package/dist/roof/glazing-panel.d.ts +5 -0
- package/dist/roof/glazing-panel.d.ts.map +1 -0
- package/dist/roof/glazing-panel.js +41 -0
- package/dist/roof/glazing-preview.d.ts +10 -0
- package/dist/roof/glazing-preview.d.ts.map +1 -0
- package/dist/roof/glazing-preview.js +48 -0
- package/dist/roof/index.d.ts +3 -3
- package/dist/roof/index.js +3 -3
- package/dist/roof/panel-model.d.ts.map +1 -1
- package/dist/roof/panel-model.js +10 -6
- package/dist/roof/panel.d.ts.map +1 -1
- package/dist/roof/panel.js +43 -15
- package/dist/roof/parametrics.js +1 -1
- package/dist/roof/renderer.d.ts.map +1 -1
- package/dist/roof/renderer.js +40 -7
- package/dist/roof/roof-footprint-source.d.ts.map +1 -1
- package/dist/roof/roof-level-target.d.ts +75 -0
- package/dist/roof/roof-level-target.d.ts.map +1 -0
- package/dist/roof/roof-level-target.js +119 -0
- package/dist/roof/roof-placement-mode.d.ts +3 -2
- package/dist/roof/roof-placement-mode.d.ts.map +1 -1
- package/dist/roof/system.d.ts +1 -2
- package/dist/roof/system.d.ts.map +1 -1
- package/dist/roof/system.js +5 -1
- package/dist/roof/tool.d.ts +3 -3
- package/dist/roof/tool.d.ts.map +1 -1
- package/dist/roof/tool.js +80 -41
- package/dist/roof-segment/definition.d.ts +1 -1
- package/dist/roof-segment/definition.d.ts.map +1 -1
- package/dist/roof-segment/definition.js +31 -62
- package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
- package/dist/roof-segment/floorplan-affordances.js +13 -34
- package/dist/roof-segment/floorplan.d.ts.map +1 -1
- package/dist/roof-segment/floorplan.js +1 -0
- package/dist/roof-segment/index.d.ts +1 -1
- package/dist/roof-segment/index.js +1 -1
- package/dist/roof-segment/measurement.js +1 -1
- package/dist/roof-segment/paint.d.ts +4 -0
- package/dist/roof-segment/paint.d.ts.map +1 -0
- package/dist/roof-segment/paint.js +92 -0
- package/dist/roof-segment/panel.d.ts.map +1 -1
- package/dist/roof-segment/panel.js +20 -30
- package/dist/roof-segment/parametrics.d.ts +1 -1
- package/dist/roof-segment/parametrics.d.ts.map +1 -1
- package/dist/roof-segment/parametrics.js +12 -1
- package/dist/roof-segment/renderer.d.ts +1 -1
- package/dist/roof-segment/renderer.d.ts.map +1 -1
- package/dist/roof-segment/renderer.js +81 -19
- package/dist/scan/definition.d.ts +1 -1
- package/dist/scan/definition.js +4 -4
- package/dist/scan/index.d.ts +1 -1
- package/dist/scan/index.js +1 -1
- package/dist/scan/renderer.d.ts.map +1 -1
- package/dist/scan/system.d.ts.map +1 -1
- package/dist/separator/definition.d.ts +3 -0
- package/dist/separator/definition.d.ts.map +1 -0
- package/dist/separator/definition.js +39 -0
- package/dist/separator/renderer.d.ts +5 -0
- package/dist/separator/renderer.d.ts.map +1 -0
- package/dist/separator/renderer.js +36 -0
- package/dist/shared/accessory-placement.d.ts +1 -1
- package/dist/shared/accessory-placement.d.ts.map +1 -1
- package/dist/shared/accessory-placement.js +3 -3
- package/dist/shared/accessory-snapping.d.ts +1 -1
- package/dist/shared/accessory-snapping.d.ts.map +1 -1
- package/dist/shared/accessory-snapping.js +1 -1
- package/dist/shared/auto-fitting.d.ts +1 -1
- package/dist/shared/auto-fitting.d.ts.map +1 -1
- package/dist/shared/auto-fitting.js +3 -3
- package/dist/shared/automatic-run-end-cap.d.ts +1 -1
- package/dist/shared/automatic-run-end-cap.d.ts.map +1 -1
- package/dist/shared/automatic-run-end-cap.js +4 -4
- package/dist/shared/block-face-host.d.ts +1 -1
- package/dist/shared/connection-feedback.d.ts +1 -2
- package/dist/shared/connection-feedback.d.ts.map +1 -1
- package/dist/shared/connection-feedback.js +1 -2
- package/dist/shared/construction-dimension-standards.d.ts +1 -1
- package/dist/shared/curtain-opening-limits.js +1 -1
- package/dist/shared/draft-axis-guides.js +1 -1
- package/dist/shared/duct-adapter.d.ts +2 -2
- package/dist/shared/duct-adapter.d.ts.map +1 -1
- package/dist/shared/duct-adapter.js +3 -3
- package/dist/shared/duct-body-paint.d.ts +0 -4
- package/dist/shared/duct-body-paint.d.ts.map +1 -1
- package/dist/shared/duct-body-paint.js +2 -6
- package/dist/shared/elbow-branch-continuation.d.ts +1 -1
- package/dist/shared/elbow-branch-continuation.d.ts.map +1 -1
- package/dist/shared/elbow-branch-continuation.js +2 -2
- package/dist/shared/finish-script-model.d.ts +12 -0
- package/dist/shared/finish-script-model.d.ts.map +1 -0
- package/dist/shared/finish-script-model.js +32 -0
- package/dist/shared/fitting-deletion-cleanup.js +2 -2
- package/dist/shared/fitting-endpoint-reaim.js +3 -3
- package/dist/shared/fitting-surface-support.d.ts.map +1 -1
- package/dist/shared/fitting-surface-support.js +2 -2
- package/dist/shared/fitting-tool-options.js +1 -1
- package/dist/shared/floor-placement.d.ts.map +1 -1
- package/dist/shared/floorplan-cursor.d.ts.map +1 -1
- package/dist/shared/hosted-resize.d.ts +2 -1
- package/dist/shared/hosted-resize.d.ts.map +1 -1
- package/dist/shared/hosted-resize.js +11 -3
- package/dist/shared/item-interaction-actions.d.ts +6 -0
- package/dist/shared/item-interaction-actions.d.ts.map +1 -0
- package/dist/shared/item-interaction-actions.js +27 -0
- package/dist/shared/item-interactions.d.ts +9 -0
- package/dist/shared/item-interactions.d.ts.map +1 -0
- package/dist/shared/item-interactions.js +74 -0
- package/dist/shared/item-light-placement.d.ts +2 -0
- package/dist/shared/item-light-placement.d.ts.map +1 -0
- package/dist/shared/item-light-placement.js +3 -0
- package/dist/shared/lean-to-post-omissions.d.ts +1 -1
- package/dist/shared/lean-to-post-omissions.js +1 -1
- package/dist/shared/mep-ghost.js +5 -5
- package/dist/shared/move-roof-tool.d.ts.map +1 -1
- package/dist/shared/move-roof-tool.js +129 -35
- package/dist/shared/node-batch/batchable.d.ts +12 -0
- package/dist/shared/node-batch/batchable.d.ts.map +1 -0
- package/dist/shared/node-batch/batchable.js +43 -0
- package/dist/shared/node-batch/candidates.d.ts +8 -6
- package/dist/shared/node-batch/candidates.d.ts.map +1 -1
- package/dist/shared/node-batch/candidates.js +44 -60
- package/dist/shared/node-batch/release.d.ts +8 -0
- package/dist/shared/node-batch/release.d.ts.map +1 -0
- package/dist/shared/node-batch/release.js +16 -0
- package/dist/shared/node-batch/store.d.ts +1 -1
- package/dist/shared/node-batch/store.d.ts.map +1 -1
- package/dist/shared/node-batch/store.js +1 -1
- package/dist/shared/node-batch/system.d.ts.map +1 -1
- package/dist/shared/node-batch/system.js +36 -16
- package/dist/shared/node-batch/types.d.ts +4 -1
- package/dist/shared/node-batch/types.d.ts.map +1 -1
- package/dist/shared/opening-documentation.d.ts +14 -2
- package/dist/shared/opening-documentation.d.ts.map +1 -1
- package/dist/shared/opening-documentation.js +246 -60
- package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
- package/dist/shared/opening-guides-runtime.js +18 -15
- package/dist/shared/opening-move-wall-gate.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.js +5 -5
- package/dist/shared/opening-plane-offset.d.ts +23 -0
- package/dist/shared/opening-plane-offset.d.ts.map +1 -0
- package/dist/shared/opening-plane-offset.js +24 -0
- package/dist/shared/opening-property-preview-host.d.ts +1 -1
- package/dist/shared/opening-property-preview.d.ts.map +1 -1
- package/dist/shared/opening-property-preview.js +1 -1
- package/dist/shared/panel-fields.js +2 -2
- package/dist/shared/path-point-affordance.js +2 -2
- package/dist/shared/pipe-run-translation-offset.d.ts +2 -2
- package/dist/shared/pipe-run-translation-offset.d.ts.map +1 -1
- package/dist/shared/pipe-run-translation-offset.js +2 -2
- package/dist/shared/pipe-vertical-offset.d.ts +2 -2
- package/dist/shared/pipe-vertical-offset.d.ts.map +1 -1
- package/dist/shared/pipe-vertical-offset.js +2 -2
- package/dist/shared/polygon-centroid-move.d.ts.map +1 -1
- package/dist/shared/polygon-centroid-move.js +5 -2
- package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
- package/dist/shared/polygon-vertex-affordance.js +19 -15
- package/dist/shared/port-systems.d.ts +9 -0
- package/dist/shared/port-systems.d.ts.map +1 -0
- package/dist/shared/port-systems.js +10 -0
- package/dist/shared/refrigerant-line-selection.d.ts.map +1 -1
- package/dist/shared/refrigerant-line-selection.js +3 -2
- package/dist/shared/relative-roof-drag.d.ts +1 -1
- package/dist/shared/relative-roof-drag.js +2 -2
- package/dist/shared/roof-segment-hit.d.ts.map +1 -1
- package/dist/shared/roof-segment-hit.js +7 -5
- package/dist/shared/roof-surface-placement-guides.d.ts +1 -1
- package/dist/shared/roof-surface-placement-guides.js +11 -11
- package/dist/shared/roof-surface.d.ts.map +1 -1
- package/dist/shared/roof-surface.js +25 -5
- package/dist/shared/run-hanger-controls.d.ts +1 -1
- package/dist/shared/run-hanger-controls.js +1 -1
- package/dist/shared/run-hanger-inspector.d.ts +1 -1
- package/dist/shared/run-hanger-inspector.js +3 -3
- package/dist/shared/run-hangers.d.ts.map +1 -1
- package/dist/shared/run-hangers.js +7 -6
- package/dist/shared/run-move-connectivity.d.ts.map +1 -1
- package/dist/shared/run-translation-offset.d.ts +3 -3
- package/dist/shared/run-translation-offset.d.ts.map +1 -1
- package/dist/shared/run-translation-offset.js +2 -2
- package/dist/shared/scripted-opening-handles.d.ts +18 -0
- package/dist/shared/scripted-opening-handles.d.ts.map +1 -0
- package/dist/shared/scripted-opening-handles.js +53 -0
- package/dist/shared/scripted-opening.d.ts +25 -0
- package/dist/shared/scripted-opening.d.ts.map +1 -0
- package/dist/shared/scripted-opening.js +72 -0
- package/dist/shared/slot-paint.d.ts +14 -2
- package/dist/shared/slot-paint.d.ts.map +1 -1
- package/dist/shared/slot-paint.js +29 -29
- package/dist/shared/surface-paint.d.ts.map +1 -1
- package/dist/shared/surface-paint.js +3 -6
- package/dist/shared/swap-preview-material.d.ts +13 -0
- package/dist/shared/swap-preview-material.d.ts.map +1 -0
- package/dist/shared/swap-preview-material.js +27 -0
- package/dist/shared/system-check-panel.js +1 -1
- package/dist/shared/system-checks.d.ts.map +1 -1
- package/dist/shared/system-checks.js +7 -5
- package/dist/shared/vertical-offset.d.ts +3 -3
- package/dist/shared/vertical-offset.d.ts.map +1 -1
- package/dist/shared/vertical-offset.js +3 -3
- package/dist/shared/wall-attach-target.d.ts +3 -10
- package/dist/shared/wall-attach-target.d.ts.map +1 -1
- package/dist/shared/wall-attach-target.js +3 -63
- package/dist/shared/wall-opening-ceiling.d.ts +5 -15
- package/dist/shared/wall-opening-ceiling.d.ts.map +1 -1
- package/dist/shared/wall-opening-ceiling.js +10 -18
- package/dist/shared/wall-run-move.d.ts +1 -1
- package/dist/shared/wall-run-move.d.ts.map +1 -1
- package/dist/shelf/definition.d.ts +1 -1
- package/dist/shelf/definition.d.ts.map +1 -1
- package/dist/shelf/definition.js +14 -12
- package/dist/shelf/dimensions.d.ts +1 -1
- package/dist/shelf/floorplan-affordances.js +1 -1
- package/dist/shelf/floorplan-move.js +1 -1
- package/dist/shelf/floorplan.d.ts +1 -1
- package/dist/shelf/floorplan.js +2 -2
- package/dist/shelf/geometry.d.ts +1 -1
- package/dist/shelf/geometry.d.ts.map +1 -1
- package/dist/shelf/geometry.js +2 -3
- package/dist/shelf/index.d.ts +3 -3
- package/dist/shelf/index.js +3 -3
- package/dist/shelf/paint.d.ts.map +1 -1
- package/dist/shelf/paint.js +4 -10
- package/dist/shelf/parametrics.d.ts +1 -1
- package/dist/shelf/preview.d.ts +1 -1
- package/dist/shelf/preview.d.ts.map +1 -1
- package/dist/shelf/preview.js +1 -1
- package/dist/shelf/tool.d.ts.map +1 -1
- package/dist/shelf/tool.js +3 -3
- package/dist/site/definition.d.ts +1 -1
- package/dist/site/definition.d.ts.map +1 -1
- package/dist/site/definition.js +5 -4
- package/dist/site/generic-foundation-geometry.d.ts +16 -0
- package/dist/site/generic-foundation-geometry.d.ts.map +1 -0
- package/dist/site/generic-foundation-geometry.js +75 -0
- package/dist/site/generic-foundation.d.ts +4 -0
- package/dist/site/generic-foundation.d.ts.map +1 -0
- package/dist/site/generic-foundation.js +91 -0
- package/dist/site/ground-hole.d.ts +92 -0
- package/dist/site/ground-hole.d.ts.map +1 -0
- package/dist/site/ground-hole.js +306 -0
- package/dist/site/ground-pit-geometry.d.ts +39 -0
- package/dist/site/ground-pit-geometry.d.ts.map +1 -0
- package/dist/site/ground-pit-geometry.js +213 -0
- package/dist/site/ground-pit.d.ts +45 -0
- package/dist/site/ground-pit.d.ts.map +1 -0
- package/dist/site/ground-pit.js +175 -0
- package/dist/site/ground-veil.d.ts +39 -0
- package/dist/site/ground-veil.d.ts.map +1 -0
- package/dist/site/ground-veil.js +86 -0
- package/dist/site/ground-window-system.d.ts +9 -0
- package/dist/site/ground-window-system.d.ts.map +1 -0
- package/dist/site/ground-window-system.js +108 -0
- package/dist/site/hole-noise.d.ts +11 -0
- package/dist/site/hole-noise.d.ts.map +1 -0
- package/dist/site/hole-noise.js +79 -0
- package/dist/site/index.d.ts +1 -1
- package/dist/site/index.js +1 -1
- package/dist/site/line-ribbon.d.ts +31 -0
- package/dist/site/line-ribbon.d.ts.map +1 -0
- package/dist/site/line-ribbon.js +117 -0
- package/dist/site/lot-mask.d.ts +20 -0
- package/dist/site/lot-mask.d.ts.map +1 -0
- package/dist/site/lot-mask.js +39 -0
- package/dist/site/panel.d.ts +10 -0
- package/dist/site/panel.d.ts.map +1 -0
- package/dist/site/panel.js +179 -0
- package/dist/site/parametrics.d.ts +7 -0
- package/dist/site/parametrics.d.ts.map +1 -1
- package/dist/site/parametrics.js +8 -0
- package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
- package/dist/site/recessed-slab-ground-holes.js +5 -2
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +275 -40
- package/dist/site/terrain-geometry.d.ts +28 -1
- package/dist/site/terrain-geometry.d.ts.map +1 -1
- package/dist/site/terrain-geometry.js +78 -4
- package/dist/site/terrain-holes.d.ts +15 -0
- package/dist/site/terrain-holes.d.ts.map +1 -0
- package/dist/site/terrain-holes.js +74 -0
- package/dist/site/terrain-mesh.d.ts +10 -3
- package/dist/site/terrain-mesh.d.ts.map +1 -1
- package/dist/site/terrain-mesh.js +36 -9
- package/dist/site/terrain-renderer.d.ts +11 -2
- package/dist/site/terrain-renderer.d.ts.map +1 -1
- package/dist/site/terrain-renderer.js +23 -6
- package/dist/site/underground-edge.d.ts +26 -0
- package/dist/site/underground-edge.d.ts.map +1 -0
- package/dist/site/underground-edge.js +46 -0
- package/dist/skylight/definition.d.ts +1 -1
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +11 -10
- package/dist/skylight/geometry.d.ts +1 -1
- package/dist/skylight/geometry.js +1 -1
- package/dist/skylight/index.d.ts +4 -4
- package/dist/skylight/index.js +4 -4
- package/dist/skylight/move-tool.js +4 -4
- package/dist/skylight/panel.js +3 -3
- package/dist/skylight/parametrics.d.ts +1 -1
- package/dist/skylight/parametrics.js +1 -1
- package/dist/skylight/preview.d.ts +1 -1
- package/dist/skylight/preview.d.ts.map +1 -1
- package/dist/skylight/preview.js +2 -2
- package/dist/skylight/renderer.d.ts.map +1 -1
- package/dist/skylight/renderer.js +5 -5
- package/dist/skylight/system.d.ts.map +1 -1
- package/dist/skylight/tool.d.ts.map +1 -1
- package/dist/skylight/tool.js +7 -7
- package/dist/slab/boundary-editor.d.ts +1 -1
- package/dist/slab/boundary-editor.d.ts.map +1 -1
- package/dist/slab/boundary-editor.js +13 -13
- package/dist/slab/definition.d.ts +1 -1
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +44 -19
- package/dist/slab/dependency-tracker.d.ts.map +1 -1
- package/dist/slab/dependency-tracker.js +67 -7
- package/dist/slab/elevation-limit.d.ts.map +1 -1
- package/dist/slab/elevation-limit.js +2 -2
- package/dist/slab/floorplan-affordances.d.ts +232 -60
- package/dist/slab/floorplan-affordances.d.ts.map +1 -1
- package/dist/slab/floorplan-affordances.js +1 -2
- package/dist/slab/floorplan-move.d.ts.map +1 -1
- package/dist/slab/floorplan-move.js +4 -5
- package/dist/slab/floorplan.d.ts +7 -0
- package/dist/slab/floorplan.d.ts.map +1 -1
- package/dist/slab/floorplan.js +22 -5
- package/dist/slab/geometry.d.ts.map +1 -1
- package/dist/slab/geometry.js +187 -77
- package/dist/slab/hole-editor.d.ts.map +1 -1
- package/dist/slab/index.d.ts +2 -2
- package/dist/slab/index.js +2 -2
- package/dist/slab/move-tool.d.ts.map +1 -1
- package/dist/slab/move-tool.js +7 -6
- package/dist/slab/paint.d.ts +18 -5
- package/dist/slab/paint.d.ts.map +1 -1
- package/dist/slab/paint.js +461 -9
- package/dist/slab/panel.d.ts.map +1 -1
- package/dist/slab/panel.js +32 -13
- package/dist/slab/parametrics.d.ts +1 -1
- package/dist/slab/parametrics.js +1 -1
- package/dist/slab/placement-ownership.d.ts +2 -1
- package/dist/slab/placement-ownership.d.ts.map +1 -1
- package/dist/slab/placement-ownership.js +2 -2
- package/dist/slab/quick-measurement.js +1 -1
- package/dist/slab/surface-split.d.ts +24 -0
- package/dist/slab/surface-split.d.ts.map +1 -0
- package/dist/slab/surface-split.js +389 -0
- package/dist/slab/system.d.ts.map +1 -1
- package/dist/slab/system.js +1 -1
- package/dist/slab/tool.d.ts.map +1 -1
- package/dist/slab/tool.js +7 -5
- package/dist/solar-panel/definition.d.ts +1 -1
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +8 -7
- package/dist/solar-panel/index.d.ts +4 -4
- package/dist/solar-panel/index.js +4 -4
- package/dist/solar-panel/move-tool.js +3 -3
- package/dist/solar-panel/panel.d.ts.map +1 -1
- package/dist/solar-panel/panel.js +4 -4
- package/dist/solar-panel/parametrics.d.ts +1 -1
- package/dist/solar-panel/parametrics.js +1 -1
- package/dist/solar-panel/preview.d.ts +1 -1
- package/dist/solar-panel/preview.d.ts.map +1 -1
- package/dist/solar-panel/preview.js +2 -2
- package/dist/solar-panel/renderer.d.ts.map +1 -1
- package/dist/solar-panel/renderer.js +3 -3
- package/dist/solar-panel/tool.d.ts.map +1 -1
- package/dist/solar-panel/tool.js +7 -7
- package/dist/spawn/definition.d.ts +1 -1
- package/dist/spawn/definition.js +7 -7
- package/dist/spawn/floorplan-affordances.js +1 -1
- package/dist/spawn/floorplan.d.ts +1 -1
- package/dist/spawn/index.d.ts +2 -2
- package/dist/spawn/index.js +2 -2
- package/dist/spawn/panel.js +1 -1
- package/dist/spawn/parametrics.d.ts +1 -1
- package/dist/spawn/parametrics.js +1 -1
- package/dist/spawn/renderer.d.ts.map +1 -1
- package/dist/spawn/renderer.js +1 -1
- package/dist/spawn/tool.d.ts.map +1 -1
- package/dist/spawn/tool.js +2 -2
- package/dist/stair/baluster-geometry.d.ts +21 -0
- package/dist/stair/baluster-geometry.d.ts.map +1 -0
- package/dist/stair/baluster-geometry.js +74 -0
- package/dist/stair/baluster-guard.d.ts +50 -0
- package/dist/stair/baluster-guard.d.ts.map +1 -0
- package/dist/stair/baluster-guard.js +71 -0
- package/dist/stair/boards-guard.d.ts +37 -0
- package/dist/stair/boards-guard.d.ts.map +1 -0
- package/dist/stair/boards-guard.js +61 -0
- package/dist/stair/cable-guard.d.ts +39 -0
- package/dist/stair/cable-guard.d.ts.map +1 -0
- package/dist/stair/cable-guard.js +105 -0
- package/dist/stair/construction-controls.d.ts +15 -0
- package/dist/stair/construction-controls.d.ts.map +1 -0
- package/dist/stair/construction-controls.js +29 -0
- package/dist/stair/continuous-railings.d.ts +10 -0
- package/dist/stair/continuous-railings.d.ts.map +1 -0
- package/dist/stair/continuous-railings.js +159 -0
- package/dist/stair/definition.d.ts +1 -1
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +39 -46
- package/dist/stair/documentation.d.ts +1 -1
- package/dist/stair/documentation.d.ts.map +1 -1
- package/dist/stair/documentation.js +11 -18
- package/dist/stair/floorplan-affordances.d.ts.map +1 -1
- package/dist/stair/floorplan-affordances.js +10 -26
- package/dist/stair/floorplan-move.d.ts.map +1 -1
- package/dist/stair/floorplan-move.js +90 -10
- package/dist/stair/floorplan.d.ts +2 -24
- package/dist/stair/floorplan.d.ts.map +1 -1
- package/dist/stair/floorplan.js +123 -88
- package/dist/stair/glass-guard.d.ts +72 -0
- package/dist/stair/glass-guard.d.ts.map +1 -0
- package/dist/stair/glass-guard.js +167 -0
- package/dist/stair/guard-path.d.ts +119 -0
- package/dist/stair/guard-path.d.ts.map +1 -0
- package/dist/stair/guard-path.js +208 -0
- package/dist/stair/index.d.ts +1 -1
- package/dist/stair/index.js +1 -1
- package/dist/stair/materials.d.ts +11 -0
- package/dist/stair/materials.d.ts.map +1 -0
- package/dist/stair/materials.js +51 -0
- package/dist/stair/metal-guard.d.ts +38 -0
- package/dist/stair/metal-guard.d.ts.map +1 -0
- package/dist/stair/metal-guard.js +79 -0
- package/dist/stair/paint.d.ts +32 -0
- package/dist/stair/paint.d.ts.map +1 -1
- package/dist/stair/paint.js +75 -36
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +170 -19
- package/dist/stair/parametrics.d.ts +1 -1
- package/dist/stair/parametrics.d.ts.map +1 -1
- package/dist/stair/parametrics.js +33 -16
- package/dist/stair/plan-entry.d.ts +31 -0
- package/dist/stair/plan-entry.d.ts.map +1 -0
- package/dist/stair/plan-entry.js +325 -0
- package/dist/stair/post-and-rail-guard.d.ts +31 -0
- package/dist/stair/post-and-rail-guard.d.ts.map +1 -0
- package/dist/stair/post-and-rail-guard.js +63 -0
- package/dist/stair/railing-controls.d.ts +9 -0
- package/dist/stair/railing-controls.d.ts.map +1 -0
- package/dist/stair/railing-controls.js +49 -0
- package/dist/stair/renderer.d.ts.map +1 -1
- package/dist/stair/renderer.js +355 -262
- package/dist/stair/stair-click-guard.d.ts +43 -0
- package/dist/stair/stair-click-guard.d.ts.map +1 -0
- package/dist/stair/stair-click-guard.js +44 -0
- package/dist/stair/stair-type.d.ts.map +1 -1
- package/dist/stair/stair-type.js +1 -2
- package/dist/stair/surface-move-preview.d.ts +4 -0
- package/dist/stair/surface-move-preview.d.ts.map +1 -0
- package/dist/stair/surface-move-preview.js +53 -0
- package/dist/stair/surface-transition.d.ts +9 -0
- package/dist/stair/surface-transition.d.ts.map +1 -0
- package/dist/stair/surface-transition.js +61 -0
- package/dist/stair/system.d.ts.map +1 -1
- package/dist/stair/tool.d.ts +2 -0
- package/dist/stair/tool.d.ts.map +1 -0
- package/dist/stair/tool.js +580 -0
- package/dist/stair/use-stair-render-data.d.ts +319 -0
- package/dist/stair/use-stair-render-data.d.ts.map +1 -0
- package/dist/stair/use-stair-render-data.js +73 -0
- package/dist/stair-segment/definition.d.ts +1 -1
- package/dist/stair-segment/definition.d.ts.map +1 -1
- package/dist/stair-segment/definition.js +52 -14
- package/dist/stair-segment/index.d.ts +1 -1
- package/dist/stair-segment/index.js +1 -1
- package/dist/stair-segment/panel.d.ts.map +1 -1
- package/dist/stair-segment/panel.js +38 -44
- package/dist/stair-segment/parametrics.d.ts +1 -1
- package/dist/stair-segment/parametrics.d.ts.map +1 -1
- package/dist/stair-segment/parametrics.js +22 -9
- package/dist/stair-segment/renderer.d.ts.map +1 -1
- package/dist/stair-segment/renderer.js +17 -29
- package/dist/structural-grid/definition.d.ts +1 -1
- package/dist/structural-grid/definition.js +3 -3
- package/dist/structural-grid/floorplan-tool.d.ts.map +1 -1
- package/dist/structural-grid/index.d.ts +1 -1
- package/dist/structural-grid/index.js +1 -1
- package/dist/turbine-vent/definition.d.ts +1 -1
- package/dist/turbine-vent/definition.d.ts.map +1 -1
- package/dist/turbine-vent/definition.js +11 -13
- package/dist/turbine-vent/geometry.js +1 -1
- package/dist/turbine-vent/index.d.ts +3 -3
- package/dist/turbine-vent/index.js +3 -3
- package/dist/turbine-vent/move-tool.js +4 -4
- package/dist/turbine-vent/paint.d.ts.map +1 -1
- package/dist/turbine-vent/paint.js +3 -6
- package/dist/turbine-vent/panel.d.ts.map +1 -1
- package/dist/turbine-vent/panel.js +6 -24
- package/dist/turbine-vent/parametrics.d.ts +1 -1
- package/dist/turbine-vent/parametrics.js +1 -1
- package/dist/turbine-vent/preview.d.ts +1 -1
- package/dist/turbine-vent/preview.d.ts.map +1 -1
- package/dist/turbine-vent/preview.js +2 -2
- package/dist/turbine-vent/renderer.d.ts.map +1 -1
- package/dist/turbine-vent/renderer.js +3 -3
- package/dist/turbine-vent/tool.d.ts.map +1 -1
- package/dist/turbine-vent/tool.js +7 -7
- package/dist/unit/definition.d.ts +1 -1
- package/dist/unit/definition.js +2 -2
- package/dist/unit/index.d.ts +1 -1
- package/dist/unit/index.js +1 -1
- package/dist/unit/parametrics.js +1 -1
- package/dist/unit/unit-panel.d.ts.map +1 -1
- package/dist/unit/unit-panel.js +7 -2
- package/dist/wall/actions.d.ts.map +1 -1
- package/dist/wall/actions.js +9 -4
- package/dist/wall/construction-dimensions.d.ts +3 -3
- package/dist/wall/construction-dimensions.js +14 -11
- package/dist/wall/contextual-dimensions.js +4 -4
- package/dist/wall/curtain-opening-frame.d.ts.map +1 -1
- package/dist/wall/curtain-wall-adapter.js +2 -2
- package/dist/wall/curtain-wall-floorplan.js +2 -2
- package/dist/wall/curtain-wall-geometry.d.ts.map +1 -1
- package/dist/wall/curtain-wall-geometry.js +4 -4
- package/dist/wall/curtain-wall-layout.d.ts +1 -2
- package/dist/wall/curtain-wall-layout.d.ts.map +1 -1
- package/dist/wall/curtain-wall-layout.js +1 -23
- package/dist/wall/curtain-wall-materials.d.ts +1 -1
- package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
- package/dist/wall/curtain-wall-materials.js +4 -3
- package/dist/wall/curtain-wall-panel.d.ts.map +1 -1
- package/dist/wall/curtain-wall-panel.js +4 -4
- package/dist/wall/curtain-wall-piece-geometry.d.ts +1 -1
- package/dist/wall/curve-tool.d.ts.map +1 -1
- package/dist/wall/curve-tool.js +4 -0
- package/dist/wall/definition.d.ts +1 -1
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +71 -42
- package/dist/wall/exterior.d.ts +6 -0
- package/dist/wall/exterior.d.ts.map +1 -0
- package/dist/wall/exterior.js +13 -0
- package/dist/wall/floorplan-move.d.ts +1 -1
- package/dist/wall/floorplan-move.d.ts.map +1 -1
- package/dist/wall/floorplan-move.js +21 -84
- package/dist/wall/floorplan-tool.d.ts.map +1 -1
- package/dist/wall/floorplan-tool.js +11 -12
- package/dist/wall/floorplan.d.ts +5 -3
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +188 -25
- package/dist/wall/index.d.ts +2 -2
- package/dist/wall/index.js +2 -2
- package/dist/wall/measurement.d.ts.map +1 -1
- package/dist/wall/measurement.js +6 -6
- package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
- package/dist/wall/move-endpoint-tool.js +25 -13
- package/dist/wall/move-shared.d.ts.map +1 -1
- package/dist/wall/move-shared.js +12 -8
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +120 -151
- package/dist/wall/paint.d.ts +26 -15
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +303 -119
- package/dist/wall/panel-model.d.ts +18 -0
- package/dist/wall/panel-model.d.ts.map +1 -1
- package/dist/wall/panel-model.js +82 -24
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +262 -53
- package/dist/wall/parametrics.d.ts +1 -1
- package/dist/wall/parametrics.d.ts.map +1 -1
- package/dist/wall/parametrics.js +4 -1
- package/dist/wall/pointer-transparency.d.ts +1 -1
- package/dist/wall/pointer-transparency.d.ts.map +1 -1
- package/dist/wall/preview.d.ts.map +1 -1
- package/dist/wall/property-preview.d.ts.map +1 -1
- package/dist/wall/quick-measurement.js +1 -1
- package/dist/wall/rectangle-command.d.ts +329 -37
- package/dist/wall/rectangle-command.d.ts.map +1 -1
- package/dist/wall/rectangle-tool.d.ts.map +1 -1
- package/dist/wall/rectangle-tool.js +27 -9
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +31 -10
- package/dist/wall/selection-hit-owner.d.ts.map +1 -1
- package/dist/wall/split-floorplan-layer.d.ts.map +1 -1
- package/dist/wall/split-floorplan-layer.js +10 -10
- package/dist/wall/split-pointer.js +2 -2
- package/dist/wall/split-preview.d.ts +1 -1
- package/dist/wall/split-session.d.ts.map +1 -1
- package/dist/wall/split-session.js +9 -3
- package/dist/wall/split-store.d.ts +1 -1
- package/dist/wall/split-tool.js +3 -3
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +42 -10
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +114 -53
- package/dist/wall/treatment-level-data.d.ts +3 -2
- package/dist/wall/treatment-level-data.d.ts.map +1 -1
- package/dist/wall/treatment-level-data.js +17 -13
- package/dist/wall/treatments.d.ts +11 -11
- package/dist/wall/treatments.d.ts.map +1 -1
- package/dist/wall/treatments.js +77 -57
- package/dist/wall/wall-batch-system.d.ts +7 -0
- package/dist/wall/wall-batch-system.d.ts.map +1 -1
- package/dist/wall/wall-batch-system.js +81 -7
- package/dist/wall/wall-batch.d.ts +6 -0
- package/dist/wall/wall-batch.d.ts.map +1 -1
- package/dist/wall/wall-batch.js +7 -1
- package/dist/window/contextual-dimensions.js +1 -1
- package/dist/window/corner-cue.d.ts +9 -0
- package/dist/window/corner-cue.d.ts.map +1 -0
- package/dist/window/corner-cue.js +31 -0
- package/dist/window/corner-fuse.d.ts +14 -0
- package/dist/window/corner-fuse.d.ts.map +1 -0
- package/dist/window/corner-fuse.js +42 -0
- package/dist/window/definition.d.ts +1 -1
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +39 -26
- package/dist/window/floor-projection.js +1 -1
- package/dist/window/floorplan-affordances.js +2 -2
- package/dist/window/floorplan-move.d.ts.map +1 -1
- package/dist/window/floorplan-move.js +49 -13
- package/dist/window/floorplan.d.ts.map +1 -1
- package/dist/window/floorplan.js +214 -87
- package/dist/window/index.d.ts +2 -2
- package/dist/window/index.js +2 -2
- package/dist/window/mechanism.d.ts +4 -0
- package/dist/window/mechanism.d.ts.map +1 -0
- package/dist/window/mechanism.js +20 -0
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +165 -69
- package/dist/window/paint.d.ts.map +1 -1
- package/dist/window/paint.js +4 -1
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +134 -100
- package/dist/window/parametrics.d.ts +1 -1
- package/dist/window/parametrics.d.ts.map +1 -1
- package/dist/window/parametrics.js +7 -1
- package/dist/window/placement.d.ts +29 -0
- package/dist/window/placement.d.ts.map +1 -0
- package/dist/window/placement.js +92 -0
- package/dist/window/preview.d.ts +1 -1
- package/dist/window/preview.d.ts.map +1 -1
- package/dist/window/preview.js +3 -1
- package/dist/window/renderer.d.ts.map +1 -1
- package/dist/window/renderer.js +4 -3
- package/dist/window/system.d.ts.map +1 -1
- package/dist/window/system.js +1 -1
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +207 -50
- package/dist/window/window-math.d.ts +7 -15
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +15 -21
- package/dist/zone/contextual-dimensions.d.ts.map +1 -1
- package/dist/zone/contextual-dimensions.js +6 -28
- package/dist/zone/definition.d.ts +1 -1
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +17 -15
- package/dist/zone/floorplan-affordances.d.ts +613 -37
- package/dist/zone/floorplan-affordances.d.ts.map +1 -1
- package/dist/zone/floorplan-affordances.js +1 -1
- package/dist/zone/floorplan-move.js +1 -1
- package/dist/zone/floorplan.d.ts +1 -1
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +96 -56
- package/dist/zone/index.d.ts +1 -1
- package/dist/zone/index.js +1 -1
- package/dist/zone/parametrics.js +1 -1
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +6 -17
- package/dist/zone/quick-measurement.d.ts +2 -2
- package/dist/zone/quick-measurement.d.ts.map +1 -1
- package/dist/zone/quick-measurement.js +7 -6
- package/dist/zone/renderer.d.ts +1 -1
- package/dist/zone/renderer.d.ts.map +1 -1
- package/dist/zone/renderer.js +67 -147
- package/dist/zone/room-clear-dimensions.js +4 -4
- package/dist/zone/room-documentation.d.ts +1 -1
- package/dist/zone/room-documentation.d.ts.map +1 -1
- package/dist/zone/room-documentation.js +3 -7
- package/dist/zone/system.d.ts.map +1 -1
- package/package.json +28 -15
- package/dist/block/slots.d.ts +0 -4
- package/dist/block/slots.d.ts.map +0 -1
- package/dist/block/slots.js +0 -17
- package/dist/cabinet/slots.d.ts +0 -4
- package/dist/cabinet/slots.d.ts.map +0 -1
- package/dist/cabinet/slots.js +0 -24
- package/dist/ceiling/slots.d.ts +0 -6
- package/dist/ceiling/slots.d.ts.map +0 -1
- package/dist/ceiling/slots.js +0 -7
- package/dist/column/slots.d.ts +0 -9
- package/dist/column/slots.d.ts.map +0 -1
- package/dist/column/slots.js +0 -19
- package/dist/door/slots.d.ts +0 -9
- package/dist/door/slots.d.ts.map +0 -1
- package/dist/door/slots.js +0 -20
- package/dist/elevator/slots.d.ts +0 -8
- package/dist/elevator/slots.d.ts.map +0 -1
- package/dist/elevator/slots.js +0 -17
- package/dist/fence/slots.d.ts +0 -10
- package/dist/fence/slots.d.ts.map +0 -1
- package/dist/fence/slots.js +0 -23
- package/dist/item/__fixtures__/main-floorplan.d.ts +0 -26
- package/dist/item/__fixtures__/main-floorplan.d.ts.map +0 -1
- package/dist/item/__fixtures__/main-floorplan.js +0 -297
- package/dist/lean-to-extension/slots.d.ts +0 -5
- package/dist/lean-to-extension/slots.d.ts.map +0 -1
- package/dist/lean-to-extension/slots.js +0 -15
- package/dist/shared/connection-compatibility.d.ts +0 -8
- package/dist/shared/connection-compatibility.d.ts.map +0 -1
- package/dist/shared/connection-compatibility.js +0 -28
- package/dist/shared/distribution-run-contract.d.ts +0 -49
- package/dist/shared/distribution-run-contract.d.ts.map +0 -1
- package/dist/shared/distribution-run-contract.js +0 -30
- package/dist/shared/distribution-run-tool.d.ts +0 -117
- package/dist/shared/distribution-run-tool.d.ts.map +0 -1
- package/dist/shared/distribution-run-tool.js +0 -986
- package/dist/shared/draw-alignment.d.ts +0 -25
- package/dist/shared/draw-alignment.d.ts.map +0 -1
- package/dist/shared/draw-alignment.js +0 -30
- package/dist/shared/ports.d.ts +0 -92
- package/dist/shared/ports.d.ts.map +0 -1
- package/dist/shared/ports.js +0 -305
- package/dist/shared/run-cursor.d.ts +0 -22
- package/dist/shared/run-cursor.d.ts.map +0 -1
- package/dist/shared/run-cursor.js +0 -19
- package/dist/shared/run-direction-feedback.d.ts +0 -20
- package/dist/shared/run-direction-feedback.d.ts.map +0 -1
- package/dist/shared/run-direction-feedback.js +0 -139
- package/dist/shared/run-port-snap.d.ts +0 -11
- package/dist/shared/run-port-snap.d.ts.map +0 -1
- package/dist/shared/run-port-snap.js +0 -19
- package/dist/shared/run-screen-direction.d.ts +0 -5
- package/dist/shared/run-screen-direction.d.ts.map +0 -1
- package/dist/shared/run-screen-direction.js +0 -24
- package/dist/shelf/slots.d.ts +0 -9
- package/dist/shelf/slots.d.ts.map +0 -1
- package/dist/shelf/slots.js +0 -30
- package/dist/slab/slots.d.ts +0 -10
- package/dist/slab/slots.d.ts.map +0 -1
- package/dist/slab/slots.js +0 -20
- package/dist/stair/floor-stack.d.ts +0 -10
- package/dist/stair/floor-stack.d.ts.map +0 -1
- package/dist/stair/floor-stack.js +0 -115
- package/dist/stair/slots.d.ts +0 -7
- package/dist/stair/slots.d.ts.map +0 -1
- package/dist/stair/slots.js +0 -13
- package/dist/wall/drawing-mode.d.ts +0 -12
- package/dist/wall/drawing-mode.d.ts.map +0 -1
- package/dist/wall/drawing-mode.js +0 -38
- package/dist/wall/slots.d.ts +0 -10
- package/dist/wall/slots.d.ts.map +0 -1
- package/dist/wall/slots.js +0 -92
- package/dist/window/slots.d.ts +0 -5
- package/dist/window/slots.d.ts.map +0 -1
- package/dist/window/slots.js +0 -11
|
@@ -0,0 +1,1144 @@
|
|
|
1
|
+
import { clampFencePicketRailProjection, getFenceCenterlineFrameAt, getFenceCenterlineLength, getFenceGateLeaves, resolveFenceFeatures, } from '@pascal-app/core';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
4
|
+
const MIN_CURVE_SEGMENT_LENGTH = 0.18;
|
|
5
|
+
const HORIZONTAL_FENCE_CURVE_SEGMENT_LENGTH = 0.2;
|
|
6
|
+
function createFencePartGeometry(part) {
|
|
7
|
+
if (part.geometry) {
|
|
8
|
+
return part.geometry;
|
|
9
|
+
}
|
|
10
|
+
const geometry = part.shape === 'pyramid'
|
|
11
|
+
? new THREE.ConeGeometry(0.5, 1, 4, 1, false, Math.PI / 4)
|
|
12
|
+
: part.shape === 'picket'
|
|
13
|
+
? createPicketGeometry(part.scale[0], part.scale[1], part.scale[2], part.picketTop)
|
|
14
|
+
: new THREE.BoxGeometry(1, 1, 1);
|
|
15
|
+
if (part.shape !== 'picket')
|
|
16
|
+
geometry.scale(part.scale[0], part.scale[1], part.scale[2]);
|
|
17
|
+
if (part.rotationZ)
|
|
18
|
+
geometry.rotateZ(part.rotationZ);
|
|
19
|
+
if (part.rotationY) {
|
|
20
|
+
geometry.rotateY(part.rotationY);
|
|
21
|
+
}
|
|
22
|
+
geometry.translate(part.position[0], part.position[1], part.position[2]);
|
|
23
|
+
applyFenceUVs(geometry);
|
|
24
|
+
return geometry;
|
|
25
|
+
}
|
|
26
|
+
function createPicketGeometry(width, height, depth, top = 'dog-ear') {
|
|
27
|
+
const shape = new THREE.Shape();
|
|
28
|
+
const halfWidth = width / 2;
|
|
29
|
+
const tip = height / 2;
|
|
30
|
+
const shoulder = tip - Math.min(halfWidth, height * 0.2);
|
|
31
|
+
shape.moveTo(-halfWidth, -tip);
|
|
32
|
+
shape.lineTo(halfWidth, -tip);
|
|
33
|
+
if (top === 'flat') {
|
|
34
|
+
shape.lineTo(halfWidth, tip);
|
|
35
|
+
shape.lineTo(-halfWidth, tip);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
shape.lineTo(halfWidth, shoulder);
|
|
39
|
+
if (top === 'pointed') {
|
|
40
|
+
shape.lineTo(0, tip);
|
|
41
|
+
}
|
|
42
|
+
else if (top === 'rounded') {
|
|
43
|
+
shape.absellipse(0, shoulder, halfWidth, tip - shoulder, 0, Math.PI, false, 0);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
shape.lineTo(width * 0.28, tip);
|
|
47
|
+
shape.lineTo(-width * 0.28, tip);
|
|
48
|
+
}
|
|
49
|
+
shape.lineTo(-halfWidth, shoulder);
|
|
50
|
+
}
|
|
51
|
+
shape.closePath();
|
|
52
|
+
const geometry = new THREE.ExtrudeGeometry(shape, {
|
|
53
|
+
bevelEnabled: false,
|
|
54
|
+
curveSegments: 8,
|
|
55
|
+
depth,
|
|
56
|
+
steps: 1,
|
|
57
|
+
});
|
|
58
|
+
geometry.translate(0, 0, -depth / 2);
|
|
59
|
+
return geometry;
|
|
60
|
+
}
|
|
61
|
+
function getInfillOffset(fence, supportDepth, infillDepth) {
|
|
62
|
+
const direction = fence.infillPlacement === 'front' ? 1 : fence.infillPlacement === 'back' ? -1 : 0;
|
|
63
|
+
// A small overlap avoids coincident faces at the attachment surface.
|
|
64
|
+
return direction * Math.max(0, (supportDepth + infillDepth) / 2 - 0.002);
|
|
65
|
+
}
|
|
66
|
+
function getFencePointAt(fence, t) {
|
|
67
|
+
const frame = getFenceCenterlineFrameAt(fence, t);
|
|
68
|
+
return {
|
|
69
|
+
point: frame.point,
|
|
70
|
+
tangentAngle: Math.atan2(frame.tangent.y, frame.tangent.x),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function createFenceCurveBlockPart(fence, startT, endT, centerY, height, depth, lateralOffset = 0) {
|
|
74
|
+
if (endT - startT <= 1e-5)
|
|
75
|
+
return null;
|
|
76
|
+
const halfHeight = height / 2;
|
|
77
|
+
const halfDepth = depth / 2;
|
|
78
|
+
const centerlineLength = getFenceCenterlineLength(fence);
|
|
79
|
+
const startDistance = startT * centerlineLength;
|
|
80
|
+
const endDistance = endT * centerlineLength;
|
|
81
|
+
const bottomY = centerY - halfHeight;
|
|
82
|
+
const topY = centerY + halfHeight;
|
|
83
|
+
const corners = [];
|
|
84
|
+
for (const t of [startT, endT]) {
|
|
85
|
+
const frame = getFencePointAt(fence, t);
|
|
86
|
+
const normalX = -Math.sin(frame.tangentAngle);
|
|
87
|
+
const normalZ = Math.cos(frame.tangentAngle);
|
|
88
|
+
const outerX = frame.point.x + normalX * (halfDepth + lateralOffset);
|
|
89
|
+
const outerZ = frame.point.y + normalZ * (halfDepth + lateralOffset);
|
|
90
|
+
const innerX = frame.point.x - normalX * (halfDepth - lateralOffset);
|
|
91
|
+
const innerZ = frame.point.y - normalZ * (halfDepth - lateralOffset);
|
|
92
|
+
corners.push([outerX, bottomY, outerZ], [innerX, bottomY, innerZ], [outerX, topY, outerZ], [innerX, topY, innerZ]);
|
|
93
|
+
}
|
|
94
|
+
const positions = [];
|
|
95
|
+
const uvs = [];
|
|
96
|
+
const pushVertex = (index, uv) => {
|
|
97
|
+
positions.push(...corners[index]);
|
|
98
|
+
uvs.push(...uv);
|
|
99
|
+
};
|
|
100
|
+
const pushQuad = (a, b, c, d, uvA, uvB, uvC, uvD) => {
|
|
101
|
+
pushVertex(a, uvA);
|
|
102
|
+
pushVertex(b, uvB);
|
|
103
|
+
pushVertex(c, uvC);
|
|
104
|
+
pushVertex(a, uvA);
|
|
105
|
+
pushVertex(c, uvC);
|
|
106
|
+
pushVertex(d, uvD);
|
|
107
|
+
};
|
|
108
|
+
const topOuterV = topY;
|
|
109
|
+
const topInnerV = topY + depth;
|
|
110
|
+
const innerTopV = topInnerV;
|
|
111
|
+
const innerBottomV = topInnerV + height;
|
|
112
|
+
const bottomInnerV = bottomY - depth;
|
|
113
|
+
pushQuad(0, 4, 6, 2, [startDistance, bottomY], [endDistance, bottomY], [endDistance, topY], [startDistance, topY]);
|
|
114
|
+
pushQuad(1, 3, 7, 5, [startDistance, innerBottomV], [startDistance, innerTopV], [endDistance, innerTopV], [endDistance, innerBottomV]);
|
|
115
|
+
pushQuad(2, 6, 7, 3, [startDistance, topOuterV], [endDistance, topOuterV], [endDistance, topInnerV], [startDistance, topInnerV]);
|
|
116
|
+
pushQuad(0, 1, 5, 4, [startDistance, bottomY], [startDistance, bottomInnerV], [endDistance, bottomInnerV], [endDistance, bottomY]);
|
|
117
|
+
pushQuad(0, 2, 3, 1, [0, bottomY], [0, topY], [depth, innerTopV], [depth, innerBottomV]);
|
|
118
|
+
pushQuad(4, 5, 7, 6, [0, bottomY], [depth, innerBottomV], [depth, innerTopV], [0, topY]);
|
|
119
|
+
const geometry = new THREE.BufferGeometry();
|
|
120
|
+
geometry.setAttribute('position', new THREE.Float32BufferAttribute(new Float32Array(positions), 3));
|
|
121
|
+
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(new Float32Array(uvs), 2));
|
|
122
|
+
geometry.setAttribute('uv2', new THREE.Float32BufferAttribute(new Float32Array(uvs), 2));
|
|
123
|
+
geometry.computeVertexNormals();
|
|
124
|
+
return {
|
|
125
|
+
geometry,
|
|
126
|
+
position: [0, 0, 0],
|
|
127
|
+
scale: [1, 1, 1],
|
|
128
|
+
startT,
|
|
129
|
+
endT,
|
|
130
|
+
curveBlock: { centerY, height, depth, lateralOffset },
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function createFenceCurveBlockParts(fence, startT, endT, centerY, height, depth, maxSegmentLength = MIN_CURVE_SEGMENT_LENGTH, lateralOffset = 0) {
|
|
134
|
+
const length = getFenceCenterlineLength(fence) * Math.max(1e-4, endT - startT);
|
|
135
|
+
const segmentCount = Math.max(1, Math.ceil(length / Math.max(1e-4, maxSegmentLength)));
|
|
136
|
+
const parts = [];
|
|
137
|
+
for (let index = 0; index < segmentCount; index += 1) {
|
|
138
|
+
const segmentStartT = startT + (endT - startT) * (index / segmentCount);
|
|
139
|
+
const segmentEndT = startT + (endT - startT) * ((index + 1) / segmentCount);
|
|
140
|
+
const part = createFenceCurveBlockPart(fence, segmentStartT, segmentEndT, centerY, height, depth, lateralOffset);
|
|
141
|
+
if (part)
|
|
142
|
+
parts.push(part);
|
|
143
|
+
}
|
|
144
|
+
return parts;
|
|
145
|
+
}
|
|
146
|
+
function applyFenceUVs(geometry) {
|
|
147
|
+
const position = geometry.getAttribute('position');
|
|
148
|
+
const normal = geometry.getAttribute('normal');
|
|
149
|
+
if (!(position && normal))
|
|
150
|
+
return;
|
|
151
|
+
// World-scale triplanar UVs: 1 UV unit = 1 metre, sampled from the part's
|
|
152
|
+
// local-space (already translated into fence space) coordinates with NO
|
|
153
|
+
// per-part origin shift. A shared origin keeps a tiled finish continuous
|
|
154
|
+
// across posts, rails, and infill instead of restarting the tile at each
|
|
155
|
+
// part's own min corner (the previous behaviour, which broke the 1 m
|
|
156
|
+
// contract and made adjacent parts mistile).
|
|
157
|
+
const uvs = new Float32Array(position.count * 2);
|
|
158
|
+
for (let index = 0; index < position.count; index += 1) {
|
|
159
|
+
const px = position.getX(index);
|
|
160
|
+
const py = position.getY(index);
|
|
161
|
+
const pz = position.getZ(index);
|
|
162
|
+
const nx = Math.abs(normal.getX(index));
|
|
163
|
+
const ny = Math.abs(normal.getY(index));
|
|
164
|
+
const nz = Math.abs(normal.getZ(index));
|
|
165
|
+
let u = 0;
|
|
166
|
+
let v = 0;
|
|
167
|
+
if (ny >= nx && ny >= nz) {
|
|
168
|
+
u = px;
|
|
169
|
+
v = pz;
|
|
170
|
+
}
|
|
171
|
+
else if (nx >= nz) {
|
|
172
|
+
u = pz;
|
|
173
|
+
v = py;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
u = px;
|
|
177
|
+
v = py;
|
|
178
|
+
}
|
|
179
|
+
uvs[index * 2] = u;
|
|
180
|
+
uvs[index * 2 + 1] = v;
|
|
181
|
+
}
|
|
182
|
+
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
|
|
183
|
+
geometry.setAttribute('uv2', new THREE.Float32BufferAttribute(uvs.slice(), 2));
|
|
184
|
+
}
|
|
185
|
+
function getStyleDefaults(style) {
|
|
186
|
+
if (style === 'privacy') {
|
|
187
|
+
return { spacingFactor: 0.42, postFactor: 1.35, baseFactor: 1.2, topFactor: 1.2 };
|
|
188
|
+
}
|
|
189
|
+
if (style === 'rail') {
|
|
190
|
+
return { spacingFactor: 0.68, postFactor: 0.8, baseFactor: 0.85, topFactor: 0.85 };
|
|
191
|
+
}
|
|
192
|
+
return { spacingFactor: 0.3, postFactor: 0.55, baseFactor: 1, topFactor: 0.75 };
|
|
193
|
+
}
|
|
194
|
+
function getFenceInfillVerticalBounds(fence) {
|
|
195
|
+
const height = fence.style === 'picket' ? Math.max(fence.height, 0.3) : fence.height;
|
|
196
|
+
if (fence.style === 'picket') {
|
|
197
|
+
const baseHeight = fence.baseStyle === 'floating' ? 0 : Math.min(Math.max(fence.baseHeight, 0.04), height * 0.5);
|
|
198
|
+
const bottom = Math.min(baseHeight + Math.max(fence.groundClearance, 0), height * 0.75);
|
|
199
|
+
const topClearance = Math.min(Math.max(fence.picketTopClearance ?? 0, 0), height - bottom - 0.02);
|
|
200
|
+
return { bottom, top: height - topClearance };
|
|
201
|
+
}
|
|
202
|
+
const styleDefaults = getStyleDefaults(fence.style);
|
|
203
|
+
const baseY = fence.baseStyle === 'floating' ? Math.max(fence.groundClearance, 0) : 0;
|
|
204
|
+
const baseHeight = Math.max(fence.baseHeight * (fence.style === 'horizontal' ? 1 : styleDefaults.baseFactor), 0.04);
|
|
205
|
+
const topRailHeight = Math.max(fence.topRailHeight * (fence.style === 'horizontal' ? 1 : styleDefaults.topFactor), 0.01);
|
|
206
|
+
const verticalHeight = Math.max(height - baseHeight - topRailHeight, 0.08);
|
|
207
|
+
const bottom = baseY + baseHeight;
|
|
208
|
+
return { bottom, top: bottom + verticalHeight };
|
|
209
|
+
}
|
|
210
|
+
export function getFenceFeatureDimensions(fence, feature) {
|
|
211
|
+
const bounds = getFenceInfillVerticalBounds(fence);
|
|
212
|
+
const fullPost = fence.style === 'picket' ||
|
|
213
|
+
fence.style === 'horizontal' ||
|
|
214
|
+
fence.baseStyle === 'floating' ||
|
|
215
|
+
!fence.showInfill;
|
|
216
|
+
const postBottom = fullPost ? 0 : bounds.bottom;
|
|
217
|
+
const defaults = getStyleDefaults(fence.style);
|
|
218
|
+
const railHeight = Math.max(fence.topRailHeight * (fence.style === 'horizontal' ? 1 : defaults.topFactor), 0.01);
|
|
219
|
+
const postTop = fence.style === 'picket'
|
|
220
|
+
? Math.max(fence.height, 0.3)
|
|
221
|
+
: fullPost
|
|
222
|
+
? bounds.top -
|
|
223
|
+
(fence.baseStyle === 'floating' ? Math.max(fence.groundClearance, 0) : 0) +
|
|
224
|
+
railHeight +
|
|
225
|
+
Math.max(fence.groundClearance, 0)
|
|
226
|
+
: bounds.top;
|
|
227
|
+
const matchesHeight = feature.matchFenceHeight ?? feature.matchFenceStyle !== false;
|
|
228
|
+
const bottom = feature.kind === 'opening'
|
|
229
|
+
? postBottom
|
|
230
|
+
: matchesHeight
|
|
231
|
+
? bounds.bottom
|
|
232
|
+
: (feature.clearance ?? bounds.bottom);
|
|
233
|
+
const defaultHeight = feature.kind === 'opening' ? postTop - postBottom : bounds.top - bounds.bottom;
|
|
234
|
+
const height = matchesHeight ? defaultHeight : (feature.height ?? defaultHeight);
|
|
235
|
+
const postHeight = Math.max(0.02, feature.kind === 'opening' ? height : postTop - postBottom);
|
|
236
|
+
return { bottom, height, postBottom, postHeight };
|
|
237
|
+
}
|
|
238
|
+
function distributePattern(fence, start, end, targetSpacing, minimumSpacing, minimumCount = 1) {
|
|
239
|
+
const length = Math.max(0, end - start);
|
|
240
|
+
if (length < 1e-5)
|
|
241
|
+
return minimumCount > 1 ? [start, end] : [(start + end) / 2];
|
|
242
|
+
const target = Math.max(targetSpacing, minimumSpacing);
|
|
243
|
+
const maxCount = Math.max(minimumCount, Math.floor(length / minimumSpacing) + 1);
|
|
244
|
+
const mode = fence.patternDistribution;
|
|
245
|
+
let count;
|
|
246
|
+
if (mode === 'fixed-count') {
|
|
247
|
+
count = THREE.MathUtils.clamp(Math.round(fence.patternCount), minimumCount, maxCount);
|
|
248
|
+
}
|
|
249
|
+
else if (mode === 'maximum-spacing') {
|
|
250
|
+
count = THREE.MathUtils.clamp(Math.ceil(length / target) + 1, minimumCount, maxCount);
|
|
251
|
+
}
|
|
252
|
+
else if (mode === 'equal-fit') {
|
|
253
|
+
count = THREE.MathUtils.clamp(Math.round(length / target) + 1, minimumCount, maxCount);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
count = THREE.MathUtils.clamp(Math.floor(length / target) + 1, minimumCount, maxCount);
|
|
257
|
+
}
|
|
258
|
+
if (count === 1) {
|
|
259
|
+
return [
|
|
260
|
+
mode === 'fixed-spacing' && fence.patternAlignment === 'start'
|
|
261
|
+
? start
|
|
262
|
+
: mode === 'fixed-spacing' && fence.patternAlignment === 'end'
|
|
263
|
+
? end
|
|
264
|
+
: (start + end) / 2,
|
|
265
|
+
];
|
|
266
|
+
}
|
|
267
|
+
const fixed = mode === 'fixed-spacing' && fence.patternRemainder === 'leave';
|
|
268
|
+
const spacing = fixed ? target : length / (count - 1);
|
|
269
|
+
const extra = Math.max(0, length - spacing * (count - 1));
|
|
270
|
+
const origin = fixed
|
|
271
|
+
? start +
|
|
272
|
+
(fence.patternAlignment === 'end'
|
|
273
|
+
? extra
|
|
274
|
+
: fence.patternAlignment === 'center'
|
|
275
|
+
? extra / 2
|
|
276
|
+
: 0)
|
|
277
|
+
: start;
|
|
278
|
+
return Array.from({ length: count }, (_, index) => origin + index * spacing);
|
|
279
|
+
}
|
|
280
|
+
function miterFencePartEnd(fence, part, endpoint, neighbor) {
|
|
281
|
+
if (!part.geometry || !part.curveBlock)
|
|
282
|
+
return;
|
|
283
|
+
const t = endpoint === 'start' ? 0 : 1;
|
|
284
|
+
if (Math.abs(((endpoint === 'start' ? part.startT : part.endT) ?? -1) - t) > 1e-5)
|
|
285
|
+
return;
|
|
286
|
+
const point = fence[endpoint];
|
|
287
|
+
const frame = getFenceCenterlineFrameAt(fence, t);
|
|
288
|
+
const sign = endpoint === 'start' ? 1 : -1;
|
|
289
|
+
const ux = frame.tangent.x * sign;
|
|
290
|
+
const uz = frame.tangent.y * sign;
|
|
291
|
+
const neighborAtStart = Math.hypot(neighbor.start[0] - point[0], neighbor.start[1] - point[1]) < 0.001;
|
|
292
|
+
const other = getFenceCenterlineFrameAt(neighbor, neighborAtStart ? 0 : 1);
|
|
293
|
+
const vx = other.tangent.x * (neighborAtStart ? 1 : -1);
|
|
294
|
+
const vz = other.tangent.y * (neighborAtStart ? 1 : -1);
|
|
295
|
+
const cross = ux * vz - uz * vx;
|
|
296
|
+
if (Math.abs(cross) < 0.15)
|
|
297
|
+
return;
|
|
298
|
+
const { depth, lateralOffset } = part.curveBlock;
|
|
299
|
+
const ratio = Math.max(neighbor.thickness, 0.03) / Math.max(fence.thickness, 0.03);
|
|
300
|
+
const position = part.geometry.getAttribute('position');
|
|
301
|
+
for (let index = 0; index < position.count; index += 1) {
|
|
302
|
+
const x = position.getX(index);
|
|
303
|
+
const z = position.getZ(index);
|
|
304
|
+
for (const side of [-1, 1]) {
|
|
305
|
+
const offset = lateralOffset + (side * depth) / 2;
|
|
306
|
+
const originalX = point[0] - uz * offset * sign;
|
|
307
|
+
const originalZ = point[1] + ux * offset * sign;
|
|
308
|
+
if (Math.hypot(x - originalX, z - originalZ) > 1e-4)
|
|
309
|
+
continue;
|
|
310
|
+
const neighborOffset = -offset * sign * ratio;
|
|
311
|
+
const nx = -uz * offset * sign;
|
|
312
|
+
const nz = ux * offset * sign;
|
|
313
|
+
const mx = -vz * neighborOffset;
|
|
314
|
+
const mz = vx * neighborOffset;
|
|
315
|
+
const reach = ((mx - nx) * vz - (mz - nz) * vx) / cross;
|
|
316
|
+
if (Math.abs(reach) > Math.max(depth, depth * ratio) * 4)
|
|
317
|
+
break;
|
|
318
|
+
position.setX(index, originalX + ux * reach);
|
|
319
|
+
position.setZ(index, originalZ + uz * reach);
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
position.needsUpdate = true;
|
|
324
|
+
part.geometry.computeVertexNormals();
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Horizontal-board fence — composite cladding boards stacked between square
|
|
328
|
+
* intermediate posts (each capped), instead of the vertical pickets the other
|
|
329
|
+
* styles draw. Posts march along the whole span at `postSpacing` (not just the
|
|
330
|
+
* two ends), the boards run full-length so they curve with the fence, and a
|
|
331
|
+
* thin reveal between boards leaves the groove shadow that reads as cladding.
|
|
332
|
+
*/
|
|
333
|
+
function createHorizontalFenceParts(fence, sharedEndpoints) {
|
|
334
|
+
const posts = [];
|
|
335
|
+
const infill = [];
|
|
336
|
+
const base = [];
|
|
337
|
+
const rail = [];
|
|
338
|
+
const length = Math.max(getFenceCenterlineLength(fence), 0.01);
|
|
339
|
+
const panelDepth = Math.max(fence.thickness, 0.03);
|
|
340
|
+
const clearance = Math.max(fence.groundClearance, 0);
|
|
341
|
+
const isFloating = fence.baseStyle === 'floating';
|
|
342
|
+
// 'raised': the kickboard becomes a bottom rail `clearance` up; the posts still reach the ground
|
|
343
|
+
const isRaised = fence.baseStyle === 'raised';
|
|
344
|
+
const showInfill = fence.showInfill ?? true;
|
|
345
|
+
const baseHeight = Math.max(fence.baseHeight, 0.04);
|
|
346
|
+
const topRailHeight = Math.max(fence.topRailHeight, 0.01);
|
|
347
|
+
const verticalHeight = Math.max(fence.height - baseHeight - topRailHeight, 0.08);
|
|
348
|
+
const baseY = isFloating || isRaised ? clearance : 0;
|
|
349
|
+
// Square posts stand proud of the recessed boards on both faces.
|
|
350
|
+
const postWidth = Math.max(fence.postSize * 1.4, 0.04);
|
|
351
|
+
const postDepth = postWidth;
|
|
352
|
+
const boardDepth = Math.min(panelDepth, postDepth - 0.012);
|
|
353
|
+
const infillOffset = getInfillOffset(fence, postDepth, boardDepth);
|
|
354
|
+
// Stop the horizontal boards / base / rail at the inner faces of the
|
|
355
|
+
// end posts. Letting curved spans run all the way to t=0/1 makes them
|
|
356
|
+
// overlap the terminal post mesh and creates the broken seam/notch seen
|
|
357
|
+
// at curve ends.
|
|
358
|
+
const edgeInset = Math.max(fence.edgeInset ?? 0.015, postWidth * 0.5);
|
|
359
|
+
const startInsetT = sharedEndpoints?.has('start') ? 0 : Math.min(0.499, edgeInset / length);
|
|
360
|
+
const endInsetT = sharedEndpoints?.has('end') ? 1 : Math.max(0.501, 1 - edgeInset / length);
|
|
361
|
+
// Grounded fences get a kickboard along the bottom; floating ones don't.
|
|
362
|
+
if (!isFloating) {
|
|
363
|
+
base.push(...createFenceCurveBlockParts(fence, startInsetT, endInsetT, baseY + baseHeight / 2, baseHeight, postDepth * 0.92, HORIZONTAL_FENCE_CURVE_SEGMENT_LENGTH));
|
|
364
|
+
}
|
|
365
|
+
// Stack full-length boards between the kickboard and the top rail. The board
|
|
366
|
+
// height is derived to evenly fill the panel around a ~0.145 m target, with a
|
|
367
|
+
// constant reveal between each so the count adapts to any fence height.
|
|
368
|
+
if (showInfill) {
|
|
369
|
+
const reveal = Math.max(fence.slatGap ?? 0.01, 0);
|
|
370
|
+
const infillBottom = baseY + baseHeight;
|
|
371
|
+
if (reveal < 0.002) {
|
|
372
|
+
// No reveal → one flush panel, so the stacked-board edge seams don't
|
|
373
|
+
// read as faint lines where the user asked for a smooth surface.
|
|
374
|
+
infill.push(...createFenceCurveBlockParts(fence, startInsetT, endInsetT, infillBottom + verticalHeight / 2, verticalHeight, boardDepth, HORIZONTAL_FENCE_CURVE_SEGMENT_LENGTH, infillOffset));
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
const boardCount = Math.max(1, Math.round(verticalHeight / (0.145 + reveal)));
|
|
378
|
+
const slabHeight = Math.max((verticalHeight - reveal * (boardCount - 1)) / boardCount, 0.02);
|
|
379
|
+
for (let index = 0; index < boardCount; index += 1) {
|
|
380
|
+
const centerY = infillBottom + slabHeight / 2 + index * (slabHeight + reveal);
|
|
381
|
+
infill.push(...createFenceCurveBlockParts(fence, startInsetT, endInsetT, centerY, slabHeight, boardDepth, HORIZONTAL_FENCE_CURVE_SEGMENT_LENGTH, infillOffset));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Top rail caps the boards.
|
|
386
|
+
rail.push(...createFenceCurveBlockParts(fence, startInsetT, endInsetT, baseY + baseHeight + verticalHeight + topRailHeight / 2, topRailHeight, Math.max(postDepth * 0.78, 0.02), HORIZONTAL_FENCE_CURVE_SEGMENT_LENGTH));
|
|
387
|
+
// Posts at every `postSpacing`, anchored at both ends, each with a flat cap.
|
|
388
|
+
const spacing = Math.max(fence.postSpacing, postWidth * 1.4);
|
|
389
|
+
const postCount = Math.max(2, Math.floor(length / spacing) + 1);
|
|
390
|
+
const postDistances = fence.patternDistribution === 'automatic'
|
|
391
|
+
? Array.from({ length: postCount }, (_, index) => (length * index) / (postCount - 1))
|
|
392
|
+
: distributePattern(fence, 0, length, spacing, postWidth * 1.4, 2);
|
|
393
|
+
const anchoredPostDistances = fence.patternDistribution === 'fixed-spacing'
|
|
394
|
+
? [
|
|
395
|
+
0,
|
|
396
|
+
...postDistances.filter((distance) => distance > postWidth * 1.4 && length - distance > postWidth * 1.4),
|
|
397
|
+
length,
|
|
398
|
+
]
|
|
399
|
+
: postDistances;
|
|
400
|
+
const postHeight = baseHeight + verticalHeight + topRailHeight + clearance;
|
|
401
|
+
const capHeight = Math.max(postWidth * 0.32, 0.03);
|
|
402
|
+
const cap = fence.postCap ?? 'pyramid';
|
|
403
|
+
for (const distance of anchoredPostDistances) {
|
|
404
|
+
const t = distance / length;
|
|
405
|
+
const frame = getFencePointAt(fence, t);
|
|
406
|
+
posts.push({
|
|
407
|
+
endpoint: distance === 0 ? 'start' : distance === length ? 'end' : undefined,
|
|
408
|
+
position: [frame.point.x, postHeight / 2, frame.point.y],
|
|
409
|
+
rotationY: -frame.tangentAngle,
|
|
410
|
+
scale: [postWidth, postHeight, postDepth],
|
|
411
|
+
});
|
|
412
|
+
if (cap === 'flat') {
|
|
413
|
+
posts.push({
|
|
414
|
+
endpoint: distance === 0 ? 'start' : distance === length ? 'end' : undefined,
|
|
415
|
+
position: [frame.point.x, postHeight + capHeight / 2, frame.point.y],
|
|
416
|
+
rotationY: -frame.tangentAngle,
|
|
417
|
+
scale: [postWidth * 1.22, capHeight, postDepth * 1.22],
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
else if (cap === 'pyramid') {
|
|
421
|
+
posts.push({
|
|
422
|
+
endpoint: distance === 0 ? 'start' : distance === length ? 'end' : undefined,
|
|
423
|
+
position: [frame.point.x, postHeight + capHeight * 0.9, frame.point.y],
|
|
424
|
+
rotationY: -frame.tangentAngle,
|
|
425
|
+
scale: [postWidth * 1.18, capHeight * 1.8, postDepth * 1.18],
|
|
426
|
+
shape: 'pyramid',
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return { posts, infill, base, rail };
|
|
431
|
+
}
|
|
432
|
+
/** Dressed lumber the guard is built from, metres. */
|
|
433
|
+
const IN = 0.0254;
|
|
434
|
+
const GUARD_CAP_T = 1.5 * IN;
|
|
435
|
+
const GUARD_CAP_W = 5.5 * IN;
|
|
436
|
+
const GUARD_RAIL_T = 1.5 * IN;
|
|
437
|
+
const GUARD_RAIL_D = 3.5 * IN;
|
|
438
|
+
const GUARD_BALUSTER = 1.5 * IN;
|
|
439
|
+
const GUARD_BOARD_D = 5.5 * IN;
|
|
440
|
+
const GUARD_CABLE = 0.5 * IN;
|
|
441
|
+
const GUARD_POST_ABOVE_CAP = 3 * IN;
|
|
442
|
+
const GUARD_POST_CAP_T = 1 * IN;
|
|
443
|
+
/**
|
|
444
|
+
* A deck guard the way the AWC Deck Construction Guide (DCA 6) draws one:
|
|
445
|
+
* 4x4 posts (`postSize`) no more than `postSpacing` apart — the two ends
|
|
446
|
+
* counted as posts whether drawn or not (`startPost` / `endPost` false:
|
|
447
|
+
* the rails die into a post already standing there, a porch's 6x6) — a 2x6
|
|
448
|
+
* cap rail flat over the posts, a 2x4 top rail on edge under it, and the
|
|
449
|
+
* infill: balusters (2x2 on a 2x4 bottom rail `groundClearance` over the
|
|
450
|
+
* deck, `slatGap` clear), cable (½ in runs `slatGap` apart from
|
|
451
|
+
* `groundClearance` up), or boards (`thickness` × 5½ in, `slatGap` apart
|
|
452
|
+
* from `groundClearance` up). `postThrough` runs the posts 3 in past the
|
|
453
|
+
* cap under a cap of their own (`postCap`). Slots: posts / infill / base
|
|
454
|
+
* (the bottom rail) / rail (cap + top rail).
|
|
455
|
+
*/
|
|
456
|
+
function createGuardFenceParts(fence) {
|
|
457
|
+
const posts = [];
|
|
458
|
+
const infill = [];
|
|
459
|
+
const base = [];
|
|
460
|
+
const rail = [];
|
|
461
|
+
const length = Math.max(getFenceCenterlineLength(fence), 0.01);
|
|
462
|
+
const H = Math.max(fence.height, 0.4);
|
|
463
|
+
const postW = Math.max(fence.postSize, 0.02);
|
|
464
|
+
const clearance = Math.max(fence.groundClearance, 0);
|
|
465
|
+
const gap = Math.max(fence.slatGap ?? 0.09, 0.01);
|
|
466
|
+
const infillKind = fence.guardInfill ?? 'balusters';
|
|
467
|
+
const through = fence.postThrough === true;
|
|
468
|
+
const capTop = H;
|
|
469
|
+
const capBottom = H - GUARD_CAP_T;
|
|
470
|
+
const topRailBottom = capBottom - GUARD_RAIL_D;
|
|
471
|
+
const bays = Math.max(1, Math.ceil(length / Math.max(fence.postSpacing, postW * 2)));
|
|
472
|
+
const stations = [];
|
|
473
|
+
for (let i = 0; i <= bays; i++)
|
|
474
|
+
stations.push(i / bays);
|
|
475
|
+
// posts: to the cap's underside, or through it with a cap
|
|
476
|
+
const postH = through ? capTop + GUARD_POST_ABOVE_CAP : capBottom;
|
|
477
|
+
for (const [i, t] of stations.entries()) {
|
|
478
|
+
if (i === 0 && fence.startPost === false)
|
|
479
|
+
continue;
|
|
480
|
+
if (i === stations.length - 1 && fence.endPost === false)
|
|
481
|
+
continue;
|
|
482
|
+
const frame = getFencePointAt(fence, t);
|
|
483
|
+
posts.push({
|
|
484
|
+
position: [frame.point.x, postH / 2, frame.point.y],
|
|
485
|
+
rotationY: -frame.tangentAngle,
|
|
486
|
+
scale: [postW, postH, postW],
|
|
487
|
+
});
|
|
488
|
+
if (through && (fence.postCap ?? 'flat') !== 'none') {
|
|
489
|
+
const cap = fence.postCap ?? 'flat';
|
|
490
|
+
if (cap === 'pyramid') {
|
|
491
|
+
posts.push({
|
|
492
|
+
position: [frame.point.x, postH + postW * 0.45, frame.point.y],
|
|
493
|
+
rotationY: -frame.tangentAngle,
|
|
494
|
+
scale: [postW * 1.18, postW * 0.9, postW * 1.18],
|
|
495
|
+
shape: 'pyramid',
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
posts.push({
|
|
500
|
+
position: [frame.point.x, postH + GUARD_POST_CAP_T / 2, frame.point.y],
|
|
501
|
+
rotationY: -frame.tangentAngle,
|
|
502
|
+
scale: [postW + 2 * IN, GUARD_POST_CAP_T, postW + 2 * IN],
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
// the cap rail flat over the posts and the 2x4 top rail on edge under it
|
|
508
|
+
rail.push(...createFenceCurveBlockParts(fence, 0, 1, capBottom + GUARD_CAP_T / 2, GUARD_CAP_T, GUARD_CAP_W));
|
|
509
|
+
rail.push(...createFenceCurveBlockParts(fence, 0, 1, topRailBottom + GUARD_RAIL_D / 2, GUARD_RAIL_D, GUARD_RAIL_T));
|
|
510
|
+
const postHalfT = postW / 2 / length;
|
|
511
|
+
const clearOfPosts = (t, halfT) => !stations.some((s) => Math.abs(s - t) < postHalfT + halfT);
|
|
512
|
+
if (infillKind === 'balusters') {
|
|
513
|
+
// the 2x4 bottom rail `clearance` over the deck, the balusters on it
|
|
514
|
+
const bottomRailTop = clearance + GUARD_RAIL_D;
|
|
515
|
+
base.push(...createFenceCurveBlockParts(fence, 0, 1, clearance + GUARD_RAIL_D / 2, GUARD_RAIL_D, GUARD_RAIL_T));
|
|
516
|
+
const balH = Math.max(topRailBottom - bottomRailTop, 0.05);
|
|
517
|
+
const pitch = GUARD_BALUSTER + gap;
|
|
518
|
+
const halfT = GUARD_BALUSTER / 2 / length;
|
|
519
|
+
for (let s = pitch; s < length - GUARD_BALUSTER; s += pitch) {
|
|
520
|
+
const t = s / length;
|
|
521
|
+
if (!clearOfPosts(t, halfT))
|
|
522
|
+
continue;
|
|
523
|
+
const part = createFenceCurveBlockPart(fence, t - halfT, t + halfT, bottomRailTop + balH / 2, balH, GUARD_BALUSTER);
|
|
524
|
+
if (part)
|
|
525
|
+
infill.push(part);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else if (infillKind === 'cable') {
|
|
529
|
+
// ½ in cables `gap` apart from `clearance` up to under the top rail
|
|
530
|
+
for (let y = clearance; y < topRailBottom - GUARD_CABLE; y += gap) {
|
|
531
|
+
infill.push(...createFenceCurveBlockParts(fence, 0, 1, y + GUARD_CABLE / 2, GUARD_CABLE, GUARD_CABLE));
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
// boards `gap` apart from `clearance` up to under the top rail
|
|
536
|
+
const boardT = Math.max(fence.thickness, 0.012);
|
|
537
|
+
for (let y = clearance; y + GUARD_BOARD_D <= topRailBottom + 1e-6; y += GUARD_BOARD_D + gap) {
|
|
538
|
+
infill.push(...createFenceCurveBlockParts(fence, 0, 1, y + GUARD_BOARD_D / 2, GUARD_BOARD_D, boardT));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return { posts, infill, base, rail };
|
|
542
|
+
}
|
|
543
|
+
function createFenceParts(fence, sharedEndpoints) {
|
|
544
|
+
if (fence.style === 'guard')
|
|
545
|
+
return createGuardFenceParts(fence);
|
|
546
|
+
if (fence.style === 'horizontal')
|
|
547
|
+
return createHorizontalFenceParts(fence, sharedEndpoints);
|
|
548
|
+
if (fence.style === 'picket')
|
|
549
|
+
return createPicketFenceParts(fence, sharedEndpoints);
|
|
550
|
+
const posts = [];
|
|
551
|
+
const infill = [];
|
|
552
|
+
const base = [];
|
|
553
|
+
const rail = [];
|
|
554
|
+
const length = Math.max(getFenceCenterlineLength(fence), 0.01);
|
|
555
|
+
const panelDepth = Math.max(fence.thickness, 0.03);
|
|
556
|
+
const clearance = Math.max(fence.groundClearance, 0);
|
|
557
|
+
const styleDefaults = getStyleDefaults(fence.style);
|
|
558
|
+
const baseHeight = Math.max(fence.baseHeight * styleDefaults.baseFactor, 0.04);
|
|
559
|
+
const topRailHeight = Math.max(fence.topRailHeight * styleDefaults.topFactor, 0.01);
|
|
560
|
+
const verticalHeight = Math.max(fence.height - baseHeight - topRailHeight, 0.08);
|
|
561
|
+
const postWidth = Math.max(fence.postSize * styleDefaults.postFactor, 0.01);
|
|
562
|
+
const spacing = Math.max(fence.postSpacing *
|
|
563
|
+
(fence.patternDistribution === 'automatic' ? styleDefaults.spacingFactor : 1), postWidth * 1.2);
|
|
564
|
+
const edgeInset = Math.max(fence.edgeInset ?? 0.015, 0.005);
|
|
565
|
+
const isFloating = fence.baseStyle === 'floating';
|
|
566
|
+
// 'raised': the base is a guard's bottom rail held `clearance` above the
|
|
567
|
+
// ground, the pickets ending on it; the end posts run to the ground
|
|
568
|
+
const isRaised = fence.baseStyle === 'raised';
|
|
569
|
+
const showInfill = fence.showInfill ?? true;
|
|
570
|
+
const baseY = isFloating || isRaised ? clearance : 0;
|
|
571
|
+
const effectiveBaseHeight = baseHeight;
|
|
572
|
+
const startInsetT = Math.min(0.499, edgeInset / length);
|
|
573
|
+
const endInsetT = Math.max(0.501, 1 - edgeInset / length);
|
|
574
|
+
if (!isFloating) {
|
|
575
|
+
base.push(...createFenceCurveBlockParts(fence, 0, 1, baseY + effectiveBaseHeight / 2, effectiveBaseHeight, panelDepth * 1.05));
|
|
576
|
+
// the grounded kickboard's thin band above it — not on a bottom rail
|
|
577
|
+
if (!isRaised) {
|
|
578
|
+
base.push(...createFenceCurveBlockParts(fence, 0, 1, baseY + effectiveBaseHeight + verticalHeight * 0.15, topRailHeight * 0.8, panelDepth * 0.35));
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
const count = showInfill && fence.style !== 'privacy'
|
|
582
|
+
? Math.max(2, Math.floor((length - edgeInset * 2) / spacing) + 1)
|
|
583
|
+
: 2;
|
|
584
|
+
const interiorStart = edgeInset + postWidth * 1.5;
|
|
585
|
+
const interiorEnd = length - edgeInset - postWidth * 1.5;
|
|
586
|
+
const positions = !showInfill || fence.patternDistribution === 'automatic'
|
|
587
|
+
? Array.from({ length: count }, (_, index) => count === 1 ? 0.5 : startInsetT + (endInsetT - startInsetT) * (index / (count - 1)))
|
|
588
|
+
: [
|
|
589
|
+
startInsetT,
|
|
590
|
+
...(interiorEnd >= interiorStart
|
|
591
|
+
? distributePattern(fence, interiorStart, interiorEnd, spacing, postWidth * 1.2).map((distance) => distance / length)
|
|
592
|
+
: []),
|
|
593
|
+
endInsetT,
|
|
594
|
+
];
|
|
595
|
+
const verticalY = baseY + effectiveBaseHeight + verticalHeight / 2;
|
|
596
|
+
for (let index = 0; index < positions.length; index += 1) {
|
|
597
|
+
const t = positions[index];
|
|
598
|
+
const isEdgePost = index === 0 || index === positions.length - 1;
|
|
599
|
+
const fullHeightPost = !showInfill || ((isFloating || isRaised) && isEdgePost);
|
|
600
|
+
const postHeight = fullHeightPost
|
|
601
|
+
? effectiveBaseHeight + verticalHeight + topRailHeight + clearance
|
|
602
|
+
: verticalHeight;
|
|
603
|
+
const postY = fullHeightPost ? postHeight / 2 : verticalY;
|
|
604
|
+
// End posts are the structural `posts` slot; the intermediate verticals are
|
|
605
|
+
// the `infill` slats (only present when showInfill adds them).
|
|
606
|
+
const slatHalfT = Math.max(0.0005, postWidth / (2 * length));
|
|
607
|
+
const slatStartT = Math.max(0, t - slatHalfT);
|
|
608
|
+
const slatEndT = Math.min(1, t + slatHalfT);
|
|
609
|
+
const slat = createFenceCurveBlockPart(fence, slatStartT, slatEndT, postY, postHeight, Math.max(panelDepth * 0.35 - 0.001, 0.011), isEdgePost
|
|
610
|
+
? 0
|
|
611
|
+
: getInfillOffset(fence, Math.max(panelDepth * 0.55, 0.018), Math.max(panelDepth * 0.35 - 0.001, 0.011)));
|
|
612
|
+
if (slat) {
|
|
613
|
+
if (isEdgePost)
|
|
614
|
+
slat.endpoint = index === 0 ? 'start' : 'end';
|
|
615
|
+
(isEdgePost ? posts : infill).push(slat);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (showInfill && fence.style === 'privacy') {
|
|
619
|
+
infill.push(...createFenceCurveBlockParts(fence, startInsetT, endInsetT, verticalY, verticalHeight, panelDepth * 0.7, MIN_CURVE_SEGMENT_LENGTH, getInfillOffset(fence, Math.max(panelDepth * 0.55, 0.018), panelDepth * 0.7)));
|
|
620
|
+
}
|
|
621
|
+
rail.push(...createFenceCurveBlockParts(fence, 0, 1, baseY + effectiveBaseHeight + verticalHeight + topRailHeight / 2, topRailHeight, Math.max(panelDepth * 0.55, 0.018)));
|
|
622
|
+
if (isFloating) {
|
|
623
|
+
rail.push(...createFenceCurveBlockParts(fence, 0, 1, baseY + effectiveBaseHeight + topRailHeight / 2, topRailHeight, Math.max(panelDepth * 0.55, 0.018)));
|
|
624
|
+
}
|
|
625
|
+
return { posts, infill, base, rail };
|
|
626
|
+
}
|
|
627
|
+
function createPicketFenceParts(fence, sharedEndpoints) {
|
|
628
|
+
const posts = [];
|
|
629
|
+
const infill = [];
|
|
630
|
+
const base = [];
|
|
631
|
+
const rail = [];
|
|
632
|
+
const length = Math.max(getFenceCenterlineLength(fence), 0.01);
|
|
633
|
+
const height = Math.max(fence.height, 0.3);
|
|
634
|
+
const postWidth = Math.max(fence.postSize, 0.02);
|
|
635
|
+
const postDepth = Math.max(fence.thickness, postWidth);
|
|
636
|
+
const baseHeight = fence.baseStyle === 'floating' ? 0 : Math.min(Math.max(fence.baseHeight, 0.04), height * 0.5);
|
|
637
|
+
const picketBottom = Math.min(baseHeight + Math.max(fence.groundClearance, 0), height * 0.75);
|
|
638
|
+
const topClearance = Math.min(Math.max(fence.picketTopClearance ?? 0, 0), height - picketBottom - 0.02);
|
|
639
|
+
const picketHeight = height - picketBottom - topClearance;
|
|
640
|
+
const railHeight = Math.min(Math.max(fence.topRailHeight, 0.01), picketHeight * 0.15);
|
|
641
|
+
// Separate the exposed faces at post/base and post/rail intersections.
|
|
642
|
+
const baseDepth = postDepth * 0.8;
|
|
643
|
+
const railDepth = postDepth + 2 * clampFencePicketRailProjection(fence.picketRailProjection, fence.postSize);
|
|
644
|
+
const variation = fence.picketProfile === 'level'
|
|
645
|
+
? 0
|
|
646
|
+
: Math.min(Math.max(fence.picketVariation, 0), picketHeight * 0.3);
|
|
647
|
+
const shortestPicketHeight = picketHeight - variation;
|
|
648
|
+
const picketDepth = Math.max(Math.min(fence.thickness * 0.5, 0.052), 0.01);
|
|
649
|
+
const picketWidth = Math.max(fence.picketWidth, 0.02);
|
|
650
|
+
const isCurved = (fence.path?.length ?? 0) >= 2 || Math.abs(fence.curveOffset ?? 0) > 0.0001;
|
|
651
|
+
// Curved runs need more clearance as neighboring boards turn toward each other.
|
|
652
|
+
const curveClearance = isCurved ? 0.03 : 0;
|
|
653
|
+
const spacing = Math.max(fence.picketSpacing, picketWidth + 0.01) + curveClearance;
|
|
654
|
+
const endInset = Math.max(fence.edgeInset, 0) + postWidth / 2;
|
|
655
|
+
const postCount = Math.max(1, Math.ceil(length / Math.max(fence.postSpacing, postWidth * 2)));
|
|
656
|
+
for (let index = 0; index <= postCount; index += 1) {
|
|
657
|
+
const frame = getFencePointAt(fence, index / postCount);
|
|
658
|
+
posts.push({
|
|
659
|
+
endpoint: index === 0 ? 'start' : index === postCount ? 'end' : undefined,
|
|
660
|
+
position: [frame.point.x, height / 2, frame.point.y],
|
|
661
|
+
rotationY: -frame.tangentAngle,
|
|
662
|
+
scale: [postWidth, height, postDepth],
|
|
663
|
+
});
|
|
664
|
+
if (fence.postCap !== 'none') {
|
|
665
|
+
const capHeight = postWidth * (fence.postCap === 'flat' ? 0.2 : 0.5);
|
|
666
|
+
posts.push({
|
|
667
|
+
endpoint: index === 0 ? 'start' : index === postCount ? 'end' : undefined,
|
|
668
|
+
position: [frame.point.x, height + capHeight / 2, frame.point.y],
|
|
669
|
+
rotationY: -frame.tangentAngle,
|
|
670
|
+
scale: [postWidth * 1.5, capHeight, postDepth * 1.5],
|
|
671
|
+
shape: fence.postCap === 'flat' ? 'box' : 'pyramid',
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
const startInsetT = sharedEndpoints?.has('start') ? 0 : Math.min(0.499, endInset / length);
|
|
676
|
+
const endInsetT = sharedEndpoints?.has('end') ? 1 : Math.max(0.501, 1 - endInset / length);
|
|
677
|
+
const railEndInset = Math.max(0, postWidth / 2 - Math.min(postWidth * 0.2, 0.015));
|
|
678
|
+
const railStartT = sharedEndpoints?.has('start') ? 0 : Math.min(0.499, railEndInset / length);
|
|
679
|
+
const railEndT = sharedEndpoints?.has('end') ? 1 : Math.max(0.501, 1 - railEndInset / length);
|
|
680
|
+
if (baseHeight > 0) {
|
|
681
|
+
base.push(...createFenceCurveBlockParts(fence, startInsetT, endInsetT, baseHeight / 2, baseHeight, baseDepth));
|
|
682
|
+
}
|
|
683
|
+
const railCount = Math.min(3, Math.max(2, Math.round(fence.picketRailCount)));
|
|
684
|
+
for (let index = 0; index < railCount; index += 1) {
|
|
685
|
+
const centerY = picketBottom + shortestPicketHeight * (0.2 + (0.55 * index) / (railCount - 1));
|
|
686
|
+
rail.push(...createFenceCurveBlockParts(fence, railStartT, railEndT, centerY, railHeight, railDepth, 0.22));
|
|
687
|
+
}
|
|
688
|
+
// Lay out each bay independently so boards never intersect the structural posts.
|
|
689
|
+
const bayLength = length / postCount;
|
|
690
|
+
const usableLength = bayLength - 2 * endInset - picketWidth;
|
|
691
|
+
if (fence.showInfill && usableLength >= 0) {
|
|
692
|
+
const faceOffset = getInfillOffset(fence, railDepth, picketDepth);
|
|
693
|
+
for (let bay = 0; bay < postCount; bay += 1) {
|
|
694
|
+
const distances = fence.patternDistribution === 'automatic'
|
|
695
|
+
? (() => {
|
|
696
|
+
const count = Math.max(1, Math.floor(usableLength / spacing) + 1);
|
|
697
|
+
const occupied = (count - 1) * spacing;
|
|
698
|
+
return Array.from({ length: count }, (_, index) => bay * bayLength + (bayLength - occupied) / 2 + index * spacing);
|
|
699
|
+
})()
|
|
700
|
+
: distributePattern(fence, bay * bayLength + endInset + picketWidth / 2, (bay + 1) * bayLength - endInset - picketWidth / 2, fence.picketSpacing, picketWidth + curveClearance + 0.01);
|
|
701
|
+
for (let index = 0; index < distances.length; index += 1) {
|
|
702
|
+
const distance = distances[index];
|
|
703
|
+
const frame = getFenceCenterlineFrameAt(fence, distance / length);
|
|
704
|
+
const u = distances.length === 1 ? 0.5 : index / (distances.length - 1);
|
|
705
|
+
const arch = Math.sin(Math.PI * u);
|
|
706
|
+
const reduction = fence.picketProfile === 'arched'
|
|
707
|
+
? 1 - arch
|
|
708
|
+
: fence.picketProfile === 'scalloped'
|
|
709
|
+
? arch
|
|
710
|
+
: fence.picketProfile === 'alternating'
|
|
711
|
+
? index % 2
|
|
712
|
+
: 0;
|
|
713
|
+
const boardHeight = picketHeight - variation * reduction;
|
|
714
|
+
infill.push({
|
|
715
|
+
position: [
|
|
716
|
+
frame.point.x + frame.normal.x * faceOffset,
|
|
717
|
+
picketBottom + boardHeight / 2,
|
|
718
|
+
frame.point.y + frame.normal.y * faceOffset,
|
|
719
|
+
],
|
|
720
|
+
rotationY: -Math.atan2(frame.tangent.y, frame.tangent.x),
|
|
721
|
+
scale: [picketWidth, boardHeight, picketDepth],
|
|
722
|
+
shape: 'picket',
|
|
723
|
+
picketTop: fence.picketTop,
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return { posts, infill, base, rail };
|
|
729
|
+
}
|
|
730
|
+
function fenceHeightTransitions(fence, heightAt) {
|
|
731
|
+
const length = getFenceCenterlineLength(fence);
|
|
732
|
+
const count = Math.max(2, Math.ceil(length / 0.06));
|
|
733
|
+
const transitions = [];
|
|
734
|
+
let previous = getFencePointAt(fence, 0).point;
|
|
735
|
+
let previousHeight = heightAt(previous.x, previous.y);
|
|
736
|
+
for (let index = 1; index <= count; index += 1) {
|
|
737
|
+
const point = getFencePointAt(fence, index / count).point;
|
|
738
|
+
const height = heightAt(point.x, point.y);
|
|
739
|
+
if (Math.abs(height - previousHeight) >= 0.12) {
|
|
740
|
+
const t = (index - 0.5) / count;
|
|
741
|
+
const last = transitions.at(-1);
|
|
742
|
+
if (last && (t - last.t) * length < 0.18) {
|
|
743
|
+
last.after = height;
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
transitions.push({ t, before: previousHeight, after: height });
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
previous = point;
|
|
750
|
+
previousHeight = height;
|
|
751
|
+
}
|
|
752
|
+
return transitions;
|
|
753
|
+
}
|
|
754
|
+
function createFencePathProgress(fence) {
|
|
755
|
+
const length = getFenceCenterlineLength(fence);
|
|
756
|
+
const count = Math.max(2, Math.ceil(length / 0.15));
|
|
757
|
+
const points = Array.from({ length: count + 1 }, (_, index) => getFencePointAt(fence, index / count).point);
|
|
758
|
+
return (x, z) => {
|
|
759
|
+
let bestT = 0;
|
|
760
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
761
|
+
for (let index = 1; index <= count; index += 1) {
|
|
762
|
+
const previous = points[index - 1];
|
|
763
|
+
const next = points[index];
|
|
764
|
+
const dx = next.x - previous.x;
|
|
765
|
+
const dz = next.y - previous.y;
|
|
766
|
+
const squared = dx * dx + dz * dz;
|
|
767
|
+
const fraction = squared > 1e-8
|
|
768
|
+
? THREE.MathUtils.clamp(((x - previous.x) * dx + (z - previous.y) * dz) / squared, 0, 1)
|
|
769
|
+
: 0;
|
|
770
|
+
const px = previous.x + dx * fraction;
|
|
771
|
+
const pz = previous.y + dz * fraction;
|
|
772
|
+
const distance = (x - px) ** 2 + (z - pz) ** 2;
|
|
773
|
+
if (distance < bestDistance) {
|
|
774
|
+
bestDistance = distance;
|
|
775
|
+
bestT = (index - 1 + fraction) / count;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return bestT;
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function transitionRailHeight(fence, rawHeight, transitions) {
|
|
782
|
+
const length = getFenceCenterlineLength(fence);
|
|
783
|
+
const halfSpan = Math.max(0.1, fence.transitionWidth / 2) / Math.max(length, 0.01);
|
|
784
|
+
const progress = createFencePathProgress(fence);
|
|
785
|
+
const ramps = transitions.map((transition) => {
|
|
786
|
+
const left = Math.max(0, transition.t - halfSpan);
|
|
787
|
+
const right = Math.min(1, transition.t + halfSpan);
|
|
788
|
+
const beforePoint = getFencePointAt(fence, left).point;
|
|
789
|
+
const afterPoint = getFencePointAt(fence, right).point;
|
|
790
|
+
return {
|
|
791
|
+
left,
|
|
792
|
+
right,
|
|
793
|
+
before: rawHeight(beforePoint.x, beforePoint.y),
|
|
794
|
+
after: rawHeight(afterPoint.x, afterPoint.y),
|
|
795
|
+
};
|
|
796
|
+
});
|
|
797
|
+
return (x, z) => {
|
|
798
|
+
const t = progress(x, z);
|
|
799
|
+
for (const ramp of ramps) {
|
|
800
|
+
if (t < ramp.left || t > ramp.right)
|
|
801
|
+
continue;
|
|
802
|
+
return THREE.MathUtils.lerp(ramp.before, ramp.after, (t - ramp.left) / Math.max(ramp.right - ramp.left, 1e-6));
|
|
803
|
+
}
|
|
804
|
+
return rawHeight(x, z);
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
export function createFenceRailHeightSampler(fence, heightAt) {
|
|
808
|
+
if (fence.surfaceMode === 'level' || fence.transitionMode !== 'slope')
|
|
809
|
+
return heightAt;
|
|
810
|
+
const transitions = fenceHeightTransitions(fence, heightAt);
|
|
811
|
+
return transitions.length > 0 ? transitionRailHeight(fence, heightAt, transitions) : heightAt;
|
|
812
|
+
}
|
|
813
|
+
function addTransitionPosts(fence, parts, transitions) {
|
|
814
|
+
const length = getFenceCenterlineLength(fence);
|
|
815
|
+
const width = Math.max(fence.postSize, fence.transitionMode === 'step' ? 0.22 : 0.07);
|
|
816
|
+
const depth = Math.max(fence.thickness, width);
|
|
817
|
+
for (const transition of transitions) {
|
|
818
|
+
if (fence.transitionMode === 'break') {
|
|
819
|
+
const offset = Math.min(0.08 / Math.max(length, 0.01), 0.2);
|
|
820
|
+
for (const t of [Math.max(0, transition.t - offset), Math.min(1, transition.t + offset)]) {
|
|
821
|
+
const frame = getFencePointAt(fence, t);
|
|
822
|
+
parts.posts.push({
|
|
823
|
+
position: [frame.point.x, fence.height / 2, frame.point.y],
|
|
824
|
+
rotationY: -frame.tangentAngle,
|
|
825
|
+
scale: [width, fence.height, depth],
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
const frame = getFencePointAt(fence, transition.t);
|
|
831
|
+
const rise = Math.abs(transition.after - transition.before);
|
|
832
|
+
parts.posts.push({
|
|
833
|
+
position: [frame.point.x, (fence.height + rise) / 2, frame.point.y],
|
|
834
|
+
rotationY: -frame.tangentAngle,
|
|
835
|
+
scale: [width, fence.height + rise, depth],
|
|
836
|
+
heightOverride: Math.min(transition.before, transition.after),
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
function omitCrossingParts(parts, transitions) {
|
|
842
|
+
return parts.filter((part) => part.startT === undefined ||
|
|
843
|
+
part.endT === undefined ||
|
|
844
|
+
!transitions.some((transition) => transition.t > part.startT && transition.t < part.endT));
|
|
845
|
+
}
|
|
846
|
+
function cutFenceParts(fence, parts, features, heightAt, renderFeatures = true, gateLeafGeometries) {
|
|
847
|
+
const progress = createFencePathProgress(fence);
|
|
848
|
+
for (const slot of ['posts', 'infill', 'base', 'rail']) {
|
|
849
|
+
parts[slot] = parts[slot].flatMap((part) => {
|
|
850
|
+
if (part.startT === undefined || part.endT === undefined || !part.curveBlock) {
|
|
851
|
+
const t = progress(part.position[0], part.position[2]);
|
|
852
|
+
return features.some((feature) => t >= feature.startT && t <= feature.endT) ? [] : [part];
|
|
853
|
+
}
|
|
854
|
+
const ranges = [];
|
|
855
|
+
let cursor = part.startT;
|
|
856
|
+
for (const feature of features) {
|
|
857
|
+
if (feature.endT <= cursor || feature.startT >= part.endT)
|
|
858
|
+
continue;
|
|
859
|
+
if (feature.startT > cursor)
|
|
860
|
+
ranges.push([cursor, Math.min(feature.startT, part.endT)]);
|
|
861
|
+
cursor = Math.max(cursor, feature.endT);
|
|
862
|
+
if (cursor >= part.endT)
|
|
863
|
+
break;
|
|
864
|
+
}
|
|
865
|
+
if (cursor < part.endT)
|
|
866
|
+
ranges.push([cursor, part.endT]);
|
|
867
|
+
if (ranges.length === 1 && ranges[0][0] === part.startT && ranges[0][1] === part.endT)
|
|
868
|
+
return [part];
|
|
869
|
+
part.geometry?.dispose();
|
|
870
|
+
return ranges.flatMap(([start, end]) => {
|
|
871
|
+
const block = part.curveBlock;
|
|
872
|
+
const clipped = createFenceCurveBlockPart(fence, start, end, block.centerY, block.height, block.depth, block.lateralOffset);
|
|
873
|
+
return clipped ? [clipped] : [];
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
if (!renderFeatures)
|
|
878
|
+
return;
|
|
879
|
+
for (const feature of features) {
|
|
880
|
+
const matchesFence = feature.matchFenceStyle !== false;
|
|
881
|
+
const styleDefaults = getStyleDefaults(fence.style);
|
|
882
|
+
const postWidth = matchesFence
|
|
883
|
+
? fence.style === 'picket'
|
|
884
|
+
? Math.max(fence.postSize, 0.02)
|
|
885
|
+
: fence.style === 'horizontal'
|
|
886
|
+
? Math.max(fence.postSize * 1.4, 0.04)
|
|
887
|
+
: Math.max(fence.postSize * styleDefaults.postFactor, 0.01)
|
|
888
|
+
: Math.max(fence.postSize, 0.05);
|
|
889
|
+
const postDepth = matchesFence && fence.style === 'horizontal'
|
|
890
|
+
? postWidth
|
|
891
|
+
: matchesFence && fence.style !== 'picket'
|
|
892
|
+
? Math.max(Math.max(fence.thickness, 0.03) * 0.35 - 0.001, 0.011)
|
|
893
|
+
: Math.max(fence.thickness, postWidth);
|
|
894
|
+
const { bottom, height, postBottom, postHeight } = getFenceFeatureDimensions(fence, feature);
|
|
895
|
+
const top = bottom + height;
|
|
896
|
+
if (feature.showPosts !== false)
|
|
897
|
+
for (const t of [feature.startT, feature.endT]) {
|
|
898
|
+
const frame = getFencePointAt(fence, t);
|
|
899
|
+
parts.posts.push({
|
|
900
|
+
position: [frame.point.x, postBottom + postHeight / 2, frame.point.y],
|
|
901
|
+
rotationY: -frame.tangentAngle,
|
|
902
|
+
scale: [postWidth, postHeight, postDepth],
|
|
903
|
+
});
|
|
904
|
+
if (matchesFence &&
|
|
905
|
+
fence.postCap !== 'none' &&
|
|
906
|
+
(fence.style === 'picket' || fence.style === 'horizontal')) {
|
|
907
|
+
const horizontal = fence.style === 'horizontal';
|
|
908
|
+
const capHeight = horizontal
|
|
909
|
+
? Math.max(postWidth * 0.32, 0.03)
|
|
910
|
+
: postWidth * (fence.postCap === 'flat' ? 0.2 : 0.5);
|
|
911
|
+
const capScale = horizontal ? 1.22 : 1.5;
|
|
912
|
+
parts.posts.push({
|
|
913
|
+
position: [
|
|
914
|
+
frame.point.x,
|
|
915
|
+
postBottom +
|
|
916
|
+
postHeight +
|
|
917
|
+
(horizontal && fence.postCap === 'pyramid' ? capHeight * 0.9 : capHeight / 2),
|
|
918
|
+
frame.point.y,
|
|
919
|
+
],
|
|
920
|
+
rotationY: -frame.tangentAngle,
|
|
921
|
+
scale: [
|
|
922
|
+
postWidth * (horizontal && fence.postCap === 'pyramid' ? 1.18 : capScale),
|
|
923
|
+
horizontal && fence.postCap === 'pyramid' ? capHeight * 1.8 : capHeight,
|
|
924
|
+
postDepth * (horizontal && fence.postCap === 'pyramid' ? 1.18 : capScale),
|
|
925
|
+
],
|
|
926
|
+
shape: fence.postCap === 'pyramid' ? 'pyramid' : 'box',
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
if (feature.kind !== 'gate')
|
|
931
|
+
continue;
|
|
932
|
+
const style = matchesFence
|
|
933
|
+
? fence.style
|
|
934
|
+
: !feature.style || feature.style === 'match'
|
|
935
|
+
? 'picket'
|
|
936
|
+
: feature.style;
|
|
937
|
+
const hostPostWidth = fence.style === 'picket'
|
|
938
|
+
? Math.max(fence.postSize, 0.02)
|
|
939
|
+
: fence.style === 'horizontal'
|
|
940
|
+
? Math.max(fence.postSize * 1.4, 0.04)
|
|
941
|
+
: Math.max(fence.postSize * styleDefaults.postFactor, 0.01);
|
|
942
|
+
const member = Math.min(matchesFence
|
|
943
|
+
? fence.style === 'rail'
|
|
944
|
+
? Math.max(fence.topRailHeight * styleDefaults.topFactor, 0.01)
|
|
945
|
+
: Math.max(fence.picketWidth, hostPostWidth * 0.55)
|
|
946
|
+
: (feature.frameWidth ?? 0.055), height / 4);
|
|
947
|
+
const matchedDepth = fence.style === 'picket'
|
|
948
|
+
? Math.max(Math.min(fence.thickness * 0.5, 0.052), 0.01)
|
|
949
|
+
: fence.style === 'slat'
|
|
950
|
+
? Math.max(fence.thickness * 0.35, 0.011)
|
|
951
|
+
: Math.max(fence.thickness, 0.03);
|
|
952
|
+
const depth = matchesFence ? matchedDepth : (feature.thickness ?? 0.06);
|
|
953
|
+
const animatedLeaves = getFenceGateLeaves(fence, feature);
|
|
954
|
+
const fullyOpenLeaves = getFenceGateLeaves(fence, { ...feature, openAngle: 90 });
|
|
955
|
+
const leaves = gateLeafGeometries
|
|
956
|
+
? getFenceGateLeaves(fence, { ...feature, openAngle: 0 })
|
|
957
|
+
: animatedLeaves;
|
|
958
|
+
// A swinging leaf is rigid: both leaves share the higher jamb elevation.
|
|
959
|
+
const support = Math.max(...[feature.startT, feature.endT].map((t) => {
|
|
960
|
+
const point = getFencePointAt(fence, t).point;
|
|
961
|
+
return heightAt?.(point.x, point.y) ?? 0;
|
|
962
|
+
}));
|
|
963
|
+
for (const [leafIndex, leaf] of leaves.entries()) {
|
|
964
|
+
const leafParts = [];
|
|
965
|
+
const width = leaf.width;
|
|
966
|
+
const frame = Math.min(member, width / 4);
|
|
967
|
+
const innerWidth = width - frame * 2;
|
|
968
|
+
const innerHeight = height - frame * 2;
|
|
969
|
+
const cos = Math.cos(leaf.rotation);
|
|
970
|
+
const sin = Math.sin(leaf.rotation);
|
|
971
|
+
const add = (x, y, z, w, h, d, rotationZ = 0, picket = false) => {
|
|
972
|
+
leafParts.push({
|
|
973
|
+
position: [leaf.hinge.x + cos * x - sin * z, y, leaf.hinge.y + sin * x + cos * z],
|
|
974
|
+
rotationY: -leaf.rotation,
|
|
975
|
+
rotationZ,
|
|
976
|
+
scale: [w, h, d],
|
|
977
|
+
heightOverride: support,
|
|
978
|
+
shape: picket ? 'picket' : 'box',
|
|
979
|
+
picketTop: fence.picketTop,
|
|
980
|
+
});
|
|
981
|
+
};
|
|
982
|
+
for (const x of [frame / 2, width - frame / 2])
|
|
983
|
+
add(x, bottom + height / 2, 0, frame, height, depth);
|
|
984
|
+
const railThickness = matchesFence && style === 'rail'
|
|
985
|
+
? Math.max(fence.topRailHeight * styleDefaults.topFactor, 0.01)
|
|
986
|
+
: frame;
|
|
987
|
+
for (const y of [
|
|
988
|
+
bottom + railThickness / 2,
|
|
989
|
+
top + (style === 'rail' && matchesFence ? railThickness / 2 : -railThickness / 2),
|
|
990
|
+
])
|
|
991
|
+
add(width / 2, y, 0, innerWidth, railThickness, depth);
|
|
992
|
+
const matchedSpacing = fence.style === 'picket'
|
|
993
|
+
? fence.picketSpacing
|
|
994
|
+
: fence.style === 'slat'
|
|
995
|
+
? fence.postSpacing * styleDefaults.spacingFactor
|
|
996
|
+
: fence.style === 'horizontal'
|
|
997
|
+
? 0.155 + Math.max(fence.slatGap, 0)
|
|
998
|
+
: 0.15;
|
|
999
|
+
const spacing = Math.max(matchesFence ? matchedSpacing : (feature.spacing ?? 0.15), 0.04);
|
|
1000
|
+
const matchedBoardWidth = fence.style === 'picket'
|
|
1001
|
+
? fence.picketWidth
|
|
1002
|
+
: fence.style === 'slat'
|
|
1003
|
+
? hostPostWidth
|
|
1004
|
+
: fence.style === 'horizontal'
|
|
1005
|
+
? 0.14
|
|
1006
|
+
: 0.055;
|
|
1007
|
+
const board = Math.min(matchesFence ? matchedBoardWidth : (feature.boardWidth ?? 0.055), innerWidth);
|
|
1008
|
+
if (style === 'privacy')
|
|
1009
|
+
add(width / 2, bottom + height / 2, 0, innerWidth, innerHeight, depth * 0.6);
|
|
1010
|
+
else if (style === 'horizontal') {
|
|
1011
|
+
const count = Math.max(1, Math.floor(innerHeight / spacing));
|
|
1012
|
+
const boardHeight = Math.min(board, (innerHeight / count) * 0.8);
|
|
1013
|
+
for (let i = 0; i < count; i++)
|
|
1014
|
+
add(width / 2, bottom + frame + (innerHeight * (i + 0.5)) / count, 0, innerWidth, boardHeight, depth * 0.65);
|
|
1015
|
+
}
|
|
1016
|
+
else if (style !== 'rail') {
|
|
1017
|
+
const count = Math.max(1, Math.floor(innerWidth / Math.max(spacing, board + 0.015)));
|
|
1018
|
+
for (let i = 0; i < count; i++)
|
|
1019
|
+
add(frame + (innerWidth * (i + 0.5)) / count, bottom + height / 2, 0, Math.min(board, (innerWidth / count) * 0.8), innerHeight, depth * 0.65, 0, style === 'picket');
|
|
1020
|
+
}
|
|
1021
|
+
if (feature.brace && feature.brace !== 'none') {
|
|
1022
|
+
const angle = Math.atan2(innerHeight, innerWidth);
|
|
1023
|
+
add(width / 2, bottom + height / 2, depth * 0.65, Math.hypot(innerWidth, innerHeight), frame * 0.7, depth * 0.35, angle);
|
|
1024
|
+
if (feature.brace === 'cross')
|
|
1025
|
+
add(width / 2, bottom + height / 2, -depth * 0.65, Math.hypot(innerWidth, innerHeight), frame * 0.7, depth * 0.35, -angle);
|
|
1026
|
+
}
|
|
1027
|
+
if (feature.showHardware !== false) {
|
|
1028
|
+
for (const y of [bottom + height * 0.25, bottom + height * 0.75])
|
|
1029
|
+
add(0, y, depth * 0.7, frame * 1.3, 0.075, depth * 0.6);
|
|
1030
|
+
add(width - frame, bottom + height * 0.55, depth * 0.8, Math.min(0.12, width / 4), 0.025, depth * 0.6);
|
|
1031
|
+
}
|
|
1032
|
+
if (gateLeafGeometries) {
|
|
1033
|
+
gateLeafGeometries.push({
|
|
1034
|
+
geometry: mergeFenceParts(leafParts, heightAt),
|
|
1035
|
+
hinge: { x: leaf.hinge.x, z: leaf.hinge.y },
|
|
1036
|
+
rotationY: -(animatedLeaves[leafIndex].rotation - leaf.rotation),
|
|
1037
|
+
openRotationY: -(fullyOpenLeaves[leafIndex].rotation - leaf.rotation),
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
else {
|
|
1041
|
+
parts.infill.push(...leafParts);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
function mergeFenceParts(parts, heightAt) {
|
|
1047
|
+
// An empty slot group (e.g. infill with showInfill off, or base on a floating
|
|
1048
|
+
// fence) must not reach mergeGeometries — it throws on an empty array. The
|
|
1049
|
+
// empty geometry has no position attribute, so the renderer skips its mesh.
|
|
1050
|
+
if (parts.length === 0)
|
|
1051
|
+
return new THREE.BufferGeometry();
|
|
1052
|
+
const geometries = parts.map((part) => {
|
|
1053
|
+
const geometry = createFencePartGeometry(part);
|
|
1054
|
+
if (heightAt) {
|
|
1055
|
+
const positions = geometry.getAttribute('position');
|
|
1056
|
+
if (positions) {
|
|
1057
|
+
for (let index = 0; index < positions.count; index += 1) {
|
|
1058
|
+
const x = positions.getX(index);
|
|
1059
|
+
const z = positions.getZ(index);
|
|
1060
|
+
const lift = part.heightOverride !== undefined
|
|
1061
|
+
? part.heightOverride
|
|
1062
|
+
: part.geometry
|
|
1063
|
+
? heightAt(x, z)
|
|
1064
|
+
: heightAt(part.position[0], part.position[2]);
|
|
1065
|
+
positions.setY(index, positions.getY(index) + lift);
|
|
1066
|
+
}
|
|
1067
|
+
positions.needsUpdate = true;
|
|
1068
|
+
geometry.computeVertexNormals();
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
if (!geometry.index)
|
|
1072
|
+
return geometry;
|
|
1073
|
+
const nonIndexed = geometry.toNonIndexed();
|
|
1074
|
+
geometry.dispose();
|
|
1075
|
+
return nonIndexed;
|
|
1076
|
+
});
|
|
1077
|
+
const merged = mergeGeometries(geometries, false) ?? new THREE.BufferGeometry();
|
|
1078
|
+
geometries.forEach((geometry) => {
|
|
1079
|
+
geometry.dispose();
|
|
1080
|
+
});
|
|
1081
|
+
const mergedUv = merged.getAttribute('uv');
|
|
1082
|
+
if (mergedUv) {
|
|
1083
|
+
merged.setAttribute('uv2', new THREE.Float32BufferAttribute(Array.from(mergedUv.array), 2));
|
|
1084
|
+
}
|
|
1085
|
+
merged.computeVertexNormals();
|
|
1086
|
+
return merged;
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Geometry split by paint slot — posts, infill, base, rail — each a separate
|
|
1090
|
+
* merged BufferGeometry (empty ones included) so the fence renderer can give
|
|
1091
|
+
* each its own material + `userData.slotId`. Slots match the panel's build
|
|
1092
|
+
* options 1:1.
|
|
1093
|
+
*/
|
|
1094
|
+
export function generateFenceSlotGeometries(fence, heightAt, mode = 'all', omitEndpointPosts, cornerNeighbors, gateLeafGeometries) {
|
|
1095
|
+
const parts = mode === 'features'
|
|
1096
|
+
? { posts: [], infill: [], base: [], rail: [] }
|
|
1097
|
+
: createFenceParts(fence, omitEndpointPosts);
|
|
1098
|
+
if (omitEndpointPosts?.size) {
|
|
1099
|
+
parts.posts = parts.posts.filter((part) => !part.endpoint || !omitEndpointPosts.has(part.endpoint));
|
|
1100
|
+
}
|
|
1101
|
+
if (cornerNeighbors) {
|
|
1102
|
+
for (const slot of ['base', 'rail', 'infill']) {
|
|
1103
|
+
if (slot === 'infill' && fence.style !== 'horizontal')
|
|
1104
|
+
continue;
|
|
1105
|
+
for (const part of parts[slot]) {
|
|
1106
|
+
for (const endpoint of ['start', 'end']) {
|
|
1107
|
+
const neighbor = cornerNeighbors[endpoint];
|
|
1108
|
+
if (neighbor)
|
|
1109
|
+
miterFencePartEnd(fence, part, endpoint, neighbor);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
const features = resolveFenceFeatures(fence);
|
|
1115
|
+
if (features.length > 0)
|
|
1116
|
+
cutFenceParts(fence, parts, features, heightAt, mode !== 'body', gateLeafGeometries);
|
|
1117
|
+
const transitions = mode !== 'features' && heightAt && fence.surfaceMode !== 'level'
|
|
1118
|
+
? fenceHeightTransitions(fence, heightAt)
|
|
1119
|
+
: [];
|
|
1120
|
+
if (heightAt && transitions.length > 0 && fence.transitionMode !== 'slope') {
|
|
1121
|
+
addTransitionPosts(fence, parts, transitions);
|
|
1122
|
+
parts.rail = omitCrossingParts(parts.rail, transitions);
|
|
1123
|
+
parts.base = omitCrossingParts(parts.base, transitions);
|
|
1124
|
+
if (fence.style === 'horizontal')
|
|
1125
|
+
parts.infill = omitCrossingParts(parts.infill, transitions);
|
|
1126
|
+
}
|
|
1127
|
+
const railHeightAt = heightAt && transitions.length > 0 && fence.transitionMode === 'slope'
|
|
1128
|
+
? transitionRailHeight(fence, heightAt, transitions)
|
|
1129
|
+
: heightAt;
|
|
1130
|
+
return {
|
|
1131
|
+
posts: mergeFenceParts(parts.posts, heightAt),
|
|
1132
|
+
infill: mergeFenceParts(parts.infill, fence.style === 'horizontal' ? railHeightAt : heightAt),
|
|
1133
|
+
base: mergeFenceParts(parts.base, railHeightAt),
|
|
1134
|
+
rail: mergeFenceParts(parts.rail, railHeightAt),
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
export function generateFenceGeometry(fence, heightAt) {
|
|
1138
|
+
const slots = generateFenceSlotGeometries(fence, heightAt);
|
|
1139
|
+
const geometries = Object.values(slots).filter((geometry) => geometry.getAttribute('position'));
|
|
1140
|
+
const merged = mergeGeometries(geometries, false) ?? new THREE.BufferGeometry();
|
|
1141
|
+
for (const geometry of Object.values(slots))
|
|
1142
|
+
geometry.dispose();
|
|
1143
|
+
return merged;
|
|
1144
|
+
}
|