Skip to content

editor: walls, porches and decks, railings, stairs, roofs, openings - #1193

Merged
wass08 merged 42 commits into
pascalorg:mainfrom
Steven-Tibbs:steve/editor-punch-list
Oct 30, 2026
Merged

wass08 merged 42 commits into
pascalorg:mainfrom
Steven-Tibbs:steve/editor-punch-list

Conversation

@Steven-Tibbs

@Steven-Tibbs Steven-Tibbs commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

The editor side of the punch list (walls, rooms, porches and decks, railings, beams, posts, stairs, roofs, doors and windows), reworked in review. The Addendum at the end records every review decision and change; this section describes the branch as it is now.

Walls

  • Pushing or dragging a wall leaves no doubled walls; a wall drawn over another built differently takes over that stretch (its openings move onto the new wall). Drawing into a wall splits it, as on main.
  • Exterior corners miter; interior walls meet the inside face and leave the outer wall whole.
  • Pull to continue from a selected wall's end; line-up snap and arrow-key nudge (2D); Tab steps through stacked objects (2D); open wall ends select their wall.
  • Temporary dimensions on selected walls (one or several): room widths and outside size, editable in 2D and 3D. The wall's length reads its faces (ID / OD), chosen in Display → Dimensions → Measure walls.
  • Moving several walls pushes each along its own normal, parallel to where it was, with joined walls following and the same live dimensions as a single wall.
  • Wall types live in the wall panel: Preset plus a menu to create, edit and duplicate project wall types; stud spacing on the framing layer. New walls are plain, as on main.

