feat(paint-slots): migrate wall + procedural kinds onto node.slots

Retire the inline material fields on every slot-model kind, moving them
onto the unified node.slots model on load so painting, edit-propagation,
and the picker behave uniformly.

Walls: slots {interior,exterior}; slot-first viewer resolution threading
sceneMaterials (content folded into the wall material hash); WallRenderer
subscribes to the scene-material palette so a scene-material edit
re-renders live; wallPaint rebuilt on createSlotPaintCapability.

Load migration generalizes legacy -> slots across slab/ceiling (surface),
fence (posts/infill/base/rail), column (shaft/base/capital/frame), shelf
(shelves/frame/back), and stair (per-role tread/side/railing). Library/
scene refs pass through; inline customs mint a deduped scene material;
legacy fields cleared. No visual change (renderers already fell back to
the legacy fields). Roof/chimney/dormer/vents intentionally stay on their
role system.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-06-18 10:12:53 -04:00
co-authored by Claude Opus 4.8
parent faf73d66f2
commit c6423e7c73
11 changed files with 659 additions and 162 deletions
@@ -104,7 +104,14 @@ export const WallCutout = () => {
const hideWall = getWallHideState(wallNode, wallMesh as Mesh, wallMode, u)
const isDeleteHighlighted = deleteHoveredWallId === wallId
const isSelectionHighlighted = !isDeleteHighlighted && highlightedWallIds.has(wallId)
const materials = getMaterialsForWall(wallNode, shading, textures, colorPreset, sceneTheme)
const materials = getMaterialsForWall(
wallNode,
shading,
textures,
colorPreset,
sceneTheme,
useScene.getState().materials,
)
if (hideWall) {
;(wallMesh as Mesh).material = isDeleteHighlighted
@@ -145,6 +152,7 @@ export const WallCutout = () => {
useViewer.getState().textures,
useViewer.getState().colorPreset,
useViewer.getState().sceneTheme,
useScene.getState().materials,
)
const current = wallMesh.material as Material | Material[]
snapshot.set(wallMesh, current)