From 275a42cc7f55a5b41c7c95bd57b516c8cf0fdf48 Mon Sep 17 00:00:00 2001 From: sudhir Date: Sat, 25 Apr 2026 00:15:29 +0530 Subject: [PATCH] Simplify paint material compatibility logic --- packages/core/src/index.ts | 1 - packages/core/src/material-library.ts | 40 ------------------- .../components/editor/selection-manager.tsx | 17 +++----- .../src/components/ui/action-menu/index.tsx | 8 ++-- .../ui/controls/material-picker.tsx | 36 ++++++++--------- .../src/components/ui/panels/paint-panel.tsx | 1 - packages/editor/src/lib/material-paint.ts | 34 ---------------- 7 files changed, 25 insertions(+), 112 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d8d80978..7ef4e545 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -40,7 +40,6 @@ export { export { baseMaterial, glassMaterial } from './materials' export { getCatalogMaterialById, - getMaterialCategoryTargets, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForCategory, diff --git a/packages/core/src/material-library.ts b/packages/core/src/material-library.ts index a52ac07f..5b08bec1 100644 --- a/packages/core/src/material-library.ts +++ b/packages/core/src/material-library.ts @@ -1,7 +1,5 @@ import { type MaterialPresetPayload, - type MaterialTarget, - MaterialTarget as MaterialTargetSchema, } from './schema/material' export type MaterialCatalogItem = { @@ -24,40 +22,6 @@ export const MATERIAL_CATEGORIES = [ ] as const export type MaterialCategory = (typeof MATERIAL_CATEGORIES)[number] -export const MATERIAL_CATEGORY_TARGETS: Record = { - wood: [ - MaterialTargetSchema.enum.wall, - MaterialTargetSchema.enum.slab, - MaterialTargetSchema.enum.stair, - MaterialTargetSchema.enum['stair-segment'], - MaterialTargetSchema.enum.fence, - MaterialTargetSchema.enum.roof, - MaterialTargetSchema.enum['roof-segment'], - ], - wallpaper: [MaterialTargetSchema.enum.wall], - parquet: [ - MaterialTargetSchema.enum.slab, - MaterialTargetSchema.enum.stair, - MaterialTargetSchema.enum['stair-segment'], - ], - granite: [MaterialTargetSchema.enum.slab], - marble: [ - MaterialTargetSchema.enum.slab, - MaterialTargetSchema.enum.stair, - MaterialTargetSchema.enum['stair-segment'], - ], - other: [ - MaterialTargetSchema.enum.wall, - MaterialTargetSchema.enum.roof, - MaterialTargetSchema.enum['roof-segment'], - MaterialTargetSchema.enum.stair, - MaterialTargetSchema.enum['stair-segment'], - MaterialTargetSchema.enum.fence, - MaterialTargetSchema.enum.slab, - MaterialTargetSchema.enum.ceiling, - ], -} - export const MATERIAL_CATALOG: MaterialCatalogItem[] = [ { id: 'wall-wood1', @@ -609,10 +573,6 @@ export function getMaterialsForCategory(category: MaterialCategory): MaterialCat return MATERIAL_CATALOG.filter((item) => item.category === category) } -export function getMaterialCategoryTargets(category: MaterialCategory): MaterialTarget[] { - return MATERIAL_CATEGORY_TARGETS[category] -} - export function getCatalogMaterialById(id?: string): MaterialCatalogItem | undefined { if (!id) return undefined return MATERIAL_CATALOG.find((item) => item.id === id) diff --git a/packages/editor/src/components/editor/selection-manager.tsx b/packages/editor/src/components/editor/selection-manager.tsx index 1db09ba1..884fc80d 100755 --- a/packages/editor/src/components/editor/selection-manager.tsx +++ b/packages/editor/src/components/editor/selection-manager.tsx @@ -44,7 +44,6 @@ import { buildStairSurfaceMaterialPatch, buildWallSurfaceMaterialPatch, hasActivePaintMaterial, - isActivePaintMaterialCompatible, resolveActivePaintMaterialFromSelection, } from '../../lib/material-paint' import { sfxEmitter } from '../../lib/sfx-bus' @@ -741,8 +740,7 @@ export const SelectionManager = () => { if (node.type === 'wall') { const role = resolveWallMaterialTarget(event as WallEvent) - const compatible = - role !== null && isActivePaintMaterialCompatible(activePaintMaterial, 'wall') + const compatible = role !== null && hasActivePaintMaterial(activePaintMaterial) return { key: `wall:${node.id}:${role ?? 'unsupported'}`, hoveredId: node.id as AnyNodeId, @@ -783,8 +781,7 @@ export const SelectionManager = () => { if (!roofNode || roofNode.type !== 'roof') return null const role = resolveRoofMaterialTarget(event as RoofEvent | RoofSegmentEvent) - const compatible = - role !== null && isActivePaintMaterialCompatible(activePaintMaterial, 'roof') + const compatible = role !== null && hasActivePaintMaterial(activePaintMaterial) return { key: `roof:${roofNode.id}:${role ?? 'unsupported'}`, hoveredId: roofNode.id as AnyNodeId, @@ -825,8 +822,7 @@ export const SelectionManager = () => { if (!stairNode || stairNode.type !== 'stair') return null const role = resolveStairMaterialTarget(event as StairEvent | StairSegmentEvent) - const compatible = - role !== null && isActivePaintMaterialCompatible(activePaintMaterial, 'stair') + const compatible = role !== null && hasActivePaintMaterial(activePaintMaterial) return { key: `stair:${stairNode.id}:${role ?? 'unsupported'}`, hoveredId: stairNode.id as AnyNodeId, @@ -858,13 +854,10 @@ export const SelectionManager = () => { } if (node.type === 'fence' || node.type === 'slab' || node.type === 'ceiling') { - const target = node.type - const compatible = - isActivePaintMaterialCompatible(activePaintMaterial, target) && - hasActivePaintMaterial(activePaintMaterial) + const compatible = hasActivePaintMaterial(activePaintMaterial) return { - key: `${target}:${node.id}:surface`, + key: `${node.type}:${node.id}:surface`, hoveredId: node.id as AnyNodeId, hoverMode: compatible ? 'paint-ready' : 'paint-disabled', apply: compatible diff --git a/packages/editor/src/components/ui/action-menu/index.tsx b/packages/editor/src/components/ui/action-menu/index.tsx index e1c59cb4..f74b6180 100644 --- a/packages/editor/src/components/ui/action-menu/index.tsx +++ b/packages/editor/src/components/ui/action-menu/index.tsx @@ -40,11 +40,11 @@ function PaintMaterialTray() { return (
{ - setActivePaintMaterial({ material, category, sourceTarget: activePaintTarget }) + onChange={(material) => { + setActivePaintMaterial({ material, sourceTarget: activePaintTarget }) }} - onSelectMaterialPreset={(materialPreset, category) => { - setActivePaintMaterial({ materialPreset, category, sourceTarget: activePaintTarget }) + onSelectMaterialPreset={(materialPreset) => { + setActivePaintMaterial({ materialPreset, sourceTarget: activePaintTarget }) }} selectedMaterialPreset={activePaintMaterial?.materialPreset} value={activePaintMaterial?.material} diff --git a/packages/editor/src/components/ui/controls/material-picker.tsx b/packages/editor/src/components/ui/controls/material-picker.tsx index ce743482..b328ee5e 100755 --- a/packages/editor/src/components/ui/controls/material-picker.tsx +++ b/packages/editor/src/components/ui/controls/material-picker.tsx @@ -6,7 +6,6 @@ import { getMaterialsForCategory, MATERIAL_CATEGORIES, toLibraryMaterialRef, - type MaterialCategory, type MaterialSchema, } from '@pascal-app/core' import { useEffect, useRef, useState } from 'react' @@ -15,8 +14,8 @@ import useEditor from '../../../store/use-editor' type MaterialPickerProps = { value?: MaterialSchema selectedMaterialPreset?: string - onChange?: (material: MaterialSchema, category: MaterialCategory) => void - onSelectMaterialPreset?: (materialPreset: string, category: MaterialCategory) => void + onChange?: (material: MaterialSchema) => void + onSelectMaterialPreset?: (materialPreset: string) => void disabled?: boolean } @@ -29,7 +28,9 @@ export function MaterialPicker({ }: MaterialPickerProps) { const setPaintPanelOpen = useEditor((state) => state.setPaintPanelOpen) const [showCustom, setShowCustom] = useState(!!value?.properties) - const [selectedCategory, setSelectedCategory] = useState(MATERIAL_CATEGORIES[0]) + const [selectedCategory, setSelectedCategory] = useState<(typeof MATERIAL_CATEGORIES)[number]>( + MATERIAL_CATEGORIES[0], + ) const catalogScrollRef = useRef(null) const categoryScrollRef = useRef(null) const catalogItems = @@ -62,9 +63,7 @@ export function MaterialPicker({ if (disabled) return setShowCustom(false) setPaintPanelOpen(false) - const category = getCatalogMaterialById(materialId)?.category - if (!category) return - onSelectMaterialPreset?.(toLibraryMaterialRef(materialId), category) + onSelectMaterialPreset?.(toLibraryMaterialRef(materialId)) } useEffect(() => { @@ -113,20 +112,17 @@ export function MaterialPicker({ if (disabled) return setShowCustom(true) setPaintPanelOpen(true) - onChange?.( - { - preset: 'custom', - properties: { - color: value?.properties?.color || '#ffffff', - roughness: value?.properties?.roughness ?? 0.5, - metalness: value?.properties?.metalness ?? 0, - opacity: value?.properties?.opacity ?? 1, - transparent: value?.properties?.transparent ?? false, - side: value?.properties?.side ?? 'front', - }, + onChange?.({ + preset: 'custom', + properties: { + color: value?.properties?.color || '#ffffff', + roughness: value?.properties?.roughness ?? 0.5, + metalness: value?.properties?.metalness ?? 0, + opacity: value?.properties?.opacity ?? 1, + transparent: value?.properties?.transparent ?? false, + side: value?.properties?.side ?? 'front', }, - 'other', - ) + }) } return ( diff --git a/packages/editor/src/components/ui/panels/paint-panel.tsx b/packages/editor/src/components/ui/panels/paint-panel.tsx index 0df8c677..ffa8ec9d 100644 --- a/packages/editor/src/components/ui/panels/paint-panel.tsx +++ b/packages/editor/src/components/ui/panels/paint-panel.tsx @@ -47,7 +47,6 @@ export function PaintPanel() { transparent: nextTransparent, }, }, - category: 'other', sourceTarget: activePaintMaterial?.sourceTarget ?? activePaintTarget, }) } diff --git a/packages/editor/src/lib/material-paint.ts b/packages/editor/src/lib/material-paint.ts index e1f52156..ffdde786 100644 --- a/packages/editor/src/lib/material-paint.ts +++ b/packages/editor/src/lib/material-paint.ts @@ -8,8 +8,6 @@ import { getEffectiveStairSurfaceMaterial, getEffectiveWallSurfaceMaterial, getLibraryMaterialIdFromRef, - getMaterialCategoryTargets, - type MaterialCategory, type MaterialSchema, type MaterialTarget, type RoofNode, @@ -31,7 +29,6 @@ export type SingleSurfaceMaterialRole = 'surface' export type ActivePaintMaterial = { material?: MaterialSchema materialPreset?: string - category?: MaterialCategory sourceTarget: PaintableMaterialTarget } @@ -50,34 +47,10 @@ function getCatalogEntryForActivePaintMaterial(material: ActivePaintMaterial | n return getCatalogMaterialById(catalogId) } -function resolvePaintMaterialCategory( - material: MaterialSchema | undefined, - materialPreset: string | undefined, -): MaterialCategory | undefined { - const catalogId = getLibraryMaterialIdFromRef(materialPreset) ?? material?.id ?? undefined - const catalogEntry = getCatalogMaterialById(catalogId) - if (catalogEntry?.category) return catalogEntry.category - if (material || materialPreset === undefined) return 'other' - return undefined -} - export function getActivePaintMaterialLabel(material: ActivePaintMaterial | null | undefined) { return getCatalogEntryForActivePaintMaterial(material)?.label ?? 'Custom' } -export function isActivePaintMaterialCompatible( - material: ActivePaintMaterial | null | undefined, - target: PaintableMaterialTarget, -) { - if (!hasActivePaintMaterial(material)) return false - - const catalogEntry = getCatalogEntryForActivePaintMaterial(material) - const category = material?.category ?? catalogEntry?.category - if (!category) return false - - return getMaterialCategoryTargets(category).includes(target) -} - export function buildWallSurfaceMaterialPatch( node: WallNode, targetSide: WallSurfaceSide, @@ -200,7 +173,6 @@ export function resolveActivePaintMaterialFromSelection(params: { ? { material: surface.material, materialPreset: surface.materialPreset, - category: resolvePaintMaterialCategory(surface.material, surface.materialPreset), sourceTarget: 'wall', } : null @@ -221,7 +193,6 @@ export function resolveActivePaintMaterialFromSelection(params: { ? { material: surface.material, materialPreset: surface.materialPreset, - category: resolvePaintMaterialCategory(surface.material, surface.materialPreset), sourceTarget: 'roof', } : null @@ -242,7 +213,6 @@ export function resolveActivePaintMaterialFromSelection(params: { ? { material: surface.material, materialPreset: surface.materialPreset, - category: resolvePaintMaterialCategory(surface.material, surface.materialPreset), sourceTarget: 'stair', } : null @@ -263,10 +233,6 @@ export function resolveActivePaintMaterialFromSelection(params: { ? { material: selectedNode.material, materialPreset: selectedNode.materialPreset, - category: resolvePaintMaterialCategory( - selectedNode.material, - selectedNode.materialPreset, - ), sourceTarget: target, } : null