@pascal-app/nodes 0.1.1 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/dist/building/definition.js +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +809 -72
- package/dist/cabinet/geometry.d.ts.map +1 -1
- package/dist/cabinet/geometry.js +4 -0
- package/dist/cabinet/move-frame.js +3 -3
- package/dist/cabinet/panel.d.ts.map +1 -1
- package/dist/cabinet/panel.js +1 -0
- package/dist/cabinet/placement-snap.d.ts +8 -0
- package/dist/cabinet/placement-snap.d.ts.map +1 -0
- package/dist/cabinet/placement-snap.js +19 -0
- package/dist/cabinet/presets.js +8 -8
- package/dist/cabinet/quick-actions.d.ts.map +1 -1
- package/dist/cabinet/quick-actions.js +9 -3
- package/dist/cabinet/resize-limits.d.ts +11 -0
- package/dist/cabinet/resize-limits.d.ts.map +1 -0
- package/dist/cabinet/resize-limits.js +22 -0
- package/dist/cabinet/run-layout.d.ts +8 -2
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +59 -7
- package/dist/cabinet/run-ops.d.ts +44 -3
- package/dist/cabinet/run-ops.d.ts.map +1 -1
- package/dist/cabinet/run-ops.js +646 -110
- package/dist/cabinet/run-panel.d.ts +2 -1
- package/dist/cabinet/run-panel.d.ts.map +1 -1
- package/dist/cabinet/run-panel.js +38 -4
- package/dist/cabinet/stack-transitions.js +4 -4
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +95 -17
- package/dist/cabinet/wall-snap.d.ts.map +1 -1
- package/dist/cabinet/wall-snap.js +2 -6
- package/dist/ceiling/boundary-editor.d.ts.map +1 -1
- package/dist/ceiling/boundary-editor.js +2 -2
- package/dist/ceiling/definition.d.ts +1 -1
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +36 -5
- package/dist/ceiling/floorplan-affordances.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts.map +1 -1
- package/dist/ceiling/floorplan-move.js +5 -4
- package/dist/ceiling/hole-editor.d.ts.map +1 -1
- package/dist/ceiling/hole-editor.js +2 -2
- package/dist/ceiling/move-tool.d.ts.map +1 -1
- package/dist/ceiling/move-tool.js +4 -3
- package/dist/ceiling/panel.d.ts.map +1 -1
- package/dist/ceiling/panel.js +65 -3
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +6 -2
- package/dist/ceiling/tool.d.ts.map +1 -1
- package/dist/ceiling/tool.js +12 -1
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +1 -0
- package/dist/chimney/tool.d.ts.map +1 -1
- package/dist/chimney/tool.js +16 -1
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +14 -2
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +19 -14
- package/dist/column/floorplan-move.d.ts.map +1 -1
- package/dist/column/floorplan-move.js +7 -2
- package/dist/column/floorplan.d.ts +9 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +59 -4
- package/dist/column/tool.d.ts.map +1 -1
- package/dist/column/tool.js +33 -7
- package/dist/construction-dimension/definition.d.ts +4 -0
- package/dist/construction-dimension/definition.d.ts.map +1 -0
- package/dist/construction-dimension/definition.js +83 -0
- package/dist/construction-dimension/drawing-coordination.d.ts +7 -0
- package/dist/construction-dimension/drawing-coordination.d.ts.map +1 -0
- package/dist/construction-dimension/drawing-coordination.js +54 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts +4 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-affordances.js +114 -0
- package/dist/construction-dimension/floorplan-tool.d.ts +21 -0
- package/dist/construction-dimension/floorplan-tool.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-tool.js +557 -0
- package/dist/construction-dimension/floorplan.d.ts +3 -0
- package/dist/construction-dimension/floorplan.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan.js +457 -0
- package/dist/construction-dimension/geometry.d.ts +31 -0
- package/dist/construction-dimension/geometry.d.ts.map +1 -0
- package/dist/construction-dimension/geometry.js +144 -0
- package/dist/construction-dimension/index.d.ts +4 -0
- package/dist/construction-dimension/index.d.ts.map +1 -0
- package/dist/construction-dimension/index.js +3 -0
- package/dist/construction-dimension/panel.d.ts +2 -0
- package/dist/construction-dimension/panel.d.ts.map +1 -0
- package/dist/construction-dimension/panel.js +128 -0
- package/dist/construction-dimension/parametrics.d.ts +3 -0
- package/dist/construction-dimension/parametrics.d.ts.map +1 -0
- package/dist/construction-dimension/parametrics.js +4 -0
- package/dist/construction-dimension/schema.d.ts +2 -0
- package/dist/construction-dimension/schema.d.ts.map +1 -0
- package/dist/construction-dimension/schema.js +1 -0
- package/dist/door/contextual-dimensions.d.ts +3 -0
- package/dist/door/contextual-dimensions.d.ts.map +1 -0
- package/dist/door/contextual-dimensions.js +7 -0
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +13 -8
- package/dist/door/floorplan-affordances.d.ts +2 -5
- package/dist/door/floorplan-affordances.d.ts.map +1 -1
- package/dist/door/floorplan-affordances.js +9 -18
- package/dist/door/floorplan.d.ts +3 -4
- package/dist/door/floorplan.d.ts.map +1 -1
- package/dist/door/floorplan.js +88 -6
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +2 -2
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +3 -1
- package/dist/door/schema.d.ts +1 -1
- package/dist/door/schema.d.ts.map +1 -1
- package/dist/door/schema.js +1 -1
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +63 -6
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +1 -0
- package/dist/dormer/tool.d.ts.map +1 -1
- package/dist/dormer/tool.js +23 -1
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +20 -9
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +9 -6
- package/dist/elevator/floorplan-affordances.d.ts +2 -6
- package/dist/elevator/floorplan-affordances.d.ts.map +1 -1
- package/dist/elevator/floorplan-affordances.js +13 -12
- package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
- package/dist/fence/actions/move-endpoint.js +29 -1
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +74 -14
- package/dist/fence/floorplan-affordances.d.ts.map +1 -1
- package/dist/fence/floorplan-affordances.js +48 -11
- package/dist/fence/floorplan-move.d.ts.map +1 -1
- package/dist/fence/floorplan-move.js +38 -3
- package/dist/fence/geometry.d.ts.map +1 -1
- package/dist/fence/geometry.js +15 -1
- package/dist/fence/lift.d.ts +38 -0
- package/dist/fence/lift.d.ts.map +1 -0
- package/dist/fence/lift.js +51 -0
- package/dist/fence/move-tool.d.ts.map +1 -1
- package/dist/fence/move-tool.js +25 -5
- package/dist/fence/system.d.ts +3 -0
- package/dist/fence/system.d.ts.map +1 -0
- package/dist/fence/system.js +46 -0
- package/dist/fence/tool.d.ts.map +1 -1
- package/dist/fence/tool.js +103 -32
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +8 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +7 -1
- package/dist/item/floorplan-move.d.ts.map +1 -1
- package/dist/item/floorplan-move.js +50 -43
- package/dist/item/floorplan.d.ts +1 -0
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +49 -0
- package/dist/item/renderer.d.ts +3 -0
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +96 -8
- package/dist/level/definition.d.ts.map +1 -1
- package/dist/level/definition.js +7 -3
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +5 -1
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +7 -1
- package/dist/measurement/definition.d.ts.map +1 -1
- package/dist/measurement/definition.js +5 -0
- package/dist/measurement/floorplan.d.ts.map +1 -1
- package/dist/measurement/floorplan.js +11 -10
- package/dist/measurement/index.d.ts +1 -1
- package/dist/measurement/index.d.ts.map +1 -1
- package/dist/measurement/index.js +1 -1
- package/dist/measurement/resolve.d.ts +5 -0
- package/dist/measurement/resolve.d.ts.map +1 -1
- package/dist/measurement/resolve.js +2 -2
- package/dist/measurement/surface-query.js +5 -5
- package/dist/measurement/tool.d.ts +6 -1
- package/dist/measurement/tool.d.ts.map +1 -1
- package/dist/measurement/tool.js +7 -11
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +22 -19
- package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
- package/dist/roof-segment/floorplan-affordances.js +14 -8
- package/dist/shared/construction-dimension-standards.d.ts +34 -0
- package/dist/shared/construction-dimension-standards.d.ts.map +1 -0
- package/dist/shared/construction-dimension-standards.js +18 -0
- package/dist/shared/construction-length.d.ts +10 -0
- package/dist/shared/construction-length.d.ts.map +1 -0
- package/dist/shared/construction-length.js +57 -0
- package/dist/shared/dimension-string.d.ts +20 -0
- package/dist/shared/dimension-string.d.ts.map +1 -0
- package/dist/shared/dimension-string.js +19 -0
- package/dist/shared/draft-axis-guides.d.ts +36 -0
- package/dist/shared/draft-axis-guides.d.ts.map +1 -0
- package/dist/shared/draft-axis-guides.js +107 -0
- package/dist/shared/move-roof-tool.d.ts.map +1 -1
- package/dist/shared/move-roof-tool.js +17 -3
- package/dist/shared/opening-documentation-fields.d.ts +16 -0
- package/dist/shared/opening-documentation-fields.d.ts.map +1 -0
- package/dist/shared/opening-documentation-fields.js +54 -0
- package/dist/shared/opening-documentation.d.ts +47 -0
- package/dist/shared/opening-documentation.d.ts.map +1 -0
- package/dist/shared/opening-documentation.js +300 -0
- package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
- package/dist/shared/opening-guides-runtime.js +3 -2
- package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.js +14 -5
- package/dist/shared/wall-opening-ceiling.d.ts +30 -0
- package/dist/shared/wall-opening-ceiling.d.ts.map +1 -0
- package/dist/shared/wall-opening-ceiling.js +29 -0
- package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
- package/dist/shelf/floorplan-affordances.js +10 -5
- package/dist/shelf/floorplan-move.d.ts +2 -16
- package/dist/shelf/floorplan-move.d.ts.map +1 -1
- package/dist/shelf/floorplan-move.js +19 -40
- package/dist/shelf/tool.d.ts.map +1 -1
- package/dist/shelf/tool.js +8 -3
- package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
- package/dist/site/recessed-slab-ground-holes.js +1 -4
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +118 -28
- package/dist/site/terrain-drape.d.ts +91 -0
- package/dist/site/terrain-drape.d.ts.map +1 -0
- package/dist/site/terrain-drape.js +205 -0
- package/dist/site/terrain-geometry.d.ts +131 -0
- package/dist/site/terrain-geometry.d.ts.map +1 -0
- package/dist/site/terrain-geometry.js +259 -0
- package/dist/site/terrain-mesh.d.ts +49 -0
- package/dist/site/terrain-mesh.d.ts.map +1 -0
- package/dist/site/terrain-mesh.js +122 -0
- package/dist/site/terrain-renderer.d.ts +28 -0
- package/dist/site/terrain-renderer.d.ts.map +1 -0
- package/dist/site/terrain-renderer.js +69 -0
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +1 -0
- package/dist/skylight/tool.d.ts.map +1 -1
- package/dist/skylight/tool.js +16 -1
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +87 -10
- package/dist/slab/elevation-limit.d.ts +43 -0
- package/dist/slab/elevation-limit.d.ts.map +1 -0
- package/dist/slab/elevation-limit.js +124 -0
- package/dist/slab/floorplan-affordances.d.ts +16 -0
- package/dist/slab/floorplan-affordances.d.ts.map +1 -1
- package/dist/slab/geometry.d.ts.map +1 -1
- package/dist/slab/geometry.js +98 -5
- package/dist/slab/panel.d.ts.map +1 -1
- package/dist/slab/panel.js +82 -4
- package/dist/slab/parametrics.d.ts +1 -1
- package/dist/slab/parametrics.d.ts.map +1 -1
- package/dist/slab/parametrics.js +13 -1
- package/dist/slab/placement-ownership.d.ts +3 -0
- package/dist/slab/placement-ownership.d.ts.map +1 -0
- package/dist/slab/placement-ownership.js +3 -0
- package/dist/slab/quick-measurement.d.ts.map +1 -1
- package/dist/slab/quick-measurement.js +3 -2
- package/dist/slab/system.d.ts.map +1 -1
- package/dist/slab/system.js +14 -4
- package/dist/slab/tool.d.ts.map +1 -1
- package/dist/slab/tool.js +81 -23
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +1 -0
- package/dist/solar-panel/tool.d.ts.map +1 -1
- package/dist/solar-panel/tool.js +17 -1
- package/dist/spawn/definition.d.ts.map +1 -1
- package/dist/spawn/definition.js +1 -0
- package/dist/spawn/floorplan-affordances.d.ts.map +1 -1
- package/dist/spawn/floorplan-affordances.js +7 -4
- package/dist/spawn/floorplan-move.d.ts.map +1 -1
- package/dist/spawn/floorplan-move.js +8 -6
- package/dist/spawn/renderer.d.ts +4 -0
- package/dist/spawn/renderer.d.ts.map +1 -1
- package/dist/spawn/renderer.js +32 -18
- package/dist/spawn/tool.d.ts +2 -2
- package/dist/spawn/tool.d.ts.map +1 -1
- package/dist/spawn/tool.js +78 -11
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +15 -7
- package/dist/stair/destination.d.ts +16 -0
- package/dist/stair/destination.d.ts.map +1 -0
- package/dist/stair/destination.js +24 -0
- package/dist/stair/documentation.d.ts +8 -0
- package/dist/stair/documentation.d.ts.map +1 -0
- package/dist/stair/documentation.js +245 -0
- package/dist/stair/floor-stack.d.ts.map +1 -1
- package/dist/stair/floor-stack.js +38 -0
- package/dist/stair/floorplan-affordances.d.ts.map +1 -1
- package/dist/stair/floorplan-affordances.js +28 -9
- package/dist/stair/floorplan-move.d.ts +3 -5
- package/dist/stair/floorplan-move.d.ts.map +1 -1
- package/dist/stair/floorplan-move.js +14 -16
- package/dist/stair/floorplan.d.ts.map +1 -1
- package/dist/stair/floorplan.js +27 -14
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +35 -2
- package/dist/stair/renderer.d.ts.map +1 -1
- package/dist/stair/renderer.js +4 -3
- package/dist/structural-grid/coordination.d.ts +16 -0
- package/dist/structural-grid/coordination.d.ts.map +1 -0
- package/dist/structural-grid/coordination.js +105 -0
- package/dist/structural-grid/definition.d.ts +4 -0
- package/dist/structural-grid/definition.d.ts.map +1 -0
- package/dist/structural-grid/definition.js +51 -0
- package/dist/structural-grid/floorplan-tool.d.ts +16 -0
- package/dist/structural-grid/floorplan-tool.d.ts.map +1 -0
- package/dist/structural-grid/floorplan-tool.js +183 -0
- package/dist/structural-grid/floorplan.d.ts +3 -0
- package/dist/structural-grid/floorplan.d.ts.map +1 -0
- package/dist/structural-grid/floorplan.js +61 -0
- package/dist/structural-grid/index.d.ts +2 -0
- package/dist/structural-grid/index.d.ts.map +1 -0
- package/dist/structural-grid/index.js +1 -0
- package/dist/structural-grid/schema.d.ts +2 -0
- package/dist/structural-grid/schema.d.ts.map +1 -0
- package/dist/structural-grid/schema.js +1 -0
- package/dist/wall/construction-dimensions.d.ts +32 -0
- package/dist/wall/construction-dimensions.d.ts.map +1 -0
- package/dist/wall/construction-dimensions.js +1031 -0
- package/dist/wall/contextual-dimensions.d.ts +13 -0
- package/dist/wall/contextual-dimensions.d.ts.map +1 -0
- package/dist/wall/contextual-dimensions.js +221 -0
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +20 -1
- package/dist/wall/floorplan-affordances.d.ts.map +1 -1
- package/dist/wall/floorplan-affordances.js +23 -8
- package/dist/wall/floorplan-overrides.d.ts +9 -6
- package/dist/wall/floorplan-overrides.d.ts.map +1 -1
- package/dist/wall/floorplan-overrides.js +20 -11
- package/dist/wall/floorplan.d.ts +12 -3
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +121 -79
- package/dist/wall/measurement.d.ts.map +1 -1
- package/dist/wall/measurement.js +17 -4
- package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
- package/dist/wall/move-endpoint-tool.js +74 -27
- package/dist/wall/move-shared.d.ts.map +1 -1
- package/dist/wall/move-shared.js +3 -2
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +15 -3
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +10 -6
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +32 -5
- package/dist/wall/parametrics.d.ts.map +1 -1
- package/dist/wall/parametrics.js +2 -0
- package/dist/wall/preview.d.ts +8 -0
- package/dist/wall/preview.d.ts.map +1 -0
- package/dist/wall/preview.js +39 -0
- package/dist/wall/quick-measurement.d.ts.map +1 -1
- package/dist/wall/quick-measurement.js +3 -2
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +7 -5
- package/dist/wall/system.d.ts +1 -1
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +37 -2
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +148 -96
- package/dist/wall/treatment-level-data.d.ts +14 -0
- package/dist/wall/treatment-level-data.d.ts.map +1 -0
- package/dist/wall/treatment-level-data.js +31 -0
- package/dist/wall/treatments.d.ts +8 -2
- package/dist/wall/treatments.d.ts.map +1 -1
- package/dist/wall/treatments.js +58 -15
- package/dist/window/contextual-dimensions.d.ts +3 -0
- package/dist/window/contextual-dimensions.d.ts.map +1 -0
- package/dist/window/contextual-dimensions.js +7 -0
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +15 -10
- package/dist/window/floorplan-affordances.d.ts +2 -5
- package/dist/window/floorplan-affordances.d.ts.map +1 -1
- package/dist/window/floorplan-affordances.js +9 -15
- package/dist/window/floorplan-move.d.ts.map +1 -1
- package/dist/window/floorplan-move.js +1 -1
- package/dist/window/floorplan.d.ts.map +1 -1
- package/dist/window/floorplan.js +7 -1
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +3 -3
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +4 -1
- package/dist/window/schema.d.ts +1 -1
- package/dist/window/schema.d.ts.map +1 -1
- package/dist/window/schema.js +1 -1
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +64 -7
- package/dist/window/window-math.d.ts +7 -3
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +8 -3
- package/dist/zone/contextual-dimensions.d.ts +3 -0
- package/dist/zone/contextual-dimensions.d.ts.map +1 -0
- package/dist/zone/contextual-dimensions.js +43 -0
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +9 -1
- package/dist/zone/floorplan-affordances.d.ts +36 -0
- package/dist/zone/floorplan-affordances.d.ts.map +1 -1
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +59 -3
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +48 -4
- package/dist/zone/room-clear-dimensions.d.ts +3 -0
- package/dist/zone/room-clear-dimensions.d.ts.map +1 -0
- package/dist/zone/room-clear-dimensions.js +406 -0
- package/dist/zone/room-documentation.d.ts +11 -0
- package/dist/zone/room-documentation.d.ts.map +1 -0
- package/dist/zone/room-documentation.js +97 -0
- package/package.json +7 -7
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { constructionDimensionRequiredAnchorCount, getWallArcData, getWallCurveFrameAt, getWallThickness, } from '@pascal-app/core';
|
|
2
|
+
import { readFloorplanContext, readFloorplanMetricNotationOverride, withFloorplanGeometryMetadata, } from '@pascal-app/editor';
|
|
3
|
+
import { resolveMeasurementAnchor } from '../measurement/resolve';
|
|
4
|
+
import { formatConstructionLength, } from '../shared/construction-length';
|
|
5
|
+
import { buildDimensionStringGeometry } from '../shared/dimension-string';
|
|
6
|
+
import { alignConstructionDimensionDirectionToSharedWall, resolveCircularConstructionDimensionLayout, resolveConstructionDimensionLayout, } from './geometry';
|
|
7
|
+
const DEFAULT_STROKE = '#334155';
|
|
8
|
+
const DANGLING_STROKE = '#dc2626';
|
|
9
|
+
const EPSILON = 1e-6;
|
|
10
|
+
export function buildConstructionDimensionFloorplan(node, ctx) {
|
|
11
|
+
if (node.visible === false)
|
|
12
|
+
return null;
|
|
13
|
+
const resolved = node.anchors.map((anchor) => resolveDimensionAnchor(node, anchor, ctx));
|
|
14
|
+
const points = resolved.map((anchor) => anchor.point);
|
|
15
|
+
if (points.length < constructionDimensionRequiredAnchorCount(node.mode))
|
|
16
|
+
return null;
|
|
17
|
+
const selected = ctx.viewState?.selected || ctx.viewState?.highlighted;
|
|
18
|
+
const baseStroke = selected
|
|
19
|
+
? (ctx.viewState?.palette.selectedStroke ?? '#2563eb')
|
|
20
|
+
: (ctx.viewState?.palette.measurementStroke ?? DEFAULT_STROKE);
|
|
21
|
+
const dangling = resolved.some((anchor) => anchor.dangling);
|
|
22
|
+
const stroke = dangling ? DANGLING_STROKE : baseStroke;
|
|
23
|
+
const unit = ctx.viewState?.unit ?? 'metric';
|
|
24
|
+
const floorplanContext = readFloorplanContext(ctx);
|
|
25
|
+
const profile = floorplanContext.purpose === 'document' ? 'document' : 'editor';
|
|
26
|
+
const metricNotationOverride = readFloorplanMetricNotationOverride(ctx);
|
|
27
|
+
const displayNode = profile === 'editor' && metricNotationOverride
|
|
28
|
+
? { ...node, metricNotation: metricNotationOverride }
|
|
29
|
+
: node;
|
|
30
|
+
const editable = ctx.viewState?.selected === true &&
|
|
31
|
+
!(typeof node.metadata === 'object' &&
|
|
32
|
+
node.metadata !== null &&
|
|
33
|
+
!Array.isArray(node.metadata) &&
|
|
34
|
+
node.metadata.drawingCoordinationLocked === true);
|
|
35
|
+
switch (node.mode) {
|
|
36
|
+
case 'linear':
|
|
37
|
+
case 'chord': {
|
|
38
|
+
const alignedNode = {
|
|
39
|
+
...displayNode,
|
|
40
|
+
baseline: {
|
|
41
|
+
...displayNode.baseline,
|
|
42
|
+
direction: alignConstructionDimensionDirectionToSharedWall(displayNode.baseline.direction, displayNode.anchors, (id) => ctx.resolve(id)),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
return withFloorplanGeometryMetadata(buildLinearOrChord(alignedNode, points, stroke, dangling, unit, profile, editable), { annotationRole: 'manual-dimension' });
|
|
46
|
+
}
|
|
47
|
+
case 'radius':
|
|
48
|
+
return withFloorplanGeometryMetadata(buildRadius(displayNode, points, stroke, dangling, unit, profile, editable), { annotationRole: 'manual-dimension' });
|
|
49
|
+
case 'diameter':
|
|
50
|
+
return withFloorplanGeometryMetadata(buildDiameter(displayNode, points, stroke, dangling, unit, profile, editable), { annotationRole: 'manual-dimension' });
|
|
51
|
+
case 'center-mark':
|
|
52
|
+
return withFloorplanGeometryMetadata(buildCenterMarkOnly(displayNode, points, stroke, editable), { annotationRole: 'manual-dimension' });
|
|
53
|
+
case 'arc-length':
|
|
54
|
+
return withFloorplanGeometryMetadata(buildArcLength(displayNode, points, stroke, dangling, unit, profile, editable), { annotationRole: 'manual-dimension' });
|
|
55
|
+
case 'angular':
|
|
56
|
+
return withFloorplanGeometryMetadata(buildAngular(displayNode, points, stroke, dangling, editable), { annotationRole: 'manual-dimension' });
|
|
57
|
+
case 'coordinate':
|
|
58
|
+
return withFloorplanGeometryMetadata(buildCoordinate(displayNode, points, stroke, dangling, unit, profile, editable), { annotationRole: 'manual-dimension' });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function resolveDimensionAnchor(node, anchor, ctx) {
|
|
62
|
+
const resolved = resolveMeasurementAnchor(anchor, (id) => ctx.resolve(id));
|
|
63
|
+
if (Array.isArray(anchor) || resolved.dangling)
|
|
64
|
+
return resolved;
|
|
65
|
+
if (!supportsWallDatum(anchor.reference.featureId))
|
|
66
|
+
return resolved;
|
|
67
|
+
const referenced = ctx.resolve(anchor.reference.nodeId);
|
|
68
|
+
if (referenced?.type !== 'wall')
|
|
69
|
+
return resolved;
|
|
70
|
+
const t = wallFeatureParameter(anchor.reference.featureId, anchor.reference.parameters?.t);
|
|
71
|
+
const frame = getWallCurveFrameAt(referenced, t);
|
|
72
|
+
const side = wallDatumSide(node, anchor.reference.featureId, resolved, frame);
|
|
73
|
+
const offset = wallDatumOffset(referenced, node.datumPolicy, side);
|
|
74
|
+
const endpointExtension = wallEndpointDatumExtension(referenced, anchor.reference.featureId, node.datumPolicy, ctx);
|
|
75
|
+
return {
|
|
76
|
+
...resolved,
|
|
77
|
+
point: [
|
|
78
|
+
frame.point.x + frame.normal.x * offset + frame.tangent.x * endpointExtension,
|
|
79
|
+
resolved.point[1],
|
|
80
|
+
frame.point.y + frame.normal.y * offset + frame.tangent.y * endpointExtension,
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function supportsWallDatum(featureId) {
|
|
85
|
+
return (featureId === 'wall:start' ||
|
|
86
|
+
featureId === 'wall:end' ||
|
|
87
|
+
featureId === 'wall:centerline' ||
|
|
88
|
+
featureId === 'wall:midpoint' ||
|
|
89
|
+
featureId === 'wall:face:left' ||
|
|
90
|
+
featureId === 'wall:face:right' ||
|
|
91
|
+
featureId === 'wall:top-centerline');
|
|
92
|
+
}
|
|
93
|
+
function wallFeatureParameter(featureId, parameter) {
|
|
94
|
+
if (featureId === 'wall:start')
|
|
95
|
+
return 0;
|
|
96
|
+
if (featureId === 'wall:end')
|
|
97
|
+
return 1;
|
|
98
|
+
return typeof parameter === 'number' ? Math.max(0, Math.min(1, parameter)) : 0.5;
|
|
99
|
+
}
|
|
100
|
+
function wallDatumSide(node, featureId, resolved, frame) {
|
|
101
|
+
if (featureId === 'wall:face:left')
|
|
102
|
+
return 1;
|
|
103
|
+
if (featureId === 'wall:face:right')
|
|
104
|
+
return -1;
|
|
105
|
+
const baselineProjection = (node.baseline.origin[0] - frame.point.x) * frame.normal.x +
|
|
106
|
+
(node.baseline.origin[1] - frame.point.y) * frame.normal.y;
|
|
107
|
+
if (Math.abs(baselineProjection) > EPSILON)
|
|
108
|
+
return baselineProjection > 0 ? 1 : -1;
|
|
109
|
+
const resolvedNormal = resolved.normal;
|
|
110
|
+
if (resolvedNormal) {
|
|
111
|
+
const normalProjection = resolvedNormal[0] * frame.normal.x + resolvedNormal[2] * frame.normal.y;
|
|
112
|
+
if (Math.abs(normalProjection) > EPSILON)
|
|
113
|
+
return normalProjection > 0 ? 1 : -1;
|
|
114
|
+
}
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
function wallDatumOffset(wall, policy, side) {
|
|
118
|
+
if (policy === 'centerline')
|
|
119
|
+
return 0;
|
|
120
|
+
return (getWallThickness(wall) / 2) * side;
|
|
121
|
+
}
|
|
122
|
+
function wallEndpointDatumExtension(wall, featureId, policy, ctx) {
|
|
123
|
+
if (policy === 'centerline' || (featureId !== 'wall:start' && featureId !== 'wall:end')) {
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
const parent = wall.parentId ? ctx.resolve(wall.parentId) : undefined;
|
|
127
|
+
const childIds = parent && 'children' in parent && Array.isArray(parent.children)
|
|
128
|
+
? parent.children
|
|
129
|
+
: [];
|
|
130
|
+
const endpoint = featureId === 'wall:start' ? wall.start : wall.end;
|
|
131
|
+
const frame = getWallCurveFrameAt(wall, featureId === 'wall:start' ? 0 : 1);
|
|
132
|
+
const projections = [0];
|
|
133
|
+
for (const childId of childIds) {
|
|
134
|
+
const candidate = ctx.resolve(childId);
|
|
135
|
+
if (candidate?.type !== 'wall' ||
|
|
136
|
+
candidate.id === wall.id ||
|
|
137
|
+
getWallArcData(candidate) ||
|
|
138
|
+
(!pointsCoincide(endpoint, candidate.start) && !pointsCoincide(endpoint, candidate.end))) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const dx = candidate.end[0] - candidate.start[0];
|
|
142
|
+
const dz = candidate.end[1] - candidate.start[1];
|
|
143
|
+
const length = Math.hypot(dx, dz);
|
|
144
|
+
if (length <= EPSILON)
|
|
145
|
+
continue;
|
|
146
|
+
const normal = [-dz / length, dx / length];
|
|
147
|
+
for (const side of [-1, 1]) {
|
|
148
|
+
const candidateOffset = wallDatumOffset(candidate, policy, side);
|
|
149
|
+
projections.push(normal[0] * candidateOffset * frame.tangent.x +
|
|
150
|
+
normal[1] * candidateOffset * frame.tangent.y);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return featureId === 'wall:start' ? Math.min(...projections) : Math.max(...projections);
|
|
154
|
+
}
|
|
155
|
+
function pointsCoincide(left, right) {
|
|
156
|
+
return Math.hypot(left[0] - right[0], left[1] - right[1]) <= 0.03;
|
|
157
|
+
}
|
|
158
|
+
function buildLinearOrChord(node, points, stroke, dangling, unit, profile, editable) {
|
|
159
|
+
const layout = resolveConstructionDimensionLayout(node, points);
|
|
160
|
+
const children = [];
|
|
161
|
+
const suppressedSegments = suppressedDimensionSegmentIndexes(node);
|
|
162
|
+
const visibleSegments = layout.segments.filter((_, index) => !suppressedSegments.has(index));
|
|
163
|
+
const dimensionSegments = visibleSegments.map((segment) => {
|
|
164
|
+
const baseText = `${node.mode === 'chord' ? 'CH ' : ''}${formatConstructionLength(segment.value, unit, profile, lengthFormatOptions(node))}`;
|
|
165
|
+
return {
|
|
166
|
+
witnessStart: segment.witnessStart,
|
|
167
|
+
witnessEnd: segment.witnessEnd,
|
|
168
|
+
dimensionStart: segment.dimensionStart,
|
|
169
|
+
dimensionEnd: segment.dimensionEnd,
|
|
170
|
+
text: notation(node, baseText, dangling),
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
children.push(...(dimensionSegments.length > 0
|
|
174
|
+
? [
|
|
175
|
+
buildDimensionStringGeometry({
|
|
176
|
+
segments: dimensionSegments,
|
|
177
|
+
offsetNormal: layout.normal,
|
|
178
|
+
offsetDistance: 0,
|
|
179
|
+
extensionStartGap: node.extensionStartGap,
|
|
180
|
+
extensionOvershoot: node.extensionOvershoot,
|
|
181
|
+
terminator: node.terminator,
|
|
182
|
+
textPosition: node.textPosition,
|
|
183
|
+
stroke,
|
|
184
|
+
}),
|
|
185
|
+
]
|
|
186
|
+
: []), ...visibleSegments.map((segment) => hitLine(segment.dimensionStart, segment.dimensionEnd)));
|
|
187
|
+
if (editable)
|
|
188
|
+
children.push(...witnessHandles(layout.witnessPoints), baselineHandle(layout.midpoint));
|
|
189
|
+
return dimensionGroup(children);
|
|
190
|
+
}
|
|
191
|
+
function buildRadius(node, points, stroke, dangling, unit, profile, editable) {
|
|
192
|
+
const layout = resolveCircularConstructionDimensionLayout('radius', points);
|
|
193
|
+
if (!layout?.end)
|
|
194
|
+
return null;
|
|
195
|
+
const direction = normalized(layout.start, layout.end);
|
|
196
|
+
if (!direction)
|
|
197
|
+
return null;
|
|
198
|
+
const normal = [-direction[1], direction[0]];
|
|
199
|
+
const children = [
|
|
200
|
+
dimensionGeometry(node, layout.start, layout.end, layout.start, layout.end, normal, notation(node, `R ${formatConstructionLength(layout.radius, unit, profile, lengthFormatOptions(node))}`, dangling), stroke),
|
|
201
|
+
hitLine(layout.start, layout.end),
|
|
202
|
+
];
|
|
203
|
+
if (node.showCenterMark)
|
|
204
|
+
children.push(...centerMark(layout.center, layout.radius, stroke));
|
|
205
|
+
if (editable)
|
|
206
|
+
children.push(...anchorHandles(points));
|
|
207
|
+
return dimensionGroup(children);
|
|
208
|
+
}
|
|
209
|
+
function buildDiameter(node, points, stroke, dangling, unit, profile, editable) {
|
|
210
|
+
const layout = resolveCircularConstructionDimensionLayout('diameter', points);
|
|
211
|
+
if (!layout?.end)
|
|
212
|
+
return null;
|
|
213
|
+
const direction = normalized(layout.start, layout.end);
|
|
214
|
+
if (!direction)
|
|
215
|
+
return null;
|
|
216
|
+
const normal = [-direction[1], direction[0]];
|
|
217
|
+
const children = [
|
|
218
|
+
dimensionGeometry(node, layout.start, layout.end, layout.start, layout.end, normal, notation(node, `Ø ${formatConstructionLength(layout.radius * 2, unit, profile, lengthFormatOptions(node))}`, dangling), stroke),
|
|
219
|
+
hitLine(layout.start, layout.end),
|
|
220
|
+
];
|
|
221
|
+
if (node.showCenterMark)
|
|
222
|
+
children.push(...centerMark(layout.center, layout.radius, stroke));
|
|
223
|
+
if (editable)
|
|
224
|
+
children.push(...anchorHandles(points));
|
|
225
|
+
return dimensionGroup(children);
|
|
226
|
+
}
|
|
227
|
+
function buildCenterMarkOnly(node, points, stroke, editable) {
|
|
228
|
+
const layout = resolveCircularConstructionDimensionLayout('center-mark', points);
|
|
229
|
+
if (!layout)
|
|
230
|
+
return null;
|
|
231
|
+
const children = centerMark(layout.center, layout.radius, stroke, true);
|
|
232
|
+
if (editable)
|
|
233
|
+
children.push(...anchorHandles(points));
|
|
234
|
+
return dimensionGroup(children);
|
|
235
|
+
}
|
|
236
|
+
function buildArcLength(node, points, stroke, dangling, unit, profile, editable) {
|
|
237
|
+
const layout = resolveCircularConstructionDimensionLayout('arc-length', points);
|
|
238
|
+
if (!(layout?.end && Math.abs(layout.sweep) > EPSILON))
|
|
239
|
+
return null;
|
|
240
|
+
const projectedEnd = arcPoint(layout.center, layout.radius, layout.endAngle);
|
|
241
|
+
const midAngle = layout.startAngle + layout.sweep / 2;
|
|
242
|
+
const arcMid = arcPoint(layout.center, layout.radius, midAngle);
|
|
243
|
+
const labelPoint = node.baseline.origin;
|
|
244
|
+
const children = [
|
|
245
|
+
arcGeometry(layout.center, layout.radius, layout.startAngle, layout.sweep, stroke),
|
|
246
|
+
styledLine(layout.center, layout.start, stroke, '0.08 0.08'),
|
|
247
|
+
styledLine(layout.center, projectedEnd, stroke, '0.08 0.08'),
|
|
248
|
+
styledLine(arcMid, labelPoint, stroke, '0.08 0.08'),
|
|
249
|
+
...openArrow(layout.start, arcPoint(layout.center, layout.radius, layout.startAngle + layout.sweep * 0.08), stroke),
|
|
250
|
+
...openArrow(projectedEnd, arcPoint(layout.center, layout.radius, layout.endAngle - layout.sweep * 0.08), stroke),
|
|
251
|
+
labelGeometry(labelPoint, notation(node, `ARC ${formatConstructionLength(layout.arcLength, unit, profile, lengthFormatOptions(node))}`, dangling), 0, true),
|
|
252
|
+
];
|
|
253
|
+
if (node.showCenterMark)
|
|
254
|
+
children.push(...centerMark(layout.center, layout.radius, stroke));
|
|
255
|
+
if (editable)
|
|
256
|
+
children.push(...anchorHandles(points), baselineHandle(labelPoint));
|
|
257
|
+
return dimensionGroup(children);
|
|
258
|
+
}
|
|
259
|
+
function buildAngular(node, points, stroke, dangling, editable) {
|
|
260
|
+
const layout = resolveCircularConstructionDimensionLayout('angular', points);
|
|
261
|
+
if (!(layout?.end && Math.abs(layout.sweep) > EPSILON))
|
|
262
|
+
return null;
|
|
263
|
+
const endRadius = distance(layout.center, layout.end);
|
|
264
|
+
const maximumRadius = Math.max(0.25, Math.min(layout.radius, endRadius) * 0.9);
|
|
265
|
+
const requestedRadius = distance(layout.center, node.baseline.origin);
|
|
266
|
+
const arcRadius = Math.min(maximumRadius, Math.max(0.25, requestedRadius));
|
|
267
|
+
const midAngle = layout.startAngle + layout.sweep / 2;
|
|
268
|
+
const arcMid = arcPoint(layout.center, arcRadius, midAngle);
|
|
269
|
+
const labelPoint = node.baseline.origin;
|
|
270
|
+
const startRayEnd = arcPoint(layout.center, Math.max(layout.radius, arcRadius + 0.12), layout.startAngle);
|
|
271
|
+
const endRayEnd = arcPoint(layout.center, Math.max(endRadius, arcRadius + 0.12), layout.endAngle);
|
|
272
|
+
const degrees = (Math.abs(layout.sweep) * 180) / Math.PI;
|
|
273
|
+
const children = [
|
|
274
|
+
styledLine(layout.center, startRayEnd, stroke),
|
|
275
|
+
styledLine(layout.center, endRayEnd, stroke),
|
|
276
|
+
arcGeometry(layout.center, arcRadius, layout.startAngle, layout.sweep, stroke),
|
|
277
|
+
styledLine(arcMid, labelPoint, stroke, '0.08 0.08'),
|
|
278
|
+
labelGeometry(labelPoint, notation(node, `∠ ${formatDegrees(degrees)}`, dangling), 0, true),
|
|
279
|
+
];
|
|
280
|
+
if (node.showCenterMark)
|
|
281
|
+
children.push(...centerMark(layout.center, arcRadius, stroke));
|
|
282
|
+
if (editable)
|
|
283
|
+
children.push(...anchorHandles(points), baselineHandle(node.baseline.origin));
|
|
284
|
+
return dimensionGroup(children);
|
|
285
|
+
}
|
|
286
|
+
function buildCoordinate(node, points, stroke, dangling, unit, profile, editable) {
|
|
287
|
+
const datum = [points[0][0], points[0][2]];
|
|
288
|
+
const features = points.slice(1).map((point) => [point[0], point[2]]);
|
|
289
|
+
if (features.length === 0)
|
|
290
|
+
return null;
|
|
291
|
+
const children = [...centerMark(datum, 0.4, stroke, true)];
|
|
292
|
+
features.forEach((feature, index) => {
|
|
293
|
+
const dx = feature[0] - datum[0];
|
|
294
|
+
const dy = feature[1] - datum[1];
|
|
295
|
+
const label = notation(node, `P${index + 1} · X ${formatConstructionLength(dx, unit, profile, lengthFormatOptions(node))} · Y ${formatConstructionLength(dy, unit, profile, lengthFormatOptions(node))}`, dangling, false);
|
|
296
|
+
children.push(styledLine(datum, feature, stroke, '0.08 0.08'), labelGeometry(feature, label, 0, true, 10), ...centerMark(feature, 0.3, stroke, true));
|
|
297
|
+
});
|
|
298
|
+
if (editable)
|
|
299
|
+
children.push(...anchorHandles(points));
|
|
300
|
+
return dimensionGroup(children);
|
|
301
|
+
}
|
|
302
|
+
function suppressedDimensionSegmentIndexes(node) {
|
|
303
|
+
const metadata = node.metadata;
|
|
304
|
+
if (!(typeof metadata === 'object' && metadata !== null && !Array.isArray(metadata))) {
|
|
305
|
+
return new Set();
|
|
306
|
+
}
|
|
307
|
+
const value = metadata.suppressedDimensionSegmentIndexes;
|
|
308
|
+
if (!Array.isArray(value))
|
|
309
|
+
return new Set();
|
|
310
|
+
return new Set(value.filter((entry) => typeof entry === 'number' && Number.isInteger(entry) && entry >= 0));
|
|
311
|
+
}
|
|
312
|
+
function dimensionGroup(children) {
|
|
313
|
+
return { kind: 'group', children };
|
|
314
|
+
}
|
|
315
|
+
function lengthFormatOptions(node) {
|
|
316
|
+
return {
|
|
317
|
+
imperialPrecision: node.imperialPrecision,
|
|
318
|
+
metricNotation: node.metricNotation,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function notation(node, base, dangling, includeFeatureCount = true) {
|
|
322
|
+
const repeated = includeFeatureCount && node.featureCount > 1 ? `${node.featureCount} x ` : '';
|
|
323
|
+
const content = node.textOverride ?? `${repeated}${base}`;
|
|
324
|
+
const decorated = `${node.prefix}${content}${node.suffix}`;
|
|
325
|
+
return dangling ? `UNLINKED · ${decorated}` : decorated;
|
|
326
|
+
}
|
|
327
|
+
function dimensionGeometry(node, start, end, dimensionStart, dimensionEnd, offsetNormal, text, stroke) {
|
|
328
|
+
return {
|
|
329
|
+
kind: 'dimension',
|
|
330
|
+
start,
|
|
331
|
+
end,
|
|
332
|
+
dimensionStart,
|
|
333
|
+
dimensionEnd,
|
|
334
|
+
offsetNormal,
|
|
335
|
+
offsetDistance: 0,
|
|
336
|
+
extensionStartGap: node.extensionStartGap,
|
|
337
|
+
extensionOvershoot: node.extensionOvershoot,
|
|
338
|
+
terminator: node.terminator,
|
|
339
|
+
textPosition: node.textPosition,
|
|
340
|
+
text,
|
|
341
|
+
stroke,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
function arcGeometry(center, radius, startAngle, sweep, stroke) {
|
|
345
|
+
const start = arcPoint(center, radius, startAngle);
|
|
346
|
+
const end = arcPoint(center, radius, startAngle + sweep);
|
|
347
|
+
return {
|
|
348
|
+
kind: 'path',
|
|
349
|
+
d: `M ${start[0]} ${start[1]} A ${radius} ${radius} 0 ${Math.abs(sweep) > Math.PI ? 1 : 0} ${sweep >= 0 ? 1 : 0} ${end[0]} ${end[1]}`,
|
|
350
|
+
...lineStyle(stroke),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function styledLine(start, end, stroke, strokeDasharray) {
|
|
354
|
+
return {
|
|
355
|
+
kind: 'line',
|
|
356
|
+
x1: start[0],
|
|
357
|
+
y1: start[1],
|
|
358
|
+
x2: end[0],
|
|
359
|
+
y2: end[1],
|
|
360
|
+
...lineStyle(stroke, strokeDasharray),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function lineStyle(stroke, strokeDasharray) {
|
|
364
|
+
return {
|
|
365
|
+
fill: 'none',
|
|
366
|
+
stroke,
|
|
367
|
+
strokeWidth: 0.9,
|
|
368
|
+
strokeDasharray,
|
|
369
|
+
vectorEffect: 'non-scaling-stroke',
|
|
370
|
+
strokeLinecap: 'butt',
|
|
371
|
+
strokeLinejoin: 'miter',
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function labelGeometry(point, text, labelAngle, screenUpright = false, offsetPx = 0) {
|
|
375
|
+
return {
|
|
376
|
+
kind: 'dimension-label',
|
|
377
|
+
cx: point[0],
|
|
378
|
+
cy: point[1],
|
|
379
|
+
text,
|
|
380
|
+
angle: labelAngle,
|
|
381
|
+
screenUpright,
|
|
382
|
+
offsetPx,
|
|
383
|
+
appearance: 'outlined',
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function centerMark(center, radius, stroke, force = false) {
|
|
387
|
+
if (!force && radius <= EPSILON)
|
|
388
|
+
return [];
|
|
389
|
+
const half = Math.min(0.22, Math.max(0.1, radius * 0.18));
|
|
390
|
+
const gap = Math.min(0.045, half * 0.3);
|
|
391
|
+
return [
|
|
392
|
+
styledLine([center[0] - half, center[1]], [center[0] - gap, center[1]], stroke),
|
|
393
|
+
styledLine([center[0] + gap, center[1]], [center[0] + half, center[1]], stroke),
|
|
394
|
+
styledLine([center[0], center[1] - half], [center[0], center[1] - gap], stroke),
|
|
395
|
+
styledLine([center[0], center[1] + gap], [center[0], center[1] + half], stroke),
|
|
396
|
+
];
|
|
397
|
+
}
|
|
398
|
+
function openArrow(tip, toward, stroke) {
|
|
399
|
+
const direction = normalized(tip, toward);
|
|
400
|
+
if (!direction)
|
|
401
|
+
return [];
|
|
402
|
+
const length = 0.15;
|
|
403
|
+
const halfWidth = 0.055;
|
|
404
|
+
const base = [tip[0] + direction[0] * length, tip[1] + direction[1] * length];
|
|
405
|
+
const normal = [-direction[1], direction[0]];
|
|
406
|
+
return [
|
|
407
|
+
styledLine(tip, [base[0] + normal[0] * halfWidth, base[1] + normal[1] * halfWidth], stroke),
|
|
408
|
+
styledLine(tip, [base[0] - normal[0] * halfWidth, base[1] - normal[1] * halfWidth], stroke),
|
|
409
|
+
];
|
|
410
|
+
}
|
|
411
|
+
function baselineHandle(point) {
|
|
412
|
+
return {
|
|
413
|
+
kind: 'endpoint-handle',
|
|
414
|
+
point,
|
|
415
|
+
state: 'idle',
|
|
416
|
+
variant: 'curve',
|
|
417
|
+
affordance: 'move-construction-dimension-baseline',
|
|
418
|
+
payload: null,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function anchorHandles(points) {
|
|
422
|
+
return witnessHandles(points.map((point) => [point[0], point[2]]));
|
|
423
|
+
}
|
|
424
|
+
function witnessHandles(points) {
|
|
425
|
+
return points.map((point, witnessIndex) => ({
|
|
426
|
+
kind: 'endpoint-handle',
|
|
427
|
+
point,
|
|
428
|
+
state: 'idle',
|
|
429
|
+
affordance: 'move-construction-dimension-witness',
|
|
430
|
+
payload: { witnessIndex },
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
function hitLine(start, end) {
|
|
434
|
+
return {
|
|
435
|
+
kind: 'hit-line',
|
|
436
|
+
x1: start[0],
|
|
437
|
+
y1: start[1],
|
|
438
|
+
x2: end[0],
|
|
439
|
+
y2: end[1],
|
|
440
|
+
strokeWidthPx: 12,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function arcPoint(center, radius, pointAngle) {
|
|
444
|
+
return [center[0] + Math.cos(pointAngle) * radius, center[1] + Math.sin(pointAngle) * radius];
|
|
445
|
+
}
|
|
446
|
+
function normalized(start, end) {
|
|
447
|
+
const dx = end[0] - start[0];
|
|
448
|
+
const dy = end[1] - start[1];
|
|
449
|
+
const magnitude = Math.hypot(dx, dy);
|
|
450
|
+
return magnitude <= EPSILON ? null : [dx / magnitude, dy / magnitude];
|
|
451
|
+
}
|
|
452
|
+
function distance(first, second) {
|
|
453
|
+
return Math.hypot(second[0] - first[0], second[1] - first[1]);
|
|
454
|
+
}
|
|
455
|
+
function formatDegrees(value) {
|
|
456
|
+
return `${Number.parseFloat(value.toFixed(value < 10 ? 1 : 0))}°`;
|
|
457
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AnyNode, type AnyNodeId, type ConstructionDimensionMode, type ConstructionDimensionNode, type FloorplanPoint, type MeasurementAnchor, type MeasurementPoint } from '@pascal-app/core';
|
|
2
|
+
export type ConstructionDimensionSegmentLayout = {
|
|
3
|
+
dimensionStart: FloorplanPoint;
|
|
4
|
+
dimensionEnd: FloorplanPoint;
|
|
5
|
+
value: number;
|
|
6
|
+
witnessStart: FloorplanPoint;
|
|
7
|
+
witnessEnd: FloorplanPoint;
|
|
8
|
+
};
|
|
9
|
+
export type ConstructionDimensionLayout = {
|
|
10
|
+
dimensionPoints: FloorplanPoint[];
|
|
11
|
+
direction: FloorplanPoint;
|
|
12
|
+
midpoint: FloorplanPoint;
|
|
13
|
+
normal: FloorplanPoint;
|
|
14
|
+
segments: ConstructionDimensionSegmentLayout[];
|
|
15
|
+
witnessPoints: FloorplanPoint[];
|
|
16
|
+
};
|
|
17
|
+
export declare function alignConstructionDimensionDirectionToSharedWall(direction: readonly [number, number], anchors: readonly MeasurementAnchor[], resolve: (id: AnyNodeId) => AnyNode | undefined): [number, number];
|
|
18
|
+
export type CircularConstructionDimensionLayout = {
|
|
19
|
+
center: FloorplanPoint;
|
|
20
|
+
start: FloorplanPoint;
|
|
21
|
+
end: FloorplanPoint | null;
|
|
22
|
+
radius: number;
|
|
23
|
+
startAngle: number;
|
|
24
|
+
endAngle: number;
|
|
25
|
+
sweep: number;
|
|
26
|
+
chordLength: number;
|
|
27
|
+
arcLength: number;
|
|
28
|
+
};
|
|
29
|
+
export declare function resolveCircularConstructionDimensionLayout(mode: ConstructionDimensionMode, anchors: readonly MeasurementPoint[]): CircularConstructionDimensionLayout | null;
|
|
30
|
+
export declare function resolveConstructionDimensionLayout(node: Pick<ConstructionDimensionNode, 'baseline' | 'chainMode'>, anchors: readonly MeasurementPoint[]): ConstructionDimensionLayout;
|
|
31
|
+
//# sourceMappingURL=geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/construction-dimension/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,MAAM,kCAAkC,GAAG;IAC/C,cAAc,EAAE,cAAc,CAAA;IAC9B,YAAY,EAAE,cAAc,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,cAAc,CAAA;IAC5B,UAAU,EAAE,cAAc,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,eAAe,EAAE,cAAc,EAAE,CAAA;IACjC,SAAS,EAAE,cAAc,CAAA;IACzB,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,cAAc,CAAA;IACtB,QAAQ,EAAE,kCAAkC,EAAE,CAAA;IAC9C,aAAa,EAAE,cAAc,EAAE,CAAA;CAChC,CAAA;AAID,wBAAgB,+CAA+C,CAC7D,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,GAAG,SAAS,GAC9C,CAAC,MAAM,EAAE,MAAM,CAAC,CA+BlB;AAcD,MAAM,MAAM,mCAAmC,GAAG;IAChD,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,cAAc,CAAA;IACrB,GAAG,EAAE,cAAc,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAgB,0CAA0C,CACxD,IAAI,EAAE,yBAAyB,EAC/B,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,mCAAmC,GAAG,IAAI,CA2C5C;AAaD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,IAAI,CAAC,yBAAyB,EAAE,UAAU,GAAG,WAAW,CAAC,EAC/D,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,2BAA2B,CAqD7B"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { getWallArcData, } from '@pascal-app/core';
|
|
2
|
+
const project = (point) => [point[0], point[2]];
|
|
3
|
+
export function alignConstructionDimensionDirectionToSharedWall(direction, anchors, resolve) {
|
|
4
|
+
const firstAnchor = anchors[0];
|
|
5
|
+
const secondAnchor = anchors[1];
|
|
6
|
+
if (!firstAnchor ||
|
|
7
|
+
!secondAnchor ||
|
|
8
|
+
Array.isArray(firstAnchor) ||
|
|
9
|
+
Array.isArray(secondAnchor) ||
|
|
10
|
+
firstAnchor.reference.nodeId !== secondAnchor.reference.nodeId) {
|
|
11
|
+
return [direction[0], direction[1]];
|
|
12
|
+
}
|
|
13
|
+
const wall = resolve(firstAnchor.reference.nodeId);
|
|
14
|
+
if (wall?.type !== 'wall' ||
|
|
15
|
+
getWallArcData(wall) ||
|
|
16
|
+
!supportsStraightWallDirection(firstAnchor.reference.featureId) ||
|
|
17
|
+
!supportsStraightWallDirection(secondAnchor.reference.featureId)) {
|
|
18
|
+
return [direction[0], direction[1]];
|
|
19
|
+
}
|
|
20
|
+
const wallDx = wall.end[0] - wall.start[0];
|
|
21
|
+
const wallDz = wall.end[1] - wall.start[1];
|
|
22
|
+
const wallLength = Math.hypot(wallDx, wallDz);
|
|
23
|
+
if (wallLength <= 1e-9)
|
|
24
|
+
return [direction[0], direction[1]];
|
|
25
|
+
const wallDirection = [wallDx / wallLength, wallDz / wallLength];
|
|
26
|
+
return direction[0] * wallDirection[0] + direction[1] * wallDirection[1] < 0
|
|
27
|
+
? [-wallDirection[0], -wallDirection[1]]
|
|
28
|
+
: wallDirection;
|
|
29
|
+
}
|
|
30
|
+
function supportsStraightWallDirection(featureId) {
|
|
31
|
+
return [
|
|
32
|
+
'wall:start',
|
|
33
|
+
'wall:end',
|
|
34
|
+
'wall:centerline',
|
|
35
|
+
'wall:midpoint',
|
|
36
|
+
'wall:face:left',
|
|
37
|
+
'wall:face:right',
|
|
38
|
+
'wall:top-centerline',
|
|
39
|
+
].includes(featureId);
|
|
40
|
+
}
|
|
41
|
+
export function resolveCircularConstructionDimensionLayout(mode, anchors) {
|
|
42
|
+
if (anchors.length < 2)
|
|
43
|
+
return null;
|
|
44
|
+
const first = project(anchors[0]);
|
|
45
|
+
const second = project(anchors[1]);
|
|
46
|
+
if (mode === 'diameter' || mode === 'radius') {
|
|
47
|
+
const center = [(first[0] + second[0]) / 2, (first[1] + second[1]) / 2];
|
|
48
|
+
const radius = distance(first, second) / 2;
|
|
49
|
+
if (radius <= 1e-9)
|
|
50
|
+
return null;
|
|
51
|
+
return {
|
|
52
|
+
center,
|
|
53
|
+
start: first,
|
|
54
|
+
end: second,
|
|
55
|
+
radius,
|
|
56
|
+
startAngle: Math.atan2(first[1] - center[1], first[0] - center[0]),
|
|
57
|
+
endAngle: Math.atan2(second[1] - center[1], second[0] - center[0]),
|
|
58
|
+
sweep: Math.PI,
|
|
59
|
+
chordLength: radius * 2,
|
|
60
|
+
arcLength: Math.PI * radius,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const usesMiddleCenter = mode === 'arc-length' || mode === 'angular';
|
|
64
|
+
const center = usesMiddleCenter ? second : first;
|
|
65
|
+
const start = usesMiddleCenter ? first : second;
|
|
66
|
+
const radius = distance(center, start);
|
|
67
|
+
if (radius <= 1e-9)
|
|
68
|
+
return null;
|
|
69
|
+
const startAngle = Math.atan2(start[1] - center[1], start[0] - center[0]);
|
|
70
|
+
const endAnchor = anchors[2];
|
|
71
|
+
const end = endAnchor ? project(endAnchor) : null;
|
|
72
|
+
const endAngle = end ? Math.atan2(end[1] - center[1], end[0] - center[0]) : startAngle;
|
|
73
|
+
const sweep = end ? normalizedSignedSweep(startAngle, endAngle) : 0;
|
|
74
|
+
return {
|
|
75
|
+
center,
|
|
76
|
+
start,
|
|
77
|
+
end,
|
|
78
|
+
radius,
|
|
79
|
+
startAngle,
|
|
80
|
+
endAngle,
|
|
81
|
+
sweep,
|
|
82
|
+
chordLength: end ? distance(start, end) : radius,
|
|
83
|
+
arcLength: Math.abs(sweep) * radius,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function normalizedSignedSweep(startAngle, endAngle) {
|
|
87
|
+
let sweep = endAngle - startAngle;
|
|
88
|
+
while (sweep > Math.PI)
|
|
89
|
+
sweep -= Math.PI * 2;
|
|
90
|
+
while (sweep <= -Math.PI)
|
|
91
|
+
sweep += Math.PI * 2;
|
|
92
|
+
return sweep;
|
|
93
|
+
}
|
|
94
|
+
function distance(first, second) {
|
|
95
|
+
return Math.hypot(second[0] - first[0], second[1] - first[1]);
|
|
96
|
+
}
|
|
97
|
+
export function resolveConstructionDimensionLayout(node, anchors) {
|
|
98
|
+
if (anchors.length < 2) {
|
|
99
|
+
throw new Error('Construction dimension layout requires at least two anchors');
|
|
100
|
+
}
|
|
101
|
+
const magnitude = Math.hypot(node.baseline.direction[0], node.baseline.direction[1]);
|
|
102
|
+
const direction = [
|
|
103
|
+
node.baseline.direction[0] / magnitude,
|
|
104
|
+
node.baseline.direction[1] / magnitude,
|
|
105
|
+
];
|
|
106
|
+
const normal = [-direction[1], direction[0]];
|
|
107
|
+
const witnessPoints = anchors.map(project);
|
|
108
|
+
const dimensionPoints = witnessPoints.map((point) => {
|
|
109
|
+
const deltaX = point[0] - node.baseline.origin[0];
|
|
110
|
+
const deltaY = point[1] - node.baseline.origin[1];
|
|
111
|
+
const distance = deltaX * direction[0] + deltaY * direction[1];
|
|
112
|
+
return [
|
|
113
|
+
node.baseline.origin[0] + distance * direction[0],
|
|
114
|
+
node.baseline.origin[1] + distance * direction[1],
|
|
115
|
+
];
|
|
116
|
+
});
|
|
117
|
+
const segmentIndexes = node.chainMode === 'continuous'
|
|
118
|
+
? witnessPoints.slice(0, -1).map((_, index) => [index, index + 1])
|
|
119
|
+
: Array.from({ length: Math.floor(witnessPoints.length / 2) }, (_, index) => [index * 2, index * 2 + 1]);
|
|
120
|
+
const segments = segmentIndexes.map(([startIndex, endIndex]) => {
|
|
121
|
+
const witnessStart = witnessPoints[startIndex];
|
|
122
|
+
const witnessEnd = witnessPoints[endIndex];
|
|
123
|
+
const dimensionStart = dimensionPoints[startIndex];
|
|
124
|
+
const dimensionEnd = dimensionPoints[endIndex];
|
|
125
|
+
return {
|
|
126
|
+
dimensionStart,
|
|
127
|
+
dimensionEnd,
|
|
128
|
+
value: Math.abs((witnessEnd[0] - witnessStart[0]) * direction[0] +
|
|
129
|
+
(witnessEnd[1] - witnessStart[1]) * direction[1]),
|
|
130
|
+
witnessStart,
|
|
131
|
+
witnessEnd,
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
const first = dimensionPoints[0];
|
|
135
|
+
const last = dimensionPoints.at(-1);
|
|
136
|
+
return {
|
|
137
|
+
dimensionPoints,
|
|
138
|
+
direction,
|
|
139
|
+
midpoint: [(first[0] + last[0]) / 2, (first[1] + last[1]) / 2],
|
|
140
|
+
normal,
|
|
141
|
+
segments,
|
|
142
|
+
witnessPoints,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { constructionDimensionDefinition } from './definition';
|
|
2
|
+
export { buildConstructionDimensionFloorplan } from './floorplan';
|
|
3
|
+
export { resolveCircularConstructionDimensionLayout, resolveConstructionDimensionLayout, } from './geometry';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/construction-dimension/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,mCAAmC,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EACL,0CAA0C,EAC1C,kCAAkC,GACnC,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/construction-dimension/panel.tsx"],"names":[],"mappings":"AAkFA,MAAM,CAAC,OAAO,UAAU,0BAA0B,uCAoPjD"}
|