Files
editor/packages/nodes/src/fence/paint.ts
T
Wassim SAMADandClaude Opus 4.8 bba0cc5f68 feat(paint-slots): prepared-drywall finish + fence 4 slots matching build options
- Add 'concrete-drywall' (Prepared Drywall) catalog finish + 512 KTX2/webp
  runtime assets; default walls (WALL_SLOT_DEFAULT interior+exterior) and the
  roof wall/trim band to it so roofs read continuous with walls.
- fence: replace the 2-slot panel/rail split with 4 slots that match the panel's
  build options — posts / infill (showInfill) / base (grounded only) / rail —
  each its own mesh with userData.slotId; conditional slots track the build
  state. Defaults: posts/infill/base charcoal, rail wood-finewood27.

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

22 lines
841 B
TypeScript

import type { AnyNode, FenceNode, PaintResolveArgs } from '@pascal-app/core'
import { createSlotPaintCapability, previewGeometrySlot } from '../shared/slot-paint'
const FENCE_SLOT_IDS = new Set<string>(['posts', 'infill', 'base', 'rail'])
function resolveFenceRole(args: PaintResolveArgs): string | null {
const slotId = (args.hitObject?.userData as { slotId?: unknown } | undefined)?.slotId
return typeof slotId === 'string' && FENCE_SLOT_IDS.has(slotId) ? slotId : null
}
export const fencePaint = createSlotPaintCapability({
resolveRole: resolveFenceRole,
applyPreview: previewGeometrySlot,
legacyEffective: (node: AnyNode) => {
const fence = node as FenceNode
if (fence.materialPreset || fence.material) {
return { material: fence.material, materialPreset: fence.materialPreset }
}
return null
},
})