Skip to content

feat(wall): interactive dimension input and continuous chain drafting in 3D and 2D - #1207

Open
saadmooh wants to merge 11 commits into
pascalorg:mainfrom
saadmooh:feat/wall-dimension-drafting
Open

saadmooh wants to merge 11 commits into
pascalorg:mainfrom
saadmooh:feat/wall-dimension-drafting

Conversation

@saadmooh

@saadmooh saadmooh commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes #1206.

Adds interactive numerical dimension input and continuous multi-point chain drafting for walls in both 3D canvas and 2D floorplan views:

  • Interactive Dimension Input Overlay:

    • Floating dimension input box (packages/editor/src/components/tools/shared/dimension-input.tsx) allowing users to type exact wall lengths and angles during drafting.
    • Supports unit parsing and normalization via packages/core/src/lib/units.ts (tested in units.test.ts).
    • Managed via a dedicated useDimensionDraftStore store (dimension-draft-store.ts) for clean decoupled reactivity.
  • Continuous Multi-Point Chain Drafting:

    • Walls can be drawn continuously point-to-point in both 3D and 2D floorplan drafting tools (wall/tool.tsx and loorplan-panel.tsx).
    • Each click creates a wall segment and immediately continues the next segment from that point.
    • Double-click, Enter, or Escape finalizes or cancels the chain.
  • 2D Floorplan Drafting Preview:

    • Real-time ghost wall line and dimension input overlay rendered directly in loorplan-panel.tsx during 2D drafting.

How to test

  1. Run unit tests for unit parsing:
    �un test packages/core/src/lib/units.test.ts
  2. Start the dev editor: �un dev
  3. Activate the Wall tool in 3D mode:
    • Click to start drafting a wall.
    • Type a dimension (e.g. 5m or 4.2) and press Enter to commit segment.
    • Continue clicking to create chained wall segments.
  4. Open the 2D floorplan panel:
    • Verify ghost walls and dimension overlays render during wall drafting.

Screenshots / screen recording

Not added yet.

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch

Note

Medium Risk
Broad changes to drafting state machines and floorplan/3D parity across several build tools, plus scene node updates from typed opening dimensions.

Overview
Adds typed length/angle drafting across wall, fence, slab, and ceiling tools in both 3D and the 2D floorplan: a shared DimensionInput + useDimensionDraftStore, core parseDimension / parseAngle helpers, keyboard shortcuts (D/A, digits), and ghost-segment previews.

Wall-specific behavior includes continuous multi-point chaining, collinear transit along existing walls via exported wallSegmentsCoverSegment (no duplicate segment when tracking an existing wall), and 2D overlay positioning.

3D opening workflow extends opening guide pills with click-to-edit dimensions (gaps, sill, head) that commit position changes on the selected door/window; dimension-drive logic is tightened for openings measured toward a wall end. Fixes: React 19-safe deferred root.unmount for localized Drei Html, and room labels hidden via display: none instead of unmounting.

Reviewed by Cursor Bugbot for commit 39b11ff. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/nodes/src/wall/tool.tsx Resolved
Comment thread packages/nodes/src/wall/tool.tsx Resolved
Comment thread packages/nodes/src/wall/tool.tsx Resolved

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/nodes/src/ceiling/tool.tsx Resolved
Comment thread packages/nodes/src/ceiling/tool.tsx Resolved

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/nodes/src/wall/tool.tsx Resolved

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

kvnloo added a commit to kvnloo/editor that referenced this pull request Nov 6, 2026
Reject malformed degree suffixes before locking wall geometry while retaining
normalization and unchanged dimension-unit behavior. Cover public core exports.

