Set apperance in feature tree context menu (#5439)

* Revert "Revert multi-profile (#4812)"

This reverts commit efe8089b08.

* fix poor 1000ms wait UX

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)

* trigger CI

* Add Rust side artifacts for startSketchOn face or plane (#4834)

* Add Rust side artifacts for startSketchOn face or plane

* move ast digging

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>

* lint

* lint

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-macos-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* trigger CI

* chore: disabled file watcher which prevents faster file write (#4835)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* partial fixes

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* Fix up all the tests

* Fix partial execution

* wip

* WIP

* wip

* rust changes to make three point confrom to same as others since we're not ready with name params yet

* most of the fix for 3 point circle

* get overlays working for circle three point

* fmt

* fix types

* cargo fmt

* add face codef ref for walls and caps

* fix sketch on face after updates to rust side artifact graph

* some things needed for multi-profile tests

* bad attempts at fixing rust

* more

* more

* fix rust

* more rust fixes

* overlay fix

* remove duplicate test

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* lint and typing

* maybe fix a unit test

* small thing

* WIP: Add Delete right click menu item to Feature Tree
Copying code around
Fixes #5090

* I don't know why it works

* WIP

* fix circ dep

* fix unit test

* fix some tests

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Working deletion machine loo

* Working helix deletion

* Extend deletion to more things

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* fix sweep point-and-click test

* fix more tests and add a fix me

* fix more tests

* fix electron specific test

* tsc

* more test tweaks

* update docs

* commint snaps?

* is clippy happy now?

* clippy again

* test works now without me changing anything big-fixed-itself

* small bug

* make three point have cross hair to make it consistent with othe rtools

* fix up state diagram

* fmt

* add draft point for first click of three point circ

* 1 test for three point circle

* 2 test for three point circle

* clean up

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* remove bad doc comment

* remove test skip

* remove onboarding test changes

* Update src/lang/modifyAst.ts

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* Update output from simulation tests

* Fix to use correct source ranges

This also reduces cloning.

* Change back to skipping face cap none and both

* Update output after changing back to skipping none and both

* Fix clippy warning

* fix profile start snap bug

* WIP: migrate to actor

* add path ids to cap

* fix going into edit sketch

* make other startSketchOn's work

* fix snapshot test

* explain function name

* Update src/lib/rectangleTool.ts

Co-authored-by: Frank Noirot <frank@zoo.dev>

* rename error

* remove file tree from diff

* Update src/clientSideScene/segments.ts

Co-authored-by: Frank Noirot <frank@zoo.dev>

* nit

* Continue actor migration

* Prevent double write to KCL code on revolve

* Clean up

* Update output after adding cap-to-path graph edge

* Clean up

* Update machine diag

* Update context menu hotkey class

* Fix edit/select sketch-on-cap via feature tree

* clean up for face codeRef

* fix changing tools part way through circle/rect tools

* fix delete of circle profile

* fix close profiles

* fix closing profile bug (tangentArcTo being ignored)

* remove stale comment

* Delete paths associated with sketch when the sketch plane is deleted

* Add support for deleting sketches on caps (not walls)

* get delet working for walls

* make delet of extrusions work for multi profile

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Delete the sketch statement too on the cap and wall cases

* Don't write to file in `split-sketch-pipe-if-needed` unless necessary

* Don't wait for file write to complete within `updateEditorWithAstAndWriteToFile`
It is already debounced internally. If we await it, we will have to wait for a debounced timeout

* Fix bad conflict resolution

* Fix a few things post merge

* Add guard back, fixing tests

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Add e2e test

* WIP: Add Set apperance right click menu item to Feature Tree
Fixes #5372

* Working cheap implementation

* Unset appearance via Default option

* More colors

* Add basic test

* Add test

* Lint

* 🔪 them timers

* Increase color matching threshold on appearance test

* Fix colors in e2e

* Move Set apperance down in the menu

* Revert "Move Set apperance down in the menu"

This reverts commit eb1d2e2c1c.

* Attempt at fixing dual extrude for role option search in test

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
Co-authored-by: 49lf <ircsurfer33@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
This commit is contained in:
Pierre Jacquier
2025-02-22 08:09:54 -05:00
committed by GitHub
parent 3ddce116e5
commit f2a6492ab7
12 changed files with 444 additions and 8 deletions

View File

@ -219,7 +219,11 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
} }
) )
test('Can extrude from the command bar', async ({ page, homePage }) => { test('Can extrude from the command bar', async ({
page,
homePage,
cmdBar,
}) => {
await page.addInitScript(async () => { await page.addInitScript(async () => {
localStorage.setItem( localStorage.setItem(
'persistCode', 'persistCode',
@ -254,7 +258,7 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
await expect(cmdSearchBar).toBeVisible() await expect(cmdSearchBar).toBeVisible()
// Search for extrude command and choose it // Search for extrude command and choose it
await page.getByRole('option', { name: 'Extrude' }).click() await cmdBar.cmdOptions.getByText('Extrude').click()
// Assert that we're on the selection step // Assert that we're on the selection step
await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled() await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled()

View File

@ -2796,4 +2796,107 @@ radius = 8.69
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy() expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
}) })
}) })
test(`Set appearance`, async ({
context,
page,
homePage,
scene,
editor,
toolbar,
cmdBar,
}) => {
const initialCode = `sketch001 = startSketchOn('XZ')
profile001 = circle({
center = [0, 0],
radius = 100
}, sketch001)
extrude001 = extrude(profile001, length = 100)
`
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
// One dumb hardcoded screen pixel value
const testPoint = { x: 500, y: 250 }
const initialColor: [number, number, number] = [135, 135, 135]
await test.step(`Confirm extrude exists with default appearance`, async () => {
await toolbar.closePane('code')
await scene.expectPixelColor(initialColor, testPoint, 15)
})
async function setApperanceAndCheck(
option: string,
hex: string,
shapeColor: [number, number, number]
) {
await toolbar.openPane('feature-tree')
const operationButton = await toolbar.getFeatureTreeOperation(
'Extrude',
0
)
await operationButton.click({ button: 'right' })
const menuButton = page.getByTestId('context-menu-set-appearance')
await menuButton.click()
await cmdBar.expectState({
commandName: 'Appearance',
currentArgKey: 'color',
currentArgValue: '',
headerArguments: {
Color: '',
},
highlightedHeaderArg: 'color',
stage: 'arguments',
})
const item = page.getByText(option, { exact: true })
await item.click()
await cmdBar.expectState({
commandName: 'Appearance',
headerArguments: {
Color: hex,
},
stage: 'review',
})
await cmdBar.progressCmdBar()
await toolbar.closePane('feature-tree')
await scene.expectPixelColor(shapeColor, testPoint, 40)
await toolbar.openPane('code')
if (hex === 'default') {
const anyAppearanceDeclaration = `|> appearance(`
await editor.expectEditor.not.toContain(anyAppearanceDeclaration)
} else {
const declaration = `|> appearance(%, color = '${hex}')`
await editor.expectEditor.toContain(declaration)
// TODO: fix selection range after appearance update
// await editor.expectState({
// diagnostics: [],
// activeLines: [declaration],
// highlightedCode: '',
// })
}
await toolbar.closePane('code')
}
await test.step(`Go through the Set Appearance flow for all options`, async () => {
await setApperanceAndCheck('Red', '#FF0000', [180, 0, 0])
await setApperanceAndCheck('Green', '#00FF00', [0, 180, 0])
await setApperanceAndCheck('Blue', '#0000FF', [0, 0, 180])
await setApperanceAndCheck('Turquoise', '#00FFFF', [0, 180, 180])
await setApperanceAndCheck('Purple', '#FF00FF', [180, 0, 180])
await setApperanceAndCheck('Yellow', '#FFFF00', [180, 180, 0])
await setApperanceAndCheck('Black', '#000000', [0, 0, 0])
await setApperanceAndCheck('Dark Grey', '#080808', [10, 10, 10])
await setApperanceAndCheck('Light Grey', '#D3D3D3', [190, 190, 190])
await setApperanceAndCheck('White', '#FFFFFF', [200, 200, 200])
await setApperanceAndCheck(
'Default (clear appearance)',
'default',
initialColor
)
})
})
}) })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -324,6 +324,18 @@ const OperationItem = (props: {
} }
} }
function enterAppearanceFlow() {
if (props.item.type === 'StdLibCall') {
props.send({
type: 'enterAppearanceFlow',
data: {
targetSourceRange: sourceRangeFromRust(props.item.sourceRange),
currentOperation: props.item,
},
})
}
}
function deleteOperation() { function deleteOperation() {
if ( if (
props.item.type === 'StdLibCall' || props.item.type === 'StdLibCall' ||
@ -380,6 +392,13 @@ const OperationItem = (props: {
: []), : []),
...(props.item.type === 'StdLibCall' ...(props.item.type === 'StdLibCall'
? [ ? [
<ContextMenuItem
disabled={!stdLibMap[props.item.name]?.supportsAppearance}
onClick={enterAppearanceFlow}
data-testid="context-menu-set-appearance"
>
Set appearance
</ContextMenuItem>,
<ContextMenuItem <ContextMenuItem
disabled={!stdLibMap[props.item.name]?.prepareToEdit} disabled={!stdLibMap[props.item.name]?.prepareToEdit}
onClick={enterEditFlow} onClick={enterEditFlow}

View File

@ -397,10 +397,10 @@ export function getEdgeTagCall(
return tagCall return tagCall
} }
function locateExtrudeDeclarator( export function locateExtrudeDeclarator(
node: Program, node: Program,
pathToExtrudeNode: PathToNode pathToExtrudeNode: PathToNode
): { extrudeDeclarator: VariableDeclarator } | Error { ): { extrudeDeclarator: VariableDeclarator; shallowPath: PathToNode } | Error {
const nodeOfExtrudeCall = getNodeFromPath<VariableDeclaration>( const nodeOfExtrudeCall = getNodeFromPath<VariableDeclaration>(
node, node,
pathToExtrudeNode, pathToExtrudeNode,
@ -427,7 +427,7 @@ function locateExtrudeDeclarator(
return new Error('Extrude must be a PipeExpression or CallExpression') return new Error('Extrude must be a PipeExpression or CallExpression')
} }
return { extrudeDeclarator } return { extrudeDeclarator, shallowPath: nodeOfExtrudeCall.shallowPath }
} }
function getPathToNodeOfEdgeTreatmentLiteral( function getPathToNodeOfEdgeTreatmentLiteral(

View File

@ -0,0 +1,70 @@
import { PathToNode, Program } from 'lang/wasm'
import { Node } from 'wasm-lib/kcl/bindings/Node'
import { locateExtrudeDeclarator } from './addEdgeTreatment'
import { err } from 'lib/trap'
import {
createCallExpressionStdLibKw,
createLabeledArg,
createLiteral,
createPipeExpression,
} from 'lang/modifyAst'
import { createPipeSubstitution } from 'lang/modifyAst'
import { COMMAND_APPEARANCE_COLOR_DEFAULT } from 'lib/commandBarConfigs/modelingCommandConfig'
export function setAppearance({
ast,
nodeToEdit,
color,
}: {
ast: Node<Program>
nodeToEdit: PathToNode
color: string
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
const modifiedAst = structuredClone(ast)
// Locate the call (not necessarily an extrude here)
const result = locateExtrudeDeclarator(modifiedAst, nodeToEdit)
if (err(result)) {
return result
}
const declarator = result.extrudeDeclarator
const call = createCallExpressionStdLibKw(
'appearance',
createPipeSubstitution(),
[createLabeledArg('color', createLiteral(color))]
)
// Modify the expression
if (
declarator.init.type === 'CallExpression' ||
declarator.init.type === 'CallExpressionKw'
) {
// 1. case when no appearance exists, mutate in place
declarator.init = createPipeExpression([declarator.init, call])
} else if (declarator.init.type === 'PipeExpression') {
// 2. case when appearance exists or extrude in sketch pipe
const existingIndex = declarator.init.body.findIndex(
(v) =>
v.type === 'CallExpressionKw' &&
v.callee.type === 'Identifier' &&
v.callee.name === 'appearance'
)
if (existingIndex > -1) {
if (color === COMMAND_APPEARANCE_COLOR_DEFAULT) {
// Special case of unsetting the appearance aka deleting the node
declarator.init.body.splice(existingIndex, 1)
} else {
declarator.init.body[existingIndex] = call
}
} else {
declarator.init.body.push(call)
}
} else {
return new Error('Unsupported operation type.')
}
return {
modifiedAst,
pathToNode: result.shallowPath,
}
}

View File

@ -3,7 +3,11 @@ import { angleLengthInfo } from 'components/Toolbar/setAngleLength'
import { transformAstSketchLines } from 'lang/std/sketchcombos' import { transformAstSketchLines } from 'lang/std/sketchcombos'
import { PathToNode } from 'lang/wasm' import { PathToNode } from 'lang/wasm'
import { StateMachineCommandSetConfig, KclCommandValue } from 'lib/commandTypes' import { StateMachineCommandSetConfig, KclCommandValue } from 'lib/commandTypes'
import { KCL_DEFAULT_LENGTH, KCL_DEFAULT_DEGREE } from 'lib/constants' import {
KCL_DEFAULT_LENGTH,
KCL_DEFAULT_DEGREE,
KCL_DEFAULT_COLOR,
} from 'lib/constants'
import { components } from 'lib/machine-api' import { components } from 'lib/machine-api'
import { Selections } from 'lib/selections' import { Selections } from 'lib/selections'
import { kclManager } from 'lib/singletons' import { kclManager } from 'lib/singletons'
@ -28,6 +32,8 @@ export const EXTRUSION_RESULTS = [
'intersect', 'intersect',
] as const ] as const
export const COMMAND_APPEARANCE_COLOR_DEFAULT = 'default'
export type ModelingCommandSchema = { export type ModelingCommandSchema = {
'Enter sketch': {} 'Enter sketch': {}
Export: { Export: {
@ -107,6 +113,10 @@ export type ModelingCommandSchema = {
selection: Selections selection: Selections
} }
'Delete selection': {} 'Delete selection': {}
Appearance: {
nodeToEdit?: PathToNode
color: string
}
} }
export const modelingMachineCommandConfig: StateMachineCommandSetConfig< export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
@ -664,4 +674,40 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
}, },
}, },
}, },
Appearance: {
description:
'Set the appearance of a solid. This only works on solids, not sketches or individual paths.',
icon: 'extrude',
needsReview: true,
args: {
nodeToEdit: {
description:
'Path to the node in the AST to edit. Never shown to the user.',
skip: true,
inputType: 'text',
required: false,
},
color: {
inputType: 'options',
required: true,
options: [
{ name: 'Red', value: '#FF0000' },
{ name: 'Green', value: '#00FF00' },
{ name: 'Blue', value: '#0000FF' },
{ name: 'Turquoise', value: '#00FFFF' },
{ name: 'Purple', value: '#FF00FF' },
{ name: 'Yellow', value: '#FFFF00' },
{ name: 'Black', value: '#000000' },
{ name: 'Dark Grey', value: '#080808' },
{ name: 'Light Grey', value: '#D3D3D3' },
{ name: 'White', value: '#FFFFFF' },
{
name: 'Default (clear appearance)',
value: COMMAND_APPEARANCE_COLOR_DEFAULT,
},
],
},
// Add more fields
},
},
} }

View File

@ -66,6 +66,9 @@ export const KCL_DEFAULT_LENGTH = `5`
/** The default KCL degree expression */ /** The default KCL degree expression */
export const KCL_DEFAULT_DEGREE = `360` export const KCL_DEFAULT_DEGREE = `360`
/** The default KCL color expression */
export const KCL_DEFAULT_COLOR = `#3c73ff`
/** localStorage key for the playwright test-specific app settings file */ /** localStorage key for the playwright test-specific app settings file */
export const TEST_SETTINGS_FILE_KEY = 'playwright-test-settings' export const TEST_SETTINGS_FILE_KEY = 'playwright-test-settings'

View File

@ -33,6 +33,7 @@ interface StdLibCallInfo {
| ExecuteCommandEventPayload | ExecuteCommandEventPayload
| PrepareToEditCallback | PrepareToEditCallback
| PrepareToEditFailurePayload | PrepareToEditFailurePayload
supportsAppearance?: boolean
} }
/** /**
@ -204,6 +205,7 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
label: 'Extrude', label: 'Extrude',
icon: 'extrude', icon: 'extrude',
prepareToEdit: prepareToEditExtrude, prepareToEdit: prepareToEditExtrude,
supportsAppearance: true,
}, },
fillet: { fillet: {
label: 'Fillet', label: 'Fillet',
@ -228,6 +230,7 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
loft: { loft: {
label: 'Loft', label: 'Loft',
icon: 'loft', icon: 'loft',
supportsAppearance: true,
}, },
offsetPlane: { offsetPlane: {
label: 'Offset Plane', label: 'Offset Plane',
@ -253,10 +256,12 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
revolve: { revolve: {
label: 'Revolve', label: 'Revolve',
icon: 'revolve', icon: 'revolve',
supportsAppearance: true,
}, },
shell: { shell: {
label: 'Shell', label: 'Shell',
icon: 'shell', icon: 'shell',
supportsAppearance: true,
}, },
startSketchOn: { startSketchOn: {
label: 'Sketch', label: 'Sketch',
@ -280,6 +285,7 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
sweep: { sweep: {
label: 'Sweep', label: 'Sweep',
icon: 'sweep', icon: 'sweep',
supportsAppearance: true,
}, },
} }
@ -432,3 +438,37 @@ export async function enterEditFlow({
'Feature tree editing not yet supported for this operation. Please edit in the code editor.' 'Feature tree editing not yet supported for this operation. Please edit in the code editor.'
) )
} }
export async function enterAppearanceFlow({
operation,
artifact,
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
if (operation.type !== 'StdLibCall') {
return new Error(
'Appearance setting not yet supported for user-defined functions. Please edit in the code editor.'
)
}
const stdLibInfo = stdLibMap[operation.name]
if (stdLibInfo && stdLibInfo.supportsAppearance) {
const argDefaultValues = {
nodeToEdit: getNodePathFromSourceRange(
kclManager.ast,
sourceRangeFromRust(operation.sourceRange)
),
}
console.log('argDefaultValues', argDefaultValues)
return {
type: 'Find and select command',
data: {
name: 'Appearance',
groupId: 'modeling',
argDefaultValues,
},
}
}
return new Error(
'Appearance setting not yet supported for this operation. Please edit in the code editor.'
)
}

File diff suppressed because one or more lines are too long

View File

@ -88,6 +88,7 @@ import {
import { getPathsFromPlaneArtifact } from 'lang/std/artifactGraph' import { getPathsFromPlaneArtifact } from 'lang/std/artifactGraph'
import { createProfileStartHandle } from 'clientSideScene/segments' import { createProfileStartHandle } from 'clientSideScene/segments'
import { DRAFT_POINT } from 'clientSideScene/sceneInfra' import { DRAFT_POINT } from 'clientSideScene/sceneInfra'
import { setAppearance } from 'lang/modifyAst/setAppearance'
export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY' export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY'
@ -314,6 +315,7 @@ export type ModelingMachineEvent =
type: 'Delete selection' type: 'Delete selection'
data: ModelingCommandSchema['Delete selection'] data: ModelingCommandSchema['Delete selection']
} }
| { type: 'Appearance'; data: ModelingCommandSchema['Appearance'] }
| { | {
type: 'Add rectangle origin' type: 'Add rectangle origin'
data: [x: number, y: number] data: [x: number, y: number]
@ -2172,6 +2174,47 @@ export const modelingMachine = setup({
}) })
} }
), ),
appearanceAstMod: fromPromise(
async ({
input,
}: {
input: ModelingCommandSchema['Appearance'] | undefined
}) => {
if (!input) return new Error('No input provided')
// Extract inputs
const ast = kclManager.ast
const { color, nodeToEdit } = input
if (!(nodeToEdit && typeof nodeToEdit[1][0] === 'number')) {
return new Error('Appearance is only an edit flow')
}
const result = setAppearance({
ast,
nodeToEdit,
color,
})
if (err(result)) {
return err(result)
}
const updateAstResult = await kclManager.updateAst(
result.modifiedAst,
true,
{
focusPath: [result.pathToNode],
}
)
await codeManager.updateEditorWithAstAndWriteToFile(
updateAstResult.newAst
)
if (updateAstResult?.selections) {
editorManager.selectRange(updateAstResult?.selections)
}
}
),
}, },
// end actors // end actors
}).createMachine({ }).createMachine({
@ -2267,6 +2310,11 @@ export const modelingMachine = setup({
}, },
'Prompt-to-edit': 'Applying Prompt-to-edit', 'Prompt-to-edit': 'Applying Prompt-to-edit',
Appearance: {
target: 'Applying appearance',
reenter: true,
},
}, },
entry: 'reset client scene mouse handlers', entry: 'reset client scene mouse handlers',
@ -3389,6 +3437,19 @@ export const modelingMachine = setup({
}, },
}, },
}, },
'Applying appearance': {
invoke: {
src: 'appearanceAstMod',
id: 'appearanceAstMod',
input: ({ event }) => {
if (event.type !== 'Appearance') return undefined
return event.data
},
onDone: ['idle'],
onError: ['idle'],
},
},
}, },
initial: 'idle', initial: 'idle',