Skip to content

One building mode, light room labels and a unified viewer - #1019

Merged
wass08 merged 8 commits into
mainfrom
feat/merge-structure-furnish
Oct 8, 2026
Merged

wass08 merged 8 commits into
mainfrom
feat/merge-structure-furnish

Conversation

@wass08

@wass08 wass08 commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Simplifies how the editor and viewers handle levels, rooms and selection.

One building mode. The editor phase was Site / Structure / Furnish, but clicks switched it to the clicked node's home, so the tab followed the last click, 2D and 3D disagreed, and some handles only existed on Structure. Phase is now site | building:

  • No click changes it, except entering the building from Site. In 2D or 3D, a click on the house from Site selects the building.
  • Everything on the active level is clickable in 2D and 3D: rooms first, then drill down.
  • Outline editors and 2D opening placement depend only on select mode.
  • Keys: 1 = Site, 2 = building, F opens the catalog; B/P/M/Z just arm their tools.
  • A stored structure/furnish preference reads back as building.
  • resolveNodeSelectionTarget, emitCanvasNodeSelection and the selection:canvas-node-click event are removed.

One rooms list, light room labels. The Elements | Rooms layer split (structureLayer) is removed.

  • The Scene panel lists Units, then Rooms, then Elements.
  • Rooms on the active level show a small pill (colour dot, name, area in the active unit) in 2D and 3D when nothing but the site, building or level is selected.
  • Pills float 1.25 m above the floor, declutter when they overlap, and fade in and out. Hover and click go through the canvas's zone rule.
  • Tinted zone volumes remain only for unit-membership painting. Drawn zones look like rooms.
  • The zone toolbar button is gone; Z still works.

Room colours. A colour is picked once at creation from the room's id (zoneColorForSeed, newZone) and stored; existing rooms are never recoloured.

Viewers. The public viewer (baked and parametric), embeds and the editor's Preview share one rules module (viewer-selection) with two hit sources and one header:

  • Floor or wall click → room; second click → element. An empty click clears but keeps the floor.
  • Breadcrumb Building › Floor › Room › Item, with framing on crumb, sidebar and pill clicks (camera-controls:frame).
  • Sidebar Units / Rooms / Zones, and a hover-name pill.
  • The editor's pills replace tinted volumes.
  • Preview saves and restores the editor's selection, focused unit, tool and camera.

Editor app. Streetscape is pinned to a one-line fix (drop setPhase('structure') / setStructureLayer); upstream sudhir9297/streetscape-pascal-plugin#1.

How to test

  1. Click a sofa, a wall, then stairs in 3D and 2D → the mode stays Building.
  2. From Site, click the house in 2D or 3D → the building is selected and you're inside.
  3. With nothing selected → room pills with distinct colours. Select a wall → pills fade out. Hover a pill → the room highlights; click it → the room is selected.
  4. Draw a zone → it gets a pill like a room, with no tint.
  5. Preview → click a floor (selects the room), an item (breadcrumb shows the room), a sidebar room (camera frames it) → exit → the editor is exactly as before.

Automated: editor, nodes, core, viewer and mcp suites pass locally.

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

🤖 Generated with Claude Code

https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X


Note

Medium Risk
Broad changes to editor phase, 2D/3D/preview selection, camera framing, and zone creation colors affect core interaction paths; regressions are likely in edge cases rather than data/security.

Overview
Unifies editor navigation around site and building, dropping the old Structure/Furnish split and the Elements vs Rooms structureLayer. Build tools and palette activations now set phase: 'building' only; selection no longer auto-switches phase. From site, clicks on the building (2D or 3D via enterBuildingFromCanvas / enterBuildingFromPlanHit) enter the building instead of routing through structure/furnish targets.

Room UX adds decluttered name/area pills in 2D and 3D (RoomLabels2D/3D) when the level is at rest (select idle, only site/building/level context selected). Zone fills are tinted volumes only during unit-membership painting; otherwise zones behave like rooms (outline highlight, shared clickZoneArea / hoverZoneArea). The old 3D zone label editor system is removed.

Core introduces newZone and zoneColorForSeed so new rooms get a deterministic palette color from their id unless explicitly set; structure reconcile remaps colors when zone ids are minted. camera-controls:frame and CameraControlFrameEvent support viewer-style framing.

