Wassim SAMAD 967a905e3b feat(paint-slots): unified slot defaults + paint for slab, ceiling, wall (phase 5)
Brings slab, ceiling, and wall onto the unified slot contract the shelf
established, so each declares its paintable slots with a declarative default and
(slab/ceiling) is painted through the registry capabilities.paint dispatch.

- Shared helper packages/nodes/src/shared/slot-paint.ts: a node.slots-based
  PaintCapability factory (commit/resolve/effective generic; preview injected).
  Distinct from surface-paint.ts, which writes the legacy inline node.material.
- slab: schema slots; def.geometry resolves node.slots.surface -> legacy
  material -> declared default, tags the mesh userData.slotId; slabPaint +
  capabilities.slots. Retires DEFAULT_SLAB_MATERIAL in the slab path.
- ceiling: schema slots; material builders extracted to ceiling/materials.ts
  (shared by renderer + paint preview, built BackSide so the hover preview is
  visible from below); renderer resolves the slot; ceilingPaint + slots.
- wall: WALL_SLOT_DEFAULT in core; the viewer's getMaterialsForWall renders an
  unpainted face with its declared default instead of the themed wall role;
  capabilities.slots (interior/exterior). wallPaint's inline interior/exterior
  fields are unchanged (node.slots migration is a later step).
- selection-manager + material-paint: drop slab/ceiling from the legacy
  single-surface arms (now registry-driven).

Behavior change (intended, matches the shelf precedent + the phase-5 plan):
colored-mode UNPAINTED slab/ceiling/wall surfaces now render their fixed slot
default (#e5e5e5 / #f5f5dc / #ffffff) instead of the theme role colour. The
textures-off (monochrome) role collapse is unchanged — the escape hatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 07:51:37 -04:00

166 lines
4.7 KiB
TypeScript

// Base
export {
SOLAR_PANEL_PRESET_LABELS,
SOLAR_PANEL_PRESETS,
type SolarPanelPresetDims,
SolarPanelPresetKey,
} from '../solar-panel-presets'
export { BaseNode, generateId, Material, nodeType, objectId } from './base'
// Camera
export { CameraSchema } from './camera'
// Collections
export { type Collection, type CollectionId, generateCollectionId } from './collections'
export type {
MaterialMapProperties,
MaterialMaps,
MaterialPresetPayload,
MaterialTarget as MaterialTargetValue,
TextureWrapMode as TextureWrapModeValue,
} from './material'
// Material
export {
DEFAULT_MATERIALS,
MaterialMapPropertiesSchema,
MaterialMapsSchema,
MaterialPreset,
MaterialPresetPayloadSchema,
MaterialProperties,
MaterialSchema,
MaterialTarget,
resolveMaterial,
TextureWrapMode,
} from './material'
export { BoxVentNode } from './nodes/box-vent'
export { BuildingNode } from './nodes/building'
export { CeilingNode } from './nodes/ceiling'
export { ChimneyMaterialRole, ChimneyNode } from './nodes/chimney'
export {
COLUMN_PRESETS,
ColumnBaseStyle,
ColumnCapitalStyle,
ColumnCarvingPlacement,
ColumnCrossSection,
ColumnNode,
ColumnPanelShape,
type ColumnPresetId,
ColumnRingPlacement,
ColumnShaftDetail,
ColumnShaftProfile,
ColumnStyle,
ColumnSupportStyle,
} from './nodes/column'
export { CupolaNode } from './nodes/cupola'
export { DoorNode, DoorSegment } from './nodes/door'
export {
DormerNode,
type DormerSurfaceMaterialRole,
type DormerSurfaceMaterialSpec,
getEffectiveDormerSurfaceMaterial,
} from './nodes/dormer'
export { DownspoutNode } from './nodes/downspout'
export {
ElevatorDoorPanelStyle,
ElevatorDoorStyle,
ElevatorNode,
ElevatorShaftStyle,
} from './nodes/elevator'
export { EyebrowVentNode } from './nodes/eyebrow-vent'
export { FenceBaseStyle, FenceNode, FenceStyle } from './nodes/fence'
export { GuideNode, GuideScaleReference } from './nodes/guide'
export { GutterNode, GutterOutlet } from './nodes/gutter'
export type {
AnimationEffect,
Asset,
AssetInput,
Control,
Effect,
Interactive,
LightEffect,
SliderControl,
TemperatureControl,
ToggleControl,
} from './nodes/item'
export {
getScaledDimensions,
ItemNode,
isLowProfileItemSurface,
LOW_PROFILE_ITEM_SURFACE_MAX_HEIGHT,
} from './nodes/item'
export { LevelNode } from './nodes/level'
// Nodes
export { RidgeVentNode } from './nodes/ridge-vent'
export type { RoofSurfaceMaterialRole, RoofSurfaceMaterialSpec } from './nodes/roof'
export { getEffectiveRoofSurfaceMaterial, RoofNode } from './nodes/roof'
export type {
RoofSegmentSurfaceMaterialRole,
RoofSegmentSurfaceMaterialSpec,
SegmentSlopeFrame,
} from './nodes/roof-segment'
export {
getActiveRoofHeight,
getEffectiveSegmentSurfaceMaterial,
getPitchFromActiveRoofHeight,
getRoofSegmentSurfaceY,
getSegmentSlopeFrame,
hasSegmentMaterialOverride,
ROOF_SHAPE_DEFAULTS,
RoofSegmentNode,
RoofType,
} from './nodes/roof-segment'
export type { RoofSegmentWallFace, RoofWallFaceId } from './nodes/roof-segment-walls'
export {
clampRectToRoofWallFace,
getMaxRoofRectHeightFromAnchor,
getMaxRoofRectWidthFromAnchor,
getRoofSegmentWallFace,
getRoofSegmentWallFaces,
getRoofWallFaceFrame,
roofFacePointToSegment,
segmentPointToRoofWallFace,
} from './nodes/roof-segment-walls'
export { ScanNode } from './nodes/scan'
export { ShelfNode } from './nodes/shelf'
export { SiteNode } from './nodes/site'
export {
SKYLIGHT_TYPE_ORDER,
SKYLIGHT_TYPE_PRESETS,
SkylightMaterialRole,
SkylightNode,
SkylightOpeningSide,
SkylightSlideDirection,
SkylightType,
type SkylightTypePreset,
} from './nodes/skylight'
export { SlabNode } from './nodes/slab'
export {
SolarPanelMaterialRole,
SolarPanelNode,
} from './nodes/solar-panel'
export { SpawnNode } from './nodes/spawn'
export type { StairSurfaceMaterialRole, StairSurfaceMaterialSpec } from './nodes/stair'
export {
getEffectiveStairSurfaceMaterial,
StairNode,
StairRailingMode,
StairSlabOpeningMode,
StairTopLandingMode,
StairType,
} from './nodes/stair'
export { AttachmentSide, StairSegmentNode, StairSegmentType } from './nodes/stair-segment'
export { SurfaceHoleMetadata } from './nodes/surface-hole-metadata'
export { TurbineVentNode } from './nodes/turbine-vent'
export type { WallSurfaceMaterialSpec, WallSurfaceSide } from './nodes/wall'
export {
getEffectiveWallSurfaceMaterial,
getWallSurfaceMaterialSignature,
WALL_SLOT_DEFAULT,
WallNode,
} from './nodes/wall'
export { WindowNode, WindowType } from './nodes/window'
export { ZoneNode } from './nodes/zone'
export { generateSceneMaterialId, SceneMaterial, type SceneMaterialId } from './scene-material'
export type { AnyNodeId, AnyNodeType } from './types'
// Union types
export { AnyNode } from './types'