Enable material paint for fence slab and ceiling nodes
This commit is contained in:
@@ -2,13 +2,16 @@ import {
|
||||
type AnyNode,
|
||||
type AnyNodeId,
|
||||
type BuildingNode,
|
||||
type CeilingNode,
|
||||
emitter,
|
||||
type FenceNode,
|
||||
type ItemNode,
|
||||
type NodeEvent,
|
||||
type RoofEvent,
|
||||
type RoofNode,
|
||||
type RoofSegmentEvent,
|
||||
resolveLevelId,
|
||||
type SlabNode,
|
||||
type StairEvent,
|
||||
type StairNode,
|
||||
type StairSegmentEvent,
|
||||
@@ -25,6 +28,7 @@ import { useCallback, useEffect, useRef } from 'react'
|
||||
import { type BufferGeometry, Color, type Material, type Mesh, type Object3D } from 'three'
|
||||
import {
|
||||
buildRoofSurfaceMaterialPatch,
|
||||
buildSingleSurfaceMaterialPatch,
|
||||
buildStairSurfaceMaterialPatch,
|
||||
buildWallSurfaceMaterialPatch,
|
||||
hasActivePaintMaterial,
|
||||
@@ -609,7 +613,30 @@ export const SelectionManager = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const disabledNodeTypes = ['fence', 'item', 'slab', 'ceiling', 'window', 'door', 'zone']
|
||||
if (node.type === 'fence' || node.type === 'slab' || node.type === 'ceiling') {
|
||||
const target = node.type
|
||||
const compatible =
|
||||
isActivePaintMaterialCompatible(activePaintMaterial, target) &&
|
||||
hasActivePaintMaterial(activePaintMaterial)
|
||||
|
||||
return {
|
||||
apply: compatible
|
||||
? () => {
|
||||
useScene
|
||||
.getState()
|
||||
.updateNode(
|
||||
node.id as AnyNodeId,
|
||||
buildSingleSurfaceMaterialPatch<FenceNode | SlabNode | CeilingNode>(
|
||||
activePaintMaterial.material,
|
||||
activePaintMaterial.materialPreset,
|
||||
),
|
||||
)
|
||||
}
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
const disabledNodeTypes = ['item', 'window', 'door', 'zone']
|
||||
if (disabledNodeTypes.includes(node.type)) {
|
||||
return {
|
||||
apply: null,
|
||||
@@ -776,6 +803,14 @@ export const SelectionManager = () => {
|
||||
nextMaterialTargetHandled = true
|
||||
}
|
||||
|
||||
if (
|
||||
(node.type === 'fence' || node.type === 'slab' || node.type === 'ceiling') &&
|
||||
nodeToSelect.type === node.type
|
||||
) {
|
||||
setSelectedMaterialTargetForNode(nodeToSelect, 'surface')
|
||||
nextMaterialTargetHandled = true
|
||||
}
|
||||
|
||||
if (!nextMaterialTargetHandled && useEditor.getState().selectedMaterialTarget) {
|
||||
useEditor.getState().setSelectedMaterialTarget(null)
|
||||
}
|
||||
@@ -1092,6 +1127,9 @@ const SelectionStateSync = () => {
|
||||
if (
|
||||
!selectedNode ||
|
||||
(selectedNode.type !== 'wall' &&
|
||||
selectedNode.type !== 'fence' &&
|
||||
selectedNode.type !== 'slab' &&
|
||||
selectedNode.type !== 'ceiling' &&
|
||||
selectedNode.type !== 'stair' &&
|
||||
selectedNode.type !== 'roof')
|
||||
) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
type CeilingNode,
|
||||
type FenceNode,
|
||||
getCatalogMaterialById,
|
||||
getEffectiveRoofSurfaceMaterial,
|
||||
getEffectiveStairSurfaceMaterial,
|
||||
@@ -10,13 +12,19 @@ import {
|
||||
type MaterialTarget,
|
||||
type RoofNode,
|
||||
type RoofSurfaceMaterialRole,
|
||||
type SlabNode,
|
||||
type StairNode,
|
||||
type StairSurfaceMaterialRole,
|
||||
type WallNode,
|
||||
type WallSurfaceSide,
|
||||
} from '@pascal-app/core'
|
||||
|
||||
export type PaintableMaterialTarget = Extract<MaterialTarget, 'wall' | 'roof' | 'stair'>
|
||||
export type PaintableMaterialTarget = Extract<
|
||||
MaterialTarget,
|
||||
'wall' | 'roof' | 'stair' | 'fence' | 'slab' | 'ceiling'
|
||||
>
|
||||
|
||||
export type SingleSurfaceMaterialRole = 'surface'
|
||||
|
||||
export type ActivePaintMaterial = {
|
||||
material?: MaterialSchema
|
||||
@@ -135,12 +143,26 @@ export function buildStairSurfaceMaterialPatch(
|
||||
}
|
||||
}
|
||||
|
||||
export function buildSingleSurfaceMaterialPatch<TNode extends FenceNode | SlabNode | CeilingNode>(
|
||||
material: MaterialSchema | undefined,
|
||||
materialPreset: string | undefined,
|
||||
): Partial<TNode> {
|
||||
return {
|
||||
material,
|
||||
materialPreset,
|
||||
} as Partial<TNode>
|
||||
}
|
||||
|
||||
export function resolveActivePaintMaterialFromSelection(params: {
|
||||
nodes: Record<string, any>
|
||||
selectedId: string | null
|
||||
selectedMaterialTarget: {
|
||||
nodeId: string
|
||||
role: WallSurfaceSide | StairSurfaceMaterialRole | RoofSurfaceMaterialRole
|
||||
role:
|
||||
| WallSurfaceSide
|
||||
| StairSurfaceMaterialRole
|
||||
| RoofSurfaceMaterialRole
|
||||
| SingleSurfaceMaterialRole
|
||||
} | null
|
||||
}): ActivePaintMaterial | null {
|
||||
const { nodes, selectedId, selectedMaterialTarget } = params
|
||||
@@ -208,6 +230,26 @@ export function resolveActivePaintMaterialFromSelection(params: {
|
||||
: null
|
||||
}
|
||||
|
||||
if (
|
||||
(selectedNode.type === 'fence' ||
|
||||
selectedNode.type === 'slab' ||
|
||||
selectedNode.type === 'ceiling') &&
|
||||
selectedMaterialTarget.role === 'surface'
|
||||
) {
|
||||
const target = selectedNode.type
|
||||
return hasActivePaintMaterial({
|
||||
material: selectedNode.material,
|
||||
materialPreset: selectedNode.materialPreset,
|
||||
sourceTarget: target,
|
||||
})
|
||||
? {
|
||||
material: selectedNode.material,
|
||||
materialPreset: selectedNode.materialPreset,
|
||||
sourceTarget: target,
|
||||
}
|
||||
: null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -233,5 +275,17 @@ export function resolvePaintTargetFromSelection(params: {
|
||||
return 'stair'
|
||||
}
|
||||
|
||||
if (selectedNode.type === 'fence') {
|
||||
return 'fence'
|
||||
}
|
||||
|
||||
if (selectedNode.type === 'slab') {
|
||||
return 'slab'
|
||||
}
|
||||
|
||||
if (selectedNode.type === 'ceiling') {
|
||||
return 'ceiling'
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
type PaintableMaterialTarget,
|
||||
resolveActivePaintMaterialFromSelection,
|
||||
resolvePaintTargetFromSelection,
|
||||
type SingleSurfaceMaterialRole,
|
||||
} from '../lib/material-paint'
|
||||
|
||||
const DEFAULT_ACTIVE_SIDEBAR_PANEL = 'site'
|
||||
@@ -94,6 +95,7 @@ export type MaterialTargetRole =
|
||||
| WallSurfaceSide
|
||||
| StairSurfaceMaterialRole
|
||||
| RoofSurfaceMaterialRole
|
||||
| SingleSurfaceMaterialRole
|
||||
|
||||
export type SelectedMaterialTarget = {
|
||||
nodeId: AnyNodeId
|
||||
|
||||
Reference in New Issue
Block a user