More consistent error handling in modelingMachine codemods (#6910)
* First pass at consistency in modelingMachine codemods
* Add 'no kcl errors' guard instead of if check for all the existing ones
* Add more commands and improve consistency
* Add comments
* Fix test with old kcl that was showcasing the very behavior we're trying to fix
https://kittycadworkspace.slack.com/archives/C07A80B83FS/p1747231832870739?thread_ts=1747231178.515289&cid=C07A80B83FS
* Add test for sketch and helix
* Remove guard use and move hasErrors check closer to updateAst calls
* Revert "Remove guard use and move hasErrors check closer to updateAst calls"
This reverts commit 868ea4b605
.
* Remove toasts from guards
* Remove some scene.settled calls
* Lint
* More shaky fixes
* Clean up and more test fixes
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
This commit is contained in:
@ -134,8 +134,6 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
await expect(codePaneButtonHolder).toContainText('notification', {
|
await expect(codePaneButtonHolder).toContainText('notification', {
|
||||||
@ -183,7 +181,7 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await scene.settled(cmdBar)
|
// await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
|
@ -1533,7 +1533,6 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await scene.expectPixelColor(
|
await scene.expectPixelColor(
|
||||||
TEST_COLORS.DARK_MODE_BKGD,
|
TEST_COLORS.DARK_MODE_BKGD,
|
||||||
|
@ -4943,4 +4943,34 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test(`Point and click codemods can't run on KCL errors`, async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const badCode = `sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
||||||
|
extrude001 = extrude(profile001 length = 1)`
|
||||||
|
await context.addInitScript((initialCode) => {
|
||||||
|
localStorage.setItem('persistCode', initialCode)
|
||||||
|
}, badCode)
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
|
await test.step(`Start Sketch is disabled`, async () => {
|
||||||
|
await expect(toolbar.startSketchBtn).not.toBeEnabled()
|
||||||
|
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Helix is disabled`, async () => {
|
||||||
|
await expect(toolbar.helixButton).not.toBeEnabled()
|
||||||
|
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -19,11 +19,12 @@ test.describe('Regression tests', () => {
|
|||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
// because the model has `line([0,0]..` it is valid code, but the model is invalid
|
// because the model has `line([0,0]..` it is valid code, but the model is invalid
|
||||||
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
|
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
|
||||||
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
|
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
|
||||||
const u = await getUtils(page)
|
// const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
@ -40,7 +41,8 @@ test.describe('Regression tests', () => {
|
|||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await scene.connectionEstablished()
|
||||||
|
// await u.waitForPageLoad()
|
||||||
|
|
||||||
// error in guter
|
// error in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
@ -188,8 +190,8 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
page.locator('.pretty-json-container >> text=myVar:"67')
|
page.locator('.pretty-json-container >> text=myVar:"67')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
test('ProgramMemory can be serialised', async ({ page, homePage }) => {
|
test('ProgramMemory can be serialised', async ({ page, homePage, scene }) => {
|
||||||
const u = await getUtils(page)
|
// const u = await getUtils(page)
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
@ -214,11 +216,12 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
// Listen for all console events and push the message text to an array
|
// Listen for all console events and push the message text to an array
|
||||||
page.on('console', (message) => messages.push(message.text()))
|
page.on('console', (message) => messages.push(message.text()))
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
// await u.waitForPageLoad()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// wait for execution done
|
// wait for execution done
|
||||||
await u.openDebugPanel()
|
// await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
// await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
const forbiddenMessages = ['cannot serialize tagged newtype variant']
|
const forbiddenMessages = ['cannot serialize tagged newtype variant']
|
||||||
forbiddenMessages.forEach((forbiddenMessage) => {
|
forbiddenMessages.forEach((forbiddenMessage) => {
|
||||||
@ -232,6 +235,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -250,11 +254,10 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
await expect(async () => {
|
await expect(async () => {
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
|
|
||||||
// error in guter
|
// error in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||||
timeout: 1_000,
|
timeout: 1_000,
|
||||||
|
@ -1365,18 +1365,18 @@ solid001 = subtract([extrude001], tools = [extrude002])
|
|||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
`fn in2mm = (inches) => {
|
`fn in2mm(@inches) {
|
||||||
return inches * 25.4
|
return inches * 25.4
|
||||||
}
|
}
|
||||||
|
|
||||||
const railTop = in2mm(.748)
|
railTop = in2mm(.748)
|
||||||
const railSide = in2mm(.024)
|
railSide = in2mm(.024)
|
||||||
const railBaseWidth = in2mm(.612)
|
railBaseWidth = in2mm(.612)
|
||||||
const railWideWidth = in2mm(.835)
|
railWideWidth = in2mm(.835)
|
||||||
const railBaseLength = in2mm(.200)
|
railBaseLength = in2mm(.200)
|
||||||
const railClampable = in2mm(.200)
|
railClampable = in2mm(.200)
|
||||||
|
|
||||||
const rail = startSketchOn(XZ)
|
rail = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-railTop / 2, railClampable + railBaseLength])
|
|> startProfile(at = [-railTop / 2, railClampable + railBaseLength])
|
||||||
|> line(endAbsolute = [
|
|> line(endAbsolute = [
|
||||||
railTop / 2,
|
railTop / 2,
|
||||||
@ -3540,7 +3540,6 @@ profile001 = startProfile(sketch001, at = [127.56, 179.02])
|
|||||||
|
|
||||||
await homePage.openProject('multi-file-sketch-test')
|
await homePage.openProject('multi-file-sketch-test')
|
||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
@ -3555,9 +3554,6 @@ profile001 = startProfile(sketch001, at = [127.56, 179.02])
|
|||||||
|
|
||||||
await toolbar.openFile('error.kcl')
|
await toolbar.openFile('error.kcl')
|
||||||
|
|
||||||
// Ensure filetree is populated
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
toolbar.featureTreePane.getByRole('button', { name: 'Sketch' })
|
toolbar.featureTreePane.getByRole('button', { name: 'Sketch' })
|
||||||
).toHaveCount(0)
|
).toHaveCount(0)
|
||||||
|
@ -158,7 +158,8 @@ export function Toolbar({
|
|||||||
const isDisabled =
|
const isDisabled =
|
||||||
disableAllButtons ||
|
disableAllButtons ||
|
||||||
!isConfiguredAvailable ||
|
!isConfiguredAvailable ||
|
||||||
maybeIconConfig.disabled?.(state) === true
|
maybeIconConfig.disabled?.(state) === true ||
|
||||||
|
kclManager.hasErrors()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...maybeIconConfig,
|
...maybeIconConfig,
|
||||||
@ -444,6 +445,15 @@ const ToolbarItemTooltip = memo(function ToolbarItemContents({
|
|||||||
contentClassName={contentClassName}
|
contentClassName={contentClassName}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
{kclManager.hasErrors() && (
|
||||||
|
<p className="text-xs p-1 text-chalkboard-70 dark:text-chalkboard-40">
|
||||||
|
<CustomIcon
|
||||||
|
name="exclamationMark"
|
||||||
|
className="w-4 h-4 inline-block mr-1 text-destroy-80 bg-destroy-10"
|
||||||
|
/>
|
||||||
|
Fix KCL errors to enable tools
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -136,8 +136,9 @@ function optionIsDisabled(option: Command): boolean {
|
|||||||
option.disabled ||
|
option.disabled ||
|
||||||
('machineActor' in option &&
|
('machineActor' in option &&
|
||||||
option.machineActor !== undefined &&
|
option.machineActor !== undefined &&
|
||||||
!getActorNextEvents(option.machineActor.getSnapshot()).includes(
|
(!getActorNextEvents(option.machineActor.getSnapshot()).includes(
|
||||||
option.name
|
option.name
|
||||||
))
|
) ||
|
||||||
|
!option.machineActor?.getSnapshot().can({ type: option.name })))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -580,24 +580,23 @@ export const ModelingMachineProvider = ({
|
|||||||
selectionRanges
|
selectionRanges
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
'Has exportable geometry': () => {
|
'Has exportable geometry': () =>
|
||||||
if (!kclManager.hasErrors() && kclManager.ast.body.length > 0)
|
!kclManager.hasErrors() && kclManager.ast.body.length > 0,
|
||||||
return true
|
|
||||||
else {
|
|
||||||
let errorMessage = 'Unable to Export '
|
|
||||||
if (kclManager.hasErrors()) errorMessage += 'due to KCL Errors'
|
|
||||||
else if (kclManager.ast.body.length === 0)
|
|
||||||
errorMessage += 'due to Empty Scene'
|
|
||||||
console.error(errorMessage)
|
|
||||||
toast.error(errorMessage)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
actors: {
|
actors: {
|
||||||
exportFromEngine: fromPromise(
|
exportFromEngine: fromPromise(
|
||||||
async ({ input }: { input?: ModelingCommandSchema['Export'] }) => {
|
async ({ input }: { input?: ModelingCommandSchema['Export'] }) => {
|
||||||
if (!input) {
|
if (kclManager.hasErrors() || kclManager.ast.body.length === 0) {
|
||||||
|
let errorMessage = 'Unable to Export '
|
||||||
|
if (kclManager.hasErrors()) {
|
||||||
|
errorMessage += 'due to KCL Errors'
|
||||||
|
} else if (kclManager.ast.body.length === 0) {
|
||||||
|
errorMessage += 'due to Empty Scene'
|
||||||
|
}
|
||||||
|
console.error(errorMessage)
|
||||||
|
toast.error(errorMessage)
|
||||||
|
return new Error(errorMessage)
|
||||||
|
} else if (!input) {
|
||||||
return new Error('No input provided')
|
return new Error('No input provided')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,6 +566,8 @@ export const modelingMachineDefaultContext: ModelingMachineContext = {
|
|||||||
planesInitialized: false,
|
planesInitialized: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NO_INPUT_PROVIDED_MESSAGE = 'No input provided'
|
||||||
|
|
||||||
export const modelingMachine = setup({
|
export const modelingMachine = setup({
|
||||||
types: {
|
types: {
|
||||||
context: {} as ModelingMachineContext,
|
context: {} as ModelingMachineContext,
|
||||||
@ -1357,6 +1359,8 @@ export const modelingMachine = setup({
|
|||||||
},
|
},
|
||||||
// end actions
|
// end actions
|
||||||
actors: {
|
actors: {
|
||||||
|
/* Below are all the do-constrain sketch actors,
|
||||||
|
* which aren't using updateModelingState and don't have the 'no kcl errors' guard yet */
|
||||||
'do-constrain-remove-constraint': fromPromise(
|
'do-constrain-remove-constraint': fromPromise(
|
||||||
async ({
|
async ({
|
||||||
input: { selectionRanges, sketchDetails, data },
|
input: { selectionRanges, sketchDetails, data },
|
||||||
@ -1694,6 +1698,9 @@ export const modelingMachine = setup({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
|
/* Below are actors being defined in src/components/ModelingMachineProvider.tsx
|
||||||
|
* which aren't using updateModelingState and don't have the 'no kcl errors' guard yet */
|
||||||
'Get vertical info': fromPromise(
|
'Get vertical info': fromPromise(
|
||||||
async (_: {
|
async (_: {
|
||||||
input: Pick<ModelingMachineContext, 'selectionRanges' | 'sketchDetails'>
|
input: Pick<ModelingMachineContext, 'selectionRanges' | 'sketchDetails'>
|
||||||
@ -1775,11 +1782,92 @@ export const modelingMachine = setup({
|
|||||||
return {} as SetSelections
|
return {} as SetSelections
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
extrudeAstMod: fromPromise<
|
'set-up-draft-circle': fromPromise(
|
||||||
unknown,
|
async (_: {
|
||||||
ModelingCommandSchema['Extrude'] | undefined
|
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
||||||
>(async ({ input }) => {
|
data: [x: number, y: number]
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
}
|
||||||
|
}) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'set-up-draft-circle-three-point': fromPromise(
|
||||||
|
async (_: {
|
||||||
|
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
||||||
|
data: { p1: [x: number, y: number]; p2: [x: number, y: number] }
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'set-up-draft-rectangle': fromPromise(
|
||||||
|
async (_: {
|
||||||
|
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
||||||
|
data: [x: number, y: number]
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'set-up-draft-center-rectangle': fromPromise(
|
||||||
|
async (_: {
|
||||||
|
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
||||||
|
data: [x: number, y: number]
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'set-up-draft-arc': fromPromise(
|
||||||
|
async (_: {
|
||||||
|
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
||||||
|
data: [x: number, y: number]
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'set-up-draft-arc-three-point': fromPromise(
|
||||||
|
async (_: {
|
||||||
|
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
||||||
|
data: [x: number, y: number]
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'setup-client-side-sketch-segments': fromPromise(
|
||||||
|
async (_: {
|
||||||
|
input: Pick<ModelingMachineContext, 'sketchDetails' | 'selectionRanges'>
|
||||||
|
}) => {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'split-sketch-pipe-if-needed': fromPromise(
|
||||||
|
async (_: { input: Pick<ModelingMachineContext, 'sketchDetails'> }) => {
|
||||||
|
return {} as SketchDetailsUpdate
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'submit-prompt-edit': fromPromise(
|
||||||
|
async ({
|
||||||
|
input,
|
||||||
|
}: {
|
||||||
|
input: ModelingCommandSchema['Prompt-to-edit']
|
||||||
|
}) => {}
|
||||||
|
),
|
||||||
|
|
||||||
|
/* Below are recent modeling codemods that are using updateModelinState,
|
||||||
|
* trigger toastError on Error, and have the 'no kcl errors' guard yet */
|
||||||
|
extrudeAstMod: fromPromise(
|
||||||
|
async ({
|
||||||
|
input,
|
||||||
|
}: {
|
||||||
|
input: ModelingCommandSchema['Extrude'] | undefined
|
||||||
|
}) => {
|
||||||
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const { nodeToEdit, sketches, length } = input
|
const { nodeToEdit, sketches, length } = input
|
||||||
const { ast } = kclManager
|
const { ast } = kclManager
|
||||||
const astResult = addExtrude({
|
const astResult = addExtrude({
|
||||||
@ -1805,12 +1893,18 @@ export const modelingMachine = setup({
|
|||||||
focusPath: [pathToNode],
|
focusPath: [pathToNode],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}),
|
}
|
||||||
sweepAstMod: fromPromise<
|
),
|
||||||
unknown,
|
sweepAstMod: fromPromise(
|
||||||
ModelingCommandSchema['Sweep'] | undefined
|
async ({
|
||||||
>(async ({ input }) => {
|
input,
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
}: {
|
||||||
|
input: ModelingCommandSchema['Sweep'] | undefined
|
||||||
|
}) => {
|
||||||
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const { nodeToEdit, sketches, path, sectional } = input
|
const { nodeToEdit, sketches, path, sectional } = input
|
||||||
const { ast } = kclManager
|
const { ast } = kclManager
|
||||||
const astResult = addSweep({
|
const astResult = addSweep({
|
||||||
@ -1837,14 +1931,18 @@ export const modelingMachine = setup({
|
|||||||
focusPath: [pathToNode],
|
focusPath: [pathToNode],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}),
|
}
|
||||||
|
),
|
||||||
loftAstMod: fromPromise(
|
loftAstMod: fromPromise(
|
||||||
async ({
|
async ({
|
||||||
input,
|
input,
|
||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Loft'] | undefined
|
input: ModelingCommandSchema['Loft'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const { sketches } = input
|
const { sketches } = input
|
||||||
const { ast } = kclManager
|
const { ast } = kclManager
|
||||||
const astResult = addLoft({ ast, sketches })
|
const astResult = addLoft({ ast, sketches })
|
||||||
@ -1867,11 +1965,16 @@ export const modelingMachine = setup({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
revolveAstMod: fromPromise<
|
revolveAstMod: fromPromise(
|
||||||
unknown,
|
async ({
|
||||||
ModelingCommandSchema['Revolve'] | undefined
|
input,
|
||||||
>(async ({ input }) => {
|
}: {
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
input: ModelingCommandSchema['Revolve'] | undefined
|
||||||
|
}) => {
|
||||||
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const { nodeToEdit, sketches, angle, axis, edge, axisOrEdge } = input
|
const { nodeToEdit, sketches, angle, axis, edge, axisOrEdge } = input
|
||||||
const { ast } = kclManager
|
const { ast } = kclManager
|
||||||
const astResult = addRevolve({
|
const astResult = addRevolve({
|
||||||
@ -1900,14 +2003,18 @@ export const modelingMachine = setup({
|
|||||||
focusPath: [pathToNode],
|
focusPath: [pathToNode],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}),
|
}
|
||||||
|
),
|
||||||
offsetPlaneAstMod: fromPromise(
|
offsetPlaneAstMod: fromPromise(
|
||||||
async ({
|
async ({
|
||||||
input,
|
input,
|
||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Offset plane'] | undefined
|
input: ModelingCommandSchema['Offset plane'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return new Error('No input provided')
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
// Extract inputs
|
// Extract inputs
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const { plane: selection, distance, nodeToEdit } = input
|
const { plane: selection, distance, nodeToEdit } = input
|
||||||
@ -1989,9 +2096,10 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Helix'] | undefined
|
input: ModelingCommandSchema['Helix'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return new Error('No input provided')
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
// Extract inputs
|
// Extract inputs
|
||||||
console.log('input', input)
|
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const {
|
const {
|
||||||
mode,
|
mode,
|
||||||
@ -2043,7 +2151,7 @@ export const modelingMachine = setup({
|
|||||||
cylinder.graphSelections[0].artifact?.type === 'wall'
|
cylinder.graphSelections[0].artifact?.type === 'wall'
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return new Error('Cylinder argument not valid')
|
return Promise.reject(new Error('Cylinder argument not valid'))
|
||||||
}
|
}
|
||||||
const clonedAstForGetExtrude = structuredClone(ast)
|
const clonedAstForGetExtrude = structuredClone(ast)
|
||||||
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
||||||
@ -2052,7 +2160,7 @@ export const modelingMachine = setup({
|
|||||||
kclManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(extrudeLookupResult)) {
|
if (err(extrudeLookupResult)) {
|
||||||
return extrudeLookupResult
|
return Promise.reject(extrudeLookupResult)
|
||||||
}
|
}
|
||||||
const extrudeNode = getNodeFromPath<VariableDeclaration>(
|
const extrudeNode = getNodeFromPath<VariableDeclaration>(
|
||||||
ast,
|
ast,
|
||||||
@ -2060,19 +2168,21 @@ export const modelingMachine = setup({
|
|||||||
'VariableDeclaration'
|
'VariableDeclaration'
|
||||||
)
|
)
|
||||||
if (err(extrudeNode)) {
|
if (err(extrudeNode)) {
|
||||||
return extrudeNode
|
return Promise.reject(extrudeNode)
|
||||||
}
|
}
|
||||||
cylinderDeclarator = extrudeNode.node.declaration
|
cylinderDeclarator = extrudeNode.node.declaration
|
||||||
} else if (mode === 'Axis' || mode === 'Edge') {
|
} else if (mode === 'Axis' || mode === 'Edge') {
|
||||||
const getAxisResult = getAxisExpressionAndIndex(mode, axis, edge, ast)
|
const getAxisResult = getAxisExpressionAndIndex(mode, axis, edge, ast)
|
||||||
if (err(getAxisResult)) {
|
if (err(getAxisResult)) {
|
||||||
return getAxisResult
|
return Promise.reject(getAxisResult)
|
||||||
}
|
}
|
||||||
axisExpression = getAxisResult.generatedAxis
|
axisExpression = getAxisResult.generatedAxis
|
||||||
} else {
|
} else {
|
||||||
return new Error(
|
return Promise.reject(
|
||||||
|
new Error(
|
||||||
'Generated axis or cylinder declarator selection is missing.'
|
'Generated axis or cylinder declarator selection is missing.'
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: figure out if we want to smart insert after the sketch as below
|
// TODO: figure out if we want to smart insert after the sketch as below
|
||||||
@ -2132,7 +2242,7 @@ export const modelingMachine = setup({
|
|||||||
input: ModelingCommandSchema['Shell'] | undefined
|
input: ModelingCommandSchema['Shell'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return new Error('No input provided')
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract inputs
|
// Extract inputs
|
||||||
@ -2173,10 +2283,12 @@ export const modelingMachine = setup({
|
|||||||
kclManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
)
|
)
|
||||||
if (err(extrudeLookupResult)) {
|
if (err(extrudeLookupResult)) {
|
||||||
return new Error(
|
return Promise.reject(
|
||||||
|
new Error(
|
||||||
"Couldn't find extrude paths from getPathToExtrudeForSegmentSelection",
|
"Couldn't find extrude paths from getPathToExtrudeForSegmentSelection",
|
||||||
{ cause: extrudeLookupResult }
|
{ cause: extrudeLookupResult }
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const extrudeNode = getNodeFromPath<VariableDeclaration>(
|
const extrudeNode = getNodeFromPath<VariableDeclaration>(
|
||||||
@ -2196,9 +2308,11 @@ export const modelingMachine = setup({
|
|||||||
'VariableDeclaration'
|
'VariableDeclaration'
|
||||||
)
|
)
|
||||||
if (err(segmentNode)) {
|
if (err(segmentNode)) {
|
||||||
return new Error("Couldn't find segment node from selection", {
|
return Promise.reject(
|
||||||
|
new Error("Couldn't find segment node from selection", {
|
||||||
cause: segmentNode,
|
cause: segmentNode,
|
||||||
})
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extrudeNode.node.declaration.init.type === 'CallExpressionKw') {
|
if (extrudeNode.node.declaration.init.type === 'CallExpressionKw') {
|
||||||
@ -2208,15 +2322,17 @@ export const modelingMachine = setup({
|
|||||||
) {
|
) {
|
||||||
pathToExtrudeNode = extrudeLookupResult.pathToSegmentNode
|
pathToExtrudeNode = extrudeLookupResult.pathToSegmentNode
|
||||||
} else {
|
} else {
|
||||||
return new Error(
|
return Promise.reject(
|
||||||
|
new Error(
|
||||||
"Couldn't find extrude node that was either a call expression or a pipe",
|
"Couldn't find extrude node that was either a call expression or a pipe",
|
||||||
{ cause: segmentNode }
|
{ cause: segmentNode }
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedArtifact = graphSelection.artifact
|
const selectedArtifact = graphSelection.artifact
|
||||||
if (!selectedArtifact) {
|
if (!selectedArtifact) {
|
||||||
return new Error('Bad artifact from selection')
|
return Promise.reject(new Error('Bad artifact from selection'))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check on the selection, and handle the wall vs cap cases
|
// Check on the selection, and handle the wall vs cap cases
|
||||||
@ -2229,20 +2345,22 @@ export const modelingMachine = setup({
|
|||||||
extrudeLookupResult.pathToSegmentNode
|
extrudeLookupResult.pathToSegmentNode
|
||||||
)
|
)
|
||||||
if (err(tagResult)) {
|
if (err(tagResult)) {
|
||||||
return tagResult
|
return Promise.reject(tagResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tag } = tagResult
|
const { tag } = tagResult
|
||||||
expr = createLocalName(tag)
|
expr = createLocalName(tag)
|
||||||
} else {
|
} else {
|
||||||
return new Error('Artifact is neither a cap nor a wall')
|
return Promise.reject(
|
||||||
|
new Error('Artifact is neither a cap nor a wall')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
faces.push(expr)
|
faces.push(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pathToExtrudeNode) {
|
if (!pathToExtrudeNode) {
|
||||||
return new Error('No path to extrude node found')
|
return Promise.reject(new Error('No path to extrude node found'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const extrudeNode = getNodeFromPath<VariableDeclarator>(
|
const extrudeNode = getNodeFromPath<VariableDeclarator>(
|
||||||
@ -2251,9 +2369,11 @@ export const modelingMachine = setup({
|
|||||||
'VariableDeclarator'
|
'VariableDeclarator'
|
||||||
)
|
)
|
||||||
if (err(extrudeNode)) {
|
if (err(extrudeNode)) {
|
||||||
return new Error("Couldn't find extrude node", {
|
return Promise.reject(
|
||||||
|
new Error("Couldn't find extrude node", {
|
||||||
cause: extrudeNode,
|
cause: extrudeNode,
|
||||||
})
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the shell op
|
// Perform the shell op
|
||||||
@ -2308,7 +2428,7 @@ export const modelingMachine = setup({
|
|||||||
input: ModelingCommandSchema['Fillet'] | undefined
|
input: ModelingCommandSchema['Fillet'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return new Error('No input provided')
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract inputs
|
// Extract inputs
|
||||||
@ -2401,7 +2521,7 @@ export const modelingMachine = setup({
|
|||||||
input: ModelingCommandSchema['Chamfer'] | undefined
|
input: ModelingCommandSchema['Chamfer'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return Promise.reject(new Error('No input provided'))
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract inputs
|
// Extract inputs
|
||||||
@ -2492,10 +2612,13 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['event.parameter.create'] | undefined
|
input: ModelingCommandSchema['event.parameter.create'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return new Error('No input provided')
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const { value } = input
|
const { value } = input
|
||||||
if (!('variableName' in value)) {
|
if (!('variableName' in value)) {
|
||||||
return new Error('variable name is required')
|
return Promise.reject(new Error('variable name is required'))
|
||||||
}
|
}
|
||||||
const newAst = insertNamedConstant({
|
const newAst = insertNamedConstant({
|
||||||
node: kclManager.ast,
|
node: kclManager.ast,
|
||||||
@ -2514,7 +2637,10 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['event.parameter.edit'] | undefined
|
input: ModelingCommandSchema['event.parameter.edit'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return new Error('No input provided')
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
// Get the variable AST node to edit
|
// Get the variable AST node to edit
|
||||||
const { nodeToEdit, value } = input
|
const { nodeToEdit, value } = input
|
||||||
const newAst = structuredClone(kclManager.ast)
|
const newAst = structuredClone(kclManager.ast)
|
||||||
@ -2528,7 +2654,7 @@ export const modelingMachine = setup({
|
|||||||
variableNode.node.type !== 'VariableDeclarator' ||
|
variableNode.node.type !== 'VariableDeclarator' ||
|
||||||
!variableNode.node
|
!variableNode.node
|
||||||
) {
|
) {
|
||||||
return new Error('No variable found, this is a bug')
|
return Promise.reject(new Error('No variable found, this is a bug'))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutate the variable's value
|
// Mutate the variable's value
|
||||||
@ -2541,79 +2667,6 @@ export const modelingMachine = setup({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
'set-up-draft-circle': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
|
||||||
data: [x: number, y: number]
|
|
||||||
}
|
|
||||||
}) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'set-up-draft-circle-three-point': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
|
||||||
data: { p1: [x: number, y: number]; p2: [x: number, y: number] }
|
|
||||||
}
|
|
||||||
}) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'set-up-draft-rectangle': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
|
||||||
data: [x: number, y: number]
|
|
||||||
}
|
|
||||||
}) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'set-up-draft-center-rectangle': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
|
||||||
data: [x: number, y: number]
|
|
||||||
}
|
|
||||||
}) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'set-up-draft-arc': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
|
||||||
data: [x: number, y: number]
|
|
||||||
}
|
|
||||||
}) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'set-up-draft-arc-three-point': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails'> & {
|
|
||||||
data: [x: number, y: number]
|
|
||||||
}
|
|
||||||
}) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'setup-client-side-sketch-segments': fromPromise(
|
|
||||||
async (_: {
|
|
||||||
input: Pick<ModelingMachineContext, 'sketchDetails' | 'selectionRanges'>
|
|
||||||
}) => {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'split-sketch-pipe-if-needed': fromPromise(
|
|
||||||
async (_: { input: Pick<ModelingMachineContext, 'sketchDetails'> }) => {
|
|
||||||
return {} as SketchDetailsUpdate
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'submit-prompt-edit': fromPromise(
|
|
||||||
async ({
|
|
||||||
input,
|
|
||||||
}: {
|
|
||||||
input: ModelingCommandSchema['Prompt-to-edit']
|
|
||||||
}) => {}
|
|
||||||
),
|
|
||||||
deleteSelectionAstMod: fromPromise(
|
deleteSelectionAstMod: fromPromise(
|
||||||
({
|
({
|
||||||
input: { selectionRanges },
|
input: { selectionRanges },
|
||||||
@ -2648,12 +2701,15 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Appearance'] | undefined
|
input: ModelingCommandSchema['Appearance'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return new Error('No input provided')
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
// Extract inputs
|
// Extract inputs
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const { color, nodeToEdit } = input
|
const { color, nodeToEdit } = input
|
||||||
if (!(nodeToEdit && typeof nodeToEdit[1][0] === 'number')) {
|
if (!(nodeToEdit && typeof nodeToEdit[1][0] === 'number')) {
|
||||||
return new Error('Appearance is only an edit flow')
|
return Promise.reject(new Error('Appearance is only an edit flow'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = setAppearance({
|
const result = setAppearance({
|
||||||
@ -2663,7 +2719,7 @@ export const modelingMachine = setup({
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (err(result)) {
|
if (err(result)) {
|
||||||
return err(result)
|
return Promise.reject(err(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
await updateModelingState(
|
await updateModelingState(
|
||||||
@ -2686,7 +2742,10 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Translate'] | undefined
|
input: ModelingCommandSchema['Translate'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const modifiedAst = structuredClone(ast)
|
const modifiedAst = structuredClone(ast)
|
||||||
const { x, y, z, nodeToEdit, selection } = input
|
const { x, y, z, nodeToEdit, selection } = input
|
||||||
@ -2764,7 +2823,10 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Rotate'] | undefined
|
input: ModelingCommandSchema['Rotate'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const modifiedAst = structuredClone(ast)
|
const modifiedAst = structuredClone(ast)
|
||||||
const { roll, pitch, yaw, nodeToEdit, selection } = input
|
const { roll, pitch, yaw, nodeToEdit, selection } = input
|
||||||
@ -2842,7 +2904,10 @@ export const modelingMachine = setup({
|
|||||||
}: {
|
}: {
|
||||||
input: ModelingCommandSchema['Clone'] | undefined
|
input: ModelingCommandSchema['Clone'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) return Promise.reject(new Error('No input provided'))
|
if (!input) {
|
||||||
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
|
}
|
||||||
|
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const { nodeToEdit, selection, variableName } = input
|
const { nodeToEdit, selection, variableName } = input
|
||||||
let pathToNode = nodeToEdit
|
let pathToNode = nodeToEdit
|
||||||
@ -2933,15 +2998,17 @@ export const modelingMachine = setup({
|
|||||||
input: ModelingCommandSchema['Boolean Subtract'] | undefined
|
input: ModelingCommandSchema['Boolean Subtract'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return new Error('No input provided')
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
}
|
}
|
||||||
|
|
||||||
const { target, tool } = input
|
const { target, tool } = input
|
||||||
if (
|
if (
|
||||||
!target.graphSelections[0].artifact ||
|
!target.graphSelections[0].artifact ||
|
||||||
!tool.graphSelections[0].artifact
|
!tool.graphSelections[0].artifact
|
||||||
) {
|
) {
|
||||||
return new Error('No artifact in selections found')
|
return Promise.reject(new Error('No artifact in selections found'))
|
||||||
}
|
}
|
||||||
|
|
||||||
await applySubtractFromTargetOperatorSelections(
|
await applySubtractFromTargetOperatorSelections(
|
||||||
target.graphSelections[0],
|
target.graphSelections[0],
|
||||||
tool.graphSelections[0],
|
tool.graphSelections[0],
|
||||||
@ -2961,12 +3028,14 @@ export const modelingMachine = setup({
|
|||||||
input: ModelingCommandSchema['Boolean Union'] | undefined
|
input: ModelingCommandSchema['Boolean Union'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return new Error('No input provided')
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
}
|
}
|
||||||
|
|
||||||
const { solids } = input
|
const { solids } = input
|
||||||
if (!solids.graphSelections[0].artifact) {
|
if (!solids.graphSelections[0].artifact) {
|
||||||
return new Error('No artifact in selections found')
|
return Promise.reject(new Error('No artifact in selections found'))
|
||||||
}
|
}
|
||||||
|
|
||||||
await applyUnionFromTargetOperatorSelections(solids, {
|
await applyUnionFromTargetOperatorSelections(solids, {
|
||||||
kclManager,
|
kclManager,
|
||||||
codeManager,
|
codeManager,
|
||||||
@ -2982,12 +3051,14 @@ export const modelingMachine = setup({
|
|||||||
input: ModelingCommandSchema['Boolean Union'] | undefined
|
input: ModelingCommandSchema['Boolean Union'] | undefined
|
||||||
}) => {
|
}) => {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return new Error('No input provided')
|
return Promise.reject(new Error(NO_INPUT_PROVIDED_MESSAGE))
|
||||||
}
|
}
|
||||||
|
|
||||||
const { solids } = input
|
const { solids } = input
|
||||||
if (!solids.graphSelections[0].artifact) {
|
if (!solids.graphSelections[0].artifact) {
|
||||||
return new Error('No artifact in selections found')
|
return Promise.reject(new Error('No artifact in selections found'))
|
||||||
}
|
}
|
||||||
|
|
||||||
await applyIntersectFromTargetOperatorSelections(solids, {
|
await applyIntersectFromTargetOperatorSelections(solids, {
|
||||||
kclManager,
|
kclManager,
|
||||||
codeManager,
|
codeManager,
|
||||||
@ -2996,6 +3067,8 @@ export const modelingMachine = setup({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
|
/* Pierre: looks like somewhat of a one-off */
|
||||||
'reeval-node-paths': fromPromise(
|
'reeval-node-paths': fromPromise(
|
||||||
async ({
|
async ({
|
||||||
input: { sketchDetails },
|
input: { sketchDetails },
|
||||||
@ -3096,50 +3169,74 @@ export const modelingMachine = setup({
|
|||||||
target: 'animating to existing sketch',
|
target: 'animating to existing sketch',
|
||||||
guard: 'Selection is on face',
|
guard: 'Selection is on face',
|
||||||
},
|
},
|
||||||
'Sketch no face',
|
{
|
||||||
|
target: 'Sketch no face',
|
||||||
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
Extrude: {
|
Extrude: {
|
||||||
target: 'Applying extrude',
|
target: 'Applying extrude',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
},
|
guard: 'no kcl errors',
|
||||||
|
|
||||||
Revolve: {
|
|
||||||
target: 'Applying revolve',
|
|
||||||
reenter: true,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Sweep: {
|
Sweep: {
|
||||||
target: 'Applying sweep',
|
target: 'Applying sweep',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Loft: {
|
Loft: {
|
||||||
target: 'Applying loft',
|
target: 'Applying loft',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
|
|
||||||
|
Revolve: {
|
||||||
|
target: 'Applying revolve',
|
||||||
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
|
|
||||||
|
'Offset plane': {
|
||||||
|
target: 'Applying offset plane',
|
||||||
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
|
|
||||||
|
Helix: {
|
||||||
|
target: 'Applying helix',
|
||||||
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Shell: {
|
Shell: {
|
||||||
target: 'Applying shell',
|
target: 'Applying shell',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Fillet: {
|
Fillet: {
|
||||||
target: 'Applying fillet',
|
target: 'Applying fillet',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Chamfer: {
|
Chamfer: {
|
||||||
target: 'Applying chamfer',
|
target: 'Applying chamfer',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
'event.parameter.create': {
|
'event.parameter.create': {
|
||||||
target: '#Modeling.parameter.creating',
|
target: '#Modeling.parameter.creating',
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
'event.parameter.edit': {
|
'event.parameter.edit': {
|
||||||
target: '#Modeling.parameter.editing',
|
target: '#Modeling.parameter.editing',
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Export: {
|
Export: {
|
||||||
@ -3164,41 +3261,44 @@ export const modelingMachine = setup({
|
|||||||
actions: ['Submit to Text-to-CAD API'],
|
actions: ['Submit to Text-to-CAD API'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'Offset plane': {
|
|
||||||
target: 'Applying offset plane',
|
|
||||||
reenter: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
Helix: {
|
|
||||||
target: 'Applying helix',
|
|
||||||
reenter: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
'Prompt-to-edit': 'Applying Prompt-to-edit',
|
'Prompt-to-edit': 'Applying Prompt-to-edit',
|
||||||
|
|
||||||
Appearance: {
|
Appearance: {
|
||||||
target: 'Applying appearance',
|
target: 'Applying appearance',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Translate: {
|
Translate: {
|
||||||
target: 'Applying translate',
|
target: 'Applying translate',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Rotate: {
|
Rotate: {
|
||||||
target: 'Applying rotate',
|
target: 'Applying rotate',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
Clone: {
|
Clone: {
|
||||||
target: 'Applying clone',
|
target: 'Applying clone',
|
||||||
reenter: true,
|
reenter: true,
|
||||||
|
guard: 'no kcl errors',
|
||||||
},
|
},
|
||||||
|
|
||||||
'Boolean Subtract': 'Boolean subtracting',
|
'Boolean Subtract': {
|
||||||
'Boolean Union': 'Boolean uniting',
|
target: 'Boolean subtracting',
|
||||||
'Boolean Intersect': 'Boolean intersecting',
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
|
'Boolean Union': {
|
||||||
|
target: 'Boolean uniting',
|
||||||
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
|
'Boolean Intersect': {
|
||||||
|
target: 'Boolean intersecting',
|
||||||
|
guard: 'no kcl errors',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
entry: 'reset client scene mouse handlers',
|
entry: 'reset client scene mouse handlers',
|
||||||
@ -4415,6 +4515,38 @@ export const modelingMachine = setup({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'Applying sweep': {
|
||||||
|
invoke: {
|
||||||
|
src: 'sweepAstMod',
|
||||||
|
id: 'sweepAstMod',
|
||||||
|
input: ({ event }) => {
|
||||||
|
if (event.type !== 'Sweep') return undefined
|
||||||
|
return event.data
|
||||||
|
},
|
||||||
|
onDone: ['idle'],
|
||||||
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'Applying loft': {
|
||||||
|
invoke: {
|
||||||
|
src: 'loftAstMod',
|
||||||
|
id: 'loftAstMod',
|
||||||
|
input: ({ event }) => {
|
||||||
|
if (event.type !== 'Loft') return undefined
|
||||||
|
return event.data
|
||||||
|
},
|
||||||
|
onDone: ['idle'],
|
||||||
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
'Applying revolve': {
|
'Applying revolve': {
|
||||||
invoke: {
|
invoke: {
|
||||||
src: 'revolveAstMod',
|
src: 'revolveAstMod',
|
||||||
@ -4440,7 +4572,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4453,34 +4588,11 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'Applying sweep': {
|
|
||||||
invoke: {
|
|
||||||
src: 'sweepAstMod',
|
|
||||||
id: 'sweepAstMod',
|
|
||||||
input: ({ event }) => {
|
|
||||||
if (event.type !== 'Sweep') return undefined
|
|
||||||
return event.data
|
|
||||||
},
|
|
||||||
onDone: ['idle'],
|
|
||||||
onError: ['idle'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
'Applying loft': {
|
|
||||||
invoke: {
|
|
||||||
src: 'loftAstMod',
|
|
||||||
id: 'loftAstMod',
|
|
||||||
input: ({ event }) => {
|
|
||||||
if (event.type !== 'Loft') return undefined
|
|
||||||
return event.data
|
|
||||||
},
|
|
||||||
onDone: ['idle'],
|
|
||||||
onError: ['idle'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'Applying shell': {
|
'Applying shell': {
|
||||||
@ -4492,7 +4604,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4505,7 +4620,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4518,7 +4636,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4535,7 +4656,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['#Modeling.idle'],
|
onDone: ['#Modeling.idle'],
|
||||||
onError: ['#Modeling.idle'],
|
onError: {
|
||||||
|
target: '#Modeling.idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
editing: {
|
editing: {
|
||||||
@ -4547,7 +4671,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['#Modeling.idle'],
|
onDone: ['#Modeling.idle'],
|
||||||
onError: ['#Modeling.idle'],
|
onError: {
|
||||||
|
target: '#Modeling.idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4604,7 +4731,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4617,7 +4747,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4630,7 +4763,10 @@ export const modelingMachine = setup({
|
|||||||
return event.data
|
return event.data
|
||||||
},
|
},
|
||||||
onDone: ['idle'],
|
onDone: ['idle'],
|
||||||
onError: ['idle'],
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4686,7 +4822,10 @@ export const modelingMachine = setup({
|
|||||||
input: ({ event }) =>
|
input: ({ event }) =>
|
||||||
event.type !== 'Boolean Subtract' ? undefined : event.data,
|
event.type !== 'Boolean Subtract' ? undefined : event.data,
|
||||||
onDone: 'idle',
|
onDone: 'idle',
|
||||||
onError: 'idle',
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4697,7 +4836,10 @@ export const modelingMachine = setup({
|
|||||||
input: ({ event }) =>
|
input: ({ event }) =>
|
||||||
event.type !== 'Boolean Union' ? undefined : event.data,
|
event.type !== 'Boolean Union' ? undefined : event.data,
|
||||||
onDone: 'idle',
|
onDone: 'idle',
|
||||||
onError: 'idle',
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4708,7 +4850,10 @@ export const modelingMachine = setup({
|
|||||||
input: ({ event }) =>
|
input: ({ event }) =>
|
||||||
event.type !== 'Boolean Intersect' ? undefined : event.data,
|
event.type !== 'Boolean Intersect' ? undefined : event.data,
|
||||||
onDone: 'idle',
|
onDone: 'idle',
|
||||||
onError: 'idle',
|
onError: {
|
||||||
|
target: 'idle',
|
||||||
|
actions: 'toastError',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user