Compare commits
57 Commits
derive-doc
...
achalmers/
Author | SHA1 | Date | |
---|---|---|---|
de74c4eae0 | |||
8972ddb640 | |||
8a62869d1d | |||
033687924a | |||
92ed9e445d | |||
2c2974c082 | |||
999897102c | |||
ac69b1263f | |||
026e45895e | |||
220a49b52b | |||
e9862e7677 | |||
99cb8d3eb0 | |||
4e2a200bdf | |||
d95d4d7f66 | |||
5edfae961e | |||
6075aa1d07 | |||
75f996e0ef | |||
d29d2d4a11 | |||
33287d540d | |||
66fe3c7892 | |||
3085b0c2c7 | |||
ff884153db | |||
bcd52a43ca | |||
83ee6511be | |||
c1ff258bf9 | |||
1469c685c0 | |||
b2fea24fc4 | |||
1829c1047a | |||
d5c7a1cef3 | |||
23ea59cf58 | |||
3d6fb4e6e6 | |||
157ee93032 | |||
6c4c59ced9 | |||
925cc892a7 | |||
08ae896b65 | |||
2073df8a3f | |||
743732ba15 | |||
b8525ccd61 | |||
0188d6c065 | |||
ddc7d5b20a | |||
81c2be78bb | |||
0f85e85c57 | |||
55a302bd75 | |||
21e710ee41 | |||
bb51c8d269 | |||
d9d970b436 | |||
1e9a2e3a1a | |||
e9ca2469c5 | |||
1248623922 | |||
49ba5d31c7 | |||
af7d0e6b66 | |||
004898e0c7 | |||
e7457dac0d | |||
a8d76950d0 | |||
2ac836c0b8 | |||
25c73aae6c | |||
65682e755a |
@ -1,4 +1,5 @@
|
||||
NODE_ENV=production
|
||||
DEV=false
|
||||
VITE_KC_API_WS_MODELING_URL=wss://api.zoo.dev/ws/modeling/commands
|
||||
VITE_KC_API_BASE_URL=https://api.zoo.dev
|
||||
VITE_KC_SITE_BASE_URL=https://zoo.dev
|
||||
|
File diff suppressed because one or more lines are too long
@ -33,7 +33,14 @@ helix(revolutions: number, angle_start: number, ccw?: bool, radius: number, axis
|
||||
|
||||
```js
|
||||
// Create a helix around the Z axis.
|
||||
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = 'Z')
|
||||
helixPath = helix(
|
||||
angleStart = 0,
|
||||
ccw = true,
|
||||
revolutions = 5,
|
||||
length = 10,
|
||||
radius = 5,
|
||||
axis = 'Z',
|
||||
)
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('YZ')
|
||||
@ -49,7 +56,14 @@ helper001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line(end = [0, 10], tag = $edge001)
|
||||
|
||||
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = edge001)
|
||||
helixPath = helix(
|
||||
angleStart = 0,
|
||||
ccw = true,
|
||||
revolutions = 5,
|
||||
length = 10,
|
||||
radius = 5,
|
||||
axis = edge001,
|
||||
)
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('XY')
|
||||
@ -61,12 +75,19 @@ springSketch = startSketchOn('XY')
|
||||
|
||||
```js
|
||||
// Create a helix around a custom axis.
|
||||
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = {
|
||||
helixPath = helix(
|
||||
angleStart = 0,
|
||||
ccw = true,
|
||||
revolutions = 5,
|
||||
length = 10,
|
||||
radius = 5,
|
||||
axis = {
|
||||
custom = {
|
||||
axis = [0, 0, 1.0],
|
||||
origin = [0, 0.25, 0]
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('XY')
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ Repeat a 2-dimensional sketch some number of times along a partial or
|
||||
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
|
||||
|
||||
```js
|
||||
patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch]
|
||||
patternCircular2d(sketch_set: SketchSet, instances: integer, center: [number], arc_degrees: number, rotate_duplicates: bool, use_original?: bool) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
@ -17,8 +17,12 @@ patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`CircularPattern2dData`](/docs/kcl/types/CircularPattern2dData) | Data for a circular pattern on a 2D sketch. | Yes |
|
||||
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
|
||||
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | Which sketch(es) to pattern | Yes |
|
||||
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
||||
| `center` | `[number]` | The center about which to make the pattern. This is a 2D vector. | Yes |
|
||||
| `arc_degrees` | `number` | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes |
|
||||
| `rotate_duplicates` | `bool` | Whether or not to rotate the duplicates as they are copied. | Yes |
|
||||
| `use_original` | `bool` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -34,12 +38,12 @@ exampleSketch = startSketchOn('XZ')
|
||||
|> line(end = [-1, 0])
|
||||
|> line(end = [0, -5])
|
||||
|> close()
|
||||
|> patternCircular2d({
|
||||
|> patternCircular2d(
|
||||
center = [0, 0],
|
||||
instances = 13,
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = true
|
||||
}, %)
|
||||
rotateDuplicates = true,
|
||||
)
|
||||
|
||||
example = extrude(exampleSketch, length = 1)
|
||||
```
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount
|
||||
of distance between each repetition, some specified number of times.
|
||||
|
||||
```js
|
||||
patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?: bool) -> [Sketch]
|
||||
patternLinear2d(sketch_set: SketchSet, instances: integer, distance: number, axis: [number], use_original?: bool) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
@ -17,9 +17,11 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?:
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`LinearPattern2dData`](/docs/kcl/types/LinearPattern2dData) | Data for a linear pattern on a 2D sketch. | Yes |
|
||||
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
|
||||
| `use_original` | `bool` | | No |
|
||||
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch(es) to duplicate | Yes |
|
||||
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
||||
| `distance` | `number` | Distance between each repetition. Also known as 'spacing'. | Yes |
|
||||
| `axis` | `[number]` | The axis of the pattern. A 2D vector. | Yes |
|
||||
| `use_original` | `bool` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -31,11 +33,7 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?:
|
||||
```js
|
||||
exampleSketch = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
||||
|> patternLinear2d({
|
||||
axis = [1, 0],
|
||||
instances = 7,
|
||||
distance = 4
|
||||
}, %)
|
||||
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4)
|
||||
|
||||
example = extrude(exampleSketch, length = 1)
|
||||
```
|
||||
|
File diff suppressed because one or more lines are too long
25286
docs/kcl/std.json
25286
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
@ -59,7 +59,14 @@ sweepSketch = startSketchOn('XY')
|
||||
|
||||
|
||||
// Create a helix around the Z axis.
|
||||
helixPath = helix(angleStart = 0, ccw = true, revolutions = 4, length = 10, radius = 5, axis = 'Z')
|
||||
helixPath = helix(
|
||||
angleStart = 0,
|
||||
ccw = true,
|
||||
revolutions = 4,
|
||||
length = 10,
|
||||
radius = 5,
|
||||
axis = 'Z',
|
||||
)
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('YZ')
|
||||
|
@ -716,330 +716,6 @@ openSketch = startSketchOn('XY')
|
||||
})
|
||||
})
|
||||
|
||||
test(`Shift-click to select and deselect edges and faces`, async ({
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
}) => {
|
||||
// Code samples
|
||||
const initialCode = `sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-12, -6], %)
|
||||
|> line(end = [0, 12])
|
||||
|> line(end = [24, 0])
|
||||
|> line(end = [0, -12])
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
|> extrude(%, length = -12)`
|
||||
|
||||
// Locators
|
||||
const upperEdgeLocation = { x: 600, y: 192 }
|
||||
const lowerEdgeLocation = { x: 600, y: 383 }
|
||||
const faceLocation = { x: 630, y: 290 }
|
||||
|
||||
// Click helpers
|
||||
const [clickOnUpperEdge] = scene.makeMouseHelpers(
|
||||
upperEdgeLocation.x,
|
||||
upperEdgeLocation.y
|
||||
)
|
||||
const [clickOnLowerEdge] = scene.makeMouseHelpers(
|
||||
lowerEdgeLocation.x,
|
||||
lowerEdgeLocation.y
|
||||
)
|
||||
const [clickOnFace] = scene.makeMouseHelpers(faceLocation.x, faceLocation.y)
|
||||
|
||||
// Colors
|
||||
const edgeColorWhite: [number, number, number] = [220, 220, 220] // varies from 192 to 255
|
||||
const edgeColorYellow: [number, number, number] = [251, 251, 40] // vaies from 12 to 67
|
||||
const faceColorGray: [number, number, number] = [168, 168, 168]
|
||||
const faceColorYellow: [number, number, number] = [155, 155, 155]
|
||||
const tolerance = 40
|
||||
const timeout = 150
|
||||
|
||||
// Setup
|
||||
await test.step(`Initial test setup`, async () => {
|
||||
await context.addInitScript((initialCode) => {
|
||||
localStorage.setItem('persistCode', initialCode)
|
||||
}, initialCode)
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// Wait for the scene and stream to load
|
||||
await scene.expectPixelColor(faceColorGray, faceLocation, tolerance)
|
||||
})
|
||||
|
||||
await test.step('Select and deselect a single edge', async () => {
|
||||
await test.step('Click the edge', async () => {
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
await clickOnUpperEdge()
|
||||
await scene.expectPixelColor(
|
||||
edgeColorYellow,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Shift-click the same edge to deselect', async () => {
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickOnUpperEdge()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
await test.step('Select and deselect multiple objects', async () => {
|
||||
await test.step('Select both edges and the face', async () => {
|
||||
await test.step('Select the upper edge', async () => {
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
await clickOnUpperEdge()
|
||||
await scene.expectPixelColor(
|
||||
edgeColorYellow,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Select the lower edge (Shift-click)', async () => {
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
lowerEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickOnLowerEdge()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorYellow,
|
||||
lowerEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Select the face (Shift-click)', async () => {
|
||||
await scene.expectPixelColor(faceColorGray, faceLocation, tolerance)
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickOnFace()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(faceColorYellow, faceLocation, tolerance)
|
||||
})
|
||||
})
|
||||
await test.step('Deselect them one by one', async () => {
|
||||
await test.step('Deselect the face (Shift-click)', async () => {
|
||||
await scene.expectPixelColor(faceColorYellow, faceLocation, tolerance)
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickOnFace()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(faceColorGray, faceLocation, tolerance)
|
||||
})
|
||||
await test.step('Deselect the lower edge (Shift-click)', async () => {
|
||||
await scene.expectPixelColor(
|
||||
edgeColorYellow,
|
||||
lowerEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickOnLowerEdge()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
lowerEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Deselect the upper edge (Shift-click)', async () => {
|
||||
await scene.expectPixelColor(
|
||||
edgeColorYellow,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickOnUpperEdge()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
upperEdgeLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test(`Shift-click to select and deselect sketch segments`, async ({
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
editor,
|
||||
}) => {
|
||||
// Locators
|
||||
const firstPointLocation = { x: 200, y: 100 }
|
||||
const secondPointLocation = { x: 800, y: 100 }
|
||||
const thirdPointLocation = { x: 800, y: 400 }
|
||||
const fristSegmentLocation = { x: 750, y: 100 }
|
||||
const secondSegmentLocation = { x: 800, y: 150 }
|
||||
const planeLocation = { x: 700, y: 200 }
|
||||
|
||||
// Click helpers
|
||||
const [clickFirstPoint] = scene.makeMouseHelpers(
|
||||
firstPointLocation.x,
|
||||
firstPointLocation.y
|
||||
)
|
||||
const [clickSecondPoint] = scene.makeMouseHelpers(
|
||||
secondPointLocation.x,
|
||||
secondPointLocation.y
|
||||
)
|
||||
const [clickThirdPoint] = scene.makeMouseHelpers(
|
||||
thirdPointLocation.x,
|
||||
thirdPointLocation.y
|
||||
)
|
||||
const [clickFirstSegment] = scene.makeMouseHelpers(
|
||||
fristSegmentLocation.x,
|
||||
fristSegmentLocation.y
|
||||
)
|
||||
const [clickSecondSegment] = scene.makeMouseHelpers(
|
||||
secondSegmentLocation.x,
|
||||
secondSegmentLocation.y
|
||||
)
|
||||
const [clickPlane] = scene.makeMouseHelpers(
|
||||
planeLocation.x,
|
||||
planeLocation.y
|
||||
)
|
||||
|
||||
// Colors
|
||||
const edgeColorWhite: [number, number, number] = [220, 220, 220]
|
||||
const edgeColorBlue: [number, number, number] = [20, 20, 200]
|
||||
const backgroundColor: [number, number, number] = [30, 30, 30]
|
||||
const tolerance = 40
|
||||
const timeout = 150
|
||||
|
||||
// Setup
|
||||
await test.step(`Initial test setup`, async () => {
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// Wait for the scene and stream to load
|
||||
await scene.expectPixelColor(
|
||||
backgroundColor,
|
||||
secondPointLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
|
||||
await test.step('Select and deselect a single sketch segment', async () => {
|
||||
await test.step('Get into sketch mode', async () => {
|
||||
await editor.closePane()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickPlane()
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
await test.step('Draw sketch', async () => {
|
||||
await clickFirstPoint()
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickSecondPoint()
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickThirdPoint()
|
||||
await page.waitForTimeout(timeout)
|
||||
})
|
||||
await test.step('Deselect line tool', async () => {
|
||||
const btnLine = page.getByTestId('line')
|
||||
const btnLineAriaPressed = await btnLine.getAttribute('aria-pressed')
|
||||
if (btnLineAriaPressed === 'true') {
|
||||
await btnLine.click()
|
||||
}
|
||||
await page.waitForTimeout(timeout)
|
||||
})
|
||||
await test.step('Select the first segment', async () => {
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickFirstSegment()
|
||||
await page.waitForTimeout(timeout)
|
||||
await scene.expectPixelColor(
|
||||
edgeColorBlue,
|
||||
fristSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
secondSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Select the second segment (Shift-click)', async () => {
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickSecondSegment()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorBlue,
|
||||
fristSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
await scene.expectPixelColor(
|
||||
edgeColorBlue,
|
||||
secondSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Deselect the first segment', async () => {
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickFirstSegment()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
fristSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
await scene.expectPixelColor(
|
||||
edgeColorBlue,
|
||||
secondSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
await test.step('Deselect the second segment', async () => {
|
||||
await page.keyboard.down('Shift')
|
||||
await page.waitForTimeout(timeout)
|
||||
await clickSecondSegment()
|
||||
await page.waitForTimeout(timeout)
|
||||
await page.keyboard.up('Shift')
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
fristSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
await scene.expectPixelColor(
|
||||
edgeColorWhite,
|
||||
secondSegmentLocation,
|
||||
tolerance
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test(`Offset plane point-and-click`, async ({
|
||||
context,
|
||||
page,
|
||||
|
@ -192,11 +192,11 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
|> line(end = [0, -1])
|
||||
|> close()
|
||||
|> extrude(length = 1)
|
||||
|> patternLinear3d({
|
||||
axis: [1, 0, 1],
|
||||
repetitions: 3,
|
||||
distance: 6
|
||||
}, %)`
|
||||
|> patternLinear3d(
|
||||
axis = [1, 0, 1],
|
||||
repetitions = 3,
|
||||
distance = 6,
|
||||
)`
|
||||
)
|
||||
})
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
@ -32,6 +32,10 @@ win:
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
# - target: msi
|
||||
# arch:
|
||||
# - x64
|
||||
# - arm64
|
||||
signingHashAlgorithms:
|
||||
- sha256
|
||||
sign: "./scripts/sign-win.js"
|
||||
@ -43,12 +47,15 @@ win:
|
||||
mimeType: text/vnd.zoo.kcl
|
||||
description: Zoo KCL File
|
||||
role: Editor
|
||||
# msi:
|
||||
# oneClick: false
|
||||
# perMachine: true
|
||||
nsis:
|
||||
oneClick: false
|
||||
perMachine: true
|
||||
allowElevation: true
|
||||
installerIcon: "assets/icon.ico"
|
||||
include: "./scripts/installer.nsh"
|
||||
include: "./installer.nsh"
|
||||
linux:
|
||||
artifactName: "${productName}-${version}-${arch}-${os}.${ext}"
|
||||
target:
|
||||
|
@ -85,7 +85,7 @@
|
||||
"fmt": "prettier --write ./src *.ts *.json *.js ./e2e ./packages",
|
||||
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages",
|
||||
"fetch:wasm": "./get-latest-wasm-bundle.sh",
|
||||
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/achalmers/kw-appearance/manifest.json",
|
||||
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/achalmers/kw-pattern/manifest.json",
|
||||
"isomorphic-copy-wasm": "(copy src/wasm-lib/pkg/wasm_lib_bg.wasm public || cp src/wasm-lib/pkg/wasm_lib_bg.wasm public)",
|
||||
"build:wasm-dev": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt",
|
||||
"build:wasm": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings && cd ../.. && yarn isomorphic-copy-wasm && yarn fmt",
|
||||
|
@ -11,7 +11,6 @@ echo "$PACKAGE" > package.json
|
||||
# electron-builder.yml
|
||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/nightly"' electron-builder.yml
|
||||
yq -i '.appId = "dev.zoo.modeling-app-nightly"' electron-builder.yml
|
||||
yq -i '.nsis.include = "./scripts/installer-nightly.nsh"' electron-builder.yml
|
||||
|
||||
# Release notes
|
||||
echo "Nightly build $VERSION (commit $COMMIT)" > release-notes.md
|
||||
|
@ -1,8 +0,0 @@
|
||||
!macro preInit
|
||||
SetRegView 64
|
||||
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Program Files\Zoo Modeling App (Nightly)"
|
||||
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Program Files\Zoo Modeling App (Nightly)"
|
||||
SetRegView 32
|
||||
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Program Files\Zoo Modeling App (Nightly)"
|
||||
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Program Files\Zoo Modeling App (Nightly)"
|
||||
!macroend
|
@ -329,83 +329,11 @@ export const ModelingMachineProvider = ({
|
||||
otherSelections: [],
|
||||
}
|
||||
} else if (setSelections.selection && editorManager.isShiftDown) {
|
||||
// selecting and deselecting multiple objects
|
||||
|
||||
/**
|
||||
* There are two scenarios:
|
||||
* 1. General case:
|
||||
* When selecting and deselecting edges,
|
||||
* faces or segment (during sketch edit)
|
||||
* we use its artifact ID to identify the selection
|
||||
* 2. Initial sketch setup:
|
||||
* The artifact is not yet created
|
||||
* so we use the codeRef.range
|
||||
*/
|
||||
|
||||
let updatedSelections: typeof selectionRanges.graphSelections
|
||||
|
||||
// 1. General case: Artifact exists, use its ID
|
||||
if (setSelections.selection.artifact?.id) {
|
||||
// check if already selected
|
||||
const alreadySelected = selectionRanges.graphSelections.some(
|
||||
(selection) =>
|
||||
selection.artifact?.id ===
|
||||
setSelections.selection?.artifact?.id
|
||||
)
|
||||
if (
|
||||
alreadySelected &&
|
||||
setSelections.selection?.artifact?.id
|
||||
) {
|
||||
// remove it
|
||||
updatedSelections = selectionRanges.graphSelections.filter(
|
||||
(selection) =>
|
||||
selection.artifact?.id !==
|
||||
setSelections.selection?.artifact?.id
|
||||
)
|
||||
} else {
|
||||
// add it
|
||||
updatedSelections = [
|
||||
...selectionRanges.graphSelections,
|
||||
setSelections.selection,
|
||||
]
|
||||
}
|
||||
} else {
|
||||
// 2. Initial sketch setup: Artifact not yet created – use codeRef.range
|
||||
const selectionRange = JSON.stringify(
|
||||
setSelections.selection?.codeRef?.range
|
||||
)
|
||||
|
||||
// check if already selected
|
||||
const alreadySelected = selectionRanges.graphSelections.some(
|
||||
(selection) => {
|
||||
const existingRange = JSON.stringify(
|
||||
selection.codeRef?.range
|
||||
)
|
||||
return existingRange === selectionRange
|
||||
}
|
||||
)
|
||||
|
||||
if (
|
||||
alreadySelected &&
|
||||
setSelections.selection?.codeRef?.range
|
||||
) {
|
||||
// remove it
|
||||
updatedSelections = selectionRanges.graphSelections.filter(
|
||||
(selection) =>
|
||||
JSON.stringify(selection.codeRef?.range) !==
|
||||
selectionRange
|
||||
)
|
||||
} else {
|
||||
// add it
|
||||
updatedSelections = [
|
||||
...selectionRanges.graphSelections,
|
||||
setSelections.selection,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
selections = {
|
||||
graphSelections: updatedSelections,
|
||||
graphSelections: [
|
||||
...selectionRanges.graphSelections,
|
||||
setSelections.selection,
|
||||
],
|
||||
otherSelections: selectionRanges.otherSelections,
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ export class KclManager {
|
||||
nonCodeNodes: {},
|
||||
startNodes: [],
|
||||
},
|
||||
trivia: [],
|
||||
}
|
||||
private _execState: ExecState = emptyExecState()
|
||||
private _programMemory: ProgramMemory = ProgramMemory.empty()
|
||||
@ -240,7 +239,6 @@ export class KclManager {
|
||||
nonCodeNodes: {},
|
||||
startNodes: [],
|
||||
},
|
||||
trivia: [],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ child_process.spawnSync('git', [
|
||||
'clone',
|
||||
'--single-branch',
|
||||
'--branch',
|
||||
'achalmers/kw-appearance',
|
||||
'achalmers/kw-pattern',
|
||||
URL_GIT_KCL_SAMPLES,
|
||||
DIR_KCL_SAMPLES,
|
||||
])
|
||||
|
@ -128,78 +128,15 @@ describe('Testing findUniqueName', () => {
|
||||
it('should find a unique name', () => {
|
||||
const result = findUniqueName(
|
||||
JSON.stringify([
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo01',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo02',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo03',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo04',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo05',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo06',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo07',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo08',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{
|
||||
type: 'Identifier',
|
||||
name: 'yo09',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
},
|
||||
{ type: 'Identifier', name: 'yo01', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo02', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo03', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo04', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo05', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo06', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo07', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo08', start: 0, end: 0, moduleId: 0 },
|
||||
{ type: 'Identifier', name: 'yo09', start: 0, end: 0, moduleId: 0 },
|
||||
] satisfies Node<Identifier>[]),
|
||||
'yo',
|
||||
2
|
||||
@ -217,7 +154,6 @@ describe('Testing addSketchTo', () => {
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
nonCodeMeta: { nonCodeNodes: {}, startNodes: [] },
|
||||
trivia: [],
|
||||
},
|
||||
'yz'
|
||||
)
|
||||
|
@ -278,7 +278,6 @@ export function mutateObjExpProp(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -891,7 +890,6 @@ export function createLiteral(value: LiteralValue | number): Node<Literal> {
|
||||
moduleId: 0,
|
||||
value,
|
||||
raw,
|
||||
trivia: [],
|
||||
}
|
||||
}
|
||||
|
||||
@ -901,7 +899,6 @@ export function createTagDeclarator(value: string): Node<TagDeclarator> {
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
value,
|
||||
}
|
||||
@ -913,7 +910,6 @@ export function createIdentifier(name: string): Node<Identifier> {
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
name,
|
||||
}
|
||||
@ -925,7 +921,6 @@ export function createPipeSubstitution(): Node<PipeSubstitution> {
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
}
|
||||
}
|
||||
|
||||
@ -938,13 +933,11 @@ export function createCallExpressionStdLib(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
callee: {
|
||||
type: 'Identifier',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
name,
|
||||
},
|
||||
@ -962,13 +955,11 @@ export function createCallExpressionStdLibKw(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
callee: {
|
||||
type: 'Identifier',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
name,
|
||||
},
|
||||
@ -986,13 +977,11 @@ export function createCallExpression(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
callee: {
|
||||
type: 'Identifier',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
name,
|
||||
},
|
||||
@ -1008,7 +997,6 @@ export function createArrayExpression(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
nonCodeMeta: nonCodeMetaEmpty(),
|
||||
elements,
|
||||
@ -1023,7 +1011,6 @@ export function createPipeExpression(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
body,
|
||||
nonCodeMeta: nonCodeMetaEmpty(),
|
||||
@ -1041,14 +1028,12 @@ export function createVariableDeclaration(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
declaration: {
|
||||
type: 'VariableDeclarator',
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
id: createIdentifier(varName),
|
||||
init,
|
||||
@ -1066,7 +1051,6 @@ export function createObjectExpression(properties: {
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
nonCodeMeta: nonCodeMetaEmpty(),
|
||||
properties: Object.entries(properties).map(([key, value]) => ({
|
||||
@ -1074,7 +1058,6 @@ export function createObjectExpression(properties: {
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
key: createIdentifier(key),
|
||||
|
||||
value,
|
||||
@ -1091,7 +1074,6 @@ export function createUnaryExpression(
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
operator,
|
||||
argument,
|
||||
@ -1108,7 +1090,6 @@ export function createBinaryExpression([left, operator, right]: [
|
||||
start: 0,
|
||||
end: 0,
|
||||
moduleId: 0,
|
||||
trivia: [],
|
||||
|
||||
operator,
|
||||
left,
|
||||
|
@ -289,7 +289,10 @@ describe('testing addTagForSketchOnFace', () => {
|
||||
segAng(rectangleSegmentA001),
|
||||
-segLen(rectangleSegmentA001)
|
||||
], %)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||
|> line(
|
||||
endAbsolute = [profileStartX(%), profileStartY(%)],
|
||||
tag = $seg02,
|
||||
)
|
||||
|> close()
|
||||
extrude001 = extrude(sketch001, length = 100)
|
||||
${insertCode}
|
||||
|
@ -1954,7 +1954,6 @@ export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({
|
||||
startNodes: [],
|
||||
nonCodeNodes: [],
|
||||
},
|
||||
trivia: [],
|
||||
},
|
||||
pathToNode,
|
||||
}
|
||||
@ -2535,8 +2534,6 @@ function addTagKw(): addTagFn {
|
||||
...primaryCallExp,
|
||||
start: callExpr.node.start,
|
||||
end: callExpr.node.end,
|
||||
moduleId: callExpr.node.moduleId,
|
||||
trivia: callExpr.node.trivia,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -51,16 +51,16 @@ sketch002 = startSketchOn(sketch001, seg03)
|
||||
center = [-1.25, 1],
|
||||
radius = mountingHoleDiameter / 2,
|
||||
}, %)
|
||||
|> patternLinear2d({
|
||||
|> patternLinear2d(
|
||||
instances = 2,
|
||||
distance = 2.5,
|
||||
axis = [-1, 0],
|
||||
}, %)
|
||||
|> patternLinear2d({
|
||||
)
|
||||
|> patternLinear2d(
|
||||
instances = 2,
|
||||
distance = 4,
|
||||
axis = [0, 1],
|
||||
}, %)
|
||||
)
|
||||
|> extrude(%, length = -thickness-.01)
|
||||
|
||||
sketch003 = startSketchOn(sketch001, seg04)
|
||||
@ -68,11 +68,11 @@ sketch003 = startSketchOn(sketch001, seg04)
|
||||
center = [1, -1],
|
||||
radius = mountingHoleDiameter / 2,
|
||||
}, %)
|
||||
|> patternLinear2d({
|
||||
|> patternLinear2d(
|
||||
instances = 2,
|
||||
distance = 4,
|
||||
axis = [1, 0],
|
||||
}, %)
|
||||
)
|
||||
|> extrude(%, length = -thickness-0.1)
|
||||
`
|
||||
|
||||
|
12
src/main.ts
12
src/main.ts
@ -40,6 +40,7 @@ dotenv.config({ path: [`.env.${NODE_ENV}.local`, `.env.${NODE_ENV}`] })
|
||||
|
||||
// default vite values based on mode
|
||||
process.env.NODE_ENV ??= viteEnv.MODE
|
||||
process.env.DEV ??= viteEnv.DEV + ''
|
||||
process.env.BASE_URL ??= viteEnv.VITE_KC_API_BASE_URL
|
||||
process.env.VITE_KC_API_WS_MODELING_URL ??= viteEnv.VITE_KC_API_WS_MODELING_URL
|
||||
process.env.VITE_KC_API_BASE_URL ??= viteEnv.VITE_KC_API_BASE_URL
|
||||
@ -93,11 +94,12 @@ const createWindow = (pathToOpen?: string, reuse?: boolean): BrowserWindow => {
|
||||
}
|
||||
|
||||
// Deep Link: Case of a cold start from Windows or Linux
|
||||
const zooProtocolArg = process.argv.find((a) =>
|
||||
a.startsWith(ZOO_STUDIO_PROTOCOL + '://')
|
||||
)
|
||||
if (!pathToOpen && zooProtocolArg) {
|
||||
pathToOpen = zooProtocolArg
|
||||
if (
|
||||
!pathToOpen &&
|
||||
process.argv.length > 1 &&
|
||||
process.argv[1].indexOf(ZOO_STUDIO_PROTOCOL + '://') > -1
|
||||
) {
|
||||
pathToOpen = process.argv[1]
|
||||
console.log('Retrieved deep link from argv', pathToOpen)
|
||||
}
|
||||
|
||||
|
4
src/wasm-lib/Cargo.lock
generated
4
src/wasm-lib/Cargo.lock
generated
@ -730,7 +730,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "derive-docs"
|
||||
version = "0.1.36"
|
||||
version = "0.1.35"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
@ -1712,7 +1712,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.2.35"
|
||||
version = "0.2.34"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx 0.5.1",
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "derive-docs"
|
||||
description = "A tool for generating documentation from Rust derive macros"
|
||||
version = "0.1.36"
|
||||
version = "0.1.35"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -36,5 +36,11 @@ run-sim-test test_name:
|
||||
{{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
|
||||
TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
|
||||
|
||||
overwrite-sim-test test_name:
|
||||
EXPECTORATE=overwrite {{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::parse
|
||||
EXPECTORATE=overwrite {{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
|
||||
{{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
|
||||
|
||||
|
||||
test:
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language implementation and tools"
|
||||
version = "0.2.35"
|
||||
version = "0.2.34"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -944,13 +944,7 @@ mod tests {
|
||||
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
||||
assert_eq!(
|
||||
snippet,
|
||||
r#"patternCircular3d({
|
||||
instances = ${0:10},
|
||||
axis = [${1:3.14}, ${2:3.14}, ${3:3.14}],
|
||||
center = [${4:3.14}, ${5:3.14}, ${6:3.14}],
|
||||
arcDegrees = ${7:3.14},
|
||||
rotateDuplicates = ${8:false},
|
||||
}, ${9:%})${}"#
|
||||
r#"patternCircular3d(${0:%}, instances = ${1:10}, axis = [${2:3.14}, ${3:3.14}, ${4:3.14}], center = [${5:3.14}, ${6:3.14}, ${7:3.14}], arc_degrees = ${8:3.14}, rotate_duplicates = ${9:false})${}"#
|
||||
);
|
||||
}
|
||||
|
||||
@ -1006,11 +1000,7 @@ mod tests {
|
||||
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
||||
assert_eq!(
|
||||
snippet,
|
||||
r#"patternLinear2d({
|
||||
instances = ${0:10},
|
||||
distance = ${1:3.14},
|
||||
axis = [${2:3.14}, ${3:3.14}],
|
||||
}, ${4:%})${}"#
|
||||
r#"patternLinear2d(${0:%}, instances = ${1:10}, distance = ${2:3.14}, axis = [${3:3.14}, ${4:3.14}])${}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,7 @@ use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
use crate::{
|
||||
execution::{ArtifactCommand, ArtifactGraph, Operation},
|
||||
lsp::IntoDiagnostic,
|
||||
source_range::SourceRange,
|
||||
ModuleId,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
};
|
||||
|
||||
/// How did the KCL execution fail
|
||||
|
@ -10,17 +10,16 @@ use crate::{
|
||||
annotations,
|
||||
cad_op::{OpArg, Operation},
|
||||
state::ModuleState,
|
||||
BodyType, ExecState, ExecutorContext, KclValue, MemoryFunction, Metadata, ProgramMemory, TagEngineInfo,
|
||||
TagIdentifier,
|
||||
BodyType, ExecState, ExecutorContext, KclValue, MemoryFunction, Metadata, ModulePath, ModuleRepr,
|
||||
ProgramMemory, TagEngineInfo, TagIdentifier,
|
||||
},
|
||||
modules::{ModuleId, ModulePath, ModuleRepr},
|
||||
parsing::ast::types::{
|
||||
ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, CallExpression,
|
||||
CallExpressionKw, Expr, FunctionExpression, IfExpression, ImportPath, ImportSelector, ItemVisibility,
|
||||
LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, NodeRef, NonCodeValue, ObjectExpression,
|
||||
PipeExpression, TagDeclarator, UnaryExpression, UnaryOperator,
|
||||
},
|
||||
source_range::SourceRange,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
std::{
|
||||
args::{Arg, KwArgs},
|
||||
FunctionKind,
|
||||
@ -1769,7 +1768,6 @@ mod test {
|
||||
start: 0,
|
||||
end: 0,
|
||||
module_id: ModuleId::default(),
|
||||
trivia: Vec::new(),
|
||||
},
|
||||
return_type: None,
|
||||
digest: None,
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! The executor for the AST.
|
||||
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::{fmt, path::PathBuf, sync::Arc};
|
||||
|
||||
use anyhow::Result;
|
||||
pub use artifact::{Artifact, ArtifactCommand, ArtifactGraph, ArtifactId};
|
||||
@ -9,9 +9,7 @@ use cache::OldAstState;
|
||||
pub use cad_op::Operation;
|
||||
pub use exec_ast::FunctionParam;
|
||||
pub use geometry::*;
|
||||
pub(crate) use import::{
|
||||
import_foreign, send_to_engine as send_import_to_engine, PreImportedGeometry, ZOO_COORD_SYSTEM,
|
||||
};
|
||||
pub(crate) use import::{import_foreign, send_to_engine as send_import_to_engine, ZOO_COORD_SYSTEM};
|
||||
use indexmap::IndexMap;
|
||||
pub use kcl_value::{KclObjectFields, KclValue, UnitAngle, UnitLen};
|
||||
use kcmc::{
|
||||
@ -28,15 +26,15 @@ pub use state::{ExecState, IdGenerator, MetaSettings};
|
||||
|
||||
use crate::{
|
||||
engine::EngineManager,
|
||||
errors::KclError,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
artifact::build_artifact_graph,
|
||||
cache::{CacheInformation, CacheResult},
|
||||
},
|
||||
fs::FileManager,
|
||||
parsing::ast::types::{Expr, FunctionExpression, Node, NodeRef, Program},
|
||||
fs::{FileManager, FileSystem},
|
||||
parsing::ast::types::{Expr, FunctionExpression, ImportPath, Node, NodeRef, Program},
|
||||
settings::types::UnitLength,
|
||||
source_range::SourceRange,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
std::{args::Arg, StdLib},
|
||||
ExecError, KclErrorWithOutputs,
|
||||
};
|
||||
@ -164,6 +162,118 @@ pub enum BodyType {
|
||||
Block,
|
||||
}
|
||||
|
||||
/// Info about a module. Right now, this is pretty minimal. We hope to cache
|
||||
/// modules here in the future.
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub struct ModuleInfo {
|
||||
/// The ID of the module.
|
||||
id: ModuleId,
|
||||
/// Absolute path of the module's source file.
|
||||
path: ModulePath,
|
||||
repr: ModuleRepr,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash)]
|
||||
pub enum ModulePath {
|
||||
Local(std::path::PathBuf),
|
||||
Std(String),
|
||||
}
|
||||
|
||||
impl ModulePath {
|
||||
fn expect_path(&self) -> &std::path::PathBuf {
|
||||
match self {
|
||||
ModulePath::Local(p) => p,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn source(&self, fs: &FileManager, source_range: SourceRange) -> Result<String, KclError> {
|
||||
match self {
|
||||
ModulePath::Local(p) => fs.read_to_string(p, source_range).await,
|
||||
ModulePath::Std(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_import_path(path: &ImportPath, project_directory: &Option<PathBuf>) -> Self {
|
||||
match path {
|
||||
ImportPath::Kcl { filename: path } | ImportPath::Foreign { path } => {
|
||||
let resolved_path = if let Some(project_dir) = project_directory {
|
||||
project_dir.join(path)
|
||||
} else {
|
||||
std::path::PathBuf::from(path)
|
||||
};
|
||||
ModulePath::Local(resolved_path)
|
||||
}
|
||||
ImportPath::Std { path } => {
|
||||
// For now we only support importing from singly-nested modules inside std.
|
||||
assert_eq!(path.len(), 2);
|
||||
assert_eq!(&path[0], "std");
|
||||
|
||||
ModulePath::Std(path[1].clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ModulePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ModulePath::Local(path) => path.display().fmt(f),
|
||||
ModulePath::Std(s) => write!(f, "std::{s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub enum ModuleRepr {
|
||||
Root,
|
||||
Kcl(Node<Program>),
|
||||
Foreign(import::PreImportedGeometry),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModuleLoader {
|
||||
/// The stack of import statements for detecting circular module imports.
|
||||
/// If this is empty, we're not currently executing an import statement.
|
||||
pub import_stack: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl ModuleLoader {
|
||||
pub(crate) fn cycle_check(&self, path: &ModulePath, source_range: SourceRange) -> Result<(), KclError> {
|
||||
if self.import_stack.contains(path.expect_path()) {
|
||||
return Err(KclError::ImportCycle(KclErrorDetails {
|
||||
message: format!(
|
||||
"circular import of modules is not allowed: {} -> {}",
|
||||
self.import_stack
|
||||
.iter()
|
||||
.map(|p| p.as_path().to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" -> "),
|
||||
path,
|
||||
),
|
||||
source_ranges: vec![source_range],
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn enter_module(&mut self, path: &ModulePath) {
|
||||
if let ModulePath::Local(ref path) = path {
|
||||
self.import_stack.push(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn leave_module(&mut self, path: &ModulePath) {
|
||||
if let ModulePath::Local(ref path) = path {
|
||||
let popped = self.import_stack.pop().unwrap();
|
||||
assert_eq!(path, &popped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq, Copy)]
|
||||
#[ts(export)]
|
||||
@ -774,7 +884,7 @@ mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use crate::{errors::KclErrorDetails, ModuleId};
|
||||
use crate::errors::KclErrorDetails;
|
||||
|
||||
/// Convenience function to get a JSON value from memory and unwrap.
|
||||
#[track_caller]
|
||||
|
@ -9,11 +9,11 @@ use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
annotations, kcl_value, Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, ExecOutcome, ExecutorSettings,
|
||||
KclValue, Operation, ProgramMemory, SolidLazyIds, UnitAngle, UnitLen,
|
||||
KclValue, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr, Operation, ProgramMemory, SolidLazyIds, UnitAngle,
|
||||
UnitLen,
|
||||
},
|
||||
modules::{ModuleId, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr},
|
||||
parsing::ast::types::NonCodeValue,
|
||||
source_range::SourceRange,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
};
|
||||
|
||||
/// State for executing a program.
|
||||
|
@ -65,7 +65,6 @@ mod fs;
|
||||
pub mod lint;
|
||||
mod log;
|
||||
mod lsp;
|
||||
mod modules;
|
||||
mod parsing;
|
||||
mod settings;
|
||||
#[cfg(test)]
|
||||
@ -88,10 +87,9 @@ pub use lsp::{
|
||||
copilot::Backend as CopilotLspBackend,
|
||||
kcl::{Backend as KclLspBackend, Server as KclLspServerSubCommand},
|
||||
};
|
||||
pub use modules::ModuleId;
|
||||
pub use parsing::ast::{modify::modify_ast_for_sketch, types::FormatOptions};
|
||||
pub use settings::types::{project::ProjectConfiguration, Configuration, UnitLength};
|
||||
pub use source_range::SourceRange;
|
||||
pub use source_range::{ModuleId, SourceRange};
|
||||
|
||||
// Rather than make executor public and make lots of it pub(crate), just re-export into a new module.
|
||||
// Ideally we wouldn't export these things at all, they should only be used for testing.
|
||||
|
@ -1543,13 +1543,13 @@ sphere = startSketchOn('XZ')
|
||||
}, %)
|
||||
|> close()
|
||||
|> revolve({ axis: 'x' }, %)
|
||||
|> patternCircular3d({
|
||||
axis: [0, 0, 1],
|
||||
center: [0, 0, 0],
|
||||
repetitions: 10,
|
||||
arcDegrees: 360,
|
||||
rotateDuplicates: true
|
||||
}, %)
|
||||
|> patternCircular3d(
|
||||
axis = [0, 0, 1],
|
||||
center = [0, 0, 0],
|
||||
repetitions = 10,
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = true,
|
||||
)
|
||||
|
||||
// Sketch and revolve the outside bearing
|
||||
outsideRevolve = startSketchOn('XZ')
|
||||
@ -1644,13 +1644,13 @@ sphere = startSketchOn('XZ')
|
||||
}, %)
|
||||
|> close()
|
||||
|> revolve({ axis = 'x' }, %)
|
||||
|> patternCircular3d({
|
||||
|> patternCircular3d(
|
||||
axis = [0, 0, 1],
|
||||
center = [0, 0, 0],
|
||||
repetitions = 10,
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = true
|
||||
}, %)
|
||||
rotateDuplicates = true,
|
||||
)
|
||||
|
||||
// Sketch and revolve the outside bearing
|
||||
outsideRevolve = startSketchOn('XZ')
|
||||
|
@ -1,157 +0,0 @@
|
||||
use std::{fmt, path::PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::PreImportedGeometry,
|
||||
fs::{FileManager, FileSystem},
|
||||
parsing::ast::types::{ImportPath, Node, Program},
|
||||
source_range::SourceRange,
|
||||
};
|
||||
|
||||
/// Identifier of a source file. Uses a u32 to keep the size small.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
pub struct ModuleId(u32);
|
||||
|
||||
impl ModuleId {
|
||||
pub fn from_usize(id: usize) -> Self {
|
||||
Self(u32::try_from(id).expect("module ID should fit in a u32"))
|
||||
}
|
||||
|
||||
pub fn as_usize(&self) -> usize {
|
||||
usize::try_from(self.0).expect("module ID should fit in a usize")
|
||||
}
|
||||
|
||||
/// Top-level file is the one being executed.
|
||||
/// Represented by module ID of 0, i.e. the default value.
|
||||
pub fn is_top_level(&self) -> bool {
|
||||
*self == Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModuleLoader {
|
||||
/// The stack of import statements for detecting circular module imports.
|
||||
/// If this is empty, we're not currently executing an import statement.
|
||||
pub import_stack: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl ModuleLoader {
|
||||
pub(crate) fn cycle_check(&self, path: &ModulePath, source_range: SourceRange) -> Result<(), KclError> {
|
||||
if self.import_stack.contains(path.expect_path()) {
|
||||
return Err(KclError::ImportCycle(KclErrorDetails {
|
||||
message: format!(
|
||||
"circular import of modules is not allowed: {} -> {}",
|
||||
self.import_stack
|
||||
.iter()
|
||||
.map(|p| p.as_path().to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" -> "),
|
||||
path,
|
||||
),
|
||||
source_ranges: vec![source_range],
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn enter_module(&mut self, path: &ModulePath) {
|
||||
if let ModulePath::Local(ref path) = path {
|
||||
self.import_stack.push(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn leave_module(&mut self, path: &ModulePath) {
|
||||
if let ModulePath::Local(ref path) = path {
|
||||
let popped = self.import_stack.pop().unwrap();
|
||||
assert_eq!(path, &popped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read_std(_mod_name: &str) -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Info about a module. Right now, this is pretty minimal. We hope to cache
|
||||
/// modules here in the future.
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub struct ModuleInfo {
|
||||
/// The ID of the module.
|
||||
pub(crate) id: ModuleId,
|
||||
/// Absolute path of the module's source file.
|
||||
pub(crate) path: ModulePath,
|
||||
pub(crate) repr: ModuleRepr,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub enum ModuleRepr {
|
||||
Root,
|
||||
Kcl(Node<Program>),
|
||||
Foreign(PreImportedGeometry),
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash)]
|
||||
pub enum ModulePath {
|
||||
Local(PathBuf),
|
||||
Std(String),
|
||||
}
|
||||
|
||||
impl ModulePath {
|
||||
pub(crate) fn expect_path(&self) -> &PathBuf {
|
||||
match self {
|
||||
ModulePath::Local(p) => p,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn source(&self, fs: &FileManager, source_range: SourceRange) -> Result<String, KclError> {
|
||||
match self {
|
||||
ModulePath::Local(p) => fs.read_to_string(p, source_range).await,
|
||||
ModulePath::Std(name) => read_std(name)
|
||||
.ok_or_else(|| {
|
||||
KclError::Semantic(KclErrorDetails {
|
||||
message: format!("Cannot find standard library module to import: std::{name}."),
|
||||
source_ranges: vec![source_range],
|
||||
})
|
||||
})
|
||||
.map(str::to_owned),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_import_path(path: &ImportPath, project_directory: &Option<PathBuf>) -> Self {
|
||||
match path {
|
||||
ImportPath::Kcl { filename: path } | ImportPath::Foreign { path } => {
|
||||
let resolved_path = if let Some(project_dir) = project_directory {
|
||||
project_dir.join(path)
|
||||
} else {
|
||||
std::path::PathBuf::from(path)
|
||||
};
|
||||
ModulePath::Local(resolved_path)
|
||||
}
|
||||
ImportPath::Std { path } => {
|
||||
// For now we only support importing from singly-nested modules inside std.
|
||||
assert_eq!(path.len(), 2);
|
||||
assert_eq!(&path[0], "std");
|
||||
|
||||
ModulePath::Std(path[1].clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ModulePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ModulePath::Local(path) => path.display().fmt(f),
|
||||
ModulePath::Std(s) => write!(f, "std::{s}"),
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ pub mod types;
|
||||
|
||||
use crate::{
|
||||
parsing::ast::types::{BinaryPart, BodyItem, Expr, LiteralIdentifier, MemberObject},
|
||||
ModuleId,
|
||||
source_range::ModuleId,
|
||||
};
|
||||
|
||||
impl BodyItem {
|
||||
|
@ -15,8 +15,8 @@ use crate::{
|
||||
ArrayExpression, CallExpression, ConstraintLevel, FormatOptions, Literal, Node, PipeExpression,
|
||||
PipeSubstitution, VariableDeclarator,
|
||||
},
|
||||
source_range::SourceRange,
|
||||
ModuleId, Program,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
Program,
|
||||
};
|
||||
|
||||
type Point3d = kcmc::shared::Point3d<f64>;
|
||||
|
@ -28,8 +28,7 @@ use crate::{
|
||||
execution::{annotations, KclValue, Metadata, TagIdentifier},
|
||||
parsing::{ast::digest::Digest, PIPE_OPERATOR},
|
||||
pretty::NumericSuffix,
|
||||
source_range::SourceRange,
|
||||
ModuleId,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
};
|
||||
|
||||
mod condition;
|
||||
@ -41,7 +40,7 @@ pub enum Definition<'a> {
|
||||
Import(NodeRef<'a, ImportStatement>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS)]
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Node<T> {
|
||||
@ -51,8 +50,6 @@ pub struct Node<T> {
|
||||
pub end: usize,
|
||||
#[serde(default, skip_serializing_if = "ModuleId::is_top_level")]
|
||||
pub module_id: ModuleId,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub trivia: NodeList<NonCodeNode>,
|
||||
}
|
||||
|
||||
impl<T> Node<T> {
|
||||
@ -96,7 +93,6 @@ impl<T> Node<T> {
|
||||
start,
|
||||
end,
|
||||
module_id,
|
||||
trivia: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +102,6 @@ impl<T> Node<T> {
|
||||
start: 0,
|
||||
end: 0,
|
||||
module_id: ModuleId::default(),
|
||||
trivia: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +111,6 @@ impl<T> Node<T> {
|
||||
start,
|
||||
end,
|
||||
module_id,
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -647,7 +641,6 @@ impl From<&BodyItem> for SourceRange {
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(tag = "type")]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum Expr {
|
||||
Literal(BoxNode<Literal>),
|
||||
Identifier(BoxNode<Identifier>),
|
||||
@ -3829,7 +3822,6 @@ const cylinder = startSketchOn('-XZ')
|
||||
start: 0,
|
||||
end: 0,
|
||||
module_id: ModuleId::default(),
|
||||
trivia: Vec::new(),
|
||||
},
|
||||
return_type: None,
|
||||
digest: None,
|
||||
@ -3859,7 +3851,6 @@ const cylinder = startSketchOn('-XZ')
|
||||
start: 0,
|
||||
end: 0,
|
||||
module_id: ModuleId::default(),
|
||||
trivia: Vec::new(),
|
||||
},
|
||||
return_type: None,
|
||||
digest: None,
|
||||
@ -3901,7 +3892,6 @@ const cylinder = startSketchOn('-XZ')
|
||||
start: 0,
|
||||
end: 0,
|
||||
module_id: ModuleId::default(),
|
||||
trivia: Vec::new(),
|
||||
},
|
||||
return_type: None,
|
||||
digest: None,
|
||||
|
@ -131,7 +131,7 @@ mod tests {
|
||||
ast::types::{Literal, LiteralValue},
|
||||
token::NumericSuffix,
|
||||
},
|
||||
ModuleId,
|
||||
source_range::ModuleId,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -4,8 +4,7 @@ use crate::{
|
||||
ast::types::{Node, Program},
|
||||
token::TokenStream,
|
||||
},
|
||||
source_range::SourceRange,
|
||||
ModuleId,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
};
|
||||
|
||||
pub(crate) mod ast;
|
||||
|
@ -308,7 +308,6 @@ fn annotation(i: &mut TokenSlice) -> PResult<Node<NonCodeNode>> {
|
||||
value,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
}),
|
||||
comma_sep,
|
||||
)
|
||||
@ -427,7 +426,6 @@ fn pipe_expression(i: &mut TokenSlice) -> PResult<Node<PipeExpression>> {
|
||||
non_code_meta,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -830,7 +828,6 @@ fn object_property_same_key_and_val(i: &mut TokenSlice) -> PResult<Node<ObjectPr
|
||||
key,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -859,7 +856,6 @@ fn object_property(i: &mut TokenSlice) -> PResult<Node<ObjectProperty>> {
|
||||
value: expr,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
};
|
||||
|
||||
if sep.token_type == TokenType::Colon {
|
||||
@ -1790,7 +1786,6 @@ fn return_stmt(i: &mut TokenSlice) -> PResult<Node<ReturnStatement>> {
|
||||
end: argument.end(),
|
||||
module_id: ret.module_id,
|
||||
inner: ReturnStatement { argument, digest: None },
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -2017,13 +2012,11 @@ fn declaration(i: &mut TokenSlice) -> PResult<BoxNode<VariableDeclaration>> {
|
||||
init: val,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
},
|
||||
visibility,
|
||||
kind,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -2229,7 +2222,6 @@ fn unary_expression(i: &mut TokenSlice) -> PResult<Node<UnaryExpression>> {
|
||||
argument,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -2310,7 +2302,6 @@ fn expression_stmt(i: &mut TokenSlice) -> PResult<Node<ExpressionStatement>> {
|
||||
expression: val,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -2750,7 +2741,6 @@ fn fn_call(i: &mut TokenSlice) -> PResult<Node<CallExpression>> {
|
||||
arguments: args,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -2780,7 +2770,6 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
|
||||
arguments: args,
|
||||
digest: None,
|
||||
},
|
||||
trivia: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
assertion_line: 4521
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
assertion_line: 4522
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
assertion_line: 4523
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
assertion_line: 4524
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
assertion_line: 4525
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/parsing/parser.rs
|
||||
expression: actual
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"body": [
|
||||
|
@ -18,8 +18,8 @@ use winnow::{
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
parsing::ast::types::{ItemVisibility, VariableKind},
|
||||
source_range::SourceRange,
|
||||
CompilationError, ModuleId,
|
||||
source_range::{ModuleId, SourceRange},
|
||||
CompilationError,
|
||||
};
|
||||
|
||||
mod tokeniser;
|
||||
|
@ -13,7 +13,7 @@ use winnow::{
|
||||
use super::TokenStream;
|
||||
use crate::{
|
||||
parsing::token::{Token, TokenType},
|
||||
ModuleId,
|
||||
source_range::ModuleId,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
exec::ArtifactCommand,
|
||||
execution::{ArtifactGraph, Operation},
|
||||
parsing::ast::types::{Node, Program},
|
||||
ModuleId,
|
||||
source_range::ModuleId,
|
||||
};
|
||||
|
||||
/// Deserialize the data from a snapshot.
|
||||
|
@ -2,7 +2,26 @@ use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tower_lsp::lsp_types::{Position as LspPosition, Range as LspRange};
|
||||
|
||||
use crate::modules::ModuleId;
|
||||
/// Identifier of a source file. Uses a u32 to keep the size small.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
pub struct ModuleId(u32);
|
||||
|
||||
impl ModuleId {
|
||||
pub fn from_usize(id: usize) -> Self {
|
||||
Self(u32::try_from(id).expect("module ID should fit in a u32"))
|
||||
}
|
||||
|
||||
pub fn as_usize(&self) -> usize {
|
||||
usize::try_from(self.0).expect("module ID should fit in a usize")
|
||||
}
|
||||
|
||||
/// Top-level file is the one being executed.
|
||||
/// Represented by module ID of 0, i.e. the default value.
|
||||
pub fn is_top_level(&self) -> bool {
|
||||
*self == Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// The first two items are the start and end points (byte offsets from the start of the file).
|
||||
/// The third item is whether the source range belongs to the 'main' file, i.e., the file currently
|
||||
|
@ -180,12 +180,12 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
||||
/// color = '#ff0000',
|
||||
/// metalness = 90,
|
||||
/// roughness = 90
|
||||
/// )
|
||||
/// |> patternLinear3d({
|
||||
/// axis = [1, 0, 1],
|
||||
/// instances = 7,
|
||||
/// distance = 6
|
||||
/// }, %)
|
||||
/// )
|
||||
/// |> patternLinear3d(
|
||||
/// axis = [1, 0, 1],
|
||||
/// instances = 7,
|
||||
/// distance = 6
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
@ -199,16 +199,16 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
||||
/// |> close()
|
||||
///
|
||||
/// example = extrude(exampleSketch, length = 1)
|
||||
/// |> patternLinear3d({
|
||||
/// |> patternLinear3d(
|
||||
/// axis = [1, 0, 1],
|
||||
/// instances = 7,
|
||||
/// distance = 6
|
||||
/// }, %)
|
||||
/// |> appearance(
|
||||
/// color = '#ff0000',
|
||||
/// metalness = 90,
|
||||
/// roughness = 90
|
||||
/// )
|
||||
/// )
|
||||
/// |> appearance(
|
||||
/// color = '#ff0000',
|
||||
/// metalness = 90,
|
||||
/// roughness = 90
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
@ -219,12 +219,12 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
|
||||
/// |> line(end = [-1, 0])
|
||||
/// |> line(end = [0, -5])
|
||||
/// |> close()
|
||||
/// |> patternCircular2d({
|
||||
/// |> patternCircular2d(
|
||||
/// center = [0, 0],
|
||||
/// instances = 13,
|
||||
/// arcDegrees = 360,
|
||||
/// rotateDuplicates = true
|
||||
/// }, %)
|
||||
/// )
|
||||
///
|
||||
/// example = extrude(exampleSketch, length = 1)
|
||||
/// |> appearance(
|
||||
|
@ -440,13 +440,6 @@ impl Args {
|
||||
FromArgs::from_args(self, 0)
|
||||
}
|
||||
|
||||
pub(crate) fn get_data_and_solid_set<'a, T>(&'a self) -> Result<(T, SolidSet), KclError>
|
||||
where
|
||||
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
||||
{
|
||||
FromArgs::from_args(self, 0)
|
||||
}
|
||||
|
||||
pub(crate) fn get_data_and_solid<'a, T>(&'a self) -> Result<(T, Box<Solid>), KclError>
|
||||
where
|
||||
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
||||
@ -943,72 +936,6 @@ impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::Direction {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::patterns::CircularPattern3dData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, instances);
|
||||
let_field_of!(obj, arc_degrees "arcDegrees");
|
||||
let_field_of!(obj, rotate_duplicates "rotateDuplicates");
|
||||
let_field_of!(obj, axis);
|
||||
let_field_of!(obj, center);
|
||||
let_field_of!(obj, use_original? "useOriginal");
|
||||
Some(Self {
|
||||
instances,
|
||||
axis,
|
||||
center,
|
||||
arc_degrees,
|
||||
rotate_duplicates,
|
||||
use_original,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::patterns::CircularPattern2dData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, instances);
|
||||
let_field_of!(obj, arc_degrees "arcDegrees");
|
||||
let_field_of!(obj, rotate_duplicates "rotateDuplicates");
|
||||
let_field_of!(obj, center);
|
||||
let_field_of!(obj, use_original? "useOriginal");
|
||||
Some(Self {
|
||||
instances,
|
||||
center,
|
||||
arc_degrees,
|
||||
rotate_duplicates,
|
||||
use_original,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::patterns::LinearPattern3dData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, distance);
|
||||
let_field_of!(obj, instances);
|
||||
let_field_of!(obj, axis);
|
||||
Some(Self {
|
||||
instances,
|
||||
distance,
|
||||
axis,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::patterns::LinearPattern2dData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
let_field_of!(obj, distance);
|
||||
let_field_of!(obj, instances);
|
||||
let_field_of!(obj, axis);
|
||||
Some(Self {
|
||||
instances,
|
||||
distance,
|
||||
axis,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromKclValue<'a> for super::sketch::BezierData {
|
||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||
let obj = arg.as_object()?;
|
||||
|
@ -29,22 +29,6 @@ use crate::{
|
||||
|
||||
const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry";
|
||||
|
||||
/// Data for a linear pattern on a 2D sketch.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LinearPattern2dData {
|
||||
/// The number of total instances. Must be greater than or equal to 1.
|
||||
/// This includes the original entity. For example, if instances is 2,
|
||||
/// there will be two copies -- the original, and one new copy.
|
||||
/// If instances is 1, this has no effect.
|
||||
pub instances: u32,
|
||||
/// The distance between each repetition. This can also be referred to as spacing.
|
||||
pub distance: f64,
|
||||
/// The axis of the pattern. This is a 2D vector.
|
||||
pub axis: [f64; 2],
|
||||
}
|
||||
|
||||
/// Data for a linear pattern on a 3D model.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
@ -689,10 +673,13 @@ mod tests {
|
||||
|
||||
/// A linear pattern on a 2D sketch.
|
||||
pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, sketch_set, use_original): (LinearPattern2dData, SketchSet, Option<bool>) =
|
||||
super::args::FromArgs::from_args(&args, 0)?;
|
||||
let sketch_set: SketchSet = args.get_unlabeled_kw_arg("sketchSet")?;
|
||||
let instances: u32 = args.get_kw_arg("instances")?;
|
||||
let distance: f64 = args.get_kw_arg("distance")?;
|
||||
let axis: [f64; 2] = args.get_kw_arg("axis")?;
|
||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||
|
||||
if data.axis == [0.0, 0.0] {
|
||||
if axis == [0.0, 0.0] {
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
message:
|
||||
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
|
||||
@ -701,7 +688,8 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
|
||||
}));
|
||||
}
|
||||
|
||||
let sketches = inner_pattern_linear_2d(data, sketch_set, use_original, exec_state, args).await?;
|
||||
let sketches =
|
||||
inner_pattern_linear_2d(sketch_set, instances, distance, axis, use_original, exec_state, args).await?;
|
||||
Ok(sketches.into())
|
||||
}
|
||||
|
||||
@ -711,31 +699,41 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
|
||||
/// ```no_run
|
||||
/// exampleSketch = startSketchOn('XZ')
|
||||
/// |> circle({ center = [0, 0], radius = 1 }, %)
|
||||
/// |> patternLinear2d({
|
||||
/// |> patternLinear2d(
|
||||
/// axis = [1, 0],
|
||||
/// instances = 7,
|
||||
/// distance = 4
|
||||
/// }, %)
|
||||
/// )
|
||||
///
|
||||
/// example = extrude(exampleSketch, length = 1)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "patternLinear2d",
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
args = {
|
||||
sketch_set = { docs = "The sketch(es) to duplicate" },
|
||||
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
|
||||
distance = { docs = "Distance between each repetition. Also known as 'spacing'."},
|
||||
axis = { docs = "The axis of the pattern. A 2D vector." },
|
||||
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
|
||||
}
|
||||
}]
|
||||
async fn inner_pattern_linear_2d(
|
||||
data: LinearPattern2dData,
|
||||
sketch_set: SketchSet,
|
||||
instances: u32,
|
||||
distance: f64,
|
||||
axis: [f64; 2],
|
||||
use_original: Option<bool>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Box<Sketch>>, KclError> {
|
||||
let axis = data.axis;
|
||||
let [x, y] = axis;
|
||||
let axis_len = f64::sqrt(x * x + y * y);
|
||||
let normalized_axis = kcmc::shared::Point2d::from([x / axis_len, y / axis_len]);
|
||||
let transforms: Vec<_> = (1..data.instances)
|
||||
let transforms: Vec<_> = (1..instances)
|
||||
.map(|i| {
|
||||
let d = data.distance * (i as f64);
|
||||
let d = distance * (i as f64);
|
||||
let translate = (normalized_axis * d).with_z(0.0).map(LengthUnit);
|
||||
vec![Transform {
|
||||
translate,
|
||||
@ -755,10 +753,13 @@ async fn inner_pattern_linear_2d(
|
||||
|
||||
/// A linear pattern on a 3D model.
|
||||
pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, solid_set, use_original): (LinearPattern3dData, SolidSet, Option<bool>) =
|
||||
super::args::FromArgs::from_args(&args, 0)?;
|
||||
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
|
||||
let instances: u32 = args.get_kw_arg("instances")?;
|
||||
let distance: f64 = args.get_kw_arg("distance")?;
|
||||
let axis: [f64; 3] = args.get_kw_arg("axis")?;
|
||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||
|
||||
if data.axis == [0.0, 0.0, 0.0] {
|
||||
if axis == [0.0, 0.0, 0.0] {
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
message:
|
||||
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
|
||||
@ -767,7 +768,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
|
||||
}));
|
||||
}
|
||||
|
||||
let solids = inner_pattern_linear_3d(data, solid_set, use_original, exec_state, args).await?;
|
||||
let solids = inner_pattern_linear_3d(solid_set, instances, distance, axis, use_original, exec_state, args).await?;
|
||||
Ok(solids.into())
|
||||
}
|
||||
|
||||
@ -783,30 +784,40 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
|
||||
/// |> close()
|
||||
///
|
||||
/// example = extrude(exampleSketch, length = 1)
|
||||
/// |> patternLinear3d({
|
||||
/// |> patternLinear3d(
|
||||
/// axis = [1, 0, 1],
|
||||
/// instances = 7,
|
||||
/// distance = 6
|
||||
/// }, %)
|
||||
/// )
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "patternLinear3d",
|
||||
feature_tree_operation = true,
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
args = {
|
||||
solid_set = { docs = "The solid(s) to duplicate" },
|
||||
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
|
||||
distance = { docs = "Distance between each repetition. Also known as 'spacing'."},
|
||||
axis = { docs = "The axis of the pattern. A 2D vector." },
|
||||
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
|
||||
}
|
||||
}]
|
||||
async fn inner_pattern_linear_3d(
|
||||
data: LinearPattern3dData,
|
||||
solid_set: SolidSet,
|
||||
instances: u32,
|
||||
distance: f64,
|
||||
axis: [f64; 3],
|
||||
use_original: Option<bool>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Box<Solid>>, KclError> {
|
||||
let axis = data.axis;
|
||||
let [x, y, z] = axis;
|
||||
let axis_len = f64::sqrt(x * x + y * y + z * z);
|
||||
let normalized_axis = kcmc::shared::Point3d::from([x / axis_len, y / axis_len, z / axis_len]);
|
||||
let transforms: Vec<_> = (1..data.instances)
|
||||
let transforms: Vec<_> = (1..instances)
|
||||
.map(|i| {
|
||||
let d = data.distance * (i as f64);
|
||||
let d = distance * (i as f64);
|
||||
let translate = (normalized_axis * d).map(LengthUnit);
|
||||
vec![Transform {
|
||||
translate,
|
||||
@ -828,7 +839,7 @@ async fn inner_pattern_linear_3d(
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CircularPattern2dData {
|
||||
struct CircularPattern2dData {
|
||||
/// The number of total instances. Must be greater than or equal to 1.
|
||||
/// This includes the original entity. For example, if instances is 2,
|
||||
/// there will be two copies -- the original, and one new copy.
|
||||
@ -870,7 +881,7 @@ pub struct CircularPattern3dData {
|
||||
pub use_original: Option<bool>,
|
||||
}
|
||||
|
||||
pub enum CircularPattern {
|
||||
enum CircularPattern {
|
||||
ThreeD(CircularPattern3dData),
|
||||
TwoD(CircularPattern2dData),
|
||||
}
|
||||
@ -941,9 +952,24 @@ impl CircularPattern {
|
||||
|
||||
/// A circular pattern on a 2D sketch.
|
||||
pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, sketch_set): (CircularPattern2dData, SketchSet) = args.get_data_and_sketch_set()?;
|
||||
let sketch_set: SketchSet = args.get_unlabeled_kw_arg("sketchSet")?;
|
||||
let instances: u32 = args.get_kw_arg("instances")?;
|
||||
let center: [f64; 2] = args.get_kw_arg("center")?;
|
||||
let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?;
|
||||
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
|
||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||
|
||||
let sketches = inner_pattern_circular_2d(data, sketch_set, exec_state, args).await?;
|
||||
let sketches = inner_pattern_circular_2d(
|
||||
sketch_set,
|
||||
instances,
|
||||
center,
|
||||
arc_degrees,
|
||||
rotate_duplicates,
|
||||
use_original,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
Ok(sketches.into())
|
||||
}
|
||||
|
||||
@ -959,21 +985,36 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu
|
||||
/// |> line(end = [-1, 0])
|
||||
/// |> line(end = [0, -5])
|
||||
/// |> close()
|
||||
/// |> patternCircular2d({
|
||||
/// |> patternCircular2d(
|
||||
/// center = [0, 0],
|
||||
/// instances = 13,
|
||||
/// arcDegrees = 360,
|
||||
/// rotateDuplicates = true
|
||||
/// }, %)
|
||||
/// )
|
||||
///
|
||||
/// example = extrude(exampleSketch, length = 1)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "patternCircular2d",
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
args = {
|
||||
sketch_set = { docs = "Which sketch(es) to pattern" },
|
||||
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect."},
|
||||
center = { docs = "The center about which to make the pattern. This is a 2D vector."},
|
||||
arc_degrees = { docs = "The arc angle (in degrees) to place the repetitions. Must be greater than 0."},
|
||||
rotate_duplicates= { docs = "Whether or not to rotate the duplicates as they are copied."},
|
||||
use_original= { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false."},
|
||||
}
|
||||
}]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn inner_pattern_circular_2d(
|
||||
data: CircularPattern2dData,
|
||||
sketch_set: SketchSet,
|
||||
instances: u32,
|
||||
center: [f64; 2],
|
||||
arc_degrees: f64,
|
||||
rotate_duplicates: bool,
|
||||
use_original: Option<bool>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Box<Sketch>>, KclError> {
|
||||
@ -982,6 +1023,13 @@ async fn inner_pattern_circular_2d(
|
||||
if args.ctx.context_type == crate::execution::ContextType::Mock {
|
||||
return Ok(starting_sketches);
|
||||
}
|
||||
let data = CircularPattern2dData {
|
||||
instances,
|
||||
center,
|
||||
arc_degrees,
|
||||
rotate_duplicates,
|
||||
use_original,
|
||||
};
|
||||
|
||||
let mut sketches = Vec::new();
|
||||
for sketch in starting_sketches.iter() {
|
||||
@ -1008,9 +1056,36 @@ async fn inner_pattern_circular_2d(
|
||||
|
||||
/// A circular pattern on a 3D model.
|
||||
pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let (data, solid_set): (CircularPattern3dData, SolidSet) = args.get_data_and_solid_set()?;
|
||||
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
|
||||
// The number of total instances. Must be greater than or equal to 1.
|
||||
// This includes the original entity. For example, if instances is 2,
|
||||
// there will be two copies -- the original, and one new copy.
|
||||
// If instances is 1, this has no effect.
|
||||
let instances: u32 = args.get_kw_arg("instances")?;
|
||||
// The axis around which to make the pattern. This is a 3D vector.
|
||||
let axis: [f64; 3] = args.get_kw_arg("axis")?;
|
||||
// The center about which to make the pattern. This is a 3D vector.
|
||||
let center: [f64; 3] = args.get_kw_arg("center")?;
|
||||
// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
|
||||
let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?;
|
||||
// Whether or not to rotate the duplicates as they are copied.
|
||||
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
|
||||
// If the target being patterned is itself a pattern, then, should you use the original solid,
|
||||
// or the pattern?
|
||||
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
|
||||
|
||||
let solids = inner_pattern_circular_3d(data, solid_set, exec_state, args).await?;
|
||||
let solids = inner_pattern_circular_3d(
|
||||
solid_set,
|
||||
instances,
|
||||
axis,
|
||||
center,
|
||||
arc_degrees,
|
||||
rotate_duplicates,
|
||||
use_original,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
Ok(solids.into())
|
||||
}
|
||||
|
||||
@ -1024,21 +1099,38 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
|
||||
/// |> circle({ center = [0, 0], radius = 1 }, %)
|
||||
///
|
||||
/// example = extrude(exampleSketch, length = -5)
|
||||
/// |> patternCircular3d({
|
||||
/// |> patternCircular3d(
|
||||
/// axis = [1, -1, 0],
|
||||
/// center = [10, -20, 0],
|
||||
/// instances = 11,
|
||||
/// arcDegrees = 360,
|
||||
/// rotateDuplicates = true
|
||||
/// }, %)
|
||||
/// )
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "patternCircular3d",
|
||||
feature_tree_operation = true,
|
||||
keywords = true,
|
||||
unlabeled_first = true,
|
||||
args = {
|
||||
solid_set = { docs = "Which solid(s) to pattern" },
|
||||
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect."},
|
||||
axis = { docs = "The axis around which to make the pattern. This is a 3D vector"},
|
||||
center = { docs = "The center about which to make the pattern. This is a 3D vector."},
|
||||
arc_degrees = { docs = "The arc angle (in degrees) to place the repetitions. Must be greater than 0."},
|
||||
rotate_duplicates= { docs = "Whether or not to rotate the duplicates as they are copied."},
|
||||
use_original= { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false."},
|
||||
}
|
||||
}]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn inner_pattern_circular_3d(
|
||||
data: CircularPattern3dData,
|
||||
solid_set: SolidSet,
|
||||
instances: u32,
|
||||
axis: [f64; 3],
|
||||
center: [f64; 3],
|
||||
arc_degrees: f64,
|
||||
rotate_duplicates: bool,
|
||||
use_original: Option<bool>,
|
||||
exec_state: &mut ExecState,
|
||||
args: Args,
|
||||
) -> Result<Vec<Box<Solid>>, KclError> {
|
||||
@ -1055,6 +1147,14 @@ async fn inner_pattern_circular_3d(
|
||||
}
|
||||
|
||||
let mut solids = Vec::new();
|
||||
let data = CircularPattern3dData {
|
||||
instances,
|
||||
axis,
|
||||
center,
|
||||
arc_degrees,
|
||||
rotate_duplicates,
|
||||
use_original,
|
||||
};
|
||||
for solid in starting_solids.iter() {
|
||||
let geometries = pattern_circular(
|
||||
CircularPattern::ThreeD(data.clone()),
|
||||
|
@ -334,8 +334,25 @@ impl CallExpressionKw {
|
||||
.iter()
|
||||
.map(|arg| arg.recast(options, indentation_level, ctxt)),
|
||||
);
|
||||
let args = arg_list.join(", ");
|
||||
format!("{indent}{name}({args})")
|
||||
let args = arg_list.clone().join(", ");
|
||||
if arg_list.len() >= 4 {
|
||||
let inner_indentation = if ctxt == ExprContext::Pipe {
|
||||
options.get_indentation_offset_pipe(indentation_level + 1)
|
||||
} else {
|
||||
options.get_indentation(indentation_level + 1)
|
||||
};
|
||||
let mut args = arg_list.join(&format!(",\n{inner_indentation}"));
|
||||
args.push(',');
|
||||
let args = args;
|
||||
let end_indent = if ctxt == ExprContext::Pipe {
|
||||
options.get_indentation_offset_pipe(indentation_level)
|
||||
} else {
|
||||
options.get_indentation(indentation_level)
|
||||
};
|
||||
format!("{indent}{name}(\n{inner_indentation}{args}\n{end_indent})")
|
||||
} else {
|
||||
format!("{indent}{name}({args})")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,7 +812,7 @@ mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use crate::{parsing::ast::types::FormatOptions, ModuleId};
|
||||
use crate::{parsing::ast::types::FormatOptions, source_range::ModuleId};
|
||||
|
||||
#[test]
|
||||
fn test_recast_if_else_if_same() {
|
||||
@ -1031,13 +1048,13 @@ sphere = startSketchOn('XZ')
|
||||
}, %)
|
||||
|> close()
|
||||
|> revolve({ axis: 'x' }, %)
|
||||
|> patternCircular3d({
|
||||
|> patternCircular3d(
|
||||
axis = [0, 0, 1],
|
||||
center = [0, 0, 0],
|
||||
repetitions = 10,
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = true
|
||||
}, %)
|
||||
)
|
||||
|
||||
// Sketch and revolve the outside bearing
|
||||
outsideRevolve = startSketchOn('XZ')
|
||||
@ -1098,13 +1115,13 @@ sphere = startSketchOn('XZ')
|
||||
}, %)
|
||||
|> close()
|
||||
|> revolve({ axis = 'x' }, %)
|
||||
|> patternCircular3d({
|
||||
|> patternCircular3d(
|
||||
axis = [0, 0, 1],
|
||||
center = [0, 0, 0],
|
||||
repetitions = 10,
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = true
|
||||
}, %)
|
||||
rotateDuplicates = true,
|
||||
)
|
||||
|
||||
// Sketch and revolve the outside bearing
|
||||
outsideRevolve = startSketchOn('XZ')
|
||||
@ -1417,11 +1434,11 @@ tabs_r = startSketchOn({
|
||||
radius = hole_diam / 2
|
||||
}, %), %)
|
||||
|> extrude(-thk, %)
|
||||
|> patternLinear3d({
|
||||
|> patternLinear3d(
|
||||
axis = [0, -1, 0],
|
||||
repetitions = 1,
|
||||
distance = length - 10
|
||||
}, %)
|
||||
)
|
||||
// build the tabs of the mounting bracket (left side)
|
||||
tabs_l = startSketchOn({
|
||||
plane: {
|
||||
@ -1444,11 +1461,7 @@ tabs_l = startSketchOn({
|
||||
radius = hole_diam / 2
|
||||
}, %), %)
|
||||
|> extrude(-thk, %)
|
||||
|> patternLinear3d({
|
||||
axis = [0, -1, 0],
|
||||
repetitions = 1,
|
||||
distance = length - 10
|
||||
}, %)
|
||||
|> patternLinear3d(axis = [0, -1, 0], repetitions = 1, distance = length - 10)
|
||||
"#;
|
||||
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
|
||||
|
||||
@ -1542,11 +1555,7 @@ tabs_r = startSketchOn({
|
||||
radius = hole_diam / 2
|
||||
}, %), %)
|
||||
|> extrude(-thk, %)
|
||||
|> patternLinear3d({
|
||||
axis = [0, -1, 0],
|
||||
repetitions = 1,
|
||||
distance = length - 10
|
||||
}, %)
|
||||
|> patternLinear3d(axis = [0, -1, 0], repetitions = 1, distance = length - 10)
|
||||
// build the tabs of the mounting bracket (left side)
|
||||
tabs_l = startSketchOn({
|
||||
plane = {
|
||||
@ -1569,11 +1578,7 @@ tabs_l = startSketchOn({
|
||||
radius = hole_diam / 2
|
||||
}, %), %)
|
||||
|> extrude(-thk, %)
|
||||
|> patternLinear3d({
|
||||
axis = [0, -1, 0],
|
||||
repetitions = 1,
|
||||
distance = length - 10
|
||||
}, %)
|
||||
|> patternLinear3d(axis = [0, -1, 0], repetitions = 1, distance = length - 10)
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing angled_line.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing artifact_graph_example_code1.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing artifact_graph_example_code1.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing artifact_graph_example_code_no_3d.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing artifact_graph_example_code_no_3d.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing artifact_graph_example_code_offset_planes.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing artifact_graph_sketch_on_face_etc.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing basic_fillet_cube_close_opposite.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing basic_fillet_cube_end.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing basic_fillet_cube_next_adjacent.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing basic_fillet_cube_previous_adjacent.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing basic_fillet_cube_start.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing big_number_angle_to_match_length_x.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing big_number_angle_to_match_length_x.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing big_number_angle_to_match_length_y.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -631,7 +631,7 @@ snapshot_kind: text
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
189,
|
||||
276,
|
||||
277,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -819,8 +819,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -844,8 +844,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -869,8 +869,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -894,8 +894,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -919,8 +919,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -944,8 +944,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -969,8 +969,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing circular_pattern3d_a_pattern.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
@ -321,7 +322,7 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 276,
|
||||
"end": 277,
|
||||
"id": {
|
||||
"end": 186,
|
||||
"name": "pattn1",
|
||||
@ -331,115 +332,88 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 260,
|
||||
"properties": [
|
||||
{
|
||||
"end": 225,
|
||||
"key": {
|
||||
"end": 213,
|
||||
"name": "axis",
|
||||
"start": 209,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 209,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 218,
|
||||
"raw": "1",
|
||||
"start": 217,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 221,
|
||||
"raw": "0",
|
||||
"start": 220,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 224,
|
||||
"raw": "0",
|
||||
"start": 223,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 225,
|
||||
"start": 216,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 242,
|
||||
"key": {
|
||||
"end": 238,
|
||||
"name": "instances",
|
||||
"start": 229,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 229,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 242,
|
||||
"raw": "7",
|
||||
"start": 241,
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "axis"
|
||||
},
|
||||
"arg": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 234,
|
||||
"raw": "1",
|
||||
"start": 233,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 258,
|
||||
"key": {
|
||||
"end": 254,
|
||||
"name": "distance",
|
||||
"start": 246,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 246,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 258,
|
||||
"raw": "6",
|
||||
"start": 257,
|
||||
{
|
||||
"end": 237,
|
||||
"raw": "0",
|
||||
"start": 236,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 6.0,
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 240,
|
||||
"raw": "0",
|
||||
"start": 239,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 205,
|
||||
"type": "ObjectExpression",
|
||||
"type": "ObjectExpression"
|
||||
],
|
||||
"end": 241,
|
||||
"start": 232,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 275,
|
||||
"name": "exampleSketch",
|
||||
"start": 262,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "instances"
|
||||
},
|
||||
"arg": {
|
||||
"end": 258,
|
||||
"raw": "7",
|
||||
"start": 257,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "distance"
|
||||
},
|
||||
"arg": {
|
||||
"end": 274,
|
||||
"raw": "6",
|
||||
"start": 273,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 6.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
@ -448,15 +422,22 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
|
||||
"start": 189,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 276,
|
||||
"end": 277,
|
||||
"start": 189,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"end": 221,
|
||||
"name": "exampleSketch",
|
||||
"start": 208,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 180,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 276,
|
||||
"end": 277,
|
||||
"kind": "const",
|
||||
"start": 180,
|
||||
"type": "VariableDeclaration",
|
||||
@ -464,241 +445,213 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 430,
|
||||
"end": 432,
|
||||
"id": {
|
||||
"end": 284,
|
||||
"end": 285,
|
||||
"name": "pattn2",
|
||||
"start": 278,
|
||||
"start": 279,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 421,
|
||||
"properties": [
|
||||
{
|
||||
"end": 325,
|
||||
"key": {
|
||||
"end": 313,
|
||||
"name": "axis",
|
||||
"start": 309,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 309,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 318,
|
||||
"raw": "0",
|
||||
"start": 317,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 321,
|
||||
"raw": "0",
|
||||
"start": 320,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 324,
|
||||
"raw": "1",
|
||||
"start": 323,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 325,
|
||||
"start": 316,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 353,
|
||||
"key": {
|
||||
"end": 335,
|
||||
"name": "center",
|
||||
"start": 329,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 329,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"elements": [
|
||||
{
|
||||
"argument": {
|
||||
"end": 342,
|
||||
"raw": "20",
|
||||
"start": 340,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"end": 342,
|
||||
"operator": "-",
|
||||
"start": 339,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
},
|
||||
{
|
||||
"argument": {
|
||||
"end": 347,
|
||||
"raw": "20",
|
||||
"start": 345,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"end": 347,
|
||||
"operator": "-",
|
||||
"start": 344,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
},
|
||||
{
|
||||
"argument": {
|
||||
"end": 352,
|
||||
"raw": "20",
|
||||
"start": 350,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"end": 352,
|
||||
"operator": "-",
|
||||
"start": 349,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
}
|
||||
],
|
||||
"end": 353,
|
||||
"start": 338,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 371,
|
||||
"key": {
|
||||
"end": 366,
|
||||
"name": "instances",
|
||||
"start": 357,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 357,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 371,
|
||||
"raw": "41",
|
||||
"start": 369,
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "axis"
|
||||
},
|
||||
"arg": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 328,
|
||||
"raw": "0",
|
||||
"start": 327,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 41.0,
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 391,
|
||||
"key": {
|
||||
"end": 385,
|
||||
"name": "arcDegrees",
|
||||
"start": 375,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 375,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 391,
|
||||
"raw": "360",
|
||||
"start": 388,
|
||||
{
|
||||
"end": 331,
|
||||
"raw": "0",
|
||||
"start": 330,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 360.0,
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 334,
|
||||
"raw": "1",
|
||||
"start": 333,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 419,
|
||||
"key": {
|
||||
"end": 411,
|
||||
"name": "rotateDuplicates",
|
||||
"start": 395,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 395,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 419,
|
||||
"raw": "false",
|
||||
"start": 414,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 305,
|
||||
"type": "ObjectExpression",
|
||||
"type": "ObjectExpression"
|
||||
],
|
||||
"end": 335,
|
||||
"start": 326,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 429,
|
||||
"name": "pattn1",
|
||||
"start": 423,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "center"
|
||||
},
|
||||
"arg": {
|
||||
"elements": [
|
||||
{
|
||||
"argument": {
|
||||
"end": 352,
|
||||
"raw": "20",
|
||||
"start": 350,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"end": 352,
|
||||
"operator": "-",
|
||||
"start": 349,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
},
|
||||
{
|
||||
"argument": {
|
||||
"end": 357,
|
||||
"raw": "20",
|
||||
"start": 355,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"end": 357,
|
||||
"operator": "-",
|
||||
"start": 354,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
},
|
||||
{
|
||||
"argument": {
|
||||
"end": 362,
|
||||
"raw": "20",
|
||||
"start": 360,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 20.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"end": 362,
|
||||
"operator": "-",
|
||||
"start": 359,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
}
|
||||
],
|
||||
"end": 363,
|
||||
"start": 348,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "instances"
|
||||
},
|
||||
"arg": {
|
||||
"end": 381,
|
||||
"raw": "41",
|
||||
"start": 379,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 41.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "arcDegrees"
|
||||
},
|
||||
"arg": {
|
||||
"end": 401,
|
||||
"raw": "360",
|
||||
"start": 398,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 360.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "rotateDuplicates"
|
||||
},
|
||||
"arg": {
|
||||
"end": 429,
|
||||
"raw": "false",
|
||||
"start": 424,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 304,
|
||||
"end": 305,
|
||||
"name": "patternCircular3d",
|
||||
"start": 287,
|
||||
"start": 288,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 430,
|
||||
"start": 287,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
"end": 432,
|
||||
"start": 288,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"end": 315,
|
||||
"name": "pattn1",
|
||||
"start": 309,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 278,
|
||||
"start": 279,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 430,
|
||||
"end": 432,
|
||||
"kind": "const",
|
||||
"start": 278,
|
||||
"start": 279,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 431,
|
||||
"end": 433,
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"0": [
|
||||
@ -713,8 +666,8 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
|
||||
],
|
||||
"1": [
|
||||
{
|
||||
"end": 278,
|
||||
"start": 276,
|
||||
"end": 279,
|
||||
"start": 277,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
|
@ -6,16 +6,18 @@ exampleSketch = startSketchOn('XZ')
|
||||
|> close(%)
|
||||
|> extrude(length = 1)
|
||||
|
||||
pattn1 = patternLinear3d({
|
||||
pattn1 = patternLinear3d(
|
||||
exampleSketch,
|
||||
axis = [1, 0, 0],
|
||||
instances = 7,
|
||||
distance = 6
|
||||
}, exampleSketch)
|
||||
distance = 6,
|
||||
)
|
||||
|
||||
pattn2 = patternCircular3d({
|
||||
pattn2 = patternCircular3d(
|
||||
pattn1,
|
||||
axis = [0, 0, 1],
|
||||
center = [-20, -20, -20],
|
||||
instances = 41,
|
||||
arcDegrees = 360,
|
||||
rotateDuplicates = false
|
||||
}, pattn1)
|
||||
rotateDuplicates = false,
|
||||
)
|
||||
|
@ -44,17 +44,24 @@ snapshot_kind: text
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"axis": {
|
||||
"sourceRange": [
|
||||
205,
|
||||
260,
|
||||
232,
|
||||
241,
|
||||
0
|
||||
]
|
||||
},
|
||||
"solid_set": {
|
||||
"distance": {
|
||||
"sourceRange": [
|
||||
262,
|
||||
275,
|
||||
273,
|
||||
274,
|
||||
0
|
||||
]
|
||||
},
|
||||
"instances": {
|
||||
"sourceRange": [
|
||||
257,
|
||||
258,
|
||||
0
|
||||
]
|
||||
}
|
||||
@ -62,24 +69,51 @@ snapshot_kind: text
|
||||
"name": "patternLinear3d",
|
||||
"sourceRange": [
|
||||
189,
|
||||
276,
|
||||
277,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": null
|
||||
"unlabeledArg": {
|
||||
"sourceRange": [
|
||||
208,
|
||||
221,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"data": {
|
||||
"arcDegrees": {
|
||||
"sourceRange": [
|
||||
305,
|
||||
421,
|
||||
398,
|
||||
401,
|
||||
0
|
||||
]
|
||||
},
|
||||
"solid_set": {
|
||||
"axis": {
|
||||
"sourceRange": [
|
||||
423,
|
||||
326,
|
||||
335,
|
||||
0
|
||||
]
|
||||
},
|
||||
"center": {
|
||||
"sourceRange": [
|
||||
348,
|
||||
363,
|
||||
0
|
||||
]
|
||||
},
|
||||
"instances": {
|
||||
"sourceRange": [
|
||||
379,
|
||||
381,
|
||||
0
|
||||
]
|
||||
},
|
||||
"rotateDuplicates": {
|
||||
"sourceRange": [
|
||||
424,
|
||||
429,
|
||||
0
|
||||
]
|
||||
@ -87,11 +121,17 @@ snapshot_kind: text
|
||||
},
|
||||
"name": "patternCircular3d",
|
||||
"sourceRange": [
|
||||
287,
|
||||
430,
|
||||
288,
|
||||
432,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": null
|
||||
"unlabeledArg": {
|
||||
"sourceRange": [
|
||||
309,
|
||||
315,
|
||||
0
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing cube.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing cube_with_error.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing fillet-and-shell.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing fillet-and-shell.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing function_sketch.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing function_sketch_with_position.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Artifact commands helix_simple.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
[
|
||||
{
|
||||
@ -383,7 +384,7 @@ description: Artifact commands helix_simple.kcl
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
151,
|
||||
242,
|
||||
257,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
|
@ -5,7 +5,7 @@ flowchart LR
|
||||
3["Segment<br>[102, 137, 0]"]
|
||||
end
|
||||
1["Plane<br>[46, 65, 0]"]
|
||||
4["Helix<br>[151, 242, 0]"]
|
||||
4["Helix<br>[151, 257, 0]"]
|
||||
1 --- 2
|
||||
2 --- 3
|
||||
3 <--x 4
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing helix_simple.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
@ -171,7 +172,7 @@ description: Result of parsing helix_simple.kcl
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 242,
|
||||
"end": 257,
|
||||
"id": {
|
||||
"end": 148,
|
||||
"name": "helixPath",
|
||||
@ -187,9 +188,9 @@ description: Result of parsing helix_simple.kcl
|
||||
"name": "angleStart"
|
||||
},
|
||||
"arg": {
|
||||
"end": 171,
|
||||
"end": 174,
|
||||
"raw": "0",
|
||||
"start": 170,
|
||||
"start": 173,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
@ -205,9 +206,9 @@ description: Result of parsing helix_simple.kcl
|
||||
"name": "ccw"
|
||||
},
|
||||
"arg": {
|
||||
"end": 183,
|
||||
"end": 188,
|
||||
"raw": "true",
|
||||
"start": 179,
|
||||
"start": 184,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": true
|
||||
@ -220,9 +221,9 @@ description: Result of parsing helix_simple.kcl
|
||||
"name": "revolutions"
|
||||
},
|
||||
"arg": {
|
||||
"end": 200,
|
||||
"end": 207,
|
||||
"raw": "5",
|
||||
"start": 199,
|
||||
"start": 206,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
@ -238,9 +239,9 @@ description: Result of parsing helix_simple.kcl
|
||||
"name": "length"
|
||||
},
|
||||
"arg": {
|
||||
"end": 213,
|
||||
"end": 222,
|
||||
"raw": "10",
|
||||
"start": 211,
|
||||
"start": 220,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
@ -256,9 +257,9 @@ description: Result of parsing helix_simple.kcl
|
||||
"name": "radius"
|
||||
},
|
||||
"arg": {
|
||||
"end": 225,
|
||||
"end": 236,
|
||||
"raw": "5",
|
||||
"start": 224,
|
||||
"start": 235,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
@ -274,9 +275,9 @@ description: Result of parsing helix_simple.kcl
|
||||
"name": "axis"
|
||||
},
|
||||
"arg": {
|
||||
"end": 241,
|
||||
"end": 254,
|
||||
"name": "edge001",
|
||||
"start": 234,
|
||||
"start": 247,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
@ -288,7 +289,7 @@ description: Result of parsing helix_simple.kcl
|
||||
"start": 151,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 242,
|
||||
"end": 257,
|
||||
"start": 151,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
@ -297,14 +298,14 @@ description: Result of parsing helix_simple.kcl
|
||||
"start": 139,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 242,
|
||||
"end": 257,
|
||||
"kind": "const",
|
||||
"start": 139,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 243,
|
||||
"end": 258,
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"0": [
|
||||
|
@ -3,4 +3,11 @@ helper001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line(end = [0, 10], tag = $edge001)
|
||||
|
||||
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = edge001)
|
||||
helixPath = helix(
|
||||
angleStart = 0,
|
||||
ccw = true,
|
||||
revolutions = 5,
|
||||
length = 10,
|
||||
radius = 5,
|
||||
axis = edge001,
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Operations executed helix_simple.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
[
|
||||
{
|
||||
@ -26,43 +27,43 @@ description: Operations executed helix_simple.kcl
|
||||
"labeledArgs": {
|
||||
"angleStart": {
|
||||
"sourceRange": [
|
||||
170,
|
||||
171,
|
||||
173,
|
||||
174,
|
||||
0
|
||||
]
|
||||
},
|
||||
"axis": {
|
||||
"sourceRange": [
|
||||
234,
|
||||
241,
|
||||
247,
|
||||
254,
|
||||
0
|
||||
]
|
||||
},
|
||||
"ccw": {
|
||||
"sourceRange": [
|
||||
179,
|
||||
183,
|
||||
184,
|
||||
188,
|
||||
0
|
||||
]
|
||||
},
|
||||
"length": {
|
||||
"sourceRange": [
|
||||
211,
|
||||
213,
|
||||
220,
|
||||
222,
|
||||
0
|
||||
]
|
||||
},
|
||||
"radius": {
|
||||
"sourceRange": [
|
||||
224,
|
||||
225,
|
||||
235,
|
||||
236,
|
||||
0
|
||||
]
|
||||
},
|
||||
"revolutions": {
|
||||
"sourceRange": [
|
||||
199,
|
||||
200,
|
||||
206,
|
||||
207,
|
||||
0
|
||||
]
|
||||
}
|
||||
@ -70,7 +71,7 @@ description: Operations executed helix_simple.kcl
|
||||
"name": "helix",
|
||||
"sourceRange": [
|
||||
151,
|
||||
242,
|
||||
257,
|
||||
0
|
||||
],
|
||||
"type": "StdLibCall",
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing helix_simple.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
@ -86,7 +87,7 @@ description: Program memory after executing helix_simple.kcl
|
||||
{
|
||||
"sourceRange": [
|
||||
151,
|
||||
242,
|
||||
257,
|
||||
0
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing import_cycle1.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing import_function_not_sketch.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing import_function_not_sketch.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Program memory after executing import_side_effect.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"environments": [
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing import_whole.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
|
@ -631,7 +631,7 @@ snapshot_kind: text
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
189,
|
||||
276,
|
||||
277,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -819,8 +819,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -1008,8 +1008,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -1197,8 +1197,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -1386,8 +1386,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -1575,8 +1575,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -1764,8 +1764,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
@ -1953,8 +1953,8 @@ snapshot_kind: text
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [
|
||||
287,
|
||||
367,
|
||||
288,
|
||||
369,
|
||||
0
|
||||
],
|
||||
"command": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
source: kcl/src/simulation_tests.rs
|
||||
description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
snapshot_kind: text
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
@ -321,7 +322,7 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 276,
|
||||
"end": 277,
|
||||
"id": {
|
||||
"end": 186,
|
||||
"name": "pattn1",
|
||||
@ -331,115 +332,88 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 260,
|
||||
"properties": [
|
||||
{
|
||||
"end": 225,
|
||||
"key": {
|
||||
"end": 213,
|
||||
"name": "axis",
|
||||
"start": 209,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 209,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 218,
|
||||
"raw": "1",
|
||||
"start": 217,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 221,
|
||||
"raw": "0",
|
||||
"start": 220,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 224,
|
||||
"raw": "0",
|
||||
"start": 223,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 225,
|
||||
"start": 216,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 242,
|
||||
"key": {
|
||||
"end": 238,
|
||||
"name": "instances",
|
||||
"start": 229,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 229,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 242,
|
||||
"raw": "7",
|
||||
"start": 241,
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "axis"
|
||||
},
|
||||
"arg": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 234,
|
||||
"raw": "1",
|
||||
"start": 233,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 258,
|
||||
"key": {
|
||||
"end": 254,
|
||||
"name": "distance",
|
||||
"start": 246,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 246,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 258,
|
||||
"raw": "6",
|
||||
"start": 257,
|
||||
{
|
||||
"end": 237,
|
||||
"raw": "0",
|
||||
"start": 236,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 6.0,
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 240,
|
||||
"raw": "0",
|
||||
"start": 239,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 205,
|
||||
"type": "ObjectExpression",
|
||||
"type": "ObjectExpression"
|
||||
],
|
||||
"end": 241,
|
||||
"start": 232,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 275,
|
||||
"name": "exampleSketch",
|
||||
"start": 262,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "instances"
|
||||
},
|
||||
"arg": {
|
||||
"end": 258,
|
||||
"raw": "7",
|
||||
"start": 257,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "distance"
|
||||
},
|
||||
"arg": {
|
||||
"end": 274,
|
||||
"raw": "6",
|
||||
"start": 273,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 6.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
@ -448,15 +422,22 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
"start": 189,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 276,
|
||||
"end": 277,
|
||||
"start": 189,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"end": 221,
|
||||
"name": "exampleSketch",
|
||||
"start": 208,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 180,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 276,
|
||||
"end": 277,
|
||||
"kind": "const",
|
||||
"start": 180,
|
||||
"type": "VariableDeclaration",
|
||||
@ -464,84 +445,49 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
},
|
||||
{
|
||||
"declaration": {
|
||||
"end": 367,
|
||||
"end": 369,
|
||||
"id": {
|
||||
"end": 284,
|
||||
"end": 285,
|
||||
"name": "pattn2",
|
||||
"start": 278,
|
||||
"start": 279,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"arguments": [
|
||||
{
|
||||
"end": 358,
|
||||
"properties": [
|
||||
{
|
||||
"end": 323,
|
||||
"key": {
|
||||
"end": 311,
|
||||
"name": "axis",
|
||||
"start": 307,
|
||||
"type": "Identifier"
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "axis"
|
||||
},
|
||||
"arg": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 326,
|
||||
"raw": "0",
|
||||
"start": 325,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"start": 307,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"elements": [
|
||||
{
|
||||
"end": 316,
|
||||
"raw": "0",
|
||||
"start": 315,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 319,
|
||||
"raw": "0",
|
||||
"start": 318,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 322,
|
||||
"raw": "1",
|
||||
"start": 321,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 323,
|
||||
"start": 314,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 339,
|
||||
"key": {
|
||||
"end": 335,
|
||||
"name": "distance",
|
||||
"start": 327,
|
||||
"type": "Identifier"
|
||||
{
|
||||
"end": 329,
|
||||
"raw": "0",
|
||||
"start": 328,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"start": 327,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 339,
|
||||
{
|
||||
"end": 332,
|
||||
"raw": "1",
|
||||
"start": 338,
|
||||
"start": 331,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
@ -549,64 +495,79 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 356,
|
||||
"key": {
|
||||
"end": 352,
|
||||
"name": "instances",
|
||||
"start": 343,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 343,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"end": 356,
|
||||
"raw": "7",
|
||||
"start": 355,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 303,
|
||||
"type": "ObjectExpression",
|
||||
"type": "ObjectExpression"
|
||||
],
|
||||
"end": 333,
|
||||
"start": 324,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"end": 366,
|
||||
"name": "pattn1",
|
||||
"start": 360,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "distance"
|
||||
},
|
||||
"arg": {
|
||||
"end": 349,
|
||||
"raw": "1",
|
||||
"start": 348,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"type": "Identifier",
|
||||
"name": "instances"
|
||||
},
|
||||
"arg": {
|
||||
"end": 366,
|
||||
"raw": "7",
|
||||
"start": 365,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 7.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"end": 302,
|
||||
"end": 303,
|
||||
"name": "patternLinear3d",
|
||||
"start": 287,
|
||||
"start": 288,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"end": 367,
|
||||
"start": 287,
|
||||
"type": "CallExpression",
|
||||
"type": "CallExpression"
|
||||
"end": 369,
|
||||
"start": 288,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"end": 313,
|
||||
"name": "pattn1",
|
||||
"start": 307,
|
||||
"type": "Identifier",
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
"start": 278,
|
||||
"start": 279,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 367,
|
||||
"end": 369,
|
||||
"kind": "const",
|
||||
"start": 278,
|
||||
"start": 279,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"end": 368,
|
||||
"end": 370,
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"0": [
|
||||
@ -621,8 +582,8 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
|
||||
],
|
||||
"1": [
|
||||
{
|
||||
"end": 278,
|
||||
"start": 276,
|
||||
"end": 279,
|
||||
"start": 277,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
|
@ -6,14 +6,16 @@ exampleSketch = startSketchOn('XZ')
|
||||
|> close(%)
|
||||
|> extrude(length = 1)
|
||||
|
||||
pattn1 = patternLinear3d({
|
||||
pattn1 = patternLinear3d(
|
||||
exampleSketch,
|
||||
axis = [1, 0, 0],
|
||||
instances = 7,
|
||||
distance = 6
|
||||
}, exampleSketch)
|
||||
distance = 6,
|
||||
)
|
||||
|
||||
pattn2 = patternLinear3d({
|
||||
pattn2 = patternLinear3d(
|
||||
pattn1,
|
||||
axis = [0, 0, 1],
|
||||
distance = 1,
|
||||
instances = 7
|
||||
}, pattn1)
|
||||
instances = 7,
|
||||
)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user