Compare commits
30 Commits
adjust-seg
...
kcl-73
Author | SHA1 | Date | |
---|---|---|---|
e489222b6a | |||
d93a57d7bf | |||
d34aea345b | |||
0b6102b0ac | |||
9e0873ed84 | |||
8587eb5fea | |||
b898c27e74 | |||
3026866a16 | |||
92fc294eae | |||
21e967ea7f | |||
3f00e7186c | |||
d3a4fd8b55 | |||
2be7107cca | |||
94f194a984 | |||
4fe880a970 | |||
8f5fbfc273 | |||
e660f52bb0 | |||
d74fdd9369 | |||
334145f0be | |||
c24073b6ae | |||
078b7f3bf7 | |||
3d65676ccb | |||
ce566fb6e5 | |||
b23fc9f623 | |||
5c2dfb8e40 | |||
0e341d7863 | |||
6a03ff9596 | |||
d7bd0c937d | |||
d3b2483f4f | |||
7838b7c9fd |
55
.github/workflows/build-apps.yml
vendored
55
.github/workflows/build-apps.yml
vendored
@ -123,18 +123,6 @@ jobs:
|
||||
- id: export_notes
|
||||
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Prepare electron-builder.yml file for updater test
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
run: |
|
||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
with:
|
||||
name: prepared-files-updater-test
|
||||
path: |
|
||||
electron-builder.yml
|
||||
|
||||
|
||||
build-apps:
|
||||
needs: [prepare-files]
|
||||
@ -259,49 +247,6 @@ jobs:
|
||||
|
||||
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
||||
|
||||
# The steps below are for updater-test builds, only on release
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
name: prepared-files-updater-test
|
||||
|
||||
- name: Copy updated electron-builder.yml file for updater test
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
run: |
|
||||
ls -R prepared-files-updater-test
|
||||
cp prepared-files-updater-test/electron-builder.yml electron-builder.yml
|
||||
|
||||
- name: Build the app (updater-test)
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
run: npm run tronb:package:prod
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
with:
|
||||
name: updater-test-arm64-${{ matrix.platform }}
|
||||
path: |
|
||||
out/*-arm64-win.exe
|
||||
out/*-arm64-mac.dmg
|
||||
out/*-arm64-linux.AppImage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
with:
|
||||
name: updater-test-x64-${{ matrix.platform }}
|
||||
path: |
|
||||
out/*-x64-win.exe
|
||||
out/*-x64-mac.dmg
|
||||
out/*-x86_64-linux.AppImage
|
||||
|
||||
|
||||
upload-apps-release:
|
||||
runs-on: ubuntu-22.04
|
||||
|
28
.github/workflows/e2e-tests.yml
vendored
28
.github/workflows/e2e-tests.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Download Wasm Cache
|
||||
- name: Download Wasm cache
|
||||
id: download-wasm
|
||||
if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
|
||||
uses: dawidd6/action-download-artifact@v7
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
branch: main
|
||||
path: rust/kcl-wasm-lib/pkg
|
||||
|
||||
- name: Build WASM condition
|
||||
- name: Build Wasm condition
|
||||
id: wasm
|
||||
run: |
|
||||
set -euox pipefail
|
||||
@ -70,7 +70,7 @@ jobs:
|
||||
run: |
|
||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
||||
|
||||
- name: Install rust
|
||||
- name: Install Rust
|
||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
@ -81,7 +81,7 @@ jobs:
|
||||
with:
|
||||
tool: wasm-pack
|
||||
|
||||
- name: Rust Cache
|
||||
- name: Use Rust cache
|
||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
@ -117,7 +117,7 @@ jobs:
|
||||
- uses: actions/download-artifact@v4
|
||||
name: prepared-wasm
|
||||
|
||||
- name: Copy prepared wasm
|
||||
- name: Copy prepared Wasm
|
||||
run: |
|
||||
ls -R prepared-wasm
|
||||
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
||||
@ -133,20 +133,17 @@ jobs:
|
||||
id: deps-install
|
||||
run: npm install
|
||||
|
||||
- name: Cache Playwright Browsers
|
||||
- name: Cache browsers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright/
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
- name: Install browsers
|
||||
run: npm run playwright install --with-deps
|
||||
|
||||
- name: build web
|
||||
run: npm run tronb:vite:dev
|
||||
|
||||
- name: Run ubuntu/chrome snapshots
|
||||
- name: Capture snapshots
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
@ -170,7 +167,7 @@ jobs:
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
|
||||
- name: Check for changes
|
||||
- name: Check diff
|
||||
if: ${{ github.ref != 'refs/heads/main' }}
|
||||
shell: bash
|
||||
id: git-check
|
||||
@ -181,9 +178,8 @@ jobs:
|
||||
else echo "modified=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Commit changes, if any
|
||||
# TODO: find a more reliable way to detect visual changes
|
||||
if: ${{ false && steps.git-check.outputs.modified == 'true' }}
|
||||
- name: Commit changes
|
||||
if: ${{ steps.git-check.outputs.modified == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
|
||||
@ -193,7 +189,7 @@ jobs:
|
||||
git fetch origin
|
||||
echo ${{ github.head_ref }}
|
||||
git checkout ${{ github.head_ref }}
|
||||
git commit -m "A snapshot a day keeps the bugs away! 📷🐛" || true
|
||||
git commit --message "Update snapshots" || true
|
||||
git push
|
||||
git push origin ${{ github.head_ref }}
|
||||
|
||||
|
@ -130,7 +130,7 @@ git tag $VERSION
|
||||
git push origin --tags
|
||||
```
|
||||
|
||||
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
|
||||
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files.
|
||||
|
||||
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
|
||||
|
||||
@ -142,13 +142,10 @@ The release builds can be found under the `out-{arch}-{platform}` zip files, at
|
||||
|
||||
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
||||
|
||||
##### Updater-test builds
|
||||
|
||||
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
||||
|
||||
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
||||
|
||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
|
||||
A prompt should show up asking for a downgrade to the last release version. Running through that at the end of testing
|
||||
and making sure the current release candidate has the ability to be updated to what electron-updater points to is critical,
|
||||
but what is actually being downloaded and installed isn't.
|
||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing.
|
||||
|
||||
```
|
||||
# Windows (PowerShell)
|
||||
|
16
docs/kcl-std/consts/std-sweep-SKETCH_PLANE.md
Normal file
16
docs/kcl-std/consts/std-sweep-SKETCH_PLANE.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: "sweep::SKETCH_PLANE"
|
||||
subtitle: "Constant in std::sweep"
|
||||
excerpt: "Local/relative to a position centered within the plane being sketched on"
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Local/relative to a position centered within the plane being sketched on
|
||||
|
||||
```kcl
|
||||
sweep::SKETCH_PLANE: string = 'sketchPlane'
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
16
docs/kcl-std/consts/std-sweep-TRAJECTORY.md
Normal file
16
docs/kcl-std/consts/std-sweep-TRAJECTORY.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: "sweep::TRAJECTORY"
|
||||
subtitle: "Constant in std::sweep"
|
||||
excerpt: "Local/relative to the trajectory curve"
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Local/relative to the trajectory curve
|
||||
|
||||
```kcl
|
||||
sweep::TRAJECTORY: string = 'trajectoryCurve'
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -128,6 +128,9 @@ layout: manual
|
||||
* [`E`](/docs/kcl-std/consts/std-math-E)
|
||||
* [`PI`](/docs/kcl-std/consts/std-math-PI)
|
||||
* [`TAU`](/docs/kcl-std/consts/std-math-TAU)
|
||||
* [**std::sweep**](/docs/kcl-std/modules/std-sweep)
|
||||
* [`sweep::SKETCH_PLANE`](/docs/kcl-std/consts/std-sweep-SKETCH_PLANE)
|
||||
* [`sweep::TRAJECTORY`](/docs/kcl-std/consts/std-sweep-TRAJECTORY)
|
||||
* [**std::turns**](/docs/kcl-std/modules/std-turns)
|
||||
* [`turns::HALF_TURN`](/docs/kcl-std/consts/std-turns-HALF_TURN)
|
||||
* [`turns::QUARTER_TURN`](/docs/kcl-std/consts/std-turns-QUARTER_TURN)
|
||||
|
17
docs/kcl-std/modules/std-sweep.md
Normal file
17
docs/kcl-std/modules/std-sweep.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "sweep"
|
||||
subtitle: "Module in std"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Functions and constants
|
||||
|
||||
* [`sweep::SKETCH_PLANE`](/docs/kcl-std/consts/std-sweep-SKETCH_PLANE)
|
||||
* [`sweep::TRAJECTORY`](/docs/kcl-std/consts/std-sweep-TRAJECTORY)
|
||||
|
@ -19,6 +19,7 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui
|
||||
* [`math`](/docs/kcl-std/modules/std-math)
|
||||
* [`sketch`](/docs/kcl-std/modules/std-sketch)
|
||||
* [`solid`](/docs/kcl-std/modules/std-solid)
|
||||
* [`sweep::sweep`](/docs/kcl-std/modules/std-sweep)
|
||||
* [`transform`](/docs/kcl-std/modules/std-transform)
|
||||
* [`turns::turns`](/docs/kcl-std/modules/std-turns)
|
||||
* [`types`](/docs/kcl-std/modules/std-types)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -134,8 +134,6 @@ extrude001 = extrude(sketch001, length = 5)`
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
// Ensure badge is present
|
||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||
await expect(codePaneButtonHolder).toContainText('notification', {
|
||||
@ -158,10 +156,14 @@ extrude001 = extrude(sketch001, length = 5)`
|
||||
await expect(
|
||||
page
|
||||
.getByText(
|
||||
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
||||
'Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis'
|
||||
)
|
||||
.first()
|
||||
).toBeVisible()
|
||||
|
||||
// Make sure ApiError is not on the page.
|
||||
// This ensures we didn't nest the json
|
||||
await expect(page.getByText('ApiError')).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
||||
@ -179,7 +181,7 @@ extrude001 = extrude(sketch001, length = 5)`
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await scene.settled(cmdBar)
|
||||
// await scene.settled(cmdBar)
|
||||
|
||||
// Ensure badge is present
|
||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||
|
@ -58,12 +58,6 @@ test(
|
||||
await expect(submitButton).toBeVisible()
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Look out for the toast message
|
||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
||||
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
||||
await expect(exportingToastMessage).toBeVisible()
|
||||
await expect(alreadyExportingToastMessage).not.toBeVisible()
|
||||
|
||||
// Expect it to succeed
|
||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
||||
@ -72,7 +66,6 @@ test(
|
||||
|
||||
const successToastMessage = page.getByText(`Exported successfully`)
|
||||
await expect(successToastMessage).toBeVisible()
|
||||
await expect(exportingToastMessage).not.toBeVisible()
|
||||
|
||||
// Check for the exported file
|
||||
const firstFileFullPath = path.resolve(
|
||||
|
@ -1533,7 +1533,6 @@ sketch001 = startSketchOn(XZ)
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await scene.expectPixelColor(
|
||||
TEST_COLORS.DARK_MODE_BKGD,
|
||||
|
@ -1931,84 +1931,6 @@ sketch002 = startSketchOn(XZ)
|
||||
})
|
||||
})
|
||||
|
||||
test(`Sweep point-and-click failing validation`, async ({
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
toolbar,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `@settings(defaultLengthUnit = in)
|
||||
sketch001 = startSketchOn(YZ)
|
||||
|> circle(
|
||||
center = [0, 0],
|
||||
radius = 500
|
||||
)
|
||||
sketch002 = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> xLine(length = -500)
|
||||
|> line(endAbsolute = [-2000, 500])
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
localStorage.setItem('persistCode', initialCode)
|
||||
}, initialCode)
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// One dumb hardcoded screen pixel value
|
||||
const testPoint = { x: 700, y: 250 }
|
||||
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||
const [clickOnSketch2] = scene.makeMouseHelpers(
|
||||
testPoint.x - 50,
|
||||
testPoint.y
|
||||
)
|
||||
|
||||
await test.step(`Look for sketch001`, async () => {
|
||||
await toolbar.closePane('code')
|
||||
await scene.expectPixelColor([53, 53, 53], testPoint, 15)
|
||||
})
|
||||
|
||||
await test.step(`Go through the command bar flow and fail validation with a toast`, async () => {
|
||||
await toolbar.sweepButton.click()
|
||||
await expect
|
||||
.poll(() => page.getByText('Please select one').count())
|
||||
.toBe(1)
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Sweep',
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Sketches: '',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'sketches',
|
||||
stage: 'arguments',
|
||||
})
|
||||
await clickOnSketch1()
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Sweep',
|
||||
currentArgKey: 'path',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Sketches: '1 face',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'path',
|
||||
stage: 'arguments',
|
||||
})
|
||||
await clickOnSketch2()
|
||||
await cmdBar.progressCmdBar()
|
||||
await expect(
|
||||
page.getByText('Unable to sweep with the current selection. Reason:')
|
||||
).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test(`Fillet point-and-click`, async ({
|
||||
context,
|
||||
page,
|
||||
@ -3627,67 +3549,6 @@ profile001 = startProfile(sketch001, at = [-20, 20])
|
||||
})
|
||||
})
|
||||
|
||||
test(`Shell dry-run validation rejects sweeps`, async ({
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
editor,
|
||||
toolbar,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn(YZ)
|
||||
|> circle(
|
||||
center = [0, 0],
|
||||
radius = 500
|
||||
)
|
||||
sketch002 = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> xLine(length = -2000)
|
||||
sweep001 = sweep(sketch001, path = sketch002)
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
localStorage.setItem('persistCode', initialCode)
|
||||
}, initialCode)
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// One dumb hardcoded screen pixel value
|
||||
const testPoint = { x: 500, y: 250 }
|
||||
const [clickOnSweep] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||
|
||||
await test.step(`Confirm sweep exists`, async () => {
|
||||
await toolbar.closePane('code')
|
||||
await scene.expectPixelColor([231, 231, 231], testPoint, 15)
|
||||
})
|
||||
|
||||
await test.step(`Go through the Shell flow and fail validation with a toast`, async () => {
|
||||
await toolbar.shellButton.click()
|
||||
await expect
|
||||
.poll(() => page.getByText('Please select one').count())
|
||||
.toBe(1)
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'selection',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Selection: '',
|
||||
Thickness: '',
|
||||
},
|
||||
highlightedHeaderArg: 'selection',
|
||||
commandName: 'Shell',
|
||||
})
|
||||
await clickOnSweep()
|
||||
await page.waitForTimeout(500)
|
||||
await cmdBar.progressCmdBar()
|
||||
await expect(
|
||||
page.getByText('Unable to shell with the current selection. Reason:')
|
||||
).toBeVisible()
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Revolve point and click workflows', () => {
|
||||
test('Base case workflow, auto spam continue in command bar', async ({
|
||||
context,
|
||||
@ -4943,4 +4804,34 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test(`Point and click codemods can't run on KCL errors`, async ({
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
editor,
|
||||
toolbar,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const badCode = `sketch001 = startSketchOn(XZ)
|
||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
||||
extrude001 = extrude(profile001 length = 1)`
|
||||
await context.addInitScript((initialCode) => {
|
||||
localStorage.setItem('persistCode', initialCode)
|
||||
}, badCode)
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
await test.step(`Start Sketch is disabled`, async () => {
|
||||
await expect(toolbar.startSketchBtn).not.toBeEnabled()
|
||||
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||
})
|
||||
|
||||
await test.step(`Helix is disabled`, async () => {
|
||||
await expect(toolbar.helixButton).not.toBeEnabled()
|
||||
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -19,11 +19,12 @@ test.describe('Regression tests', () => {
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
}) => {
|
||||
// because the model has `line([0,0]..` it is valid code, but the model is invalid
|
||||
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
|
||||
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
|
||||
const u = await getUtils(page)
|
||||
// const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -40,7 +41,8 @@ test.describe('Regression tests', () => {
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
await scene.connectionEstablished()
|
||||
// await u.waitForPageLoad()
|
||||
|
||||
// error in guter
|
||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||
@ -51,8 +53,11 @@ test.describe('Regression tests', () => {
|
||||
// the close doesn't work
|
||||
// when https://github.com/KittyCAD/modeling-app/issues/3268 is closed
|
||||
// this test will need updating
|
||||
const crypticErrorText = `ApiError`
|
||||
const crypticErrorText = `Cannot close a path that is non-planar or with duplicate vertices.
|
||||
Internal engine error on request`
|
||||
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
|
||||
// Ensure we didn't nest the json.
|
||||
await expect(page.getByText('ApiError')).not.toBeVisible()
|
||||
})
|
||||
test('user should not have to press down twice in cmdbar', async ({
|
||||
page,
|
||||
@ -185,8 +190,8 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
page.locator('.pretty-json-container >> text=myVar:"67')
|
||||
).toBeVisible()
|
||||
})
|
||||
test('ProgramMemory can be serialised', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
test('ProgramMemory can be serialised', async ({ page, homePage, scene }) => {
|
||||
// const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -211,11 +216,12 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
// Listen for all console events and push the message text to an array
|
||||
page.on('console', (message) => messages.push(message.text()))
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
// await u.waitForPageLoad()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
// await u.openDebugPanel()
|
||||
// await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
|
||||
const forbiddenMessages = ['cannot serialize tagged newtype variant']
|
||||
forbiddenMessages.forEach((forbiddenMessage) => {
|
||||
@ -229,6 +235,7 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
@ -247,11 +254,10 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
||||
)
|
||||
})
|
||||
await homePage.goToModelingScene()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
await expect(async () => {
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
|
||||
// error in guter
|
||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||
timeout: 1_000,
|
||||
@ -545,7 +551,8 @@ extrude002 = extrude(profile002, length = 150)
|
||||
expect(alreadyExportingToastMessage).not.toBeVisible(),
|
||||
])
|
||||
|
||||
await expect(successToastMessage).toHaveCount(2)
|
||||
const count = await successToastMessage.count()
|
||||
await expect(count).toBeGreaterThanOrEqual(2)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -1365,18 +1365,18 @@ solid001 = subtract([extrude001], tools = [extrude002])
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`fn in2mm = (inches) => {
|
||||
`fn in2mm(@inches) {
|
||||
return inches * 25.4
|
||||
}
|
||||
|
||||
const railTop = in2mm(.748)
|
||||
const railSide = in2mm(.024)
|
||||
const railBaseWidth = in2mm(.612)
|
||||
const railWideWidth = in2mm(.835)
|
||||
const railBaseLength = in2mm(.200)
|
||||
const railClampable = in2mm(.200)
|
||||
railTop = in2mm(.748)
|
||||
railSide = in2mm(.024)
|
||||
railBaseWidth = in2mm(.612)
|
||||
railWideWidth = in2mm(.835)
|
||||
railBaseLength = in2mm(.200)
|
||||
railClampable = in2mm(.200)
|
||||
|
||||
const rail = startSketchOn(XZ)
|
||||
rail = startSketchOn(XZ)
|
||||
|> startProfile(at = [-railTop / 2, railClampable + railBaseLength])
|
||||
|> line(endAbsolute = [
|
||||
railTop / 2,
|
||||
@ -3540,7 +3540,6 @@ profile001 = startProfile(sketch001, at = [127.56, 179.02])
|
||||
|
||||
await homePage.openProject('multi-file-sketch-test')
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
|
||||
@ -3555,9 +3554,6 @@ profile001 = startProfile(sketch001, at = [127.56, 179.02])
|
||||
|
||||
await toolbar.openFile('error.kcl')
|
||||
|
||||
// Ensure filetree is populated
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await expect(
|
||||
toolbar.featureTreePane.getByRole('button', { name: 'Sketch' })
|
||||
).toHaveCount(0)
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
|
||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
|
||||
@ -9,6 +8,7 @@ import {
|
||||
settingsToToml,
|
||||
} from '@e2e/playwright/test-utils'
|
||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
|
||||
|
||||
test.beforeEach(async ({ page, context }) => {
|
||||
// Make the user avatar image always 404
|
||||
@ -766,7 +766,7 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('theme persists', async ({ page, context }) => {
|
||||
test('theme persists', async ({ page, context, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -784,7 +784,7 @@ test('theme persists', async ({ page, context }) => {
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await page.waitForTimeout(500)
|
||||
|
||||
// await page.getByRole('link', { name: 'Settings Settings (tooltip)' }).click()
|
||||
@ -812,7 +812,7 @@ test('theme persists', async ({ page, context }) => {
|
||||
// Disconnect and reconnect to check the theme persists through a reload
|
||||
|
||||
// Expect the network to be down
|
||||
await expect(networkToggle).toContainText('Offline')
|
||||
await expect(networkToggle).toContainText('Problem')
|
||||
|
||||
// simulate network up
|
||||
await u.emulateNetworkConditions({
|
||||
@ -873,6 +873,50 @@ sweepSketch = startSketchOn(XY)
|
||||
mask: lowerRightMasks(page),
|
||||
})
|
||||
})
|
||||
test('code color goober works with single quotes', async ({
|
||||
page,
|
||||
context,
|
||||
scene,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`// Create a pipe using a sweep.
|
||||
|
||||
// Create a path for the sweep.
|
||||
sweepPath = startSketchOn(XZ)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> line(end = [0, 7])
|
||||
|
||||
sweepSketch = startSketchOn(XY)
|
||||
|> startProfile(at = [2, 0])
|
||||
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|
||||
|> sweep(path = sweepPath)
|
||||
|> appearance(
|
||||
color = '#bb00ff',
|
||||
metalness = 90,
|
||||
roughness = 90
|
||||
)
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 1000 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await expect(page, 'expect small color widget').toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask: lowerRightMasks(page),
|
||||
})
|
||||
})
|
||||
|
||||
test('code color goober opening window', async ({
|
||||
page,
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
@ -1,19 +1,22 @@
|
||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
|
||||
import { uuidv4 } from '@src/lib/utils'
|
||||
|
||||
import { commonPoints, getUtils } from '@e2e/playwright/test-utils'
|
||||
import {
|
||||
commonPoints,
|
||||
getUtils,
|
||||
TEST_COLORS,
|
||||
circleMove,
|
||||
} from '@e2e/playwright/test-utils'
|
||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||
|
||||
test.describe(
|
||||
'Test network and connection issues',
|
||||
{
|
||||
tag: ['@macos', '@windows'],
|
||||
},
|
||||
() => {
|
||||
test.describe('Test network related behaviors', () => {
|
||||
test(
|
||||
'simulate network down and network little widget',
|
||||
{ tag: '@skipLocalEngine' },
|
||||
async ({ page, homePage }) => {
|
||||
const networkToggleConnectedText = page.getByText('Connected')
|
||||
const networkToggleWeakText = page.getByText('Network health (Weak)')
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
@ -34,7 +37,9 @@ test.describe(
|
||||
await expect(networkPopover).not.toBeVisible()
|
||||
|
||||
// (First check) Expect the network to be up
|
||||
await expect(networkToggle).toContainText('Connected')
|
||||
await expect(
|
||||
networkToggleConnectedText.or(networkToggleWeakText)
|
||||
).toBeVisible()
|
||||
|
||||
// Click the network widget
|
||||
await networkWidget.click()
|
||||
@ -82,7 +87,9 @@ test.describe(
|
||||
).not.toBeDisabled({ timeout: 15000 })
|
||||
|
||||
// (Second check) expect the network to be up
|
||||
await expect(networkToggle).toContainText('Connected')
|
||||
await expect(
|
||||
networkToggleConnectedText.or(networkToggleWeakText)
|
||||
).toBeVisible()
|
||||
}
|
||||
)
|
||||
|
||||
@ -91,6 +98,8 @@ test.describe(
|
||||
{ tag: '@skipLocalEngine' },
|
||||
async ({ page, homePage, toolbar, scene, cmdBar }) => {
|
||||
const networkToggle = page.getByTestId('network-toggle')
|
||||
const networkToggleConnectedText = page.getByText('Connected')
|
||||
const networkToggleWeakText = page.getByText('Network health (Weak)')
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
@ -109,7 +118,7 @@ test.describe(
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`sketch001 = startSketchOn(XZ)`
|
||||
`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)`
|
||||
)
|
||||
await u.closeDebugPanel()
|
||||
|
||||
@ -118,7 +127,7 @@ test.describe(
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})`
|
||||
`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})`
|
||||
)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
@ -127,11 +136,14 @@ test.describe(
|
||||
|
||||
await expect(
|
||||
page.locator('.cm-content')
|
||||
).toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})
|
||||
).toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})
|
||||
|> xLine(length = ${commonPoints.num1})`)
|
||||
|
||||
// Expect the network to be up
|
||||
await expect(networkToggle).toContainText('Connected')
|
||||
await networkToggle.hover()
|
||||
await expect(
|
||||
networkToggleConnectedText.or(networkToggleWeakText)
|
||||
).toBeVisible()
|
||||
|
||||
// simulate network down
|
||||
await u.emulateNetworkConditions({
|
||||
@ -143,6 +155,7 @@ test.describe(
|
||||
})
|
||||
|
||||
// Expect the network to be down
|
||||
await networkToggle.hover()
|
||||
await expect(networkToggle).toContainText('Problem')
|
||||
|
||||
// Ensure we are not in sketch mode
|
||||
@ -168,7 +181,11 @@ test.describe(
|
||||
).not.toBeDisabled({ timeout: 15000 })
|
||||
|
||||
// Expect the network to be up
|
||||
await expect(networkToggle).toContainText('Connected')
|
||||
await networkToggle.hover()
|
||||
await expect(
|
||||
networkToggleConnectedText.or(networkToggleWeakText)
|
||||
).toBeVisible()
|
||||
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// Click off the code pane.
|
||||
@ -183,9 +200,7 @@ test.describe(
|
||||
await toolbar.editSketch()
|
||||
|
||||
// Click the line tool
|
||||
await page
|
||||
.getByRole('button', { name: 'line Line', exact: true })
|
||||
.click()
|
||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||
|
||||
await page.waitForTimeout(150)
|
||||
|
||||
@ -219,7 +234,10 @@ test.describe(
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||
await expect
|
||||
.poll(u.normalisedEditorCode)
|
||||
.toBe(`sketch001 = startSketchOn(XZ)
|
||||
.toBe(`@settings(defaultLengthUnit = in)
|
||||
|
||||
|
||||
sketch001 = startSketchOn(XZ)
|
||||
profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
||||
|> xLine(length = 12.34)
|
||||
|> line(end = [-12.34, 12.34])
|
||||
@ -230,7 +248,10 @@ profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
||||
|
||||
await expect
|
||||
.poll(u.normalisedEditorCode)
|
||||
.toBe(`sketch001 = startSketchOn(XZ)
|
||||
.toBe(`@settings(defaultLengthUnit = in)
|
||||
|
||||
|
||||
sketch001 = startSketchOn(XZ)
|
||||
profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
||||
|> xLine(length = 12.34)
|
||||
|> line(end = [-12.34, 12.34])
|
||||
@ -255,5 +276,88 @@ profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
||||
).not.toBeVisible()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'Paused stream freezes view frame, unpause reconnect is seamless to user',
|
||||
{ tag: ['@electron', '@skipLocalEngine'] },
|
||||
async ({ page, homePage, scene, cmdBar, toolbar, tronApp }) => {
|
||||
const networkToggle = page.getByTestId('network-toggle')
|
||||
const networkToggleConnectedText = page.getByText('Connected')
|
||||
const networkToggleWeakText = page.getByText('Network health (Weak)')
|
||||
|
||||
if (!tronApp) {
|
||||
fail()
|
||||
}
|
||||
|
||||
await tronApp.cleanProjectDir({
|
||||
app: {
|
||||
stream_idle_mode: 5000,
|
||||
},
|
||||
})
|
||||
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn(XY)
|
||||
profile001 = startProfile(sketch001, at = [0.0, 0.0])
|
||||
|> line(end = [10.0, 0])
|
||||
|> line(end = [0, 10.0])
|
||||
|> close()`
|
||||
)
|
||||
})
|
||||
|
||||
const dim = { width: 1200, height: 500 }
|
||||
await page.setBodyDimensions(dim)
|
||||
|
||||
await test.step('Go to modeling scene', async () => {
|
||||
await homePage.goToModelingScene()
|
||||
await scene.settled(cmdBar)
|
||||
})
|
||||
|
||||
await test.step('Verify pausing behavior', async () => {
|
||||
// Wait 5s + 1s to pause.
|
||||
await page.waitForTimeout(6000)
|
||||
|
||||
// We should now be paused. To the user, it should appear we're still
|
||||
// connected.
|
||||
await networkToggle.hover()
|
||||
await expect(
|
||||
networkToggleConnectedText.or(networkToggleWeakText)
|
||||
).toBeVisible()
|
||||
|
||||
const center = {
|
||||
x: dim.width / 2,
|
||||
y: dim.height / 2,
|
||||
}
|
||||
|
||||
let probe = { x: 0, y: 0 }
|
||||
|
||||
// ... and the model's still visibly there
|
||||
probe.x = center.x + dim.width / 100
|
||||
probe.y = center.y
|
||||
await scene.expectPixelColor(TEST_COLORS.GREY, probe, 15)
|
||||
probe = { ...center }
|
||||
|
||||
// Now move the mouse around to unpause!
|
||||
await circleMove(page, probe.x, probe.y, 20, 10)
|
||||
|
||||
// ONCE AGAIN! Check the view area hasn't changed at all.
|
||||
// Check the pixel a couple times as it reconnects.
|
||||
// NOTE: Remember, idle behavior is still on at this point -
|
||||
// if this test takes longer than 5s shit WILL go south!
|
||||
probe.x = center.x + dim.width / 100
|
||||
probe.y = center.y
|
||||
await scene.expectPixelColor(TEST_COLORS.GREY, probe, 15)
|
||||
await page.waitForTimeout(1000)
|
||||
await scene.expectPixelColor(TEST_COLORS.GREY, probe, 15)
|
||||
probe = { ...center }
|
||||
|
||||
// Ensure we're still connected
|
||||
await networkToggle.hover()
|
||||
await expect(
|
||||
networkToggleConnectedText.or(networkToggleWeakText)
|
||||
).toBeVisible()
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -44,6 +44,8 @@ export const lowerRightMasks = (page: Page) => [
|
||||
export type TestColor = [number, number, number]
|
||||
export const TEST_COLORS: { [key: string]: TestColor } = {
|
||||
WHITE: [249, 249, 249],
|
||||
OFFWHITE: [237, 237, 237],
|
||||
GREY: [142, 142, 142],
|
||||
YELLOW: [255, 255, 0],
|
||||
BLUE: [0, 0, 255],
|
||||
DARK_MODE_BKGD: [27, 27, 27],
|
||||
|
@ -57,9 +57,9 @@ fn connectorSketch(@plane, start) {
|
||||
|
||||
export fn connector(@plane, length) {
|
||||
connectorSketch(plane, start = [-12, 8])
|
||||
|> extrude(length = length)
|
||||
|> extrude(length)
|
||||
connectorSketch(plane, start = [16, 8])
|
||||
|> extrude(length = length)
|
||||
|> extrude(length)
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ fn seatSlatSketch(@plane) {
|
||||
|
||||
export fn seatSlats(@plane, length) {
|
||||
seatSlatSketch(plane)
|
||||
|> extrude(length = length)
|
||||
|> extrude(length)
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ fn backSlatsSketch(@plane) {
|
||||
|
||||
export fn backSlats(@plane, length) {
|
||||
b = backSlatsSketch(plane)
|
||||
|> extrude(length = length)
|
||||
|> extrude(length)
|
||||
return b
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ holeDia = 4
|
||||
sketch001 = startSketchOn(XY)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 0, length = width, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = length, tag = $rectangleSegmentB001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length, tag = $rectangleSegmentB001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
||||
|> close()
|
||||
@ -74,7 +74,7 @@ function001([
|
||||
sketch003 = startSketchOn(XY)
|
||||
|> startProfile(at = [width * 1.2, 0])
|
||||
|> angledLine(angle = 0, length = width, tag = $rectangleSegmentA002)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = length, tag = $rectangleSegmentB002)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length, tag = $rectangleSegmentB002)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC002)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|
||||
|> close()
|
||||
|
@ -1,12 +1,12 @@
|
||||
[test-groups]
|
||||
# If a test uses the engine, we want to limit the number that can run in parallel.
|
||||
# This way we don't start and stop too many engine instances, putting pressure on our cloud.
|
||||
uses-engine = { max-threads = 4 }
|
||||
uses-engine = { max-threads = 32 }
|
||||
# If a test must run after the engine tests, we want to make sure the engine tests are done first.
|
||||
after-engine = { max-threads = 12 }
|
||||
after-engine = { max-threads = 32 }
|
||||
|
||||
[profile.default]
|
||||
slow-timeout = { period = "180s", terminate-after = 1 }
|
||||
slow-timeout = { period = "280s", terminate-after = 1 }
|
||||
|
||||
[profile.ci]
|
||||
slow-timeout = { period = "280s", terminate-after = 5 }
|
||||
|
24
rust/Cargo.lock
generated
24
rust/Cargo.lock
generated
@ -1815,7 +1815,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-bumper"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1826,7 +1826,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-derive-docs"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
@ -1845,7 +1845,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-directory-test-macro"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1854,7 +1854,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-language-server"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1875,7 +1875,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-language-server-release"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@ -1895,7 +1895,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx 0.5.1",
|
||||
@ -1971,7 +1971,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-python-bindings"
|
||||
version = "0.3.69"
|
||||
version = "0.3.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kcl-lib",
|
||||
@ -1986,7 +1986,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-test-server"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hyper 0.14.32",
|
||||
@ -1999,7 +1999,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-to-core"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -2013,7 +2013,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-wasm-lib"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bson",
|
||||
@ -2080,9 +2080,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad-modeling-cmds"
|
||||
version = "0.2.120"
|
||||
version = "0.2.121"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48b71e06ee5d711d0085864a756fb6a304531246689ea00c6ef5d740670c3701"
|
||||
checksum = "94ba95c22493d79ec8a1faab963d8903f6de0e373efedf2bc3bb76a0ddbab036"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
[package]
|
||||
name = "kcl-bumper"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KittyCAD/modeling-api"
|
||||
rust-version = "1.76"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-derive-docs"
|
||||
description = "A tool for generating documentation from Rust derive macros"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-directory-test-macro"
|
||||
description = "A tool for generating tests from a directory of kcl files"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-language-server-release"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||
publish = false
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "kcl-language-server"
|
||||
description = "A language server for KCL."
|
||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language implementation and tools"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -953,36 +953,6 @@ sketch001 = startSketchOn(box, face = END)
|
||||
assert_out("revolve_on_edge", &result);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_revolve_on_edge_get_edge() {
|
||||
let code = r#"box = startSketchOn(XY)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [0, -10], tag = $revolveAxis)
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|
||||
sketch001 = startSketchOn(box, face = revolveAxis)
|
||||
|> startProfile(at = [5, 10])
|
||||
|> line(end = [0, -10])
|
||||
|> line(end = [2, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> close()
|
||||
|> revolve(axis = revolveAxis, angle = 90)
|
||||
|
||||
"#;
|
||||
|
||||
let result = execute_and_snapshot(code, None).await;
|
||||
|
||||
result.unwrap_err();
|
||||
//this fails right now, but slightly differently, lets just say its enough for it to fail - mike
|
||||
//assert_eq!(
|
||||
// result.err().unwrap().to_string(),
|
||||
// r#"engine: KclErrorDetails { source_ranges: [SourceRange([346, 390, 0])], message: "Modeling command failed: [ApiError { error_code: InternalEngine, message: \"Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis\" }]" }"#
|
||||
//);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_revolve_on_face_circle_edge() {
|
||||
let code = r#"box = startSketchOn(XY)
|
||||
|
@ -788,6 +788,7 @@ impl ArgData {
|
||||
Some("Axis2d | Edge") | Some("Axis3d | Edge") => Some((index, format!(r#"{label}${{{index}:X}}"#))),
|
||||
Some("Edge") => Some((index, format!(r#"{label}${{{index}:tag_or_edge_fn}}"#))),
|
||||
Some("[Edge; 1+]") => Some((index, format!(r#"{label}[${{{index}:tag_or_edge_fn}}]"#))),
|
||||
Some("Plane") => Some((index, format!(r#"{label}${{{}:XY}}"#, index))),
|
||||
|
||||
Some("string") => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))),
|
||||
Some("bool") => Some((index, format!(r#"{label}${{{}:false}}"#, index))),
|
||||
|
@ -1167,6 +1167,16 @@ mod tests {
|
||||
assert_eq!(snippet, r#"clone(${0:part001})"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_autocomplete_snippet_offset_plane() {
|
||||
let data = kcl_doc::walk_prelude();
|
||||
let DocData::Fn(offset_plane_fn) = data.find_by_name("offsetPlane").unwrap() else {
|
||||
panic!();
|
||||
};
|
||||
let snippet = offset_plane_fn.to_autocomplete_snippet();
|
||||
assert_eq!(snippet, r#"offsetPlane(${0:XY}, offset = ${1:3.14})"#);
|
||||
}
|
||||
|
||||
// We want to test the snippets we compile at lsp start.
|
||||
#[test]
|
||||
fn get_all_stdlib_autocomplete_snippets() {
|
||||
|
@ -223,6 +223,26 @@ impl EngineConnection {
|
||||
message: errors.iter().map(|e| e.message.clone()).collect::<Vec<_>>().join("\n"),
|
||||
source_ranges: vec![source_range],
|
||||
})
|
||||
} else if let Ok(data) =
|
||||
serde_json::from_str::<Vec<kittycad_modeling_cmds::websocket::FailureWebSocketResponse>>(&err_str)
|
||||
{
|
||||
if let Some(data) = data.first() {
|
||||
// It could also be an array of responses.
|
||||
KclError::Engine(KclErrorDetails {
|
||||
message: data
|
||||
.errors
|
||||
.iter()
|
||||
.map(|e| e.message.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
source_ranges: vec![source_range],
|
||||
})
|
||||
} else {
|
||||
KclError::Engine(KclErrorDetails {
|
||||
message: "Received empty response from engine".into(),
|
||||
source_ranges: vec![source_range],
|
||||
})
|
||||
}
|
||||
} else {
|
||||
KclError::Engine(KclErrorDetails {
|
||||
message: format!("Failed to wait for promise from send modeling command: {:?}", e),
|
||||
|
@ -764,7 +764,12 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
WebSocketResponse::Failure(fail) => {
|
||||
let _request_id = fail.request_id;
|
||||
Err(KclError::Engine(KclErrorDetails {
|
||||
message: format!("Modeling command failed: {:?}", fail.errors),
|
||||
message: fail
|
||||
.errors
|
||||
.iter()
|
||||
.map(|e| e.message.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
source_ranges: vec![source_range],
|
||||
}))
|
||||
}
|
||||
@ -807,7 +812,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
})
|
||||
})?;
|
||||
return Err(KclError::Engine(KclErrorDetails {
|
||||
message: format!("Modeling command failed: {:?}", errors),
|
||||
message: errors.iter().map(|e| e.message.clone()).collect::<Vec<_>>().join("\n"),
|
||||
source_ranges: vec![source_range],
|
||||
}));
|
||||
}
|
||||
|
@ -1311,10 +1311,15 @@ impl Node<CallExpressionKw> {
|
||||
Some(l) => {
|
||||
fn_args.insert(l.name.clone(), arg);
|
||||
}
|
||||
None => errors.push(arg),
|
||||
None => {
|
||||
if let Some(id) = arg_expr.arg.ident_name() {
|
||||
fn_args.insert(id.to_owned(), arg);
|
||||
} else {
|
||||
errors.push(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let fn_args = fn_args; // remove mutability
|
||||
|
||||
// Evaluate the unlabeled first param, if any exists.
|
||||
let unlabeled = if let Some(ref arg_expr) = self.unlabeled {
|
||||
@ -1323,12 +1328,15 @@ impl Node<CallExpressionKw> {
|
||||
let value = ctx
|
||||
.execute_expr(arg_expr, exec_state, &metadata, &[], StatementKind::Expression)
|
||||
.await?;
|
||||
Some(Arg::new(value, source_range))
|
||||
|
||||
let label = arg_expr.ident_name().map(str::to_owned);
|
||||
|
||||
Some((label, Arg::new(value, source_range)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let args = Args::new_kw(
|
||||
let mut args = Args::new_kw(
|
||||
KwArgs {
|
||||
unlabeled,
|
||||
labeled: fn_args,
|
||||
@ -1347,6 +1355,20 @@ impl Node<CallExpressionKw> {
|
||||
));
|
||||
}
|
||||
|
||||
let formals = func.args(false);
|
||||
|
||||
// If it's possible the input arg was meant to be labelled and we probably don't want to use
|
||||
// it as the input arg, then treat it as labelled.
|
||||
if let Some((Some(label), _)) = &args.kw_args.unlabeled {
|
||||
if (formals.iter().all(|a| a.label_required) || exec_state.pipe_value().is_some())
|
||||
&& formals.iter().any(|a| &a.name == label && a.label_required)
|
||||
&& !args.kw_args.labeled.contains_key(label)
|
||||
{
|
||||
let (label, arg) = args.kw_args.unlabeled.take().unwrap();
|
||||
args.kw_args.labeled.insert(label.unwrap(), arg);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
let op = if func.feature_tree_operation() {
|
||||
let op_labeled_args = args
|
||||
@ -1368,7 +1390,6 @@ impl Node<CallExpressionKw> {
|
||||
None
|
||||
};
|
||||
|
||||
let formals = func.args(false);
|
||||
for (label, arg) in &args.kw_args.labeled {
|
||||
match formals.iter().find(|p| &p.name == label) {
|
||||
Some(p) => {
|
||||
@ -1865,6 +1886,21 @@ fn type_check_params_kw(
|
||||
args: &mut KwArgs,
|
||||
exec_state: &mut ExecState,
|
||||
) -> Result<(), KclError> {
|
||||
// If it's possible the input arg was meant to be labelled and we probably don't want to use
|
||||
// it as the input arg, then treat it as labelled.
|
||||
if let Some((Some(label), _)) = &args.unlabeled {
|
||||
if (function_expression.params.iter().all(|p| p.labeled) || exec_state.pipe_value().is_some())
|
||||
&& function_expression
|
||||
.params
|
||||
.iter()
|
||||
.any(|p| &p.identifier.name == label && p.labeled)
|
||||
&& !args.labeled.contains_key(label)
|
||||
{
|
||||
let (label, arg) = args.unlabeled.take().unwrap();
|
||||
args.labeled.insert(label.unwrap(), arg);
|
||||
}
|
||||
}
|
||||
|
||||
for (label, arg) in &mut args.labeled {
|
||||
match function_expression.params.iter().find(|p| &p.identifier.name == label) {
|
||||
Some(p) => {
|
||||
@ -1959,10 +1995,11 @@ fn type_check_params_kw(
|
||||
if let Some(arg) = &mut args.unlabeled {
|
||||
if let Some(p) = function_expression.params.iter().find(|p| !p.labeled) {
|
||||
if let Some(ty) = &p.type_ {
|
||||
arg.value = arg
|
||||
arg.1.value = arg
|
||||
.1
|
||||
.value
|
||||
.coerce(
|
||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
|
||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.1.source_range)
|
||||
.map_err(|e| KclError::Semantic(e.into()))?,
|
||||
exec_state,
|
||||
)
|
||||
@ -1974,9 +2011,9 @@ fn type_check_params_kw(
|
||||
.map(|n| format!("`{}`", n))
|
||||
.unwrap_or_else(|| "this function".to_owned()),
|
||||
ty.inner,
|
||||
arg.value.human_friendly_type()
|
||||
arg.1.value.human_friendly_type()
|
||||
),
|
||||
source_ranges: vec![arg.source_range],
|
||||
source_ranges: vec![arg.1.source_range],
|
||||
})
|
||||
})?;
|
||||
}
|
||||
@ -2139,10 +2176,11 @@ impl FunctionSource {
|
||||
if let Some(arg) = &mut args.kw_args.unlabeled {
|
||||
if let Some(p) = ast.params.iter().find(|p| !p.labeled) {
|
||||
if let Some(ty) = &p.type_ {
|
||||
arg.value = arg
|
||||
arg.1.value = arg
|
||||
.1
|
||||
.value
|
||||
.coerce(
|
||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
|
||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.1.source_range)
|
||||
.map_err(|e| KclError::Semantic(e.into()))?,
|
||||
exec_state,
|
||||
)
|
||||
@ -2152,7 +2190,7 @@ impl FunctionSource {
|
||||
"The input argument of {} requires a value with type `{}`, but found {}",
|
||||
props.name,
|
||||
ty.inner,
|
||||
arg.value.human_friendly_type(),
|
||||
arg.1.value.human_friendly_type(),
|
||||
),
|
||||
source_ranges: vec![callsite],
|
||||
})
|
||||
@ -2224,7 +2262,7 @@ impl FunctionSource {
|
||||
.kw_args
|
||||
.unlabeled
|
||||
.as_ref()
|
||||
.map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
|
||||
.map(|arg| OpArg::new(OpKclValue::from(&arg.1.value), arg.1.source_range)),
|
||||
labeled_args: op_labeled_args,
|
||||
},
|
||||
source_range: callsite,
|
||||
@ -2665,13 +2703,12 @@ a = foo()
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_sensible_error_when_missing_equals_in_kwarg() {
|
||||
for (i, call) in ["f(x=1,y)", "f(x=1,3,z)", "f(x=1,y,z=1)", "f(x=1, 3 + 4, z=1)"]
|
||||
for (i, call) in ["f(x=1,3,0)", "f(x=1,3,z)", "f(x=1,0,z=1)", "f(x=1, 3 + 4, z)"]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
let program = format!(
|
||||
"fn foo() {{ return 0 }}
|
||||
y = 42
|
||||
z = 0
|
||||
fn f(x, y, z) {{ return 0 }}
|
||||
{call}"
|
||||
@ -2691,9 +2728,10 @@ fn f(x, y, z) {{ return 0 }}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn default_param_for_unlabeled() {
|
||||
// Tests that the input param for myExtrude is taken from the pipeline value.
|
||||
// Tests that the input param for myExtrude is taken from the pipeline value and same-name
|
||||
// keyword args.
|
||||
let ast = r#"fn myExtrude(@sk, length) {
|
||||
return extrude(sk, length = length)
|
||||
return extrude(sk, length)
|
||||
}
|
||||
sketch001 = startSketchOn(XY)
|
||||
|> circle(center = [0, 0], radius = 93.75)
|
||||
@ -2703,6 +2741,18 @@ sketch001 = startSketchOn(XY)
|
||||
parse_execute(ast).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn dont_use_unlabelled_as_input() {
|
||||
// `length` should be used as the `length` argument to extrude, not the unlabelled input
|
||||
let ast = r#"length = 10
|
||||
startSketchOn(XY)
|
||||
|> circle(center = [0, 0], radius = 93.75)
|
||||
|> extrude(length)
|
||||
"#;
|
||||
|
||||
parse_execute(ast).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn ascription_in_binop() {
|
||||
let ast = r#"foo = tan(0): number(rad) - 4deg"#;
|
||||
|
@ -426,14 +426,14 @@ impl ExecutorContext {
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub async fn new_mock() -> Self {
|
||||
pub async fn new_mock(settings: Option<ExecutorSettings>) -> Self {
|
||||
ExecutorContext {
|
||||
engine: Arc::new(Box::new(
|
||||
crate::engine::conn_mock::EngineConnection::new().await.unwrap(),
|
||||
)),
|
||||
fs: Arc::new(FileManager::new()),
|
||||
stdlib: Arc::new(StdLib::new()),
|
||||
settings: Default::default(),
|
||||
settings: settings.unwrap_or_default(),
|
||||
context_type: ContextType::Mock,
|
||||
}
|
||||
}
|
||||
@ -2232,7 +2232,7 @@ w = f() + f()
|
||||
let result = ctx.run_with_caching(program).await.unwrap();
|
||||
assert_eq!(result.variables.get("x").unwrap().as_f64().unwrap(), 2.0);
|
||||
|
||||
let ctx2 = ExecutorContext::new_mock().await;
|
||||
let ctx2 = ExecutorContext::new_mock(None).await;
|
||||
let program2 = crate::Program::parse_no_errs("z = x + 1").unwrap();
|
||||
let result = ctx2.run_mock(program2, true).await.unwrap();
|
||||
assert_eq!(result.variables.get("z").unwrap().as_f64().unwrap(), 3.0);
|
||||
|
@ -1460,7 +1460,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_idempotent() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
let values = values(&mut exec_state);
|
||||
for v in &values {
|
||||
// Identity subtype
|
||||
@ -1550,7 +1550,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_none() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
let none = KclValue::KclNone {
|
||||
value: crate::parsing::ast::types::KclNone::new(),
|
||||
meta: Vec::new(),
|
||||
@ -1608,7 +1608,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_record() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
|
||||
let obj0 = KclValue::Object {
|
||||
value: HashMap::new(),
|
||||
@ -1690,7 +1690,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_array() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
|
||||
let hom_arr = KclValue::HomArray {
|
||||
value: vec![
|
||||
@ -1843,7 +1843,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_union() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
|
||||
// Subtyping smaller unions
|
||||
assert!(RuntimeType::Union(vec![]).subtype(&RuntimeType::Union(vec![
|
||||
@ -1894,7 +1894,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_axes() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
|
||||
// Subtyping
|
||||
assert!(RuntimeType::Primitive(PrimitiveType::Axis2d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis2d)));
|
||||
@ -2009,7 +2009,7 @@ mod test {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_numeric() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
|
||||
let count = KclValue::Number {
|
||||
value: 1.0,
|
||||
@ -2237,7 +2237,7 @@ d = cos(30)
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn coerce_nested_array() {
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock(None).await);
|
||||
|
||||
let mixed1 = KclValue::HomArray {
|
||||
value: vec![
|
||||
|
@ -4220,8 +4220,8 @@ sketch001 = startSketchOn(XY)
|
||||
result,
|
||||
vec![tower_lsp::lsp_types::ColorInformation {
|
||||
range: tower_lsp::lsp_types::Range {
|
||||
start: tower_lsp::lsp_types::Position { line: 4, character: 24 },
|
||||
end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
|
||||
start: tower_lsp::lsp_types::Position { line: 4, character: 25 },
|
||||
end: tower_lsp::lsp_types::Position { line: 4, character: 32 },
|
||||
},
|
||||
color: tower_lsp::lsp_types::Color {
|
||||
red: 1.0,
|
||||
@ -4272,8 +4272,8 @@ sketch001 = startSketchOn(XY)
|
||||
result,
|
||||
vec![tower_lsp::lsp_types::ColorInformation {
|
||||
range: tower_lsp::lsp_types::Range {
|
||||
start: tower_lsp::lsp_types::Position { line: 4, character: 24 },
|
||||
end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
|
||||
start: tower_lsp::lsp_types::Position { line: 4, character: 25 },
|
||||
end: tower_lsp::lsp_types::Position { line: 4, character: 32 },
|
||||
},
|
||||
color: tower_lsp::lsp_types::Color {
|
||||
red: 1.0,
|
||||
@ -4291,8 +4291,8 @@ sketch001 = startSketchOn(XY)
|
||||
uri: "file:///test.kcl".try_into().unwrap(),
|
||||
},
|
||||
range: tower_lsp::lsp_types::Range {
|
||||
start: tower_lsp::lsp_types::Position { line: 4, character: 24 },
|
||||
end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
|
||||
start: tower_lsp::lsp_types::Position { line: 4, character: 25 },
|
||||
end: tower_lsp::lsp_types::Position { line: 4, character: 32 },
|
||||
},
|
||||
color: tower_lsp::lsp_types::Color {
|
||||
red: 1.0,
|
||||
@ -4316,3 +4316,64 @@ sketch001 = startSketchOn(XY)
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_kcl_lsp_diagnostic_compilation_warnings() {
|
||||
let server = kcl_lsp_server(false).await.unwrap();
|
||||
|
||||
// Send open file.
|
||||
server
|
||||
.did_open(tower_lsp::lsp_types::DidOpenTextDocumentParams {
|
||||
text_document: tower_lsp::lsp_types::TextDocumentItem {
|
||||
uri: "file:///test.kcl".try_into().unwrap(),
|
||||
language_id: "kcl".to_string(),
|
||||
version: 1,
|
||||
text: r#"foo = 42
|
||||
@settings(defaultLengthUnit = mm)"#
|
||||
.to_string(),
|
||||
},
|
||||
})
|
||||
.await;
|
||||
|
||||
// Send diagnostics request.
|
||||
let diagnostics = server
|
||||
.diagnostic(tower_lsp::lsp_types::DocumentDiagnosticParams {
|
||||
text_document: tower_lsp::lsp_types::TextDocumentIdentifier {
|
||||
uri: "file:///test.kcl".try_into().unwrap(),
|
||||
},
|
||||
partial_result_params: Default::default(),
|
||||
work_done_progress_params: Default::default(),
|
||||
identifier: None,
|
||||
previous_result_id: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Check the diagnostics.
|
||||
if let tower_lsp::lsp_types::DocumentDiagnosticReportResult::Report(diagnostics) = diagnostics {
|
||||
if let tower_lsp::lsp_types::DocumentDiagnosticReport::Full(diagnostics) = diagnostics {
|
||||
assert_eq!(diagnostics.full_document_diagnostic_report.items.len(), 1);
|
||||
assert_eq!(
|
||||
diagnostics.full_document_diagnostic_report.items[0],
|
||||
tower_lsp::lsp_types::Diagnostic {
|
||||
range: tower_lsp::lsp_types::Range {
|
||||
start: tower_lsp::lsp_types::Position { line: 0, character: 8 },
|
||||
end: tower_lsp::lsp_types::Position { line: 1, character: 33 },
|
||||
},
|
||||
severity: Some(tower_lsp::lsp_types::DiagnosticSeverity::WARNING),
|
||||
code: None,
|
||||
source: Some("kcl".to_string()),
|
||||
message: "Named attributes should appear before any declarations or expressions.\n\nBecause named attributes apply to the whole function or module, including code written before them, it can be confusing for readers to not have these attributes at the top of code blocks.".to_string(),
|
||||
related_information: None,
|
||||
tags: None,
|
||||
data: None,
|
||||
code_description: None,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
panic!("Expected full diagnostics");
|
||||
}
|
||||
} else {
|
||||
panic!("Expected diagnostics");
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
|
||||
"solid" => Some(include_str!("../std/solid.kcl")),
|
||||
"units" => Some(include_str!("../std/units.kcl")),
|
||||
"array" => Some(include_str!("../std/array.kcl")),
|
||||
"sweep" => Some(include_str!("../std/sweep.kcl")),
|
||||
"transform" => Some(include_str!("../std/transform.kcl")),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ impl<T> Node<T> {
|
||||
self.comment_start = start;
|
||||
}
|
||||
|
||||
pub fn map_ref<'a, U: 'a>(&'a self, f: fn(&'a T) -> U) -> Node<U> {
|
||||
pub fn map_ref<'a, U: 'a>(&'a self, f: impl Fn(&'a T) -> U) -> Node<U> {
|
||||
Node {
|
||||
inner: f(&self.inner),
|
||||
start: self.start,
|
||||
@ -438,8 +438,15 @@ impl Node<Program> {
|
||||
let add_color = |literal: &Node<Literal>| {
|
||||
// Check if the string is a color.
|
||||
if let Some(c) = literal.value.is_color() {
|
||||
let source_range = literal.as_source_range();
|
||||
// We subtract 1 from either side because of the "'s in the literal.
|
||||
let fixed_source_range = SourceRange::new(
|
||||
source_range.start() + 1,
|
||||
source_range.end() - 1,
|
||||
source_range.module_id(),
|
||||
);
|
||||
let color = ColorInformation {
|
||||
range: literal.as_source_range().to_lsp_range(code),
|
||||
range: fixed_source_range.to_lsp_range(code),
|
||||
color: tower_lsp::lsp_types::Color {
|
||||
red: c.r,
|
||||
green: c.g,
|
||||
@ -498,7 +505,11 @@ impl Node<Program> {
|
||||
crate::walk::walk(self, |node: crate::walk::Node<'a>| {
|
||||
match node {
|
||||
crate::walk::Node::Literal(literal) => {
|
||||
if literal.start == pos_start && literal.end == pos_end && literal.value.is_color().is_some() {
|
||||
// Account for the quotes in the literal.
|
||||
if (literal.start + 1) == pos_start
|
||||
&& (literal.end - 1) == pos_end
|
||||
&& literal.value.is_color().is_some()
|
||||
{
|
||||
found.replace(true);
|
||||
return Ok(true);
|
||||
}
|
||||
@ -1187,7 +1198,7 @@ impl Expr {
|
||||
|
||||
pub fn ident_name(&self) -> Option<&str> {
|
||||
match self {
|
||||
Expr::Name(ident) => Some(&ident.name.name),
|
||||
Expr::Name(name) => name.local_ident().map(|n| n.inner),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -2371,7 +2382,7 @@ impl Name {
|
||||
|
||||
pub fn local_ident(&self) -> Option<Node<&str>> {
|
||||
if self.path.is_empty() && !self.abs_path {
|
||||
Some(self.name.map_ref(|n| &n.name))
|
||||
Some(self.name.map_ref(|n| &*n.name))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -2729,6 +2729,17 @@ fn ty(i: &mut TokenSlice) -> PResult<Token> {
|
||||
keyword(i, "type")
|
||||
}
|
||||
|
||||
fn any_keyword(i: &mut TokenSlice) -> PResult<Token> {
|
||||
any.try_map(|token: Token| match token.token_type {
|
||||
TokenType::Keyword => Ok(token),
|
||||
_ => Err(CompilationError::fatal(
|
||||
token.as_source_range(),
|
||||
"expected some reserved keyword".to_owned(),
|
||||
)),
|
||||
})
|
||||
.parse_next(i)
|
||||
}
|
||||
|
||||
fn keyword(i: &mut TokenSlice, expected: &str) -> PResult<Token> {
|
||||
any.try_map(|token: Token| match token.token_type {
|
||||
TokenType::Keyword if token.value == expected => Ok(token),
|
||||
@ -3143,12 +3154,14 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
|
||||
NonCode(Node<NonCodeNode>),
|
||||
LabeledArg(LabeledArg),
|
||||
UnlabeledArg(Expr),
|
||||
Keyword(Token),
|
||||
}
|
||||
let initial_unlabeled_arg = opt((expression, comma, opt(whitespace)).map(|(arg, _, _)| arg)).parse_next(i)?;
|
||||
let args: Vec<_> = repeat(
|
||||
0..,
|
||||
alt((
|
||||
terminated(non_code_node.map(ArgPlace::NonCode), whitespace),
|
||||
terminated(any_keyword.map(ArgPlace::Keyword), whitespace),
|
||||
terminated(labeled_argument, labeled_arg_separator).map(ArgPlace::LabeledArg),
|
||||
expression.map(ArgPlace::UnlabeledArg),
|
||||
)),
|
||||
@ -3164,6 +3177,18 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
|
||||
ArgPlace::LabeledArg(x) => {
|
||||
args.push(x);
|
||||
}
|
||||
ArgPlace::Keyword(kw) => {
|
||||
return Err(ErrMode::Cut(
|
||||
CompilationError::fatal(
|
||||
SourceRange::from(kw.clone()),
|
||||
format!(
|
||||
"`{}` is not the name of an argument (it's a reserved keyword)",
|
||||
kw.value
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
ArgPlace::UnlabeledArg(arg) => {
|
||||
let followed_by_equals = peek((opt(whitespace), equals)).parse_next(i).is_ok();
|
||||
if followed_by_equals {
|
||||
@ -5055,6 +5080,30 @@ bar = 1
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sensible_error_when_using_keyword_as_arg_label() {
|
||||
for (i, program) in ["pow(2, fn = 8)"].into_iter().enumerate() {
|
||||
let tokens = crate::parsing::token::lex(program, ModuleId::default()).unwrap();
|
||||
let err = match fn_call_kw.parse(tokens.as_slice()) {
|
||||
Err(e) => e,
|
||||
Ok(ast) => {
|
||||
eprintln!("{ast:#?}");
|
||||
panic!("Expected this to error but it didn't");
|
||||
}
|
||||
};
|
||||
let cause = err.inner().cause.as_ref().unwrap();
|
||||
assert_eq!(
|
||||
cause.message, "`fn` is not the name of an argument (it's a reserved keyword)",
|
||||
"failed test {i}: {program}"
|
||||
);
|
||||
assert_eq!(
|
||||
cause.source_range.start(),
|
||||
program.find("fn").unwrap(),
|
||||
"failed test {i}: {program}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sensible_error_when_missing_rhs_of_obj_property() {
|
||||
for (i, program) in ["{x = 1, y =}"].into_iter().enumerate() {
|
||||
|
@ -1669,7 +1669,6 @@ mod mike_stress_test {
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[ignore = "when kurt made the artifact graph lots of commands, this became super slow and sometimes the engine will just die, turn this back on when we can parallelize the simulation tests with snapshots deterministically"]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
@ -2749,7 +2748,6 @@ mod import_mesh_clone {
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[ignore = "turn on when katie fixes the mesh import"]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
@ -2772,6 +2770,7 @@ mod clone_w_fillets {
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[ignore] // turn on when https://github.com/KittyCAD/engine/pull/3380 is merged
|
||||
// Theres also a test in clone.rs you need to turn too
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
@ -3071,3 +3070,45 @@ mod error_inside_fn_also_has_source_range_of_call_site_recursive {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
}
|
||||
mod error_revolve_on_edge_get_edge {
|
||||
const TEST_NAME: &str = "error_revolve_on_edge_get_edge";
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn unparse() {
|
||||
super::unparse(TEST_NAME).await
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
}
|
||||
mod sketch_on_face_union {
|
||||
const TEST_NAME: &str = "sketch_on_face_union";
|
||||
|
||||
/// Test parsing KCL.
|
||||
#[test]
|
||||
fn parse() {
|
||||
super::parse(TEST_NAME)
|
||||
}
|
||||
|
||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn unparse() {
|
||||
super::unparse(TEST_NAME).await
|
||||
}
|
||||
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,9 @@ impl Arg {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct KwArgs {
|
||||
/// Unlabeled keyword args. Currently only the first arg can be unlabeled.
|
||||
pub unlabeled: Option<Arg>,
|
||||
/// If the argument was a local variable, then the first element of the tuple is its name
|
||||
/// which may be used to treat this arg as a labelled arg.
|
||||
pub unlabeled: Option<(Option<String>, Arg)>,
|
||||
/// Labeled args.
|
||||
pub labeled: IndexMap<String, Arg>,
|
||||
pub errors: Vec<Arg>,
|
||||
@ -342,6 +344,7 @@ impl Args {
|
||||
self.kw_args
|
||||
.unlabeled
|
||||
.as_ref()
|
||||
.map(|(_, a)| a)
|
||||
.or(self.args.first())
|
||||
.or(self.pipe_value.as_ref())
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ async fn call_map_closure(
|
||||
ctxt: &ExecutorContext,
|
||||
) -> Result<KclValue, KclError> {
|
||||
let kw_args = KwArgs {
|
||||
unlabeled: Some(Arg::new(input, source_range)),
|
||||
unlabeled: Some((None, Arg::new(input, source_range))),
|
||||
labeled: Default::default(),
|
||||
errors: Vec::new(),
|
||||
};
|
||||
@ -104,7 +104,7 @@ async fn call_reduce_closure(
|
||||
let mut labeled = IndexMap::with_capacity(1);
|
||||
labeled.insert("accum".to_string(), Arg::new(accum, source_range));
|
||||
let kw_args = KwArgs {
|
||||
unlabeled: Some(Arg::new(elem, source_range)),
|
||||
unlabeled: Some((None, Arg::new(elem, source_range))),
|
||||
labeled,
|
||||
errors: Vec::new(),
|
||||
};
|
||||
|
@ -177,25 +177,6 @@ async fn get_old_new_child_map(
|
||||
exec_state: &mut ExecState,
|
||||
args: &Args,
|
||||
) -> Result<HashMap<uuid::Uuid, uuid::Uuid>> {
|
||||
// Get the new geometries entity ids.
|
||||
let response = args
|
||||
.send_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
ModelingCmd::from(mcmd::EntityGetAllChildUuids {
|
||||
entity_id: new_geometry_id,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response:
|
||||
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids {
|
||||
entity_ids: new_entity_ids,
|
||||
}),
|
||||
} = response
|
||||
else {
|
||||
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
|
||||
};
|
||||
|
||||
// Get the old geometries entity ids.
|
||||
let response = args
|
||||
.send_modeling_cmd(
|
||||
@ -215,6 +196,25 @@ async fn get_old_new_child_map(
|
||||
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
|
||||
};
|
||||
|
||||
// Get the new geometries entity ids.
|
||||
let response = args
|
||||
.send_modeling_cmd(
|
||||
exec_state.next_uuid(),
|
||||
ModelingCmd::from(mcmd::EntityGetAllChildUuids {
|
||||
entity_id: new_geometry_id,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
let OkWebSocketResponseData::Modeling {
|
||||
modeling_response:
|
||||
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids {
|
||||
entity_ids: new_entity_ids,
|
||||
}),
|
||||
} = response
|
||||
else {
|
||||
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
|
||||
};
|
||||
|
||||
// Create a map of old entity ids to new entity ids.
|
||||
Ok(HashMap::from_iter(
|
||||
old_entity_ids
|
||||
|
@ -14,7 +14,7 @@ use super::{args::TyF64, DEFAULT_TOLERANCE};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{types::RuntimeType, ExecState, KclValue, Solid},
|
||||
std::Args,
|
||||
std::{patterns::GeometryTrait, Args},
|
||||
};
|
||||
|
||||
/// Union two or more solids into a single solid.
|
||||
@ -123,7 +123,7 @@ pub(crate) async fn inner_union(
|
||||
let solid_out_id = exec_state.next_uuid();
|
||||
|
||||
let mut solid = solids[0].clone();
|
||||
solid.id = solid_out_id;
|
||||
solid.set_id(solid_out_id);
|
||||
let mut new_solids = vec![solid.clone()];
|
||||
|
||||
if args.ctx.no_engine_commands().await {
|
||||
@ -155,7 +155,7 @@ pub(crate) async fn inner_union(
|
||||
|
||||
// If we have more solids, set those as well.
|
||||
if !extra_solid_ids.is_empty() {
|
||||
solid.id = extra_solid_ids[0];
|
||||
solid.set_id(extra_solid_ids[0]);
|
||||
new_solids.push(solid.clone());
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ pub(crate) async fn inner_intersect(
|
||||
let solid_out_id = exec_state.next_uuid();
|
||||
|
||||
let mut solid = solids[0].clone();
|
||||
solid.id = solid_out_id;
|
||||
solid.set_id(solid_out_id);
|
||||
let mut new_solids = vec![solid.clone()];
|
||||
|
||||
if args.ctx.no_engine_commands().await {
|
||||
@ -281,7 +281,7 @@ pub(crate) async fn inner_intersect(
|
||||
|
||||
// If we have more solids, set those as well.
|
||||
if !extra_solid_ids.is_empty() {
|
||||
solid.id = extra_solid_ids[0];
|
||||
solid.set_id(extra_solid_ids[0]);
|
||||
new_solids.push(solid.clone());
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ pub(crate) async fn inner_subtract(
|
||||
let solid_out_id = exec_state.next_uuid();
|
||||
|
||||
let mut solid = solids[0].clone();
|
||||
solid.id = solid_out_id;
|
||||
solid.set_id(solid_out_id);
|
||||
let mut new_solids = vec![solid.clone()];
|
||||
|
||||
if args.ctx.no_engine_commands().await {
|
||||
@ -419,7 +419,7 @@ pub(crate) async fn inner_subtract(
|
||||
|
||||
// If we have more solids, set those as well.
|
||||
if !extra_solid_ids.is_empty() {
|
||||
solid.id = extra_solid_ids[0];
|
||||
solid.set_id(extra_solid_ids[0]);
|
||||
new_solids.push(solid.clone());
|
||||
}
|
||||
|
||||
|
@ -424,7 +424,7 @@ async fn make_transform<T: GeometryTrait>(
|
||||
meta: vec![source_range.into()],
|
||||
};
|
||||
let kw_args = KwArgs {
|
||||
unlabeled: Some(Arg::new(repetition_num, source_range)),
|
||||
unlabeled: Some((None, Arg::new(repetition_num, source_range))),
|
||||
labeled: Default::default(),
|
||||
errors: Vec::new(),
|
||||
};
|
||||
@ -598,7 +598,7 @@ fn array_to_point2d(
|
||||
.map(|val| val.as_point2d().unwrap())
|
||||
}
|
||||
|
||||
trait GeometryTrait: Clone {
|
||||
pub trait GeometryTrait: Clone {
|
||||
type Set: Into<Vec<Self>> + Clone;
|
||||
fn id(&self) -> Uuid;
|
||||
fn original_id(&self) -> Uuid;
|
||||
@ -608,6 +608,7 @@ trait GeometryTrait: Clone {
|
||||
source_ranges: Vec<SourceRange>,
|
||||
exec_state: &mut ExecState,
|
||||
) -> Result<[TyF64; 3], KclError>;
|
||||
#[allow(async_fn_in_trait)]
|
||||
async fn flush_batch(args: &Args, exec_state: &mut ExecState, set: &Self::Set) -> Result<(), KclError>;
|
||||
}
|
||||
|
||||
@ -641,6 +642,8 @@ impl GeometryTrait for Solid {
|
||||
type Set = Vec<Solid>;
|
||||
fn set_id(&mut self, id: Uuid) {
|
||||
self.id = id;
|
||||
// We need this for in extrude.rs when you sketch on face.
|
||||
self.sketch.id = id;
|
||||
}
|
||||
|
||||
fn id(&self) -> Uuid {
|
||||
@ -671,7 +674,7 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_array_to_point3d() {
|
||||
let mut exec_state = ExecState::new(&ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&ExecutorContext::new_mock(None).await);
|
||||
let input = KclValue::HomArray {
|
||||
value: vec![
|
||||
KclValue::Number {
|
||||
@ -703,7 +706,7 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_tuple_to_point3d() {
|
||||
let mut exec_state = ExecState::new(&ExecutorContext::new_mock().await);
|
||||
let mut exec_state = ExecState::new(&ExecutorContext::new_mock(None).await);
|
||||
let input = KclValue::Tuple {
|
||||
value: vec![
|
||||
KclValue::Number {
|
||||
|
@ -3,7 +3,7 @@
|
||||
use anyhow::Result;
|
||||
use kcl_derive_docs::stdlib;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||
use kittycad_modeling_cmds::{self as kcmc};
|
||||
use kittycad_modeling_cmds::{self as kcmc, shared::RelativeTo};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -37,11 +37,20 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
)?;
|
||||
let sectional = args.get_kw_arg_opt("sectional")?;
|
||||
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?;
|
||||
let relative_to: Option<String> = args.get_kw_arg_opt_typed("relativeTo", &RuntimeType::string(), exec_state)?;
|
||||
let tag_start = args.get_kw_arg_opt("tagStart")?;
|
||||
let tag_end = args.get_kw_arg_opt("tagEnd")?;
|
||||
|
||||
let value = inner_sweep(
|
||||
sketches, path, sectional, tolerance, tag_start, tag_end, exec_state, args,
|
||||
sketches,
|
||||
path,
|
||||
sectional,
|
||||
tolerance,
|
||||
relative_to,
|
||||
tag_start,
|
||||
tag_end,
|
||||
exec_state,
|
||||
args,
|
||||
)
|
||||
.await?;
|
||||
Ok(value.into())
|
||||
@ -103,7 +112,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(YZ)
|
||||
/// |> circle( center = [0, 0], radius = 1)
|
||||
/// |> sweep(path = helixPath)
|
||||
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
@ -158,6 +167,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
path = { docs = "The path to sweep the sketch along" },
|
||||
sectional = { docs = "If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components." },
|
||||
tolerance = { docs = "Tolerance for this operation" },
|
||||
relative_to = { docs = "What is the sweep relative to? Can be either 'sketchPlane' or 'trajectoryCurve'. Defaults to trajectoryCurve."},
|
||||
tag_start = { docs = "A named tag for the face at the start of the sweep, i.e. the original sketch" },
|
||||
tag_end = { docs = "A named tag for the face at the end of the sweep" },
|
||||
},
|
||||
@ -169,6 +179,7 @@ async fn inner_sweep(
|
||||
path: SweepPath,
|
||||
sectional: Option<bool>,
|
||||
tolerance: Option<TyF64>,
|
||||
relative_to: Option<String>,
|
||||
tag_start: Option<TagNode>,
|
||||
tag_end: Option<TagNode>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -178,6 +189,16 @@ async fn inner_sweep(
|
||||
SweepPath::Sketch(sketch) => sketch.id.into(),
|
||||
SweepPath::Helix(helix) => helix.value.into(),
|
||||
};
|
||||
let relative_to = match relative_to.as_deref() {
|
||||
Some("sketchPlane") => RelativeTo::SketchPlane,
|
||||
Some("trajectoryCurve") | None => RelativeTo::TrajectoryCurve,
|
||||
Some(_) => {
|
||||
return Err(KclError::Syntax(crate::errors::KclErrorDetails {
|
||||
source_ranges: vec![args.source_range],
|
||||
message: "If you provide relativeTo, it must either be 'sketchPlane' or 'trajectoryCurve'".to_owned(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
|
||||
let mut solids = Vec::new();
|
||||
for sketch in &sketches {
|
||||
@ -189,6 +210,7 @@ async fn inner_sweep(
|
||||
trajectory,
|
||||
sectional: sectional.unwrap_or(false),
|
||||
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
|
||||
relative_to,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
@ -267,7 +267,7 @@ import \"a.kcl\"
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let ctx = ExecutorContext::new_mock(None).await;
|
||||
let order = import_graph(&modules, &ctx).unwrap();
|
||||
assert_eq!(vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned()]], order);
|
||||
}
|
||||
@ -290,7 +290,7 @@ x = 1
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let ctx = ExecutorContext::new_mock(None).await;
|
||||
let order = import_graph(&modules, &ctx).unwrap();
|
||||
assert_eq!(vec![vec!["a.kcl".to_owned(), "b.kcl".to_owned()]], order);
|
||||
}
|
||||
@ -316,7 +316,7 @@ import \"a.kcl\"
|
||||
);
|
||||
modules.insert("c.kcl".to_owned(), into_module_info(c));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let ctx = ExecutorContext::new_mock(None).await;
|
||||
let order = import_graph(&modules, &ctx).unwrap();
|
||||
assert_eq!(
|
||||
vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned(), "c.kcl".to_owned()]],
|
||||
@ -342,7 +342,7 @@ import \"a.kcl\"
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let ctx = ExecutorContext::new_mock(None).await;
|
||||
import_graph(&modules, &ctx).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ export import * from "std::sketch"
|
||||
export import * from "std::solid"
|
||||
export import * from "std::transform"
|
||||
export import "std::turns"
|
||||
export import "std::sweep"
|
||||
|
||||
/// An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis.
|
||||
export XY = {
|
||||
@ -83,7 +84,7 @@ export END = 'end'
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(YZ)
|
||||
/// |> circle( center = [0, 0], radius = 0.5)
|
||||
/// |> sweep(path = helixPath)
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
@ -104,7 +105,7 @@ export END = 'end'
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(XY)
|
||||
/// |> circle( center = [0, 0], radius = 0.5 )
|
||||
/// |> sweep(path = helixPath)
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
@ -124,7 +125,7 @@ export END = 'end'
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(XY)
|
||||
/// |> circle( center = [0, 0], radius = 1 )
|
||||
/// |> sweep(path = helixPath)
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
@ -413,7 +414,7 @@ export fn offsetPlane(
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// sweepedSpring = clone(springSketch)
|
||||
/// |> translate(x=100)
|
||||
/// |> sweep(path = helixPath)
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// ```
|
||||
///
|
||||
/// ```kcl
|
||||
|
5
rust/kcl-lib/std/sweep.kcl
Normal file
5
rust/kcl-lib/std/sweep.kcl
Normal file
@ -0,0 +1,5 @@
|
||||
/// Local/relative to the trajectory curve
|
||||
export TRAJECTORY = 'trajectoryCurve'
|
||||
|
||||
/// Local/relative to a position centered within the plane being sketched on
|
||||
export SKETCH_PLANE = 'sketchPlane'
|
@ -0,0 +1,349 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Artifact commands error_revolve_on_edge_get_edge.kcl
|
||||
---
|
||||
[
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "edge_lines_visible",
|
||||
"hidden": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_visible",
|
||||
"object_id": "[uuid]",
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_visible",
|
||||
"object_id": "[uuid]",
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "make_plane",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"x_axis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"y_axis": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"size": 60.0,
|
||||
"clobber": false,
|
||||
"hide": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "enable_sketch_mode",
|
||||
"entity_id": "[uuid]",
|
||||
"ortho": false,
|
||||
"animated": false,
|
||||
"adjust_camera": false,
|
||||
"planar_normal": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "move_path_pen",
|
||||
"path": "[uuid]",
|
||||
"to": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "sketch_mode_disable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "start_path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extend_path",
|
||||
"path": "[uuid]",
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 0.0,
|
||||
"y": 10.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extend_path",
|
||||
"path": "[uuid]",
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 10.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extend_path",
|
||||
"path": "[uuid]",
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 0.0,
|
||||
"y": -10.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "close_path",
|
||||
"path_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "enable_sketch_mode",
|
||||
"entity_id": "[uuid]",
|
||||
"ortho": false,
|
||||
"animated": false,
|
||||
"adjust_camera": false,
|
||||
"planar_normal": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extrude",
|
||||
"target": "[uuid]",
|
||||
"distance": 10.0,
|
||||
"faces": null,
|
||||
"opposite": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_bring_to_front",
|
||||
"object_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "sketch_mode_disable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "solid3d_get_adjacency_info",
|
||||
"object_id": "[uuid]",
|
||||
"edge_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "solid3d_get_extrusion_face_info",
|
||||
"object_id": "[uuid]",
|
||||
"edge_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "enable_sketch_mode",
|
||||
"entity_id": "[uuid]",
|
||||
"ortho": false,
|
||||
"animated": false,
|
||||
"adjust_camera": false,
|
||||
"planar_normal": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "move_path_pen",
|
||||
"path": "[uuid]",
|
||||
"to": {
|
||||
"x": 5.0,
|
||||
"y": 10.0,
|
||||
"z": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "sketch_mode_disable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "start_path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extend_path",
|
||||
"path": "[uuid]",
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 0.0,
|
||||
"y": -10.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extend_path",
|
||||
"path": "[uuid]",
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 2.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "extend_path",
|
||||
"path": "[uuid]",
|
||||
"segment": {
|
||||
"type": "line",
|
||||
"end": {
|
||||
"x": 0.0,
|
||||
"y": 10.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"relative": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "close_path",
|
||||
"path_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_bring_to_front",
|
||||
"object_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "revolve_about_edge",
|
||||
"target": "[uuid]",
|
||||
"edge_id": "[uuid]",
|
||||
"angle": {
|
||||
"unit": "degrees",
|
||||
"value": 90.0
|
||||
},
|
||||
"tolerance": 0.0000001,
|
||||
"opposite": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "solid3d_get_extrusion_face_info",
|
||||
"object_id": "[uuid]",
|
||||
"edge_id": "[uuid]"
|
||||
}
|
||||
}
|
||||
]
|
937
rust/kcl-lib/tests/error_revolve_on_edge_get_edge/ast.snap
Normal file
937
rust/kcl-lib/tests/error_revolve_on_edge_get_edge/ast.snap
Normal file
@ -0,0 +1,937 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of parsing error_revolve_on_edge_get_edge.kcl
|
||||
---
|
||||
{
|
||||
"Ok": {
|
||||
"body": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "box",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "startSketchOn",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "XY",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "at",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "startProfile",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "end",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "line",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "end",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "line",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "end",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"argument": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"operator": "-",
|
||||
"start": 0,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "tag",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "TagDeclarator",
|
||||
"type": "TagDeclarator",
|
||||
"value": "revolveAxis"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "line",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "close",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "length",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "extrude",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "sketch001",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"body": [
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "face",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "revolveAxis",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "startSketchOn",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "box",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "at",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "5",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 5.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "startProfile",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "end",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"argument": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"operator": "-",
|
||||
"start": 0,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "line",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "end",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "line",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "end",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "10",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 10.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "line",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "close",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "axis",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "revolveAxis",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "angle",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "90",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 90.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "revolve",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"nonCodeMeta": {
|
||||
"nonCodeNodes": {
|
||||
"0": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"startNodes": []
|
||||
},
|
||||
"start": 0
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Error from executing error_revolve_on_edge_get_edge.kcl
|
||||
---
|
||||
KCL Engine error
|
||||
|
||||
× engine: Solid3D revolve failed: sketch profile must lie entirely on one
|
||||
│ side of the revolution axis
|
||||
╭─[15:6]
|
||||
14 │ |> close()
|
||||
15 │ |> revolve(axis = revolveAxis, angle = 90)
|
||||
· ───────────────────┬───────────────────┬
|
||||
· ╰── tests/error_revolve_on_edge_get_edge/input.kcl
|
||||
· ╰── tests/error_revolve_on_edge_get_edge/input.kcl
|
||||
╰────
|
||||
╰─▶ KCL Engine error
|
||||
|
||||
× engine: Solid3D revolve failed: sketch profile must lie entirely on
|
||||
│ one side of the revolution axis
|
||||
╭─[15:6]
|
||||
14 │ |> close()
|
||||
15 │ |> revolve(axis = revolveAxis, angle = 90)
|
||||
· ───────────────────┬───────────────────
|
||||
· ╰── tests/error_revolve_on_edge_get_edge/
|
||||
input.kcl
|
||||
╰────
|
15
rust/kcl-lib/tests/error_revolve_on_edge_get_edge/input.kcl
Normal file
15
rust/kcl-lib/tests/error_revolve_on_edge_get_edge/input.kcl
Normal file
@ -0,0 +1,15 @@
|
||||
box = startSketchOn(XY)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [0, -10], tag = $revolveAxis)
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|
||||
sketch001 = startSketchOn(box, face = revolveAxis)
|
||||
|> startProfile(at = [5, 10])
|
||||
|> line(end = [0, -10])
|
||||
|> line(end = [2, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> close()
|
||||
|> revolve(axis = revolveAxis, angle = 90)
|
116
rust/kcl-lib/tests/error_revolve_on_edge_get_edge/ops.snap
Normal file
116
rust/kcl-lib/tests/error_revolve_on_edge_get_edge/ops.snap
Normal file
@ -0,0 +1,116 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Operations executed error_revolve_on_edge_get_edge.kcl
|
||||
---
|
||||
[
|
||||
{
|
||||
"labeledArgs": {},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Plane",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 10.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"face": {
|
||||
"value": {
|
||||
"type": "TagIdentifier",
|
||||
"value": "revolveAxis",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "KclStdLibCall",
|
||||
"name": "revolve",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
"labeledArgs": {
|
||||
"angle": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 90.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
"axis": {
|
||||
"value": {
|
||||
"type": "TagIdentifier",
|
||||
"value": "revolveAxis",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"sourceRange": [],
|
||||
"isError": true
|
||||
}
|
||||
]
|
@ -0,0 +1,19 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing error_revolve_on_edge_get_edge.kcl
|
||||
---
|
||||
box = startSketchOn(XY)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [0, -10], tag = $revolveAxis)
|
||||
|> close()
|
||||
|> extrude(length = 10)
|
||||
|
||||
sketch001 = startSketchOn(box, face = revolveAxis)
|
||||
|> startProfile(at = [5, 10])
|
||||
|> line(end = [0, -10])
|
||||
|> line(end = [2, 0])
|
||||
|> line(end = [0, 10])
|
||||
|> close()
|
||||
|> revolve(axis = revolveAxis, angle = 90)
|
@ -4,9 +4,8 @@ description: Error from executing execute_engine_error_return.kcl
|
||||
---
|
||||
KCL Engine error
|
||||
|
||||
× engine: Modeling command failed: [ApiError { error_code: BadRequest,
|
||||
│ message: "The path is not closed. Solid2D construction requires a closed
|
||||
│ path!" }]
|
||||
× engine: The path is not closed. Solid2D construction requires a closed
|
||||
│ path!
|
||||
╭─[7:6]
|
||||
6 │ |> line(end = [-11.53311, 2.81559])
|
||||
7 │ |> extrude(length = 4)
|
||||
|
@ -996,10 +996,51 @@ description: Artifact commands import_mesh_clone.kcl
|
||||
"direction": "positive"
|
||||
}
|
||||
},
|
||||
"units": "mm"
|
||||
"units": "m"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "set_object_transform",
|
||||
"object_id": "[uuid]",
|
||||
"transforms": [
|
||||
{
|
||||
"translate": {
|
||||
"property": {
|
||||
"x": -2000.0,
|
||||
"y": -2000.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"set": false,
|
||||
"is_local": true
|
||||
},
|
||||
"rotate_rpy": null,
|
||||
"rotate_angle_axis": null,
|
||||
"scale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_set_material_params_pbr",
|
||||
"object_id": "[uuid]",
|
||||
"color": {
|
||||
"r": 1.0,
|
||||
"g": 1.0,
|
||||
"b": 0.0,
|
||||
"a": 100.0
|
||||
},
|
||||
"metalness": 0.0,
|
||||
"roughness": 0.0,
|
||||
"ambient_occlusion": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
@ -1015,5 +1056,184 @@ description: Artifact commands import_mesh_clone.kcl
|
||||
"type": "entity_get_all_child_uuids",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_get_all_child_uuids",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "set_object_transform",
|
||||
"object_id": "[uuid]",
|
||||
"transforms": [
|
||||
{
|
||||
"translate": {
|
||||
"property": {
|
||||
"x": 4000.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"set": false,
|
||||
"is_local": true
|
||||
},
|
||||
"rotate_rpy": null,
|
||||
"rotate_angle_axis": null,
|
||||
"scale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_set_material_params_pbr",
|
||||
"object_id": "[uuid]",
|
||||
"color": {
|
||||
"r": 1.0,
|
||||
"g": 0.0,
|
||||
"b": 0.0,
|
||||
"a": 100.0
|
||||
},
|
||||
"metalness": 0.0,
|
||||
"roughness": 0.0,
|
||||
"ambient_occlusion": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_clone",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_get_all_child_uuids",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_get_all_child_uuids",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "set_object_transform",
|
||||
"object_id": "[uuid]",
|
||||
"transforms": [
|
||||
{
|
||||
"translate": {
|
||||
"property": {
|
||||
"x": 0.0,
|
||||
"y": 4000.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"set": false,
|
||||
"is_local": true
|
||||
},
|
||||
"rotate_rpy": null,
|
||||
"rotate_angle_axis": null,
|
||||
"scale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_set_material_params_pbr",
|
||||
"object_id": "[uuid]",
|
||||
"color": {
|
||||
"r": 0.0,
|
||||
"g": 1.0,
|
||||
"b": 0.0,
|
||||
"a": 100.0
|
||||
},
|
||||
"metalness": 0.0,
|
||||
"roughness": 0.0,
|
||||
"ambient_occlusion": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_clone",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_get_all_child_uuids",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "entity_get_all_child_uuids",
|
||||
"entity_id": "[uuid]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "set_object_transform",
|
||||
"object_id": "[uuid]",
|
||||
"transforms": [
|
||||
{
|
||||
"translate": {
|
||||
"property": {
|
||||
"x": 0.0,
|
||||
"y": 4000.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"set": false,
|
||||
"is_local": true
|
||||
},
|
||||
"rotate_rpy": null,
|
||||
"rotate_angle_axis": null,
|
||||
"scale": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cmdId": "[uuid]",
|
||||
"range": [],
|
||||
"command": {
|
||||
"type": "object_set_material_params_pbr",
|
||||
"object_id": "[uuid]",
|
||||
"color": {
|
||||
"r": 0.0,
|
||||
"g": 0.0,
|
||||
"b": 1.0,
|
||||
"a": 100.0
|
||||
},
|
||||
"metalness": 0.0,
|
||||
"roughness": 0.0,
|
||||
"ambient_occlusion": 0.0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -8,6 +8,46 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"outerAttrs": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": null,
|
||||
"properties": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"key": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "lengthUnit",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ObjectProperty",
|
||||
"value": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "m",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
}
|
||||
],
|
||||
"start": 0,
|
||||
"type": "Annotation"
|
||||
}
|
||||
],
|
||||
"path": {
|
||||
"type": "Foreign",
|
||||
"path": "../inputs/cube.obj"
|
||||
@ -17,7 +57,7 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"alias": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "cube",
|
||||
"name": "yellow",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
}
|
||||
@ -27,25 +67,18 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"type": "ImportStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "model",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"expression": {
|
||||
"body": [
|
||||
{
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "cube",
|
||||
"name": "yellow",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
@ -54,14 +87,173 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"name": "x",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"argument": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "2000",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2000.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"operator": "-",
|
||||
"start": 0,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "y",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"argument": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "2000",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2000.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"operator": "-",
|
||||
"start": 0,
|
||||
"type": "UnaryExpression",
|
||||
"type": "UnaryExpression"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "translate",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "color",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "\"#ffff00\"",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "#ffff00"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "appearance",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "yellow",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
@ -71,7 +263,7 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "model2",
|
||||
"name": "red",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
@ -105,7 +297,7 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "model",
|
||||
"name": "yellow",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
@ -129,12 +321,12 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "1020",
|
||||
"raw": "4000",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1020.0,
|
||||
"value": 4000.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
@ -160,9 +352,34 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
"unlabeled": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
@ -182,50 +399,6 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"type": "Literal",
|
||||
"value": "#ff0000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "metalness",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "50",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 50.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "roughness",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "50",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 50.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
@ -248,7 +421,131 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": null
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "red",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "green",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "clone",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "yellow",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "y",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "4000",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 4000.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "translate",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
@ -265,6 +562,259 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "color",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "\"#00ff00\"",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "#00ff00"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "appearance",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "green",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "blue",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"body": [
|
||||
{
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "clone",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "red",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "y",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "4000",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 4000.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "translate",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeSubstitution",
|
||||
"type": "PipeSubstitution"
|
||||
}
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "PipeExpression",
|
||||
"type": "PipeExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"expression": {
|
||||
"arguments": [
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "color",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"arg": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"raw": "\"#0000ff\"",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": "#0000ff"
|
||||
}
|
||||
}
|
||||
],
|
||||
"callee": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "appearance",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name"
|
||||
},
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "CallExpressionKw",
|
||||
"type": "CallExpressionKw",
|
||||
"unlabeled": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "blue",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"path": [],
|
||||
"start": 0,
|
||||
"type": "Name",
|
||||
"type": "Name"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "ExpressionStatement",
|
||||
"type": "ExpressionStatement"
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
@ -282,7 +832,29 @@ description: Result of parsing import_mesh_clone.kcl
|
||||
}
|
||||
}
|
||||
],
|
||||
"1": [
|
||||
"2": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
}
|
||||
}
|
||||
],
|
||||
"4": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"start": 0,
|
||||
"type": "NonCodeNode",
|
||||
"value": {
|
||||
"type": "newLine"
|
||||
}
|
||||
}
|
||||
],
|
||||
"6": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Error from executing import_mesh_clone.kcl
|
||||
---
|
||||
KCL Internal error
|
||||
|
||||
× internal: failed to fix tags and references: engine: KclErrorDetails
|
||||
│ { source_ranges: [SourceRange([60, 72, 0])], message: "Modeling command
|
||||
│ failed: [ApiError { error_code: BadRequest, message: \"Entity type does
|
||||
│ not currently support transform patterns.\" }, ApiError { error_code:
|
||||
│ InternalEngine, message: \"Failed to clone entity.\" }, ApiError
|
||||
│ { error_code: InternalEngine, message: \"Failed to clone entity\" }]" }
|
||||
╭─[5:10]
|
||||
4 │
|
||||
5 │ model2 = clone(model)
|
||||
· ──────┬─────
|
||||
· ╰── tests/import_mesh_clone/input.kcl
|
||||
6 │ |> translate(
|
||||
╰────
|
@ -1,13 +1,18 @@
|
||||
import "../inputs/cube.obj" as cube
|
||||
@(lengthUnit = m)
|
||||
import "../inputs/cube.obj" as yellow
|
||||
|
||||
model = cube
|
||||
yellow
|
||||
|> translate(%, x = -2000, y = -2000)
|
||||
appearance(yellow, color = "#ffff00")
|
||||
|
||||
model2 = clone(model)
|
||||
|> translate(
|
||||
x = 1020,
|
||||
)
|
||||
|> appearance(
|
||||
color = "#ff0000",
|
||||
metalness = 50,
|
||||
roughness = 50
|
||||
)
|
||||
red = clone(yellow)
|
||||
|> translate(%, x = 4000)
|
||||
appearance(red, color = "#ff0000")
|
||||
|
||||
green = clone(yellow)
|
||||
|> translate(%, y = 4000)
|
||||
appearance(green, color = "#00ff00")
|
||||
|
||||
blue = clone(red)
|
||||
|> translate(%, y = 4000)
|
||||
appearance(blue, color = "#0000ff")
|
||||
|
@ -7,28 +7,51 @@ description: Operations executed import_mesh_clone.kcl
|
||||
"type": "GroupBegin",
|
||||
"group": {
|
||||
"type": "ModuleInstance",
|
||||
"name": "cube",
|
||||
"moduleId": 6
|
||||
"name": "cube.obj",
|
||||
"moduleId": 0
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
{
|
||||
"type": "GroupEnd"
|
||||
},
|
||||
{
|
||||
"isError": true,
|
||||
"labeledArgs": {
|
||||
"geometry": {
|
||||
"type": "KclStdLibCall",
|
||||
"name": "clone",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "ImportedGeometry",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"labeledArgs": {},
|
||||
"sourceRange": []
|
||||
},
|
||||
{
|
||||
"type": "KclStdLibCall",
|
||||
"name": "clone",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": null
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "ImportedGeometry",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
"labeledArgs": {},
|
||||
"sourceRange": []
|
||||
},
|
||||
{
|
||||
"type": "KclStdLibCall",
|
||||
"name": "clone",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "ImportedGeometry",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
"labeledArgs": {},
|
||||
"sourceRange": []
|
||||
},
|
||||
{
|
||||
"type": "GroupEnd"
|
||||
}
|
||||
]
|
||||
|
31
rust/kcl-lib/tests/import_mesh_clone/program_memory.snap
Normal file
31
rust/kcl-lib/tests/import_mesh_clone/program_memory.snap
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Variables in memory after executing import_mesh_clone.kcl
|
||||
---
|
||||
{
|
||||
"blue": {
|
||||
"type": "ImportedGeometry",
|
||||
"id": "[uuid]",
|
||||
"value": [
|
||||
"cube.obj"
|
||||
]
|
||||
},
|
||||
"green": {
|
||||
"type": "ImportedGeometry",
|
||||
"id": "[uuid]",
|
||||
"value": [
|
||||
"cube.obj"
|
||||
]
|
||||
},
|
||||
"red": {
|
||||
"type": "ImportedGeometry",
|
||||
"id": "[uuid]",
|
||||
"value": [
|
||||
"cube.obj"
|
||||
]
|
||||
},
|
||||
"yellow": {
|
||||
"type": "Module",
|
||||
"value": 1
|
||||
}
|
||||
}
|
BIN
rust/kcl-lib/tests/import_mesh_clone/rendered_model.png
Normal file
BIN
rust/kcl-lib/tests/import_mesh_clone/rendered_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
@ -2,10 +2,21 @@
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing import_mesh_clone.kcl
|
||||
---
|
||||
import "../inputs/cube.obj" as cube
|
||||
@(lengthUnit = m)
|
||||
import "../inputs/cube.obj" as yellow
|
||||
|
||||
model = cube
|
||||
yellow
|
||||
|> translate(%, x = -2000, y = -2000)
|
||||
appearance(yellow, color = "#ffff00")
|
||||
|
||||
model2 = clone(model)
|
||||
|> translate(x = 1020)
|
||||
|> appearance(color = "#ff0000", metalness = 50, roughness = 50)
|
||||
red = clone(yellow)
|
||||
|> translate(%, x = 4000)
|
||||
appearance(red, color = "#ff0000")
|
||||
|
||||
green = clone(yellow)
|
||||
|> translate(%, y = 4000)
|
||||
appearance(green, color = "#00ff00")
|
||||
|
||||
blue = clone(red)
|
||||
|> translate(%, y = 4000)
|
||||
appearance(blue, color = "#0000ff")
|
||||
|
@ -5121,7 +5121,8 @@ description: Artifact commands bench.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -5132,7 +5133,8 @@ description: Artifact commands bench.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -905,7 +905,8 @@ description: Artifact commands cold-plate.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -5575,7 +5575,8 @@ description: Artifact commands cpu-cooler.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -6109,7 +6110,8 @@ description: Artifact commands cpu-cooler.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -9466,7 +9468,8 @@ description: Artifact commands cpu-cooler.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -9597,7 +9600,8 @@ description: Artifact commands cpu-cooler.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -10115,7 +10119,8 @@ description: Artifact commands cpu-cooler.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -10246,7 +10251,8 @@ description: Artifact commands cpu-cooler.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -456,13 +456,7 @@ description: Result of parsing enclosure.kcl
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "length",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"label": null,
|
||||
"arg": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
@ -3178,13 +3172,7 @@ description: Result of parsing enclosure.kcl
|
||||
},
|
||||
{
|
||||
"type": "LabeledArg",
|
||||
"label": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"name": "length",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"label": null,
|
||||
"arg": {
|
||||
"abs_path": false,
|
||||
"commentStart": 0,
|
||||
|
@ -28,9 +28,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 485,
|
||||
"end": 506,
|
||||
"start": 485,
|
||||
"commentStart": 476,
|
||||
"end": 497,
|
||||
"start": 476,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB001"
|
||||
},
|
||||
@ -41,9 +41,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 608,
|
||||
"end": 629,
|
||||
"start": 608,
|
||||
"commentStart": 599,
|
||||
"end": 620,
|
||||
"start": 599,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC001"
|
||||
},
|
||||
@ -54,9 +54,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 699,
|
||||
"end": 720,
|
||||
"start": 699,
|
||||
"commentStart": 690,
|
||||
"end": 711,
|
||||
"start": 690,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD001"
|
||||
},
|
||||
@ -102,9 +102,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 485,
|
||||
"end": 506,
|
||||
"start": 485,
|
||||
"commentStart": 476,
|
||||
"end": 497,
|
||||
"start": 476,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB001"
|
||||
},
|
||||
@ -127,9 +127,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 608,
|
||||
"end": 629,
|
||||
"start": 608,
|
||||
"commentStart": 599,
|
||||
"end": 620,
|
||||
"start": 599,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC001"
|
||||
},
|
||||
@ -152,9 +152,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 699,
|
||||
"end": 720,
|
||||
"start": 699,
|
||||
"commentStart": 690,
|
||||
"end": 711,
|
||||
"start": 690,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD001"
|
||||
},
|
||||
@ -354,9 +354,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -367,9 +367,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -380,9 +380,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -393,9 +393,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
@ -416,9 +416,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -441,9 +441,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -466,9 +466,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -491,9 +491,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
@ -693,9 +693,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 4147,
|
||||
"end": 4168,
|
||||
"start": 4147,
|
||||
"commentStart": 4129,
|
||||
"end": 4150,
|
||||
"start": 4129,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA003"
|
||||
},
|
||||
@ -706,9 +706,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 4274,
|
||||
"end": 4295,
|
||||
"start": 4274,
|
||||
"commentStart": 4256,
|
||||
"end": 4277,
|
||||
"start": 4256,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB003"
|
||||
},
|
||||
@ -719,9 +719,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 4397,
|
||||
"end": 4418,
|
||||
"start": 4397,
|
||||
"commentStart": 4379,
|
||||
"end": 4400,
|
||||
"start": 4379,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC003"
|
||||
},
|
||||
@ -732,9 +732,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 4488,
|
||||
"end": 4509,
|
||||
"start": 4488,
|
||||
"commentStart": 4470,
|
||||
"end": 4491,
|
||||
"start": 4470,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD003"
|
||||
},
|
||||
@ -755,9 +755,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
3.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4147,
|
||||
"end": 4168,
|
||||
"start": 4147,
|
||||
"commentStart": 4129,
|
||||
"end": 4150,
|
||||
"start": 4129,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA003"
|
||||
},
|
||||
@ -780,9 +780,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
3.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4274,
|
||||
"end": 4295,
|
||||
"start": 4274,
|
||||
"commentStart": 4256,
|
||||
"end": 4277,
|
||||
"start": 4256,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB003"
|
||||
},
|
||||
@ -805,9 +805,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
172.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4397,
|
||||
"end": 4418,
|
||||
"start": 4397,
|
||||
"commentStart": 4379,
|
||||
"end": 4400,
|
||||
"start": 4379,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC003"
|
||||
},
|
||||
@ -830,9 +830,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
172.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4488,
|
||||
"end": 4509,
|
||||
"start": 4488,
|
||||
"commentStart": 4470,
|
||||
"end": 4491,
|
||||
"start": 4470,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD003"
|
||||
},
|
||||
@ -896,9 +896,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -909,9 +909,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -922,9 +922,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -935,9 +935,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
@ -958,9 +958,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -983,9 +983,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -1008,9 +1008,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -1033,9 +1033,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
@ -1495,9 +1495,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 485,
|
||||
"end": 506,
|
||||
"start": 485,
|
||||
"commentStart": 476,
|
||||
"end": 497,
|
||||
"start": 476,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB001"
|
||||
},
|
||||
@ -1520,9 +1520,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 608,
|
||||
"end": 629,
|
||||
"start": 608,
|
||||
"commentStart": 599,
|
||||
"end": 620,
|
||||
"start": 599,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC001"
|
||||
},
|
||||
@ -1545,9 +1545,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 699,
|
||||
"end": 720,
|
||||
"start": 699,
|
||||
"commentStart": 690,
|
||||
"end": 711,
|
||||
"start": 690,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD001"
|
||||
},
|
||||
@ -1669,9 +1669,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -1694,9 +1694,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -1719,9 +1719,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -1744,9 +1744,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
@ -1868,9 +1868,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
3.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4147,
|
||||
"end": 4168,
|
||||
"start": 4147,
|
||||
"commentStart": 4129,
|
||||
"end": 4150,
|
||||
"start": 4129,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA003"
|
||||
},
|
||||
@ -1893,9 +1893,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
3.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4274,
|
||||
"end": 4295,
|
||||
"start": 4274,
|
||||
"commentStart": 4256,
|
||||
"end": 4277,
|
||||
"start": 4256,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB003"
|
||||
},
|
||||
@ -1918,9 +1918,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
172.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4397,
|
||||
"end": 4418,
|
||||
"start": 4397,
|
||||
"commentStart": 4379,
|
||||
"end": 4400,
|
||||
"start": 4379,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC003"
|
||||
},
|
||||
@ -1943,9 +1943,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
172.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 4488,
|
||||
"end": 4509,
|
||||
"start": 4488,
|
||||
"commentStart": 4470,
|
||||
"end": 4491,
|
||||
"start": 4470,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD003"
|
||||
},
|
||||
@ -2009,9 +2009,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -2022,9 +2022,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -2035,9 +2035,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -2048,9 +2048,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
"id": "[uuid]",
|
||||
"sourceRange": [],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
@ -2071,9 +2071,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2445,
|
||||
"end": 2466,
|
||||
"start": 2445,
|
||||
"commentStart": 2436,
|
||||
"end": 2457,
|
||||
"start": 2436,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentA002"
|
||||
},
|
||||
@ -2096,9 +2096,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
0.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2550,
|
||||
"end": 2571,
|
||||
"start": 2550,
|
||||
"commentStart": 2532,
|
||||
"end": 2553,
|
||||
"start": 2532,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentB002"
|
||||
},
|
||||
@ -2121,9 +2121,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2673,
|
||||
"end": 2694,
|
||||
"start": 2673,
|
||||
"commentStart": 2655,
|
||||
"end": 2676,
|
||||
"start": 2655,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentC002"
|
||||
},
|
||||
@ -2146,9 +2146,9 @@ description: Variables in memory after executing enclosure.kcl
|
||||
175.0
|
||||
],
|
||||
"tag": {
|
||||
"commentStart": 2764,
|
||||
"end": 2785,
|
||||
"start": 2764,
|
||||
"commentStart": 2746,
|
||||
"end": 2767,
|
||||
"start": 2746,
|
||||
"type": "TagDeclarator",
|
||||
"value": "rectangleSegmentD002"
|
||||
},
|
||||
|
@ -1597,7 +1597,8 @@ description: Artifact commands exhaust-manifold.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1608,7 +1609,8 @@ description: Artifact commands exhaust-manifold.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1619,7 +1621,8 @@ description: Artifact commands exhaust-manifold.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1630,7 +1633,8 @@ description: Artifact commands exhaust-manifold.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -4490,7 +4490,8 @@ description: Artifact commands utility-sink.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,19 +4,17 @@ description: Operations executed mike_stress_test.kcl
|
||||
---
|
||||
[
|
||||
{
|
||||
"labeledArgs": {
|
||||
"planeOrSolid": {
|
||||
"value": {
|
||||
"type": "String",
|
||||
"value": "XY"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"labeledArgs": {},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": null
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Plane",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
|
@ -26043,10 +26043,8 @@ description: Variables in memory after executing mike_stress_test.kcl
|
||||
}
|
||||
],
|
||||
"on": {
|
||||
"type": "plane",
|
||||
"id": "[uuid]",
|
||||
"artifactId": "[uuid]",
|
||||
"value": "XY",
|
||||
"id": "[uuid]",
|
||||
"origin": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
@ -26055,12 +26053,14 @@ description: Variables in memory after executing mike_stress_test.kcl
|
||||
"type": "Mm"
|
||||
}
|
||||
},
|
||||
"type": "plane",
|
||||
"value": "XY",
|
||||
"xAxis": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
"type": "Unknown"
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
@ -26068,7 +26068,7 @@ description: Variables in memory after executing mike_stress_test.kcl
|
||||
"y": 1.0,
|
||||
"z": 0.0,
|
||||
"units": {
|
||||
"type": "Mm"
|
||||
"type": "Unknown"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4,8 +4,7 @@ description: Error from executing pattern_into_union.kcl
|
||||
---
|
||||
KCL Engine error
|
||||
|
||||
× engine: Modeling command failed: [ApiError { error_code: InternalEngine,
|
||||
│ message: "More than 2 solids were passed to the low-level CSG method" }]
|
||||
× engine: More than 2 solids were passed to the low-level CSG method
|
||||
╭─[67:1]
|
||||
66 │
|
||||
67 │ union([base,endTabs])
|
||||
|
1060
rust/kcl-lib/tests/sketch_on_face_union/artifact_commands.snap
Normal file
1060
rust/kcl-lib/tests/sketch_on_face_union/artifact_commands.snap
Normal file
File diff suppressed because it is too large
Load Diff
3671
rust/kcl-lib/tests/sketch_on_face_union/ast.snap
Normal file
3671
rust/kcl-lib/tests/sketch_on_face_union/ast.snap
Normal file
File diff suppressed because it is too large
Load Diff
58
rust/kcl-lib/tests/sketch_on_face_union/input.kcl
Normal file
58
rust/kcl-lib/tests/sketch_on_face_union/input.kcl
Normal file
@ -0,0 +1,58 @@
|
||||
@settings(defaultLengthUnit = in)
|
||||
|
||||
// Define parameters
|
||||
trussSupportAngle = 15
|
||||
height = 120
|
||||
thickness = 4
|
||||
|
||||
sketch001 = startSketchOn(YZ)
|
||||
profile001 = startProfile(sketch001, at = [60, 0])
|
||||
|> xLine(length = -120, tag = $bottomFace)
|
||||
|> yLine(length = 12)
|
||||
|> angledLine(angle = 25, endAbsoluteX = 0, tag = $tag001)
|
||||
|> angledLine(angle = -25, endAbsoluteX = 60)
|
||||
|> close()
|
||||
|
||||
profile002 = startProfile(sketch001, at = [60-thickness, thickness])
|
||||
|> xLine(endAbsolute = thickness/2)
|
||||
|> yLine(endAbsolute = segEndY(tag001)-thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = -25)
|
||||
|> close(%)
|
||||
|
||||
profile003 = startProfile(sketch001, at = [-60+thickness, thickness])
|
||||
|> xLine(endAbsolute = -thickness/2)
|
||||
|> yLine(endAbsolute = segEndY(tag001)-thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = 205)
|
||||
|> close(%)
|
||||
|
||||
profile004 = subtract2d(profile001, tool = profile002)
|
||||
subtract2d(profile001, tool = profile003)
|
||||
|
||||
body001 = extrude(profile001, length = 2)
|
||||
|
||||
sketch002 = startSketchOn(offsetPlane(YZ, offset = .1))
|
||||
profile006 = startProfile(sketch002, at = [thickness/2-1, 14])
|
||||
|> angledLine(angle = 30, length = 25)
|
||||
|> angledLine(angle = -25, length = 5)
|
||||
|> angledLine(angle = 210, endAbsoluteX = profileStartX(%))
|
||||
|> close(%)
|
||||
|> extrude(%, length = 1.8)
|
||||
|
||||
profile007 = startProfile(sketch002, at = [-thickness/2+1, 14])
|
||||
|> angledLine(angle = 150, length = 25)
|
||||
|> angledLine(angle = 205, length = 5)
|
||||
|> angledLine(angle = -30, endAbsoluteX = profileStartX(%))
|
||||
|> close(%)
|
||||
|> extrude(%, length = 1.8)
|
||||
|
||||
newSketch = body001 + profile006 + profile007
|
||||
|
||||
leg001Sketch = startSketchOn(newSketch, face = bottomFace)
|
||||
legProfile001 = startProfile(leg001Sketch, at = [-60, 0])
|
||||
|> xLine(%, length = 4)
|
||||
|> yLine(%, length = 2)
|
||||
|> xLine(%, endAbsolute = profileStartX(%))
|
||||
|> close(%)
|
||||
|
||||
leg001 = extrude(legProfile001, length = 48)
|
||||
|> rotate(axis = [0, 0, 1.0], angle = -90)
|
264
rust/kcl-lib/tests/sketch_on_face_union/ops.snap
Normal file
264
rust/kcl-lib/tests/sketch_on_face_union/ops.snap
Normal file
@ -0,0 +1,264 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Operations executed sketch_on_face_union.kcl
|
||||
---
|
||||
[
|
||||
{
|
||||
"labeledArgs": {},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Plane",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"tool": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "subtract2d",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"tool": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "subtract2d",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 2.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Inches"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Plane",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "KclStdLibCall",
|
||||
"name": "offsetPlane",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Plane",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
"labeledArgs": {
|
||||
"offset": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 0.1,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Inches"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 1.8,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Inches"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 1.8,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Inches"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"face": {
|
||||
"value": {
|
||||
"type": "TagIdentifier",
|
||||
"value": "bottomFace",
|
||||
"artifact_id": "[uuid]"
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "startSketchOn",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Solid",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"labeledArgs": {
|
||||
"length": {
|
||||
"value": {
|
||||
"type": "Number",
|
||||
"value": 48.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Inches"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
},
|
||||
"name": "extrude",
|
||||
"sourceRange": [],
|
||||
"type": "StdLibCall",
|
||||
"unlabeledArg": {
|
||||
"value": {
|
||||
"type": "Sketch",
|
||||
"value": {
|
||||
"artifactId": "[uuid]"
|
||||
}
|
||||
},
|
||||
"sourceRange": []
|
||||
}
|
||||
}
|
||||
]
|
2639
rust/kcl-lib/tests/sketch_on_face_union/program_memory.snap
Normal file
2639
rust/kcl-lib/tests/sketch_on_face_union/program_memory.snap
Normal file
File diff suppressed because it is too large
Load Diff
BIN
rust/kcl-lib/tests/sketch_on_face_union/rendered_model.png
Normal file
BIN
rust/kcl-lib/tests/sketch_on_face_union/rendered_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
62
rust/kcl-lib/tests/sketch_on_face_union/unparsed.snap
Normal file
62
rust/kcl-lib/tests/sketch_on_face_union/unparsed.snap
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing sketch_on_face_union.kcl
|
||||
---
|
||||
@settings(defaultLengthUnit = in)
|
||||
|
||||
// Define parameters
|
||||
trussSupportAngle = 15
|
||||
height = 120
|
||||
thickness = 4
|
||||
|
||||
sketch001 = startSketchOn(YZ)
|
||||
profile001 = startProfile(sketch001, at = [60, 0])
|
||||
|> xLine(length = -120, tag = $bottomFace)
|
||||
|> yLine(length = 12)
|
||||
|> angledLine(angle = 25, endAbsoluteX = 0, tag = $tag001)
|
||||
|> angledLine(angle = -25, endAbsoluteX = 60)
|
||||
|> close()
|
||||
|
||||
profile002 = startProfile(sketch001, at = [60 - thickness, thickness])
|
||||
|> xLine(endAbsolute = thickness / 2)
|
||||
|> yLine(endAbsolute = segEndY(tag001) - thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = -25)
|
||||
|> close(%)
|
||||
|
||||
profile003 = startProfile(sketch001, at = [-60 + thickness, thickness])
|
||||
|> xLine(endAbsolute = -thickness / 2)
|
||||
|> yLine(endAbsolute = segEndY(tag001) - thickness) // update
|
||||
|> angledLine(endAbsoluteX = profileStartX(%), angle = 205)
|
||||
|> close(%)
|
||||
|
||||
profile004 = subtract2d(profile001, tool = profile002)
|
||||
subtract2d(profile001, tool = profile003)
|
||||
|
||||
body001 = extrude(profile001, length = 2)
|
||||
|
||||
sketch002 = startSketchOn(offsetPlane(YZ, offset = .1))
|
||||
profile006 = startProfile(sketch002, at = [thickness / 2 - 1, 14])
|
||||
|> angledLine(angle = 30, length = 25)
|
||||
|> angledLine(angle = -25, length = 5)
|
||||
|> angledLine(angle = 210, endAbsoluteX = profileStartX(%))
|
||||
|> close(%)
|
||||
|> extrude(%, length = 1.8)
|
||||
|
||||
profile007 = startProfile(sketch002, at = [-thickness / 2 + 1, 14])
|
||||
|> angledLine(angle = 150, length = 25)
|
||||
|> angledLine(angle = 205, length = 5)
|
||||
|> angledLine(angle = -30, endAbsoluteX = profileStartX(%))
|
||||
|> close(%)
|
||||
|> extrude(%, length = 1.8)
|
||||
|
||||
newSketch = body001 + profile006 + profile007
|
||||
|
||||
leg001Sketch = startSketchOn(newSketch, face = bottomFace)
|
||||
legProfile001 = startProfile(leg001Sketch, at = [-60, 0])
|
||||
|> xLine(%, length = 4)
|
||||
|> yLine(%, length = 2)
|
||||
|> xLine(%, endAbsolute = profileStartX(%))
|
||||
|> close(%)
|
||||
|
||||
leg001 = extrude(legProfile001, length = 48)
|
||||
|> rotate(axis = [0, 0, 1.0], angle = -90)
|
@ -417,7 +417,8 @@ description: Artifact commands subtract_regression03.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -394,7 +394,8 @@ description: Artifact commands subtract_regression05.kcl
|
||||
"target": "[uuid]",
|
||||
"trajectory": "[uuid]",
|
||||
"sectional": false,
|
||||
"tolerance": 0.0000001
|
||||
"tolerance": 0.0000001,
|
||||
"relative_to": "trajectory_curve"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-python-bindings"
|
||||
version = "0.3.69"
|
||||
version = "0.3.73"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/kittycad/modeling-app"
|
||||
exclude = ["tests/*", "files/*", "venv/*"]
|
||||
|
@ -217,16 +217,48 @@ async fn get_code_and_file_path(path: &str) -> Result<(String, std::path::PathBu
|
||||
Ok((code, path))
|
||||
}
|
||||
|
||||
async fn new_context_state(current_file: Option<std::path::PathBuf>) -> Result<(ExecutorContext, kcl_lib::ExecState)> {
|
||||
async fn new_context_state(
|
||||
current_file: Option<std::path::PathBuf>,
|
||||
mock: bool,
|
||||
) -> Result<(ExecutorContext, kcl_lib::ExecState)> {
|
||||
let mut settings: kcl_lib::ExecutorSettings = Default::default();
|
||||
if let Some(current_file) = current_file {
|
||||
settings.with_current_file(kcl_lib::TypedPath(current_file));
|
||||
}
|
||||
let ctx = ExecutorContext::new_with_client(settings, None, None).await?;
|
||||
let ctx = if mock {
|
||||
ExecutorContext::new_mock(Some(settings)).await
|
||||
} else {
|
||||
ExecutorContext::new_with_client(settings, None, None).await?
|
||||
};
|
||||
let state = kcl_lib::ExecState::new(&ctx);
|
||||
Ok((ctx, state))
|
||||
}
|
||||
|
||||
/// Parse the kcl code from a file path.
|
||||
#[pyfunction]
|
||||
async fn parse(path: String) -> PyResult<bool> {
|
||||
tokio()
|
||||
.spawn(async move {
|
||||
let (code, path) = get_code_and_file_path(&path)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
let _program = kcl_lib::Program::parse_no_errs(&code)
|
||||
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?;
|
||||
|
||||
Ok(true)
|
||||
})
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
|
||||
}
|
||||
|
||||
/// Parse the kcl code.
|
||||
#[pyfunction]
|
||||
fn parse_code(code: String) -> PyResult<bool> {
|
||||
let _program = kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// Execute the kcl code from a file path.
|
||||
#[pyfunction]
|
||||
async fn execute(path: String) -> PyResult<()> {
|
||||
@ -238,7 +270,7 @@ async fn execute(path: String) -> PyResult<()> {
|
||||
let program = kcl_lib::Program::parse_no_errs(&code)
|
||||
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(Some(path))
|
||||
let (ctx, mut state) = new_context_state(Some(path), false)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
@ -260,7 +292,7 @@ async fn execute_code(code: String) -> PyResult<()> {
|
||||
let program =
|
||||
kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(None)
|
||||
let (ctx, mut state) = new_context_state(None, false)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
@ -274,6 +306,53 @@ async fn execute_code(code: String) -> PyResult<()> {
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
|
||||
}
|
||||
|
||||
/// Mock execute the kcl code.
|
||||
#[pyfunction]
|
||||
async fn mock_execute_code(code: String) -> PyResult<bool> {
|
||||
tokio()
|
||||
.spawn(async move {
|
||||
let program =
|
||||
kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(None, true)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
ctx.run(&program, &mut state)
|
||||
.await
|
||||
.map_err(|err| into_miette(err, &code))?;
|
||||
|
||||
Ok(true)
|
||||
})
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
|
||||
}
|
||||
|
||||
/// Mock execute the kcl code from a file path.
|
||||
#[pyfunction]
|
||||
async fn mock_execute(path: String) -> PyResult<bool> {
|
||||
tokio()
|
||||
.spawn(async move {
|
||||
let (code, path) = get_code_and_file_path(&path)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
let program = kcl_lib::Program::parse_no_errs(&code)
|
||||
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(Some(path), true)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
ctx.run(&program, &mut state)
|
||||
.await
|
||||
.map_err(|err| into_miette(err, &code))?;
|
||||
|
||||
Ok(true)
|
||||
})
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
|
||||
}
|
||||
|
||||
/// Execute a kcl file and snapshot it in a specific format.
|
||||
#[pyfunction]
|
||||
async fn execute_and_snapshot(path: String, image_format: ImageFormat) -> PyResult<Vec<u8>> {
|
||||
@ -285,7 +364,7 @@ async fn execute_and_snapshot(path: String, image_format: ImageFormat) -> PyResu
|
||||
let program = kcl_lib::Program::parse_no_errs(&code)
|
||||
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(Some(path))
|
||||
let (ctx, mut state) = new_context_state(Some(path), false)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
@ -342,7 +421,7 @@ async fn execute_code_and_snapshot(code: String, image_format: ImageFormat) -> P
|
||||
let program =
|
||||
kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(None)
|
||||
let (ctx, mut state) = new_context_state(None, false)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
@ -402,7 +481,7 @@ async fn execute_and_export(path: String, export_format: FileExportFormat) -> Py
|
||||
let program = kcl_lib::Program::parse_no_errs(&code)
|
||||
.map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(Some(path.clone()))
|
||||
let (ctx, mut state) = new_context_state(Some(path.clone()), false)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
@ -450,7 +529,7 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat)
|
||||
let program =
|
||||
kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
|
||||
|
||||
let (ctx, mut state) = new_context_state(None)
|
||||
let (ctx, mut state) = new_context_state(None, false)
|
||||
.await
|
||||
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?;
|
||||
// Execute the program.
|
||||
@ -534,8 +613,12 @@ fn kcl(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
m.add_class::<Discovered>()?;
|
||||
|
||||
// Add our functions to the module.
|
||||
m.add_function(wrap_pyfunction!(parse, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(parse_code, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(execute, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(execute_code, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(mock_execute, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(mock_execute_code, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(execute_and_snapshot, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(execute_code_and_snapshot, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(execute_and_export, m)?)?;
|
||||
|
@ -39,6 +39,64 @@ async def test_kcl_execute():
|
||||
await kcl.execute(lego_file)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_parse_with_exception():
|
||||
# Read from a file.
|
||||
try:
|
||||
await kcl.parse(os.path.join(files_dir, "parse_file_error"))
|
||||
except Exception as e:
|
||||
assert e is not None
|
||||
assert len(str(e)) > 0
|
||||
assert "lksjndflsskjfnak;jfna##" in str(e)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_parse():
|
||||
# Read from a file.
|
||||
result = await kcl.parse(lego_file)
|
||||
assert result is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_parse_code():
|
||||
# Read from a file.
|
||||
with open(lego_file, "r") as f:
|
||||
code = str(f.read())
|
||||
assert code is not None
|
||||
assert len(code) > 0
|
||||
result = kcl.parse_code(code)
|
||||
assert result is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_mock_execute_with_exception():
|
||||
# Read from a file.
|
||||
try:
|
||||
await kcl.mock_execute(os.path.join(files_dir, "parse_file_error"))
|
||||
except Exception as e:
|
||||
assert e is not None
|
||||
assert len(str(e)) > 0
|
||||
assert "lksjndflsskjfnak;jfna##" in str(e)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_mock_execute():
|
||||
# Read from a file.
|
||||
result = await kcl.mock_execute(lego_file)
|
||||
assert result is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_mock_execute_code():
|
||||
# Read from a file.
|
||||
with open(lego_file, "r") as f:
|
||||
code = str(f.read())
|
||||
assert code is not None
|
||||
assert len(code) > 0
|
||||
result = await kcl.mock_execute_code(code)
|
||||
assert result is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_execute_code():
|
||||
# Read from a file.
|
||||
@ -97,9 +155,7 @@ async def test_kcl_execute_and_snapshot():
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_execute_and_snapshot_dir():
|
||||
# Read from a file.
|
||||
image_bytes = await kcl.execute_and_snapshot(
|
||||
car_wheel_dir, kcl.ImageFormat.Jpeg
|
||||
)
|
||||
image_bytes = await kcl.execute_and_snapshot(car_wheel_dir, kcl.ImageFormat.Jpeg)
|
||||
assert image_bytes is not None
|
||||
assert len(image_bytes) > 0
|
||||
|
||||
@ -129,10 +185,12 @@ def test_kcl_format():
|
||||
assert formatted_code is not None
|
||||
assert len(formatted_code) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kcl_format_dir():
|
||||
await kcl.format_dir(car_wheel_dir)
|
||||
|
||||
|
||||
def test_kcl_lint():
|
||||
# Read from a file.
|
||||
with open(os.path.join(files_dir, "box_with_linter_errors.kcl"), "r") as f:
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-test-server"
|
||||
description = "A test server for KCL"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-to-core"
|
||||
description = "Utility methods to convert kcl to engine core executable tests"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kcl-wasm-lib"
|
||||
version = "0.1.69"
|
||||
version = "0.1.73"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
rust-version = "1.83"
|
||||
|
@ -117,7 +117,9 @@ export function App() {
|
||||
|
||||
// When leaving the modeling scene, cut the engine stream.
|
||||
return () => {
|
||||
engineStreamActor.send({ type: EngineStreamTransition.Pause })
|
||||
// When leaving the modeling scene, cut the engine stream.
|
||||
// Stop is more serious than Pause
|
||||
engineStreamActor.send({ type: EngineStreamTransition.Stop })
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
@ -158,7 +158,8 @@ export function Toolbar({
|
||||
const isDisabled =
|
||||
disableAllButtons ||
|
||||
!isConfiguredAvailable ||
|
||||
maybeIconConfig.disabled?.(state) === true
|
||||
maybeIconConfig.disabled?.(state) === true ||
|
||||
kclManager.hasErrors()
|
||||
|
||||
return {
|
||||
...maybeIconConfig,
|
||||
@ -444,6 +445,15 @@ const ToolbarItemTooltip = memo(function ToolbarItemContents({
|
||||
contentClassName={contentClassName}
|
||||
>
|
||||
{children}
|
||||
{kclManager.hasErrors() && (
|
||||
<p className="text-xs p-1 text-chalkboard-70 dark:text-chalkboard-40">
|
||||
<CustomIcon
|
||||
name="exclamationMark"
|
||||
className="w-4 h-4 inline-block mr-1 text-destroy-80 bg-destroy-10"
|
||||
/>
|
||||
Fix KCL errors to enable tools
|
||||
</p>
|
||||
)}
|
||||
</Tooltip>
|
||||
)
|
||||
})
|
||||
|
@ -975,7 +975,6 @@ export class CameraControls {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
await this.engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd_id: uuidv4(),
|
||||
|
@ -13,6 +13,7 @@ export const STRAIGHT_SEGMENT_SNAP_LINE = 'straight-segment-snap-line'
|
||||
export const CIRCLE_SEGMENT = 'circle-segment'
|
||||
export const CIRCLE_SEGMENT_BODY = 'circle-segment-body'
|
||||
export const CIRCLE_SEGMENT_DASH = 'circle-segment-body-dashed'
|
||||
export const CIRCLE_SEGMENT_RADIUS_BODY = 'circle-segment-radius-body'
|
||||
export const TANGENTIAL_ARC_TO_SEGMENT = 'tangential-arc-to-segment'
|
||||
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
||||
export const TANGENTIAL_ARC_TO__SEGMENT_DASH =
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user