2024-12-10 12:11:01 -05:00
|
|
|
import { err } from 'lib/trap'
|
|
|
|
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
|
|
|
|
import {
|
|
|
|
Program,
|
|
|
|
PathToNode,
|
|
|
|
Expr,
|
|
|
|
CallExpression,
|
2024-12-16 10:34:11 -05:00
|
|
|
PipeExpression,
|
2024-12-10 12:11:01 -05:00
|
|
|
VariableDeclarator,
|
|
|
|
} from 'lang/wasm'
|
|
|
|
import { Selections } from 'lib/selections'
|
|
|
|
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
|
|
|
import {
|
|
|
|
createLiteral,
|
|
|
|
createCallExpressionStdLib,
|
|
|
|
createObjectExpression,
|
|
|
|
createIdentifier,
|
2024-12-16 10:34:11 -05:00
|
|
|
createPipeExpression,
|
2024-12-10 12:11:01 -05:00
|
|
|
findUniqueName,
|
|
|
|
createVariableDeclaration,
|
|
|
|
} from 'lang/modifyAst'
|
|
|
|
import { getNodeFromPath, getNodePathFromSourceRange } from 'lang/queryAst'
|
|
|
|
import {
|
|
|
|
mutateAstWithTagForSketchSegment,
|
|
|
|
getEdgeTagCall,
|
|
|
|
} from 'lang/modifyAst/addEdgeTreatment'
|
|
|
|
export function revolveSketch(
|
|
|
|
ast: Node<Program>,
|
|
|
|
pathToSketchNode: PathToNode,
|
2024-12-16 10:34:11 -05:00
|
|
|
shouldPipe = false,
|
2024-12-10 12:11:01 -05:00
|
|
|
angle: Expr = createLiteral(4),
|
2025-01-10 09:52:04 -05:00
|
|
|
axisOrEdge: string,
|
|
|
|
axis: string,
|
|
|
|
edge: Selections
|
2024-12-10 12:11:01 -05:00
|
|
|
):
|
|
|
|
| {
|
|
|
|
modifiedAst: Node<Program>
|
|
|
|
pathToSketchNode: PathToNode
|
|
|
|
pathToRevolveArg: PathToNode
|
|
|
|
}
|
|
|
|
| Error {
|
|
|
|
const clonedAst = structuredClone(ast)
|
|
|
|
const sketchNode = getNodeFromPath(clonedAst, pathToSketchNode)
|
|
|
|
if (err(sketchNode)) return sketchNode
|
|
|
|
|
2025-01-10 09:52:04 -05:00
|
|
|
let generatedAxis
|
2024-12-10 12:11:01 -05:00
|
|
|
|
2025-01-10 09:52:04 -05:00
|
|
|
if (axisOrEdge === 'Edge') {
|
|
|
|
const pathToAxisSelection = getNodePathFromSourceRange(
|
|
|
|
clonedAst,
|
|
|
|
edge.graphSelections[0]?.codeRef.range
|
|
|
|
)
|
|
|
|
const lineNode = getNodeFromPath<CallExpression>(
|
|
|
|
clonedAst,
|
|
|
|
pathToAxisSelection,
|
|
|
|
'CallExpression'
|
|
|
|
)
|
|
|
|
if (err(lineNode)) return lineNode
|
2024-12-10 12:11:01 -05:00
|
|
|
|
2025-01-10 09:52:04 -05:00
|
|
|
const tagResult = mutateAstWithTagForSketchSegment(
|
|
|
|
clonedAst,
|
|
|
|
pathToAxisSelection
|
|
|
|
)
|
2024-12-10 12:11:01 -05:00
|
|
|
|
2025-01-10 09:52:04 -05:00
|
|
|
// 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)
|
|
|
|
} else {
|
|
|
|
generatedAxis = createLiteral(axis)
|
|
|
|
}
|
2024-12-10 12:11:01 -05:00
|
|
|
|
2024-12-16 10:34:11 -05:00
|
|
|
/* Original Code */
|
|
|
|
const { node: sketchExpression } = sketchNode
|
|
|
|
|
|
|
|
// determine if sketchExpression is in a pipeExpression or not
|
|
|
|
const sketchPipeExpressionNode = getNodeFromPath<PipeExpression>(
|
|
|
|
clonedAst,
|
|
|
|
pathToSketchNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
|
|
|
if (err(sketchPipeExpressionNode)) return sketchPipeExpressionNode
|
|
|
|
const { node: sketchPipeExpression } = sketchPipeExpressionNode
|
|
|
|
const isInPipeExpression = sketchPipeExpression.type === 'PipeExpression'
|
|
|
|
|
2024-12-10 12:11:01 -05:00
|
|
|
const sketchVariableDeclaratorNode = getNodeFromPath<VariableDeclarator>(
|
|
|
|
clonedAst,
|
|
|
|
pathToSketchNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
|
|
|
if (err(sketchVariableDeclaratorNode)) return sketchVariableDeclaratorNode
|
2024-12-16 10:34:11 -05:00
|
|
|
const {
|
|
|
|
node: sketchVariableDeclarator,
|
|
|
|
shallowPath: sketchPathToDecleration,
|
|
|
|
} = sketchVariableDeclaratorNode
|
2024-12-10 12:11:01 -05:00
|
|
|
|
2025-01-10 09:52:04 -05:00
|
|
|
if (!generatedAxis) return new Error('Generated axis selection is missing.')
|
2024-12-10 12:11:01 -05:00
|
|
|
|
|
|
|
const revolveCall = createCallExpressionStdLib('revolve', [
|
|
|
|
createObjectExpression({
|
|
|
|
angle: angle,
|
2025-01-10 09:52:04 -05:00
|
|
|
axis: generatedAxis,
|
2024-12-10 12:11:01 -05:00
|
|
|
}),
|
|
|
|
createIdentifier(sketchVariableDeclarator.id.name),
|
|
|
|
])
|
|
|
|
|
2024-12-16 10:34:11 -05:00
|
|
|
if (shouldPipe) {
|
|
|
|
const pipeChain = createPipeExpression(
|
|
|
|
isInPipeExpression
|
|
|
|
? [...sketchPipeExpression.body, revolveCall]
|
|
|
|
: [sketchExpression as any, revolveCall]
|
|
|
|
)
|
|
|
|
|
|
|
|
sketchVariableDeclarator.init = pipeChain
|
|
|
|
const pathToRevolveArg: PathToNode = [
|
|
|
|
...sketchPathToDecleration,
|
|
|
|
['init', 'VariableDeclarator'],
|
|
|
|
['body', ''],
|
|
|
|
[pipeChain.body.length - 1, 'index'],
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
]
|
|
|
|
|
|
|
|
return {
|
|
|
|
modifiedAst: clonedAst,
|
|
|
|
pathToSketchNode,
|
|
|
|
pathToRevolveArg,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-10 12:11:01 -05:00
|
|
|
// We're not creating a pipe expression,
|
|
|
|
// but rather a separate constant for the extrusion
|
|
|
|
const name = findUniqueName(clonedAst, KCL_DEFAULT_CONSTANT_PREFIXES.REVOLVE)
|
|
|
|
const VariableDeclaration = createVariableDeclaration(name, revolveCall)
|
2024-12-16 10:34:11 -05:00
|
|
|
const sketchIndexInPathToNode =
|
|
|
|
sketchPathToDecleration.findIndex((a) => a[0] === 'body') + 1
|
|
|
|
const sketchIndexInBody = sketchPathToDecleration[sketchIndexInPathToNode][0]
|
2024-12-10 12:11:01 -05:00
|
|
|
if (typeof sketchIndexInBody !== 'number')
|
|
|
|
return new Error('expected sketchIndexInBody to be a number')
|
|
|
|
clonedAst.body.splice(sketchIndexInBody + 1, 0, VariableDeclaration)
|
|
|
|
|
|
|
|
const pathToRevolveArg: PathToNode = [
|
|
|
|
['body', ''],
|
|
|
|
[sketchIndexInBody + 1, 'index'],
|
|
|
|
['declaration', 'VariableDeclaration'],
|
|
|
|
['init', 'VariableDeclarator'],
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
]
|
|
|
|
return {
|
|
|
|
modifiedAst: clonedAst,
|
|
|
|
pathToSketchNode: [...pathToSketchNode.slice(0, -1), [-1, 'index']],
|
|
|
|
pathToRevolveArg,
|
|
|
|
}
|
|
|
|
}
|