Preview aligns with the shared viewer selection path (ViewerSelectionManager, ParametricViewerRooms): left click no longer pans the camera; opening preview frames level/building once; camera restore on exit. Streetscape dependency is repinned to a fork commit without the removed phase APIs.

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

wass08 and others added 7 commits October 7, 2026 16:56
The editor phase was Site / Structure / Furnish, but clicks switched it to the
clicked node's home, so the tab followed the last click, 2D and 3D disagreed,
and some handles only existed on Structure. Phase is now site | building: no
click changes it except entering the building from Site; everything on the
active level is clickable in 2D and 3D (rooms first, then drill down); slab,
ceiling and zone outline editors and 2D opening placement depend only on
select mode; the Scene panel reads Elements | Rooms; 1 = Site, 2 = building,
F opens the catalog with the item tool, B/P/M/Z just arm their tools. A stored
structure/furnish preference reads back as building. resolveNodeSelectionTarget,
emitCanvasNodeSelection and the unused selection:canvas-node-click event are
removed. Docs and wiki updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X
Removes the Elements | Rooms layer split (structureLayer): the Scene panel
lists Units, then Rooms, then Elements for the active level. Rooms on the
active level show a small pill (colour dot, name, area in the active unit)
when nothing but the site, building or level is selected and no tool is
active; tinted zone volumes remain only for unit-membership painting and a
selected free-drawn zone. In 2D, clicking any part of the building from Site
selects the building and enters it, like 3D.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X
… mode

The pinned plugin called setPhase('structure') and setStructureLayer, both gone.
Pins the one-line fix on top of the previous commit (wass08 fork, upstream PR
sudhir9297/streetscape-pascal-plugin#1) until the plugin moves to its monorepo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X
…es as rooms

Rooms show distinct colours; drawn zones render like rooms (pill + outline, tint
only while painting unit membership); the zone toolbar button is gone (Z stays);
pills float 1.25 m above the floor and declutter on camera rest; the 2D plan
uses the same pills instead of multiline tags on the editor canvas (exports and
sheets keep tags). Pill hover/click go through the canvas's zone rule
(hoverZoneArea/clickZoneArea), including modifiers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X
…reation

Viewers: the public viewer (baked and parametric), embeds and the editor's
Preview share one rules module (viewer-selection) fed by two hit sources
(node events, baked GLB picks) and one header: floor/wall clicks select the
room, a second click drills to the element, items select, empty clicks clear
but keep the floor; breadcrumb Building › Floor › Room › Item with framing on
crumb/sidebar clicks (camera-controls:frame); sidebar Units / Rooms / Zones;
the editor's room pills replace tinted zone volumes. Preview saves and restores
the editor's selection, focused unit, tool and camera.

Rooms: a colour is chosen once at creation from the room's id (zoneColorForSeed)
and stored; captured rooms seed from the capture id; nothing is recoloured on
load. Pills recompute overlaps on near-rest and while moving, and fade in/out
then unmount.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X
Viewer pills select and frame their room; a bottom hover pill names what a click
would select (baked, parametric, embed, Preview; hidden in walkthrough, 2D and
on touch); viewer pills fade out like the editor's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X

@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.

useViewer.getState().setSelection({ buildingId, selectedIds: [] })
useEditor.getState().setPhase('building')
return true
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Site entry clears the active floor

High Severity

Clicking the house from Site calls setSelection with only buildingId, and the viewer hierarchy guard then nulls levelId. The user enters Building with no active floor, so room pills, level filtering, and the floorplan lose the storey they just clicked.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a18985b. Configure here.

The WebXR plugin listens to it; canvas clicks that select a node (2D and 3D)
emit it again from emitCanvasNodeSelection (Delete mode deletes instead).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzGbHVg2Tpv4zEw9yLaT5X

@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 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

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 0eb4058. Configure here.

useViewer.getState().setShowZones(active)
return () => useViewer.getState().setShowZones(true)
}, [structureLayerState, isCaptureModeState])
}, [active])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Preview shows tinted zone volumes

Medium Severity

showZones now means “unit-painting volumes only”, but ZoneSystem still restores showZones to true on unmount. Opening Preview unmounts that system, so the shared viewer flag turns zone meshes back on and tinted volumes appear next to the new pills.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0eb4058. Configure here.

@wass08
wass08 merged commit 0c186e2 into main Oct 8, 2026
5 checks passed
@wass08
wass08 deleted the feat/merge-structure-furnish branch October 8, 2026 19:36
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.

1 participant