Remove KclValue::SketchGroup variant (#3446)
We can store Rust types like `SketchGroup` as their own variant of `KclValue`, or as `KclValue::UserVal`. Sometimes we store in one and try to read from the other, which fails. This causes bugs, like #3338. Instead, we should use either ::SketchGroup or ::UserVal, and stop using the other. If we stopped using ::UserVal, we'd need a new variant for every Rust type we wanted to build, including user-defined types. So I don't think that's practical. Instead, we should store every KCL value by de/serializing it into UserVal. This is a first step along that path, removing just the SketchGroup variants. If it goes well, we can remove the other specialized variants too. My only concern is there might be performance implications from how frequently we convert between serde_json::Value and Rust types via Serde. But I'm not too worried -- there's no parsing JSON strings, just traversing serde_json::Value trees. This isn't great for performance but I think it'll probably be miniscule in comparison to doing all the API calls.
This commit is contained in:
@ -50,6 +50,7 @@ import {
|
|||||||
ExtrudeGroup,
|
ExtrudeGroup,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
VariableDeclarator,
|
VariableDeclarator,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import {
|
import {
|
||||||
engineCommandManager,
|
engineCommandManager,
|
||||||
@ -588,10 +589,12 @@ export class SceneEntities {
|
|||||||
const variableDeclarationName =
|
const variableDeclarationName =
|
||||||
_node1.node?.declarations?.[0]?.id?.name || ''
|
_node1.node?.declarations?.[0]?.id?.name || ''
|
||||||
|
|
||||||
const sg = kclManager.programMemory.get(
|
const sg = sketchGroupFromKclValue(
|
||||||
|
kclManager.programMemory.get(variableDeclarationName),
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
) as SketchGroup
|
)
|
||||||
const lastSeg = sg?.value?.slice(-1)[0] || sg.start
|
if (err(sg)) return sg
|
||||||
|
const lastSeg = sg.value?.slice(-1)[0] || sg.start
|
||||||
|
|
||||||
const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1`
|
const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1`
|
||||||
|
|
||||||
@ -786,9 +789,11 @@ export class SceneEntities {
|
|||||||
programMemoryOverride,
|
programMemoryOverride,
|
||||||
})
|
})
|
||||||
this.sceneProgramMemory = programMemory
|
this.sceneProgramMemory = programMemory
|
||||||
const sketchGroup = programMemory.get(
|
const sketchGroup = sketchGroupFromKclValue(
|
||||||
|
programMemory.get(variableDeclarationName),
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
) as SketchGroup
|
)
|
||||||
|
if (err(sketchGroup)) return sketchGroup
|
||||||
const sgPaths = sketchGroup.value
|
const sgPaths = sketchGroup.value
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
@ -840,9 +845,11 @@ export class SceneEntities {
|
|||||||
|
|
||||||
// Prepare to update the THREEjs scene
|
// Prepare to update the THREEjs scene
|
||||||
this.sceneProgramMemory = programMemory
|
this.sceneProgramMemory = programMemory
|
||||||
const sketchGroup = programMemory.get(
|
const sketchGroup = sketchGroupFromKclValue(
|
||||||
|
programMemory.get(variableDeclarationName),
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
) as SketchGroup
|
)
|
||||||
|
if (err(sketchGroup)) return sketchGroup
|
||||||
const sgPaths = sketchGroup.value
|
const sgPaths = sketchGroup.value
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
@ -1111,8 +1118,12 @@ export class SceneEntities {
|
|||||||
|
|
||||||
const maybeSketchGroup = programMemory.get(variableDeclarationName)
|
const maybeSketchGroup = programMemory.get(variableDeclarationName)
|
||||||
let sketchGroup = undefined
|
let sketchGroup = undefined
|
||||||
if (maybeSketchGroup?.type === 'SketchGroup') {
|
const sg = sketchGroupFromKclValue(
|
||||||
sketchGroup = maybeSketchGroup
|
maybeSketchGroup,
|
||||||
|
variableDeclarationName
|
||||||
|
)
|
||||||
|
if (!err(sg)) {
|
||||||
|
sketchGroup = sg
|
||||||
} else if ((maybeSketchGroup as ExtrudeGroup).sketchGroup) {
|
} else if ((maybeSketchGroup as ExtrudeGroup).sketchGroup) {
|
||||||
sketchGroup = (maybeSketchGroup as ExtrudeGroup).sketchGroup
|
sketchGroup = (maybeSketchGroup as ExtrudeGroup).sketchGroup
|
||||||
}
|
}
|
||||||
@ -1656,9 +1667,12 @@ function prepareTruncatedMemoryAndAst(
|
|||||||
)
|
)
|
||||||
if (err(_node)) return _node
|
if (err(_node)) return _node
|
||||||
const variableDeclarationName = _node.node?.declarations?.[0]?.id?.name || ''
|
const variableDeclarationName = _node.node?.declarations?.[0]?.id?.name || ''
|
||||||
const lastSeg = (
|
const sg = sketchGroupFromKclValue(
|
||||||
programMemory.get(variableDeclarationName) as SketchGroup
|
programMemory.get(variableDeclarationName),
|
||||||
).value.slice(-1)[0]
|
variableDeclarationName
|
||||||
|
)
|
||||||
|
if (err(sg)) return sg
|
||||||
|
const lastSeg = sg?.value.slice(-1)[0]
|
||||||
if (draftSegment) {
|
if (draftSegment) {
|
||||||
// truncatedAst needs to setup with another segment at the end
|
// truncatedAst needs to setup with another segment at the end
|
||||||
let newSegment
|
let newSegment
|
||||||
@ -1782,10 +1796,11 @@ export function sketchGroupFromPathToNode({
|
|||||||
if (result?.type === 'ExtrudeGroup') {
|
if (result?.type === 'ExtrudeGroup') {
|
||||||
return result.sketchGroup
|
return result.sketchGroup
|
||||||
}
|
}
|
||||||
if (result?.type === 'SketchGroup') {
|
const sg = sketchGroupFromKclValue(result, varDec?.id?.name)
|
||||||
return result
|
if (err(sg)) {
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
|
}
|
||||||
|
return sg
|
||||||
}
|
}
|
||||||
|
|
||||||
function colorSegment(object: any, color: number) {
|
function colorSegment(object: any, color: number) {
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
import ReactJson from 'react-json-view'
|
import ReactJson from 'react-json-view'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { ProgramMemory, Path, ExtrudeSurface } from 'lang/wasm'
|
import {
|
||||||
|
ProgramMemory,
|
||||||
|
Path,
|
||||||
|
ExtrudeSurface,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
|
} from 'lang/wasm'
|
||||||
import { useKclContext } from 'lang/KclProvider'
|
import { useKclContext } from 'lang/KclProvider'
|
||||||
import { useResolvedTheme } from 'hooks/useResolvedTheme'
|
import { useResolvedTheme } from 'hooks/useResolvedTheme'
|
||||||
import { ActionButton } from 'components/ActionButton'
|
import { ActionButton } from 'components/ActionButton'
|
||||||
import { trap } from 'lib/trap'
|
import { err, trap } from 'lib/trap'
|
||||||
import Tooltip from 'components/Tooltip'
|
import Tooltip from 'components/Tooltip'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
|
|
||||||
@ -84,8 +89,9 @@ export const processMemory = (programMemory: ProgramMemory) => {
|
|||||||
const processedMemory: any = {}
|
const processedMemory: any = {}
|
||||||
for (const [key, val] of programMemory?.visibleEntries()) {
|
for (const [key, val] of programMemory?.visibleEntries()) {
|
||||||
if (typeof val.value !== 'function') {
|
if (typeof val.value !== 'function') {
|
||||||
if (val.type === 'SketchGroup') {
|
const sg = sketchGroupFromKclValue(val, null)
|
||||||
processedMemory[key] = val.value.map(({ __geoMeta, ...rest }: Path) => {
|
if (!err(sg)) {
|
||||||
|
processedMemory[key] = sg.value.map(({ __geoMeta, ...rest }: Path) => {
|
||||||
return rest
|
return rest
|
||||||
})
|
})
|
||||||
} else if (val.type === 'ExtrudeGroup') {
|
} else if (val.type === 'ExtrudeGroup') {
|
||||||
|
@ -18,6 +18,9 @@ const mySketch001 = startSketchOn('XY')
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const sketch001 = programMemory?.get('mySketch001')
|
const sketch001 = programMemory?.get('mySketch001')
|
||||||
expect(sketch001).toEqual({
|
expect(sketch001).toEqual({
|
||||||
|
type: 'UserVal',
|
||||||
|
__meta: [{ sourceRange: [46, 71] }],
|
||||||
|
value: {
|
||||||
type: 'SketchGroup',
|
type: 'SketchGroup',
|
||||||
on: expect.any(Object),
|
on: expect.any(Object),
|
||||||
start: {
|
start: {
|
||||||
@ -53,6 +56,7 @@ const mySketch001 = startSketchOn('XY')
|
|||||||
],
|
],
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
__meta: [{ sourceRange: [46, 71] }],
|
__meta: [{ sourceRange: [46, 71] }],
|
||||||
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('extrude artifacts', async () => {
|
test('extrude artifacts', async () => {
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
|
|
||||||
import { parse, ProgramMemory, SketchGroup, initPromise } from './wasm'
|
import {
|
||||||
|
parse,
|
||||||
|
ProgramMemory,
|
||||||
|
SketchGroup,
|
||||||
|
initPromise,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
|
} from './wasm'
|
||||||
import { enginelessExecutor } from '../lib/testHelpers'
|
import { enginelessExecutor } from '../lib/testHelpers'
|
||||||
import { KCLError } from './errors'
|
import { KCLError } from './errors'
|
||||||
|
|
||||||
@ -52,7 +58,7 @@ const newVar = myVar + 1`
|
|||||||
`
|
`
|
||||||
const mem = await exe(code)
|
const mem = await exe(code)
|
||||||
// geo is three js buffer geometry and is very bloated to have in tests
|
// geo is three js buffer geometry and is very bloated to have in tests
|
||||||
const minusGeo = mem.get('mySketch')?.value
|
const minusGeo = mem.get('mySketch')?.value?.value
|
||||||
expect(minusGeo).toEqual([
|
expect(minusGeo).toEqual([
|
||||||
{
|
{
|
||||||
type: 'ToPoint',
|
type: 'ToPoint',
|
||||||
@ -146,6 +152,8 @@ const newVar = myVar + 1`
|
|||||||
].join('\n')
|
].join('\n')
|
||||||
const mem = await exe(code)
|
const mem = await exe(code)
|
||||||
expect(mem.get('mySk1')).toEqual({
|
expect(mem.get('mySk1')).toEqual({
|
||||||
|
type: 'UserVal',
|
||||||
|
value: {
|
||||||
type: 'SketchGroup',
|
type: 'SketchGroup',
|
||||||
on: expect.any(Object),
|
on: expect.any(Object),
|
||||||
start: {
|
start: {
|
||||||
@ -209,6 +217,8 @@ const newVar = myVar + 1`
|
|||||||
],
|
],
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
__meta: [{ sourceRange: [39, 63] }],
|
__meta: [{ sourceRange: [39, 63] }],
|
||||||
|
},
|
||||||
|
__meta: [{ sourceRange: [39, 63] }],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('execute array expression', async () => {
|
it('execute array expression', async () => {
|
||||||
@ -358,7 +368,7 @@ describe('testing math operators', () => {
|
|||||||
'|> line([-2.21, -legLen(5, min(3, 999))], %)',
|
'|> line([-2.21, -legLen(5, min(3, 999))], %)',
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const mem = await exe(code)
|
const mem = await exe(code)
|
||||||
const sketch = mem.get('part001')
|
const sketch = sketchGroupFromKclValue(mem.get('part001'), 'part001')
|
||||||
// result of `-legLen(5, min(3, 999))` should be -4
|
// result of `-legLen(5, min(3, 999))` should be -4
|
||||||
const yVal = (sketch as SketchGroup).value?.[0]?.to?.[1]
|
const yVal = (sketch as SketchGroup).value?.[0]?.to?.[1]
|
||||||
expect(yVal).toBe(-4)
|
expect(yVal).toBe(-4)
|
||||||
@ -376,7 +386,7 @@ describe('testing math operators', () => {
|
|||||||
``,
|
``,
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const mem = await exe(code)
|
const mem = await exe(code)
|
||||||
const sketch = mem.get('part001')
|
const sketch = sketchGroupFromKclValue(mem.get('part001'), 'part001')
|
||||||
// expect -legLen(segLen('seg01'), myVar) to equal -4 setting the y value back to 0
|
// expect -legLen(segLen('seg01'), myVar) to equal -4 setting the y value back to 0
|
||||||
expect((sketch as SketchGroup).value?.[1]?.from).toEqual([3, 4])
|
expect((sketch as SketchGroup).value?.[1]?.from).toEqual([3, 4])
|
||||||
expect((sketch as SketchGroup).value?.[1]?.to).toEqual([6, 0])
|
expect((sketch as SketchGroup).value?.[1]?.to).toEqual([6, 0])
|
||||||
@ -385,7 +395,10 @@ describe('testing math operators', () => {
|
|||||||
`legLen(segLen(seg01), myVar)`
|
`legLen(segLen(seg01), myVar)`
|
||||||
)
|
)
|
||||||
const removedUnaryExpMem = await exe(removedUnaryExp)
|
const removedUnaryExpMem = await exe(removedUnaryExp)
|
||||||
const removedUnaryExpMemSketch = removedUnaryExpMem.get('part001')
|
const removedUnaryExpMemSketch = sketchGroupFromKclValue(
|
||||||
|
removedUnaryExpMem.get('part001'),
|
||||||
|
'part001'
|
||||||
|
)
|
||||||
|
|
||||||
// without the minus sign, the y value should be 8
|
// without the minus sign, the y value should be 8
|
||||||
expect((removedUnaryExpMemSketch as SketchGroup).value?.[1]?.to).toEqual([
|
expect((removedUnaryExpMemSketch as SketchGroup).value?.[1]?.to).toEqual([
|
||||||
|
@ -17,7 +17,7 @@ import {
|
|||||||
PathToNode,
|
PathToNode,
|
||||||
ProgramMemory,
|
ProgramMemory,
|
||||||
SourceRange,
|
SourceRange,
|
||||||
SketchGroup,
|
sketchGroupFromKclValue,
|
||||||
} from './wasm'
|
} from './wasm'
|
||||||
import {
|
import {
|
||||||
isNodeSafeToReplacePath,
|
isNodeSafeToReplacePath,
|
||||||
@ -981,7 +981,11 @@ export async function deleteFromSelection(
|
|||||||
if (err(parent)) {
|
if (err(parent)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const sketchToPreserve = programMemory.get(sketchName) as SketchGroup
|
const sketchToPreserve = sketchGroupFromKclValue(
|
||||||
|
programMemory.get(sketchName),
|
||||||
|
sketchName
|
||||||
|
)
|
||||||
|
if (err(sketchToPreserve)) return sketchToPreserve
|
||||||
console.log('sketchName', sketchName)
|
console.log('sketchName', sketchName)
|
||||||
// Can't kick off multiple requests at once as getFaceDetails
|
// Can't kick off multiple requests at once as getFaceDetails
|
||||||
// is three engine calls in one and they conflict
|
// is three engine calls in one and they conflict
|
||||||
|
@ -10,12 +10,12 @@ import {
|
|||||||
Program,
|
Program,
|
||||||
ProgramMemory,
|
ProgramMemory,
|
||||||
ReturnStatement,
|
ReturnStatement,
|
||||||
SketchGroup,
|
|
||||||
SourceRange,
|
SourceRange,
|
||||||
SyntaxType,
|
SyntaxType,
|
||||||
Expr,
|
Expr,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
VariableDeclarator,
|
VariableDeclarator,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
} from './wasm'
|
} from './wasm'
|
||||||
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
|
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
|
||||||
import { getSketchSegmentFromSourceRange } from './std/sketchConstraints'
|
import { getSketchSegmentFromSourceRange } from './std/sketchConstraints'
|
||||||
@ -661,15 +661,16 @@ export function isLinesParallelAndConstrained(
|
|||||||
if (err(_varDec)) return _varDec
|
if (err(_varDec)) return _varDec
|
||||||
const varDec = _varDec.node
|
const varDec = _varDec.node
|
||||||
const varName = (varDec as VariableDeclaration)?.declarations[0]?.id?.name
|
const varName = (varDec as VariableDeclaration)?.declarations[0]?.id?.name
|
||||||
const path = programMemory?.get(varName) as SketchGroup
|
const sg = sketchGroupFromKclValue(programMemory?.get(varName), varName)
|
||||||
|
if (err(sg)) return sg
|
||||||
const _primarySegment = getSketchSegmentFromSourceRange(
|
const _primarySegment = getSketchSegmentFromSourceRange(
|
||||||
path,
|
sg,
|
||||||
primaryLine.range
|
primaryLine.range
|
||||||
)
|
)
|
||||||
if (err(_primarySegment)) return _primarySegment
|
if (err(_primarySegment)) return _primarySegment
|
||||||
const primarySegment = _primarySegment.segment
|
const primarySegment = _primarySegment.segment
|
||||||
|
|
||||||
const _segment = getSketchSegmentFromSourceRange(path, secondaryLine.range)
|
const _segment = getSketchSegmentFromSourceRange(sg, secondaryLine.range)
|
||||||
if (err(_segment)) return _segment
|
if (err(_segment)) return _segment
|
||||||
const { segment: secondarySegment, index: secondaryIndex } = _segment
|
const { segment: secondarySegment, index: secondaryIndex } = _segment
|
||||||
const primaryAngle = getAngle(primarySegment.from, primarySegment.to)
|
const primaryAngle = getAngle(primarySegment.from, primarySegment.to)
|
||||||
@ -708,9 +709,7 @@ export function isLinesParallelAndConstrained(
|
|||||||
constraintType === 'angle' || constraintLevel === 'full'
|
constraintType === 'angle' || constraintLevel === 'full'
|
||||||
|
|
||||||
// get the previous segment
|
// get the previous segment
|
||||||
const prevSegment = (programMemory.get(varName) as SketchGroup).value[
|
const prevSegment = sg.value[secondaryIndex - 1]
|
||||||
secondaryIndex - 1
|
|
||||||
]
|
|
||||||
const prevSourceRange = prevSegment.__geoMeta.sourceRange
|
const prevSourceRange = prevSegment.__geoMeta.sourceRange
|
||||||
|
|
||||||
const isParallelAndConstrained =
|
const isParallelAndConstrained =
|
||||||
@ -779,7 +778,10 @@ export function hasExtrudeSketchGroup({
|
|||||||
if (varDec.type !== 'VariableDeclaration') return false
|
if (varDec.type !== 'VariableDeclaration') return false
|
||||||
const varName = varDec.declarations[0].id.name
|
const varName = varDec.declarations[0].id.name
|
||||||
const varValue = programMemory?.get(varName)
|
const varValue = programMemory?.get(varName)
|
||||||
return varValue?.type === 'ExtrudeGroup' || varValue?.type === 'SketchGroup'
|
return (
|
||||||
|
varValue?.type === 'ExtrudeGroup' ||
|
||||||
|
!err(sketchGroupFromKclValue(varValue, varName))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isSingleCursorInPipe(
|
export function isSingleCursorInPipe(
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
Literal,
|
Literal,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
Identifier,
|
Identifier,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import {
|
import {
|
||||||
getNodeFromPath,
|
getNodeFromPath,
|
||||||
@ -1009,9 +1010,12 @@ export const angledLineOfXLength: SketchLineHelper = {
|
|||||||
const { node: varDec } = nodeMeta2
|
const { node: varDec } = nodeMeta2
|
||||||
|
|
||||||
const variableName = varDec.id.name
|
const variableName = varDec.id.name
|
||||||
const sketch = previousProgramMemory?.get(variableName)
|
const sketch = sketchGroupFromKclValue(
|
||||||
if (!sketch || sketch.type !== 'SketchGroup') {
|
previousProgramMemory?.get(variableName),
|
||||||
return new Error('not a SketchGroup')
|
variableName
|
||||||
|
)
|
||||||
|
if (err(sketch)) {
|
||||||
|
return sketch
|
||||||
}
|
}
|
||||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||||
const xLength = createLiteral(roundOff(Math.abs(from[0] - to[0]), 2) || 0.1)
|
const xLength = createLiteral(roundOff(Math.abs(from[0] - to[0]), 2) || 0.1)
|
||||||
@ -1105,10 +1109,11 @@ export const angledLineOfYLength: SketchLineHelper = {
|
|||||||
if (err(nodeMeta2)) return nodeMeta2
|
if (err(nodeMeta2)) return nodeMeta2
|
||||||
const { node: varDec } = nodeMeta2
|
const { node: varDec } = nodeMeta2
|
||||||
const variableName = varDec.id.name
|
const variableName = varDec.id.name
|
||||||
const sketch = previousProgramMemory?.get(variableName)
|
const sketch = sketchGroupFromKclValue(
|
||||||
if (!sketch || sketch.type !== 'SketchGroup') {
|
previousProgramMemory?.get(variableName),
|
||||||
return new Error('not a SketchGroup')
|
variableName
|
||||||
}
|
)
|
||||||
|
if (err(sketch)) return sketch
|
||||||
|
|
||||||
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
||||||
const yLength = createLiteral(roundOff(Math.abs(from[1] - to[1]), 2) || 0.1)
|
const yLength = createLiteral(roundOff(Math.abs(from[1] - to[1]), 2) || 0.1)
|
||||||
@ -1443,7 +1448,11 @@ export const angledLineThatIntersects: SketchLineHelper = {
|
|||||||
|
|
||||||
const { node: varDec } = nodeMeta2
|
const { node: varDec } = nodeMeta2
|
||||||
const varName = varDec.declarations[0].id.name
|
const varName = varDec.declarations[0].id.name
|
||||||
const sketchGroup = previousProgramMemory.get(varName) as SketchGroup
|
const sketchGroup = sketchGroupFromKclValue(
|
||||||
|
previousProgramMemory.get(varName),
|
||||||
|
varName
|
||||||
|
)
|
||||||
|
if (err(sketchGroup)) return sketchGroup
|
||||||
const intersectPath = sketchGroup.value.find(
|
const intersectPath = sketchGroup.value.find(
|
||||||
({ tag }: Path) => tag && tag.value === intersectTagName
|
({ tag }: Path) => tag && tag.value === intersectTagName
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import { parse, SketchGroup, recast, initPromise } from '../wasm'
|
import {
|
||||||
|
parse,
|
||||||
|
SketchGroup,
|
||||||
|
recast,
|
||||||
|
initPromise,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
|
} from '../wasm'
|
||||||
import {
|
import {
|
||||||
ConstraintType,
|
ConstraintType,
|
||||||
getTransformInfos,
|
getTransformInfos,
|
||||||
@ -362,10 +368,11 @@ const part001 = startSketchOn('XY')
|
|||||||
it('normal case works', async () => {
|
it('normal case works', async () => {
|
||||||
const programMemory = await enginelessExecutor(parse(code))
|
const programMemory = await enginelessExecutor(parse(code))
|
||||||
const index = code.indexOf('// normal-segment') - 7
|
const index = code.indexOf('// normal-segment') - 7
|
||||||
const _segment = getSketchSegmentFromSourceRange(
|
const sg = sketchGroupFromKclValue(
|
||||||
programMemory.get('part001') as SketchGroup,
|
programMemory.get('part001'),
|
||||||
[index, index]
|
'part001'
|
||||||
)
|
) as SketchGroup
|
||||||
|
const _segment = getSketchSegmentFromSourceRange(sg, [index, index])
|
||||||
if (err(_segment)) throw _segment
|
if (err(_segment)) throw _segment
|
||||||
const { __geoMeta, ...segment } = _segment.segment
|
const { __geoMeta, ...segment } = _segment.segment
|
||||||
expect(segment).toEqual({
|
expect(segment).toEqual({
|
||||||
@ -379,7 +386,10 @@ const part001 = startSketchOn('XY')
|
|||||||
const programMemory = await enginelessExecutor(parse(code))
|
const programMemory = await enginelessExecutor(parse(code))
|
||||||
const index = code.indexOf('// segment-in-start') - 7
|
const index = code.indexOf('// segment-in-start') - 7
|
||||||
const _segment = getSketchSegmentFromSourceRange(
|
const _segment = getSketchSegmentFromSourceRange(
|
||||||
programMemory.get('part001') as SketchGroup,
|
sketchGroupFromKclValue(
|
||||||
|
programMemory.get('part001'),
|
||||||
|
'part001'
|
||||||
|
) as SketchGroup,
|
||||||
[index, index]
|
[index, index]
|
||||||
)
|
)
|
||||||
if (err(_segment)) throw _segment
|
if (err(_segment)) throw _segment
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
VariableDeclarator,
|
VariableDeclarator,
|
||||||
PathToNode,
|
PathToNode,
|
||||||
ProgramMemory,
|
ProgramMemory,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
} from '../wasm'
|
} from '../wasm'
|
||||||
import {
|
import {
|
||||||
getNodeFromPath,
|
getNodeFromPath,
|
||||||
@ -1636,12 +1637,16 @@ export function transformAstSketchLines({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const varName = varDec.node.id.name
|
const varName = varDec.node.id.name
|
||||||
let sketchGroup = programMemory.get(varName)
|
let kclVal = programMemory.get(varName)
|
||||||
if (sketchGroup?.type === 'ExtrudeGroup') {
|
let sketchGroup
|
||||||
sketchGroup = sketchGroup.sketchGroup
|
if (kclVal?.type === 'ExtrudeGroup') {
|
||||||
|
sketchGroup = kclVal.sketchGroup
|
||||||
|
} else {
|
||||||
|
sketchGroup = sketchGroupFromKclValue(kclVal, varName)
|
||||||
|
if (err(sketchGroup)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!sketchGroup || sketchGroup.type !== 'SketchGroup')
|
|
||||||
return new Error('not a sketch group')
|
|
||||||
const segMeta = getSketchSegmentFromPathToNode(
|
const segMeta = getSketchSegmentFromPathToNode(
|
||||||
sketchGroup,
|
sketchGroup,
|
||||||
ast,
|
ast,
|
||||||
|
@ -38,6 +38,7 @@ import { err } from 'lib/trap'
|
|||||||
import { Configuration } from 'wasm-lib/kcl/bindings/Configuration'
|
import { Configuration } from 'wasm-lib/kcl/bindings/Configuration'
|
||||||
import { DeepPartial } from 'lib/types'
|
import { DeepPartial } from 'lib/types'
|
||||||
import { ProjectConfiguration } from 'wasm-lib/kcl/bindings/ProjectConfiguration'
|
import { ProjectConfiguration } from 'wasm-lib/kcl/bindings/ProjectConfiguration'
|
||||||
|
import { SketchGroup } from '../wasm-lib/kcl/bindings/SketchGroup'
|
||||||
|
|
||||||
export type { Program } from '../wasm-lib/kcl/bindings/Program'
|
export type { Program } from '../wasm-lib/kcl/bindings/Program'
|
||||||
export type { Expr } from '../wasm-lib/kcl/bindings/Expr'
|
export type { Expr } from '../wasm-lib/kcl/bindings/Expr'
|
||||||
@ -126,6 +127,7 @@ export const parse = (code: string | Error): Program | Error => {
|
|||||||
const program: Program = parse_wasm(code)
|
const program: Program = parse_wasm(code)
|
||||||
return program
|
return program
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
// throw e
|
||||||
const parsed: RustKclError = JSON.parse(e.toString())
|
const parsed: RustKclError = JSON.parse(e.toString())
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.kind,
|
parsed.kind,
|
||||||
@ -312,7 +314,7 @@ export class ProgramMemory {
|
|||||||
*/
|
*/
|
||||||
hasSketchOrExtrudeGroup(): boolean {
|
hasSketchOrExtrudeGroup(): boolean {
|
||||||
for (const node of this.visibleEntries().values()) {
|
for (const node of this.visibleEntries().values()) {
|
||||||
if (node.type === 'ExtrudeGroup' || node.type === 'SketchGroup') {
|
if (node.type === 'ExtrudeGroup' || node.value?.type === 'SketchGroup') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,6 +334,25 @@ export class ProgramMemory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: In the future, make the parameter be a KclValue.
|
||||||
|
export function sketchGroupFromKclValue(
|
||||||
|
obj: any,
|
||||||
|
varName: string | null
|
||||||
|
): SketchGroup | Error {
|
||||||
|
if (obj?.value?.type === 'SketchGroup') return obj.value
|
||||||
|
if (!varName) {
|
||||||
|
varName = 'a KCL value'
|
||||||
|
}
|
||||||
|
const actualType = obj?.value?.type ?? obj?.type
|
||||||
|
if (actualType) {
|
||||||
|
return new Error(
|
||||||
|
`Expected ${varName} to be a sketchGroup, but it was ${actualType} instead.`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return new Error(`Expected ${varName} to be a sketchGroup, but it wasn't.`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const executor = async (
|
export const executor = async (
|
||||||
node: Program,
|
node: Program,
|
||||||
programMemory: ProgramMemory | Error = ProgramMemory.empty(),
|
programMemory: ProgramMemory | Error = ProgramMemory.empty(),
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
VariableDeclarator,
|
VariableDeclarator,
|
||||||
parse,
|
parse,
|
||||||
recast,
|
recast,
|
||||||
|
sketchGroupFromKclValue,
|
||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import { Axis, Selection, Selections, updateSelections } from 'lib/selections'
|
import { Axis, Selection, Selections, updateSelections } from 'lib/selections'
|
||||||
import { assign, createMachine } from 'xstate'
|
import { assign, createMachine } from 'xstate'
|
||||||
@ -1187,8 +1188,11 @@ export const modelingMachine = createMachine(
|
|||||||
)
|
)
|
||||||
if (err(varDecNode)) return
|
if (err(varDecNode)) return
|
||||||
const sketchVar = varDecNode.node.declarations[0].id.name
|
const sketchVar = varDecNode.node.declarations[0].id.name
|
||||||
const sketchGroup = kclManager.programMemory.get(sketchVar)
|
const sketchGroup = sketchGroupFromKclValue(
|
||||||
if (sketchGroup?.type !== 'SketchGroup') return
|
kclManager.programMemory.get(sketchVar),
|
||||||
|
sketchVar
|
||||||
|
)
|
||||||
|
if (trap(sketchGroup)) return
|
||||||
const extrusion = getExtrusionFromSuspectedPath(
|
const extrusion = getExtrusionFromSuspectedPath(
|
||||||
sketchGroup.id,
|
sketchGroup.id,
|
||||||
engineCommandManager.artifactGraph
|
engineCommandManager.artifactGraph
|
||||||
|
@ -23,7 +23,7 @@ use crate::{
|
|||||||
docs::StdLibFn,
|
docs::StdLibFn,
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
executor::{
|
executor::{
|
||||||
BodyType, DynamicState, ExecutorContext, KclValue, Metadata, PipeInfo, ProgramMemory, SourceRange,
|
BodyType, DynamicState, ExecutorContext, KclValue, Metadata, PipeInfo, ProgramMemory, SketchGroup, SourceRange,
|
||||||
StatementKind, TagEngineInfo, TagIdentifier, UserVal,
|
StatementKind, TagEngineInfo, TagIdentifier, UserVal,
|
||||||
},
|
},
|
||||||
parser::PIPE_OPERATOR,
|
parser::PIPE_OPERATOR,
|
||||||
@ -1377,10 +1377,13 @@ impl CallExpression {
|
|||||||
// TODO: This could probably be done in a better way, but as of now this was my only idea
|
// TODO: This could probably be done in a better way, but as of now this was my only idea
|
||||||
// and it works.
|
// and it works.
|
||||||
match result {
|
match result {
|
||||||
KclValue::SketchGroup(ref sketch_group) => {
|
KclValue::UserVal(ref mut uval) => {
|
||||||
|
uval.mutate(|sketch_group: &mut SketchGroup| {
|
||||||
for (_, tag) in sketch_group.tags.iter() {
|
for (_, tag) in sketch_group.tags.iter() {
|
||||||
memory.update_tag(&tag.value, tag.clone())?;
|
memory.update_tag(&tag.value, tag.clone())?;
|
||||||
}
|
}
|
||||||
|
Ok::<_, KclError>(())
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
KclValue::ExtrudeGroup(ref mut extrude_group) => {
|
KclValue::ExtrudeGroup(ref mut extrude_group) => {
|
||||||
for value in &extrude_group.value {
|
for value in &extrude_group.value {
|
||||||
|
@ -203,13 +203,22 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (_, val) in self.bindings.iter_mut() {
|
for (_, val) in self.bindings.iter_mut() {
|
||||||
if let KclValue::SketchGroup(ref mut sketch_group) = val {
|
let KclValue::UserVal(v) = val else { continue };
|
||||||
|
let meta = v.meta.clone();
|
||||||
|
let maybe_sg: Result<SketchGroup, _> = serde_json::from_value(v.value.clone());
|
||||||
|
let Ok(mut sketch_group) = maybe_sg else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
if sketch_group.original_id == sg.original_id {
|
if sketch_group.original_id == sg.original_id {
|
||||||
for tag in sg.tags.iter() {
|
for tag in sg.tags.iter() {
|
||||||
sketch_group.tags.insert(tag.0.clone(), tag.1.clone());
|
sketch_group.tags.insert(tag.0.clone(), tag.1.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
*val = KclValue::UserVal(UserVal {
|
||||||
|
meta,
|
||||||
|
value: serde_json::to_value(sketch_group).expect("can always turn SketchGroup into JSON"),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,10 +277,7 @@ pub enum KclValue {
|
|||||||
TagDeclarator(Box<TagDeclarator>),
|
TagDeclarator(Box<TagDeclarator>),
|
||||||
Plane(Box<Plane>),
|
Plane(Box<Plane>),
|
||||||
Face(Box<Face>),
|
Face(Box<Face>),
|
||||||
SketchGroup(Box<SketchGroup>),
|
|
||||||
SketchGroups {
|
|
||||||
value: Vec<Box<SketchGroup>>,
|
|
||||||
},
|
|
||||||
ExtrudeGroup(Box<ExtrudeGroup>),
|
ExtrudeGroup(Box<ExtrudeGroup>),
|
||||||
ExtrudeGroups {
|
ExtrudeGroups {
|
||||||
value: Vec<Box<ExtrudeGroup>>,
|
value: Vec<Box<ExtrudeGroup>>,
|
||||||
@ -289,27 +295,8 @@ pub enum KclValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KclValue {
|
impl KclValue {
|
||||||
pub(crate) fn get_sketch_group_set(&self) -> Result<SketchGroupSet> {
|
pub(crate) fn new_user_val<T: Serialize>(meta: Vec<Metadata>, val: T) -> Self {
|
||||||
match self {
|
Self::UserVal(UserVal::set(meta, val))
|
||||||
KclValue::SketchGroup(s) => Ok(SketchGroupSet::SketchGroup(s.clone())),
|
|
||||||
KclValue::SketchGroups { value } => Ok(SketchGroupSet::SketchGroups(value.clone())),
|
|
||||||
KclValue::UserVal(value) => {
|
|
||||||
let value = value.value.clone();
|
|
||||||
match value {
|
|
||||||
JValue::Null | JValue::Bool(_) | JValue::Number(_) | JValue::String(_) => Err(anyhow::anyhow!(
|
|
||||||
"Failed to deserialize sketch group set from JSON {}",
|
|
||||||
human_friendly_type(&value)
|
|
||||||
)),
|
|
||||||
JValue::Array(_) => serde_json::from_value::<Vec<Box<SketchGroup>>>(value)
|
|
||||||
.map(SketchGroupSet::from)
|
|
||||||
.map_err(|e| anyhow::anyhow!("Failed to deserialize array of sketch groups from JSON: {}", e)),
|
|
||||||
JValue::Object(_) => serde_json::from_value::<Box<SketchGroup>>(value)
|
|
||||||
.map(SketchGroupSet::from)
|
|
||||||
.map_err(|e| anyhow::anyhow!("Failed to deserialize sketch group from JSON: {}", e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => anyhow::bail!("Not a sketch group or sketch groups: {:?}", self),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_extrude_group_set(&self) -> Result<ExtrudeGroupSet> {
|
pub(crate) fn get_extrude_group_set(&self) -> Result<ExtrudeGroupSet> {
|
||||||
@ -342,8 +329,6 @@ impl KclValue {
|
|||||||
KclValue::UserVal(u) => human_friendly_type(&u.value),
|
KclValue::UserVal(u) => human_friendly_type(&u.value),
|
||||||
KclValue::TagDeclarator(_) => "TagDeclarator",
|
KclValue::TagDeclarator(_) => "TagDeclarator",
|
||||||
KclValue::TagIdentifier(_) => "TagIdentifier",
|
KclValue::TagIdentifier(_) => "TagIdentifier",
|
||||||
KclValue::SketchGroup(_) => "SketchGroup",
|
|
||||||
KclValue::SketchGroups { .. } => "SketchGroups",
|
|
||||||
KclValue::ExtrudeGroup(_) => "ExtrudeGroup",
|
KclValue::ExtrudeGroup(_) => "ExtrudeGroup",
|
||||||
KclValue::ExtrudeGroups { .. } => "ExtrudeGroups",
|
KclValue::ExtrudeGroups { .. } => "ExtrudeGroups",
|
||||||
KclValue::ImportedGeometry(_) => "ImportedGeometry",
|
KclValue::ImportedGeometry(_) => "ImportedGeometry",
|
||||||
@ -356,20 +341,14 @@ impl KclValue {
|
|||||||
|
|
||||||
impl From<SketchGroupSet> for KclValue {
|
impl From<SketchGroupSet> for KclValue {
|
||||||
fn from(sg: SketchGroupSet) -> Self {
|
fn from(sg: SketchGroupSet) -> Self {
|
||||||
match sg {
|
KclValue::UserVal(UserVal::set(sg.meta(), sg))
|
||||||
SketchGroupSet::SketchGroup(sg) => KclValue::SketchGroup(sg),
|
|
||||||
SketchGroupSet::SketchGroups(sgs) => KclValue::SketchGroups { value: sgs },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Box<SketchGroup>>> for KclValue {
|
impl From<Vec<Box<SketchGroup>>> for KclValue {
|
||||||
fn from(sg: Vec<Box<SketchGroup>>) -> Self {
|
fn from(sg: Vec<Box<SketchGroup>>) -> Self {
|
||||||
if sg.len() == 1 {
|
let meta = sg.iter().flat_map(|sg| sg.meta.clone()).collect();
|
||||||
KclValue::SketchGroup(sg[0].clone())
|
KclValue::UserVal(UserVal::set(meta, sg))
|
||||||
} else {
|
|
||||||
KclValue::SketchGroups { value: sg }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,6 +407,24 @@ pub enum SketchGroupSet {
|
|||||||
SketchGroups(Vec<Box<SketchGroup>>),
|
SketchGroups(Vec<Box<SketchGroup>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SketchGroupSet {
|
||||||
|
pub fn meta(&self) -> Vec<Metadata> {
|
||||||
|
match self {
|
||||||
|
SketchGroupSet::SketchGroup(sg) => sg.meta.clone(),
|
||||||
|
SketchGroupSet::SketchGroups(sg) => sg.iter().flat_map(|sg| sg.meta.clone()).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SketchGroupSet> for Vec<SketchGroup> {
|
||||||
|
fn from(value: SketchGroupSet) -> Self {
|
||||||
|
match value {
|
||||||
|
SketchGroupSet::SketchGroup(sg) => vec![*sg],
|
||||||
|
SketchGroupSet::SketchGroups(sgs) => sgs.into_iter().map(|sg| *sg).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<SketchGroup> for SketchGroupSet {
|
impl From<SketchGroup> for SketchGroupSet {
|
||||||
fn from(sg: SketchGroup) -> Self {
|
fn from(sg: SketchGroup) -> Self {
|
||||||
SketchGroupSet::SketchGroup(Box::new(sg))
|
SketchGroupSet::SketchGroup(Box::new(sg))
|
||||||
@ -641,6 +638,43 @@ pub struct UserVal {
|
|||||||
pub meta: Vec<Metadata>,
|
pub meta: Vec<Metadata>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UserVal {
|
||||||
|
/// If the UserVal matches the type `T`, return it.
|
||||||
|
pub fn get<T: serde::de::DeserializeOwned>(&self) -> Option<(T, Vec<Metadata>)> {
|
||||||
|
let meta = self.meta.clone();
|
||||||
|
// TODO: This clone might cause performance problems, it'll happen a lot.
|
||||||
|
let res: Result<T, _> = serde_json::from_value(self.value.clone());
|
||||||
|
if let Ok(t) = res {
|
||||||
|
Some((t, meta))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the UserVal matches the type `T`, then mutate it via the given closure.
|
||||||
|
/// If the closure returns Err, the mutation won't be applied.
|
||||||
|
pub fn mutate<T, F, E>(&mut self, mutate: F) -> Result<(), E>
|
||||||
|
where
|
||||||
|
T: serde::de::DeserializeOwned + Serialize,
|
||||||
|
F: FnOnce(&mut T) -> Result<(), E>,
|
||||||
|
{
|
||||||
|
let Some((mut val, meta)) = self.get::<T>() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
mutate(&mut val)?;
|
||||||
|
*self = Self::set(meta, val);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Put the given value into this UserVal.
|
||||||
|
pub fn set<T: serde::Serialize>(meta: Vec<Metadata>, val: T) -> Self {
|
||||||
|
Self {
|
||||||
|
meta,
|
||||||
|
value: serde_json::to_value(val).expect("all KCL values should be compatible with JSON"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(tag = "type", rename_all = "camelCase")]
|
#[serde(tag = "type", rename_all = "camelCase")]
|
||||||
@ -720,11 +754,6 @@ impl From<KclValue> for Vec<SourceRange> {
|
|||||||
KclValue::UserVal(u) => u.meta.iter().map(|m| m.source_range).collect(),
|
KclValue::UserVal(u) => u.meta.iter().map(|m| m.source_range).collect(),
|
||||||
KclValue::TagDeclarator(t) => t.into(),
|
KclValue::TagDeclarator(t) => t.into(),
|
||||||
KclValue::TagIdentifier(t) => t.meta.iter().map(|m| m.source_range).collect(),
|
KclValue::TagIdentifier(t) => t.meta.iter().map(|m| m.source_range).collect(),
|
||||||
KclValue::SketchGroup(s) => s.meta.iter().map(|m| m.source_range).collect(),
|
|
||||||
KclValue::SketchGroups { value } => value
|
|
||||||
.iter()
|
|
||||||
.flat_map(|sg| sg.meta.iter().map(|m| m.source_range))
|
|
||||||
.collect(),
|
|
||||||
KclValue::ExtrudeGroup(e) => e.meta.iter().map(|m| m.source_range).collect(),
|
KclValue::ExtrudeGroup(e) => e.meta.iter().map(|m| m.source_range).collect(),
|
||||||
KclValue::ExtrudeGroups { value } => value
|
KclValue::ExtrudeGroups { value } => value
|
||||||
.iter()
|
.iter()
|
||||||
@ -1274,7 +1303,7 @@ impl Point2d {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, ts_rs::TS, JsonSchema, Default)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct Point3d {
|
pub struct Point3d {
|
||||||
pub x: f64,
|
pub x: f64,
|
||||||
@ -2085,6 +2114,39 @@ mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn how_does_sketchgroup_serialize() {
|
||||||
|
let sg = SketchGroup {
|
||||||
|
id: uuid::Uuid::new_v4(),
|
||||||
|
value: vec![],
|
||||||
|
on: SketchSurface::Plane(Box::new(Plane {
|
||||||
|
id: uuid::Uuid::new_v4(),
|
||||||
|
value: PlaneType::XY,
|
||||||
|
origin: Point3d::default(),
|
||||||
|
x_axis: Point3d::default(),
|
||||||
|
y_axis: Point3d::default(),
|
||||||
|
z_axis: Point3d::default(),
|
||||||
|
meta: Vec::new(),
|
||||||
|
})),
|
||||||
|
start: BasePath {
|
||||||
|
from: [0.0, 0.0],
|
||||||
|
to: [0.0, 0.0],
|
||||||
|
tag: None,
|
||||||
|
geo_meta: GeoMeta {
|
||||||
|
id: uuid::Uuid::new_v4(),
|
||||||
|
metadata: Metadata {
|
||||||
|
source_range: SourceRange([0, 0]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tags: HashMap::new(),
|
||||||
|
original_id: uuid::Uuid::new_v4(),
|
||||||
|
meta: Vec::new(),
|
||||||
|
};
|
||||||
|
let jstr = serde_json::to_string_pretty(&sg).unwrap();
|
||||||
|
println!("{jstr}");
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_execute_assign_two_variables() {
|
async fn test_execute_assign_two_variables() {
|
||||||
let ast = r#"const myVar = 5
|
let ast = r#"const myVar = 5
|
||||||
|
@ -251,11 +251,11 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_sketch_groups(&self) -> Result<(SketchGroupSet, Box<SketchGroup>), KclError> {
|
pub(crate) fn get_sketch_groups(&self) -> Result<(SketchGroupSet, SketchGroup), KclError> {
|
||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_sketch_group(&self) -> Result<Box<SketchGroup>, KclError> {
|
pub(crate) fn get_sketch_group(&self) -> Result<SketchGroup, KclError> {
|
||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,9 +270,7 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_sketch_group_and_optional_tag(
|
pub(crate) fn get_sketch_group_and_optional_tag(&self) -> Result<(SketchGroup, Option<TagDeclarator>), KclError> {
|
||||||
&self,
|
|
||||||
) -> Result<(Box<SketchGroup>, Option<TagDeclarator>), KclError> {
|
|
||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +281,7 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_data_and_sketch_group<'a, T>(&'a self) -> Result<(T, Box<SketchGroup>), KclError>
|
pub(crate) fn get_data_and_sketch_group<'a, T>(&'a self) -> Result<(T, SketchGroup), KclError>
|
||||||
where
|
where
|
||||||
T: serde::de::DeserializeOwned + FromArgs<'a>,
|
T: serde::de::DeserializeOwned + FromArgs<'a>,
|
||||||
{
|
{
|
||||||
@ -299,7 +297,7 @@ impl Args {
|
|||||||
|
|
||||||
pub(crate) fn get_data_and_sketch_group_and_tag<'a, T>(
|
pub(crate) fn get_data_and_sketch_group_and_tag<'a, T>(
|
||||||
&'a self,
|
&'a self,
|
||||||
) -> Result<(T, Box<SketchGroup>, Option<TagDeclarator>), KclError>
|
) -> Result<(T, SketchGroup, Option<TagDeclarator>), KclError>
|
||||||
where
|
where
|
||||||
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
||||||
{
|
{
|
||||||
@ -338,7 +336,7 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_tag_to_number_sketch_group(&self) -> Result<(TagIdentifier, f64, Box<SketchGroup>), KclError> {
|
pub(crate) fn get_tag_to_number_sketch_group(&self) -> Result<(TagIdentifier, f64, SketchGroup), KclError> {
|
||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,15 +548,6 @@ impl<'a> FromKclValue<'a> for TagIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for &'a SketchGroup {
|
|
||||||
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
|
||||||
let KclValue::SketchGroup(s) = arg else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(s.as_ref())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_from_arg_via_json {
|
macro_rules! impl_from_arg_via_json {
|
||||||
($typ:path) => {
|
($typ:path) => {
|
||||||
impl<'a> FromKclValue<'a> for $typ {
|
impl<'a> FromKclValue<'a> for $typ {
|
||||||
@ -608,6 +597,7 @@ impl_from_arg_via_json!(super::revolve::RevolveData);
|
|||||||
impl_from_arg_via_json!(super::sketch::SketchData);
|
impl_from_arg_via_json!(super::sketch::SketchData);
|
||||||
impl_from_arg_via_json!(crate::std::import::ImportFormat);
|
impl_from_arg_via_json!(crate::std::import::ImportFormat);
|
||||||
impl_from_arg_via_json!(crate::std::polar::PolarCoordsData);
|
impl_from_arg_via_json!(crate::std::polar::PolarCoordsData);
|
||||||
|
impl_from_arg_via_json!(SketchGroup);
|
||||||
impl_from_arg_via_json!(FaceTag);
|
impl_from_arg_via_json!(FaceTag);
|
||||||
impl_from_arg_via_json!(String);
|
impl_from_arg_via_json!(String);
|
||||||
impl_from_arg_via_json!(u32);
|
impl_from_arg_via_json!(u32);
|
||||||
@ -618,21 +608,16 @@ impl_from_arg_via_json!(bool);
|
|||||||
impl_from_arg_for_array!(2);
|
impl_from_arg_for_array!(2);
|
||||||
impl_from_arg_for_array!(3);
|
impl_from_arg_for_array!(3);
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for &'a Box<SketchGroup> {
|
impl<'a> FromKclValue<'a> for SketchGroupSet {
|
||||||
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
||||||
let KclValue::SketchGroup(s) = arg else {
|
let KclValue::UserVal(uv) = arg else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(s)
|
if let Some((x, _meta)) = uv.get::<SketchGroup>() {
|
||||||
|
Some(SketchGroupSet::from(x))
|
||||||
|
} else {
|
||||||
|
uv.get::<Vec<SketchGroup>>().map(|x| x.0).map(SketchGroupSet::from)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for Box<SketchGroup> {
|
|
||||||
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
|
||||||
let KclValue::SketchGroup(s) = arg else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(s.to_owned())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,15 +641,16 @@ impl<'a> FromKclValue<'a> for ExtrudeGroupSet {
|
|||||||
arg.get_extrude_group_set().ok()
|
arg.get_extrude_group_set().ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> FromKclValue<'a> for SketchGroupSet {
|
|
||||||
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
|
||||||
arg.get_sketch_group_set().ok()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> FromKclValue<'a> for SketchSurfaceOrGroup {
|
impl<'a> FromKclValue<'a> for SketchSurfaceOrGroup {
|
||||||
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
fn from_mem_item(arg: &'a KclValue) -> Option<Self> {
|
||||||
match arg {
|
match arg {
|
||||||
KclValue::SketchGroup(sg) => Some(Self::SketchGroup(sg.clone())),
|
KclValue::UserVal(uv) => {
|
||||||
|
if let Some((sg, _meta)) = uv.get() {
|
||||||
|
Some(Self::SketchGroup(sg))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
KclValue::Plane(sg) => Some(Self::SketchSurface(SketchSurface::Plane(sg.clone()))),
|
KclValue::Plane(sg) => Some(Self::SketchSurface(SketchSurface::Plane(sg.clone()))),
|
||||||
KclValue::Face(sg) => Some(Self::SketchSurface(SketchSurface::Face(sg.clone()))),
|
KclValue::Face(sg) => Some(Self::SketchSurface(SketchSurface::Face(sg.clone()))),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -76,7 +76,7 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
|
|||||||
let id = uuid::Uuid::new_v4();
|
let id = uuid::Uuid::new_v4();
|
||||||
|
|
||||||
// Extrude the element(s).
|
// Extrude the element(s).
|
||||||
let sketch_groups: Vec<Box<SketchGroup>> = sketch_group_set.into();
|
let sketch_groups: Vec<SketchGroup> = sketch_group_set.into();
|
||||||
let mut extrude_groups = Vec::new();
|
let mut extrude_groups = Vec::new();
|
||||||
for sketch_group in &sketch_groups {
|
for sketch_group in &sketch_groups {
|
||||||
// Before we extrude, we need to enable the sketch mode.
|
// Before we extrude, we need to enable the sketch mode.
|
||||||
@ -118,7 +118,7 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn do_post_extrude(
|
pub(crate) async fn do_post_extrude(
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
length: f64,
|
length: f64,
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
args: Args,
|
args: Args,
|
||||||
@ -155,7 +155,7 @@ pub(crate) async fn do_post_extrude(
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut sketch_group = *sketch_group.clone();
|
let mut sketch_group = sketch_group.clone();
|
||||||
|
|
||||||
// If we were sketching on a face, we need the original face id.
|
// If we were sketching on a face, we need the original face id.
|
||||||
if let SketchSurface::Face(ref face) = sketch_group.on {
|
if let SketchSurface::Face(ref face) = sketch_group.on {
|
||||||
|
@ -102,7 +102,7 @@ impl RevolveAxisAndOrigin {
|
|||||||
|
|
||||||
/// Revolve a sketch around an axis.
|
/// Revolve a sketch around an axis.
|
||||||
pub async fn revolve(args: Args) -> Result<KclValue, KclError> {
|
pub async fn revolve(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group): (RevolveData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (RevolveData, SketchGroup) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let extrude_group = inner_revolve(data, sketch_group, args).await?;
|
let extrude_group = inner_revolve(data, sketch_group, args).await?;
|
||||||
Ok(KclValue::ExtrudeGroup(extrude_group))
|
Ok(KclValue::ExtrudeGroup(extrude_group))
|
||||||
@ -249,7 +249,7 @@ pub async fn revolve(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_revolve(
|
async fn inner_revolve(
|
||||||
data: RevolveData,
|
data: RevolveData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<ExtrudeGroup>, KclError> {
|
) -> Result<Box<ExtrudeGroup>, KclError> {
|
||||||
if let Some(angle) = data.angle {
|
if let Some(angle) = data.angle {
|
||||||
|
@ -108,7 +108,7 @@ pub async fn last_segment_x(args: Args) -> Result<KclValue, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "lastSegX",
|
name = "lastSegX",
|
||||||
}]
|
}]
|
||||||
fn inner_last_segment_x(sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
fn inner_last_segment_x(sketch_group: SketchGroup, args: Args) -> Result<f64, KclError> {
|
||||||
let last_line = sketch_group
|
let last_line = sketch_group
|
||||||
.value
|
.value
|
||||||
.last()
|
.last()
|
||||||
@ -151,7 +151,7 @@ pub async fn last_segment_y(args: Args) -> Result<KclValue, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "lastSegY",
|
name = "lastSegY",
|
||||||
}]
|
}]
|
||||||
fn inner_last_segment_y(sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
fn inner_last_segment_y(sketch_group: SketchGroup, args: Args) -> Result<f64, KclError> {
|
||||||
let last_line = sketch_group
|
let last_line = sketch_group
|
||||||
.value
|
.value
|
||||||
.last()
|
.last()
|
||||||
@ -281,7 +281,7 @@ pub async fn angle_to_match_length_x(args: Args) -> Result<KclValue, KclError> {
|
|||||||
fn inner_angle_to_match_length_x(
|
fn inner_angle_to_match_length_x(
|
||||||
tag: &TagIdentifier,
|
tag: &TagIdentifier,
|
||||||
to: f64,
|
to: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<f64, KclError> {
|
) -> Result<f64, KclError> {
|
||||||
let line = args.get_tag_engine_info(tag)?;
|
let line = args.get_tag_engine_info(tag)?;
|
||||||
@ -347,7 +347,7 @@ pub async fn angle_to_match_length_y(args: Args) -> Result<KclValue, KclError> {
|
|||||||
fn inner_angle_to_match_length_y(
|
fn inner_angle_to_match_length_y(
|
||||||
tag: &TagIdentifier,
|
tag: &TagIdentifier,
|
||||||
to: f64,
|
to: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<f64, KclError> {
|
) -> Result<f64, KclError> {
|
||||||
let line = args.get_tag_engine_info(tag)?;
|
let line = args.get_tag_engine_info(tag)?;
|
||||||
|
@ -27,7 +27,7 @@ pub async fn circle(args: Args) -> Result<KclValue, KclError> {
|
|||||||
args.get_circle_args()?;
|
args.get_circle_args()?;
|
||||||
|
|
||||||
let sketch_group = inner_circle(center, radius, sketch_surface_or_group, tag, args).await?;
|
let sketch_group = inner_circle(center, radius, sketch_surface_or_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(sketch_group))
|
Ok(KclValue::new_user_val(sketch_group.meta.clone(), sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a 2-dimensional circle, of the specified radius, centered at
|
/// Construct a 2-dimensional circle, of the specified radius, centered at
|
||||||
@ -60,7 +60,7 @@ async fn inner_circle(
|
|||||||
sketch_surface_or_group: SketchSurfaceOrGroup,
|
sketch_surface_or_group: SketchSurfaceOrGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let sketch_surface = match sketch_surface_or_group {
|
let sketch_surface = match sketch_surface_or_group {
|
||||||
SketchSurfaceOrGroup::SketchSurface(surface) => surface,
|
SketchSurfaceOrGroup::SketchSurface(surface) => surface,
|
||||||
SketchSurfaceOrGroup::SketchGroup(group) => group.on,
|
SketchSurfaceOrGroup::SketchGroup(group) => group.on,
|
||||||
|
@ -90,11 +90,11 @@ pub enum StartOrEnd {
|
|||||||
|
|
||||||
/// Draw a line to a point.
|
/// Draw a line to a point.
|
||||||
pub async fn line_to(args: Args) -> Result<KclValue, KclError> {
|
pub async fn line_to(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (to, sketch_group, tag): ([f64; 2], Box<SketchGroup>, Option<TagDeclarator>) =
|
let (to, sketch_group, tag): ([f64; 2], SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to(to, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_line_to(to, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line from the current origin to some absolute (x, y) point.
|
/// Draw a line from the current origin to some absolute (x, y) point.
|
||||||
@ -114,10 +114,10 @@ pub async fn line_to(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_line_to(
|
async fn inner_line_to(
|
||||||
to: [f64; 2],
|
to: [f64; 2],
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
let id = uuid::Uuid::new_v4();
|
let id = uuid::Uuid::new_v4();
|
||||||
|
|
||||||
@ -161,11 +161,11 @@ async fn inner_line_to(
|
|||||||
|
|
||||||
/// Draw a line to a point on the x-axis.
|
/// Draw a line to a point on the x-axis.
|
||||||
pub async fn x_line_to(args: Args) -> Result<KclValue, KclError> {
|
pub async fn x_line_to(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (to, sketch_group, tag): (f64, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (to, sketch_group, tag): (f64, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_x_line_to(to, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_x_line_to(to, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line parallel to the X axis, that ends at the given X.
|
/// Draw a line parallel to the X axis, that ends at the given X.
|
||||||
@ -196,10 +196,10 @@ pub async fn x_line_to(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_x_line_to(
|
async fn inner_x_line_to(
|
||||||
to: f64,
|
to: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to([to, from.y], sketch_group, tag, args).await?;
|
let new_sketch_group = inner_line_to([to, from.y], sketch_group, tag, args).await?;
|
||||||
@ -209,11 +209,11 @@ async fn inner_x_line_to(
|
|||||||
|
|
||||||
/// Draw a line to a point on the y-axis.
|
/// Draw a line to a point on the y-axis.
|
||||||
pub async fn y_line_to(args: Args) -> Result<KclValue, KclError> {
|
pub async fn y_line_to(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (to, sketch_group, tag): (f64, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (to, sketch_group, tag): (f64, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_y_line_to(to, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_y_line_to(to, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line parallel to the Y axis, that ends at the given Y.
|
/// Draw a line parallel to the Y axis, that ends at the given Y.
|
||||||
@ -237,10 +237,10 @@ pub async fn y_line_to(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_y_line_to(
|
async fn inner_y_line_to(
|
||||||
to: f64,
|
to: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to([from.x, to], sketch_group, tag, args).await?;
|
let new_sketch_group = inner_line_to([from.x, to], sketch_group, tag, args).await?;
|
||||||
@ -249,11 +249,11 @@ async fn inner_y_line_to(
|
|||||||
|
|
||||||
/// Draw a line.
|
/// Draw a line.
|
||||||
pub async fn line(args: Args) -> Result<KclValue, KclError> {
|
pub async fn line(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (delta, sketch_group, tag): ([f64; 2], Box<SketchGroup>, Option<TagDeclarator>) =
|
let (delta, sketch_group, tag): ([f64; 2], SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_line(delta, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_line(delta, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line relative to the current origin to a specified (x, y) away
|
/// Draw a line relative to the current origin to a specified (x, y) away
|
||||||
@ -285,10 +285,10 @@ pub async fn line(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_line(
|
async fn inner_line(
|
||||||
delta: [f64; 2],
|
delta: [f64; 2],
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
let to = [from.x + delta[0], from.y + delta[1]];
|
let to = [from.x + delta[0], from.y + delta[1]];
|
||||||
|
|
||||||
@ -334,11 +334,11 @@ async fn inner_line(
|
|||||||
|
|
||||||
/// Draw a line on the x-axis.
|
/// Draw a line on the x-axis.
|
||||||
pub async fn x_line(args: Args) -> Result<KclValue, KclError> {
|
pub async fn x_line(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (length, sketch_group, tag): (f64, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (length, sketch_group, tag): (f64, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_x_line(length, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_x_line(length, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line relative to the current origin to a specified distance away
|
/// Draw a line relative to the current origin to a specified distance away
|
||||||
@ -368,20 +368,20 @@ pub async fn x_line(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_x_line(
|
async fn inner_x_line(
|
||||||
length: f64,
|
length: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
inner_line([length, 0.0], sketch_group, tag, args).await
|
inner_line([length, 0.0], sketch_group, tag, args).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line on the y-axis.
|
/// Draw a line on the y-axis.
|
||||||
pub async fn y_line(args: Args) -> Result<KclValue, KclError> {
|
pub async fn y_line(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (length, sketch_group, tag): (f64, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (length, sketch_group, tag): (f64, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_y_line(length, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_y_line(length, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line relative to the current origin to a specified distance away
|
/// Draw a line relative to the current origin to a specified distance away
|
||||||
@ -406,10 +406,10 @@ pub async fn y_line(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_y_line(
|
async fn inner_y_line(
|
||||||
length: f64,
|
length: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
inner_line([0.0, length], sketch_group, tag, args).await
|
inner_line([0.0, length], sketch_group, tag, args).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,11 +431,11 @@ pub enum AngledLineData {
|
|||||||
|
|
||||||
/// Draw an angled line.
|
/// Draw an angled line.
|
||||||
pub async fn angled_line(args: Args) -> Result<KclValue, KclError> {
|
pub async fn angled_line(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (AngledLineData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (AngledLineData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_angled_line(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line segment relative to the current origin using the polar
|
/// Draw a line segment relative to the current origin using the polar
|
||||||
@ -460,10 +460,10 @@ pub async fn angled_line(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_angled_line(
|
async fn inner_angled_line(
|
||||||
data: AngledLineData,
|
data: AngledLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
let (angle, length) = match data {
|
let (angle, length) = match data {
|
||||||
AngledLineData::AngleAndLengthNamed { angle, length } => (angle, length),
|
AngledLineData::AngleAndLengthNamed { angle, length } => (angle, length),
|
||||||
@ -520,11 +520,11 @@ async fn inner_angled_line(
|
|||||||
|
|
||||||
/// Draw an angled line of a given x length.
|
/// Draw an angled line of a given x length.
|
||||||
pub async fn angled_line_of_x_length(args: Args) -> Result<KclValue, KclError> {
|
pub async fn angled_line_of_x_length(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (AngledLineData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (AngledLineData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_of_x_length(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_angled_line_of_x_length(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a line segment from the current 2-dimensional sketch origin
|
/// Create a line segment from the current 2-dimensional sketch origin
|
||||||
@ -545,10 +545,10 @@ pub async fn angled_line_of_x_length(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_angled_line_of_x_length(
|
async fn inner_angled_line_of_x_length(
|
||||||
data: AngledLineData,
|
data: AngledLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let (angle, length) = match data {
|
let (angle, length) = match data {
|
||||||
AngledLineData::AngleAndLengthNamed { angle, length } => (angle, length),
|
AngledLineData::AngleAndLengthNamed { angle, length } => (angle, length),
|
||||||
AngledLineData::AngleAndLengthPair(pair) => (pair[0], pair[1]),
|
AngledLineData::AngleAndLengthPair(pair) => (pair[0], pair[1]),
|
||||||
@ -588,11 +588,11 @@ pub struct AngledLineToData {
|
|||||||
|
|
||||||
/// Draw an angled line to a given x coordinate.
|
/// Draw an angled line to a given x coordinate.
|
||||||
pub async fn angled_line_to_x(args: Args) -> Result<KclValue, KclError> {
|
pub async fn angled_line_to_x(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (AngledLineToData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (AngledLineToData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_to_x(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_angled_line_to_x(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a line segment from the current 2-dimensional sketch origin
|
/// Create a line segment from the current 2-dimensional sketch origin
|
||||||
@ -614,10 +614,10 @@ pub async fn angled_line_to_x(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_angled_line_to_x(
|
async fn inner_angled_line_to_x(
|
||||||
data: AngledLineToData,
|
data: AngledLineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
let AngledLineToData { angle, to: x_to } = data;
|
let AngledLineToData { angle, to: x_to } = data;
|
||||||
|
|
||||||
@ -645,12 +645,12 @@ async fn inner_angled_line_to_x(
|
|||||||
|
|
||||||
/// Draw an angled line of a given y length.
|
/// Draw an angled line of a given y length.
|
||||||
pub async fn angled_line_of_y_length(args: Args) -> Result<KclValue, KclError> {
|
pub async fn angled_line_of_y_length(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (AngledLineData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (AngledLineData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_of_y_length(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_angled_line_of_y_length(data, sketch_group, tag, args).await?;
|
||||||
|
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a line segment from the current 2-dimensional sketch origin
|
/// Create a line segment from the current 2-dimensional sketch origin
|
||||||
@ -673,10 +673,10 @@ pub async fn angled_line_of_y_length(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_angled_line_of_y_length(
|
async fn inner_angled_line_of_y_length(
|
||||||
data: AngledLineData,
|
data: AngledLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let (angle, length) = match data {
|
let (angle, length) = match data {
|
||||||
AngledLineData::AngleAndLengthNamed { angle, length } => (angle, length),
|
AngledLineData::AngleAndLengthNamed { angle, length } => (angle, length),
|
||||||
AngledLineData::AngleAndLengthPair(pair) => (pair[0], pair[1]),
|
AngledLineData::AngleAndLengthPair(pair) => (pair[0], pair[1]),
|
||||||
@ -705,11 +705,11 @@ async fn inner_angled_line_of_y_length(
|
|||||||
|
|
||||||
/// Draw an angled line to a given y coordinate.
|
/// Draw an angled line to a given y coordinate.
|
||||||
pub async fn angled_line_to_y(args: Args) -> Result<KclValue, KclError> {
|
pub async fn angled_line_to_y(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (AngledLineToData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (AngledLineToData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_to_y(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_angled_line_to_y(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a line segment from the current 2-dimensional sketch origin
|
/// Create a line segment from the current 2-dimensional sketch origin
|
||||||
@ -731,10 +731,10 @@ pub async fn angled_line_to_y(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_angled_line_to_y(
|
async fn inner_angled_line_to_y(
|
||||||
data: AngledLineToData,
|
data: AngledLineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
let AngledLineToData { angle, to: y_to } = data;
|
let AngledLineToData { angle, to: y_to } = data;
|
||||||
|
|
||||||
@ -776,10 +776,10 @@ pub struct AngledLineThatIntersectsData {
|
|||||||
|
|
||||||
/// Draw an angled line that intersects with a given line.
|
/// Draw an angled line that intersects with a given line.
|
||||||
pub async fn angled_line_that_intersects(args: Args) -> Result<KclValue, KclError> {
|
pub async fn angled_line_that_intersects(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (AngledLineThatIntersectsData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (AngledLineThatIntersectsData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
let new_sketch_group = inner_angled_line_that_intersects(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_angled_line_that_intersects(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line from the current origin, constructing a line segment
|
/// Draw an angled line from the current origin, constructing a line segment
|
||||||
@ -806,10 +806,10 @@ pub async fn angled_line_that_intersects(args: Args) -> Result<KclValue, KclErro
|
|||||||
}]
|
}]
|
||||||
async fn inner_angled_line_that_intersects(
|
async fn inner_angled_line_that_intersects(
|
||||||
data: AngledLineThatIntersectsData,
|
data: AngledLineThatIntersectsData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let intersect_path = args.get_tag_engine_info(&data.intersect_tag)?;
|
let intersect_path = args.get_tag_engine_info(&data.intersect_tag)?;
|
||||||
let path = intersect_path.path.clone().ok_or_else(|| {
|
let path = intersect_path.path.clone().ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
@ -835,7 +835,7 @@ pub async fn start_sketch_at(args: Args) -> Result<KclValue, KclError> {
|
|||||||
let data: [f64; 2] = args.get_data()?;
|
let data: [f64; 2] = args.get_data()?;
|
||||||
|
|
||||||
let sketch_group = inner_start_sketch_at(data, args).await?;
|
let sketch_group = inner_start_sketch_at(data, args).await?;
|
||||||
Ok(KclValue::SketchGroup(sketch_group))
|
Ok(KclValue::new_user_val(sketch_group.meta.clone(), sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a new 2-dimensional sketch at a given point on the 'XY' plane.
|
/// Start a new 2-dimensional sketch at a given point on the 'XY' plane.
|
||||||
@ -872,7 +872,7 @@ pub async fn start_sketch_at(args: Args) -> Result<KclValue, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "startSketchAt",
|
name = "startSketchAt",
|
||||||
}]
|
}]
|
||||||
async fn inner_start_sketch_at(data: [f64; 2], args: Args) -> Result<Box<SketchGroup>, KclError> {
|
async fn inner_start_sketch_at(data: [f64; 2], args: Args) -> Result<SketchGroup, KclError> {
|
||||||
// Let's assume it's the XY plane for now, this is just for backwards compatibility.
|
// Let's assume it's the XY plane for now, this is just for backwards compatibility.
|
||||||
let xy_plane = PlaneData::XY;
|
let xy_plane = PlaneData::XY;
|
||||||
let sketch_surface = inner_start_sketch_on(SketchData::Plane(xy_plane), None, args.clone()).await?;
|
let sketch_surface = inner_start_sketch_on(SketchData::Plane(xy_plane), None, args.clone()).await?;
|
||||||
@ -1204,7 +1204,7 @@ pub async fn start_profile_at(args: Args) -> Result<KclValue, KclError> {
|
|||||||
args.get_data_and_sketch_surface()?;
|
args.get_data_and_sketch_surface()?;
|
||||||
|
|
||||||
let sketch_group = inner_start_profile_at(start, sketch_surface, tag, args).await?;
|
let sketch_group = inner_start_profile_at(start, sketch_surface, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(sketch_group))
|
Ok(KclValue::new_user_val(sketch_group.meta.clone(), sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a new profile at a given point.
|
/// Start a new profile at a given point.
|
||||||
@ -1249,7 +1249,7 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
sketch_surface: SketchSurface,
|
sketch_surface: SketchSurface,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
if let SketchSurface::Face(face) = &sketch_surface {
|
if let SketchSurface::Face(face) = &sketch_surface {
|
||||||
// Flush the batch for our fillets/chamfers if there are any.
|
// Flush the batch for our fillets/chamfers if there are any.
|
||||||
// If we do not do these for sketch on face, things will fail with face does not exist.
|
// If we do not do these for sketch on face, things will fail with face does not exist.
|
||||||
@ -1324,12 +1324,12 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
},
|
},
|
||||||
start: current_path,
|
start: current_path,
|
||||||
};
|
};
|
||||||
Ok(Box::new(sketch_group))
|
Ok(sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the X component of the sketch profile start point.
|
/// Returns the X component of the sketch profile start point.
|
||||||
pub async fn profile_start_x(args: Args) -> Result<KclValue, KclError> {
|
pub async fn profile_start_x(args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch_group: Box<SketchGroup> = args.get_sketch_group()?;
|
let sketch_group: SketchGroup = args.get_sketch_group()?;
|
||||||
let x = inner_profile_start_x(sketch_group)?;
|
let x = inner_profile_start_x(sketch_group)?;
|
||||||
args.make_user_val_from_f64(x)
|
args.make_user_val_from_f64(x)
|
||||||
}
|
}
|
||||||
@ -1347,13 +1347,13 @@ pub async fn profile_start_x(args: Args) -> Result<KclValue, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "profileStartX"
|
name = "profileStartX"
|
||||||
}]
|
}]
|
||||||
pub(crate) fn inner_profile_start_x(sketch_group: Box<SketchGroup>) -> Result<f64, KclError> {
|
pub(crate) fn inner_profile_start_x(sketch_group: SketchGroup) -> Result<f64, KclError> {
|
||||||
Ok(sketch_group.start.to[0])
|
Ok(sketch_group.start.to[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Y component of the sketch profile start point.
|
/// Returns the Y component of the sketch profile start point.
|
||||||
pub async fn profile_start_y(args: Args) -> Result<KclValue, KclError> {
|
pub async fn profile_start_y(args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch_group: Box<SketchGroup> = args.get_sketch_group()?;
|
let sketch_group: SketchGroup = args.get_sketch_group()?;
|
||||||
let x = inner_profile_start_y(sketch_group)?;
|
let x = inner_profile_start_y(sketch_group)?;
|
||||||
args.make_user_val_from_f64(x)
|
args.make_user_val_from_f64(x)
|
||||||
}
|
}
|
||||||
@ -1370,13 +1370,13 @@ pub async fn profile_start_y(args: Args) -> Result<KclValue, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "profileStartY"
|
name = "profileStartY"
|
||||||
}]
|
}]
|
||||||
pub(crate) fn inner_profile_start_y(sketch_group: Box<SketchGroup>) -> Result<f64, KclError> {
|
pub(crate) fn inner_profile_start_y(sketch_group: SketchGroup) -> Result<f64, KclError> {
|
||||||
Ok(sketch_group.start.to[1])
|
Ok(sketch_group.start.to[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the sketch profile start point.
|
/// Returns the sketch profile start point.
|
||||||
pub async fn profile_start(args: Args) -> Result<KclValue, KclError> {
|
pub async fn profile_start(args: Args) -> Result<KclValue, KclError> {
|
||||||
let sketch_group: Box<SketchGroup> = args.get_sketch_group()?;
|
let sketch_group: SketchGroup = args.get_sketch_group()?;
|
||||||
let point = inner_profile_start(sketch_group)?;
|
let point = inner_profile_start(sketch_group)?;
|
||||||
Ok(KclValue::UserVal(UserVal {
|
Ok(KclValue::UserVal(UserVal {
|
||||||
value: serde_json::to_value(point).map_err(|e| {
|
value: serde_json::to_value(point).map_err(|e| {
|
||||||
@ -1404,17 +1404,17 @@ pub async fn profile_start(args: Args) -> Result<KclValue, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "profileStart"
|
name = "profileStart"
|
||||||
}]
|
}]
|
||||||
pub(crate) fn inner_profile_start(sketch_group: Box<SketchGroup>) -> Result<[f64; 2], KclError> {
|
pub(crate) fn inner_profile_start(sketch_group: SketchGroup) -> Result<[f64; 2], KclError> {
|
||||||
Ok(sketch_group.start.to)
|
Ok(sketch_group.start.to)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the current sketch.
|
/// Close the current sketch.
|
||||||
pub async fn close(args: Args) -> Result<KclValue, KclError> {
|
pub async fn close(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (sketch_group, tag): (Box<SketchGroup>, Option<TagDeclarator>) = args.get_sketch_group_and_optional_tag()?;
|
let (sketch_group, tag): (SketchGroup, Option<TagDeclarator>) = args.get_sketch_group_and_optional_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_close(sketch_group, tag, args).await?;
|
let new_sketch_group = inner_close(sketch_group, tag, args).await?;
|
||||||
|
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a line segment from the current origin back to the profile's
|
/// Construct a line segment from the current origin back to the profile's
|
||||||
@ -1442,10 +1442,10 @@ pub async fn close(args: Args) -> Result<KclValue, KclError> {
|
|||||||
name = "close",
|
name = "close",
|
||||||
}]
|
}]
|
||||||
pub(crate) async fn inner_close(
|
pub(crate) async fn inner_close(
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
let to: Point2d = sketch_group.start.from.into();
|
let to: Point2d = sketch_group.start.from.into();
|
||||||
|
|
||||||
@ -1517,11 +1517,11 @@ pub enum ArcData {
|
|||||||
|
|
||||||
/// Draw an arc.
|
/// Draw an arc.
|
||||||
pub async fn arc(args: Args) -> Result<KclValue, KclError> {
|
pub async fn arc(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (ArcData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (ArcData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_arc(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_arc(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starting at the current sketch's origin, draw a curved line segment along
|
/// Starting at the current sketch's origin, draw a curved line segment along
|
||||||
@ -1553,10 +1553,10 @@ pub async fn arc(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
pub(crate) async fn inner_arc(
|
pub(crate) async fn inner_arc(
|
||||||
data: ArcData,
|
data: ArcData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from: Point2d = sketch_group.current_pen_position()?;
|
let from: Point2d = sketch_group.current_pen_position()?;
|
||||||
|
|
||||||
let (center, angle_start, angle_end, radius, end) = match &data {
|
let (center, angle_start, angle_end, radius, end) = match &data {
|
||||||
@ -1640,11 +1640,11 @@ pub enum TangentialArcData {
|
|||||||
|
|
||||||
/// Draw a tangential arc.
|
/// Draw a tangential arc.
|
||||||
pub async fn tangential_arc(args: Args) -> Result<KclValue, KclError> {
|
pub async fn tangential_arc(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (TangentialArcData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (TangentialArcData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_tangential_arc(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_tangential_arc(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starting at the current sketch's origin, draw a curved line segment along
|
/// Starting at the current sketch's origin, draw a curved line segment along
|
||||||
@ -1676,10 +1676,10 @@ pub async fn tangential_arc(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_tangential_arc(
|
async fn inner_tangential_arc(
|
||||||
data: TangentialArcData,
|
data: TangentialArcData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from: Point2d = sketch_group.current_pen_position()?;
|
let from: Point2d = sketch_group.current_pen_position()?;
|
||||||
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
||||||
let tangent_info = sketch_group.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
let tangent_info = sketch_group.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
||||||
@ -1793,7 +1793,7 @@ pub async fn tangential_arc_to(args: Args) -> Result<KclValue, KclError> {
|
|||||||
// Get arguments to function call
|
// Get arguments to function call
|
||||||
let mut it = args.args.iter();
|
let mut it = args.args.iter();
|
||||||
let to: [f64; 2] = get_arg(&mut it, src)?.get_json()?;
|
let to: [f64; 2] = get_arg(&mut it, src)?.get_json()?;
|
||||||
let sketch_group: Box<SketchGroup> = get_arg(&mut it, src)?.get_json()?;
|
let sketch_group: SketchGroup = get_arg(&mut it, src)?.get_json()?;
|
||||||
let tag = if let Ok(memory_item) = get_arg(&mut it, src) {
|
let tag = if let Ok(memory_item) = get_arg(&mut it, src) {
|
||||||
memory_item.get_json_opt()?
|
memory_item.get_json_opt()?
|
||||||
} else {
|
} else {
|
||||||
@ -1801,7 +1801,7 @@ pub async fn tangential_arc_to(args: Args) -> Result<KclValue, KclError> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let new_sketch_group = inner_tangential_arc_to(to, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_tangential_arc_to(to, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starting at the current sketch's origin, draw a curved line segment along
|
/// Starting at the current sketch's origin, draw a curved line segment along
|
||||||
@ -1826,10 +1826,10 @@ pub async fn tangential_arc_to(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_tangential_arc_to(
|
async fn inner_tangential_arc_to(
|
||||||
to: [f64; 2],
|
to: [f64; 2],
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from: Point2d = sketch_group.current_pen_position()?;
|
let from: Point2d = sketch_group.current_pen_position()?;
|
||||||
let tangent_info = sketch_group.get_tangential_info_from_paths();
|
let tangent_info = sketch_group.get_tangential_info_from_paths();
|
||||||
let tan_previous_point = if tangent_info.is_center {
|
let tan_previous_point = if tangent_info.is_center {
|
||||||
@ -1888,11 +1888,11 @@ pub struct BezierData {
|
|||||||
|
|
||||||
/// Draw a bezier curve.
|
/// Draw a bezier curve.
|
||||||
pub async fn bezier_curve(args: Args) -> Result<KclValue, KclError> {
|
pub async fn bezier_curve(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (data, sketch_group, tag): (BezierData, Box<SketchGroup>, Option<TagDeclarator>) =
|
let (data, sketch_group, tag): (BezierData, SketchGroup, Option<TagDeclarator>) =
|
||||||
args.get_data_and_sketch_group_and_tag()?;
|
args.get_data_and_sketch_group_and_tag()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_bezier_curve(data, sketch_group, tag, args).await?;
|
let new_sketch_group = inner_bezier_curve(data, sketch_group, tag, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a smooth, continuous, curved line segment from the current origin to
|
/// Draw a smooth, continuous, curved line segment from the current origin to
|
||||||
@ -1918,10 +1918,10 @@ pub async fn bezier_curve(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_bezier_curve(
|
async fn inner_bezier_curve(
|
||||||
data: BezierData,
|
data: BezierData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let from = sketch_group.current_pen_position()?;
|
let from = sketch_group.current_pen_position()?;
|
||||||
|
|
||||||
let relative = true;
|
let relative = true;
|
||||||
@ -1980,10 +1980,10 @@ async fn inner_bezier_curve(
|
|||||||
|
|
||||||
/// Use a sketch to cut a hole in another sketch.
|
/// Use a sketch to cut a hole in another sketch.
|
||||||
pub async fn hole(args: Args) -> Result<KclValue, KclError> {
|
pub async fn hole(args: Args) -> Result<KclValue, KclError> {
|
||||||
let (hole_sketch_group, sketch_group): (SketchGroupSet, Box<SketchGroup>) = args.get_sketch_groups()?;
|
let (hole_sketch_group, sketch_group): (SketchGroupSet, SketchGroup) = args.get_sketch_groups()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_hole(hole_sketch_group, sketch_group, args).await?;
|
let new_sketch_group = inner_hole(hole_sketch_group, sketch_group, args).await?;
|
||||||
Ok(KclValue::SketchGroup(new_sketch_group))
|
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch.
|
/// Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch.
|
||||||
@ -2022,10 +2022,10 @@ pub async fn hole(args: Args) -> Result<KclValue, KclError> {
|
|||||||
}]
|
}]
|
||||||
async fn inner_hole(
|
async fn inner_hole(
|
||||||
hole_sketch_group: SketchGroupSet,
|
hole_sketch_group: SketchGroupSet,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: SketchGroup,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<SketchGroup, KclError> {
|
||||||
let hole_sketch_groups: Vec<Box<SketchGroup>> = hole_sketch_group.into();
|
let hole_sketch_groups: Vec<SketchGroup> = hole_sketch_group.into();
|
||||||
for hole_sketch_group in hole_sketch_groups {
|
for hole_sketch_group in hole_sketch_groups {
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use kcl_lib::{
|
use kcl_lib::{
|
||||||
ast::{modify::modify_ast_for_sketch, types::Program},
|
ast::{modify::modify_ast_for_sketch, types::Program},
|
||||||
executor::{ExecutorContext, KclValue, PlaneType, SourceRange},
|
executor::{ExecutorContext, KclValue, PlaneType, SketchGroup, SourceRange},
|
||||||
};
|
};
|
||||||
use kittycad::types::{ModelingCmd, Point3D};
|
use kittycad::types::{ModelingCmd, Point3D};
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
@ -39,9 +39,12 @@ async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Program, uuid
|
|||||||
|
|
||||||
// We need to get the sketch ID.
|
// We need to get the sketch ID.
|
||||||
// Get the sketch group ID from memory.
|
// Get the sketch group ID from memory.
|
||||||
let KclValue::SketchGroup(sketch_group) = memory.get(name, SourceRange::default()).unwrap() else {
|
let KclValue::UserVal(user_val) = memory.get(name, SourceRange::default()).unwrap() else {
|
||||||
anyhow::bail!("part001 not found in memory: {:?}", memory);
|
anyhow::bail!("part001 not found in memory: {:?}", memory);
|
||||||
};
|
};
|
||||||
|
let Some((sketch_group, _meta)) = user_val.get::<SketchGroup>() else {
|
||||||
|
anyhow::bail!("part001 was not a SketchGroup");
|
||||||
|
};
|
||||||
let sketch_id = sketch_group.id;
|
let sketch_id = sketch_group.id;
|
||||||
|
|
||||||
let plane_id = uuid::Uuid::new_v4();
|
let plane_id = uuid::Uuid::new_v4();
|
||||||
|
Reference in New Issue
Block a user