Compare commits
16 Commits
v0.35.0
...
nightly-v2
Author | SHA1 | Date | |
---|---|---|---|
5ebd5c8dbb | |||
a9ceaf2678 | |||
c8afd3399b | |||
5dda4828c6 | |||
72acab752c | |||
81df38ad1c | |||
0576a2bef1 | |||
4b2f6b4647 | |||
69edaa4183 | |||
2eb7c382bf | |||
38913ecb98 | |||
debd06129f | |||
d38bd342a0 | |||
f026f10335 | |||
895d7ebc6d | |||
65edf17a44 |
@ -24,3 +24,5 @@ once fixed in engine will just start working here with no language changes.
|
||||
chamfer cases work currently.
|
||||
|
||||
- **Appearance**: Changing the appearance on a loft does not work.
|
||||
|
||||
- **Helix**: Currently sweeping a helix does not work.
|
||||
|
43
docs/kcl/helixRevolutions.md
Normal file
@ -48,6 +48,7 @@ layout: manual
|
||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||
* [`helix`](kcl/helix)
|
||||
* [`helixRevolutions`](kcl/helixRevolutions)
|
||||
* [`hole`](kcl/hole)
|
||||
* [`hollow`](kcl/hollow)
|
||||
* [`import`](kcl/import)
|
||||
@ -81,6 +82,7 @@ layout: manual
|
||||
* [`pi`](kcl/pi)
|
||||
* [`polar`](kcl/polar)
|
||||
* [`polygon`](kcl/polygon)
|
||||
* [`pop`](kcl/pop)
|
||||
* [`pow`](kcl/pow)
|
||||
* [`profileStart`](kcl/profileStart)
|
||||
* [`profileStartX`](kcl/profileStartX)
|
||||
|
39
docs/kcl/pop.md
Normal file
6781
docs/kcl/std.json
@ -1,19 +1,19 @@
|
||||
---
|
||||
title: "AxisOrEdgeReference"
|
||||
excerpt: "Axis or tagged edge."
|
||||
title: "Axis2dOrEdgeReference"
|
||||
excerpt: "A 2D axis or tagged edge."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Axis or tagged edge.
|
||||
A 2D axis or tagged edge.
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
Axis and origin.
|
||||
2D axis and origin.
|
||||
|
||||
[`AxisAndOrigin`](/docs/kcl/types/AxisAndOrigin)
|
||||
[`AxisAndOrigin2d`](/docs/kcl/types/AxisAndOrigin2d)
|
||||
|
||||
|
||||
|
42
docs/kcl/types/Axis3dOrEdgeReference.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "Axis3dOrEdgeReference"
|
||||
excerpt: "A 3D axis or tagged edge."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A 3D axis or tagged edge.
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
3D axis and origin.
|
||||
|
||||
[`AxisAndOrigin3d`](/docs/kcl/types/AxisAndOrigin3d)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Tagged edge.
|
||||
|
||||
[`EdgeReference`](/docs/kcl/types/EdgeReference)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "AxisAndOrigin"
|
||||
excerpt: "Axis and origin."
|
||||
title: "AxisAndOrigin2d"
|
||||
excerpt: "A 2D axis and origin."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Axis and origin.
|
||||
A 2D axis and origin.
|
||||
|
||||
|
||||
|
105
docs/kcl/types/AxisAndOrigin3d.md
Normal file
@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "AxisAndOrigin3d"
|
||||
excerpt: "A 3D axis and origin."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A 3D axis and origin.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
X-axis.
|
||||
|
||||
**enum:** `X`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Y-axis.
|
||||
|
||||
**enum:** `Y`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Z-axis.
|
||||
|
||||
**enum:** `Z`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Flip the X-axis.
|
||||
|
||||
**enum:** `-X`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Flip the Y-axis.
|
||||
|
||||
**enum:** `-Y`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Flip the Z-axis.
|
||||
|
||||
**enum:** `-Z`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `custom` |`object`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
25
docs/kcl/types/Helix.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: "Helix"
|
||||
excerpt: "A helix."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `value` |`string`| The id of the helix. | No |
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "HelixData"
|
||||
excerpt: "Data for helices."
|
||||
excerpt: "Data for a helix."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for helices.
|
||||
Data for a helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
@ -19,6 +19,8 @@ Data for helices.
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
|
||||
| `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No |
|
||||
| `length` |`number`| Length of the helix. | No |
|
||||
| `radius` |`number`| Radius of the helix. | No |
|
||||
| `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No |
|
||||
|
||||
|
||||
|
24
docs/kcl/types/HelixRevolutionsData.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
title: "HelixRevolutionsData"
|
||||
excerpt: "Data for helix revolutions."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for helix revolutions.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
|
||||
| `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No |
|
||||
|
||||
|
25
docs/kcl/types/HelixValue.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: "HelixValue"
|
||||
excerpt: "A helix."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `value` |`string`| The id of the helix. | No |
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
@ -285,6 +285,27 @@ An solid is a collection of extrude surfaces.
|
||||
| `value` |`[` [`Solid`](/docs/kcl/types/Solid) `]`| | No |
|
||||
|
||||
|
||||
----
|
||||
A helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No |
|
||||
| `value` |`string`| The id of the helix. | No |
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
||||
----
|
||||
Data for an imported geometry.
|
||||
|
||||
|
@ -16,6 +16,6 @@ Data for a mirror.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `axis` |[`AxisOrEdgeReference`](/docs/kcl/types/AxisOrEdgeReference)| Axis to use as mirror. | No |
|
||||
| `axis` |[`Axis2dOrEdgeReference`](/docs/kcl/types/Axis2dOrEdgeReference)| Axis to use as mirror. | No |
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ Data for revolution surfaces.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `angle` |`number` (**maximum:** 360.0) (**minimum:** -360.0)| Angle to revolve (in degrees). Default is 360. | No |
|
||||
| `axis` |[`AxisOrEdgeReference`](/docs/kcl/types/AxisOrEdgeReference)| Axis of revolution. | No |
|
||||
| `axis` |[`Axis2dOrEdgeReference`](/docs/kcl/types/Axis2dOrEdgeReference)| Axis of revolution. | No |
|
||||
| `tolerance` |`number`| Tolerance for the revolve operation. | No |
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ Data for a sweep.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `path` |[`Sketch`](/docs/kcl/types/Sketch)| The path to sweep along. | No |
|
||||
| `path` |[`SweepPath`](/docs/kcl/types/SweepPath)| The path to sweep along. | No |
|
||||
| `sectional` |`boolean`| If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. | No |
|
||||
| `tolerance` |`number`| Tolerance for the sweep operation. | No |
|
||||
|
||||
|
42
docs/kcl/types/SweepPath.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "SweepPath"
|
||||
excerpt: "A path to sweep along."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A path to sweep along.
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
A path to sweep along.
|
||||
|
||||
[`Sketch`](/docs/kcl/types/Sketch)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
A path to sweep along.
|
||||
|
||||
[`Helix`](/docs/kcl/types/Helix)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -39,8 +39,8 @@ test.describe('Sketch tests', () => {
|
||||
${startProfileAt1}
|
||||
|> arc({
|
||||
radius = screwRadius,
|
||||
angle_start = 0,
|
||||
angle_end = 360
|
||||
angleStart = 0,
|
||||
angleEnd = 360
|
||||
}, %)
|
||||
|
||||
part001 = startSketchOn('XY')
|
||||
@ -60,8 +60,8 @@ test.describe('Sketch tests', () => {
|
||||
|> yLine(wireOffset, %)
|
||||
|> arc({
|
||||
radius = wireRadius,
|
||||
angle_start = 0,
|
||||
angle_end = 180
|
||||
angleStart = 0,
|
||||
angleEnd = 180
|
||||
}, %)
|
||||
|> yLine(-wireOffset, %)
|
||||
|> xLine(-width / 4, %)
|
||||
|
@ -389,25 +389,25 @@ test.describe('Testing selections', () => {
|
||||
await expect(u.codeLocator).toContainText(`sketch005 = startSketchOn({
|
||||
plane = {
|
||||
origin = { x = 0, y = -50, z = 0 },
|
||||
x_axis = { x = 1, y = 0, z = 0 },
|
||||
y_axis = { x = 0, y = 0, z = 1 },
|
||||
z_axis = { x = 0, y = -1, z = 0 }
|
||||
xAxis = { x = 1, y = 0, z = 0 },
|
||||
yAxis = { x = 0, y = 0, z = 1 },
|
||||
zAxis = { x = 0, y = -1, z = 0 }
|
||||
}
|
||||
})`)
|
||||
await expect(u.codeLocator).toContainText(`sketch003 = startSketchOn({
|
||||
plane = {
|
||||
origin = { x = 116.53, y = 0, z = 163.25 },
|
||||
x_axis = { x = -0.81, y = 0, z = 0.58 },
|
||||
y_axis = { x = 0, y = -1, z = 0 },
|
||||
z_axis = { x = 0.58, y = 0, z = 0.81 }
|
||||
xAxis = { x = -0.81, y = 0, z = 0.58 },
|
||||
yAxis = { x = 0, y = -1, z = 0 },
|
||||
zAxis = { x = 0.58, y = 0, z = 0.81 }
|
||||
}
|
||||
})`)
|
||||
await expect(u.codeLocator).toContainText(`sketch002 = startSketchOn({
|
||||
plane = {
|
||||
origin = { x = -91.74, y = 0, z = 80.89 },
|
||||
x_axis = { x = -0.66, y = 0, z = -0.75 },
|
||||
y_axis = { x = 0, y = -1, z = 0 },
|
||||
z_axis = { x = -0.75, y = 0, z = 0.66 }
|
||||
xAxis = { x = -0.66, y = 0, z = -0.75 },
|
||||
yAxis = { x = 0, y = -1, z = 0 },
|
||||
zAxis = { x = -0.75, y = 0, z = 0.66 }
|
||||
}
|
||||
})`)
|
||||
|
||||
|
12
package.json
@ -15,7 +15,7 @@
|
||||
"@codemirror/autocomplete": "^6.17.0",
|
||||
"@codemirror/commands": "^6.6.0",
|
||||
"@codemirror/language": "^6.10.3",
|
||||
"@codemirror/lint": "^6.8.1",
|
||||
"@codemirror/lint": "^6.8.4",
|
||||
"@codemirror/search": "^6.5.6",
|
||||
"@codemirror/state": "^6.4.1",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
@ -52,13 +52,13 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-hotkeys-hook": "^4.5.1",
|
||||
"react-hotkeys-hook": "^4.6.1",
|
||||
"react-json-view": "^1.21.3",
|
||||
"react-modal": "^3.16.1",
|
||||
"react-modal": "^3.16.3",
|
||||
"react-modal-promise": "^1.0.2",
|
||||
"react-router-dom": "^6.28.0",
|
||||
"sketch-helpers": "^0.0.4",
|
||||
"three": "^0.166.1",
|
||||
"three": "^0.172.0",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"uuid": "^11.0.2",
|
||||
"vscode-jsonrpc": "^8.2.1",
|
||||
@ -166,7 +166,7 @@
|
||||
"@types/react": "^18.3.4",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@types/react-modal": "^3.16.3",
|
||||
"@types/three": "^0.163.0",
|
||||
"@types/three": "^0.172.0",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/wicg-file-system-access": "^2023.10.5",
|
||||
@ -186,7 +186,7 @@
|
||||
"eslint-plugin-css-modules": "^2.12.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-suggest-no-throw": "^1.0.0",
|
||||
"happy-dom": "^15.11.7",
|
||||
"happy-dom": "^16.3.0",
|
||||
"http-server": "^14.1.1",
|
||||
"husky": "^9.1.5",
|
||||
"kill-port": "^2.0.1",
|
||||
|
@ -85,7 +85,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* }
|
||||
@tokens {
|
||||
String[isolate] { "'" ("\\" _ | !['\\])* "'" | '"' ("\\" _ | !["\\])* '"' }
|
||||
|
||||
Number { "." @digit+ | @digit+ ("." @digit*)? }
|
||||
Number { "." @digit+ | @digit+ ("." @digit+)? }
|
||||
@precedence { Number, "." }
|
||||
|
||||
AddOp { "+" | "-" }
|
||||
|
43
packages/codemirror-lang-kcl/test/range.txt
Normal file
@ -0,0 +1,43 @@
|
||||
# spaced
|
||||
|
||||
a = [0 .. 1]
|
||||
|
||||
==>
|
||||
Program(VariableDeclaration(VariableDefinition,
|
||||
Equals,
|
||||
ArrayExpression(IntegerRange(Number,
|
||||
Number))))
|
||||
|
||||
# compact
|
||||
|
||||
a = [0..1]
|
||||
|
||||
==>
|
||||
Program(VariableDeclaration(VariableDefinition,
|
||||
Equals,
|
||||
ArrayExpression(IntegerRange(Number,
|
||||
Number))))
|
||||
|
||||
# expr spaced
|
||||
|
||||
a = [start .. start + 10]
|
||||
|
||||
==>
|
||||
Program(VariableDeclaration(VariableDefinition,
|
||||
Equals,
|
||||
ArrayExpression(IntegerRange(VariableName,
|
||||
BinaryExpression(VariableName,
|
||||
AddOp,
|
||||
Number)))))
|
||||
|
||||
# expr compact
|
||||
|
||||
a = [start..start + 10]
|
||||
|
||||
==>
|
||||
Program(VariableDeclaration(VariableDefinition,
|
||||
Equals,
|
||||
ArrayExpression(IntegerRange(VariableName,
|
||||
BinaryExpression(VariableName,
|
||||
AddOp,
|
||||
Number)))))
|
@ -1,42 +0,0 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { vi } from 'vitest'
|
||||
import { UpdaterModal } from './UpdaterModal'
|
||||
|
||||
describe('UpdaterModal tests', () => {
|
||||
test('Renders the modal', () => {
|
||||
const callback = vi.fn()
|
||||
const data = {
|
||||
version: '1.2.3',
|
||||
date: '2021-22-23T21:22:23Z',
|
||||
body: 'This is the body.',
|
||||
}
|
||||
|
||||
render(
|
||||
<UpdaterModal
|
||||
isOpen={true}
|
||||
onReject={() => {}}
|
||||
onResolve={callback}
|
||||
instanceId=""
|
||||
open={false}
|
||||
close={(res) => {}}
|
||||
version={data.version}
|
||||
date={data.date}
|
||||
body={data.body}
|
||||
/>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('update-version')).toHaveTextContent(data.version)
|
||||
|
||||
const updateButton = screen.getByTestId('update-button-update')
|
||||
expect(updateButton).toBeEnabled()
|
||||
fireEvent.click(updateButton)
|
||||
expect(callback.mock.calls).toHaveLength(1)
|
||||
expect(callback.mock.lastCall[0]).toEqual({ wantUpdate: true })
|
||||
|
||||
const cancelButton = screen.getByTestId('update-button-cancel')
|
||||
expect(cancelButton).toBeEnabled()
|
||||
fireEvent.click(cancelButton)
|
||||
expect(callback.mock.calls).toHaveLength(2)
|
||||
expect(callback.mock.lastCall[0]).toEqual({ wantUpdate: false })
|
||||
})
|
||||
})
|
@ -1,87 +0,0 @@
|
||||
import { create, InstanceProps } from 'react-modal-promise'
|
||||
import { ActionButton } from './ActionButton'
|
||||
import { Logo } from './Logo'
|
||||
import { Marked } from '@ts-stack/markdown'
|
||||
|
||||
type ModalResolve = {
|
||||
wantUpdate: boolean
|
||||
}
|
||||
|
||||
type ModalReject = boolean
|
||||
|
||||
type UpdaterModalProps = InstanceProps<ModalResolve, ModalReject> & {
|
||||
version: string
|
||||
date?: string
|
||||
body?: string
|
||||
}
|
||||
|
||||
export const createUpdaterModal = create<
|
||||
UpdaterModalProps,
|
||||
ModalResolve,
|
||||
ModalReject
|
||||
>
|
||||
|
||||
export const UpdaterModal = ({
|
||||
onResolve,
|
||||
version,
|
||||
date,
|
||||
body,
|
||||
}: UpdaterModalProps) => (
|
||||
<div className="fixed inset-0 z-50 grid place-content-center bg-chalkboard-110/50">
|
||||
<div className="max-w-3xl min-w-[45rem] p-8 rounded bg-chalkboard-10 dark:bg-chalkboard-90">
|
||||
<div className="flex items-center">
|
||||
<h1 className="flex-grow text-3xl font-bold">New version available!</h1>
|
||||
<Logo className="h-9" />
|
||||
</div>
|
||||
<div className="my-4 flex items-baseline">
|
||||
<span
|
||||
className="px-3 py-1 text-xl rounded-full bg-energy-10 text-energy-80"
|
||||
data-testid="update-version"
|
||||
>
|
||||
v{version}
|
||||
</span>
|
||||
<span className="ml-4 text-sm text-gray-400">Published on {date}</span>
|
||||
</div>
|
||||
{/* TODO: fix list bullets */}
|
||||
{body && (
|
||||
<div
|
||||
className="my-4 max-h-60 overflow-y-auto"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: Marked.parse(body, {
|
||||
gfm: true,
|
||||
breaks: true,
|
||||
sanitize: true,
|
||||
}),
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
<div className="flex justify-between">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => onResolve({ wantUpdate: false })}
|
||||
iconStart={{
|
||||
icon: 'close',
|
||||
bgClassName: 'bg-destroy-80',
|
||||
iconClassName: 'text-destroy-20 group-hover:text-destroy-10',
|
||||
}}
|
||||
className="hover:border-destroy-40 hover:bg-destroy-10/50 dark:hover:bg-destroy-80/50"
|
||||
data-testid="update-button-cancel"
|
||||
>
|
||||
Not now
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => onResolve({ wantUpdate: true })}
|
||||
iconStart={{
|
||||
icon: 'arrowRight',
|
||||
bgClassName: 'dark:bg-chalkboard-80',
|
||||
}}
|
||||
className="dark:hover:bg-chalkboard-80/50"
|
||||
data-testid="update-button-update"
|
||||
>
|
||||
Update
|
||||
</ActionButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
@ -47,7 +47,7 @@ describe('parsing errors', () => {
|
||||
const result = parse(code)
|
||||
if (err(result)) throw result
|
||||
const error = result.errors[0]
|
||||
expect(error.message).toBe('Unexpected token: (')
|
||||
expect(error.sourceRange).toEqual([27, 28, 0])
|
||||
expect(error.message).toBe('Array is missing a closing bracket(`]`)')
|
||||
expect(error.sourceRange).toEqual([28, 29, 0])
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
Program,
|
||||
_executor,
|
||||
executor,
|
||||
ProgramMemory,
|
||||
kclLint,
|
||||
emptyExecState,
|
||||
@ -64,7 +64,7 @@ export async function executeAst({
|
||||
try {
|
||||
const execState = await (programMemoryOverride
|
||||
? enginelessExecutor(ast, programMemoryOverride)
|
||||
: _executor(ast, engineCommandManager))
|
||||
: executor(ast, engineCommandManager))
|
||||
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
|
||||
|
@ -806,9 +806,9 @@ sketch001 = startSketchOn('XZ')
|
||||
sketch002 = startSketchOn({
|
||||
plane = {
|
||||
origin = { x = 1, y = 2, z = 3 },
|
||||
x_axis = { x = 4, y = 5, z = 6 },
|
||||
y_axis = { x = 7, y = 8, z = 9 },
|
||||
z_axis = { x = 10, y = 11, z = 12 }
|
||||
xAxis = { x = 4, y = 5, z = 6 },
|
||||
yAxis = { x = 7, y = 8, z = 9 },
|
||||
zAxis = { x = 10, y = 11, z = 12 }
|
||||
}
|
||||
})
|
||||
|> startProfileAt([-12.55, 2.89], %)
|
||||
@ -862,9 +862,9 @@ sketch001 = startSketchOn('XZ')
|
||||
sketch002 = startSketchOn({
|
||||
plane = {
|
||||
origin = { x = 1, y = 2, z = 3 },
|
||||
x_axis = { x = 4, y = 5, z = 6 },
|
||||
y_axis = { x = 7, y = 8, z = 9 },
|
||||
z_axis = { x = 10, y = 11, z = 12 }
|
||||
xAxis = { x = 4, y = 5, z = 6 },
|
||||
yAxis = { x = 7, y = 8, z = 9 },
|
||||
zAxis = { x = 10, y = 11, z = 12 }
|
||||
}
|
||||
})
|
||||
|> startProfileAt([-12.55, 2.89], %)
|
||||
|
@ -1278,17 +1278,17 @@ export async function deleteFromSelection(
|
||||
y: roundLiteral(faceDetails.origin.y),
|
||||
z: roundLiteral(faceDetails.origin.z),
|
||||
}),
|
||||
x_axis: createObjectExpression({
|
||||
xAxis: createObjectExpression({
|
||||
x: roundLiteral(faceDetails.x_axis.x),
|
||||
y: roundLiteral(faceDetails.x_axis.y),
|
||||
z: roundLiteral(faceDetails.x_axis.z),
|
||||
}),
|
||||
y_axis: createObjectExpression({
|
||||
yAxis: createObjectExpression({
|
||||
x: roundLiteral(faceDetails.y_axis.x),
|
||||
y: roundLiteral(faceDetails.y_axis.y),
|
||||
z: roundLiteral(faceDetails.y_axis.z),
|
||||
}),
|
||||
z_axis: createObjectExpression({
|
||||
zAxis: createObjectExpression({
|
||||
x: roundLiteral(faceDetails.z_axis.x),
|
||||
y: roundLiteral(faceDetails.z_axis.y),
|
||||
z: roundLiteral(faceDetails.z_axis.z),
|
||||
|
@ -506,22 +506,6 @@ export const executor = async (
|
||||
return Promise.reject(programMemoryOverride)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
engineCommandManager.startNewSession()
|
||||
const _programMemory = await _executor(
|
||||
node,
|
||||
engineCommandManager,
|
||||
programMemoryOverride
|
||||
)
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
|
||||
return _programMemory
|
||||
}
|
||||
|
||||
export const _executor = async (
|
||||
node: Node<Program>,
|
||||
engineCommandManager: EngineCommandManager,
|
||||
programMemoryOverride: ProgramMemory | Error | null = null
|
||||
): Promise<ExecState> => {
|
||||
if (programMemoryOverride !== null && err(programMemoryOverride))
|
||||
return Promise.reject(programMemoryOverride)
|
||||
|
||||
|
@ -1,20 +1,16 @@
|
||||
import {
|
||||
Program,
|
||||
ProgramMemory,
|
||||
_executor,
|
||||
executor,
|
||||
SourceRange,
|
||||
ExecState,
|
||||
} from '../lang/wasm'
|
||||
import {
|
||||
EngineCommandManager,
|
||||
EngineCommandManagerEvents,
|
||||
} from 'lang/std/engineConnection'
|
||||
import { EngineCommandManager } from 'lang/std/engineConnection'
|
||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||
import { Models } from '@kittycad/lib'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { DefaultPlanes } from 'wasm-lib/kcl/bindings/DefaultPlanes'
|
||||
import { err, reportRejection } from 'lib/trap'
|
||||
import { toSync } from './utils'
|
||||
import { err } from 'lib/trap'
|
||||
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
||||
|
||||
type WebSocketResponse = Models['WebSocketResponse_type']
|
||||
@ -94,36 +90,7 @@ export async function enginelessExecutor(
|
||||
}) as any as EngineCommandManager
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
mockEngineCommandManager.startNewSession()
|
||||
const execState = await _executor(ast, mockEngineCommandManager, pmo)
|
||||
const execState = await executor(ast, mockEngineCommandManager, pmo)
|
||||
await mockEngineCommandManager.waitForAllCommands()
|
||||
return execState
|
||||
}
|
||||
|
||||
export async function executor(
|
||||
ast: Node<Program>,
|
||||
pmo: ProgramMemory = ProgramMemory.empty()
|
||||
): Promise<ExecState> {
|
||||
const engineCommandManager = new EngineCommandManager()
|
||||
engineCommandManager.start({
|
||||
setIsStreamReady: () => {},
|
||||
setMediaStream: () => {},
|
||||
width: 0,
|
||||
height: 0,
|
||||
makeDefaultPlanes: () => {
|
||||
return new Promise((resolve) => resolve(defaultPlanes))
|
||||
},
|
||||
})
|
||||
|
||||
return new Promise((resolve) => {
|
||||
engineCommandManager.addEventListener(
|
||||
EngineCommandManagerEvents.SceneReady,
|
||||
toSync(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
engineCommandManager.startNewSession()
|
||||
const execState = await _executor(ast, engineCommandManager, pmo)
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
resolve(execState)
|
||||
}, reportRejection)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
34
src/wasm-lib/Cargo.lock
generated
@ -181,9 +181,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.83"
|
||||
version = "0.1.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
|
||||
checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1819,9 +1819,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad-modeling-cmds"
|
||||
version = "0.2.79"
|
||||
version = "0.2.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a9cab4476455be70ea57643c31444068b056d091bd348cab6044c0d8ad7fcc"
|
||||
checksum = "65e34a8eeb4fff5167666d1f2bc36c95d08ab3a0f736a02c8d33a8cde21cfd8d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -2687,9 +2687,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -3200,9 +3200,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.216"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
|
||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -3218,9 +3218,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.216"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
|
||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3240,9 +3240,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.133"
|
||||
version = "1.0.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
||||
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
|
||||
dependencies = [
|
||||
"indexmap 2.7.0",
|
||||
"itoa",
|
||||
@ -4609,9 +4609,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.20"
|
||||
version = "0.6.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
|
||||
checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -4748,9 +4748,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "2.2.0"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494"
|
||||
checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
@ -4758,5 +4758,5 @@ dependencies = [
|
||||
"displaydoc",
|
||||
"indexmap 2.7.0",
|
||||
"memchr",
|
||||
"thiserror 1.0.68",
|
||||
"thiserror 2.0.0",
|
||||
]
|
||||
|
@ -16,7 +16,7 @@ gloo-utils = "0.2.0"
|
||||
kcl-lib = { path = "kcl" }
|
||||
kittycad.workspace = true
|
||||
lazy_static = "1.5.0"
|
||||
serde_json = "1.0.128"
|
||||
serde_json = "1.0.135"
|
||||
tokio = { version = "1.41.1", features = ["sync"] }
|
||||
toml = "0.8.19"
|
||||
uuid = { version = "1.11.0", features = ["v4", "js", "serde"] }
|
||||
@ -76,7 +76,7 @@ members = [
|
||||
[workspace.dependencies]
|
||||
http = "1"
|
||||
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
|
||||
kittycad-modeling-cmds = { version = "0.2.79", features = ["websocket"] }
|
||||
kittycad-modeling-cmds = { version = "0.2.86", features = ["websocket"] }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
assertions_on_result_states = "warn"
|
||||
|
@ -18,7 +18,7 @@ once_cell = "1.20.2"
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
regex = "1.11"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
serde_tokenstream = "0.2"
|
||||
syn = { version = "2.0.95", features = ["full"] }
|
||||
|
||||
|
@ -10,8 +10,8 @@ anyhow = "1.0.95"
|
||||
hyper = { version = "0.14.29", features = ["http1", "server", "tcp"] }
|
||||
kcl-lib = { version = "0.2", path = "../kcl" }
|
||||
pico-args = "0.5.0"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
serde_json = "1.0.128"
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
serde_json = "1.0.135"
|
||||
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
|
||||
|
||||
[lints]
|
||||
|
@ -14,7 +14,7 @@ path = "src/tool.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
async-trait = "0.1.81"
|
||||
async-trait = "0.1.85"
|
||||
indexmap = "2.7.0"
|
||||
kcl-lib = { path = "../kcl" }
|
||||
kittycad = { workspace = true, features = ["clap"] }
|
||||
|
@ -13,7 +13,7 @@ keywords = ["kcl", "KittyCAD", "CAD"]
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0.95", features = ["backtrace"] }
|
||||
async-recursion = "1.1.1"
|
||||
async-trait = "0.1.83"
|
||||
async-trait = "0.1.85"
|
||||
base64 = "0.22.1"
|
||||
chrono = "0.4.38"
|
||||
clap = { version = "4.5.23", default-features = false, optional = true, features = [
|
||||
@ -54,8 +54,8 @@ schemars = { version = "0.8.17", features = [
|
||||
"uuid1",
|
||||
"preserve_order",
|
||||
] }
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
serde_json = "1.0.128"
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
serde_json = "1.0.135"
|
||||
sha2 = "0.10.8"
|
||||
tabled = { version = "0.15.0", optional = true }
|
||||
thiserror = "2.0.0"
|
||||
@ -73,8 +73,8 @@ urlencoding = "2.1.3"
|
||||
uuid = { version = "1.11.0", features = ["v4", "js", "serde"] }
|
||||
validator = { version = "0.19.0", features = ["derive"] }
|
||||
web-time = "1.1"
|
||||
winnow = "0.6.18"
|
||||
zip = { version = "2.0.0", default-features = false }
|
||||
winnow = "0.6.22"
|
||||
zip = { version = "2.2.2", default-features = false }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
js-sys = { version = "0.3.72" }
|
||||
|
@ -535,7 +535,11 @@ fn generate_type(
|
||||
|| name == "CircularPattern3dData"
|
||||
|| name == "LinearPattern2dData"
|
||||
|| name == "LinearPattern3dData"
|
||||
|| name == "Mirror2dData")
|
||||
|| name == "Mirror2dData"
|
||||
|| name == "Axis2dOrEdgeReference"
|
||||
|| name == "Axis3dOrEdgeReference"
|
||||
|| name == "AxisAndOrigin2d"
|
||||
|| name == "AxisAndOrigin3d")
|
||||
{
|
||||
return Err(anyhow::anyhow!("Type name is not pascal cased: {}", name));
|
||||
}
|
||||
|
@ -7,7 +7,9 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
errors::KclErrorDetails,
|
||||
exec::{ProgramMemory, Sketch},
|
||||
execution::{Face, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet, TagIdentifier},
|
||||
execution::{
|
||||
Face, Helix, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet, TagIdentifier,
|
||||
},
|
||||
parsing::{
|
||||
ast::types::{FunctionExpression, KclNone, LiteralValue, TagDeclarator, TagNode},
|
||||
token::NumericSuffix,
|
||||
@ -72,6 +74,7 @@ pub enum KclValue {
|
||||
Solids {
|
||||
value: Vec<Box<Solid>>,
|
||||
},
|
||||
Helix(Box<Helix>),
|
||||
ImportedGeometry(ImportedGeometry),
|
||||
#[ts(skip)]
|
||||
Function {
|
||||
@ -141,6 +144,7 @@ impl From<KclValue> for Vec<SourceRange> {
|
||||
KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
|
||||
KclValue::Sketch { value } => to_vec_sr(&value.meta),
|
||||
KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
|
||||
KclValue::Helix(e) => to_vec_sr(&e.meta),
|
||||
KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta),
|
||||
KclValue::Function { meta, .. } => to_vec_sr(&meta),
|
||||
KclValue::Plane(p) => to_vec_sr(&p.meta),
|
||||
@ -171,6 +175,7 @@ impl From<&KclValue> for Vec<SourceRange> {
|
||||
KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
|
||||
KclValue::Sketch { value } => to_vec_sr(&value.meta),
|
||||
KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
|
||||
KclValue::Helix(x) => to_vec_sr(&x.meta),
|
||||
KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta),
|
||||
KclValue::Function { meta, .. } => to_vec_sr(meta),
|
||||
KclValue::Plane(p) => to_vec_sr(&p.meta),
|
||||
@ -206,6 +211,7 @@ impl KclValue {
|
||||
KclValue::Sketches { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(),
|
||||
KclValue::Solid(x) => x.meta.clone(),
|
||||
KclValue::Solids { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(),
|
||||
KclValue::Helix(x) => x.meta.clone(),
|
||||
KclValue::ImportedGeometry(x) => x.meta.clone(),
|
||||
KclValue::Function { meta, .. } => meta.clone(),
|
||||
KclValue::Module { meta, .. } => meta.clone(),
|
||||
@ -264,6 +270,7 @@ impl KclValue {
|
||||
KclValue::Solids { .. } => "Solids",
|
||||
KclValue::Sketch { .. } => "Sketch",
|
||||
KclValue::Sketches { .. } => "Sketches",
|
||||
KclValue::Helix(_) => "Helix",
|
||||
KclValue::ImportedGeometry(_) => "ImportedGeometry",
|
||||
KclValue::Function { .. } => "Function",
|
||||
KclValue::Plane(_) => "Plane",
|
||||
|
@ -702,6 +702,23 @@ pub struct ImportedGeometry {
|
||||
pub meta: Vec<Metadata>,
|
||||
}
|
||||
|
||||
/// A helix.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Helix {
|
||||
/// The id of the helix.
|
||||
pub value: uuid::Uuid,
|
||||
/// Number of revolutions.
|
||||
pub revolutions: f64,
|
||||
/// Start angle (in degrees).
|
||||
pub angle_start: f64,
|
||||
/// Is the helix rotation counter clockwise?
|
||||
pub ccw: bool,
|
||||
#[serde(rename = "__meta")]
|
||||
pub meta: Vec<Metadata>,
|
||||
}
|
||||
|
||||
/// A plane.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
|
@ -12,6 +12,7 @@ use winnow::{
|
||||
token::{any, one_of, take_till},
|
||||
};
|
||||
|
||||
use super::{ast::types::LabelledExpression, token::NumericSuffix};
|
||||
use crate::{
|
||||
docs::StdLibFn,
|
||||
errors::{CompilationError, Severity, Tag},
|
||||
@ -33,8 +34,6 @@ use crate::{
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
use super::{ast::types::LabelledExpression, token::NumericSuffix};
|
||||
|
||||
thread_local! {
|
||||
/// The current `ParseContext`. `None` if parsing is not currently happening on this thread.
|
||||
static CTXT: RefCell<Option<ParseContext>> = const { RefCell::new(None) };
|
||||
@ -683,8 +682,8 @@ pub enum NonCodeOr<T> {
|
||||
fn array(i: &mut TokenSlice) -> PResult<Expr> {
|
||||
alt((
|
||||
array_empty.map(Box::new).map(Expr::ArrayExpression),
|
||||
array_elem_by_elem.map(Box::new).map(Expr::ArrayExpression),
|
||||
array_end_start.map(Box::new).map(Expr::ArrayRangeExpression),
|
||||
array_elem_by_elem.map(Box::new).map(Expr::ArrayExpression),
|
||||
))
|
||||
.parse_next(i)
|
||||
}
|
||||
@ -732,7 +731,20 @@ pub(crate) fn array_elem_by_elem(i: &mut TokenSlice) -> PResult<Node<ArrayExpres
|
||||
.context(expected("array contents, a list of elements (like [1, 2, 3])"))
|
||||
.parse_next(i)?;
|
||||
ignore_whitespace(i);
|
||||
let end = close_bracket(i)?.end;
|
||||
let end = close_bracket(i)
|
||||
.map_err(|e| {
|
||||
if let Some(mut err) = e.clone().into_inner() {
|
||||
err.cause = Some(CompilationError::fatal(
|
||||
open.as_source_range(),
|
||||
"Array is missing a closing bracket(`]`)",
|
||||
));
|
||||
ErrMode::Cut(err)
|
||||
} else {
|
||||
// ErrMode::Incomplete, not sure if it's actually possible to end up with this here
|
||||
e
|
||||
}
|
||||
})?
|
||||
.end;
|
||||
|
||||
// Sort the array's elements (i.e. expression nodes) from the noncode nodes.
|
||||
let (elements, non_code_nodes): (Vec<_>, HashMap<usize, _>) = elements.into_iter().enumerate().fold(
|
||||
@ -4319,6 +4331,13 @@ let myBox = box([0,0], -3, -16, -10)
|
||||
assert_no_err(some_program_string);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_missing_closing_bracket() {
|
||||
let some_program_string = r#"
|
||||
sketch001 = startSketchOn('XZ') |> startProfileAt([90.45, 119.09, %)"#;
|
||||
assert_err(some_program_string, "Array is missing a closing bracket(`]`)", [51, 52]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn warn_object_expr() {
|
||||
let some_program_string = "{ foo: bar }";
|
||||
|
@ -1677,3 +1677,66 @@ mod circle_three_point {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
}
|
||||
mod array_elem_pop {
|
||||
const TEST_NAME: &str = "array_elem_pop";
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[test]
|
||||
fn unparse() {
|
||||
super::unparse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, false).await
|
||||
}
|
||||
}
|
||||
mod array_elem_pop_empty_fail {
|
||||
const TEST_NAME: &str = "array_elem_pop_empty_fail";
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[test]
|
||||
fn unparse() {
|
||||
super::unparse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, false).await
|
||||
}
|
||||
}
|
||||
mod array_elem_pop_fail {
|
||||
const TEST_NAME: &str = "array_elem_pop_fail";
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[test]
|
||||
fn unparse() {
|
||||
super::unparse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, false).await
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ use super::shapes::PolygonType;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
ExecState, ExecutorContext, ExtrudeSurface, KclObjectFields, KclValue, Metadata, Sketch, SketchSet,
|
||||
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSet,
|
||||
SketchSurface, Solid, SolidSet, TagIdentifier,
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
source_range::SourceRange,
|
||||
std::{shapes::SketchOrSurface, sketch::FaceTag, FnAsArg},
|
||||
std::{shapes::SketchOrSurface, sketch::FaceTag, sweep::SweepPath, FnAsArg},
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
@ -634,7 +634,7 @@ where
|
||||
message: format!(
|
||||
"Argument at index {i} was supposed to be type {} but found {}",
|
||||
type_name::<T>(),
|
||||
arg.value.human_friendly_type()
|
||||
arg.value.human_friendly_type(),
|
||||
),
|
||||
source_ranges: arg.source_ranges(),
|
||||
}));
|
||||
@ -1105,13 +1105,34 @@ impl<'a> FromKclValue<'a> for super::appearance::AppearanceData {
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::helix::HelixData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, revolutions);
|
||||
let_field_of!(obj, length);
|
||||
let_field_of!(obj, ccw?);
|
||||
let_field_of!(obj, radius);
|
||||
let_field_of!(obj, axis);
|
||||
let ccw = ccw.unwrap_or_default();
|
||||
let angle_start = obj.get("angleStart")?.as_f64()?;
|
||||
Some(Self {
|
||||
revolutions,
|
||||
angle_start,
|
||||
ccw,
|
||||
length,
|
||||
radius,
|
||||
axis,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::helix::HelixRevolutionsData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, revolutions);
|
||||
let_field_of!(obj, length?);
|
||||
let_field_of!(obj, ccw?);
|
||||
let ccw = ccw.unwrap_or_default();
|
||||
let angle_start = obj.get("angleStart").or_else(|| obj.get("angle_start"))?.as_f64()?;
|
||||
let angle_start = obj.get("angleStart")?.as_f64()?;
|
||||
Some(Self {
|
||||
revolutions,
|
||||
angle_start,
|
||||
@ -1159,8 +1180,8 @@ impl<'a> FromKclValue<'a> for super::sketch::ArcData {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, radius);
|
||||
let case1 = || {
|
||||
let angle_start = obj.get("angleStart").or_else(|| obj.get("angle_start"))?.as_f64()?;
|
||||
let angle_end = obj.get("angleEnd").or_else(|| obj.get("angle_end"))?.as_f64()?;
|
||||
let angle_start = obj.get("angleStart")?.as_f64()?;
|
||||
let angle_end = obj.get("angleEnd")?.as_f64()?;
|
||||
Some(Self::AnglesAndRadius {
|
||||
angle_start,
|
||||
angle_end,
|
||||
@ -1256,21 +1277,9 @@ impl<'a> FromKclValue<'a> for super::sketch::PlaneData {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, plane, &KclObjectFields);
|
||||
let origin = plane.get("origin").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
|
||||
let x_axis = plane
|
||||
.get("xAxis")
|
||||
.or_else(|| plane.get("x_axis"))
|
||||
.and_then(FromKclValue::from_kcl_val)
|
||||
.map(Box::new)?;
|
||||
let y_axis = plane
|
||||
.get("yAxis")
|
||||
.or_else(|| plane.get("y_axis"))
|
||||
.and_then(FromKclValue::from_kcl_val)
|
||||
.map(Box::new)?;
|
||||
let z_axis = plane
|
||||
.get("zAxis")
|
||||
.or_else(|| plane.get("z_axis"))
|
||||
.and_then(FromKclValue::from_kcl_val)
|
||||
.map(Box::new)?;
|
||||
let x_axis = plane.get("xAxis").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
|
||||
let y_axis = plane.get("yAxis").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
|
||||
let z_axis = plane.get("zAxis").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
|
||||
Some(Self::Plane {
|
||||
origin,
|
||||
x_axis,
|
||||
@ -1442,7 +1451,7 @@ impl<'a> FromKclValue<'a> for super::sketch::SketchData {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::revolve::AxisAndOrigin {
|
||||
impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin2d {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
// Case 1: predefined planes.
|
||||
if let Some(s) = arg.as_str() {
|
||||
@ -1463,6 +1472,29 @@ impl<'a> FromKclValue<'a> for super::revolve::AxisAndOrigin {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin3d {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
// Case 1: predefined planes.
|
||||
if let Some(s) = arg.as_str() {
|
||||
return match s {
|
||||
"X" | "x" => Some(Self::X),
|
||||
"Y" | "y" => Some(Self::Y),
|
||||
"Z" | "z" => Some(Self::Z),
|
||||
"-X" | "-x" => Some(Self::NegX),
|
||||
"-Y" | "-y" => Some(Self::NegY),
|
||||
"-Z" | "-z" => Some(Self::NegZ),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
// Case 2: custom planes.
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, custom, &KclObjectFields);
|
||||
let_field_of!(custom, origin);
|
||||
let_field_of!(custom, axis);
|
||||
Some(Self::Custom { axis, origin })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::fillet::EdgeReference {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let id = arg.as_uuid().map(Self::Uuid);
|
||||
@ -1471,9 +1503,17 @@ impl<'a> FromKclValue<'a> for super::fillet::EdgeReference {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::revolve::AxisOrEdgeReference {
|
||||
impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis2dOrEdgeReference {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let case1 = super::revolve::AxisAndOrigin::from_kcl_val;
|
||||
let case1 = super::axis_or_reference::AxisAndOrigin2d::from_kcl_val;
|
||||
let case2 = super::fillet::EdgeReference::from_kcl_val;
|
||||
case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis3dOrEdgeReference {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let case1 = super::axis_or_reference::AxisAndOrigin3d::from_kcl_val;
|
||||
let case2 = super::fillet::EdgeReference::from_kcl_val;
|
||||
case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge))
|
||||
}
|
||||
@ -1584,6 +1624,24 @@ impl<'a> FromKclValue<'a> for Sketch {
|
||||
Some(value.as_ref().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for Helix {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let KclValue::Helix(value) = arg else {
|
||||
return None;
|
||||
};
|
||||
Some(value.as_ref().to_owned())
|
||||
}
|
||||
}
|
||||
impl<'a> FromKclValue<'a> for SweepPath {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let case1 = Sketch::from_kcl_val;
|
||||
let case2 = Helix::from_kcl_val;
|
||||
case1(arg)
|
||||
.map(Self::Sketch)
|
||||
.or_else(|| case2(arg).map(|arg0: Helix| Self::Helix(Box::new(arg0))))
|
||||
}
|
||||
}
|
||||
impl<'a> FromKclValue<'a> for String {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let KclValue::String { value, meta: _ } = arg else {
|
||||
|
@ -256,3 +256,55 @@ pub async fn push(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
};
|
||||
inner_push(array, elem, &args).await
|
||||
}
|
||||
|
||||
/// Remove the last element from an array.
|
||||
///
|
||||
/// Returns a new array with the last element removed.
|
||||
///
|
||||
/// ```no_run
|
||||
/// arr = [1, 2, 3, 4]
|
||||
/// new_arr = pop(arr)
|
||||
/// assertEqual(new_arr[0], 1, 0.00001, "1 is the first element of the array")
|
||||
/// assertEqual(new_arr[1], 2, 0.00001, "2 is the second element of the array")
|
||||
/// assertEqual(new_arr[2], 3, 0.00001, "3 is the third element of the array")
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "pop",
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
arg_docs = {
|
||||
array = "The array to pop from. Must not be empty.",
|
||||
}
|
||||
}]
|
||||
async fn inner_pop(array: Vec<KclValue>, args: &Args) -> Result<KclValue, KclError> {
|
||||
if array.is_empty() {
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
message: "Cannot pop from an empty array".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
|
||||
// Create a new array with all elements except the last one
|
||||
let new_array = array[..array.len() - 1].to_vec();
|
||||
|
||||
Ok(KclValue::Array {
|
||||
value: new_array,
|
||||
meta: vec![args.source_range.into()],
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn pop(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
// Extract the array from the arguments
|
||||
let val = args.get_unlabeled_kw_arg("array")?;
|
||||
|
||||
let meta = vec![args.source_range];
|
||||
let KclValue::Array { value: array, meta: _ } = val else {
|
||||
let actual_type = val.human_friendly_type();
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
source_ranges: meta,
|
||||
message: format!("You can't pop from a value of type {actual_type}, only an array"),
|
||||
}));
|
||||
};
|
||||
|
||||
inner_pop(array, &args).await
|
||||
}
|
||||
|
233
src/wasm-lib/kcl/src/std/axis_or_reference.rs
Normal file
@ -0,0 +1,233 @@
|
||||
//! Types for referencing an axis or edge.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::length_unit::LengthUnit;
|
||||
use kittycad_modeling_cmds::{self as kcmc};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{errors::KclError, std::fillet::EdgeReference};
|
||||
|
||||
/// A 2D axis or tagged edge.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(untagged)]
|
||||
pub enum Axis2dOrEdgeReference {
|
||||
/// 2D axis and origin.
|
||||
Axis(AxisAndOrigin2d),
|
||||
/// Tagged edge.
|
||||
Edge(EdgeReference),
|
||||
}
|
||||
|
||||
/// A 2D axis and origin.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum AxisAndOrigin2d {
|
||||
/// X-axis.
|
||||
#[serde(rename = "X", alias = "x")]
|
||||
X,
|
||||
/// Y-axis.
|
||||
#[serde(rename = "Y", alias = "y")]
|
||||
Y,
|
||||
/// Flip the X-axis.
|
||||
#[serde(rename = "-X", alias = "-x")]
|
||||
NegX,
|
||||
/// Flip the Y-axis.
|
||||
#[serde(rename = "-Y", alias = "-y")]
|
||||
NegY,
|
||||
Custom {
|
||||
/// The axis.
|
||||
axis: [f64; 2],
|
||||
/// The origin.
|
||||
origin: [f64; 2],
|
||||
},
|
||||
}
|
||||
|
||||
impl AxisAndOrigin2d {
|
||||
/// Get the axis and origin.
|
||||
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
|
||||
let (axis, origin) = match self {
|
||||
AxisAndOrigin2d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin2d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin2d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin2d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin2d::Custom { axis, origin } => ([axis[0], axis[1], 0.0], [origin[0], origin[1], 0.0]),
|
||||
};
|
||||
|
||||
Ok((
|
||||
kcmc::shared::Point3d {
|
||||
x: axis[0],
|
||||
y: axis[1],
|
||||
z: axis[2],
|
||||
},
|
||||
kcmc::shared::Point3d {
|
||||
x: LengthUnit(origin[0]),
|
||||
y: LengthUnit(origin[1]),
|
||||
z: LengthUnit(origin[2]),
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// A 3D axis or tagged edge.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(untagged)]
|
||||
pub enum Axis3dOrEdgeReference {
|
||||
/// 3D axis and origin.
|
||||
Axis(AxisAndOrigin3d),
|
||||
/// Tagged edge.
|
||||
Edge(EdgeReference),
|
||||
}
|
||||
|
||||
/// A 3D axis and origin.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum AxisAndOrigin3d {
|
||||
/// X-axis.
|
||||
#[serde(rename = "X", alias = "x")]
|
||||
X,
|
||||
/// Y-axis.
|
||||
#[serde(rename = "Y", alias = "y")]
|
||||
Y,
|
||||
/// Z-axis.
|
||||
#[serde(rename = "Z", alias = "z")]
|
||||
Z,
|
||||
/// Flip the X-axis.
|
||||
#[serde(rename = "-X", alias = "-x")]
|
||||
NegX,
|
||||
/// Flip the Y-axis.
|
||||
#[serde(rename = "-Y", alias = "-y")]
|
||||
NegY,
|
||||
/// Flip the Z-axis.
|
||||
#[serde(rename = "-Z", alias = "-z")]
|
||||
NegZ,
|
||||
Custom {
|
||||
/// The axis.
|
||||
axis: [f64; 3],
|
||||
/// The origin.
|
||||
origin: [f64; 3],
|
||||
},
|
||||
}
|
||||
|
||||
impl AxisAndOrigin3d {
|
||||
/// Get the axis and origin.
|
||||
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
|
||||
let (axis, origin) = match self {
|
||||
AxisAndOrigin3d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin3d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin3d::Z => ([0.0, 0.0, 1.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin3d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin3d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin3d::NegZ => ([0.0, 0.0, -1.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin3d::Custom { axis, origin } => {
|
||||
([axis[0], axis[1], axis[2]], [origin[0], origin[1], origin[2]])
|
||||
}
|
||||
};
|
||||
|
||||
Ok((
|
||||
kcmc::shared::Point3d {
|
||||
x: axis[0],
|
||||
y: axis[1],
|
||||
z: axis[2],
|
||||
},
|
||||
kcmc::shared::Point3d {
|
||||
x: LengthUnit(origin[0]),
|
||||
y: LengthUnit(origin[1]),
|
||||
z: LengthUnit(origin[2]),
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::std::axis_or_reference::{
|
||||
Axis2dOrEdgeReference, Axis3dOrEdgeReference, AxisAndOrigin2d, AxisAndOrigin3d,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_revolve_axis_2d() {
|
||||
let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::X);
|
||||
let mut str_json = serde_json::to_string(&data).unwrap();
|
||||
assert_eq!(str_json, "\"X\"");
|
||||
|
||||
str_json = "\"Y\"".to_string();
|
||||
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Y));
|
||||
|
||||
str_json = "\"-Y\"".to_string();
|
||||
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegY));
|
||||
|
||||
str_json = "\"-x\"".to_string();
|
||||
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegX));
|
||||
|
||||
let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom {
|
||||
axis: [0.0, -1.0],
|
||||
origin: [1.0, 0.0],
|
||||
});
|
||||
str_json = serde_json::to_string(&data).unwrap();
|
||||
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0],"origin":[1.0,0.0]}}"#);
|
||||
|
||||
str_json = r#"{"custom": {"axis": [0,-1], "origin": [1,2.0]}}"#.to_string();
|
||||
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(
|
||||
data,
|
||||
Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom {
|
||||
axis: [0.0, -1.0],
|
||||
origin: [1.0, 2.0]
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_revolve_axis_3d() {
|
||||
let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::X);
|
||||
let mut str_json = serde_json::to_string(&data).unwrap();
|
||||
assert_eq!(str_json, "\"X\"");
|
||||
|
||||
str_json = "\"Y\"".to_string();
|
||||
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Y));
|
||||
|
||||
str_json = "\"Z\"".to_string();
|
||||
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Z));
|
||||
|
||||
str_json = "\"-Y\"".to_string();
|
||||
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegY));
|
||||
|
||||
str_json = "\"-x\"".to_string();
|
||||
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegX));
|
||||
|
||||
str_json = "\"-z\"".to_string();
|
||||
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegZ));
|
||||
|
||||
let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom {
|
||||
axis: [0.0, -1.0, 0.0],
|
||||
origin: [1.0, 0.0, 0.0],
|
||||
});
|
||||
str_json = serde_json::to_string(&data).unwrap();
|
||||
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0,0.0],"origin":[1.0,0.0,0.0]}}"#);
|
||||
|
||||
str_json = r#"{"custom": {"axis": [0,-1,0], "origin": [1,2.0,0]}}"#.to_string();
|
||||
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(
|
||||
data,
|
||||
Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom {
|
||||
axis: [0.0, -1.0, 0.0],
|
||||
origin: [1.0, 2.0, 0.0]
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -9,14 +9,145 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{ExecState, KclValue, Solid},
|
||||
std::Args,
|
||||
execution::{ExecState, Helix as HelixValue, KclValue, Solid},
|
||||
std::{axis_or_reference::Axis3dOrEdgeReference, Args},
|
||||
};
|
||||
|
||||
/// Data for helices.
|
||||
/// Data for a helix.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
pub struct HelixData {
|
||||
/// Number of revolutions.
|
||||
pub revolutions: f64,
|
||||
/// Start angle (in degrees).
|
||||
#[serde(rename = "angleStart")]
|
||||
pub angle_start: f64,
|
||||
/// Is the helix rotation counter clockwise?
|
||||
/// The default is `false`.
|
||||
#[serde(default)]
|
||||
pub ccw: bool,
|
||||
/// Length of the helix.
|
||||
pub length: f64,
|
||||
/// Radius of the helix.
|
||||
pub radius: f64,
|
||||
/// Axis to use as mirror.
|
||||
pub axis: Axis3dOrEdgeReference,
|
||||
}
|
||||
|
||||
/// Create a helix.
|
||||
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let data: HelixData = args.get_data()?;
|
||||
|
||||
let helix = inner_helix(data, exec_state, args).await?;
|
||||
Ok(KclValue::Helix(helix))
|
||||
}
|
||||
|
||||
/// Create a helix.
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Create a helix around the Z axis.
|
||||
/// helixPath = helix({
|
||||
/// angleStart = 0,
|
||||
/// ccw = true,
|
||||
/// revolutions = 16,
|
||||
/// length = 10,
|
||||
/// radius = 5,
|
||||
/// axis = 'Z',
|
||||
/// })
|
||||
///
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn('YZ')
|
||||
/// |> circle({ center = [0, 0], radius = 1 }, %)
|
||||
/// //|> sweep({ path = helixPath }, %)
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Create a helix around an edge.
|
||||
/// /*helper001 = startSketchOn('XZ')
|
||||
/// |> startProfileAt([0, 0], %)
|
||||
/// |> line([0, 10], %, $edge001)
|
||||
///
|
||||
/// helixPath = helix({
|
||||
/// angleStart = 0,
|
||||
/// ccw = true,
|
||||
/// revolutions = 16,
|
||||
/// length = 10,
|
||||
/// radius = 5,
|
||||
/// axis = edge001,
|
||||
/// })
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn('XY')
|
||||
/// |> circle({ center = [0, 0], radius = 1 }, %)
|
||||
/// |> sweep({ path = helixPath }, %)*/
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "helix",
|
||||
feature_tree_operation = true,
|
||||
}]
|
||||
async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) -> Result<Box<HelixValue>, KclError> {
|
||||
let id = exec_state.next_uuid();
|
||||
|
||||
let helix_result = Box::new(HelixValue {
|
||||
value: id,
|
||||
revolutions: data.revolutions,
|
||||
angle_start: data.angle_start,
|
||||
ccw: data.ccw,
|
||||
meta: vec![args.source_range.into()],
|
||||
});
|
||||
|
||||
if args.ctx.is_mock() {
|
||||
return Ok(helix_result);
|
||||
}
|
||||
|
||||
match data.axis {
|
||||
Axis3dOrEdgeReference::Axis(axis) => {
|
||||
let (axis, origin) = axis.axis_and_origin()?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
ModelingCmd::from(mcmd::EntityMakeHelixFromParams {
|
||||
radius: data.radius,
|
||||
is_clockwise: !data.ccw,
|
||||
length: LengthUnit(data.length),
|
||||
revolutions: data.revolutions,
|
||||
start_angle: Angle::from_degrees(data.angle_start),
|
||||
axis,
|
||||
center: origin,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Axis3dOrEdgeReference::Edge(_edge) => {
|
||||
/*let edge_id = edge.get_engine_id(exec_state, &args)?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
ModelingCmd::from(mcmd::EntityMakeHelixFromEdge {
|
||||
radius: data.radius,
|
||||
is_clockwise: !data.ccw,
|
||||
length: LengthUnit(data.length),
|
||||
revolutions: data.revolutions,
|
||||
start_angle: Angle::from_degrees(data.angle_start),
|
||||
edge_id,
|
||||
}),
|
||||
)
|
||||
.await?;*/
|
||||
return Err(KclError::Unimplemented(crate::errors::KclErrorDetails {
|
||||
message: "Helix around edge is not yet implemented".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(helix_result)
|
||||
}
|
||||
|
||||
/// Data for helix revolutions.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
pub struct HelixRevolutionsData {
|
||||
/// Number of revolutions.
|
||||
pub revolutions: f64,
|
||||
/// Start angle (in degrees).
|
||||
@ -32,10 +163,10 @@ pub struct HelixData {
|
||||
}
|
||||
|
||||
/// Create a helix on a cylinder.
|
||||
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, solid): (HelixData, Box<Solid>) = args.get_data_and_solid()?;
|
||||
pub async fn helix_revolutions(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, solid): (HelixRevolutionsData, Box<Solid>) = args.get_data_and_solid()?;
|
||||
|
||||
let solid = inner_helix(data, solid, exec_state, args).await?;
|
||||
let solid = inner_helix_revolutions(data, solid, exec_state, args).await?;
|
||||
Ok(KclValue::Solid(solid))
|
||||
}
|
||||
|
||||
@ -45,18 +176,18 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// part001 = startSketchOn('XY')
|
||||
/// |> circle({ center: [5, 5], radius: 10 }, %)
|
||||
/// |> extrude(10, %)
|
||||
/// |> helix({
|
||||
/// |> helixRevolutions({
|
||||
/// angleStart = 0,
|
||||
/// ccw = true,
|
||||
/// revolutions = 16,
|
||||
/// }, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "helix",
|
||||
name = "helixRevolutions",
|
||||
feature_tree_operation = true,
|
||||
}]
|
||||
async fn inner_helix(
|
||||
data: HelixData,
|
||||
async fn inner_helix_revolutions(
|
||||
data: HelixRevolutionsData,
|
||||
solid: Box<Solid>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
|
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{ExecState, KclValue, Sketch, SketchSet},
|
||||
std::{revolve::AxisOrEdgeReference, Args},
|
||||
std::{axis_or_reference::Axis2dOrEdgeReference, Args},
|
||||
};
|
||||
|
||||
/// Data for a mirror.
|
||||
@ -19,7 +19,7 @@ use crate::{
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Mirror2dData {
|
||||
/// Axis to use as mirror.
|
||||
pub axis: AxisOrEdgeReference,
|
||||
pub axis: Axis2dOrEdgeReference,
|
||||
}
|
||||
|
||||
/// Mirror a sketch.
|
||||
@ -117,7 +117,7 @@ async fn inner_mirror_2d(
|
||||
}
|
||||
|
||||
match data.axis {
|
||||
AxisOrEdgeReference::Axis(axis) => {
|
||||
Axis2dOrEdgeReference::Axis(axis) => {
|
||||
let (axis, origin) = axis.axis_and_origin()?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
@ -130,7 +130,7 @@ async fn inner_mirror_2d(
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
AxisOrEdgeReference::Edge(edge) => {
|
||||
Axis2dOrEdgeReference::Edge(edge) => {
|
||||
let edge_id = edge.get_engine_id(exec_state, &args)?;
|
||||
|
||||
args.batch_modeling_cmd(
|
||||
|
@ -4,6 +4,7 @@ pub mod appearance;
|
||||
pub mod args;
|
||||
pub mod array;
|
||||
pub mod assert;
|
||||
pub mod axis_or_reference;
|
||||
pub mod chamfer;
|
||||
pub mod convert;
|
||||
pub mod extrude;
|
||||
@ -107,12 +108,14 @@ lazy_static! {
|
||||
Box::new(crate::std::array::Reduce),
|
||||
Box::new(crate::std::array::Map),
|
||||
Box::new(crate::std::array::Push),
|
||||
Box::new(crate::std::array::Pop),
|
||||
Box::new(crate::std::chamfer::Chamfer),
|
||||
Box::new(crate::std::fillet::Fillet),
|
||||
Box::new(crate::std::fillet::GetOppositeEdge),
|
||||
Box::new(crate::std::fillet::GetNextAdjacentEdge),
|
||||
Box::new(crate::std::fillet::GetPreviousAdjacentEdge),
|
||||
Box::new(crate::std::helix::Helix),
|
||||
Box::new(crate::std::helix::HelixRevolutions),
|
||||
Box::new(crate::std::shell::Shell),
|
||||
Box::new(crate::std::shell::Hollow),
|
||||
Box::new(crate::std::revolve::Revolve),
|
||||
|
@ -10,11 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{ExecState, KclValue, Sketch, Solid},
|
||||
std::{
|
||||
extrude::do_post_extrude,
|
||||
fillet::{default_tolerance, EdgeReference},
|
||||
Args,
|
||||
},
|
||||
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args},
|
||||
};
|
||||
|
||||
/// Data for revolution surfaces.
|
||||
@ -26,74 +22,12 @@ pub struct RevolveData {
|
||||
#[schemars(range(min = -360.0, max = 360.0))]
|
||||
pub angle: Option<f64>,
|
||||
/// Axis of revolution.
|
||||
pub axis: AxisOrEdgeReference,
|
||||
pub axis: Axis2dOrEdgeReference,
|
||||
/// Tolerance for the revolve operation.
|
||||
#[serde(default)]
|
||||
pub tolerance: Option<f64>,
|
||||
}
|
||||
|
||||
/// Axis or tagged edge.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(untagged)]
|
||||
pub enum AxisOrEdgeReference {
|
||||
/// Axis and origin.
|
||||
Axis(AxisAndOrigin),
|
||||
/// Tagged edge.
|
||||
Edge(EdgeReference),
|
||||
}
|
||||
|
||||
/// Axis and origin.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum AxisAndOrigin {
|
||||
/// X-axis.
|
||||
#[serde(rename = "X", alias = "x")]
|
||||
X,
|
||||
/// Y-axis.
|
||||
#[serde(rename = "Y", alias = "y")]
|
||||
Y,
|
||||
/// Flip the X-axis.
|
||||
#[serde(rename = "-X", alias = "-x")]
|
||||
NegX,
|
||||
/// Flip the Y-axis.
|
||||
#[serde(rename = "-Y", alias = "-y")]
|
||||
NegY,
|
||||
Custom {
|
||||
/// The axis.
|
||||
axis: [f64; 2],
|
||||
/// The origin.
|
||||
origin: [f64; 2],
|
||||
},
|
||||
}
|
||||
|
||||
impl AxisAndOrigin {
|
||||
/// Get the axis and origin.
|
||||
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
|
||||
let (axis, origin) = match self {
|
||||
AxisAndOrigin::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
|
||||
AxisAndOrigin::Custom { axis, origin } => ([axis[0], axis[1], 0.0], [origin[0], origin[1], 0.0]),
|
||||
};
|
||||
|
||||
Ok((
|
||||
kcmc::shared::Point3d {
|
||||
x: axis[0],
|
||||
y: axis[1],
|
||||
z: axis[2],
|
||||
},
|
||||
kcmc::shared::Point3d {
|
||||
x: LengthUnit(origin[0]),
|
||||
y: LengthUnit(origin[1]),
|
||||
z: LengthUnit(origin[2]),
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Revolve a sketch around an axis.
|
||||
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, sketch): (RevolveData, Sketch) = args.get_data_and_sketch()?;
|
||||
@ -266,7 +200,7 @@ async fn inner_revolve(
|
||||
|
||||
let id = exec_state.next_uuid();
|
||||
match data.axis {
|
||||
AxisOrEdgeReference::Axis(axis) => {
|
||||
Axis2dOrEdgeReference::Axis(axis) => {
|
||||
let (axis, origin) = axis.axis_and_origin()?;
|
||||
args.batch_modeling_cmd(
|
||||
id,
|
||||
@ -281,7 +215,7 @@ async fn inner_revolve(
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
AxisOrEdgeReference::Edge(edge) => {
|
||||
Axis2dOrEdgeReference::Edge(edge) => {
|
||||
let edge_id = edge.get_engine_id(exec_state, &args)?;
|
||||
args.batch_modeling_cmd(
|
||||
id,
|
||||
@ -298,47 +232,3 @@ async fn inner_revolve(
|
||||
|
||||
do_post_extrude(sketch, 0.0, exec_state, args).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::std::revolve::{AxisAndOrigin, AxisOrEdgeReference};
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_revolve_axis() {
|
||||
let data = AxisOrEdgeReference::Axis(AxisAndOrigin::X);
|
||||
let mut str_json = serde_json::to_string(&data).unwrap();
|
||||
assert_eq!(str_json, "\"X\"");
|
||||
|
||||
str_json = "\"Y\"".to_string();
|
||||
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, AxisOrEdgeReference::Axis(AxisAndOrigin::Y));
|
||||
|
||||
str_json = "\"-Y\"".to_string();
|
||||
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, AxisOrEdgeReference::Axis(AxisAndOrigin::NegY));
|
||||
|
||||
str_json = "\"-x\"".to_string();
|
||||
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(data, AxisOrEdgeReference::Axis(AxisAndOrigin::NegX));
|
||||
|
||||
let data = AxisOrEdgeReference::Axis(AxisAndOrigin::Custom {
|
||||
axis: [0.0, -1.0],
|
||||
origin: [1.0, 0.0],
|
||||
});
|
||||
str_json = serde_json::to_string(&data).unwrap();
|
||||
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0],"origin":[1.0,0.0]}}"#);
|
||||
|
||||
str_json = r#"{"custom": {"axis": [0,-1], "origin": [1,2.0]}}"#.to_string();
|
||||
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
|
||||
assert_eq!(
|
||||
data,
|
||||
AxisOrEdgeReference::Axis(AxisAndOrigin::Custom {
|
||||
axis: [0.0, -1.0],
|
||||
origin: [1.0, 2.0]
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,25 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{ExecState, KclValue, Sketch, Solid},
|
||||
execution::{ExecState, Helix, KclValue, Sketch, Solid},
|
||||
std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
|
||||
};
|
||||
|
||||
/// A path to sweep along.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(untagged)]
|
||||
pub enum SweepPath {
|
||||
Sketch(Sketch),
|
||||
Helix(Box<Helix>),
|
||||
}
|
||||
|
||||
/// Data for a sweep.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
pub struct SweepData {
|
||||
/// The path to sweep along.
|
||||
pub path: Sketch,
|
||||
pub path: SweepPath,
|
||||
/// If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components.
|
||||
pub sectional: Option<bool>,
|
||||
/// Tolerance for the sweep operation.
|
||||
@ -77,6 +86,26 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// path: sweepPath,
|
||||
/// }, %)
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Create a spring by sweeping around a helix path.
|
||||
///
|
||||
/// // Create a helix around the Z axis.
|
||||
/// helixPath = helix({
|
||||
/// angleStart = 0,
|
||||
/// ccw = true,
|
||||
/// revolutions = 16,
|
||||
/// length = 10,
|
||||
/// radius = 5,
|
||||
/// axis = 'Z',
|
||||
/// })
|
||||
///
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn('YZ')
|
||||
/// |> circle({ center = [0, 0], radius = 1 }, %)
|
||||
/// //|> sweep({ path = helixPath }, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "sweep",
|
||||
feature_tree_operation = true,
|
||||
@ -92,7 +121,10 @@ async fn inner_sweep(
|
||||
id,
|
||||
ModelingCmd::from(mcmd::Sweep {
|
||||
target: sketch.id.into(),
|
||||
trajectory: data.path.id.into(),
|
||||
trajectory: match data.path {
|
||||
SweepPath::Sketch(sketch) => sketch.id.into(),
|
||||
SweepPath::Helix(helix) => helix.value.into(),
|
||||
},
|
||||
sectional: data.sectional.unwrap_or(false),
|
||||
tolerance: LengthUnit(data.tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
|
||||
}),
|
||||
|
377
src/wasm-lib/kcl/tests/array_elem_pop/ast.snap
Normal file
@ -0,0 +1,377 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing array_elem_pop.kcl
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
"body": [
|
||||
{
|
||||
"declaration": {
|
||||
"end": 15,
|
||||
"id": {
|
||||
"end": 3,
|
||||
"name": "arr",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 8,
|
||||
"raw": "1",
|
||||
"start": 7,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"end": 11,
|
||||
"raw": "2",
|
||||
"start": 10,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 2.0
|
||||
},
|
||||
{
|
||||
"end": 14,
|
||||
"raw": "3",
|
||||
"start": 13,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 3.0
|
||||
}
|
||||
],
|
||||
"end": 15,
|
||||
"start": 6,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 15,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 35,
|
||||
"id": {
|
||||
"end": 24,
|
||||
"name": "new_arr1",
|
||||
"start": 16,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 34,
|
||||
"name": "arr",
|
||||
"start": 31,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 30,
|
||||
"name": "pop",
|
||||
"start": 27,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 35,
|
||||
"start": 27,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 16,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 35,
|
||||
"kind": "const",
|
||||
"start": 16,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 60,
|
||||
"id": {
|
||||
"end": 44,
|
||||
"name": "new_arr2",
|
||||
"start": 36,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 59,
|
||||
"name": "new_arr1",
|
||||
"start": 51,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 50,
|
||||
"name": "pop",
|
||||
"start": 47,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 60,
|
||||
"start": 47,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 36,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 60,
|
||||
"kind": "const",
|
||||
"start": 36,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 85,
|
||||
"id": {
|
||||
"end": 69,
|
||||
"name": "new_arr3",
|
||||
"start": 61,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 84,
|
||||
"name": "new_arr2",
|
||||
"start": 76,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 75,
|
||||
"name": "pop",
|
||||
"start": 72,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 85,
|
||||
"start": 72,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 61,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 85,
|
||||
"kind": "const",
|
||||
"start": 61,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"end": 159,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"computed": false,
|
||||
"end": 109,
|
||||
"object": {
|
||||
"end": 106,
|
||||
"name": "new_arr1",
|
||||
"start": 98,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
},
|
||||
"property": {
|
||||
"end": 108,
|
||||
"raw": "0",
|
||||
"start": 107,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 0.0
|
||||
},
|
||||
"start": 98,
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression"
|
||||
},
|
||||
{
|
||||
"end": 112,
|
||||
"raw": "1",
|
||||
"start": 111,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"end": 121,
|
||||
"raw": "0.00001",
|
||||
"start": 114,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 0.00001
|
||||
},
|
||||
{
|
||||
"end": 158,
|
||||
"raw": "\"element 0 should not have changed\"",
|
||||
"start": 123,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "element 0 should not have changed"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 97,
|
||||
"name": "assertEqual",
|
||||
"start": 86,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 159,
|
||||
"start": 86,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 86,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"end": 233,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"computed": false,
|
||||
"end": 183,
|
||||
"object": {
|
||||
"end": 180,
|
||||
"name": "new_arr1",
|
||||
"start": 172,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
},
|
||||
"property": {
|
||||
"end": 182,
|
||||
"raw": "1",
|
||||
"start": 181,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 1.0
|
||||
},
|
||||
"start": 172,
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression"
|
||||
},
|
||||
{
|
||||
"end": 186,
|
||||
"raw": "2",
|
||||
"start": 185,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 2.0
|
||||
},
|
||||
{
|
||||
"end": 195,
|
||||
"raw": "0.00001",
|
||||
"start": 188,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 0.00001
|
||||
},
|
||||
{
|
||||
"end": 232,
|
||||
"raw": "\"element 1 should not have changed\"",
|
||||
"start": 197,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "element 1 should not have changed"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 171,
|
||||
"name": "assertEqual",
|
||||
"start": 160,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 233,
|
||||
"start": 160,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 160,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"end": 307,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"computed": false,
|
||||
"end": 257,
|
||||
"object": {
|
||||
"end": 254,
|
||||
"name": "new_arr2",
|
||||
"start": 246,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
},
|
||||
"property": {
|
||||
"end": 256,
|
||||
"raw": "0",
|
||||
"start": 255,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 0.0
|
||||
},
|
||||
"start": 246,
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression"
|
||||
},
|
||||
{
|
||||
"end": 260,
|
||||
"raw": "1",
|
||||
"start": 259,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"end": 269,
|
||||
"raw": "0.00001",
|
||||
"start": 262,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 0.00001
|
||||
},
|
||||
{
|
||||
"end": 306,
|
||||
"raw": "\"element 0 should not have changed\"",
|
||||
"start": 271,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "element 0 should not have changed"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 245,
|
||||
"name": "assertEqual",
|
||||
"start": 234,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 307,
|
||||
"start": 234,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 234,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
}
|
||||
],
|
||||
"end": 308,
|
||||
"start": 0
|
||||
}
|
||||
}
|
7
src/wasm-lib/kcl/tests/array_elem_pop/input.kcl
Normal file
@ -0,0 +1,7 @@
|
||||
arr = [1, 2, 3]
|
||||
new_arr1 = pop(arr)
|
||||
new_arr2 = pop(new_arr1)
|
||||
new_arr3 = pop(new_arr2)
|
||||
assertEqual(new_arr1[0], 1, 0.00001, "element 0 should not have changed")
|
||||
assertEqual(new_arr1[1], 2, 0.00001, "element 1 should not have changed")
|
||||
assertEqual(new_arr2[0], 1, 0.00001, "element 0 should not have changed")
|
5
src/wasm-lib/kcl/tests/array_elem_pop/ops.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Operations executed array_elem_pop.kcl
|
||||
---
|
||||
[]
|
168
src/wasm-lib/kcl/tests/array_elem_pop/program_memory.snap
Normal file
@ -0,0 +1,168 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing array_elem_pop.kcl
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
"bindings": {
|
||||
"HALF_TURN": {
|
||||
"type": "Number",
|
||||
"value": 180.0,
|
||||
"__meta": []
|
||||
},
|
||||
"QUARTER_TURN": {
|
||||
"type": "Number",
|
||||
"value": 90.0,
|
||||
"__meta": []
|
||||
},
|
||||
"THREE_QUARTER_TURN": {
|
||||
"type": "Number",
|
||||
"value": 270.0,
|
||||
"__meta": []
|
||||
},
|
||||
"ZERO": {
|
||||
"type": "Number",
|
||||
"value": 0.0,
|
||||
"__meta": []
|
||||
},
|
||||
"arr": {
|
||||
"type": "Array",
|
||||
"value": [
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 1.0,
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
7,
|
||||
8,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 2.0,
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
10,
|
||||
11,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 3.0,
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
13,
|
||||
14,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
6,
|
||||
15,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"new_arr1": {
|
||||
"type": "Array",
|
||||
"value": [
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 1.0,
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
7,
|
||||
8,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 2.0,
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
10,
|
||||
11,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
27,
|
||||
35,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"new_arr2": {
|
||||
"type": "Array",
|
||||
"value": [
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 1.0,
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
7,
|
||||
8,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
47,
|
||||
60,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"new_arr3": {
|
||||
"type": "Array",
|
||||
"value": [],
|
||||
"__meta": [
|
||||
{
|
||||
"sourceRange": [
|
||||
72,
|
||||
85,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"parent": null
|
||||
}
|
||||
],
|
||||
"currentEnv": 0,
|
||||
"return": null
|
||||
}
|
76
src/wasm-lib/kcl/tests/array_elem_pop_empty_fail/ast.snap
Normal file
@ -0,0 +1,76 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing array_elem_pop_empty_fail.kcl
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
"body": [
|
||||
{
|
||||
"declaration": {
|
||||
"end": 8,
|
||||
"id": {
|
||||
"end": 3,
|
||||
"name": "arr",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"elements": [],
|
||||
"end": 8,
|
||||
"start": 6,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 8,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 24,
|
||||
"id": {
|
||||
"end": 13,
|
||||
"name": "fail",
|
||||
"start": 9,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 23,
|
||||
"name": "arr",
|
||||
"start": 20,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 19,
|
||||
"name": "pop",
|
||||
"start": 16,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 24,
|
||||
"start": 16,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 9,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 24,
|
||||
"kind": "const",
|
||||
"start": 9,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 25,
|
||||
"start": 0
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Error from executing array_elem_pop_empty_fail.kcl
|
||||
---
|
||||
KCL Semantic error
|
||||
|
||||
× semantic: Cannot pop from an empty array
|
||||
╭─[2:8]
|
||||
1 │ arr = []
|
||||
2 │ fail = pop(arr)
|
||||
· ────────
|
||||
╰────
|
@ -0,0 +1,2 @@
|
||||
arr = []
|
||||
fail = pop(arr)
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Operations executed array_elem_pop_empty_fail.kcl
|
||||
---
|
||||
[]
|
141
src/wasm-lib/kcl/tests/array_elem_pop_fail/ast.snap
Normal file
@ -0,0 +1,141 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing array_elem_pop_fail.kcl
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
"body": [
|
||||
{
|
||||
"declaration": {
|
||||
"end": 15,
|
||||
"id": {
|
||||
"end": 3,
|
||||
"name": "arr",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 8,
|
||||
"raw": "1",
|
||||
"start": 7,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 1.0
|
||||
},
|
||||
{
|
||||
"end": 11,
|
||||
"raw": "2",
|
||||
"start": 10,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 2.0
|
||||
},
|
||||
{
|
||||
"end": 14,
|
||||
"raw": "3",
|
||||
"start": 13,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 3.0
|
||||
}
|
||||
],
|
||||
"end": 15,
|
||||
"start": 6,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 15,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 36,
|
||||
"id": {
|
||||
"end": 25,
|
||||
"name": "pushedArr",
|
||||
"start": 16,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 35,
|
||||
"name": "arr",
|
||||
"start": 32,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 31,
|
||||
"name": "pop",
|
||||
"start": 28,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 36,
|
||||
"start": 28,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
},
|
||||
"start": 16,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 36,
|
||||
"kind": "const",
|
||||
"start": 16,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 56,
|
||||
"id": {
|
||||
"end": 41,
|
||||
"name": "fail",
|
||||
"start": 37,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"computed": false,
|
||||
"end": 56,
|
||||
"object": {
|
||||
"end": 53,
|
||||
"name": "pushedArr",
|
||||
"start": 44,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
},
|
||||
"property": {
|
||||
"end": 55,
|
||||
"raw": "2",
|
||||
"start": 54,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 2.0
|
||||
},
|
||||
"start": 44,
|
||||
"type": "MemberExpression",
|
||||
"type": "MemberExpression"
|
||||
},
|
||||
"start": 37,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 56,
|
||||
"kind": "const",
|
||||
"start": 37,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 57,
|
||||
"start": 0
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Error from executing array_elem_pop_fail.kcl
|
||||
---
|
||||
KCL UndefinedValue error
|
||||
|
||||
× undefined value: The array doesn't have any item at index 2
|
||||
╭─[3:8]
|
||||
2 │ pushedArr = pop(arr)
|
||||
3 │ fail = pushedArr[2]
|
||||
· ────────────
|
||||
╰────
|
3
src/wasm-lib/kcl/tests/array_elem_pop_fail/input.kcl
Normal file
@ -0,0 +1,3 @@
|
||||
arr = [1, 2, 3]
|
||||
pushedArr = pop(arr)
|
||||
fail = pushedArr[2]
|
5
src/wasm-lib/kcl/tests/array_elem_pop_fail/ops.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Operations executed array_elem_pop_fail.kcl
|
||||
---
|
||||
[]
|
@ -1,13 +1,14 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing helix_ccw.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
"body": [
|
||||
{
|
||||
"declaration": {
|
||||
"end": 188,
|
||||
"end": 199,
|
||||
"id": {
|
||||
"end": 7,
|
||||
"name": "part001",
|
||||
@ -151,90 +152,90 @@ description: Result of parsing helix_ccw.kcl
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"end": 184,
|
||||
"end": 195,
|
||||
"properties": [
|
||||
{
|
||||
"end": 135,
|
||||
"end": 146,
|
||||
"key": {
|
||||
"end": 130,
|
||||
"end": 141,
|
||||
"name": "revolutions",
|
||||
"start": 119,
|
||||
"start": 130,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 119,
|
||||
"start": 130,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 135,
|
||||
"end": 146,
|
||||
"raw": "16",
|
||||
"start": 133,
|
||||
"start": 144,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 16.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 158,
|
||||
"end": 169,
|
||||
"key": {
|
||||
"end": 154,
|
||||
"end": 165,
|
||||
"name": "angleStart",
|
||||
"start": 144,
|
||||
"start": 155,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 144,
|
||||
"start": 155,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 158,
|
||||
"end": 169,
|
||||
"raw": "0",
|
||||
"start": 157,
|
||||
"start": 168,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 177,
|
||||
"end": 188,
|
||||
"key": {
|
||||
"end": 170,
|
||||
"end": 181,
|
||||
"name": "ccw",
|
||||
"start": 167,
|
||||
"start": 178,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 167,
|
||||
"start": 178,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 177,
|
||||
"end": 188,
|
||||
"raw": "true",
|
||||
"start": 173,
|
||||
"start": 184,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 110,
|
||||
"start": 121,
|
||||
"type": "ObjectExpression",
|
||||
"type": "ObjectExpression"
|
||||
},
|
||||
{
|
||||
"end": 187,
|
||||
"start": 186,
|
||||
"end": 198,
|
||||
"start": 197,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 109,
|
||||
"name": "helix",
|
||||
"end": 120,
|
||||
"name": "helixRevolutions",
|
||||
"start": 104,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 188,
|
||||
"end": 199,
|
||||
"start": 104,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
}
|
||||
],
|
||||
"end": 188,
|
||||
"end": 199,
|
||||
"start": 10,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
@ -242,14 +243,14 @@ description: Result of parsing helix_ccw.kcl
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 188,
|
||||
"end": 199,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 189,
|
||||
"end": 200,
|
||||
"start": 0
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
part001 = startSketchOn('XY')
|
||||
|> circle({ center = [5, 5], radius = 10 }, %)
|
||||
|> extrude(10, %)
|
||||
|> helix({
|
||||
|> helixRevolutions({
|
||||
revolutions = 16,
|
||||
angleStart = 0,
|
||||
ccw = true
|
||||
|
@ -53,23 +53,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
110,
|
||||
184,
|
||||
121,
|
||||
195,
|
||||
0
|
||||
]
|
||||
},
|
||||
"solid": {
|
||||
"sourceRange": [
|
||||
186,
|
||||
187,
|
||||
197,
|
||||
198,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "helix",
|
||||
"name": "helixRevolutions",
|
||||
"sourceRange": [
|
||||
104,
|
||||
188,
|
||||
199,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
|
BIN
src/wasm-lib/kcl/tests/kw_fn/rendered_model.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 182 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_helix1.png
Normal file
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 132 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_pop0.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_sweep1.png
Normal file
After Width: | Height: | Size: 182 KiB |
@ -2,8 +2,8 @@ triangleHeight = 200
|
||||
plumbusLen = 100
|
||||
radius = 80
|
||||
circ = {
|
||||
angle_start = 0,
|
||||
angle_end = 360,
|
||||
angleStart = 0,
|
||||
angleEnd = 360,
|
||||
radius = radius
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,16 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
154,
|
||||
158,
|
||||
152,
|
||||
156,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [
|
||||
140,
|
||||
159,
|
||||
138,
|
||||
157,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -27,23 +27,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"sourceRange": [
|
||||
389,
|
||||
387,
|
||||
401,
|
||||
0
|
||||
]
|
||||
},
|
||||
"sketch_set": {
|
||||
"sourceRange": [
|
||||
403,
|
||||
0
|
||||
]
|
||||
},
|
||||
"sketch_set": {
|
||||
"sourceRange": [
|
||||
405,
|
||||
406,
|
||||
404,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [
|
||||
381,
|
||||
407,
|
||||
379,
|
||||
405,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -53,15 +53,15 @@ snapshot_kind: text
|
||||
"type": "UserDefinedFunctionCall",
|
||||
"name": "circl",
|
||||
"functionSourceRange": [
|
||||
417,
|
||||
567,
|
||||
415,
|
||||
565,
|
||||
0
|
||||
],
|
||||
"unlabeledArg": null,
|
||||
"labeledArgs": {},
|
||||
"sourceRange": [
|
||||
574,
|
||||
588,
|
||||
572,
|
||||
586,
|
||||
0
|
||||
]
|
||||
},
|
||||
@ -69,23 +69,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
452,
|
||||
453,
|
||||
450,
|
||||
451,
|
||||
0
|
||||
]
|
||||
},
|
||||
"tag": {
|
||||
"sourceRange": [
|
||||
455,
|
||||
459,
|
||||
453,
|
||||
457,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [
|
||||
438,
|
||||
460,
|
||||
436,
|
||||
458,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -98,23 +98,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"sourceRange": [
|
||||
616,
|
||||
614,
|
||||
624,
|
||||
0
|
||||
]
|
||||
},
|
||||
"sketch_set": {
|
||||
"sourceRange": [
|
||||
626,
|
||||
0
|
||||
]
|
||||
},
|
||||
"sketch_set": {
|
||||
"sourceRange": [
|
||||
628,
|
||||
629,
|
||||
627,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [
|
||||
608,
|
||||
630,
|
||||
606,
|
||||
628,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -124,23 +124,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
643,
|
||||
763,
|
||||
641,
|
||||
761,
|
||||
0
|
||||
]
|
||||
},
|
||||
"solid": {
|
||||
"sourceRange": [
|
||||
765,
|
||||
766,
|
||||
763,
|
||||
764,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "fillet",
|
||||
"sourceRange": [
|
||||
636,
|
||||
767,
|
||||
634,
|
||||
765,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -150,15 +150,15 @@ snapshot_kind: text
|
||||
"type": "UserDefinedFunctionCall",
|
||||
"name": "circl",
|
||||
"functionSourceRange": [
|
||||
417,
|
||||
567,
|
||||
415,
|
||||
565,
|
||||
0
|
||||
],
|
||||
"unlabeledArg": null,
|
||||
"labeledArgs": {},
|
||||
"sourceRange": [
|
||||
773,
|
||||
786,
|
||||
771,
|
||||
784,
|
||||
0
|
||||
]
|
||||
},
|
||||
@ -166,23 +166,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
452,
|
||||
453,
|
||||
450,
|
||||
451,
|
||||
0
|
||||
]
|
||||
},
|
||||
"tag": {
|
||||
"sourceRange": [
|
||||
455,
|
||||
459,
|
||||
453,
|
||||
457,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [
|
||||
438,
|
||||
460,
|
||||
436,
|
||||
458,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -195,23 +195,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"sourceRange": [
|
||||
814,
|
||||
824,
|
||||
812,
|
||||
822,
|
||||
0
|
||||
]
|
||||
},
|
||||
"sketch_set": {
|
||||
"sourceRange": [
|
||||
826,
|
||||
827,
|
||||
824,
|
||||
825,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [
|
||||
806,
|
||||
828,
|
||||
804,
|
||||
826,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
@ -221,23 +221,23 @@ snapshot_kind: text
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"sourceRange": [
|
||||
841,
|
||||
961,
|
||||
839,
|
||||
959,
|
||||
0
|
||||
]
|
||||
},
|
||||
"solid": {
|
||||
"sourceRange": [
|
||||
963,
|
||||
964,
|
||||
961,
|
||||
962,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "fillet",
|
||||
"sourceRange": [
|
||||
834,
|
||||
965,
|
||||
832,
|
||||
963,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
|
@ -4,6 +4,6 @@ const height = 3
|
||||
|
||||
const body = startSketchOn('XY')
|
||||
|> startProfileAt([center[0]+radius, center[1]], %)
|
||||
|> arc({angle_end: 360, angle_start: 0, radius: radius}, %)
|
||||
|> arc({angleEnd: 360, angleStart: 0, radius: radius}, %)
|
||||
|> close(%)
|
||||
|> extrude(height, %)
|
||||
|
@ -12,9 +12,9 @@ const extrude000 = extrude(1.0, sketch000)
|
||||
const plane005 = {
|
||||
plane: {
|
||||
origin: [0.0, 0.0, 1.0],
|
||||
x_axis: [0.707107, 0.707107, 0.0],
|
||||
y_axis: [-0.0, 0.0, 1.0],
|
||||
z_axis: [0.707107, -0.707107, 0.0]
|
||||
xAxis: [0.707107, 0.707107, 0.0],
|
||||
yAxis: [-0.0, 0.0, 1.0],
|
||||
zAxis: [0.707107, -0.707107, 0.0]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,9 @@ fn rectShape = (pos, w, l) => {
|
||||
const bracketPlane = {
|
||||
plane: {
|
||||
origin: { x: 0, y: length / 2 + thk, z: 0 },
|
||||
x_axis: { x: 1, y: 0, z: 0 },
|
||||
y_axis: { x: 0, y: 0, z: 1 },
|
||||
z_axis: { x: 0, y: -1, z: 0 }
|
||||
xAxis: { x: 1, y: 0, z: 0 },
|
||||
yAxis: { x: 0, y: 0, z: 1 },
|
||||
zAxis: { x: 0, y: -1, z: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,9 @@ fn rectShape = (pos, w, l) => {
|
||||
const bracketPlane = {
|
||||
plane: {
|
||||
origin: { x: 0, y: length / 2 + thk, z: 0 },
|
||||
x_axis: { x: 1, y: 0, z: 0 },
|
||||
y_axis: { x: 0, y: 0, z: 1 },
|
||||
z_axis: { x: 0, y: -1, z: 0 }
|
||||
xAxis: { x: 1, y: 0, z: 0 },
|
||||
yAxis: { x: 0, y: 0, z: 1 },
|
||||
zAxis: { x: 0, y: -1, z: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,9 +67,9 @@ const bracketBody = bs
|
||||
const tabPlane = {
|
||||
plane: {
|
||||
origin: { x: 0, y: 0, z: depth + thk },
|
||||
x_axis: { x: 1, y: 0, z: 0 },
|
||||
y_axis: { x: 0, y: 1, z: 0 },
|
||||
z_axis: { x: 0, y: 0, z: 1 }
|
||||
xAxis: { x: 1, y: 0, z: 0 },
|
||||
yAxis: { x: 0, y: 1, z: 0 },
|
||||
zAxis: { x: 0, y: 0, z: 1 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,9 +133,9 @@ const tabsL = startSketchOn(tabPlane)
|
||||
const retPlane = {
|
||||
plane: {
|
||||
origin: { x: -width / 2 + 20, y: 0, z: 0 },
|
||||
x_axis: { x: 0, y: 1, z: 0 },
|
||||
y_axis: { x: 0, y: 0, z: 1 },
|
||||
z_axis: { x: 1, y: 0, z: 0 }
|
||||
xAxis: { x: 0, y: 1, z: 0 },
|
||||
yAxis: { x: 0, y: 0, z: 1 },
|
||||
zAxis: { x: 1, y: 0, z: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
const part001 = startSketchOn('XY')
|
||||
|> circle({ center: [5, 5], radius: 10 }, %)
|
||||
|> extrude(10, %)
|
||||
|> helix({revolutions: 16, angle_start: 0}, %)
|
||||
|> helixRevolutions({revolutions = 16, angleStart = 0}, %)
|
||||
|
@ -1,4 +1,4 @@
|
||||
const part001 = startSketchOn('XY')
|
||||
|> circle({ center: [5, 5], radius: 10 }, %)
|
||||
|> extrude(-10, %)
|
||||
|> helix({revolutions: 16, angle_start: 0}, %)
|
||||
|> helixRevolutions({revolutions = 16, angleStart = 0}, %)
|
||||
|
@ -1,4 +1,4 @@
|
||||
const part001 = startSketchOn('XY')
|
||||
|> circle({ center: [5, 5], radius: 10 }, %)
|
||||
|> extrude(10, %)
|
||||
|> helix({revolutions: 16, angle_start: 0, length: 3}, %)
|
||||
|> helixRevolutions({revolutions = 16, angleStart = 0, length = 3}, %)
|
||||
|
@ -2,13 +2,13 @@
|
||||
const plane94894440791888 = {
|
||||
plane: {
|
||||
origin: [0.005000000000000001, 0.01, -0.005],
|
||||
x_axis: [
|
||||
xAxis: [
|
||||
0.9285064634886234,
|
||||
0.37131623619207604,
|
||||
0.0
|
||||
],
|
||||
y_axis: [-0.0, 0.0, 1.0],
|
||||
z_axis: [
|
||||
yAxis: [-0.0, 0.0, 1.0],
|
||||
zAxis: [
|
||||
0.37131623619207604,
|
||||
-0.9285064634886234,
|
||||
0.0
|
||||
|
@ -2,13 +2,13 @@
|
||||
const plane94894440791888 = {
|
||||
plane: {
|
||||
origin: [0.005000000000000001, 0.01, -0.005],
|
||||
x_axis: [
|
||||
xAxis: [
|
||||
0.9285064634886234,
|
||||
0.37131623619207604,
|
||||
0.0
|
||||
],
|
||||
y_axis: [-0.0, 0.0, 1.0],
|
||||
z_axis: [
|
||||
yAxis: [-0.0, 0.0, 1.0],
|
||||
zAxis: [
|
||||
0.37131623619207604,
|
||||
-0.9285064634886234,
|
||||
0.0
|
||||
|
@ -13,8 +13,8 @@ const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, depth - templateGap], %)
|
||||
|> xLine(length001, %, $seg01)
|
||||
|> arc({
|
||||
angle_end: 0,
|
||||
angle_start: 90,
|
||||
angleEnd: 0,
|
||||
angleStart: 90,
|
||||
radius: radius - templateGap
|
||||
}, %)
|
||||
|> yLineTo(-templateGap * 2 - (templateDiameter / 2), %, $seg05)
|
||||
@ -26,8 +26,8 @@ const sketch001 = startSketchOn('XZ')
|
||||
|> xLine(segLen(seg04, %), %)
|
||||
|> yLine(segLen(seg05, %), %)
|
||||
|> arc({
|
||||
angle_end: 90,
|
||||
angle_start: 180,
|
||||
angleEnd: 90,
|
||||
angleStart: 180,
|
||||
radius: radius - templateGap
|
||||
}, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|
@ -285,7 +285,7 @@ async fn optional_params() {
|
||||
fn other_circle = (pos, radius, tag?) => {
|
||||
sg = startSketchOn('XY')
|
||||
|> startProfileAt(pos, %)
|
||||
|> arc({angle_end: 360, angle_start: 0, radius: radius}, %)
|
||||
|> arc({angleEnd: 360, angleStart: 0, radius: radius}, %)
|
||||
|> close(%)
|
||||
|> extrude(2, %)
|
||||
|
||||
@ -1160,8 +1160,8 @@ async fn kcl_test_plumbus_fillets() {
|
||||
sg = startSketchOn(ext, face)
|
||||
|> startProfileAt([pos[0] + radius, pos[1]], %)
|
||||
|> arc({
|
||||
angle_end: 360,
|
||||
angle_start: 0,
|
||||
angleEnd: 360,
|
||||
angleStart: 0,
|
||||
radius: radius
|
||||
}, %, $arc1)
|
||||
|> close(%)
|
||||
@ -1235,9 +1235,9 @@ async fn kcl_test_member_expression_in_params() {
|
||||
y: originStart[1],
|
||||
z: originStart[2],
|
||||
},
|
||||
x_axis: { x: 0, y: 0, z: -1 },
|
||||
y_axis: { x: 1, y: 0, z: 0 },
|
||||
z_axis: { x: 0, y: 1, z: 0 }
|
||||
xAxis: { x: 0, y: 0, z: -1 },
|
||||
yAxis: { x: 1, y: 0, z: 0 },
|
||||
zAxis: { x: 0, y: 1, z: 0 }
|
||||
}
|
||||
})
|
||||
|> circle({ center: [0, 0], radius: capDia / 2 }, %)
|
||||
@ -1732,8 +1732,8 @@ async fn kcl_test_arc_error_same_start_end() {
|
||||
let code = r#"startSketchOn('XY')
|
||||
|> startProfileAt([10, 0], %)
|
||||
|> arc({
|
||||
angle_start: 180,
|
||||
angle_end: 180,
|
||||
angleStart: 180,
|
||||
angleEnd: 180,
|
||||
radius: 1.5
|
||||
}, %)
|
||||
|> close(%)
|
||||
@ -1749,7 +1749,7 @@ async fn kcl_test_arc_error_same_start_end() {
|
||||
assert!(result.is_err());
|
||||
assert_eq!(
|
||||
result.err().unwrap().to_string(),
|
||||
r#"type: KclErrorDetails { source_ranges: [SourceRange([57, 140, 0])], message: "Arc start and end angles must be different" }"#
|
||||
r#"type: KclErrorDetails { source_ranges: [SourceRange([57, 138, 0])], message: "Arc start and end angles must be different" }"#
|
||||
);
|
||||
}
|
||||
|
||||
|
91
yarn.lock
@ -1236,13 +1236,13 @@
|
||||
"@lezer/lr" "^1.0.0"
|
||||
style-mod "^4.0.0"
|
||||
|
||||
"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.1":
|
||||
version "6.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.1.tgz#6427848815baaf68c08e98c7673b804d3d8c0e7f"
|
||||
integrity sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==
|
||||
"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.4":
|
||||
version "6.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.4.tgz#7d8aa5d1a6dec89ffcc23ad45ddca2e12e90982d"
|
||||
integrity sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==
|
||||
dependencies:
|
||||
"@codemirror/state" "^6.0.0"
|
||||
"@codemirror/view" "^6.0.0"
|
||||
"@codemirror/view" "^6.35.0"
|
||||
crelt "^1.0.5"
|
||||
|
||||
"@codemirror/search@^6.0.0", "@codemirror/search@^6.5.6":
|
||||
@ -1254,10 +1254,12 @@
|
||||
"@codemirror/view" "^6.0.0"
|
||||
crelt "^1.0.5"
|
||||
|
||||
"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.1", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1":
|
||||
version "6.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.1.tgz#da57143695c056d9a3c38705ed34136e2b68171b"
|
||||
integrity sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==
|
||||
"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.1", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1", "@codemirror/state@^6.5.0":
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.0.tgz#e98dde85620618651543152fe1c2483300a0ccc9"
|
||||
integrity sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==
|
||||
dependencies:
|
||||
"@marijn/find-cluster-break" "^1.0.0"
|
||||
|
||||
"@codemirror/theme-one-dark@^6.1.2":
|
||||
version "6.1.2"
|
||||
@ -1269,12 +1271,12 @@
|
||||
"@codemirror/view" "^6.0.0"
|
||||
"@lezer/highlight" "^1.0.0"
|
||||
|
||||
"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0":
|
||||
version "6.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.29.1.tgz#9c6c6f8a15e12df1b7e9d136dcbf4ff90b81ef71"
|
||||
integrity sha512-7r+DlO/QFwPqKp73uq5mmrS4TuLPUVotbNOKYzN3OLP5ScrOVXcm4g13/48b6ZXGhdmzMinzFYqH0vo+qihIkQ==
|
||||
"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0", "@codemirror/view@^6.35.0":
|
||||
version "6.36.1"
|
||||
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.1.tgz#3c543b8fd72c96b30c4b2b1464d1ebce7e0c5c4b"
|
||||
integrity sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ==
|
||||
dependencies:
|
||||
"@codemirror/state" "^6.4.0"
|
||||
"@codemirror/state" "^6.5.0"
|
||||
style-mod "^4.1.0"
|
||||
w3c-keyname "^2.2.4"
|
||||
|
||||
@ -2073,6 +2075,11 @@
|
||||
lodash "^4.17.15"
|
||||
tmp-promise "^3.0.2"
|
||||
|
||||
"@marijn/find-cluster-break@^1.0.0":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8"
|
||||
integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==
|
||||
|
||||
"@nabla/vite-plugin-eslint@^2.0.5":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@nabla/vite-plugin-eslint/-/vite-plugin-eslint-2.0.5.tgz#f99333a9fe26442e497fd6af269803453b8c4c68"
|
||||
@ -2372,7 +2379,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
|
||||
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
|
||||
|
||||
"@tweenjs/tween.js@^23.1.1", "@tweenjs/tween.js@~23.1.1":
|
||||
"@tweenjs/tween.js@^23.1.1", "@tweenjs/tween.js@~23.1.3":
|
||||
version "23.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-23.1.3.tgz#eff0245735c04a928bb19c026b58c2a56460539d"
|
||||
integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==
|
||||
@ -2640,14 +2647,15 @@
|
||||
dependencies:
|
||||
"@types/jest" "*"
|
||||
|
||||
"@types/three@^0.163.0":
|
||||
version "0.163.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.163.0.tgz#96f5440fcd39452d2c84dfe0c9b7a9cf0247b9e6"
|
||||
integrity sha512-uIdDhsXRpQiBUkflBS/i1l3JX14fW6Ot9csed60nfbZNXHDTRsnV2xnTVwXcgbvTiboAR4IW+t+lTL5f1rqIqA==
|
||||
"@types/three@^0.172.0":
|
||||
version "0.172.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.172.0.tgz#5094852dfa781d2fe1c65eb1b4985a4aa99858b7"
|
||||
integrity sha512-LrUtP3FEG26Zg5WiF0nbg8VoXiKokBLTcqM2iLvM9vzcfEiYmmBAPGdBgV0OYx9fvWlY3R/3ERTZcD9X5sc0NA==
|
||||
dependencies:
|
||||
"@tweenjs/tween.js" "~23.1.1"
|
||||
"@tweenjs/tween.js" "~23.1.3"
|
||||
"@types/stats.js" "*"
|
||||
"@types/webxr" "*"
|
||||
"@webgpu/types" "*"
|
||||
fflate "~0.8.2"
|
||||
meshoptimizer "~0.18.1"
|
||||
|
||||
@ -2860,6 +2868,11 @@
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
|
||||
"@webgpu/types@*":
|
||||
version "0.1.52"
|
||||
resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.52.tgz#239995418d86de927269aca54cbadfbee04eb03a"
|
||||
integrity sha512-eI883Nlag2hGIkhXxAnq8s4APpqXWuPL3Gbn2ghiU12UjLvfCbVqHK4XfXl3eLRTatqcMmeK7jws7IwWsGfbzw==
|
||||
|
||||
"@xmldom/xmldom@^0.8.8":
|
||||
version "0.8.10"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
|
||||
@ -4496,11 +4509,6 @@ end-of-stream@^1.1.0:
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
entities@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
env-paths@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
@ -5692,12 +5700,11 @@ graphemer@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
|
||||
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
|
||||
|
||||
happy-dom@^15.11.7:
|
||||
version "15.11.7"
|
||||
resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-15.11.7.tgz#db9854f11e5dd3fd4ab20cbbcfdf7bd9e17cd971"
|
||||
integrity sha512-KyrFvnl+J9US63TEzwoiJOQzZBJY7KgBushJA8X61DMbNsH+2ONkDuLDnCnwUiPTF42tLoEmrPyoqbenVA5zrg==
|
||||
happy-dom@^16.3.0:
|
||||
version "16.3.0"
|
||||
resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-16.3.0.tgz#e138b5692cdff8e1e25d02b7730d320b4a151f65"
|
||||
integrity sha512-Q71RaIhyS21vhW17Tpa5W36yqQXIlE1TZ0A0Gguts8PShUSQE/7fBgxYGxgm3+5y0gF6afdlAVHLQqgrIcfRzg==
|
||||
dependencies:
|
||||
entities "^4.5.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
whatwg-mimetype "^3.0.0"
|
||||
|
||||
@ -7803,10 +7810,10 @@ react-hot-toast@^2.4.1:
|
||||
dependencies:
|
||||
goober "^2.1.10"
|
||||
|
||||
react-hotkeys-hook@^4.5.1:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-4.5.1.tgz#990260ecc7e5a431414148a93b02a2f1a9707897"
|
||||
integrity sha512-scAEJOh3Irm0g95NIn6+tQVf/OICCjsQsC9NBHfQws/Vxw4sfq1tDQut5fhTEvPraXhu/sHxRd9lOtxzyYuNAg==
|
||||
react-hotkeys-hook@^4.6.1:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-4.6.1.tgz#db9066c07377a1c8be067a238ab16e328266345a"
|
||||
integrity sha512-XlZpbKUj9tkfgPgT9gA+1p7Ey6vFIZHttUjPqpTdyT5nqQ8mHL7elxvSbaC+dpSiHUSmr21Ya1mDxBZG3aje4Q==
|
||||
|
||||
react-is@^16.13.1:
|
||||
version "16.13.1"
|
||||
@ -7843,10 +7850,10 @@ react-modal-promise@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/react-modal-promise/-/react-modal-promise-1.0.2.tgz#122620b7f19eec73683affadfa77c543d88edc40"
|
||||
integrity sha512-dqT618ROhG8qh1+O6EZkia5ELw3zaZWGpMX2YfEH4bgwYENPuFonqKw1W70LFx3K/SCZvVBcD6UYEI12yzYXzg==
|
||||
|
||||
react-modal@^3.16.1:
|
||||
version "3.16.1"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b"
|
||||
integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==
|
||||
react-modal@^3.16.3:
|
||||
version "3.16.3"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.3.tgz#c412d41915782e3c261253435d01468e2439b11b"
|
||||
integrity sha512-yCYRJB5YkeQDQlTt17WGAgFJ7jr2QYcWa1SHqZ3PluDmnKJ/7+tVU+E6uKyZ0nODaeEj+xCpK4LcSnKXLMC0Nw==
|
||||
dependencies:
|
||||
exenv "^1.2.0"
|
||||
prop-types "^15.7.2"
|
||||
@ -8854,10 +8861,10 @@ thenify-all@^1.0.0:
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
three@^0.166.1:
|
||||
version "0.166.1"
|
||||
resolved "https://registry.yarnpkg.com/three/-/three-0.166.1.tgz#322cfc48fff4e751cd47d61fd1558c387d098d7c"
|
||||
integrity sha512-LtuafkKHHzm61AQA1be2MAYIw1IjmhOUxhBa0prrLpEMWbV7ijvxCRHjSgHPGp2493wLBzwKV46tA9nivLEgKg==
|
||||
three@^0.172.0:
|
||||
version "0.172.0"
|
||||
resolved "https://registry.yarnpkg.com/three/-/three-0.172.0.tgz#6944a72f8439e8f7e4b034c8539ec82f5ebe0082"
|
||||
integrity sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==
|
||||
|
||||
thunky@^1.0.2:
|
||||
version "1.1.0"
|
||||
|