Follow-up to pascalorg#1207, original feature by saadmooh.
Aymericr added a commit that referenced this pull request Nov 9, 2026
…es (#1249)

* feat(wall): typed exact length during two-click wall drafting (#308)

While drafting a wall, printable keys open a typing buffer; the draft
endpoint is projected onto the typed length along the current draft
direction, so the pointer keeps steering direction only. Enter commits
at the typed length, two-stage Escape clears the buffer first and then
cancels the draft, Backspace/Delete edit the buffer. Shared zustand
store keeps the 2D floor plan and the 3D view in lockstep (parity rule
in wiki/architecture/tools.md); angle/junction snapping is preserved on
untyped drafts and bypassed only for the typed commit.

* fix(wall): address review — commit typed length exactly, no buffer leaks

- click/Enter commit reuses the projected endpoint the previews show
  instead of re-snapping the raw pointer (2D + 3D parity)
- HUD subscribes to the typing store so the label tracks keystrokes
- typing buffer cleared on every commit/cancel path; never carries
  into the next chain segment
- 2D typing keys stopPropagation so tool shortcuts don't fire mid-type
- drop unused begin() action

* fix(wall): honor typed length on Enter/click exits, latest-ref for 2D Enter commit

- 3D Enter keeps the buffer across the synthetic grid:click so the
  commit is recognized as typed (no re-snap), clears defensively after
- stopDrafting clears the typing store: double-click finish and chain
  auto-close no longer leak the old length into the next draft
- 2D Enter commits through a latest-ref instead of the first-render
  closure, which used to restart the draft at the typed point
- 2D move preview publishes projectedEnd so a click mid-type commits
  the projected endpoint, matching the 3D tool

* feat(cabinet): add typed coordinate placement

* fix(cabinet): address typed-placement review findings

- Strip insertionPreview/insertionFailure in applyTypedPlacement so Enter
  commits the typed wall position instead of re-entering the pointer
  path's run-insertion branch (Bugbot: stale insertion, high).
- Drop the trailing setProjectedPosition(snap) in beginTypedPlacement that
  pinned the HUD to the pre-typing snap instead of the first digit's
  projection.
- Clear typedWallHitRef/typedCoordinateDefaultsRef on every typing exit
  (becameInactive), covering Escape typed inside the HUD input whose
  window handler skips INPUT targets.
- Render the coordinate HUD from exactly one surface: 2D pane in 2d/split,
  3D Html in 3d-only — split view mounts both panes, so both instances
  fought over caret/focus.

* fix(cabinet): typed-commit hardening + screen-space 2D HUD

- Neutralize altKey on the reused pointer event for typed commits so a
  stale force-place modifier cannot override the typed pose (Bugbot:
  stale Alt click).
- onClick now reports whether a cabinet was committed; a rejected typed
  commit (e.g. collision) keeps the typing session so values survive and
  can be adjusted instead of being silently wiped.
- 2D typed-entry HUD sizes its foreignObject from CSS px × unitsPerPixel
  and counter-rotates by -sceneRotationDeg (mirrors the measurement
  extrusion control), so inputs render screen-upright at a usable size
  at any zoom/rotation.

* fix(cabinet): typed-commit stretch seeding + click ends typing session

- Continuous-mode typed Enter now seeds the stretch preview at the typed
  position (zero-length span) via a rawOverride on
  resolveStretchedPlacement, instead of growing toward the stale cursor
  position carried by the reused pointer event (Bugbot: high).
- A canvas click while typed entry is active ends the typing session
  before committing, so a newly started stretch can follow the pointer
  instead of being frozen until Escape (Bugbot: medium).

* fix(cabinet): keep typed entry reachable after large offsets

findClosestCabinetWallInPlan now accepts maxDistance; beginTypedPlacement
passes Infinity since the placement already knows its wallId and only
needs the projection onto it. A typed perpendicular offset (or deep
cabinet) can push the center beyond WALL_SNAP_DISTANCE_M, which made the
next session fail to start and let digits fall through to global phase
shortcuts.

* fix(cabinet): typed-entry cancel/island/short-wall hardening

- Restore the pre-typing pose when a typing session ends uncommitted
  (Escape/tool cancel): placementRef kept the typed pose, so a click right
  after Escape committed the cancelled coordinates (Bugbot: high).
- Ending the session on island toggle: island has no wall snapping, so the
  session would be orphaned (frozen pointer, vanished HUD) until Escape.
- resolveCabinetTypedPlacementPosition clamps distance instead of
  rejecting when the cabinet is wider than the wall, matching the
  coordinate getter's clamp so the pose stays committable (Bugbot: medium).

* fix(cabinet): typed-entry WYSIWYG click, click-swallow, miter station

- A canvas click during typed entry now commits the typed preview pose
  (suppress the pre-typing restore; keep placementRef) instead of the
  restored original snap (Bugbot: high).
- Strip 'node' from the synthetic typed-commit event so
  stopPlacementCommitPropagation does not install its 300ms window click
  swallow, which could eat the user's next real click (Bugbot: medium).
- resolveCabinetTypedPlacementPosition samples the mitered face offset at
  the destination station (hit.localX = typed distance + width/2) instead
  of the frozen pre-typing snap (Bugbot: medium).

* fix(review): HIGH-2, HIGH-3, QUICKWIN-2

- HIGH-2: recompute wallSurfaceNormal from updated resolved.yaw in applyTypedPlacement

- HIGH-3: re-resolve and publish placement from lastPlacementEventRef when typing ends without commit

- QUICKWIN-2: allow '/' and ',' in isPlacementTypingKey and advance field on comma in PlacementCoordinateInput

Note: HIGH-1 and QUICKWIN-1 were already addressed in commit 7c7851a.

* fix(cabinet): keep typing session on invalid click commit; comma toggles field

- A canvas click during typed entry now ends the session only when the
  commit succeeds (onClick wrapper defers clear() past onClickInner). An
  invalid typed pose keeps the session alive so values stay editable
  (Bugbot: invalid click ends typed entry, high).
- The capture-phase window keydown handler now treats ',' as a field
  toggle like the focused HUD input does, so comma advances to the
  offset field even when the HUD is unfocused (Bugbot: medium).

* fix(cabinet): center a cabinet wider than its wall on typed entry

Wall snap centers an oversized cabinet on the wall (empty span →
midpoint), but typed entry mapped default distance 0 to
localX = width / 2, sliding the cabinet off the wall center — possibly
past the wall end — the moment coordinate entry started or the default
was committed. resolveCabinetTypedPlacementPosition now resolves the
centered pose (wallLength / 2) when the cabinet is wider than the wall,
matching getCabinetPlacementCoordinates and resolveCabinetWallSnapPlacement.

Adds a regression test: wall 4m, cabinet 5m wide → distance 0 resolves
to wallLocalX 2 (wall center), not 2.5.

* fix(wall): re-derive typed endpoint at click commit time

Bugbot 8497d792 (round 3, high): append/backspace only change the
buffer, while projectedEnd is published by pointer move — so digits
typed after the last move left the click commit using a stale
endpoint (typed "1" then "2" without moving committed 1, not 12).
Enter already re-parsed and re-projected; click now does too, via a
shared resolveTypedCommitEnd(start, currentEnd, input, parseOpts)
helper used by both the 3D grid-click path and the 2D floor-plan
placement callback, falling back to the last projected end only when
there is no usable direction. The 2D move preview also re-binds on
unit/metricNotation changes so the parse options stay in sync.

check-types + biome + editor (1072) + nodes (3392) suites pass.

* fix(wall): let the 2D-only view own the typed Enter commit

Bugbot cb434c3d (round 4, high): the 3D tool's capture-phase Enter
handler synthesized grid:click and stopped the event, so the 2D Enter
path never ran handleWallPlacementPoint. In 2D-only that click pipeline
commits nothing (the canvas is display:none), so a typed Enter silently
did nothing; in split view the 3D commit left the panel's draftStart on
the previous segment, so the next 2D preview and typed commit projected
from a stale origin.

The tool's key handler now yields in 2D-only view — the floor-plan
panel is the committer there (view-gated createWallOnCurrentLevel
already exists). For split view, the panel subscribes to the chain
start the 3D tool publishes on useSegmentDraftChain and re-bases its
draft onto it, so both views keep drafting from the same point with a
single commit owner. The subscription re-arms reactively on
mode/tool instead of reading the store once at mount.

check-types + biome + editor (1072) + nodes (3393) suites pass.

* fix(wall): round-4 bugbot fixes for the typed 2D draft

- Escape during a typed 2D draft now only clears the buffer: the panel's
  cancel handler recognizes the stage-1 tool:cancel via
  wallTypingEscapeClearedRef and consumes it, so the draft and the tool
  survive (Bugbot e9c12894).
- A null publish from the 3D chain store (auto-close, T-junction,
  single-segment finish, cancel) now tears the 2D draft down too —
  clearWallPlacementDraft resets draftStart and wallChainFirstVertex
  (Bugbot a172c934).
- 2D Enter guards before clearing: a valid buffer with a degenerate
  preview no longer wipes the input without committing; clearInput moves
  after the guards and after setDraftEnd, matching the 3D path (Bugbot
  622bea04).
- Split view: a grid:move emitted by the floor-plan panel carries a
  screenProjection; while a typing buffer is active the 3D move path now
  trusts that point verbatim instead of re-running magnetic/grid snap,
  which could rotate the draft ray away from the 2D preview (Bugbot
  3cd53dd1).
- acceptsWallTypingKey gates buffer START on a digit or leading dot;
  letters only continue an active buffer, so c/m/t/f drafting shortcuts
  stay live before typing begins (Bugbot 7dcff331).

* refactor(typed-entry): share one store, key convention and HUD between walls and cabinets

#883 (typed wall length) and #887 (typed cabinet distance/offset) each
brought their own typed-entry store, key handling and HUD. Replace
`useWallDraftTyping` with the cabinet's `usePlacementTyping`, now carrying
its session's field labels, so both tools share:

- `routePlacementTypingKey`: a digit or `.` opens a session, Tab or comma
  switches field, Enter commits, Escape clears the session (the next Escape
  cancels the draft), Backspace edits, Delete empties the field; Cmd/Ctrl/Alt
  chords are never consumed.
- A display-only `PlacementCoordinateInput` (no focused inputs), rendered in
  3D through `LocalizedHtml` and in the plan through
  `FloorplanPlacementTypingHud`, so split view shows it in both panes.
- `resolveTypedWallEnd` for the wall projection, used by the 3D tool and
  the plan alike. The plan forwards the pointer itself on `grid:move` and
  each side re-projects it, and a typed Enter that resolves to nothing
  keeps the session instead of dropping it.

Also drops the floorplan preview layer's cabinet kind check (E-002), clears
the session after each Polygon corner, and removes the frozen-copy
typed-length test in favour of tests through the exported resolver.

* feat(wall): type the drafted wall's angle as well as its length

Adapted from the typed-angle idea in #1207: the wall draft's typed entry
gets a second field, the heading. Tab (or comma) switches between length
and angle, and Tab with no session open starts on the angle.

- Length only: the pointer steers the direction, the length is exact.
- Angle only: the direction is locked and the pointer's projection onto it
  sets the length, on the grid step when grid snapping is on.
- Both: the endpoint is fully determined.

Degrees are measured the way the 15° angle snap builds its rays,
`atan2(dz, dx)` from the building's +X axis towards +Z; the field's
placeholder shows the live heading in that convention. The same resolver
drives the 3D tool and the plan, so 2D, 3D and split view agree. Only the
angle field is taken from #1207; its chain, guide and parser changes are
not.

Co-authored-by: saadmooh <saadmoooooha2000@gmail.com>

* docs(tools): describe the shared typed-entry convention

Co-authored-by: dkbbdev <dkbbdev@users.noreply.github.com>
Co-authored-by: saadmooh <saadmoooooha2000@gmail.com>

* fix(floorplan): take 2D-only typed wall keys ahead of the global shortcuts

The plan's typed entry sat in its bubble-phase keydown listener, which is
re-registered (after the global `useKeyboard` one) on every draft's first
click. In 2D-only view a typed `1`/`2` switched phase, `m` armed Measure and
the first Escape cancelled the tool instead of clearing what was typed.

Move it into `installFloorplanWallTypingKeys`, a window capture listener
registered once that reads the draft through refs, consumes its keys before
any shortcut sees them, and stands down outside 2D-only view, where the 3D
wall tool's capture listener owns them. The stage-1 Escape marker and its
`tool:cancel` workaround are gone: that Escape no longer reaches the global
handler. Also tidies two comments left half-edited.

* fix(wall): let a 3D typed Enter commit before the pointer moves

Right after the start click the tool has no pointer yet, so Enter with both
length and angle typed did nothing and typing showed no preview. Fall back
to the start point, as the plan does.

* fix(floorplan): keep the typed-entry HUD off the ghost it labels

The plan's HUD was centred on the cabinet with a pointer-active box around
it, so clicks on the ghost hit the HUD. Lift it just above its anchor and
let only the HUD panel take the pointer.

* fix(wall): wrap the angle placeholder's rounded heading to 0°

A heading just under 360° rounded to a 360° placeholder; show 0° as the
typed-angle convention reads it.

* docs(tools): spell out the typed wall angle convention and pointer forwarding

The typed angle is an absolute heading in the plan frame, as the angle snap
measures it, and its placeholder shows the live heading the same way, while
the draft's angle labels stay relative. The plan forwards its snapped
pointer, never the typed end, and takes 2D-only keys in a capture listener.

* test(floorplan): start the typed wall key test from an empty session

The typing store is shared across test files, so a session another file
left open turned the typed `1m` into `51m` in the full suite.

* fix(floorplan): size the 2D wall typing HUD from the plan's own scale

The wall draft renders outside FloorplanRenderProvider, so the shared HUD
read the context defaults (unitsPerPixel 1, rotation 0) and drew a
plan-metre-sized box far off screen in the 2D-only view. The HUD now takes
unitsPerPixel and sceneRotationDeg from its caller.

Co-authored-by: dkbbdev <dkbbdev@users.noreply.github.com>

* docs(floorplan): reflow the typing HUD comment

---------

Co-authored-by: dkbbdev <dkbbdev@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: saadmooh <saadmoooooha2000@gmail.com>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/nodes/src/wall/tool.tsx Resolved
Comment thread packages/nodes/src/wall/tool.tsx Resolved
const geo = new BoxGeometry(length, DEFAULT_LEVEL_HEIGHT, DRAFT_WALL_THICKNESS)
const matrix = new Vector3(midX, y + DEFAULT_LEVEL_HEIGHT / 2, midZ)
return { geo, position: matrix, angle }
}, [start, end, y])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ghost wall geometries are leaked

