feat(paint-slots): migrate column onto the unified slot model

Column exposes shaft / base / capital / frame slots on node.slots (base when
baseStyle!=none, capital when capitalStyle!=none, frame only for non-vertical
support styles). The single material context is widened to a per-slot map plus
a ColumnSlotContext; each part subtree is wrapped in <ColumnSlot> so every
mesh primitive resolves its material AND stamps userData.slotId from the same
context. Decorative shaft parts inherit shaft, base/capital carvings inherit
their parent slot. Resolution: textures-off wall role -> node.slots ref ->
legacy material/preset -> declared default (shaft/base/capital concrete-plaster,
frame metal-steel). Monochrome unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-06-17 15:34:39 -04:00
co-authored by Claude Opus 4.8
parent a8f32dd47a
commit 0cdaf8b1b9
4 changed files with 307 additions and 67 deletions
+4
View File
@@ -7,8 +7,10 @@ import {
import { buildColumnFloorplan } from './floorplan'
import { columnResizeAffordance, columnRotateAffordance } from './floorplan-affordances'
import { columnFloorplanMoveTarget } from './floorplan-move'
import { columnPaint } from './paint'
import { columnParametrics } from './parametrics'
import { ColumnNode } from './schema'
import { columnSlots } from './slots'
// Limits + offsets shared with the in-world arrows. Mirrors the floors
// the renderer clamps to (`Math.max(0.2, node.height)` etc.) so a drag
@@ -325,6 +327,8 @@ export const columnDefinition: NodeDefinition<typeof ColumnNode> = {
selectable: { hitVolume: 'bbox' },
duplicable: true,
deletable: true,
slots: (node) => columnSlots(node as ColumnNodeType),
paint: columnPaint,
// Slab elevation lift via the generic `<FloorElevationSystem>`.
floorPlaced: {
footprint: (node) => {