2024-04-19 11:56:21 -04:00
|
|
|
import {
|
|
|
|
createArrayExpression,
|
|
|
|
createBinaryExpression,
|
|
|
|
createCallExpressionStdLib,
|
2024-06-24 22:39:04 -07:00
|
|
|
createIdentifier,
|
2024-04-19 11:56:21 -04:00
|
|
|
createLiteral,
|
|
|
|
createPipeSubstitution,
|
2024-06-24 22:39:04 -07:00
|
|
|
createTagDeclarator,
|
2024-04-19 11:56:21 -04:00
|
|
|
createUnaryExpression,
|
|
|
|
} from 'lang/modifyAst'
|
2025-01-31 10:45:39 -05:00
|
|
|
import {
|
|
|
|
ArrayExpression,
|
|
|
|
CallExpression,
|
|
|
|
PipeExpression,
|
|
|
|
recast,
|
|
|
|
} from 'lang/wasm'
|
2024-11-18 10:04:09 -05:00
|
|
|
import { roundOff } from 'lib/utils'
|
|
|
|
import {
|
|
|
|
isCallExpression,
|
|
|
|
isArrayExpression,
|
|
|
|
isLiteral,
|
|
|
|
isBinaryExpression,
|
2025-01-31 10:45:39 -05:00
|
|
|
isLiteralValueNumber,
|
2024-11-18 10:04:09 -05:00
|
|
|
} from 'lang/util'
|
2024-04-19 11:56:21 -04:00
|
|
|
|
|
|
|
/**
|
2024-11-18 10:04:09 -05:00
|
|
|
* It does not create the startSketchOn and it does not create the startProfileAt.
|
2024-04-19 11:56:21 -04:00
|
|
|
* Returns AST expressions for this KCL code:
|
|
|
|
* const yo = startSketchOn('XY')
|
|
|
|
* |> startProfileAt([0, 0], %)
|
2024-07-27 22:56:46 -07:00
|
|
|
* |> angledLine([0, 0], %, $a)
|
|
|
|
* |> angledLine([segAng(a) - 90, 0], %, $b)
|
|
|
|
* |> angledLine([segAng(a), -segLen(a)], %, $c)
|
2024-04-19 11:56:21 -04:00
|
|
|
* |> close(%)
|
|
|
|
*/
|
|
|
|
export const getRectangleCallExpressions = (
|
|
|
|
rectangleOrigin: [number, number],
|
2024-12-16 10:34:11 -05:00
|
|
|
tags: [string, string, string]
|
2024-04-19 11:56:21 -04:00
|
|
|
) => [
|
|
|
|
createCallExpressionStdLib('angledLine', [
|
|
|
|
createArrayExpression([
|
|
|
|
createLiteral(0), // 0 deg
|
|
|
|
createLiteral(0), // This will be the width of the rectangle
|
|
|
|
]),
|
|
|
|
createPipeSubstitution(),
|
2024-12-16 10:34:11 -05:00
|
|
|
createTagDeclarator(tags[0]),
|
2024-04-19 11:56:21 -04:00
|
|
|
]),
|
|
|
|
createCallExpressionStdLib('angledLine', [
|
|
|
|
createArrayExpression([
|
|
|
|
createBinaryExpression([
|
2024-12-16 10:34:11 -05:00
|
|
|
createCallExpressionStdLib('segAng', [createIdentifier(tags[0])]),
|
2024-04-19 11:56:21 -04:00
|
|
|
'+',
|
|
|
|
createLiteral(90),
|
|
|
|
]), // 90 offset from the previous line
|
|
|
|
createLiteral(0), // This will be the height of the rectangle
|
|
|
|
]),
|
|
|
|
createPipeSubstitution(),
|
2024-12-16 10:34:11 -05:00
|
|
|
createTagDeclarator(tags[1]),
|
2024-04-19 11:56:21 -04:00
|
|
|
]),
|
|
|
|
createCallExpressionStdLib('angledLine', [
|
|
|
|
createArrayExpression([
|
2024-12-16 10:34:11 -05:00
|
|
|
createCallExpressionStdLib('segAng', [createIdentifier(tags[0])]), // same angle as the first line
|
2024-04-19 11:56:21 -04:00
|
|
|
createUnaryExpression(
|
2024-12-16 10:34:11 -05:00
|
|
|
createCallExpressionStdLib('segLen', [createIdentifier(tags[0])]),
|
2024-04-19 11:56:21 -04:00
|
|
|
'-'
|
|
|
|
), // negative height
|
|
|
|
]),
|
|
|
|
createPipeSubstitution(),
|
2024-12-16 10:34:11 -05:00
|
|
|
createTagDeclarator(tags[2]),
|
2024-04-19 11:56:21 -04:00
|
|
|
]),
|
2024-05-31 14:02:46 -04:00
|
|
|
createCallExpressionStdLib('lineTo', [
|
|
|
|
createArrayExpression([
|
|
|
|
createCallExpressionStdLib('profileStartX', [createPipeSubstitution()]),
|
|
|
|
createCallExpressionStdLib('profileStartY', [createPipeSubstitution()]),
|
|
|
|
]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
]), // close the rectangle
|
2024-04-19 11:56:21 -04:00
|
|
|
createCallExpressionStdLib('close', [createPipeSubstitution()]),
|
|
|
|
]
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mutates the pipeExpression to update the rectangle sketch
|
|
|
|
* @param pipeExpression
|
|
|
|
* @param x
|
|
|
|
* @param y
|
|
|
|
* @param tag
|
|
|
|
*/
|
|
|
|
export function updateRectangleSketch(
|
|
|
|
pipeExpression: PipeExpression,
|
|
|
|
x: number,
|
|
|
|
y: number,
|
|
|
|
tag: string
|
|
|
|
) {
|
2024-12-16 10:34:11 -05:00
|
|
|
;((pipeExpression.body[2] as CallExpression)
|
2024-04-19 11:56:21 -04:00
|
|
|
.arguments[0] as ArrayExpression) = createArrayExpression([
|
|
|
|
createLiteral(x >= 0 ? 0 : 180),
|
|
|
|
createLiteral(Math.abs(x)),
|
|
|
|
])
|
2024-12-16 10:34:11 -05:00
|
|
|
;((pipeExpression.body[3] as CallExpression)
|
2024-04-19 11:56:21 -04:00
|
|
|
.arguments[0] as ArrayExpression) = createArrayExpression([
|
|
|
|
createBinaryExpression([
|
2024-07-27 22:56:46 -07:00
|
|
|
createCallExpressionStdLib('segAng', [createIdentifier(tag)]),
|
2024-04-19 11:56:21 -04:00
|
|
|
Math.sign(y) === Math.sign(x) ? '+' : '-',
|
|
|
|
createLiteral(90),
|
|
|
|
]), // 90 offset from the previous line
|
|
|
|
createLiteral(Math.abs(y)), // This will be the height of the rectangle
|
|
|
|
])
|
|
|
|
}
|
2024-11-18 10:04:09 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Mutates the pipeExpression to update the center rectangle sketch
|
|
|
|
* @param pipeExpression
|
|
|
|
* @param x
|
|
|
|
* @param y
|
|
|
|
* @param tag
|
|
|
|
*/
|
|
|
|
export function updateCenterRectangleSketch(
|
|
|
|
pipeExpression: PipeExpression,
|
|
|
|
deltaX: number,
|
|
|
|
deltaY: number,
|
|
|
|
tag: string,
|
|
|
|
originX: number,
|
|
|
|
originY: number
|
|
|
|
) {
|
|
|
|
let startX = originX - Math.abs(deltaX)
|
|
|
|
let startY = originY - Math.abs(deltaY)
|
|
|
|
|
|
|
|
// pipeExpression.body[1] is startProfileAt
|
2024-12-16 10:34:11 -05:00
|
|
|
let callExpression = pipeExpression.body[1]
|
2024-11-18 10:04:09 -05:00
|
|
|
if (isCallExpression(callExpression)) {
|
|
|
|
const arrayExpression = callExpression.arguments[0]
|
|
|
|
if (isArrayExpression(arrayExpression)) {
|
|
|
|
callExpression.arguments[0] = createArrayExpression([
|
|
|
|
createLiteral(roundOff(startX)),
|
|
|
|
createLiteral(roundOff(startY)),
|
|
|
|
])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const twoX = deltaX * 2
|
|
|
|
const twoY = deltaY * 2
|
|
|
|
|
2024-12-16 10:34:11 -05:00
|
|
|
callExpression = pipeExpression.body[2]
|
2024-11-18 10:04:09 -05:00
|
|
|
if (isCallExpression(callExpression)) {
|
|
|
|
const arrayExpression = callExpression.arguments[0]
|
|
|
|
if (isArrayExpression(arrayExpression)) {
|
|
|
|
const literal = arrayExpression.elements[0]
|
|
|
|
if (isLiteral(literal)) {
|
2025-01-31 10:45:39 -05:00
|
|
|
if (isLiteralValueNumber(literal.value)) {
|
|
|
|
callExpression.arguments[0] = createArrayExpression([
|
|
|
|
createLiteral(literal.value),
|
|
|
|
createLiteral(Math.abs(twoX)),
|
|
|
|
])
|
|
|
|
}
|
2024-11-18 10:04:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-16 10:34:11 -05:00
|
|
|
callExpression = pipeExpression.body[3]
|
2024-11-18 10:04:09 -05:00
|
|
|
if (isCallExpression(callExpression)) {
|
|
|
|
const arrayExpression = callExpression.arguments[0]
|
|
|
|
if (isArrayExpression(arrayExpression)) {
|
|
|
|
const binaryExpression = arrayExpression.elements[0]
|
|
|
|
if (isBinaryExpression(binaryExpression)) {
|
|
|
|
callExpression.arguments[0] = createArrayExpression([
|
|
|
|
createBinaryExpression([
|
|
|
|
createCallExpressionStdLib('segAng', [createIdentifier(tag)]),
|
|
|
|
binaryExpression.operator,
|
|
|
|
createLiteral(90),
|
|
|
|
]), // 90 offset from the previous line
|
|
|
|
createLiteral(Math.abs(twoY)), // This will be the height of the rectangle
|
|
|
|
])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|