Compare commits

...

13 Commits

Author SHA1 Message Date
61807e7629 KCL: Make shell stdlib fn use keyword arguments (#5293)
Before:

```
shell({ faces = ['end'], thickness = caseThickness }, case)
```

After:
```
shell(case, faces = ['end'], thickness = caseThickness)
```
2025-02-07 02:03:12 +00:00
357bbffce5 refactor: Rename function to not have unneeded prefix (#5292) 2025-02-06 19:54:58 -05:00
6ac9c49773 KCL: Patterns of patterns can use the original sketch/solid as target (#5284)
Right now, if you model something like this box with a button:

<img width="413" alt="Screenshot 2025-02-06 at 3 08 03 PM" src="https://github.com/user-attachments/assets/04818a70-7cf3-4ee3-b8c5-df5959ac10db" />

Let's say you want to pattern the button, and repeat it a second time. If you try, you'll actually pattern the entire model (box + button).

<img width="486" alt="Screenshot 2025-02-06 at 3 08 52 PM" src="https://github.com/user-attachments/assets/09fc28d9-5d80-4ab3-b4dc-b8de2945fcba" />

Why? Because right now, when you sketch on a face (like the button was), both the box and the button share the same ID. All extrusions from a solid will share the same ID, because they all refer to the same composite solid.

This is helpful in some ways -- arguably the solid _is_ just one big complex shape now -- but it's not helpful in other ways. What if I want to only pattern the button? Luckily there's an original ID for the button part, which is still stored. So we just need a way to tell the pattern stdlib functions whether to use the target's main ID or its original ID. This PR adds a new optional bool, `useOriginal`, to patterns. It's false by default, to keep backwards-compatibility (make sure that old KCL code doesn't change).

This PR is based on https://github.com/KittyCAD/modeling-app/pull/3914. It's based on work Serena and I are doing to fix a bug (engine does not allow patterning a 3D solid which was sketched on a face of another solid). @gserena01 our test program is now:

```
w = 400

case = startSketchOn('XY')
  |> startProfileAt([-w, -w], %)
  |> line(endAbsolute = [-w, w])
  |> line(endAbsolute = [w, -w])
  |> line(endAbsolute = [-w, -w])
  |> close()
  |> extrude(length = 200)

bump1 = startSketchOn(case, 'end')
  |> circle({ center = [-50, -50], radius = 40 }, %)
  |> extrude(length = 20)

// We pass in "bump1" here since we want to pattern just this object on the face.
useOriginal = true
target = bump1
transform = {
  axis = [1, 0, 0],
  instances = 3,
  distance = -100
}
patternLinear3d(transform, target, useOriginal)
```

If you change the `useOriginal = true` to `false` you can see the difference.
2025-02-06 17:46:47 -06:00
020497cde2 Don't close the command palette on backspace (#5291)
* Don't close the command palette on backspace

It leads to awkward UX like the one reported in #5007. Users can still
go back between arguments using <kbd>Backspace</kbd> on an empty
argument, but to close it they have to hit <kbd>Escape</kbd>,
<kbd>Cmd+K</kbd>, or click the close button.

* fmt
'
2025-02-06 16:28:35 -05:00
688852a5df Bump @types/mocha from 10.0.7 to 10.0.10 (#5028)
Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 10.0.7 to 10.0.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha)

---
updated-dependencies:
- dependency-name: "@types/mocha"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 15:17:14 -05:00
6c635bd70d refactor: Remove dead code to update the artifact graph after mock execution (#5158)
Remove dead code to update the artifact graph after mock execution
2025-02-06 17:56:19 +00:00
1c0a38a1e2 Update lower-right corner units menu to read and edit inline settings annotations if present (#5212)
* WIP show annotation length unit setting in LowerRightControls if present

* Add logic for changing settings annotation if it's present

* Add E2E test

* Cleanup lints, fmt, tsc, logs

* Change to use settings from Rust helper function

- Fix thrown error to use the cause field
- Fix function names to not use "get"

* Remove unneeded constants

* Post-merge fixups

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Add back `ImportStatement` to make tsc happy (thanks @jtran!)

* fmt

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-06 17:37:13 +00:00
019cb815f9 Fix resizing view breaking app on high DPI displays (#5275)
* Fix resizing view breaking app on high DPI displays

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 12:06:50 -05:00
c8653beae7 updating onboarding bracket with SSI (#5281)
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 16:15:21 +00:00
9ea3cb51ba Bump miette from 7.2.0 to 7.5.0 in /src/wasm-lib (#5224)
Bumps [miette](https://github.com/zkat/miette) from 7.2.0 to 7.5.0.
- [Release notes](https://github.com/zkat/miette/releases)
- [Changelog](https://github.com/zkat/miette/blob/main/CHANGELOG.md)
- [Commits](https://github.com/zkat/miette/commits)

---
updated-dependencies:
- dependency-name: miette
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 08:06:10 -08:00
e0de0493ab Skip prompt-to-edit playwright tests on windows (#5290)
* Skip prompt-to-edit playwright tests on windows

* Fix lint

* Fix test hookk

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Clear bad snapshots

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-06 09:45:12 -05:00
11cac0c30e Skip text-to-cad playwright tests on windows (#5286) 2025-02-06 08:48:17 -05:00
4de50edf5a Bump @types/node from 22.7.8 to 22.13.1 (#5262)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.8 to 22.13.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 10:51:07 +00:00
100 changed files with 11696 additions and 1873 deletions

File diff suppressed because one or more lines are too long

View File

@ -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) -> [Sketch]
patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?: bool) -> [Sketch]
```
@ -19,6 +19,7 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet) -> [Sketch]
|----------|------|-------------|----------|
| `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 |
### Returns

View File

@ -9,7 +9,7 @@ Repeat a 3-dimensional solid along a linear path, with a dynamic amount
of distance between each repetition, some specified number of times.
```js
patternLinear3d(data: LinearPattern3dData, solid_set: SolidSet) -> [Solid]
patternLinear3d(data: LinearPattern3dData, solid_set: SolidSet, use_original?: bool) -> [Solid]
```
@ -19,6 +19,7 @@ patternLinear3d(data: LinearPattern3dData, solid_set: SolidSet) -> [Solid]
|----------|------|-------------|----------|
| `data` | [`LinearPattern3dData`](/docs/kcl/types/LinearPattern3dData) | Data for a linear pattern on a 3D model. | Yes |
| `solid_set` | [`SolidSet`](/docs/kcl/types/SolidSet) | A solid or a group of solids. | Yes |
| `use_original` | `bool` | | No |
### Returns

View File

@ -35,7 +35,7 @@ The transform function returns a transform object. All properties of the object
- `rotation.origin` (either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local")
```js
patternTransform(total_instances: integer, transform_function: FunctionParam, solid_set: SolidSet) -> [Solid]
patternTransform(total_instances: integer, transform_function: FunctionParam, solid_set: SolidSet, use_original?: bool) -> [Solid]
```
@ -46,6 +46,7 @@ patternTransform(total_instances: integer, transform_function: FunctionParam, so
| `total_instances` | `integer` | | Yes |
| `transform_function` | `FunctionParam` | | Yes |
| `solid_set` | [`SolidSet`](/docs/kcl/types/SolidSet) | A solid or a group of solids. | Yes |
| `use_original` | `bool` | | No |
### Returns

View File

@ -9,7 +9,7 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
```js
patternTransform2d(total_instances: integer, transform_function: FunctionParam, solid_set: SketchSet) -> [Sketch]
patternTransform2d(total_instances: integer, transform_function: FunctionParam, solid_set: SketchSet, use_original?: bool) -> [Sketch]
```
@ -20,6 +20,7 @@ patternTransform2d(total_instances: integer, transform_function: FunctionParam,
| `total_instances` | `integer` | | Yes |
| `transform_function` | `FunctionParam` | | Yes |
| `solid_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `use_original` | `bool` | | No |
### Returns

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -20,5 +20,6 @@ Data for a circular pattern on a 2D sketch.
| `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No |
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
| `useOriginal` |`boolean`| If the target being patterned is itself a pattern, then, should you use the original solid, or the pattern? | No |

View File

@ -21,5 +21,6 @@ Data for a circular pattern on a 3D model.
| `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No |
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
| `useOriginal` |`boolean`| If the target being patterned is itself a pattern, then, should you use the original solid, or the pattern? | No |

View File

@ -22,6 +22,7 @@ A sketch is a collection of paths.
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |`string`| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch is a collection of paths. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -31,6 +31,7 @@ A sketch is a collection of paths.
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |`string`| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch or a group of sketches. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -1890,7 +1890,7 @@ chamfer04 = chamfer({ length = 5, tags = [getOppositeEdge(seg02)]}, extrude001
const testPoint = { x: 575, y: 200 }
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const shellDeclaration =
"shell001 = shell({ faces = ['end'], thickness = 5 }, extrude001)"
"shell001 = shell(extrude001, faces = ['end'], thickness = 5)"
await test.step(`Look for the grey of the shape`, async () => {
await scene.expectPixelColor([127, 127, 127], testPoint, 15)
@ -1990,8 +1990,7 @@ extrude001 = extrude(sketch001, length = 40)
const [clickOnWall] = scene.makeMouseHelpers(testPoint.x, testPoint.y + 70)
const mutatedCode = 'xLine(-40, %, $seg01)'
const shellDeclaration =
"shell001 = shell({ faces = ['end', seg01], thickness = 5}, extrude001)"
const formattedOutLastLine = '}, extrude001)'
"shell001 = shell(extrude001, faces = ['end', seg01], thickness = 5)"
await test.step(`Look for the grey of the shape`, async () => {
await scene.expectPixelColor([99, 99, 99], testPoint, 15)
@ -2034,7 +2033,7 @@ extrude001 = extrude(sketch001, length = 40)
await editor.expectEditor.toContain(shellDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: [formattedOutLastLine],
activeLines: [shellDeclaration],
highlightedCode: '',
})
await scene.expectPixelColor([49, 49, 49], testPoint, 15)
@ -2088,9 +2087,8 @@ extrude002 = extrude(sketch002, length = 50)
// One dumb hardcoded screen pixel value
const testPoint = { x: 550, y: 295 }
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const shellDeclaration = `shell001 = shell({ faces = ['end'], thickness = 5 }, ${
hasExtrudesInPipe ? 'sketch002' : 'extrude002'
})`
const shellTarget = hasExtrudesInPipe ? 'sketch002' : 'extrude002'
const shellDeclaration = `shell001 = shell(${shellTarget}, faces = ['end'], thickness = 5)`
await test.step(`Look for the grey of the shape`, async () => {
await toolbar.closePane('code')

View File

@ -35,106 +35,108 @@ sketch003 = startSketchOn('XY')
extrude003 = extrude(sketch003, length = 20)
`
test.describe('Check the happy path, for basic changing color', () => {
const cases = [
{
desc: 'User accepts change',
shouldReject: false,
},
{
desc: 'User rejects change',
shouldReject: true,
},
] as const
for (const { desc, shouldReject } of cases) {
test(`${desc}`, async ({
context,
homePage,
cmdBar,
editor,
page,
scene,
}) => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
test.describe('Check the happy path, for basic changing color', () => {
const cases = [
{
desc: 'User accepts change',
shouldReject: false,
},
{
desc: 'User rejects change',
shouldReject: true,
},
] as const
for (const { desc, shouldReject } of cases) {
test(`${desc}`, async ({
context,
homePage,
cmdBar,
editor,
page,
scene,
}) => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
const body1CapCoords = { x: 571, y: 351 }
const greenCheckCoords = { x: 565, y: 345 }
const body2WallCoords = { x: 609, y: 153 }
const [clickBody1Cap] = scene.makeMouseHelpers(
body1CapCoords.x,
body1CapCoords.y
)
const yellow: [number, number, number] = [179, 179, 131]
const green: [number, number, number] = [108, 152, 75]
const notGreen: [number, number, number] = [132, 132, 132]
const body2NotGreen: [number, number, number] = [88, 88, 88]
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
const successToast = page.getByText('Prompt to edit successful')
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
const rejectBtn = page.getByRole('button', { name: 'close Reject' })
const body1CapCoords = { x: 571, y: 351 }
const greenCheckCoords = { x: 565, y: 345 }
const body2WallCoords = { x: 609, y: 153 }
const [clickBody1Cap] = scene.makeMouseHelpers(
body1CapCoords.x,
body1CapCoords.y
)
const yellow: [number, number, number] = [179, 179, 131]
const green: [number, number, number] = [108, 152, 75]
const notGreen: [number, number, number] = [132, 132, 132]
const body2NotGreen: [number, number, number] = [88, 88, 88]
const submittingToast = page.getByText(
'Submitting to Text-to-CAD API...'
)
const successToast = page.getByText('Prompt to edit successful')
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
const rejectBtn = page.getByRole('button', { name: 'close Reject' })
await test.step('wait for scene to load select body and check selection came through', async () => {
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
await clickBody1Cap()
await scene.expectPixelColor(yellow, body1CapCoords, 20)
await editor.expectState({
highlightedCode: '',
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
diagnostics: [],
await test.step('wait for scene to load select body and check selection came through', async () => {
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
await clickBody1Cap()
await scene.expectPixelColor(yellow, body1CapCoords, 20)
await editor.expectState({
highlightedCode: '',
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
diagnostics: [],
})
})
})
await test.step('fire off edit prompt', async () => {
await cmdBar.openCmdBar('promptToEdit')
// being specific about the color with a hex means asserting pixel color is more stable
await page
.getByTestId('cmd-bar-arg-value')
.fill('make this neon green please, use #39FF14')
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(submittingToast).toBeVisible()
await expect(submittingToast).not.toBeVisible({ timeout: 2 * 60_000 }) // can take a while
await expect(successToast).toBeVisible()
})
await test.step('verify initial change', async () => {
await scene.expectPixelColor(green, greenCheckCoords, 15)
await scene.expectPixelColor(body2NotGreen, body2WallCoords, 15)
await editor.expectEditor.toContain('appearance({')
})
if (!shouldReject) {
await test.step('check accept works and can be "undo"ed', async () => {
await acceptBtn.click()
await expect(successToast).not.toBeVisible()
await test.step('fire off edit prompt', async () => {
await cmdBar.openCmdBar('promptToEdit')
// being specific about the color with a hex means asserting pixel color is more stable
await page
.getByTestId('cmd-bar-arg-value')
.fill('make this neon green please, use #39FF14')
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(submittingToast).toBeVisible()
await expect(submittingToast).not.toBeVisible({ timeout: 2 * 60_000 }) // can take a while
await expect(successToast).toBeVisible()
})
await test.step('verify initial change', async () => {
await scene.expectPixelColor(green, greenCheckCoords, 15)
await scene.expectPixelColor(body2NotGreen, body2WallCoords, 15)
await editor.expectEditor.toContain('appearance({')
// ctrl-z works after accepting
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up('ControlOrMeta')
await editor.expectEditor.not.toContain('appearance({')
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
})
} else {
await test.step('check reject works', async () => {
await rejectBtn.click()
await expect(successToast).not.toBeVisible()
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
await editor.expectEditor.not.toContain('appearance({')
})
}
})
}
})
if (!shouldReject) {
await test.step('check accept works and can be "undo"ed', async () => {
await acceptBtn.click()
await expect(successToast).not.toBeVisible()
await scene.expectPixelColor(green, greenCheckCoords, 15)
await editor.expectEditor.toContain('appearance({')
// ctrl-z works after accepting
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up('ControlOrMeta')
await editor.expectEditor.not.toContain('appearance({')
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
})
} else {
await test.step('check reject works', async () => {
await rejectBtn.click()
await expect(successToast).not.toBeVisible()
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
await editor.expectEditor.not.toContain('appearance({')
})
}
})
}
})
test.describe('bad path', { tag: ['@skipWin'] }, () => {
test(`bad edit prompt`, async ({
context,
homePage,

View File

@ -253,7 +253,7 @@ extrude001 = extrude(sketch001, length = 50)
|>
example = extrude(exampleSketch, length = 5)
shell({ faces: ['end'], thickness: 0.25 }, exampleSketch)`
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
)
})
@ -314,6 +314,7 @@ extrude001 = extrude(sketch001, length = 50)
)
test('when engine fails export we handle the failure and alert the user', async ({
scene,
page,
homePage,
}) => {
@ -383,10 +384,7 @@ extrude001 = extrude(sketch001, length = 50)
await page.keyboard.press('End')
await page.keyboard.press('Enter')
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await scene.waitForExecutionDone()
// Now try exporting

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -896,4 +896,53 @@ test.describe('Testing settings', () => {
})
}
)
test(`Change inline units setting`, async ({
page,
homePage,
context,
editor,
}) => {
const initialInlineUnits = 'yd'
const editedInlineUnits = { short: 'mm', long: 'Millimeters' }
const inlineSettingsString = (s: string) =>
`@settings(defaultLengthUnit = ${s})`
const unitsIndicator = page.getByRole('button', {
name: 'Current units are:',
})
const unitsChangeButton = (name: string) =>
page.getByRole('button', { name, exact: true })
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'project-000')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('cube.kcl'),
join(bracketDir, 'main.kcl')
)
})
await test.step(`Initial units from settings`, async () => {
await homePage.openProject('project-000')
await expect(unitsIndicator).toHaveText('Current units are: in')
})
await test.step(`Manually write inline settings`, async () => {
await editor.openPane()
await editor.replaceCode(
`fn cube`,
`${inlineSettingsString(initialInlineUnits)}
fn cube`
)
await expect(unitsIndicator).toContainText(initialInlineUnits)
})
await test.step(`Change units setting via lower-right control`, async () => {
await unitsIndicator.click()
await unitsChangeButton(editedInlineUnits.long).click()
await expect(
page.getByText(`Updated per-file units to ${editedInlineUnits.short}`)
).toBeVisible()
})
})
})

View File

@ -3,7 +3,7 @@ import { getUtils, createProject } from './test-utils'
import { join } from 'path'
import fs from 'fs'
test.describe('Text-to-CAD tests', () => {
test.describe('Text-to-CAD tests', { tag: ['@skipWin'] }, () => {
test('basic lego happy case', async ({ page, homePage }) => {
const u = await getUtils(page)

View File

@ -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/main/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-shell/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",
@ -158,8 +158,8 @@
"@types/electron": "^1.6.10",
"@types/isomorphic-fetch": "^0.0.39",
"@types/minimist": "^1.2.5",
"@types/mocha": "^10.0.6",
"@types/node": "^22.7.8",
"@types/mocha": "^10.0.10",
"@types/node": "^22.13.1",
"@types/pixelmatch": "^5.2.6",
"@types/pngjs": "^6.0.4",
"@types/react": "^18.3.4",

View File

@ -1 +1,212 @@
404: Not Found
[
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "80-20-rail/main.kcl",
"multipleFiles": false,
"title": "80/20 Rail",
"description": "An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "a-parametric-bearing-pillow-block/main.kcl",
"multipleFiles": false,
"title": "A Parametric Bearing Pillow Block",
"description": "A bearing pillow block, also known as a plummer block or pillow block bearing, is a pedestal used to provide support for a rotating shaft with the help of compatible bearings and various accessories. Housing a bearing, the pillow block provides a secure and stable foundation that allows the shaft to rotate smoothly within its machinery setup. These components are essential in a wide range of mechanical systems and machinery, playing a key role in reducing friction and supporting radial and axial loads."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "ball-bearing/main.kcl",
"multipleFiles": false,
"title": "Ball Bearing",
"description": "A ball bearing is a type of rolling-element bearing that uses balls to maintain the separation between the bearing races. The primary purpose of a ball bearing is to reduce rotational friction and support radial and axial loads."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "bracket/main.kcl",
"multipleFiles": false,
"title": "Shelf Bracket",
"description": "This is a bracket that holds a shelf. It is made of aluminum and is designed to hold a force of 300 lbs. The bracket is 6 inches wide and the force is applied at the end of the shelf, 12 inches from the wall. The bracket has a factor of safety of 1.2. The legs of the bracket are 5 inches and 2 inches long. The thickness of the bracket is calculated from the constraints provided."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "car-wheel-assembly/main.kcl",
"multipleFiles": true,
"title": "Car Wheel Assembly",
"description": "A car wheel assembly with a rotor, tire, and lug nuts."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "dodecahedron/main.kcl",
"multipleFiles": false,
"title": "Hollow Dodecahedron",
"description": "A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the individual faces of the dodecahedron and extruding inwards."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "enclosure/main.kcl",
"multipleFiles": false,
"title": "Enclosure",
"description": "An enclosure body and sealing lid for storing items"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "flange-with-patterns/main.kcl",
"multipleFiles": false,
"title": "Flange",
"description": "A flange is a flat rim, collar, or rib, typically forged or cast, that is used to strengthen an object, guide it, or attach it to another object. Flanges are known for their use in various applications, including piping, plumbing, and mechanical engineering, among others."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "flange-xy/main.kcl",
"multipleFiles": false,
"title": "Flange with XY coordinates",
"description": "A flange is a flat rim, collar, or rib, typically forged or cast, that is used to strengthen an object, guide it, or attach it to another object. Flanges are known for their use in various applications, including piping, plumbing, and mechanical engineering, among others."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "focusrite-scarlett-mounting-bracket/main.kcl",
"multipleFiles": false,
"title": "A mounting bracket for the Focusrite Scarlett Solo audio interface",
"description": "This is a bracket that holds an audio device underneath a desk or shelf. The audio device has dimensions of 144mm wide, 80mm length and 45mm depth with fillets of 6mm. This mounting bracket is designed to be 3D printed with PLA material"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "food-service-spatula/main.kcl",
"multipleFiles": false,
"title": "Food Service Spatula",
"description": "Use these spatulas for mixing, flipping, and scraping."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "french-press/main.kcl",
"multipleFiles": false,
"title": "French Press",
"description": "A french press immersion coffee maker"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "gear/main.kcl",
"multipleFiles": false,
"title": "Spur Gear",
"description": "A rotating machine part having cut teeth or, in the case of a cogwheel, inserted teeth (called cogs), which mesh with another toothed part to transmit torque. Geared devices can change the speed, torque, and direction of a power source. The two elements that define a gear are its circular shape and the teeth that are integrated into its outer edge, which are designed to fit into the teeth of another gear."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "gear-rack/main.kcl",
"multipleFiles": false,
"title": "100mm Gear Rack",
"description": "A flat bar or rail that is engraved with teeth along its length. These teeth are designed to mesh with the teeth of a gear, known as a pinion. When the pinion, a small cylindrical gear, rotates, its teeth engage with the teeth on the rack, causing the rack to move linearly. Conversely, linear motion applied to the rack will cause the pinion to rotate."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "hex-nut/main.kcl",
"multipleFiles": false,
"title": "Hex nut",
"description": "A hex nut is a type of fastener with a threaded hole and a hexagonal outer shape, used in a wide variety of applications to secure parts together. The hexagonal shape allows for a greater torque to be applied with wrenches or tools, making it one of the most common nut types in hardware."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "i-beam/main.kcl",
"multipleFiles": false,
"title": "I-beam",
"description": "A structural metal beam with an I shaped cross section. Often used in construction"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "kitt/main.kcl",
"multipleFiles": false,
"title": "Kitt",
"description": "The beloved KittyCAD mascot in a voxelized style."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "lego/main.kcl",
"multipleFiles": false,
"title": "Lego Brick",
"description": "A standard Lego brick. This is a small, plastic construction block toy that can be interlocked with other blocks to build various structures, models, and figures. There are a lot of hacks used in this code."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "mounting-plate/main.kcl",
"multipleFiles": false,
"title": "Mounting Plate",
"description": "A flat piece of material, often metal or plastic, that serves as a support or base for attaching, securing, or mounting various types of equipment, devices, or components."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "multi-axis-robot/main.kcl",
"multipleFiles": true,
"title": "Robot Arm",
"description": "A 4 axis robotic arm for industrial use. These machines can be used for assembly, packaging, organization of goods, and quality inspection processes"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "pipe/main.kcl",
"multipleFiles": false,
"title": "Pipe",
"description": "A tubular section or hollow cylinder, usually but not necessarily of circular cross-section, used mainly to convey substances that can flow."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "pipe-flange-assembly/main.kcl",
"multipleFiles": false,
"title": "Pipe and Flange Assembly",
"description": "A crucial component in various piping systems, designed to facilitate the connection, disconnection, and access to piping for inspection, cleaning, and modifications. This assembly combines pipes (long cylindrical conduits) with flanges (plate-like fittings) to create a secure yet detachable joint."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "pipe-with-bend/main.kcl",
"multipleFiles": false,
"title": "Pipe with bend",
"description": "A tubular section or hollow cylinder, usually but not necessarily of circular cross-section, used mainly to convey substances that can flow."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "poopy-shoe/main.kcl",
"multipleFiles": false,
"title": "Poopy Shoe",
"description": "poop shute for bambu labs printer - optimized for printing."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "router-template-cross-bar/main.kcl",
"multipleFiles": false,
"title": "Router template for a cross bar",
"description": "A guide for routing a notch into a cross bar."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "router-template-slate/main.kcl",
"multipleFiles": false,
"title": "Router template for a slate",
"description": "A guide for routing a slate for a cross bar."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "sheet-metal-bracket/main.kcl",
"multipleFiles": false,
"title": "Sheet Metal Bracket",
"description": "A component typically made from flat sheet metal through various manufacturing processes such as bending, punching, cutting, and forming. These brackets are used to support, attach, or mount other hardware components, often providing a structural or functional base for assembly."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "socket-head-cap-screw/main.kcl",
"multipleFiles": false,
"title": "Socket Head Cap Screw",
"description": "This is for a #10-24 screw that is 1.00 inches long. A socket head cap screw is a type of fastener that is widely used in a variety of applications requiring a high strength fastening solution. It is characterized by its cylindrical head and internal hexagonal drive, which allows for tightening with an Allen wrench or hex key."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "walkie-talkie/main.kcl",
"multipleFiles": true,
"title": "Walkie Talkie",
"description": "A portable, handheld two-way radio device that allows users to communicate wirelessly over short to medium distances. It operates on specific radio frequencies and features a push-to-talk button for transmitting messages, making it ideal for quick and reliable communication in outdoor, work, or emergency settings."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "washer/main.kcl",
"multipleFiles": false,
"title": "Washer",
"description": "A small, typically disk-shaped component with a hole in the middle, used in a wide range of applications, primarily in conjunction with fasteners like bolts and screws. Washers distribute the load of a fastener across a broader area. This is especially important when the fastening surface is soft or uneven, as it helps to prevent damage to the surface and ensures the load is evenly distributed, reducing the risk of the fastener becoming loose over time."
}
]

View File

@ -57,7 +57,7 @@ function CommandComboBox({
onKeyDown={(event) => {
if (
(event.metaKey && event.key === 'k') ||
(event.key === 'Backspace' && !event.currentTarget.value)
event.key === 'Escape'
) {
event.preventDefault()
commandBarActor.send({ type: 'Close' })

View File

@ -1,9 +1,31 @@
import { Popover } from '@headlessui/react'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { changeKclSettings, unitLengthToUnitLen } from 'lang/wasm'
import { baseUnitLabels, baseUnitsUnion } from 'lib/settings/settingsTypes'
import { codeManager, kclManager } from 'lib/singletons'
import { err, reportRejection } from 'lib/trap'
import { useEffect, useState } from 'react'
import toast from 'react-hot-toast'
export function UnitsMenu() {
const { settings } = useSettingsAuthContext()
const [hasPerFileLengthUnit, setHasPerFileLengthUnit] = useState(
Boolean(kclManager.fileSettings.defaultLengthUnit)
)
const [lengthSetting, setLengthSetting] = useState(
kclManager.fileSettings.defaultLengthUnit ||
settings.context.modeling.defaultUnit.current
)
useEffect(() => {
setHasPerFileLengthUnit(Boolean(kclManager.fileSettings.defaultLengthUnit))
setLengthSetting(
kclManager.fileSettings.defaultLengthUnit ||
settings.context.modeling.defaultUnit.current
)
}, [
kclManager.fileSettings.defaultLengthUnit,
settings.context.modeling.defaultUnit.current,
])
return (
<Popover className="relative pointer-events-auto">
{({ close }) => (
@ -18,7 +40,7 @@ export function UnitsMenu() {
<div className="absolute w-[1px] h-[1em] bg-primary right-0 top-1/2 -translate-y-1/2"></div>
</div>
<span className="sr-only">Current units are:&nbsp;</span>
{settings.context.modeling.defaultUnit.current}
{lengthSetting}
</Popover.Button>
<Popover.Panel
className={`absolute bottom-full right-0 mb-2 w-48 bg-chalkboard-10 dark:bg-chalkboard-90
@ -31,18 +53,40 @@ export function UnitsMenu() {
<button
className="flex items-center gap-2 m-0 py-1.5 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left"
onClick={() => {
settings.send({
type: 'set.modeling.defaultUnit',
data: {
level: 'project',
value: unit,
},
})
if (hasPerFileLengthUnit) {
const newCode = changeKclSettings(codeManager.code, {
defaultLengthUnits: unitLengthToUnitLen(unit),
defaultAngleUnits: { type: 'Degrees' },
})
if (err(newCode)) {
toast.error(
`Failed to set per-file units: ${newCode.message}`
)
} else {
codeManager.updateCodeStateEditor(newCode)
Promise.all([
codeManager.writeToFile(),
kclManager.executeCode(),
])
.then(() => {
toast.success(`Updated per-file units to ${unit}`)
})
.catch(reportRejection)
}
} else {
settings.send({
type: 'set.modeling.defaultUnit',
data: {
level: 'project',
value: unit,
},
})
}
close()
}}
>
<span className="flex-1">{baseUnitLabels[unit]}</span>
{unit === settings.context.modeling.defaultUnit.current && (
{unit === lengthSetting && (
<span className="text-chalkboard-60">current</span>
)}
</button>

View File

@ -25,7 +25,7 @@ import {
SourceRange,
topLevelRange,
} from 'lang/wasm'
import { getNodeFromPath } from './queryAst'
import { getNodeFromPath, getSettingsAnnotation } from './queryAst'
import { codeManager, editorManager, sceneInfra } from 'lib/singletons'
import { Diagnostic } from '@codemirror/lint'
import { markOnce } from 'lib/performance'
@ -35,6 +35,7 @@ import {
ModelingCmdReq_type,
} from '@kittycad/lib/dist/types/src/models'
import { Operation } from 'wasm-lib/kcl/bindings/Operation'
import { KclSettingsAnnotation } from 'lib/settings/settingsTypes'
interface ExecuteArgs {
ast?: Node<Program>
@ -70,6 +71,7 @@ export class KclManager {
private _wasmInitFailed = true
private _hasErrors = false
private _switchedFiles = false
private _fileSettings: KclSettingsAnnotation = {}
engineCommandManager: EngineCommandManager
@ -368,6 +370,13 @@ export class KclManager {
await this.disableSketchMode()
}
let fileSettings = getSettingsAnnotation(ast)
if (err(fileSettings)) {
console.error(fileSettings)
fileSettings = {}
}
this.fileSettings = fileSettings
this.logs = logs
this.errors = errors
// Do not add the errors since the program was interrupted and the error is not a real KCL error
@ -413,14 +422,7 @@ export class KclManager {
// NOTE: this always updates the code state and editor.
// DO NOT CALL THIS from codemirror ever.
async executeAstMock(
ast: Program = this._ast,
{
updates,
}: {
updates: 'none' | 'artifactRanges'
} = { updates: 'none' }
) {
async executeAstMock(ast: Program = this._ast) {
await this.ensureWasmInit()
const newCode = recast(ast)
@ -450,34 +452,6 @@ export class KclManager {
this.lastSuccessfulProgramMemory = execState.memory
this.lastSuccessfulOperations = execState.operations
}
if (updates !== 'artifactRanges') return
// TODO the below seems like a work around, I wish there's a comment explaining exactly what
// problem this solves, but either way we should strive to remove it.
Array.from(this.engineCommandManager.artifactGraph).forEach(
([commandId, artifact]) => {
if (!('codeRef' in artifact && artifact.codeRef)) return
const _node1 = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
this.ast,
artifact.codeRef.pathToNode,
['CallExpression', 'CallExpressionKw']
)
if (err(_node1)) return
const { node } = _node1
if (node.type !== 'CallExpression' && node.type !== 'CallExpressionKw')
return
const [oldStart, oldEnd] = artifact.codeRef.range
if (oldStart === 0 && oldEnd === 0) return
if (oldStart === node.start && oldEnd === node.end) return
this.engineCommandManager.artifactGraph.set(commandId, {
...artifact,
codeRef: {
...artifact.codeRef,
range: topLevelRange(node.start, node.end),
},
})
}
)
}
cancelAllExecutions() {
this._cancelTokens.forEach((_, key) => {
@ -699,6 +673,14 @@ export class KclManager {
_isAstEmpty(ast: Node<Program>) {
return ast.start === 0 && ast.end === 0 && ast.body.length === 0
}
get fileSettings() {
return this._fileSettings
}
set fileSettings(settings: KclSettingsAnnotation) {
this._fileSettings = settings
}
}
const defaultSelectionFilter: EntityType_type[] = [

View File

@ -55,6 +55,7 @@ const mySketch001 = startSketchOn('XY')
],
id: expect.any(String),
artifactId: expect.any(String),
originalId: expect.any(String),
units: {
type: 'Mm',
},
@ -98,6 +99,7 @@ const mySketch001 = startSketchOn('XY')
],
sketch: {
id: expect.any(String),
originalId: expect.any(String),
artifactId: expect.any(String),
units: {
type: 'Mm',
@ -203,6 +205,7 @@ const sk2 = startSketchOn('XY')
],
sketch: {
id: expect.any(String),
originalId: expect.any(String),
artifactId: expect.any(String),
__meta: expect.any(Array),
on: expect.any(Object),
@ -308,6 +311,7 @@ const sk2 = startSketchOn('XY')
],
sketch: {
id: expect.any(String),
originalId: expect.any(String),
artifactId: expect.any(String),
units: {
type: 'Mm',

View File

@ -221,6 +221,7 @@ const newVar = myVar + 1`
},
],
id: expect.any(String),
originalId: expect.any(String),
artifactId: expect.any(String),
units: {
type: 'Mm',

View File

@ -28,7 +28,14 @@ try {
console.log(e)
}
child_process.spawnSync('git', ['clone', URL_GIT_KCL_SAMPLES, DIR_KCL_SAMPLES])
child_process.spawnSync('git', [
'clone',
'--single-branch',
'--branch',
'achalmers/kw-shell',
URL_GIT_KCL_SAMPLES,
DIR_KCL_SAMPLES,
])
// @ts-expect-error
let files = await fs.readdir(DIR_KCL_SAMPLES)

View File

@ -17,6 +17,8 @@ import {
createObjectExpression,
createArrayExpression,
createVariableDeclaration,
createCallExpressionStdLibKw,
createLabeledArg,
} from 'lang/modifyAst'
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
import { KclManager } from 'lang/KclSingleton'
@ -121,13 +123,14 @@ export function addShell({
}
const name = findUniqueName(node, KCL_DEFAULT_CONSTANT_PREFIXES.SHELL)
const shell = createCallExpressionStdLib('shell', [
createObjectExpression({
faces: createArrayExpression(expressions),
thickness,
}),
const shell = createCallExpressionStdLibKw(
'shell',
createIdentifier(extrudeNode.node.id.name),
])
[
createLabeledArg('faces', createArrayExpression(expressions)),
createLabeledArg('thickness', thickness),
]
)
const declaration = createVariableDeclaration(name, shell)
// TODO: check if we should append at the end like here or right after the extrude
@ -137,8 +140,7 @@ export function addShell({
[modifiedAst.body.length - 1, 'index'],
['declaration', 'VariableDeclaration'],
['init', 'VariableDeclarator'],
['arguments', 'CallExpression'],
[0, 'index'],
['unlabeled', 'CallExpressionKw'],
]
return {
modifiedAst,

View File

@ -23,6 +23,9 @@ import {
VariableDeclaration,
VariableDeclarator,
recast,
kclSettings,
unitLenToUnitLength,
unitAngToUnitAngle,
} from './wasm'
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
@ -38,6 +41,7 @@ import { ImportStatement } from 'wasm-lib/kcl/bindings/ImportStatement'
import { Node } from 'wasm-lib/kcl/bindings/Node'
import { findKwArg } from './util'
import { codeRefFromRange } from './std/artifactGraph'
import { KclSettingsAnnotation } from 'lib/settings/settingsTypes'
export const LABELED_ARG_FIELD = 'LabeledArg -> Arg'
export const ARG_INDEX_FIELD = 'arg index'
@ -866,3 +870,24 @@ export function getObjExprProperty(
if (index === -1) return null
return { expr: node.properties[index].value, index }
}
/**
* Given KCL, returns the settings annotation object if it exists.
*/
export function getSettingsAnnotation(
kcl: string | Node<Program>
): KclSettingsAnnotation | Error {
const metaSettings = kclSettings(kcl)
if (err(metaSettings)) return metaSettings
const settings: KclSettingsAnnotation = {}
// No settings in the KCL.
if (!metaSettings) return settings
settings.defaultLengthUnit = unitLenToUnitLength(
metaSettings.defaultLengthUnits
)
settings.defaultAngleUnit = unitAngToUnitAngle(metaSettings.defaultAngleUnits)
return settings
}

View File

@ -1406,6 +1406,8 @@ export class EngineCommandManager extends EventTarget {
commandId: string
}
settings: SettingsViaQueryString
width: number = 1337
height: number = 1337
/**
* Export intent traxcks the intent of the export. If it is null there is no
@ -1511,6 +1513,9 @@ export class EngineCommandManager extends EventTarget {
return
}
this.width = width
this.height = height
// If we already have an engine connection, just need to resize the stream.
if (this.engineConnection) {
this.handleResize({
@ -1823,6 +1828,9 @@ export class EngineCommandManager extends EventTarget {
return
}
this.width = streamWidth
this.height = streamHeight
const resizeCmd: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),

View File

@ -18,6 +18,7 @@ import {
default_project_settings,
base64_decode,
clear_scene_and_bust_cache,
kcl_settings,
change_kcl_settings,
reloadModule,
} from 'lib/wasm_lib_wrapper'
@ -58,6 +59,9 @@ import { Artifact } from './std/artifactGraph'
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
import { NumericSuffix } from 'wasm-lib/kcl/bindings/NumericSuffix'
import { MetaSettings } from 'wasm-lib/kcl/bindings/MetaSettings'
import { UnitAngle, UnitLength } from 'wasm-lib/kcl/bindings/ModelingCmd'
import { UnitLen } from 'wasm-lib/kcl/bindings/UnitLen'
import { UnitAngle as UnitAng } from 'wasm-lib/kcl/bindings/UnitAngle'
export type { Artifact } from 'wasm-lib/kcl/bindings/Artifact'
export type { ArtifactCommand } from 'wasm-lib/kcl/bindings/Artifact'
@ -857,8 +861,35 @@ export function base64Decode(base64: string): ArrayBuffer | Error {
}
}
/// Change the meta settings for the kcl file.
/// Returns the new kcl string with the updated settings.
/**
* Get the meta settings for the KCL. If no settings were set in the file,
* returns null.
*/
export function kclSettings(
kcl: string | Node<Program>
): MetaSettings | null | Error {
let program: Node<Program>
if (typeof kcl === 'string') {
const parseResult = parse(kcl)
if (err(parseResult)) return parseResult
if (!resultIsOk(parseResult)) {
return new Error(`parse result had errors`, { cause: parseResult })
}
program = parseResult.program
} else {
program = kcl
}
try {
return kcl_settings(JSON.stringify(program))
} catch (e) {
return new Error('Caught error getting kcl settings', { cause: e })
}
}
/**
* Change the meta settings for the kcl file.
* @returns the new kcl string with the updated settings.
*/
export function changeKclSettings(
kcl: string,
settings: MetaSettings
@ -866,7 +897,59 @@ export function changeKclSettings(
try {
return change_kcl_settings(kcl, JSON.stringify(settings))
} catch (e) {
console.error('Caught error changing kcl settings: ' + e)
return new Error('Caught error changing kcl settings: ' + e)
console.error('Caught error changing kcl settings', e)
return new Error('Caught error changing kcl settings', { cause: e })
}
}
/**
* Convert a `UnitLength_type` to a `UnitLen`
*/
export function unitLengthToUnitLen(input: UnitLength): UnitLen {
switch (input) {
case 'm':
return { type: 'M' }
case 'cm':
return { type: 'Cm' }
case 'yd':
return { type: 'Yards' }
case 'ft':
return { type: 'Feet' }
case 'in':
return { type: 'Inches' }
default:
return { type: 'Mm' }
}
}
/**
* Convert `UnitLen` to `UnitLength_type`.
*/
export function unitLenToUnitLength(input: UnitLen): UnitLength {
switch (input.type) {
case 'M':
return 'm'
case 'Cm':
return 'cm'
case 'Yards':
return 'yd'
case 'Feet':
return 'ft'
case 'Inches':
return 'in'
default:
return 'mm'
}
}
/**
* Convert `UnitAngle` to `UnitAngle_type`.
*/
export function unitAngToUnitAngle(input: UnitAng): UnitAngle {
switch (input.type) {
case 'Radians':
return 'radians'
default:
return 'degrees'
}
}

View File

@ -12,104 +12,68 @@ wallMountL = 2 // inches
shelfDepth = 12 // Shelf is 12 inches in depth from the wall
moment = shelfDepth * p // assume the force is applied at the end of the shelf to be conservative (lb-in)
filletRadius = .375 // inches
extFilletRadius = .25 // inches
mountingHoleDiameter = 0.5 // inches
// Calculate required thickness of bracket
thickness = sqrt(moment * factorOfSafety * 6 / (sigmaAllow * width)) // this is the calculation of two brackets holding up the shelf (inches)
filletRadius = .25
extFilletRadius = filletRadius + thickness
mountingHoleDiameter = 0.5
// Sketch the bracket body and fillet the inner and outer edges of the bend
bracketLeg1Sketch = startSketchOn('XY')
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(end = [shelfMountL - filletRadius, 0], tag = $fillet1)
|> line(end = [0, width], tag = $fillet2)
|> line(end = [-shelfMountL + filletRadius, 0])
|> xLine(shelfMountL - thickness, %, $seg01)
|> yLine(thickness, %, $seg02)
|> xLine(-shelfMountL, %, $seg03)
|> yLine(-wallMountL, %, $seg04)
|> xLine(thickness, %, $seg05)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg06)
|> close()
|> hole(circle({
center = [1, 1],
radius = mountingHoleDiameter / 2
}, %), %)
|> hole(circle({
center = [shelfMountL - 1.5, width - 1],
radius = mountingHoleDiameter / 2
}, %), %)
|> hole(circle({
center = [1, width - 1],
radius = mountingHoleDiameter / 2
}, %), %)
|> hole(circle({
center = [shelfMountL - 1.5, 1],
radius = mountingHoleDiameter / 2
}, %), %)
// Extrude the leg 2 bracket sketch
bracketLeg1Extrude = extrude(bracketLeg1Sketch, length = thickness)
|> extrude(%, length = width)
|> fillet({
radius = extFilletRadius,
tags = [
getNextAdjacentEdge(fillet1),
getNextAdjacentEdge(fillet2)
]
tags = [getNextAdjacentEdge(seg03)]
}, %)
// Sketch the fillet arc
filletSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(end = [0, thickness])
|> arc({
angleEnd = 180,
angleStart = 90,
radius = filletRadius + thickness
}, %)
|> line(end = [thickness, 0])
|> arc({
angleEnd = 90,
angleStart = 180,
radius = filletRadius
}, %)
// Sketch the bend
filletExtrude = extrude(filletSketch, length = -width)
// Create a custom plane for the leg that sits on the wall
customPlane = {
plane = {
origin = { x = -filletRadius, y = 0, z = 0 },
xAxis = { x = 0, y = 1, z = 0 },
yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 1, y = 0, z = 0 }
}
}
// Create a sketch for the second leg
bracketLeg2Sketch = startSketchOn(customPlane)
|> startProfileAt([0, -filletRadius], %)
|> line(end = [width, 0])
|> line(end = [0, -wallMountL], tag = $fillet3)
|> line(end = [-width, 0], tag = $fillet4)
|> close()
|> hole(circle({
center = [1, -1.5],
radius = mountingHoleDiameter / 2
}, %), %)
|> hole(circle({
center = [5, -1.5],
radius = mountingHoleDiameter / 2
}, %), %)
// Extrude the second leg
bracketLeg2Extrude = extrude(bracketLeg2Sketch, length = -thickness)
|> fillet({
radius = extFilletRadius,
tags = [
getNextAdjacentEdge(fillet3),
getNextAdjacentEdge(fillet4)
]
radius = filletRadius,
tags = [getNextAdjacentEdge(seg06)]
}, %)
|> fillet({
radius = filletRadius,
tags = [seg02, getOppositeEdge(seg02)],
}, %)
|> fillet({
radius = filletRadius,
tags = [seg05, getOppositeEdge(seg05)],
}, %)
sketch002 = startSketchOn(sketch001, seg03)
|> circle({
center = [-1.25, 1],
radius = mountingHoleDiameter / 2,
}, %)
|> patternLinear2d({
instances = 2,
distance = 2.5,
axis = [-1, 0],
}, %)
|> patternLinear2d({
instances = 2,
distance = 4,
axis = [0, 1],
}, %)
|> extrude(%, length = -thickness-.01)
sketch003 = startSketchOn(sketch001, seg04)
|> circle({
center = [1, -1],
radius = mountingHoleDiameter / 2,
}, %)
|> patternLinear2d({
instances = 2,
distance = 4,
axis = [1, 0],
}, %)
|> extrude(%, length = -thickness-0.1)
`
/**

View File

@ -819,8 +819,8 @@ export async function sendSelectEventToEngine(
clientX: e.clientX,
clientY: e.clientY,
el,
streamWidth: el.clientWidth,
streamHeight: el.clientHeight,
streamWidth: engineCommandManager.width,
streamHeight: engineCommandManager.height,
})
const res = await engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',

View File

@ -4,6 +4,10 @@ import { AtLeast, PathValue, Paths } from 'lib/types'
import { CommandArgumentConfig } from 'lib/commandTypes'
import { Themes } from 'lib/theme'
import { CameraProjectionType } from 'wasm-lib/kcl/bindings/CameraProjectionType'
import {
UnitAngle_type,
UnitLength_type,
} from '@kittycad/lib/dist/types/src/models'
import { CameraOrbitType } from 'wasm-lib/kcl/bindings/CameraOrbitType'
export interface SettingsViaQueryString {
@ -138,3 +142,12 @@ type RecursiveSettingsPayloads<T> = {
}
export type SaveSettingsPayload = RecursiveSettingsPayloads<typeof settings>
/**
* Annotation names for default units are defined on rust side in
* src/wasm-lib/kcl/src/execution/annotations.rs
*/
export interface KclSettingsAnnotation {
defaultLengthUnit?: UnitLength_type
defaultAngleUnit?: UnitAngle_type
}

View File

@ -26,6 +26,7 @@ import {
default_project_settings as DefaultProjectSettings,
base64_decode as Base64Decode,
clear_scene_and_bust_cache as ClearSceneAndBustCache,
kcl_settings as KclSettings,
change_kcl_settings as ChangeKclSettings,
} from '../wasm-lib/pkg/wasm_lib'
@ -111,6 +112,9 @@ export const clear_scene_and_bust_cache: typeof ClearSceneAndBustCache = (
) => {
return getModule().clear_scene_and_bust_cache(...args)
}
export const kcl_settings: typeof KclSettings = (...args) => {
return getModule().kcl_settings(...args)
}
export const change_kcl_settings: typeof ChangeKclSettings = (...args) => {
return getModule().change_kcl_settings(...args)
}

View File

@ -2014,9 +2014,9 @@ dependencies = [
[[package]]
name = "miette"
version = "7.4.0"
version = "7.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "317f146e2eb7021892722af37cf1b971f0a70c8406f487e24952667616192c64"
checksum = "1a955165f87b37fd1862df2a59547ac542c77ef6d17c666f619d1ad22dd89484"
dependencies = [
"backtrace",
"backtrace-ext",
@ -2034,9 +2034,9 @@ dependencies = [
[[package]]
name = "miette-derive"
version = "7.4.0"
version = "7.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67"
checksum = "bf45bf44ab49be92fd1227a3be6fc6f617f1a337c06af54981048574d8783147"
dependencies = [
"proc-macro2",
"quote",

View File

@ -37,7 +37,7 @@ kittycad = { workspace = true }
kittycad-modeling-cmds = { workspace = true }
lazy_static = "1.5.0"
measurements = "0.11.0"
miette = "7.2.0"
miette = "7.5.0"
mime_guess = "2.0.5"
parse-display = "0.9.1"
pyo3 = { version = "0.22.6", optional = true }
@ -116,7 +116,7 @@ expectorate = "1.1.0"
handlebars = "6.3.0"
image = { version = "0.25.5", default-features = false, features = ["png"] }
insta = { version = "1.41.1", features = ["json", "filters", "redactions"] }
miette = { version = "7.2.0", features = ["fancy"] }
miette = { version = "7.5.0", features = ["fancy"] }
pretty_assertions = "1.4.1"
tokio = { version = "1.41.1", features = ["rt-multi-thread", "macros", "time"] }
twenty-twenty = "0.8.0"

View File

@ -242,7 +242,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program, ctx, _) = parse_execute(new).await.unwrap();
@ -273,7 +273,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch) "#;
shell(firstSketch, faces = ['end'], thickness = 0.25) "#;
let new = r#"// Remove the end face for the extrusion.
firstSketch = startSketchOn('XY')
@ -285,7 +285,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program_old, ctx, _) = parse_execute(old).await.unwrap();
@ -318,7 +318,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch) "#;
shell(firstSketch, faces = ['end'], thickness = 0.25) "#;
let new = r#"// Remove the end face for the extrusion.
firstSketch = startSketchOn('XY')
@ -330,7 +330,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program, ctx, _) = parse_execute(old).await.unwrap();
@ -363,7 +363,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch) "#;
shell(firstSketch, faces = ['end'], thickness = 0.25) "#;
let new = r#"// Remove the end face for the extrusion.
firstSketch = startSketchOn('XY')
@ -375,7 +375,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program, ctx, _) = parse_execute(old).await.unwrap();
@ -409,7 +409,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program, mut ctx, _) = parse_execute(new).await.unwrap();
@ -451,7 +451,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program, mut ctx, _) = parse_execute(new).await.unwrap();
@ -486,7 +486,7 @@ firstSketch = startSketchOn('XY')
|> extrude(length = 6)
// Remove the end face for the extrusion.
shell({ faces = ['end'], thickness = 0.25 }, firstSketch)"#;
shell(firstSketch, faces = ['end'], thickness = 0.25)"#;
let (program, mut ctx, _) = parse_execute(new).await.unwrap();

View File

@ -32,6 +32,16 @@ impl Geometry {
Geometry::Solid(e) => e.id,
}
}
/// If this geometry is the result of a pattern, then return the ID of
/// the original sketch which was patterned.
/// Equivalent to the `id()` method if this isn't a pattern.
pub fn original_id(&self) -> uuid::Uuid {
match self {
Geometry::Sketch(s) => s.original_id,
Geometry::Solid(e) => e.sketch.original_id,
}
}
}
/// A set of geometry.
@ -419,6 +429,8 @@ pub struct Sketch {
/// The original id of the sketch. This stays the same even if the sketch is
/// is sketched on face etc.
pub artifact_id: ArtifactId,
#[ts(skip)]
pub original_id: uuid::Uuid,
pub units: UnitLen,
/// Metadata.
#[serde(rename = "__meta")]

View File

@ -1590,10 +1590,10 @@ let w = f() + f()
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> extrude(length = 40.14)
|> shell({
faces: [seg01],
thickness: 3.14,
}, %)
|> shell(
thickness = 3.14,
faces = [seg01]
)
"#;
let ctx = crate::test_server::new_context(UnitLength::Mm, true, None)
@ -1620,10 +1620,10 @@ let w = f() + f()
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> extrude(length = 40.14)
|> shell({
faces: [seg01],
thickness: 3.14,
}, %)
|> shell(
faces = [seg01],
thickness = 3.14,
)
"#;
// Execute a slightly different program again.

View File

@ -159,8 +159,8 @@ impl Program {
}
/// Get the meta settings for the kcl file from the annotations.
pub fn get_meta_settings(&self) -> Result<Option<crate::MetaSettings>, KclError> {
self.ast.get_meta_settings()
pub fn meta_settings(&self) -> Result<Option<crate::MetaSettings>, KclError> {
self.ast.meta_settings()
}
/// Change the meta settings for the kcl file.

View File

@ -269,7 +269,7 @@ impl Node<Program> {
}
/// Get the annotations for the meta settings from the kcl file.
pub fn get_meta_settings(&self) -> Result<Option<crate::execution::MetaSettings>, KclError> {
pub fn meta_settings(&self) -> Result<Option<crate::execution::MetaSettings>, KclError> {
for annotation_node in self.annotations() {
let annotation = &annotation_node.value;
if annotation.annotation_name() == Some(annotations::SETTINGS) {
@ -3881,7 +3881,7 @@ const cylinder = startSketchOn('-XZ')
startSketchOn('XY')"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let result = program.get_meta_settings().unwrap();
let result = program.meta_settings().unwrap();
assert!(result.is_some());
let meta_settings = result.unwrap();
@ -3897,7 +3897,7 @@ startSketchOn('XY')"#;
startSketchOn('XY')"#;
let mut program = crate::parsing::top_level_parse(some_program_string).unwrap();
let result = program.get_meta_settings().unwrap();
let result = program.meta_settings().unwrap();
assert!(result.is_some());
let meta_settings = result.unwrap();
@ -3914,7 +3914,7 @@ startSketchOn('XY')"#;
})
.unwrap();
let result = new_program.get_meta_settings().unwrap();
let result = new_program.meta_settings().unwrap();
assert!(result.is_some());
let meta_settings = result.unwrap();
@ -3939,7 +3939,7 @@ startSketchOn('XY')
async fn test_parse_get_meta_settings_nothing_to_mm() {
let some_program_string = r#"startSketchOn('XY')"#;
let mut program = crate::parsing::top_level_parse(some_program_string).unwrap();
let result = program.get_meta_settings().unwrap();
let result = program.meta_settings().unwrap();
assert!(result.is_none());
// Edit the ast.
@ -3950,7 +3950,7 @@ startSketchOn('XY')
})
.unwrap();
let result = new_program.get_meta_settings().unwrap();
let result = new_program.meta_settings().unwrap();
assert!(result.is_some());
let meta_settings = result.unwrap();

View File

@ -120,10 +120,11 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// |> close()
/// |> extrude(length = 6)
///
/// shell({
/// shell(
/// firstSketch,
/// faces = ['end'],
/// thickness = 0.25,
/// }, firstSketch)
/// )
/// |> appearance({
/// color = '#ff0000',
/// metalness = 90,
@ -147,10 +148,11 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// roughness = 90
/// }, %)
///
/// shell({
/// shell(
/// firstSketch,
/// faces = ['end'],
/// thickness = 0.25,
/// }, firstSketch)
/// )
/// ```
///
/// ```no_run

View File

@ -356,7 +356,7 @@ impl Args {
Ok(numbers)
}
pub(crate) fn get_pattern_transform_args(&self) -> Result<(u32, FnAsArg<'_>, SolidSet), KclError> {
pub(crate) fn get_pattern_transform_args(&self) -> Result<(u32, FnAsArg<'_>, SolidSet, Option<bool>), KclError> {
FromArgs::from_args(self, 0)
}
@ -764,6 +764,10 @@ macro_rules! let_field_of {
($obj:ident, $field:ident?) => {
let $field = $obj.get(stringify!($field)).and_then(FromKclValue::from_kcl_val);
};
// Optional field but with a different string used as the key
($obj:ident, $field:ident? $key:literal) => {
let $field = $obj.get($key).and_then(FromKclValue::from_kcl_val);
};
// Mandatory field, but with a different string used as the key.
($obj:ident, $field:ident $key:literal) => {
let $field = $obj.get($key).and_then(FromKclValue::from_kcl_val)?;
@ -947,12 +951,14 @@ impl<'a> FromKclValue<'a> for super::patterns::CircularPattern3dData {
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,
})
}
}
@ -964,11 +970,13 @@ impl<'a> FromKclValue<'a> for super::patterns::CircularPattern2dData {
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,
})
}
}
@ -1011,15 +1019,6 @@ impl<'a> FromKclValue<'a> for super::sketch::BezierData {
}
}
impl<'a> FromKclValue<'a> for super::shell::ShellData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, thickness);
let_field_of!(obj, faces);
Some(Self { thickness, faces })
}
}
impl<'a> FromKclValue<'a> for super::chamfer::ChamferData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;

View File

@ -63,7 +63,7 @@ pub struct LinearPattern3dData {
/// Repeat some 3D solid, changing each repetition slightly.
pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (num_repetitions, transform, extr) = args.get_pattern_transform_args()?;
let (num_repetitions, transform, extr, use_original) = args.get_pattern_transform_args()?;
let solids = inner_pattern_transform(
num_repetitions,
@ -75,6 +75,7 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
memory: *transform.memory,
},
extr,
use_original,
exec_state,
&args,
)
@ -84,7 +85,7 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
/// Repeat some 2D sketch, changing each repetition slightly.
pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (num_repetitions, transform, sketch): (u32, super::FnAsArg<'_>, SketchSet) =
let (num_repetitions, transform, sketch, use_original): (u32, super::FnAsArg<'_>, SketchSet, Option<bool>) =
super::args::FromArgs::from_args(&args, 0)?;
let sketches = inner_pattern_transform_2d(
@ -97,6 +98,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
memory: *transform.memory,
},
sketch,
use_original,
exec_state,
&args,
)
@ -295,6 +297,7 @@ async fn inner_pattern_transform<'a>(
total_instances: u32,
transform_function: FunctionParam<'a>,
solid_set: SolidSet,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
) -> Result<Vec<Box<Solid>>, KclError> {
@ -310,7 +313,7 @@ async fn inner_pattern_transform<'a>(
let t = make_transform::<Box<Solid>>(i, &transform_function, args.source_range, exec_state).await?;
transform.push(t);
}
execute_pattern_transform(transform, solid_set, exec_state, args).await
execute_pattern_transform(transform, solid_set, use_original.unwrap_or_default(), exec_state, args).await
}
/// Just like patternTransform, but works on 2D sketches not 3D solids.
@ -332,6 +335,7 @@ async fn inner_pattern_transform_2d<'a>(
total_instances: u32,
transform_function: FunctionParam<'a>,
solid_set: SketchSet,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
@ -347,12 +351,13 @@ async fn inner_pattern_transform_2d<'a>(
let t = make_transform::<Box<Sketch>>(i, &transform_function, args.source_range, exec_state).await?;
transform.push(t);
}
execute_pattern_transform(transform, solid_set, exec_state, args).await
execute_pattern_transform(transform, solid_set, use_original.unwrap_or_default(), exec_state, args).await
}
async fn execute_pattern_transform<T: GeometryTrait>(
transforms: Vec<Vec<Transform>>,
geo_set: T::Set,
use_original: bool,
exec_state: &mut ExecState,
args: &Args,
) -> Result<Vec<T>, KclError> {
@ -368,7 +373,7 @@ async fn execute_pattern_transform<T: GeometryTrait>(
let mut output = Vec::new();
for geo in starting {
let new = send_pattern_transform(transforms.clone(), &geo, exec_state, args).await?;
let new = send_pattern_transform(transforms.clone(), &geo, use_original, exec_state, args).await?;
output.extend(new)
}
Ok(output)
@ -379,6 +384,7 @@ async fn send_pattern_transform<T: GeometryTrait>(
// https://github.com/KittyCAD/modeling-app/issues/2821
transforms: Vec<Vec<Transform>>,
solid: &T,
use_original: bool,
exec_state: &mut ExecState,
args: &Args,
) -> Result<Vec<T>, KclError> {
@ -388,7 +394,7 @@ async fn send_pattern_transform<T: GeometryTrait>(
.send_modeling_cmd(
id,
ModelingCmd::from(mcmd::EntityLinearPatternTransform {
entity_id: solid.id(),
entity_id: if use_original { solid.original_id() } else { solid.id() },
transform: Default::default(),
transforms,
}),
@ -602,6 +608,7 @@ fn array_to_point2d(val: &KclValue, source_ranges: Vec<SourceRange>) -> Result<P
trait GeometryTrait: Clone {
type Set: Into<Vec<Self>> + Clone;
fn id(&self) -> Uuid;
fn original_id(&self) -> Uuid;
fn set_id(&mut self, id: Uuid);
fn array_to_point3d(val: &KclValue, source_ranges: Vec<SourceRange>) -> Result<Point3d, KclError>;
async fn flush_batch(args: &Args, exec_state: &mut ExecState, set: Self::Set) -> Result<(), KclError>;
@ -615,6 +622,9 @@ impl GeometryTrait for Box<Sketch> {
fn id(&self) -> Uuid {
self.id
}
fn original_id(&self) -> Uuid {
self.original_id
}
fn array_to_point3d(val: &KclValue, source_ranges: Vec<SourceRange>) -> Result<Point3d, KclError> {
let Point2d { x, y } = array_to_point2d(val, source_ranges)?;
Ok(Point3d { x, y, z: 0.0 })
@ -634,6 +644,11 @@ impl GeometryTrait for Box<Solid> {
fn id(&self) -> Uuid {
self.id
}
fn original_id(&self) -> Uuid {
self.sketch.original_id
}
fn array_to_point3d(val: &KclValue, source_ranges: Vec<SourceRange>) -> Result<Point3d, KclError> {
array_to_point3d(val, source_ranges)
}
@ -674,7 +689,8 @@ 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): (LinearPattern2dData, SketchSet) = args.get_data_and_sketch_set()?;
let (data, sketch_set, use_original): (LinearPattern2dData, SketchSet, Option<bool>) =
super::args::FromArgs::from_args(&args, 0)?;
if data.axis == [0.0, 0.0] {
return Err(KclError::Semantic(KclErrorDetails {
@ -685,7 +701,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
}));
}
let sketches = inner_pattern_linear_2d(data, sketch_set, exec_state, args).await?;
let sketches = inner_pattern_linear_2d(data, sketch_set, use_original, exec_state, args).await?;
Ok(sketches.into())
}
@ -709,6 +725,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
async fn inner_pattern_linear_2d(
data: LinearPattern2dData,
sketch_set: SketchSet,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
@ -726,12 +743,20 @@ async fn inner_pattern_linear_2d(
}]
})
.collect();
execute_pattern_transform(transforms, sketch_set, exec_state, &args).await
execute_pattern_transform(
transforms,
sketch_set,
use_original.unwrap_or_default(),
exec_state,
&args,
)
.await
}
/// 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): (LinearPattern3dData, SolidSet) = args.get_data_and_solid_set()?;
let (data, solid_set, use_original): (LinearPattern3dData, SolidSet, Option<bool>) =
super::args::FromArgs::from_args(&args, 0)?;
if data.axis == [0.0, 0.0, 0.0] {
return Err(KclError::Semantic(KclErrorDetails {
@ -742,7 +767,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
}));
}
let solids = inner_pattern_linear_3d(data, solid_set, exec_state, args).await?;
let solids = inner_pattern_linear_3d(data, solid_set, use_original, exec_state, args).await?;
Ok(solids.into())
}
@ -771,6 +796,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
async fn inner_pattern_linear_3d(
data: LinearPattern3dData,
solid_set: SolidSet,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Solid>>, KclError> {
@ -788,7 +814,14 @@ async fn inner_pattern_linear_3d(
}]
})
.collect();
execute_pattern_transform(transforms, solid_set, exec_state, &args).await
execute_pattern_transform(
transforms,
solid_set,
use_original.unwrap_or_default(),
exec_state,
&args,
)
.await
}
/// Data for a circular pattern on a 2D sketch.
@ -807,6 +840,10 @@ pub struct CircularPattern2dData {
pub arc_degrees: f64,
/// Whether or not to rotate the duplicates as they are copied.
pub rotate_duplicates: bool,
/// If the target being patterned is itself a pattern, then, should you use the original solid,
/// or the pattern?
#[serde(default)]
pub use_original: Option<bool>,
}
/// Data for a circular pattern on a 3D model.
@ -827,6 +864,10 @@ pub struct CircularPattern3dData {
pub arc_degrees: f64,
/// Whether or not to rotate the duplicates as they are copied.
pub rotate_duplicates: bool,
/// If the target being patterned is itself a pattern, then, should you use the original solid,
/// or the pattern?
#[serde(default)]
pub use_original: Option<bool>,
}
pub enum CircularPattern {
@ -889,6 +930,13 @@ impl CircularPattern {
CircularPattern::ThreeD(lp) => lp.rotate_duplicates,
}
}
pub fn use_original(&self) -> bool {
match self {
CircularPattern::TwoD(lp) => lp.use_original.unwrap_or_default(),
CircularPattern::ThreeD(lp) => lp.use_original.unwrap_or_default(),
}
}
}
/// A circular pattern on a 2D sketch.
@ -1055,7 +1103,11 @@ async fn pattern_circular(
id,
ModelingCmd::from(mcmd::EntityCircularPattern {
axis: kcmc::shared::Point3d::from(data.axis()),
entity_id: geometry.id(),
entity_id: if data.use_original() {
geometry.original_id()
} else {
geometry.id()
},
center: kcmc::shared::Point3d {
x: LengthUnit(center[0]),
y: LengthUnit(center[1]),

View File

@ -4,8 +4,6 @@ use anyhow::Result;
use derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
use kittycad_modeling_cmds as kcmc;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
@ -13,22 +11,13 @@ use crate::{
std::{sketch::FaceTag, Args},
};
/// Data for shells.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ShellData {
/// The thickness of the shell.
pub thickness: f64,
/// The faces you want removed.
pub faces: Vec<FaceTag>,
}
/// Create a shell.
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid_set): (ShellData, SolidSet) = args.get_data_and_solid_set()?;
let solid_set = args.get_unlabeled_kw_arg("solidSet")?;
let thickness = args.get_kw_arg("thickness")?;
let faces = args.get_kw_arg("faces")?;
let result = inner_shell(data, solid_set, exec_state, args).await?;
let result = inner_shell(solid_set, thickness, faces, exec_state, args).await?;
Ok(result.into())
}
@ -47,10 +36,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 6)
///
/// // Remove the end face for the extrusion.
/// shell({
/// shell(
/// firstSketch,
/// faces = ['end'],
/// thickness = 0.25,
/// }, firstSketch)
/// )
/// ```
///
/// ```no_run
@ -64,10 +54,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 6)
///
/// // Remove the start face for the extrusion.
/// shell({
/// shell(
/// firstSketch,
/// faces = ['start'],
/// thickness = 0.25,
/// }, firstSketch)
/// )
/// ```
///
/// ```no_run
@ -81,10 +72,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 6)
///
/// // Remove a tagged face for the extrusion.
/// shell({
/// shell(
/// firstSketch,
/// faces = [myTag],
/// thickness = 0.25,
/// }, firstSketch)
/// )
/// ```
///
/// ```no_run
@ -98,10 +90,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 6)
///
/// // Remove a tagged face and the end face for the extrusion.
/// shell({
/// shell(
/// firstSketch,
/// faces = [myTag, 'end'],
/// thickness = 0.25,
/// }, firstSketch)
/// )
/// ```
///
/// ```no_run
@ -124,7 +117,7 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 50)
///
/// // We put "case" in the shell function to shell the entire object.
/// shell({ faces = ['start'], thickness = 5 }, case)
/// shell(case, faces = ['start'], thickness = 5)
/// ```
///
/// ```no_run
@ -147,7 +140,7 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 50)
///
/// // We put "thing1" in the shell function to shell the end face of the object.
/// shell({ faces = ['end'], thickness = 5 }, thing1)
/// shell(thing1, faces = ['end'], thickness = 5)
/// ```
///
/// ```no_run
@ -172,21 +165,29 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> extrude(length = 50)
///
/// // We put "thing1" and "thing2" in the shell function to shell the end face of the object.
/// shell({ faces = ['end'], thickness = 5 }, [thing1, thing2])
/// shell([thing1, thing2], faces = ['end'], thickness = 5)
/// ```
#[stdlib {
name = "shell",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "Which solid (or solids) to shell out"},
thickness = {docs = "The thickness of the shell"},
faces = {docs = "The faces you want removed"},
}
}]
async fn inner_shell(
data: ShellData,
solid_set: SolidSet,
thickness: f64,
faces: Vec<FaceTag>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidSet, KclError> {
if data.faces.is_empty() {
if faces.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "Expected at least one face".to_string(),
message: "You must shell at least one face".to_string(),
source_ranges: vec![args.source_range],
}));
}
@ -194,7 +195,7 @@ async fn inner_shell(
let solids: Vec<Box<Solid>> = solid_set.clone().into();
if solids.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "Expected at least one solid".to_string(),
message: "You must shell at least one solid".to_string(),
source_ranges: vec![args.source_range],
}));
}
@ -205,7 +206,7 @@ async fn inner_shell(
// If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_solid_set(exec_state, solid.clone().into()).await?;
for tag in &data.faces {
for tag in &faces {
let extrude_plane_id = tag.get_face_id(solid, exec_state, &args, false).await?;
face_ids.push(extrude_plane_id);
@ -235,7 +236,7 @@ async fn inner_shell(
hollow: false,
face_ids,
object_id: solids[0].id,
shell_thickness: LengthUnit(data.thickness),
shell_thickness: LengthUnit(thickness),
}),
)
.await?;

View File

@ -1360,6 +1360,7 @@ pub(crate) async fn inner_start_profile_at(
let sketch = Sketch {
id: path_id,
original_id: path_id,
artifact_id: path_id.into(),
on: sketch_surface.clone(),
paths: vec![],

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing angled_line.kcl
snapshot_kind: text
---
{
"environments": [
@ -346,6 +347,7 @@ description: Program memory after executing angled_line.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -374,6 +374,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -904,6 +905,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -975,6 +977,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1412,6 +1415,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1878,6 +1882,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1949,6 +1954,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -468,6 +468,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -609,6 +610,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -200,6 +200,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -274,6 +274,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -695,6 +696,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -757,6 +759,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1332,6 +1335,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1394,6 +1398,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1517,6 +1522,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2236,6 +2242,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2298,6 +2305,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2421,6 +2429,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2483,6 +2492,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2836,6 +2846,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3202,6 +3213,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3264,6 +3276,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3779,6 +3792,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3841,6 +3855,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3964,6 +3979,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4628,6 +4644,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4690,6 +4707,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4813,6 +4831,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4875,6 +4894,7 @@ snapshot_kind: text
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -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": [
@ -422,6 +423,7 @@ description: Program memory after executing basic_fillet_cube_close_opposite.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_end.kcl
snapshot_kind: text
---
{
"environments": [
@ -353,6 +354,7 @@ description: Program memory after executing basic_fillet_cube_end.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -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": [
@ -491,6 +492,7 @@ description: Program memory after executing basic_fillet_cube_next_adjacent.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -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": [
@ -491,6 +492,7 @@ description: Program memory after executing basic_fillet_cube_previous_adjacent.
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_start.kcl
snapshot_kind: text
---
{
"environments": [
@ -353,6 +354,7 @@ description: Program memory after executing basic_fillet_cube_start.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -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": [
@ -253,6 +254,7 @@ description: Program memory after executing big_number_angle_to_match_length_x.k
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -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": [
@ -253,6 +254,7 @@ description: Program memory after executing big_number_angle_to_match_length_y.k
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing circle_three_point.kcl
snapshot_kind: text
---
{
"environments": [
@ -126,6 +127,7 @@ description: Program memory after executing circle_three_point.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing cube.kcl
snapshot_kind: text
---
{
"environments": [
@ -944,6 +945,7 @@ description: Program memory after executing cube.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -2542,7 +2542,7 @@ snapshot_kind: text
"cmdId": "[uuid]",
"range": [
2047,
2110,
2102,
0
],
"command": {

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing fillet-and-shell.kcl
snapshot_kind: text
---
{
"Ok": {
@ -2582,68 +2583,45 @@ description: Result of parsing fillet-and-shell.kcl
"type": "ExpressionStatement"
},
{
"end": 2110,
"end": 2102,
"expression": {
"arguments": [
{
"end": 2103,
"properties": [
{
"end": 2072,
"key": {
"end": 2062,
"name": "faces",
"start": 2057,
"type": "Identifier"
},
"start": 2057,
"type": "ObjectProperty",
"value": {
"elements": [
{
"end": 2071,
"raw": "'end'",
"start": 2066,
"type": "Literal",
"type": "Literal",
"value": "end"
}
],
"end": 2072,
"start": 2065,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "faces"
},
"arg": {
"elements": [
{
"end": 2073,
"raw": "'end'",
"start": 2068,
"type": "Literal",
"type": "Literal",
"value": "end"
}
},
{
"end": 2101,
"key": {
"end": 2085,
"name": "thickness",
"start": 2076,
"type": "Identifier"
},
"start": 2076,
"type": "ObjectProperty",
"value": {
"end": 2101,
"name": "caseThickness",
"start": 2088,
"type": "Identifier",
"type": "Identifier"
}
}
],
"start": 2053,
"type": "ObjectExpression",
"type": "ObjectExpression"
],
"end": 2074,
"start": 2067,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 2109,
"name": "case",
"start": 2105,
"type": "Identifier",
"type": "Identifier"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "thickness"
},
"arg": {
"end": 2101,
"name": "caseThickness",
"start": 2088,
"type": "Identifier",
"type": "Identifier"
}
}
],
"callee": {
@ -2652,17 +2630,24 @@ description: Result of parsing fillet-and-shell.kcl
"start": 2047,
"type": "Identifier"
},
"end": 2110,
"end": 2102,
"start": 2047,
"type": "CallExpression",
"type": "CallExpression"
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"end": 2057,
"name": "case",
"start": 2053,
"type": "Identifier",
"type": "Identifier"
}
},
"start": 2047,
"type": "ExpressionStatement",
"type": "ExpressionStatement"
}
],
"end": 2111,
"end": 2103,
"nonCodeMeta": {
"nonCodeNodes": {
"1": [

View File

@ -74,7 +74,4 @@ m25Screw(border + rpizWidth / 2 + widthBetweenScrews / 2, 0 + border + rpizLengt
m25Screw(border + rpizWidth / 2 + widthBetweenScrews / 2, 0 + border + rpizLength / 2 - (lengthBetweenScrews / 2), screwHeight)
shell({
faces = ['end'],
thickness = caseThickness
}, case)
shell(case, faces = ['end'], thickness = caseThickness)

View File

@ -402,17 +402,17 @@ snapshot_kind: text
},
{
"labeledArgs": {
"data": {
"faces": {
"sourceRange": [
2053,
2103,
2067,
2074,
0
]
},
"solid_set": {
"thickness": {
"sourceRange": [
2105,
2109,
2088,
2101,
0
]
}
@ -420,10 +420,16 @@ snapshot_kind: text
"name": "shell",
"sourceRange": [
2047,
2110,
2102,
0
],
"type": "StdLibCall",
"unlabeledArg": null
"unlabeledArg": {
"sourceRange": [
2053,
2057,
0
]
}
}
]

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing fillet-and-shell.kcl
snapshot_kind: text
---
{
"environments": [
@ -504,6 +505,7 @@ description: Program memory after executing fillet-and-shell.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1787,6 +1789,7 @@ description: Program memory after executing fillet-and-shell.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2389,6 +2392,7 @@ description: Program memory after executing fillet-and-shell.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2674,6 +2678,7 @@ description: Program memory after executing fillet-and-shell.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing function_sketch.kcl
snapshot_kind: text
---
{
"environments": [
@ -622,6 +623,7 @@ description: Program memory after executing function_sketch.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing function_sketch_with_position.kcl
snapshot_kind: text
---
{
"environments": [
@ -608,6 +609,7 @@ description: Program memory after executing function_sketch_with_position.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing helix_ccw.kcl
snapshot_kind: text
---
{
"environments": [
@ -126,6 +127,7 @@ description: Program memory after executing helix_ccw.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing i_shape.kcl
snapshot_kind: text
---
{
"environments": [
@ -643,6 +644,7 @@ description: Program memory after executing i_shape.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1623,6 +1625,7 @@ description: Program memory after executing i_shape.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1923,6 +1926,7 @@ description: Program memory after executing i_shape.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_function_not_sketch.kcl
snapshot_kind: text
---
{
"environments": [
@ -471,6 +472,7 @@ description: Program memory after executing import_function_not_sketch.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -905,6 +907,7 @@ description: Program memory after executing import_function_not_sketch.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Artifact commands import_whole.kcl
snapshot_kind: text
---
[
{
@ -525,7 +526,7 @@ description: Artifact commands import_whole.kcl
"cmdId": "[uuid]",
"range": [
83,
130,
123,
0
],
"command": {

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing import_whole.kcl
snapshot_kind: text
---
{
"Ok": {
@ -26,7 +27,7 @@ description: Result of parsing import_whole.kcl
},
{
"declaration": {
"end": 130,
"end": 123,
"id": {
"end": 71,
"name": "bar",
@ -45,67 +46,45 @@ description: Result of parsing import_whole.kcl
{
"arguments": [
{
"end": 126,
"properties": [
{
"end": 106,
"key": {
"end": 96,
"name": "faces",
"start": 91,
"type": "Identifier"
},
"start": 91,
"type": "ObjectProperty",
"value": {
"elements": [
{
"end": 105,
"raw": "'end'",
"start": 100,
"type": "Literal",
"type": "Literal",
"value": "end"
}
],
"end": 106,
"start": 99,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 124,
"key": {
"end": 117,
"name": "thickness",
"start": 108,
"type": "Identifier"
},
"start": 108,
"type": "ObjectProperty",
"value": {
"end": 124,
"raw": "0.25",
"start": 120,
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "faces"
},
"arg": {
"elements": [
{
"end": 103,
"raw": "'end'",
"start": 98,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.25,
"suffix": "None"
}
"value": "end"
}
}
],
"start": 89,
"type": "ObjectExpression",
"type": "ObjectExpression"
],
"end": 104,
"start": 97,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 129,
"start": 128,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "thickness"
},
"arg": {
"end": 122,
"raw": "0.25",
"start": 118,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.25,
"suffix": "None"
}
}
}
],
"callee": {
@ -114,13 +93,14 @@ description: Result of parsing import_whole.kcl
"start": 83,
"type": "Identifier"
},
"end": 130,
"end": 123,
"start": 83,
"type": "CallExpression",
"type": "CallExpression"
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
}
],
"end": 130,
"end": 123,
"start": 74,
"type": "PipeExpression",
"type": "PipeExpression"
@ -128,14 +108,14 @@ description: Result of parsing import_whole.kcl
"start": 68,
"type": "VariableDeclarator"
},
"end": 130,
"end": 123,
"kind": "const",
"start": 68,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 131,
"end": 124,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [

View File

@ -2,4 +2,4 @@
import "exported_mod.kcl" as foo
bar = foo
|> shell({ faces = ['end'], thickness = 0.25 }, %)
|> shell(faces = ['end'], thickness = 0.25)

View File

@ -1,21 +1,22 @@
---
source: kcl/src/simulation_tests.rs
description: Operations executed import_whole.kcl
snapshot_kind: text
---
[
{
"labeledArgs": {
"data": {
"faces": {
"sourceRange": [
89,
126,
97,
104,
0
]
},
"solid_set": {
"thickness": {
"sourceRange": [
128,
129,
118,
122,
0
]
}
@ -23,7 +24,7 @@ description: Operations executed import_whole.kcl
"name": "shell",
"sourceRange": [
83,
130,
123,
0
],
"type": "StdLibCall",

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_whole.kcl
snapshot_kind: text
---
{
"environments": [
@ -126,6 +127,7 @@ description: Program memory after executing import_whole.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Inches"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing kittycad_svg.kcl
snapshot_kind: text
---
{
"environments": [
@ -8820,6 +8821,7 @@ description: Program memory after executing kittycad_svg.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing linear_pattern3d_a_pattern.kcl
snapshot_kind: text
---
{
"environments": [
@ -213,6 +214,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -431,6 +433,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -645,6 +648,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -859,6 +863,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1073,6 +1078,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1287,6 +1293,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1501,6 +1508,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1715,6 +1723,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1934,6 +1943,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2148,6 +2158,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2362,6 +2373,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2576,6 +2588,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2790,6 +2803,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3004,6 +3018,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3218,6 +3233,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3432,6 +3448,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3646,6 +3663,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3860,6 +3878,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4074,6 +4093,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4288,6 +4308,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4502,6 +4523,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4716,6 +4738,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4930,6 +4953,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -5144,6 +5168,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -5358,6 +5383,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -5572,6 +5598,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -5786,6 +5813,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -6000,6 +6028,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -6214,6 +6243,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -6428,6 +6458,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -6642,6 +6673,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -6856,6 +6888,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -7070,6 +7103,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -7284,6 +7318,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -7498,6 +7533,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -7712,6 +7748,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -7926,6 +7963,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -8140,6 +8178,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -8354,6 +8393,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -8568,6 +8608,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -8782,6 +8823,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -8996,6 +9038,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -9210,6 +9253,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -9424,6 +9468,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -9638,6 +9683,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -9852,6 +9898,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -10066,6 +10113,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -10280,6 +10328,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -10494,6 +10543,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -10708,6 +10758,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -10922,6 +10973,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -11136,6 +11188,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -11350,6 +11403,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -11564,6 +11618,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -11778,6 +11833,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -11992,6 +12048,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -12206,6 +12263,7 @@ description: Program memory after executing linear_pattern3d_a_pattern.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing mike_stress_test.kcl
snapshot_kind: text
---
{
"environments": [
@ -31120,6 +31121,7 @@ description: Program memory after executing mike_stress_test.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing neg_xz_plane.kcl
snapshot_kind: text
---
{
"environments": [
@ -182,6 +183,7 @@ description: Program memory after executing neg_xz_plane.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing parametric.kcl
snapshot_kind: text
---
{
"environments": [
@ -288,6 +289,7 @@ description: Program memory after executing parametric.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing parametric_with_tan_arc.kcl
snapshot_kind: text
---
{
"environments": [
@ -360,6 +361,7 @@ description: Program memory after executing parametric_with_tan_arc.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing pentagon_fillet_sugar.kcl
snapshot_kind: text
---
{
"environments": [
@ -713,6 +714,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -842,6 +844,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1297,6 +1300,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1426,6 +1430,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2318,6 +2323,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2782,6 +2788,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3275,6 +3282,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3404,6 +3412,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3913,6 +3922,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4042,6 +4052,7 @@ description: Program memory after executing pentagon_fillet_sugar.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing pipe_as_arg.kcl
snapshot_kind: text
---
{
"environments": [
@ -1765,6 +1766,7 @@ description: Program memory after executing pipe_as_arg.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing poop_chute.kcl
snapshot_kind: text
---
{
"environments": [
@ -680,6 +681,7 @@ description: Program memory after executing poop_chute.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1213,6 +1215,7 @@ description: Program memory after executing poop_chute.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1764,6 +1767,7 @@ description: Program memory after executing poop_chute.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing riddle_small.kcl
snapshot_kind: text
---
{
"environments": [
@ -322,6 +323,7 @@ description: Program memory after executing riddle_small.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch-on-chamfer-two-times-different-order.kcl
snapshot_kind: text
---
{
"environments": [
@ -544,6 +545,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1330,6 +1332,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1604,6 +1607,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2622,6 +2626,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3294,6 +3299,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3568,6 +3574,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4240,6 +4247,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4469,6 +4477,7 @@ description: Program memory after executing sketch-on-chamfer-two-times-differen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch-on-chamfer-two-times.kcl
snapshot_kind: text
---
{
"environments": [
@ -544,6 +545,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1330,6 +1332,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1604,6 +1607,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -2622,6 +2626,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3294,6 +3299,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -3568,6 +3574,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4240,6 +4247,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -4469,6 +4477,7 @@ description: Program memory after executing sketch-on-chamfer-two-times.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_in_object.kcl
snapshot_kind: text
---
{
"environments": [
@ -1173,6 +1174,7 @@ description: Program memory after executing sketch_in_object.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1330,6 +1332,7 @@ description: Program memory after executing sketch_in_object.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_on_face.kcl
snapshot_kind: text
---
{
"environments": [
@ -344,6 +345,7 @@ description: Program memory after executing sketch_on_face.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -787,6 +789,7 @@ description: Program memory after executing sketch_on_face.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -849,6 +852,7 @@ description: Program memory after executing sketch_on_face.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_on_face_after_fillets_referencing_face.kcl
snapshot_kind: text
---
{
"environments": [
@ -537,6 +538,7 @@ description: Program memory after executing sketch_on_face_after_fillets_referen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1448,6 +1450,7 @@ description: Program memory after executing sketch_on_face_after_fillets_referen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1526,6 +1529,7 @@ description: Program memory after executing sketch_on_face_after_fillets_referen
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_on_face_circle_tagged.kcl
snapshot_kind: text
---
{
"environments": [
@ -607,6 +608,7 @@ description: Program memory after executing sketch_on_face_circle_tagged.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -902,6 +904,7 @@ description: Program memory after executing sketch_on_face_circle_tagged.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1031,6 +1034,7 @@ description: Program memory after executing sketch_on_face_circle_tagged.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_on_face_end.kcl
snapshot_kind: text
---
{
"environments": [
@ -541,6 +542,7 @@ description: Program memory after executing sketch_on_face_end.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -913,6 +915,7 @@ description: Program memory after executing sketch_on_face_end.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -975,6 +978,7 @@ description: Program memory after executing sketch_on_face_end.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_on_face_end_negative_extrude.kcl
snapshot_kind: text
---
{
"environments": [
@ -541,6 +542,7 @@ description: Program memory after executing sketch_on_face_end_negative_extrude.
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -913,6 +915,7 @@ description: Program memory after executing sketch_on_face_end_negative_extrude.
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -975,6 +978,7 @@ description: Program memory after executing sketch_on_face_end_negative_extrude.
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing sketch_on_face_start.kcl
snapshot_kind: text
---
{
"environments": [
@ -541,6 +542,7 @@ description: Program memory after executing sketch_on_face_start.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -758,6 +760,7 @@ description: Program memory after executing sketch_on_face_start.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1130,6 +1133,7 @@ description: Program memory after executing sketch_on_face_start.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
@ -1192,6 +1196,7 @@ description: Program memory after executing sketch_on_face_start.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing tangential_arc.kcl
snapshot_kind: text
---
{
"environments": [
@ -187,6 +188,7 @@ description: Program memory after executing tangential_arc.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing xz_plane.kcl
snapshot_kind: text
---
{
"environments": [
@ -182,6 +183,7 @@ description: Program memory after executing xz_plane.kcl
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},

View File

@ -539,6 +539,18 @@ pub fn calculate_circle_from_3_points(ax: f64, ay: f64, bx: f64, by: f64, cx: f6
}
}
/// Takes a parsed KCL program and returns the Meta settings. If it's not
/// found, null is returned.
#[wasm_bindgen]
pub fn kcl_settings(program_json: &str) -> Result<JsValue, String> {
console_error_panic_hook::set_once();
let program: Program = serde_json::from_str(program_json).map_err(|e| e.to_string())?;
let settings = program.meta_settings().map_err(|e| e.to_string())?;
JsValue::from_serde(&settings).map_err(|e| e.to_string())
}
/// Takes a kcl string and Meta settings and changes the meta settings in the kcl string.
#[wasm_bindgen]
pub fn change_kcl_settings(code: &str, settings_str: &str) -> Result<String, String> {

View File

@ -75,7 +75,7 @@ m25Screw(border + rpizWidth / 2 + widthBetweenScrews / 2, 0 + border + rpizLengt
m25Screw(border + rpizWidth / 2 + widthBetweenScrews / 2, 0 + border + rpizLength / 2 - (lengthBetweenScrews / 2), screwHeight)
shell({
faces: ['end'],
thickness: caseThickness
}, case)
shell(
faces = ['end'],
thickness = caseThickness
)

View File

@ -1534,10 +1534,10 @@ async fn kcl_test_shell_with_tag() {
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> extrude(length = 40.14)
|> shell({
faces: [seg01],
thickness: 3.14,
}, %)
|> shell(
faces = [seg01],
thickness = 3.14,
)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -1998,10 +1998,10 @@ async fn kcl_test_error_no_auth_websocket() {
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> extrude(length = 40.14)
|> shell({
faces: [seg01],
thickness: 3.14,
}, %)
|> shell(
faces = [seg01],
thickness = 3.14,
)
"#;
let result = execute_and_snapshot_no_auth(code, UnitLength::Mm, None).await;

View File

@ -2361,22 +2361,22 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e"
integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==
"@types/mocha@^10.0.6":
version "10.0.7"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.7.tgz#4c620090f28ca7f905a94b706f74dc5b57b44f2f"
integrity sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==
"@types/mocha@^10.0.10":
version "10.0.10"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.10.tgz#91f62905e8d23cbd66225312f239454a23bebfa0"
integrity sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==
"@types/ms@*":
version "0.7.34"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
"@types/node@*", "@types/node@^22.7.8":
version "22.7.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.8.tgz#a1dbf0dc5f71bdd2642fc89caef65d58747ce825"
integrity sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==
"@types/node@*", "@types/node@^22.13.1":
version "22.13.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.1.tgz#a2a3fefbdeb7ba6b89f40371842162fac0934f33"
integrity sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==
dependencies:
undici-types "~6.19.2"
undici-types "~6.20.0"
"@types/node@^20.9.0":
version "20.14.13"
@ -9268,10 +9268,10 @@ undici-types@~5.26.4:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
undici-types@~6.19.2:
version "6.19.6"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.6.tgz#e218c3df0987f4c0e0008ca00d6b6472d9b89b36"
integrity sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==
undici-types@~6.20.0:
version "6.20.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.0"