Files
houseplan-card/docs/WALL-THICKNESS.md
T
MatyshandCursor ee87d3d00e v1.59.0-beta.5: wall-thickness redesign, draw thickness, plan on new space
Seamless ±½ wall rings with inner floor/area/sun; Draw toolbar thickness
(default 15 cm); new spaces open Plan; audit hygiene from beta.4 recheck.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 15:13:19 +03:00

3.5 KiB
Raw Blame History

Wall thickness — the spec

Status: implemented / evolving (post beta.4 redesign). Visual reference: docs/assets/wall-thickness-reference.png (look at wall bodies only).

Owner intent: thick walls form one continuous hatched body (seamless L and T), grow both ways from the room centreline, fills/light stay inside the inner contour, displayed area is the clean floor, and sun wedges narrow through the opening tunnel.

Code: src/wall-thickness.ts, render in src/houseplan-card.ts / src/space-render.ts. Sun: src/sun.ts. Tests: test/wall-thickness.test.mjs, demo/smoke_wall_thickness.mjs.

1. Model

Per space: walls: [{ key, cm }]. Key = quantised midpoint + direction (modulo 180°). Config always stores centimetres. Open boundaries refuse thickness. One physical stretch has one thickness (atomic collinear spans when neighbours overlap only partially).

Degrade unmatched keys silently on write. Resize / undo / scale re-key all touched spans in the same transaction and keep walls in the resize snapshot.

2. Growth (centreline ±½)

Every thick wall grows half outward and half inward from the polygon edge (outer and shared alike). Silhouette is wider than the polygon by cm/2 on outer walls. Paper and the content frame grow under that outer half.

3. Body render

Production body is the ring outset(poly, half) − inset(poly, half) per room, unioned across rooms so shared and T junctions show one continuous hatch with no internal seams (as in the reference plan). Mitre joins; bevel when the mitre spike exceeds MITRE_LIMIT × thickness.

Openings cut the body full-depth; jambs cap the cut; window glass mid-tunnel; door swing from the inner face. Association uses wall direction ≈ opening angle (mod 180°), then nearest span — never a perpendicular neighbour at a T.

4. Floor, fills, light, area

  • Inner contour = inset(poly, half[]).
  • Room fills and glow are clipped to the inner contour (not painted into the wall hatch).
  • Displayed m² = area of the inner contour (clean floor). Wall-length rulers and opening anchors stay on the centreline.
  • With no thickness, inner = poly (parity with pre-thickness behaviour).

5. Sun

Wedges do not draw through wall bodies. The window is a tunnel of depth cm: effective lit width ≈ max(0, L − d·tan(|α|)) where α is the ray angle from the inward normal. Clip to the receiving room’s inner contour. d = 0 keeps the previous wedge. hide_openings hides the symbol only.

6. Tool / hooks / i18n

Plan-editor tool «Wall thickness»; hover whole wall; cm/in from HA; empty/0 clears; apply-to-room. Hooks: data-hp="wall". i18n en/ru.

Draw with thickness. The Draw toolbar carries a session thickness field (default 15 cm, or inches when HA is imperial). Closing a new room outline writes that cm onto every new edge that does not already have one; shared stretches that already carry a neighbour's thickness are left alone. Empty / 0 leaves the room thin. Live thick preview follows the rubber-band while drawing. Split does not use this field. The Wall thickness tool remains for later edits.

7. Out of scope

Decor-line thickness, per-side finish, auto-from-backdrop, plan-wide default.

8. Testing

Unit: ring closed at corners; half-out; inner area; atomic partial shared; angle-aware opening; rekey after edge/scale. Browser: seamless frame; fill not in hatch; m² drops with thickness; real resize/undo keeps walls; sun narrows with thickness + obliqueness; nav mode restores after can_write.