diff --git a/e2e/playwright/point-click.spec.ts b/e2e/playwright/point-click.spec.ts index 585519daf..6ddb372a3 100644 --- a/e2e/playwright/point-click.spec.ts +++ b/e2e/playwright/point-click.spec.ts @@ -776,7 +776,6 @@ const shellPointAndClickCapCases = [ shellPointAndClickCapCases.forEach(({ shouldPreselect }) => { test(`Shell point-and-click cap (preselected sketches: ${shouldPreselect})`, async ({ app, - page, scene, editor, toolbar, @@ -877,7 +876,7 @@ extrude001 = extrude(40, sketch001) // One dumb hardcoded screen pixel value const testPoint = { x: 580, y: 250 } - const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y) + const [clickOnWall] = scene.makeMouseHelpers(testPoint.x, testPoint.y) const mutatedCode = 'xLine(-40, %, $seg01)' const shellDeclaration = 'shell001 = shell({ faces = [seg01], thickness = 5 }, extrude001)' @@ -899,7 +898,7 @@ extrude001 = extrude(40, sketch001) highlightedHeaderArg: 'selection', commandName: 'Shell', }) - await clickOnCap() + await clickOnWall() await cmdBar.progressCmdBar() await cmdBar.expectState({ stage: 'review', diff --git a/src/components/ModelingMachineProvider.tsx b/src/components/ModelingMachineProvider.tsx index f41eb101f..4af48cf14 100644 --- a/src/components/ModelingMachineProvider.tsx +++ b/src/components/ModelingMachineProvider.tsx @@ -70,6 +70,7 @@ import { } from 'lang/modifyAst' import { Program, parse, recast } from 'lang/wasm' import { + doesSceneHaveExtrudedSketch, doesSceneHaveSweepableSketch, getNodePathFromSourceRange, isSingleCursorInPipe, @@ -586,18 +587,21 @@ export const ModelingMachineProvider = ({ if (err(canLoft)) return false return canLoft }, - 'has valid shell selection': ({ context: { selectionRanges } }) => { + 'has valid shell selection': ({ + context: { selectionRanges }, + event, + }) => { const hasNoSelection = selectionRanges.graphSelections.length === 0 || isRangeBetweenCharacters(selectionRanges) || isSelectionLastLine(selectionRanges, codeManager.code) if (hasNoSelection) { - // TODO: find extrude in ast - // return doesSceneHaveSweepableSketch(kclManager.ast, count) + return doesSceneHaveExtrudedSketch(kclManager.ast) } const canShell = canShellSelection(selectionRanges) + console.log('canShellSelection', canShellSelection(selectionRanges)) if (err(canShell)) return false return canShell }, diff --git a/src/lang/queryAst.ts b/src/lang/queryAst.ts index 2ab0c405f..d74d85865 100644 --- a/src/lang/queryAst.ts +++ b/src/lang/queryAst.ts @@ -1042,6 +1042,35 @@ export function doesSceneHaveSweepableSketch(ast: Node, count = 1) { return Object.keys(theMap).length >= count } +export function doesSceneHaveExtrudedSketch(ast: Node) { + const theMap: any = {} + traverse(ast as any, { + enter(node) { + if ( + node.type === 'VariableDeclarator' && + node.init?.type === 'PipeExpression' + ) { + for (const pipe of node.init.body) { + if ( + pipe.type === 'CallExpression' && + pipe.callee.name === 'extrude' + ) { + theMap[node.id.name] = true + break + } + } + } else if ( + node.type === 'CallExpression' && + node.callee.name === 'extrude' && + node.arguments[1]?.type === 'Identifier' + ) { + theMap[node.moduleId] = true + } + }, + }) + return Object.keys(theMap).length > 0 +} + export function getObjExprProperty( node: ObjectExpression, propName: string diff --git a/src/lib/commandBarConfigs/modelingCommandConfig.ts b/src/lib/commandBarConfigs/modelingCommandConfig.ts index 808e585c7..6dde0b198 100644 --- a/src/lib/commandBarConfigs/modelingCommandConfig.ts +++ b/src/lib/commandBarConfigs/modelingCommandConfig.ts @@ -289,7 +289,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig< selection: { inputType: 'selection', selectionTypes: ['cap', 'wall'], - // TODO: check if we can have multiple here + // TODO: allow multiple faces to be selected here multiple: false, required: true, skip: true, diff --git a/src/lib/selections.ts b/src/lib/selections.ts index 89a2ee87d..a5d53f51f 100644 --- a/src/lib/selections.ts +++ b/src/lib/selections.ts @@ -583,15 +583,10 @@ export function canShellSelection(selection: Selections) { const commonNodes = selection.graphSelections.map((_, i) => buildCommonNodeFromSelection(selection, i) ) - return ( - // TODO: check what's needed here - // !!isCursorInSketchCommandRange( - // engineCommandManager.artifactGraph, - // selection - // ) && - commonNodes.every((n) => !hasSketchPipeBeenExtruded(n.selection, n.ast)) && - commonNodes.every((n) => nodeHasClose(n) || nodeHasCircle(n)) && - commonNodes.every((n) => !nodeHasExtrude(n)) + return commonNodes.every( + (n) => + n.selection.artifact?.type == 'cap' || + n.selection.artifact?.type == 'wall' ) } diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index 51b6a0cb3..8b6d63235 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -1682,11 +1682,13 @@ export const modelingMachine = setup({ Loft: { target: 'Applying loft', + guard: 'has valid loft selection', reenter: true, }, Shell: { target: 'Applying shell', + guard: 'has valid shell selection', reenter: true, },