Low Severity

GhostWallSegment allocates a new BoxGeometry in useMemo whenever start, end, or y change and never disposes the previous geometry. Long chain drafts and live previews will accumulate GPU buffers until the tool unmounts.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 199443e. Configure here.

if (factor === undefined) return null

return value * factor
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dimension parser ignores project units

High Severity

parseDimension and the copy inside setValues treat a bare number as meters and reject architectural feet-inch strings. The editor already has parseDimensionInput, which honors metric vs imperial. In an imperial project, typing 10 or 12'6" during wall/fence/slab/ceiling drafting produces the wrong length or fails to parse.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 199443e. Configure here.

} catch {
// Read-only or unsupported environment
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global root unmount is deferred

High Severity

Patching ReactDOMClient.createRoot so every root’s unmount runs on a timeout applies to the whole app, not just drei Html. A remount on the same container can run createRoot while the previous root is still mounted; the delayed unmount can then tear down the new tree. Html-heavy tools (dimension HUD, opening pills, snap beacons) remount often enough to hit this.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 199443e. Configure here.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/nodes/src/wall/tool.tsx Resolved
…art shadowing, 2D vertex measurement, and fence confirm

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

handleCeilingPlacementPoint(pt)
} else {
handleSlabPlacementPoint(pt)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2D dimension Enter crashes on commit

High Severity

Confirming a typed length in the 2D overlay passes a constructed MouseEvent into emitFloorplanGridEvent, which reads nativeEvent.currentTarget.querySelector. A constructed event has a null currentTarget, so Enter during 2D wall, slab, or ceiling drafting throws and never places the segment.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1a9ed75. Configure here.

Comment thread packages/nodes/src/wall/tool.tsx Resolved

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

There are 6 total unresolved issues (including 4 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 39b11ff. Configure here.

else clearSlabPlacementDraft()
useDimensionDraftStore.getState().reset()
}}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split view shows duplicate overlays

Medium Severity

In split view, fence, slab, and ceiling each mount a 3D DimensionInput while FloorplanDimensionInputOverlay also mounts in the floorplan. Two inputs bind to the same store, so users see duplicate boxes and both fight for focus on dimension:focus.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 39b11ff. Configure here.

else if (isZoneBuildActive) clearZonePlacementDraft()
else clearSlabPlacementDraft()
useDimensionDraftStore.getState().reset()
}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2D cancel leaves 3D draft live

Medium Severity

Escape on the 2D dimension overlay only clears local floorplan draft state and useDimensionDraftStore. It never emits tool:cancel, so in split view the 3D wall/fence/slab/ceiling tool keeps drafting after 2D has already cancelled.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 39b11ff. Configure here.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(wall): Dimension input overlay and continuous chain drafting in 3D and 2D floorplan

1 participant