import type { ToolMode } from "../core/tool-mode"; import { createOpaqueId } from "../core/ids"; import type { EditorSelection } from "../core/selection"; import { cloneFaceUvState, updateBrush, type FaceUvState, type WhiteboxFaceId } from "../document/brushes"; import { getBrushFaceIds } from "../geometry/whitebox-topology"; import { cloneSelectionForCommand, getBoxBrushOrThrow, replaceBrush } from "./brush-command-helpers"; import type { EditorCommand } from "./command"; interface UpdateBoxBrushAllFaceUvsCommandOptions { brushId: string; label: string; updateUvState(uvState: FaceUvState, faceId: WhiteboxFaceId): FaceUvState; } export function createUpdateBoxBrushAllFaceUvsCommand( options: UpdateBoxBrushAllFaceUvsCommandOptions ): EditorCommand { let previousUvStates: Record | null = null; let previousSelection: EditorSelection | null = null; let previousToolMode: ToolMode | null = null; return { id: createOpaqueId("command"), label: options.label, execute(context) { const currentDocument = context.getDocument(); const currentBrush = getBoxBrushOrThrow(currentDocument, options.brushId); if (previousUvStates === null) { previousUvStates = Object.fromEntries( getBrushFaceIds(currentBrush).map((faceId) => [ faceId, cloneFaceUvState(currentBrush.faces[faceId].uv) ]) ); } if (previousSelection === null) { previousSelection = cloneSelectionForCommand(context.getSelection()); } if (previousToolMode === null) { previousToolMode = context.getToolMode(); } context.setDocument( replaceBrush( currentDocument, updateBrush(currentBrush, { faces: Object.fromEntries( getBrushFaceIds(currentBrush).map((faceId) => [ faceId, { ...currentBrush.faces[faceId], uv: cloneFaceUvState( options.updateUvState(currentBrush.faces[faceId].uv, faceId) ) } ]) ) as typeof currentBrush.faces }) ) ); context.setToolMode("select"); }, undo(context) { if (previousUvStates === null) { return; } const currentDocument = context.getDocument(); const currentBrush = getBoxBrushOrThrow(currentDocument, options.brushId); const restoredUvStates = previousUvStates; context.setDocument( replaceBrush( currentDocument, updateBrush(currentBrush, { faces: Object.fromEntries( getBrushFaceIds(currentBrush).map((faceId) => [ faceId, { ...currentBrush.faces[faceId], uv: cloneFaceUvState(restoredUvStates[faceId]) } ]) ) as typeof currentBrush.faces }) ) ); if (previousSelection !== null) { context.setSelection(previousSelection); } if (previousToolMode !== null) { context.setToolMode(previousToolMode); } } }; }