WIP: Add edge and segment selection in point-and-click Helix flow
Fixes #5393
This commit is contained in:
@ -1093,17 +1093,17 @@ openSketch = startSketchOn('XY')
|
|||||||
await toolbar.helixButton.click()
|
await toolbar.helixButton.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'revolutions',
|
currentArgKey: 'axisOrEdge',
|
||||||
currentArgValue: '1',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
AngleStart: '',
|
AngleStart: '',
|
||||||
Axis: '',
|
AxisOrEdge: '',
|
||||||
CounterClockWise: '',
|
CounterClockWise: '',
|
||||||
Length: '',
|
Length: '',
|
||||||
Radius: '',
|
Radius: '',
|
||||||
Revolutions: '',
|
Revolutions: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'revolutions',
|
highlightedHeaderArg: 'axisOrEdge',
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -1113,6 +1113,7 @@ openSketch = startSketchOn('XY')
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
|
@ -795,7 +795,7 @@ export function addHelix({
|
|||||||
angleStart: Expr
|
angleStart: Expr
|
||||||
counterClockWise: boolean
|
counterClockWise: boolean
|
||||||
radius: Expr
|
radius: Expr
|
||||||
axis: string
|
axis: Node<Literal> | Node<Identifier | CallExpression | CallExpressionKw>
|
||||||
length: Expr
|
length: Expr
|
||||||
insertIndex?: number
|
insertIndex?: number
|
||||||
variableName?: string
|
variableName?: string
|
||||||
@ -813,7 +813,7 @@ export function addHelix({
|
|||||||
createLabeledArg('angleStart', angleStart),
|
createLabeledArg('angleStart', angleStart),
|
||||||
createLabeledArg('counterClockWise', createLiteral(counterClockWise)),
|
createLabeledArg('counterClockWise', createLiteral(counterClockWise)),
|
||||||
createLabeledArg('radius', radius),
|
createLabeledArg('radius', radius),
|
||||||
createLabeledArg('axis', createLiteral(axis)),
|
createLabeledArg('axis', axis),
|
||||||
createLabeledArg('length', length),
|
createLabeledArg('length', length),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -84,12 +84,15 @@ export type ModelingCommandSchema = {
|
|||||||
Helix: {
|
Helix: {
|
||||||
// Enables editing workflow
|
// Enables editing workflow
|
||||||
nodeToEdit?: PathToNode
|
nodeToEdit?: PathToNode
|
||||||
|
// Flow arg
|
||||||
|
axisOrEdge: 'Axis' | 'Edge'
|
||||||
// KCL stdlib arguments
|
// KCL stdlib arguments
|
||||||
|
axis: string
|
||||||
|
edge: Selections
|
||||||
revolutions: KclCommandValue
|
revolutions: KclCommandValue
|
||||||
angleStart: KclCommandValue
|
angleStart: KclCommandValue
|
||||||
counterClockWise: boolean
|
counterClockWise: boolean
|
||||||
radius: KclCommandValue
|
radius: KclCommandValue
|
||||||
axis: string
|
|
||||||
length: KclCommandValue
|
length: KclCommandValue
|
||||||
}
|
}
|
||||||
'change tool': {
|
'change tool': {
|
||||||
@ -495,6 +498,38 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
|||||||
required: false,
|
required: false,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
},
|
},
|
||||||
|
axisOrEdge: {
|
||||||
|
inputType: 'options',
|
||||||
|
required: true,
|
||||||
|
defaultValue: 'Axis',
|
||||||
|
options: [
|
||||||
|
{ name: 'Axis', isCurrent: true, value: 'Axis' },
|
||||||
|
{ name: 'Edge', isCurrent: false, value: 'Edge' },
|
||||||
|
],
|
||||||
|
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
inputType: 'options',
|
||||||
|
required: (commandContext) =>
|
||||||
|
['Axis'].includes(
|
||||||
|
commandContext.argumentsToSubmit.axisOrEdge as string
|
||||||
|
),
|
||||||
|
options: [
|
||||||
|
{ name: 'X Axis', value: 'X' },
|
||||||
|
{ name: 'Y Axis', value: 'Y' },
|
||||||
|
{ name: 'Z Axis', value: 'Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
edge: {
|
||||||
|
required: (commandContext) =>
|
||||||
|
['Edge'].includes(
|
||||||
|
commandContext.argumentsToSubmit.axisOrEdge as string
|
||||||
|
),
|
||||||
|
inputType: 'selection',
|
||||||
|
selectionTypes: ['segment', 'sweepEdge', 'edgeCutEdge'],
|
||||||
|
multiple: false,
|
||||||
|
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
||||||
|
},
|
||||||
revolutions: {
|
revolutions: {
|
||||||
inputType: 'kcl',
|
inputType: 'kcl',
|
||||||
defaultValue: '1',
|
defaultValue: '1',
|
||||||
@ -521,16 +556,6 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
|||||||
defaultValue: KCL_DEFAULT_LENGTH,
|
defaultValue: KCL_DEFAULT_LENGTH,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
axis: {
|
|
||||||
inputType: 'options',
|
|
||||||
required: true,
|
|
||||||
defaultValue: 'X',
|
|
||||||
options: [
|
|
||||||
{ name: 'X Axis', value: 'X' },
|
|
||||||
{ name: 'Y Axis', value: 'Y' },
|
|
||||||
{ name: 'Z Axis', value: 'Z' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
length: {
|
length: {
|
||||||
inputType: 'kcl',
|
inputType: 'kcl',
|
||||||
defaultValue: KCL_DEFAULT_LENGTH,
|
defaultValue: KCL_DEFAULT_LENGTH,
|
||||||
|
@ -311,7 +311,10 @@ const prepareToEditOffsetPlane: PrepareToEditCallback = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
const prepareToEditHelix: PrepareToEditCallback = async ({
|
||||||
|
operation,
|
||||||
|
artifact,
|
||||||
|
}) => {
|
||||||
const baseCommand = {
|
const baseCommand = {
|
||||||
name: 'Helix',
|
name: 'Helix',
|
||||||
groupId: 'modeling',
|
groupId: 'modeling',
|
||||||
@ -321,6 +324,25 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: find a way to loop over the arguments while keeping it safe
|
// TODO: find a way to loop over the arguments while keeping it safe
|
||||||
|
// axis options string arg
|
||||||
|
if (!('axis' in operation.labeledArgs) || !operation.labeledArgs.axis)
|
||||||
|
return baseCommand
|
||||||
|
const axisValue = codeManager.code
|
||||||
|
.slice(
|
||||||
|
operation.labeledArgs.axis.sourceRange[0],
|
||||||
|
operation.labeledArgs.axis.sourceRange[1]
|
||||||
|
)
|
||||||
|
.replaceAll("'", '') // TODO: fix this crap
|
||||||
|
console.log('preparedToEditHelix axis', axisValue)
|
||||||
|
console.log('preparedToEditHelix artifact', artifact)
|
||||||
|
console.log('preparedToEditHelix operation', operation)
|
||||||
|
// TODO: replace with constants
|
||||||
|
const isAxis = axisValue === 'X' || axisValue === 'Y' || axisValue === 'Z'
|
||||||
|
const axisOrEdge = isAxis ? 'Axis' : 'Edge'
|
||||||
|
let axis = isAxis ? axisValue : undefined
|
||||||
|
// TODO: massage selection in for edge edits
|
||||||
|
let edge: Selections | undefined = undefined
|
||||||
|
|
||||||
// revolutions kcl arg
|
// revolutions kcl arg
|
||||||
if (
|
if (
|
||||||
!('revolutions' in operation.labeledArgs) ||
|
!('revolutions' in operation.labeledArgs) ||
|
||||||
@ -372,16 +394,6 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
)
|
)
|
||||||
if (err(radius) || 'errors' in radius) return baseCommand
|
if (err(radius) || 'errors' in radius) return baseCommand
|
||||||
|
|
||||||
// axis options string arg
|
|
||||||
if (!('axis' in operation.labeledArgs) || !operation.labeledArgs.axis)
|
|
||||||
return baseCommand
|
|
||||||
const axis = codeManager.code
|
|
||||||
.slice(
|
|
||||||
operation.labeledArgs.axis.sourceRange[0],
|
|
||||||
operation.labeledArgs.axis.sourceRange[1]
|
|
||||||
)
|
|
||||||
.replaceAll("'", '') // TODO: fix this crap
|
|
||||||
|
|
||||||
// length kcl arg
|
// length kcl arg
|
||||||
if (!('length' in operation.labeledArgs) || !operation.labeledArgs.length)
|
if (!('length' in operation.labeledArgs) || !operation.labeledArgs.length)
|
||||||
return baseCommand
|
return baseCommand
|
||||||
@ -397,11 +409,13 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
|
|||||||
// with `nodeToEdit` set, which will let the Offset Plane actor know
|
// with `nodeToEdit` set, which will let the Offset Plane actor know
|
||||||
// to edit the node that corresponds to the StdLibCall.
|
// to edit the node that corresponds to the StdLibCall.
|
||||||
const argDefaultValues: ModelingCommandSchema['Helix'] = {
|
const argDefaultValues: ModelingCommandSchema['Helix'] = {
|
||||||
|
axisOrEdge,
|
||||||
|
axis,
|
||||||
|
edge,
|
||||||
revolutions,
|
revolutions,
|
||||||
angleStart,
|
angleStart,
|
||||||
counterClockWise,
|
counterClockWise,
|
||||||
radius,
|
radius,
|
||||||
axis,
|
|
||||||
length,
|
length,
|
||||||
nodeToEdit: getNodePathFromSourceRange(
|
nodeToEdit: getNodePathFromSourceRange(
|
||||||
kclManager.ast,
|
kclManager.ast,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
|
CallExpression,
|
||||||
|
CallExpressionKw,
|
||||||
Expr,
|
Expr,
|
||||||
PathToNode,
|
PathToNode,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
@ -57,6 +59,7 @@ import {
|
|||||||
ChamferParameters,
|
ChamferParameters,
|
||||||
EdgeTreatmentType,
|
EdgeTreatmentType,
|
||||||
FilletParameters,
|
FilletParameters,
|
||||||
|
getEdgeTagCall,
|
||||||
getPathToExtrudeForSegmentSelection,
|
getPathToExtrudeForSegmentSelection,
|
||||||
mutateAstWithTagForSketchSegment,
|
mutateAstWithTagForSketchSegment,
|
||||||
} from 'lang/modifyAst/addEdgeTreatment'
|
} from 'lang/modifyAst/addEdgeTreatment'
|
||||||
@ -1892,11 +1895,13 @@ export const modelingMachine = setup({
|
|||||||
// Extract inputs
|
// Extract inputs
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const {
|
const {
|
||||||
|
axisOrEdge,
|
||||||
|
axis,
|
||||||
|
edge,
|
||||||
revolutions,
|
revolutions,
|
||||||
angleStart,
|
angleStart,
|
||||||
counterClockWise,
|
counterClockWise,
|
||||||
radius,
|
radius,
|
||||||
axis,
|
|
||||||
length,
|
length,
|
||||||
nodeToEdit,
|
nodeToEdit,
|
||||||
} = input
|
} = input
|
||||||
@ -1924,6 +1929,47 @@ export const modelingMachine = setup({
|
|||||||
opInsertIndex = nodeToEdit[1][0]
|
opInsertIndex = nodeToEdit[1][0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let generatedAxis
|
||||||
|
let axisDeclaration: PathToNode | null = null
|
||||||
|
|
||||||
|
if (axisOrEdge === 'Edge') {
|
||||||
|
const pathToAxisSelection = getNodePathFromSourceRange(
|
||||||
|
ast,
|
||||||
|
edge.graphSelections[0]?.codeRef.range
|
||||||
|
)
|
||||||
|
const lineNode = getNodeFromPath<CallExpression | CallExpressionKw>(
|
||||||
|
ast,
|
||||||
|
pathToAxisSelection,
|
||||||
|
['CallExpression', 'CallExpressionKw']
|
||||||
|
)
|
||||||
|
if (err(lineNode)) return lineNode
|
||||||
|
|
||||||
|
const tagResult = mutateAstWithTagForSketchSegment(
|
||||||
|
ast,
|
||||||
|
pathToAxisSelection
|
||||||
|
)
|
||||||
|
|
||||||
|
// Have the tag whether it is already created or a new one is generated
|
||||||
|
if (err(tagResult)) return tagResult
|
||||||
|
const { tag } = tagResult
|
||||||
|
const axisSelection = edge?.graphSelections[0]?.artifact
|
||||||
|
if (!axisSelection)
|
||||||
|
return new Error('Generated axis selection is missing.')
|
||||||
|
generatedAxis = getEdgeTagCall(tag, axisSelection)
|
||||||
|
if (
|
||||||
|
axisSelection.type === 'segment' ||
|
||||||
|
axisSelection.type === 'path' ||
|
||||||
|
axisSelection.type === 'edgeCut'
|
||||||
|
) {
|
||||||
|
axisDeclaration = axisSelection.codeRef.pathToNode
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generatedAxis = createLiteral(axis)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!generatedAxis)
|
||||||
|
return new Error('Generated axis selection is missing.')
|
||||||
|
|
||||||
for (const variable of [revolutions, angleStart, radius, length]) {
|
for (const variable of [revolutions, angleStart, radius, length]) {
|
||||||
// Insert the variable if it exists
|
// Insert the variable if it exists
|
||||||
if (
|
if (
|
||||||
@ -1952,7 +1998,7 @@ export const modelingMachine = setup({
|
|||||||
angleStart: valueOrVariable(angleStart),
|
angleStart: valueOrVariable(angleStart),
|
||||||
counterClockWise,
|
counterClockWise,
|
||||||
radius: valueOrVariable(radius),
|
radius: valueOrVariable(radius),
|
||||||
axis,
|
axis: generatedAxis,
|
||||||
length: valueOrVariable(length),
|
length: valueOrVariable(length),
|
||||||
insertIndex: opInsertIndex,
|
insertIndex: opInsertIndex,
|
||||||
variableName: opVariableName,
|
variableName: opVariableName,
|
||||||
|
Reference in New Issue
Block a user