Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/lang/modifyAst/sweeps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
addSweep,
getAxisExpressionAndIndex,
retrieveAxisOrEdgeSelectionsFromOpArg,
retrieveBodyTypeFromOpArg,
} from '@src/lang/modifyAst/sweeps'
import type { Node } from '@rust/kcl-lib/bindings/Node'
import type { ConnectionManager } from '@src/network/connectionManager'
Expand Down Expand Up @@ -832,6 +833,41 @@ profile001 = circle(sketch001, center = [3, 0], radius = 1)`
)
})

it('should add basic revolve call with surface bodyType', async () => {
const { ast, sketches } = await getAstAndSketchSelections(
circleCode,
instanceInThisFile,
kclManagerInThisFile
)
expect(sketches.graphSelections).toHaveLength(1)
const angle = await getKclCommandValue(
'10',
instanceInThisFile,
rustContextInThisFile
)
const axis = 'X'
const result = addRevolve({
ast,
sketches,
angle,
axis,
bodyType: 'SURFACE',
wasmInstance: instanceInThisFile,
})
if (err(result)) throw result
await runNewAstAndCheckForSweep(result.modifiedAst, rustContextInThisFile)
const newCode = recast(result.modifiedAst, instanceInThisFile)
expect(newCode).toContain(circleCode)
expect(newCode).toContain(
`revolve001 = revolve(
profile001,
angle = 10,
axis = X,
bodyType = SURFACE,
)`
)
})

Comment on lines +836 to +870
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra codemod integration test case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good stuff

it('should add basic revolve call with symmetric true', async () => {
const { ast, sketches } = await getAstAndSketchSelections(
circleCode,
Expand Down Expand Up @@ -1157,4 +1193,40 @@ helix001 = helix(
expect(result.axis).toBeUndefined()
})
})

describe('Testing retrieveBodyTypeFromOpArg', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New util function used for Extrude and Revolve here in the edit flow, see operations.ts

async function findBodyTypeArg(code: string) {
const ast = assertParse(code, instanceInThisFile)
const { operations } = await enginelessExecutor(
ast,
rustContextInThisFile
)
const op = operations.find(
(o) => o.type === 'StdLibCall' && o.name === 'extrude'
)
if (!op || op.type !== 'StdLibCall' || !op.labeledArgs.bodyType) {
throw new Error('Extrude operation not found')
}

return op.labeledArgs.bodyType
}

it('should return SOLID bodyType from op argument', async () => {
const code = `${circleProfileCode}
extrude001 = extrude(profile001, length = 1, bodyType = SOLID)`
const opArg = await findBodyTypeArg(code)
const result = retrieveBodyTypeFromOpArg(opArg, code)
if (err(result)) throw result
expect(result).toEqual('SOLID')
})

it('should return SURFACE bodyType from op argument', async () => {
const code = `${circleProfileCode}
extrude001 = extrude(profile001, length = 1, bodyType = SURFACE)`
const opArg = await findBodyTypeArg(code)
const result = retrieveBodyTypeFromOpArg(opArg, code)
if (err(result)) throw result
expect(result).toEqual('SURFACE')
})
})
})
26 changes: 26 additions & 0 deletions src/lang/modifyAst/sweeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import {
KCL_DEFAULT_CONSTANT_PREFIXES,
type KclPreludeExtrudeMethod,
type KclPreludeBodyType,
KCL_PRELUDE_BODY_TYPE_SOLID,
KCL_PRELUDE_BODY_TYPE_SURFACE,
} from '@src/lib/constants'
import { err } from '@src/lib/trap'
import type { Selections } from '@src/machines/modelingSharedTypes'
Expand Down Expand Up @@ -453,6 +455,7 @@ export function addRevolve({
bidirectionalAngle,
tagStart,
tagEnd,
bodyType,
nodeToEdit,
}: {
ast: Node<Program>
Expand All @@ -465,6 +468,7 @@ export function addRevolve({
bidirectionalAngle?: KclCommandValue
tagStart?: string
tagEnd?: string
bodyType?: KclPreludeBodyType
nodeToEdit?: PathToNode
}):
| {
Expand Down Expand Up @@ -517,6 +521,9 @@ export function addRevolve({
const tagEndExpr = tagEnd
? [createLabeledArg('tagEnd', createTagDeclarator(tagEnd))]
: []
const bodyTypeExpr = bodyType
? [createLabeledArg('bodyType', createLocalName(bodyType))]
: []

const sketchesExpr = createVariableExpressionsArray(vars.exprs)
const call = createCallExpressionStdLibKw('revolve', sketchesExpr, [
Expand All @@ -526,6 +533,7 @@ export function addRevolve({
...bidirectionalAngleExpr,
...tagStartExpr,
...tagEndExpr,
...bodyTypeExpr,
])

// Insert variables for labeled arguments if provided
Expand Down Expand Up @@ -732,3 +740,21 @@ export function retrieveTagDeclaratorFromOpArg(
toUtf16(opArg.sourceRange[1], code)
)
}

export function retrieveBodyTypeFromOpArg(
opArg: OpArg,
code: string
): KclPreludeBodyType | Error {
/** Version of `toUtf16` bound to our code, for mapping source range values. */
const boundToUtf16 = (n: number) => toUtf16(n, code)
const result = code.slice(...opArg.sourceRange.map(boundToUtf16))
if (result === KCL_PRELUDE_BODY_TYPE_SOLID) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to normalize the lover/upper case here, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, are both defined?

return KCL_PRELUDE_BODY_TYPE_SOLID
}

if (result === KCL_PRELUDE_BODY_TYPE_SURFACE) {
return KCL_PRELUDE_BODY_TYPE_SURFACE
}

return new Error("Couldn't retrieve bodyType argument")
}
17 changes: 13 additions & 4 deletions src/lib/commandBarConfigs/modelingCommandConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ const objectsTypesAndFilters: {
selectionFilter: ['object'],
}

// For all surface modeling commands
const kclBodyTypeOptions = KCL_PRELUDE_BODY_TYPE_VALUES.map((value) => ({
name: capitaliseFC(value.toLowerCase()),
value,
}))

const hasEngineConnection = (
engineCommandManager: ConnectionManager
): true | Error => {
Expand Down Expand Up @@ -188,6 +194,7 @@ export type ModelingCommandSchema = {
tagEnd?: string
symmetric?: boolean
bidirectionalAngle?: KclCommandValue
bodyType?: KclPreludeBodyType
}
Shell: {
// Enables editing workflow
Expand Down Expand Up @@ -637,10 +644,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
bodyType: {
inputType: 'options',
required: false,
options: KCL_PRELUDE_BODY_TYPE_VALUES.map((value) => ({
name: capitaliseFC(value.toLowerCase()),
value,
})),
options: kclBodyTypeOptions,
},
},
},
Expand Down Expand Up @@ -865,6 +869,11 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
inputType: 'tagDeclarator',
required: false,
},
bodyType: {
inputType: 'options',
required: false,
options: kclBodyTypeOptions,
},
},
},
Shell: {
Expand Down
25 changes: 13 additions & 12 deletions src/lib/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '@src/lang/modifyAst/faces'
import {
retrieveAxisOrEdgeSelectionsFromOpArg,
retrieveBodyTypeFromOpArg,
retrieveTagDeclaratorFromOpArg,
SWEEP_CONSTANTS,
SWEEP_MODULE,
Expand Down Expand Up @@ -48,8 +49,6 @@ import { err } from '@src/lib/trap'
import type { CommandBarMachineEvent } from '@src/machines/commandBarMachine'
import { retrieveEdgeSelectionsFromOpArgs } from '@src/lang/modifyAst/edges'
import {
KCL_PRELUDE_BODY_TYPE_SOLID,
KCL_PRELUDE_BODY_TYPE_SURFACE,
type KclPreludeBodyType,
KCL_PRELUDE_EXTRUDE_METHOD_MERGE,
KCL_PRELUDE_EXTRUDE_METHOD_NEW,
Expand Down Expand Up @@ -407,16 +406,9 @@ const prepareToEditExtrude: PrepareToEditCallback = async ({
// bodyType argument from a string
let bodyType: KclPreludeBodyType | undefined
if ('bodyType' in operation.labeledArgs && operation.labeledArgs.bodyType) {
const result = code.slice(
...operation.labeledArgs.bodyType.sourceRange.map(boundToUtf16)
)
if (result === KCL_PRELUDE_BODY_TYPE_SOLID) {
bodyType = KCL_PRELUDE_BODY_TYPE_SOLID
} else if (result === KCL_PRELUDE_BODY_TYPE_SURFACE) {
bodyType = KCL_PRELUDE_BODY_TYPE_SURFACE
} else {
return { reason: "Couldn't retrieve bodyType argument" }
}
const res = retrieveBodyTypeFromOpArg(operation.labeledArgs.bodyType, code)
if (err(res)) return { reason: res.message }
bodyType = res
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so much cleaner, love it

}

// 3. Assemble the default argument values for the command,
Expand Down Expand Up @@ -1349,6 +1341,14 @@ const prepareToEditRevolve: PrepareToEditCallback = async ({
tagEnd = retrieveTagDeclaratorFromOpArg(operation.labeledArgs.tagEnd, code)
}

// bodyType argument from a string
let bodyType: KclPreludeBodyType | undefined
if ('bodyType' in operation.labeledArgs && operation.labeledArgs.bodyType) {
const res = retrieveBodyTypeFromOpArg(operation.labeledArgs.bodyType, code)
if (err(res)) return { reason: res.message }
bodyType = res
}

// 3. Assemble the default argument values for the command,
// with `nodeToEdit` set, which will let the actor know
// to edit the node that corresponds to the StdLibCall.
Expand All @@ -1362,6 +1362,7 @@ const prepareToEditRevolve: PrepareToEditCallback = async ({
bidirectionalAngle,
tagStart,
tagEnd,
bodyType,
nodeToEdit: pathToNodeFromRustNodePath(operation.nodePath),
}
return {
Expand Down
Loading