Rooms, porches, decks and patios (on main's floor plates)

  • Invisible walls (room dividers): they close rooms, never cut walls, stay joined when moved, push and drag at their ends.
  • Room types Room, Porch, Deck and Patio. A room closed off outside the house steps down and takes its type's defaults; porches get automatic posts and a beam.
  • Decks drawn as boards on their framing (ledger, joists, rims, beam, posts on piers); porch and patio slabs run down to the natural ground.
  • All of it reads and writes main's floor plates. The plate of an outdoor room carries metadata.floor (porch-slab / deck) as a documented interop field for framing plugins; built-in code reads the room's roomType.

Railings, beams, posts and stairs

  • Railing as a wall type (style, post spacing and size, openings); rooms close on railings; a door on a railing is a gap (via a host-surface capability, not a kind check).
  • Beam and Post tools with their panels and plan symbols.
  • Stairs with wood stringers, concrete or steel, with code checks; square floor openings; a moved stair heals its old cutout at once.

Roofs

  • Roof plan with the eave outline and live updates; moved roofs and side arrows catch the wall lines; gable and heel walls match the walls below; roofs snap to porch, deck and invisible-wall edges.
  • Roof layers (build-up) and ceiling layers; Display → Ceilings (solid tops).

Doors and windows

  • Casing on the finished wall faces for new doors and windows (existing ones load without it), painted per side (casing-a / casing-b, inheriting the frame until painted).
  • New doors and windows get 20 mm frames; an automatic frame depth equals the wall thickness.
  • Swap swing / hinge side opens a closed door to show the result; single casement windows get Swap hinge side.

Editor

  • Build panel: Rooms = Rectangle / Polygon / Walls, with a Standard · Invisible · Railing row under Walls; Walls draws one wall per two clicks; B arms the last Rooms shape.
  • Display menu regrouped: Show (Grid, Other levels below / above) / Dimensions (Dimensions on-off, Measure walls Inside / Outside / Both, Units) / Plan (2D only) / Scene (3D only) / Editing.
  • Adding a storey offers to copy the exterior walls below; a box selection leaves rooms' automatic floors and ceilings out.
  • Clicking an already-selected object picks it up, as on main. Plugin inspector views (e.g. Bones' Engineering) are buttons in the node action menu.
  • Tool shortcuts: Shift+D door, Shift+W window, Shift+S stairs, Shift+R roof. The shortcuts dialog documents Alt (hold) as the snapping bypass and a Shift tap as the snapping-mode cycle.
  • Siding is its own Paint category; siding and shingle materials are KTX2 with thumbnails; a catalog map the asset CDN doesn't have yet loads from the app.

Agent tools

  • add_wall: type (wall assembly preset or project wall type) and wallType: 'railing' with guard settings. New set_wall_type for existing walls. get_walls reports types.
  • add_column: framing posts (role: 'post', size, base). get_zones: room type, step-down, porch framing and decking.

Translations

New copy goes through the i18n catalog; es, fr, ja and zh-CN drafts are marked for review.

How to test

  1. Build panel. Rooms shows Rectangle / Polygon / Walls. Arm Walls: the Standard · Invisible · Railing row appears, and one wall is drawn per two clicks. Press V, then B: the last shape is armed.
  2. Rooms. Draw a rectangle on a fresh scene: one room, plain walls. Draw invisible walls outside the house: a Porch with posts and a beam appears; railings give a Deck.
  3. Wall dimensions. Select a wall, then several: their dimensions show in 2D and 3D. Change Display → Dimensions → Measure walls: they switch between Inside, Outside and Both.
  4. Moving walls. Select two walls of a room and drag: each stays parallel, joined walls follow, dimensions show, and one undo step reverts it.
  5. Stairs. Under an upper floor, move a stair: the old cutout closes immediately, with no reload.
  6. Doors and windows. Place a door and a window: casing on both faces, 20 mm frames, depth equal to the wall. Open an old scene: its doors and windows have no casing. Swap swing side on a closed door: it opens.
  7. Levels. Cut to a lower level: upper levels and roofs still cast shadows.
  8. Siding. Paint a wall with lap siding: the boards show in 3D.
  9. Agent tools. add_wall with type and with wallType: 'railing', then set_wall_type, add_column with role: 'post', and get_zones on a porch: each reports back what it wrote.

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

Addendum: product review (2026-10-30)

The original punch list was reviewed against the settled decisions (DECISIONS.md) and reworked on this branch. Below are the decisions the product owner took, then what changed. Checks run on the final head: bun run ci locally (Biome, i18n, skills, typecheck, all package tests, build) and GitHub CI.

Decisions

Floor plates, slabs and foundations: back to main. Main's floor plates and slabs are the single source of truth again. Removed:

  • the designed foundation (slab with turned-down edge, raised floor, piles and grade beams, designed basements);
  • the Foundation and Footing kinds and tools;
  • the foundation row and view;
  • ground grading and its seat rule;
  • floor layers and the ~0.33 m framed upper floors;
  • the "+ below" framed-floor lift and the delete-level re-seat;
  • slab rooms.

Kept: porches, decks and patios (adapted onto main's plates), ceiling layers and Display → Ceilings, roof layers, square stair openings, the "Copy exterior walls?" prompt.

Walls and the Build panel

  • New walls are plain, as on main. The type/finish pickers and the Exterior / Interior / Invisible / Railing tiles leave the Build panel; wall types (presets and project types) are edited from the wall panel.
  • Walls draws one wall and stops. B recalls the last Rooms shape. Shift+E and I are removed.
  • Automatic splitting of a wall you draw into is restored.

Wall dimensions

  • One setting, Display → Measure walls (Inside / Outside / Both), replaces Finished faces / Centerline / Face of stud. The ID+OD button leaves the wall's action menu.
  • The Display menu follows the design draft.

Interaction

  • A click on an already-selected object enters move mode again, as on main.
  • Several selected walls move like their own push arrows and show their dimensions.

Upper levels: keep their shadows (shadow-only casting) when you cut to a lower level.

Doors and windows

  • Casing only on new openings, with its own paint slot per side.
  • 20 mm frames for new doors and windows.
  • An automatic frame depth is exactly the wall thickness.
  • Swaps open the door.

Rooms: the "Garage" name rule is removed; a room's name is only a label.

Materials

  • Siding uses KTX2 maps like the rest of the catalog, with flipY handled, plus thumbnails.
  • Thumbnails of tinted entries show their colour.

Architecture review

  • Kind checks move behind registry capabilities.
  • Porch framing writes are guarded by the derived-writer test.
  • Built-in code reads roomType; metadata.floor stays as an interop field.
  • The shortcuts dialog describes E-004 correctly.

Agent tools: wall types, railings, posts and room types are exposed (E-010).

Changes made in review

  • Walls:
    • restore auto host splitting;
    • one-wall Walls variant;
    • B recall;
    • Build-panel Walls sub-row;
    • wall types in the wall panel (WallTypeMenu);
    • plain new walls, with the drawn-wall-type code removed;
    • multi-wall push move;
    • multi-wall selection dimensions.
  • Display:
    • menu regrouped;
    • wallDimensionReference removed in favour of wallDimensionFaces;
    • new Dimensions on-off;
    • Split / Merge tooltips.
  • Selection: click-to-move restored; plugin inspector views moved to the action menu.
  • Floor plates / foundations: reverted to main as above; porches, decks and patios rebuilt on main's plates; ceiling caps measured against main's slabs.
  • Stairs:
    • stale automatic cutouts healed in reconciliation;
    • the live drag preview no longer survives the drop;
    • repro tests added.
  • Levels: hidden upper levels cast shadows again (with main's tests).
  • Rooms: Garage rule removed.
  • Doors and windows:
    • casing new-only, plus per-side slots;
    • window and door frame depth = wall;
    • 20 mm frames on creation (schema defaults unchanged, so saved openings keep theirs);
    • swap actions open the leaf;
    • casement hinge swap.
  • Materials:
    • siding and shingles to KTX2;
    • tinted thumbnail swatches;
    • CDN-miss fallback to the app's own asset.
  • Architecture:
    • renderOpeningContent on the host-surface contract (railing doors);
    • porch posts counted by marker;
    • porch framing guard;
    • outdoor plates read roomType.
  • Agent tools: add_wall.type, add_wall.wallType: 'railing', set_wall_type, add_column posts, get_zones outdoor rooms, get_walls types.
  • Translations: catalogs re-extracted; es / fr / ja / zh-CN drafts for new and changed copy, marked for review.

Old scenes (E-003)

  • Main's scenes load as on main; the corpus and frozen-floor gates are unchanged.
  • Scenes saved on this branch before the review still open: removed fields are ignored, and removed kinds behave like an uninstalled plugin's.
  • Existing doors and windows load without casing.

Not in this PR (follow-ups)

  • pascalorg/private-editor#1412 needs to follow this branch: Bones' designed-foundation and footing framing, the community Build tab and Display menu, the removed exports, and the hosted agent-tool parity for set_wall_type and the new inputs.
  • Agent tools: add_beam, and the pascal-3d skill docs (porches, railings and beams are still described as free objects).
  • Railings: consolidate the four railing mechanisms (fence, slab railing, stair railing, railing wall).
  • Main's generic foundation (Underground: the ground steps aside over a basement, the world turns to earth below it, a ground line in the levels, and a foundation under every house #1097): draw nothing under an on-ground slab, and decide per plate rather than per level (one raised plate currently removes the foundation under the whole level).
  • DECISIONS.md: add a superseding entry for 2D plan selection (a wall click selects the wall, while 3D stays room-first).

🤖 Generated with Claude Code

- Walls: push and overlap fixes, square T and corner joins, pull to
  continue from a wall end, line-up snap, arrow nudge, Tab through stacked
  selections
- Rooms: invisible walls; Room, Porch, Deck and Patio room types; outdoor
  rooms step down from the house and take their defaults
- Porches: automatic posts and beam (sizes, spacing, Automatic or Manual),
  optional on decks and patios
- Decks: 3D boards (size, gap, direction) on a framed deck drawn in the
  model; one framing layout shared with the framing plugin
- Railings: railing wall type with styles, posts and openings; rooms close
  on railings
- Beams and posts: beam and post tools, panels and plan symbols
- Stairs: wood stringers, concrete or steel, with code checks
- Foundations: designed slab, raised floor and piles; stepped and drawn
  footings; ground graded round slabs; porch and patio slabs run to grade
- Roofs: roof plan, wall catch, gable walls; snapping to porch, deck and
  invisible-wall edges
- Assemblies: wall stud spacing, roof and ceiling layers, floor build-up
- Display: framing plan hooks, foundation view, ceilings and walls below
- Box selection leaves rooms' automatic floors and ceilings out

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 28, 2026

Copy link
Copy Markdown

This PR is too large for Bugbot to review. It changes 59,852 lines and 3,318,517 characters. Split the change into smaller pull requests to get a review.

@Steven-Tibbs Steven-Tibbs changed the title Porches, decks, railings, stairs, foundations and framing tools Editor punch list: walls, rooms, porches and decks, railings, stairs, foundations and roofs Oct 28, 2026
Steven-Tibbs and others added 27 commits October 28, 2026 14:23
- New UI text goes through the i18n catalog
- es, fr, ja and zh-CN drafts for the new messages, marked for review
- The literal baseline shrinks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- es, fr, ja and zh-CN catalogs back in the order i18n:extract writes them; no message changes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The open-source editor's Display menu shows Walls below and Walls above in the 2D view; it had no button for them
- Uses the existing translations

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share lap and batten PBR maps across all 18 painted siding finishes. Preflip sources for compressed texture storage and preserve the existing tint, sheen and board spacing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Convert grey shingles base color and supply classic/weathered map sets and thumbnails. Preserve their existing compressed-texture orientation, remove superseded WebP maps, and require KTX2 maps plus thumbnails for textured catalog entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n the action menu

- Door "Swap hinge side" / "Swap swing side" now open a closed door through
  its mechanism (the action menu's Open preview), so the new side shows. The
  swap stays one undo step; the open state is not saved.
- Windows get "Swap hinge side" in the action bar (2D and 3D) for a single
  casement, the only type hung from a side jamb; the swap opens a closed
  sash the same way. Windows have no inward/outward notion, so no swing swap.
- Plugin inspector extensions (e.g. Bones' Engineering) leave the panel
  header: each is now an action-menu button with the extension's icon and
  its title as tooltip, opening or keeping the card on that extension. The
  active extension moves from PanelWrapper-local state into the inspector
  store so the menu can drive it; the header keeps back, reset, collapse and
  close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Display is grouped as Show / Dimensions / Plan (2D only) / Scene (3D only) /
  Editing, with a scope line and view tags in split; other levels (walls
  below / above) are Below / Above chips shown where the plan is
- New Dimensions switch (persisted, default on) hides the selected wall's
  temporary dimensions in 2D and 3D and the plan's automatic and contextual
  dimensions, in the editor and the PDF export
- Measure walls (Inside ID / Outside OD / Both, default Both) replaces the
  Expert "Wall dimensions" reference (finished faces / centerline / face of
  stud) and the wall action menu's ID+OD button; the Expert strings always
  measure finished faces and the choice keeps their interior chains, their
  facade chains or both; a stale stored value reads as Both
- Split wall and Merge walls use the action menu's tooltip button
- Wiki: selection-managers "Selected-wall dimensions"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wall panel

- Rooms tiles are Rectangle / Polygon / Walls only. The Exterior wall,
  Interior wall, Invisible wall and Railing tiles are gone; while Walls is
  armed a segmented row picks Standard / Invisible / Railing with one help
  line (`WALL_KINDS`, `selectWallKind`, session-only).
- The wall type and finish pickers under the tiles are gone and new walls
  are plain again, as on main: `DrawnWallTypes`, the wall types / finishes
  preferences, the type override and the draft-time finish helpers are
  deleted. Foundation walls copied up a storey are plain walls.
- Project wall types are made, edited, duplicated and deleted from the wall
  panel's Assembly Preset (`WallTypeMenu`, reusing the type editor dialog,
  moved to components/ui/wall-type); a saved type is applied to the wall in
  the same undo step.
- Walls draws one wall per two clicks and stops, with main's angle and
  magnetic snapping, in the 3D tool and the plan. Polygon sides and pulled
  runs keep the square-holding run snap (`wallDraftIsRun`).
- B arms the wall tool on the Rooms shape picked last (persisted), Rectangle
  the first time.
- Shift+E and I are removed with their tiles.
- tools.md: wall lifecycle and tool keys updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shadow revert left the PR's assertions that hidden upper levels drop out
of the shadow map; they now check main's shadow-only casting again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restores main's click-to-move: a plain click on the already-selected sole
movable node starts its move (3D selection manager), and a plain click on a
multi-selection member or on the group's dashed box, in 2D and 3D, starts
the group pick-up. The PR's other fixes in those files stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A group move whose participants are all walls (body drag in 2D or 3D, or
the pick-up) now moves each wall as its own push arrow would:
planWallGroupPush projects the drag on each wall's normal so it stays
parallel, moves an end shared with another moved, non-parallel wall by the
whole drag so they stay joined, and lets the junction planner carry the
walls joined to them. The preview rides the push's live overrides and
ghosts, release commits one undo step, and the room widths each wall's push
shows appear live in both views (wall-group-push drag). Mixed selections and
pasted or duplicated carries keep the rigid slide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Catalogs re-extracted after the Display, Build panel, wall-type and window
  action changes; strings the fixes removed drop out
- es, fr, ja and zh-CN drafts for the 35 new messages, marked for review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The product decision for this branch is to keep main's floor plates and
slabs as the single source of truth. This takes out what the branch built
beside them and restores main's code:

- the designed foundation (slab with turned-down edge, raised floor, piles,
  stepped footings, designed basements) and the building foundation record;
  main's generic foundation, ground seat, ground level and floor datum are
  back exactly;
- the Foundation and Footing kinds, their tools, panels, plan symbols,
  Build-panel tiles and action-menu entries;
- the level list's Foundation row, the foundation view and its panel;
- ground grading round the foundation (terrain, ground surface, first-person
  collider);
- floor layers on slabs (`buildUp`), the automatic framed thickness of new
  upper floors, the framed lift of "+ below" and the delete-level re-seat;
- slab rooms (a garage carved out of a raised house) and the door sills and
  plate rules that served them.

The deck's posts and the porch slab's edge now run down to the site's own
terrain instead of the graded ground. A slab or wall that still names a
removed field, and a footing or foundation node, load as before: plates are
rebuilt without the field, and the removed kinds stay as unregistered nodes,
as an uninstalled plugin's do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Porch, deck and patio rooms keep their plates from main's generator: the
room's `floor.drop` gives it a step-down plate of its own, tagged for the
slab geometry and the framing plugin, and the kernel keeps a covered porch's
posts and beam with it. A deck's posts stand on concrete piers of its own and
a porch or patio slab runs its edge down to the site's terrain, now that no
grading reshapes the ground round them.

A deck's railings still carry no footing under main's generic foundation:
a test pins it, and the space-detection page says how outdoor rooms sit on
the plates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A ceiling's cap stands on its layers, stopped short of the floor above.
The floor above is main's plate again, resting on the walls below with its
underside at their top, so the test reads the clamp against that plate
rather than a framed floor hanging into the storey.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dragging a stair previews its cuts as live overrides on the floor plate
above and the ceiling below. The preview's re-entry guard was lifted on a
microtask, so the refresh the drop asks for in the same handler (the stair's
live transform cleared) was swallowed, and so was the opening system's own
refresh after it re-cut the surfaces: the preview's old and new holes stayed
drawn over the stored ones until a reload. The guard now covers only the
preview's own writes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wass08 and others added 14 commits October 30, 2026 14:14
With walls selected in Select mode, alone or among other things, both views
now show every selected wall's temporary room widths and outside sizes, and
the plan keeps each wall's own length (ID/OD) through a multi-selection.
A room width or outside size two selected walls both measure shows once,
by the multi-wall move's own test (now `sameRoomDimension`); the outside
size is placed from the same end of its stretch whichever way the wall was
drawn, so opposite walls put it in one place. Display → Dimensions and
Measure walls apply as before.

Every value stays typeable and moves the wall it runs from. In the plan,
a press on a value under the dashed group box, or on a member's, opens the
type-a-value box instead of starting a group move or pick-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Catalogs re-extracted: strings for the removed foundation, footing,
  floor-layer and slab-room UI drop out
- Floor thickness takes main's translations back

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Material maps resolve to the asset CDN, which only has a new map once it is
deployed; until then the load failed and the surface fell back to its flat
tint (the KTX2 siding on this branch). A CDN miss now retries the app's own
public copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dialog said holding Shift builds freely; the bypass is Alt (E-004), and a
Shift tap cycles the snapping mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arkers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Catalogs re-extracted
- es, fr, ja and zh-CN drafts for the corrected shortcuts note (Alt bypasses
  snapping), marked for review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The metadata reference inventory scans property chains: `metadata.porchPart
.startsWith` read as an unclassified key. Reading the part into a local keeps
the classified `porchPart` key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guide names set_wall_type's refusal code; the test reads snake_case names
as tools unless listed as refusal codes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wass08 wass08 changed the title Editor punch list: walls, rooms, porches and decks, railings, stairs, foundations and roofs editor: walls, porches and decks, railings, stairs, roofs, openings Oct 30, 2026
@wass08
wass08 merged commit 3782f83 into pascalorg:main Oct 30, 2026
4 checks passed
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.

2 participants