Compare commits

..

1 Commits

Author SHA1 Message Date
6c570036b4 Adjust expected segment overlay counts 2025-05-14 10:49:17 -04:00
82 changed files with 47519 additions and 11737 deletions

View File

@ -40,7 +40,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm install run: npm install
- name: Download Wasm cache - name: Download Wasm Cache
id: download-wasm id: download-wasm
if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }} if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
uses: dawidd6/action-download-artifact@v7 uses: dawidd6/action-download-artifact@v7
@ -52,7 +52,7 @@ jobs:
branch: main branch: main
path: rust/kcl-wasm-lib/pkg path: rust/kcl-wasm-lib/pkg
- name: Build Wasm condition - name: Build WASM condition
id: wasm id: wasm
run: | run: |
set -euox pipefail set -euox pipefail
@ -70,7 +70,7 @@ jobs:
run: | run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./ [ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install Rust - name: Install rust
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
@ -81,7 +81,7 @@ jobs:
with: with:
tool: wasm-pack tool: wasm-pack
- name: Use Rust cache - name: Rust Cache
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
uses: Swatinem/rust-cache@v2 uses: Swatinem/rust-cache@v2
with: with:
@ -117,7 +117,7 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
name: prepared-wasm name: prepared-wasm
- name: Copy prepared Wasm - name: Copy prepared wasm
run: | run: |
ls -R prepared-wasm ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public cp prepared-wasm/kcl_wasm_lib_bg.wasm public
@ -133,17 +133,20 @@ jobs:
id: deps-install id: deps-install
run: npm install run: npm install
- name: Cache browsers - name: Cache Playwright Browsers
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
~/.cache/ms-playwright/ ~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }} key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
- name: Install browsers - name: Install Playwright Browsers
run: npm run playwright install --with-deps run: npm run playwright install --with-deps
- name: Capture snapshots - name: build web
run: npm run tronb:vite:dev
- name: Run ubuntu/chrome snapshots
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
with: with:
shell: bash shell: bash
@ -167,7 +170,7 @@ jobs:
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
- name: Check diff - name: Check for changes
if: ${{ github.ref != 'refs/heads/main' }} if: ${{ github.ref != 'refs/heads/main' }}
shell: bash shell: bash
id: git-check id: git-check
@ -178,8 +181,9 @@ jobs:
else echo "modified=false" >> $GITHUB_OUTPUT else echo "modified=false" >> $GITHUB_OUTPUT
fi fi
- name: Commit changes - name: Commit changes, if any
if: ${{ steps.git-check.outputs.modified == 'true' }} # TODO: find a more reliable way to detect visual changes
if: ${{ false && steps.git-check.outputs.modified == 'true' }}
shell: bash shell: bash
run: | run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
@ -189,7 +193,7 @@ jobs:
git fetch origin git fetch origin
echo ${{ github.head_ref }} echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }} git checkout ${{ github.head_ref }}
git commit --message "Update snapshots" || true git commit -m "A snapshot a day keeps the bugs away! 📷🐛" || true
git push git push
git push origin ${{ github.head_ref }} git push origin ${{ github.head_ref }}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -158,14 +158,10 @@ extrude001 = extrude(sketch001, length = 5)`
await expect( await expect(
page page
.getByText( .getByText(
'Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis' 'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
) )
.first() .first()
).toBeVisible() ).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 ({ test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({

View File

@ -58,6 +58,12 @@ test(
await expect(submitButton).toBeVisible() await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter') 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 // Expect it to succeed
const errorToastMessage = page.getByText(`Error while exporting`) const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`) const engineErrorToastMessage = page.getByText(`Nothing to export`)
@ -66,6 +72,7 @@ test(
const successToastMessage = page.getByText(`Exported successfully`) const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible() await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
// Check for the exported file // Check for the exported file
const firstFileFullPath = path.resolve( const firstFileFullPath = path.resolve(

View File

@ -51,11 +51,8 @@ test.describe('Regression tests', () => {
// the close doesn't work // the close doesn't work
// when https://github.com/KittyCAD/modeling-app/issues/3268 is closed // when https://github.com/KittyCAD/modeling-app/issues/3268 is closed
// this test will need updating // this test will need updating
const crypticErrorText = `Cannot close a path that is non-planar or with duplicate vertices. const crypticErrorText = `ApiError`
Internal engine error on request`
await expect(page.getByText(crypticErrorText).first()).toBeVisible() 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 ({ test('user should not have to press down twice in cmdbar', async ({
page, page,
@ -548,8 +545,7 @@ extrude002 = extrude(profile002, length = 150)
expect(alreadyExportingToastMessage).not.toBeVisible(), expect(alreadyExportingToastMessage).not.toBeVisible(),
]) ])
const count = await successToastMessage.count() await expect(successToastMessage).toHaveCount(2)
await expect(count).toBeGreaterThanOrEqual(2)
}) })
}) })

View File

@ -1,3 +1,4 @@
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture' import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture' import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates' import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
@ -8,7 +9,6 @@ import {
settingsToToml, settingsToToml,
} from '@e2e/playwright/test-utils' } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test' import { expect, test } from '@e2e/playwright/zoo-test'
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
test.beforeEach(async ({ page, context }) => { test.beforeEach(async ({ page, context }) => {
// Make the user avatar image always 404 // Make the user avatar image always 404
@ -873,50 +873,6 @@ sweepSketch = startSketchOn(XY)
mask: lowerRightMasks(page), 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 ({ test('code color goober opening window', async ({
page, page,

View File

@ -237,7 +237,7 @@ test.describe('Testing segment overlays', () => {
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await expect(page.getByTestId('segment-overlay')).toHaveCount(13) await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
const clickUnconstrained = _clickUnconstrained(page, editor) const clickUnconstrained = _clickUnconstrained(page, editor)
const clickConstrained = _clickConstrained(page, editor) const clickConstrained = _clickConstrained(page, editor)
@ -402,7 +402,7 @@ test.describe('Testing segment overlays', () => {
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await expect(page.getByTestId('segment-overlay')).toHaveCount(8) await expect(page.getByTestId('segment-overlay')).toHaveCount(9)
const clickUnconstrained = _clickUnconstrained(page, editor) const clickUnconstrained = _clickUnconstrained(page, editor)
@ -482,7 +482,7 @@ test.describe('Testing segment overlays', () => {
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await expect(page.getByTestId('segment-overlay')).toHaveCount(13) await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
const clickUnconstrained = _clickUnconstrained(page, editor) const clickUnconstrained = _clickUnconstrained(page, editor)
const clickConstrained = _clickConstrained(page, editor) const clickConstrained = _clickConstrained(page, editor)
@ -602,7 +602,7 @@ test.describe('Testing segment overlays', () => {
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await expect(page.getByTestId('segment-overlay')).toHaveCount(13) await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
const clickUnconstrained = _clickUnconstrained(page, editor) const clickUnconstrained = _clickUnconstrained(page, editor)
const clickConstrained = _clickConstrained(page, editor) const clickConstrained = _clickConstrained(page, editor)
@ -808,7 +808,7 @@ profile001 = startProfile(sketch001, at = [56.37, 120.33])
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await expect(page.getByTestId('segment-overlay')).toHaveCount(5) await expect(page.getByTestId('segment-overlay')).toHaveCount(6)
const clickUnconstrained = _clickUnconstrained(page, editor) const clickUnconstrained = _clickUnconstrained(page, editor)
const clickConstrained = _clickConstrained(page, editor) const clickConstrained = _clickConstrained(page, editor)
@ -1307,7 +1307,7 @@ part001 = startSketchOn(XZ)
.toBe(true) .toBe(true)
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await expect(page.getByTestId('segment-overlay')).toHaveCount(3) await expect(page.getByTestId('segment-overlay')).toHaveCount(4)
const segmentToDelete = await u.getBoundingBox( const segmentToDelete = await u.getBoundingBox(
`[data-overlay-index="0"]` `[data-overlay-index="0"]`
) )

View File

@ -57,9 +57,9 @@ fn connectorSketch(@plane, start) {
export fn connector(@plane, length) { export fn connector(@plane, length) {
connectorSketch(plane, start = [-12, 8]) connectorSketch(plane, start = [-12, 8])
|> extrude(length) |> extrude(length = length)
connectorSketch(plane, start = [16, 8]) connectorSketch(plane, start = [16, 8])
|> extrude(length) |> extrude(length = length)
return 0 return 0
} }
@ -79,7 +79,7 @@ fn seatSlatSketch(@plane) {
export fn seatSlats(@plane, length) { export fn seatSlats(@plane, length) {
seatSlatSketch(plane) seatSlatSketch(plane)
|> extrude(length) |> extrude(length = length)
return 0 return 0
} }
@ -99,7 +99,7 @@ fn backSlatsSketch(@plane) {
export fn backSlats(@plane, length) { export fn backSlats(@plane, length) {
b = backSlatsSketch(plane) b = backSlatsSketch(plane)
|> extrude(length) |> extrude(length = length)
return b return b
} }

View File

@ -15,7 +15,7 @@ holeDia = 4
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
|> startProfile(at = [0, 0]) |> startProfile(at = [0, 0])
|> angledLine(angle = 0, length = width, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = width, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length, tag = $rectangleSegmentB001) |> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = length, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001) |> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001) |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|> close() |> close()
@ -74,7 +74,7 @@ function001([
sketch003 = startSketchOn(XY) sketch003 = startSketchOn(XY)
|> startProfile(at = [width * 1.2, 0]) |> startProfile(at = [width * 1.2, 0])
|> angledLine(angle = 0, length = width, tag = $rectangleSegmentA002) |> angledLine(angle = 0, length = width, tag = $rectangleSegmentA002)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length, tag = $rectangleSegmentB002) |> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = length, tag = $rectangleSegmentB002)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC002) |> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC002)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002) |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|> close() |> close()

View File

@ -1,12 +1,12 @@
[test-groups] [test-groups]
# If a test uses the engine, we want to limit the number that can run in parallel. # 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. # This way we don't start and stop too many engine instances, putting pressure on our cloud.
uses-engine = { max-threads = 32 } uses-engine = { max-threads = 4 }
# If a test must run after the engine tests, we want to make sure the engine tests are done first. # If a test must run after the engine tests, we want to make sure the engine tests are done first.
after-engine = { max-threads = 32 } after-engine = { max-threads = 12 }
[profile.default] [profile.default]
slow-timeout = { period = "280s", terminate-after = 1 } slow-timeout = { period = "180s", terminate-after = 1 }
[profile.ci] [profile.ci]
slow-timeout = { period = "280s", terminate-after = 5 } slow-timeout = { period = "280s", terminate-after = 5 }

24
rust/Cargo.lock generated
View File

@ -1815,7 +1815,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-bumper" name = "kcl-bumper"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -1826,7 +1826,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-derive-docs" name = "kcl-derive-docs"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"anyhow", "anyhow",
@ -1845,7 +1845,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-directory-test-macro" name = "kcl-directory-test-macro"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1854,7 +1854,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-language-server" name = "kcl-language-server"
version = "0.2.71" version = "0.2.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -1875,7 +1875,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-language-server-release" name = "kcl-language-server-release"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -1895,7 +1895,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-lib" name = "kcl-lib"
version = "0.2.71" version = "0.2.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"approx 0.5.1", "approx 0.5.1",
@ -1971,7 +1971,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-python-bindings" name = "kcl-python-bindings"
version = "0.3.71" version = "0.3.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"kcl-lib", "kcl-lib",
@ -1986,7 +1986,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-test-server" name = "kcl-test-server"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hyper 0.14.32", "hyper 0.14.32",
@ -1999,7 +1999,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-to-core" name = "kcl-to-core"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -2013,7 +2013,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-wasm-lib" name = "kcl-wasm-lib"
version = "0.1.71" version = "0.1.69"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bson", "bson",
@ -2080,9 +2080,9 @@ dependencies = [
[[package]] [[package]]
name = "kittycad-modeling-cmds" name = "kittycad-modeling-cmds"
version = "0.2.121" version = "0.2.120"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94ba95c22493d79ec8a1faab963d8903f6de0e373efedf2bc3bb76a0ddbab036" checksum = "48b71e06ee5d711d0085864a756fb6a304531246689ea00c6ef5d740670c3701"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-bumper" name = "kcl-bumper"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
repository = "https://github.com/KittyCAD/modeling-api" repository = "https://github.com/KittyCAD/modeling-api"
rust-version = "1.76" rust-version = "1.76"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-derive-docs" name = "kcl-derive-docs"
description = "A tool for generating documentation from Rust derive macros" description = "A tool for generating documentation from Rust derive macros"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-directory-test-macro" name = "kcl-directory-test-macro"
description = "A tool for generating tests from a directory of kcl files" description = "A tool for generating tests from a directory of kcl files"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "kcl-language-server-release" name = "kcl-language-server-release"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
authors = ["KittyCAD Inc <kcl@kittycad.io>"] authors = ["KittyCAD Inc <kcl@kittycad.io>"]
publish = false publish = false

View File

@ -2,7 +2,7 @@
name = "kcl-language-server" name = "kcl-language-server"
description = "A language server for KCL." description = "A language server for KCL."
authors = ["KittyCAD Inc <kcl@kittycad.io>"] authors = ["KittyCAD Inc <kcl@kittycad.io>"]
version = "0.2.71" version = "0.2.69"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-lib" name = "kcl-lib"
description = "KittyCAD Language implementation and tools" description = "KittyCAD Language implementation and tools"
version = "0.2.71" version = "0.2.69"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -953,6 +953,36 @@ sketch001 = startSketchOn(box, face = END)
assert_out("revolve_on_edge", &result); 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")] #[tokio::test(flavor = "multi_thread")]
async fn kcl_test_revolve_on_face_circle_edge() { async fn kcl_test_revolve_on_face_circle_edge() {
let code = r#"box = startSketchOn(XY) let code = r#"box = startSketchOn(XY)

View File

@ -223,26 +223,6 @@ impl EngineConnection {
message: errors.iter().map(|e| e.message.clone()).collect::<Vec<_>>().join("\n"), message: errors.iter().map(|e| e.message.clone()).collect::<Vec<_>>().join("\n"),
source_ranges: vec![source_range], 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 { } else {
KclError::Engine(KclErrorDetails { KclError::Engine(KclErrorDetails {
message: format!("Failed to wait for promise from send modeling command: {:?}", e), message: format!("Failed to wait for promise from send modeling command: {:?}", e),

View File

@ -764,12 +764,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
WebSocketResponse::Failure(fail) => { WebSocketResponse::Failure(fail) => {
let _request_id = fail.request_id; let _request_id = fail.request_id;
Err(KclError::Engine(KclErrorDetails { Err(KclError::Engine(KclErrorDetails {
message: fail message: format!("Modeling command failed: {:?}", fail.errors),
.errors
.iter()
.map(|e| e.message.clone())
.collect::<Vec<_>>()
.join("\n"),
source_ranges: vec![source_range], source_ranges: vec![source_range],
})) }))
} }
@ -812,7 +807,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
}) })
})?; })?;
return Err(KclError::Engine(KclErrorDetails { return Err(KclError::Engine(KclErrorDetails {
message: errors.iter().map(|e| e.message.clone()).collect::<Vec<_>>().join("\n"), message: format!("Modeling command failed: {:?}", errors),
source_ranges: vec![source_range], source_ranges: vec![source_range],
})); }));
} }

View File

@ -1311,15 +1311,10 @@ impl Node<CallExpressionKw> {
Some(l) => { Some(l) => {
fn_args.insert(l.name.clone(), arg); fn_args.insert(l.name.clone(), arg);
} }
None => { None => errors.push(arg),
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. // Evaluate the unlabeled first param, if any exists.
let unlabeled = if let Some(ref arg_expr) = self.unlabeled { let unlabeled = if let Some(ref arg_expr) = self.unlabeled {
@ -1328,15 +1323,12 @@ impl Node<CallExpressionKw> {
let value = ctx let value = ctx
.execute_expr(arg_expr, exec_state, &metadata, &[], StatementKind::Expression) .execute_expr(arg_expr, exec_state, &metadata, &[], StatementKind::Expression)
.await?; .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 { } else {
None None
}; };
let mut args = Args::new_kw( let args = Args::new_kw(
KwArgs { KwArgs {
unlabeled, unlabeled,
labeled: fn_args, labeled: fn_args,
@ -1355,20 +1347,6 @@ 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")] #[cfg(feature = "artifact-graph")]
let op = if func.feature_tree_operation() { let op = if func.feature_tree_operation() {
let op_labeled_args = args let op_labeled_args = args
@ -1390,6 +1368,7 @@ impl Node<CallExpressionKw> {
None None
}; };
let formals = func.args(false);
for (label, arg) in &args.kw_args.labeled { for (label, arg) in &args.kw_args.labeled {
match formals.iter().find(|p| &p.name == label) { match formals.iter().find(|p| &p.name == label) {
Some(p) => { Some(p) => {
@ -1886,21 +1865,6 @@ fn type_check_params_kw(
args: &mut KwArgs, args: &mut KwArgs,
exec_state: &mut ExecState, exec_state: &mut ExecState,
) -> Result<(), KclError> { ) -> 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 { for (label, arg) in &mut args.labeled {
match function_expression.params.iter().find(|p| &p.identifier.name == label) { match function_expression.params.iter().find(|p| &p.identifier.name == label) {
Some(p) => { Some(p) => {
@ -1995,11 +1959,10 @@ fn type_check_params_kw(
if let Some(arg) = &mut args.unlabeled { if let Some(arg) = &mut args.unlabeled {
if let Some(p) = function_expression.params.iter().find(|p| !p.labeled) { if let Some(p) = function_expression.params.iter().find(|p| !p.labeled) {
if let Some(ty) = &p.type_ { if let Some(ty) = &p.type_ {
arg.1.value = arg arg.value = arg
.1
.value .value
.coerce( .coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.1.source_range) &RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
.map_err(|e| KclError::Semantic(e.into()))?, .map_err(|e| KclError::Semantic(e.into()))?,
exec_state, exec_state,
) )
@ -2011,9 +1974,9 @@ fn type_check_params_kw(
.map(|n| format!("`{}`", n)) .map(|n| format!("`{}`", n))
.unwrap_or_else(|| "this function".to_owned()), .unwrap_or_else(|| "this function".to_owned()),
ty.inner, ty.inner,
arg.1.value.human_friendly_type() arg.value.human_friendly_type()
), ),
source_ranges: vec![arg.1.source_range], source_ranges: vec![arg.source_range],
}) })
})?; })?;
} }
@ -2176,11 +2139,10 @@ impl FunctionSource {
if let Some(arg) = &mut args.kw_args.unlabeled { if let Some(arg) = &mut args.kw_args.unlabeled {
if let Some(p) = ast.params.iter().find(|p| !p.labeled) { if let Some(p) = ast.params.iter().find(|p| !p.labeled) {
if let Some(ty) = &p.type_ { if let Some(ty) = &p.type_ {
arg.1.value = arg arg.value = arg
.1
.value .value
.coerce( .coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.1.source_range) &RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
.map_err(|e| KclError::Semantic(e.into()))?, .map_err(|e| KclError::Semantic(e.into()))?,
exec_state, exec_state,
) )
@ -2190,7 +2152,7 @@ impl FunctionSource {
"The input argument of {} requires a value with type `{}`, but found {}", "The input argument of {} requires a value with type `{}`, but found {}",
props.name, props.name,
ty.inner, ty.inner,
arg.1.value.human_friendly_type(), arg.value.human_friendly_type(),
), ),
source_ranges: vec![callsite], source_ranges: vec![callsite],
}) })
@ -2262,7 +2224,7 @@ impl FunctionSource {
.kw_args .kw_args
.unlabeled .unlabeled
.as_ref() .as_ref()
.map(|arg| OpArg::new(OpKclValue::from(&arg.1.value), arg.1.source_range)), .map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
labeled_args: op_labeled_args, labeled_args: op_labeled_args,
}, },
source_range: callsite, source_range: callsite,
@ -2703,12 +2665,13 @@ a = foo()
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn test_sensible_error_when_missing_equals_in_kwarg() { async fn test_sensible_error_when_missing_equals_in_kwarg() {
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)"] 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)"]
.into_iter() .into_iter()
.enumerate() .enumerate()
{ {
let program = format!( let program = format!(
"fn foo() {{ return 0 }} "fn foo() {{ return 0 }}
y = 42
z = 0 z = 0
fn f(x, y, z) {{ return 0 }} fn f(x, y, z) {{ return 0 }}
{call}" {call}"
@ -2728,10 +2691,9 @@ fn f(x, y, z) {{ return 0 }}
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn default_param_for_unlabeled() { async fn default_param_for_unlabeled() {
// Tests that the input param for myExtrude is taken from the pipeline value and same-name // Tests that the input param for myExtrude is taken from the pipeline value.
// keyword args.
let ast = r#"fn myExtrude(@sk, length) { let ast = r#"fn myExtrude(@sk, length) {
return extrude(sk, length) return extrude(sk, length = length)
} }
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
|> circle(center = [0, 0], radius = 93.75) |> circle(center = [0, 0], radius = 93.75)
@ -2741,18 +2703,6 @@ sketch001 = startSketchOn(XY)
parse_execute(ast).await.unwrap(); 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")] #[tokio::test(flavor = "multi_thread")]
async fn ascription_in_binop() { async fn ascription_in_binop() {
let ast = r#"foo = tan(0): number(rad) - 4deg"#; let ast = r#"foo = tan(0): number(rad) - 4deg"#;

View File

@ -4220,8 +4220,8 @@ sketch001 = startSketchOn(XY)
result, result,
vec![tower_lsp::lsp_types::ColorInformation { vec![tower_lsp::lsp_types::ColorInformation {
range: tower_lsp::lsp_types::Range { range: tower_lsp::lsp_types::Range {
start: tower_lsp::lsp_types::Position { line: 4, character: 25 }, start: tower_lsp::lsp_types::Position { line: 4, character: 24 },
end: tower_lsp::lsp_types::Position { line: 4, character: 32 }, end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
}, },
color: tower_lsp::lsp_types::Color { color: tower_lsp::lsp_types::Color {
red: 1.0, red: 1.0,
@ -4272,8 +4272,8 @@ sketch001 = startSketchOn(XY)
result, result,
vec![tower_lsp::lsp_types::ColorInformation { vec![tower_lsp::lsp_types::ColorInformation {
range: tower_lsp::lsp_types::Range { range: tower_lsp::lsp_types::Range {
start: tower_lsp::lsp_types::Position { line: 4, character: 25 }, start: tower_lsp::lsp_types::Position { line: 4, character: 24 },
end: tower_lsp::lsp_types::Position { line: 4, character: 32 }, end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
}, },
color: tower_lsp::lsp_types::Color { color: tower_lsp::lsp_types::Color {
red: 1.0, red: 1.0,
@ -4291,8 +4291,8 @@ sketch001 = startSketchOn(XY)
uri: "file:///test.kcl".try_into().unwrap(), uri: "file:///test.kcl".try_into().unwrap(),
}, },
range: tower_lsp::lsp_types::Range { range: tower_lsp::lsp_types::Range {
start: tower_lsp::lsp_types::Position { line: 4, character: 25 }, start: tower_lsp::lsp_types::Position { line: 4, character: 24 },
end: tower_lsp::lsp_types::Position { line: 4, character: 32 }, end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
}, },
color: tower_lsp::lsp_types::Color { color: tower_lsp::lsp_types::Color {
red: 1.0, red: 1.0,

View File

@ -186,7 +186,7 @@ impl<T> Node<T> {
self.comment_start = start; self.comment_start = start;
} }
pub fn map_ref<'a, U: 'a>(&'a self, f: impl Fn(&'a T) -> U) -> Node<U> { pub fn map_ref<'a, U: 'a>(&'a self, f: fn(&'a T) -> U) -> Node<U> {
Node { Node {
inner: f(&self.inner), inner: f(&self.inner),
start: self.start, start: self.start,
@ -438,15 +438,8 @@ impl Node<Program> {
let add_color = |literal: &Node<Literal>| { let add_color = |literal: &Node<Literal>| {
// Check if the string is a color. // Check if the string is a color.
if let Some(c) = literal.value.is_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 { let color = ColorInformation {
range: fixed_source_range.to_lsp_range(code), range: literal.as_source_range().to_lsp_range(code),
color: tower_lsp::lsp_types::Color { color: tower_lsp::lsp_types::Color {
red: c.r, red: c.r,
green: c.g, green: c.g,
@ -505,11 +498,7 @@ impl Node<Program> {
crate::walk::walk(self, |node: crate::walk::Node<'a>| { crate::walk::walk(self, |node: crate::walk::Node<'a>| {
match node { match node {
crate::walk::Node::Literal(literal) => { crate::walk::Node::Literal(literal) => {
// Account for the quotes in the literal. if literal.start == pos_start && literal.end == pos_end && literal.value.is_color().is_some() {
if (literal.start + 1) == pos_start
&& (literal.end - 1) == pos_end
&& literal.value.is_color().is_some()
{
found.replace(true); found.replace(true);
return Ok(true); return Ok(true);
} }
@ -1198,7 +1187,7 @@ impl Expr {
pub fn ident_name(&self) -> Option<&str> { pub fn ident_name(&self) -> Option<&str> {
match self { match self {
Expr::Name(name) => name.local_ident().map(|n| n.inner), Expr::Name(ident) => Some(&ident.name.name),
_ => None, _ => None,
} }
} }
@ -2382,7 +2371,7 @@ impl Name {
pub fn local_ident(&self) -> Option<Node<&str>> { pub fn local_ident(&self) -> Option<Node<&str>> {
if self.path.is_empty() && !self.abs_path { 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 { } else {
None None
} }

View File

@ -2729,17 +2729,6 @@ fn ty(i: &mut TokenSlice) -> PResult<Token> {
keyword(i, "type") 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> { fn keyword(i: &mut TokenSlice, expected: &str) -> PResult<Token> {
any.try_map(|token: Token| match token.token_type { any.try_map(|token: Token| match token.token_type {
TokenType::Keyword if token.value == expected => Ok(token), TokenType::Keyword if token.value == expected => Ok(token),
@ -3154,14 +3143,12 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
NonCode(Node<NonCodeNode>), NonCode(Node<NonCodeNode>),
LabeledArg(LabeledArg), LabeledArg(LabeledArg),
UnlabeledArg(Expr), UnlabeledArg(Expr),
Keyword(Token),
} }
let initial_unlabeled_arg = opt((expression, comma, opt(whitespace)).map(|(arg, _, _)| arg)).parse_next(i)?; let initial_unlabeled_arg = opt((expression, comma, opt(whitespace)).map(|(arg, _, _)| arg)).parse_next(i)?;
let args: Vec<_> = repeat( let args: Vec<_> = repeat(
0.., 0..,
alt(( alt((
terminated(non_code_node.map(ArgPlace::NonCode), whitespace), terminated(non_code_node.map(ArgPlace::NonCode), whitespace),
terminated(any_keyword.map(ArgPlace::Keyword), whitespace),
terminated(labeled_argument, labeled_arg_separator).map(ArgPlace::LabeledArg), terminated(labeled_argument, labeled_arg_separator).map(ArgPlace::LabeledArg),
expression.map(ArgPlace::UnlabeledArg), expression.map(ArgPlace::UnlabeledArg),
)), )),
@ -3177,18 +3164,6 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
ArgPlace::LabeledArg(x) => { ArgPlace::LabeledArg(x) => {
args.push(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) => { ArgPlace::UnlabeledArg(arg) => {
let followed_by_equals = peek((opt(whitespace), equals)).parse_next(i).is_ok(); let followed_by_equals = peek((opt(whitespace), equals)).parse_next(i).is_ok();
if followed_by_equals { if followed_by_equals {
@ -5080,30 +5055,6 @@ 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] #[test]
fn test_sensible_error_when_missing_rhs_of_obj_property() { fn test_sensible_error_when_missing_rhs_of_obj_property() {
for (i, program) in ["{x = 1, y =}"].into_iter().enumerate() { for (i, program) in ["{x = 1, y =}"].into_iter().enumerate() {

View File

@ -1669,6 +1669,7 @@ mod mike_stress_test {
/// Test that KCL is executed correctly. /// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")] #[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() { async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await super::execute(TEST_NAME, true).await
} }
@ -2771,7 +2772,6 @@ mod clone_w_fillets {
/// Test that KCL is executed correctly. /// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[ignore] // turn on when https://github.com/KittyCAD/engine/pull/3380 is merged #[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() { async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await super::execute(TEST_NAME, true).await
} }
@ -3071,45 +3071,3 @@ mod error_inside_fn_also_has_source_range_of_call_site_recursive {
super::execute(TEST_NAME, true).await 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
}
}

View File

@ -59,9 +59,7 @@ impl Arg {
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct KwArgs { pub struct KwArgs {
/// Unlabeled keyword args. Currently only the first arg can be unlabeled. /// Unlabeled keyword args. Currently only the first arg can be unlabeled.
/// If the argument was a local variable, then the first element of the tuple is its name pub unlabeled: Option<Arg>,
/// which may be used to treat this arg as a labelled arg.
pub unlabeled: Option<(Option<String>, Arg)>,
/// Labeled args. /// Labeled args.
pub labeled: IndexMap<String, Arg>, pub labeled: IndexMap<String, Arg>,
pub errors: Vec<Arg>, pub errors: Vec<Arg>,
@ -344,7 +342,6 @@ impl Args {
self.kw_args self.kw_args
.unlabeled .unlabeled
.as_ref() .as_ref()
.map(|(_, a)| a)
.or(self.args.first()) .or(self.args.first())
.or(self.pipe_value.as_ref()) .or(self.pipe_value.as_ref())
} }

View File

@ -48,7 +48,7 @@ async fn call_map_closure(
ctxt: &ExecutorContext, ctxt: &ExecutorContext,
) -> Result<KclValue, KclError> { ) -> Result<KclValue, KclError> {
let kw_args = KwArgs { let kw_args = KwArgs {
unlabeled: Some((None, Arg::new(input, source_range))), unlabeled: Some(Arg::new(input, source_range)),
labeled: Default::default(), labeled: Default::default(),
errors: Vec::new(), errors: Vec::new(),
}; };
@ -104,7 +104,7 @@ async fn call_reduce_closure(
let mut labeled = IndexMap::with_capacity(1); let mut labeled = IndexMap::with_capacity(1);
labeled.insert("accum".to_string(), Arg::new(accum, source_range)); labeled.insert("accum".to_string(), Arg::new(accum, source_range));
let kw_args = KwArgs { let kw_args = KwArgs {
unlabeled: Some((None, Arg::new(elem, source_range))), unlabeled: Some(Arg::new(elem, source_range)),
labeled, labeled,
errors: Vec::new(), errors: Vec::new(),
}; };

View File

@ -177,25 +177,6 @@ async fn get_old_new_child_map(
exec_state: &mut ExecState, exec_state: &mut ExecState,
args: &Args, args: &Args,
) -> Result<HashMap<uuid::Uuid, uuid::Uuid>> { ) -> Result<HashMap<uuid::Uuid, uuid::Uuid>> {
// Get the old geometries entity ids.
let response = args
.send_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityGetAllChildUuids {
entity_id: old_geometry_id,
}),
)
.await?;
let OkWebSocketResponseData::Modeling {
modeling_response:
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids {
entity_ids: old_entity_ids,
}),
} = response
else {
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
};
// Get the new geometries entity ids. // Get the new geometries entity ids.
let response = args let response = args
.send_modeling_cmd( .send_modeling_cmd(
@ -215,6 +196,25 @@ async fn get_old_new_child_map(
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response); anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
}; };
// Get the old geometries entity ids.
let response = args
.send_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityGetAllChildUuids {
entity_id: old_geometry_id,
}),
)
.await?;
let OkWebSocketResponseData::Modeling {
modeling_response:
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids {
entity_ids: old_entity_ids,
}),
} = response
else {
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
};
// Create a map of old entity ids to new entity ids. // Create a map of old entity ids to new entity ids.
Ok(HashMap::from_iter( Ok(HashMap::from_iter(
old_entity_ids old_entity_ids

View File

@ -14,7 +14,7 @@ use super::{args::TyF64, DEFAULT_TOLERANCE};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{types::RuntimeType, ExecState, KclValue, Solid}, execution::{types::RuntimeType, ExecState, KclValue, Solid},
std::{patterns::GeometryTrait, Args}, std::Args,
}; };
/// Union two or more solids into a single solid. /// 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 solid_out_id = exec_state.next_uuid();
let mut solid = solids[0].clone(); let mut solid = solids[0].clone();
solid.set_id(solid_out_id); solid.id = solid_out_id;
let mut new_solids = vec![solid.clone()]; let mut new_solids = vec![solid.clone()];
if args.ctx.no_engine_commands().await { 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 we have more solids, set those as well.
if !extra_solid_ids.is_empty() { if !extra_solid_ids.is_empty() {
solid.set_id(extra_solid_ids[0]); solid.id = extra_solid_ids[0];
new_solids.push(solid.clone()); new_solids.push(solid.clone());
} }
@ -249,7 +249,7 @@ pub(crate) async fn inner_intersect(
let solid_out_id = exec_state.next_uuid(); let solid_out_id = exec_state.next_uuid();
let mut solid = solids[0].clone(); let mut solid = solids[0].clone();
solid.set_id(solid_out_id); solid.id = solid_out_id;
let mut new_solids = vec![solid.clone()]; let mut new_solids = vec![solid.clone()];
if args.ctx.no_engine_commands().await { 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 we have more solids, set those as well.
if !extra_solid_ids.is_empty() { if !extra_solid_ids.is_empty() {
solid.set_id(extra_solid_ids[0]); solid.id = extra_solid_ids[0];
new_solids.push(solid.clone()); new_solids.push(solid.clone());
} }
@ -385,7 +385,7 @@ pub(crate) async fn inner_subtract(
let solid_out_id = exec_state.next_uuid(); let solid_out_id = exec_state.next_uuid();
let mut solid = solids[0].clone(); let mut solid = solids[0].clone();
solid.set_id(solid_out_id); solid.id = solid_out_id;
let mut new_solids = vec![solid.clone()]; let mut new_solids = vec![solid.clone()];
if args.ctx.no_engine_commands().await { 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 we have more solids, set those as well.
if !extra_solid_ids.is_empty() { if !extra_solid_ids.is_empty() {
solid.set_id(extra_solid_ids[0]); solid.id = extra_solid_ids[0];
new_solids.push(solid.clone()); new_solids.push(solid.clone());
} }

View File

@ -424,7 +424,7 @@ async fn make_transform<T: GeometryTrait>(
meta: vec![source_range.into()], meta: vec![source_range.into()],
}; };
let kw_args = KwArgs { let kw_args = KwArgs {
unlabeled: Some((None, Arg::new(repetition_num, source_range))), unlabeled: Some(Arg::new(repetition_num, source_range)),
labeled: Default::default(), labeled: Default::default(),
errors: Vec::new(), errors: Vec::new(),
}; };
@ -598,7 +598,7 @@ fn array_to_point2d(
.map(|val| val.as_point2d().unwrap()) .map(|val| val.as_point2d().unwrap())
} }
pub trait GeometryTrait: Clone { trait GeometryTrait: Clone {
type Set: Into<Vec<Self>> + Clone; type Set: Into<Vec<Self>> + Clone;
fn id(&self) -> Uuid; fn id(&self) -> Uuid;
fn original_id(&self) -> Uuid; fn original_id(&self) -> Uuid;
@ -608,7 +608,6 @@ pub trait GeometryTrait: Clone {
source_ranges: Vec<SourceRange>, source_ranges: Vec<SourceRange>,
exec_state: &mut ExecState, exec_state: &mut ExecState,
) -> Result<[TyF64; 3], KclError>; ) -> Result<[TyF64; 3], KclError>;
#[allow(async_fn_in_trait)]
async fn flush_batch(args: &Args, exec_state: &mut ExecState, set: &Self::Set) -> Result<(), KclError>; async fn flush_batch(args: &Args, exec_state: &mut ExecState, set: &Self::Set) -> Result<(), KclError>;
} }
@ -642,8 +641,6 @@ impl GeometryTrait for Solid {
type Set = Vec<Solid>; type Set = Vec<Solid>;
fn set_id(&mut self, id: Uuid) { fn set_id(&mut self, id: Uuid) {
self.id = id; self.id = id;
// We need this for in extrude.rs when you sketch on face.
self.sketch.id = id;
} }
fn id(&self) -> Uuid { fn id(&self) -> Uuid {

View File

@ -3,7 +3,7 @@
use anyhow::Result; use anyhow::Result;
use kcl_derive_docs::stdlib; use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd}; use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
use kittycad_modeling_cmds::{self as kcmc, shared::RelativeTo}; use kittycad_modeling_cmds::{self as kcmc};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::Serialize; use serde::Serialize;
@ -37,20 +37,11 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
)?; )?;
let sectional = args.get_kw_arg_opt("sectional")?; let sectional = args.get_kw_arg_opt("sectional")?;
let tolerance: Option<TyF64> = args.get_kw_arg_opt_typed("tolerance", &RuntimeType::length(), exec_state)?; 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_start = args.get_kw_arg_opt("tagStart")?;
let tag_end = args.get_kw_arg_opt("tagEnd")?; let tag_end = args.get_kw_arg_opt("tagEnd")?;
let value = inner_sweep( let value = inner_sweep(
sketches, sketches, path, sectional, tolerance, tag_start, tag_end, exec_state, args,
path,
sectional,
tolerance,
relative_to,
tag_start,
tag_end,
exec_state,
args,
) )
.await?; .await?;
Ok(value.into()) Ok(value.into())
@ -112,7 +103,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn(YZ) /// springSketch = startSketchOn(YZ)
/// |> circle( center = [0, 0], radius = 1) /// |> circle( center = [0, 0], radius = 1)
/// |> sweep(path = helixPath, relativeTo = "sketchPlane") /// |> sweep(path = helixPath)
/// ``` /// ```
/// ///
/// ```no_run /// ```no_run
@ -167,7 +158,6 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
path = { docs = "The path to sweep the sketch along" }, 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." }, 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" }, 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_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" }, tag_end = { docs = "A named tag for the face at the end of the sweep" },
}, },
@ -179,7 +169,6 @@ async fn inner_sweep(
path: SweepPath, path: SweepPath,
sectional: Option<bool>, sectional: Option<bool>,
tolerance: Option<TyF64>, tolerance: Option<TyF64>,
relative_to: Option<String>,
tag_start: Option<TagNode>, tag_start: Option<TagNode>,
tag_end: Option<TagNode>, tag_end: Option<TagNode>,
exec_state: &mut ExecState, exec_state: &mut ExecState,
@ -189,16 +178,6 @@ async fn inner_sweep(
SweepPath::Sketch(sketch) => sketch.id.into(), SweepPath::Sketch(sketch) => sketch.id.into(),
SweepPath::Helix(helix) => helix.value.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(); let mut solids = Vec::new();
for sketch in &sketches { for sketch in &sketches {
@ -210,7 +189,6 @@ async fn inner_sweep(
trajectory, trajectory,
sectional: sectional.unwrap_or(false), sectional: sectional.unwrap_or(false),
tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)), tolerance: LengthUnit(tolerance.as_ref().map(|t| t.to_mm()).unwrap_or(DEFAULT_TOLERANCE)),
relative_to,
}), }),
) )
.await?; .await?;

View File

@ -83,7 +83,7 @@ export END = 'end'
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn(YZ) /// springSketch = startSketchOn(YZ)
/// |> circle( center = [0, 0], radius = 0.5) /// |> circle( center = [0, 0], radius = 0.5)
/// |> sweep(path = helixPath, relativeTo = "sketchPlane") /// |> sweep(path = helixPath)
/// ``` /// ```
/// ///
/// ``` /// ```
@ -104,7 +104,7 @@ export END = 'end'
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn(XY) /// springSketch = startSketchOn(XY)
/// |> circle( center = [0, 0], radius = 0.5 ) /// |> circle( center = [0, 0], radius = 0.5 )
/// |> sweep(path = helixPath, relativeTo = "sketchPlane") /// |> sweep(path = helixPath)
/// ``` /// ```
/// ///
/// ``` /// ```
@ -124,7 +124,7 @@ export END = 'end'
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn(XY) /// springSketch = startSketchOn(XY)
/// |> circle( center = [0, 0], radius = 1 ) /// |> circle( center = [0, 0], radius = 1 )
/// |> sweep(path = helixPath, relativeTo = "sketchPlane") /// |> sweep(path = helixPath)
/// ``` /// ```
/// ///
/// ``` /// ```
@ -413,7 +413,7 @@ export fn offsetPlane(
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// sweepedSpring = clone(springSketch) /// sweepedSpring = clone(springSketch)
/// |> translate(x=100) /// |> translate(x=100)
/// |> sweep(path = helixPath, relativeTo = "sketchPlane") /// |> sweep(path = helixPath)
/// ``` /// ```
/// ///
/// ```kcl /// ```kcl

View File

@ -1,349 +0,0 @@
---
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]"
}
}
]

View File

@ -1,937 +0,0 @@
---
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
}
}

View File

@ -1,26 +0,0 @@
---
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
╰────

View File

@ -1,15 +0,0 @@
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)

View File

@ -1,116 +0,0 @@
---
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
}
]

View File

@ -1,19 +0,0 @@
---
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)

View File

@ -4,8 +4,9 @@ description: Error from executing execute_engine_error_return.kcl
--- ---
KCL Engine error KCL Engine error
× engine: The path is not closed. Solid2D construction requires a closed × engine: Modeling command failed: [ApiError { error_code: BadRequest,
path! message: "The path is not closed. Solid2D construction requires a closed
│ path!" }]
╭─[7:6] ╭─[7:6]
6 │ |> line(end = [-11.53311, 2.81559]) 6 │ |> line(end = [-11.53311, 2.81559])
7 │ |> extrude(length = 4) 7 │ |> extrude(length = 4)

View File

@ -1012,41 +1012,8 @@ description: Artifact commands import_mesh_clone.kcl
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
"command": { "command": {
"type": "set_object_transform", "type": "entity_get_all_child_uuids",
"object_id": "[uuid]", "entity_id": "[uuid]"
"transforms": [
{
"translate": {
"property": {
"x": 1020.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.5,
"roughness": 0.5,
"ambient_occlusion": 0.0
} }
} }
] ]

View File

@ -2,9 +2,18 @@
source: kcl-lib/src/simulation_tests.rs source: kcl-lib/src/simulation_tests.rs
description: Error from executing import_mesh_clone.kcl description: Error from executing import_mesh_clone.kcl
--- ---
KCL Engine error KCL Internal error
× engine: Modeling command failed: websocket closed early × internal: failed to fix tags and references: engine: KclErrorDetails
╭──── │ { source_ranges: [SourceRange([60, 72, 0])], message: "Modeling command
13 ) 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(
╰────

View File

@ -7,25 +7,28 @@ description: Operations executed import_mesh_clone.kcl
"type": "GroupBegin", "type": "GroupBegin",
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "cube.obj", "name": "cube",
"moduleId": 0 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },
{
"type": "KclStdLibCall",
"name": "clone",
"unlabeledArg": {
"value": {
"type": "ImportedGeometry",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{ {
"type": "GroupEnd" "type": "GroupEnd"
},
{
"isError": true,
"labeledArgs": {
"geometry": {
"value": {
"type": "ImportedGeometry",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
},
"name": "clone",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
} }
] ]

View File

@ -5121,8 +5121,7 @@ description: Artifact commands bench.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -5133,8 +5132,7 @@ description: Artifact commands bench.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
} }
] ]

View File

@ -905,8 +905,7 @@ description: Artifact commands cold-plate.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {

View File

@ -5575,8 +5575,7 @@ description: Artifact commands cpu-cooler.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -6110,8 +6109,7 @@ description: Artifact commands cpu-cooler.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -9468,8 +9466,7 @@ description: Artifact commands cpu-cooler.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -9600,8 +9597,7 @@ description: Artifact commands cpu-cooler.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -10119,8 +10115,7 @@ description: Artifact commands cpu-cooler.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -10251,8 +10246,7 @@ description: Artifact commands cpu-cooler.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {

View File

@ -456,7 +456,13 @@ description: Result of parsing enclosure.kcl
}, },
{ {
"type": "LabeledArg", "type": "LabeledArg",
"label": null, "label": {
"commentStart": 0,
"end": 0,
"name": "length",
"start": 0,
"type": "Identifier"
},
"arg": { "arg": {
"abs_path": false, "abs_path": false,
"commentStart": 0, "commentStart": 0,
@ -3172,7 +3178,13 @@ description: Result of parsing enclosure.kcl
}, },
{ {
"type": "LabeledArg", "type": "LabeledArg",
"label": null, "label": {
"commentStart": 0,
"end": 0,
"name": "length",
"start": 0,
"type": "Identifier"
},
"arg": { "arg": {
"abs_path": false, "abs_path": false,
"commentStart": 0, "commentStart": 0,

View File

@ -28,9 +28,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 476, "commentStart": 485,
"end": 497, "end": 506,
"start": 476, "start": 485,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB001" "value": "rectangleSegmentB001"
}, },
@ -41,9 +41,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 599, "commentStart": 608,
"end": 620, "end": 629,
"start": 599, "start": 608,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC001" "value": "rectangleSegmentC001"
}, },
@ -54,9 +54,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 690, "commentStart": 699,
"end": 711, "end": 720,
"start": 690, "start": 699,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD001" "value": "rectangleSegmentD001"
}, },
@ -102,9 +102,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 476, "commentStart": 485,
"end": 497, "end": 506,
"start": 476, "start": 485,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB001" "value": "rectangleSegmentB001"
}, },
@ -127,9 +127,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 599, "commentStart": 608,
"end": 620, "end": 629,
"start": 599, "start": 608,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC001" "value": "rectangleSegmentC001"
}, },
@ -152,9 +152,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 690, "commentStart": 699,
"end": 711, "end": 720,
"start": 690, "start": 699,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD001" "value": "rectangleSegmentD001"
}, },
@ -354,9 +354,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -367,9 +367,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -380,9 +380,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -393,9 +393,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },
@ -416,9 +416,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -441,9 +441,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -466,9 +466,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -491,9 +491,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },
@ -693,9 +693,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 4129, "commentStart": 4147,
"end": 4150, "end": 4168,
"start": 4129, "start": 4147,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA003" "value": "rectangleSegmentA003"
}, },
@ -706,9 +706,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 4256, "commentStart": 4274,
"end": 4277, "end": 4295,
"start": 4256, "start": 4274,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB003" "value": "rectangleSegmentB003"
}, },
@ -719,9 +719,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 4379, "commentStart": 4397,
"end": 4400, "end": 4418,
"start": 4379, "start": 4397,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC003" "value": "rectangleSegmentC003"
}, },
@ -732,9 +732,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 4470, "commentStart": 4488,
"end": 4491, "end": 4509,
"start": 4470, "start": 4488,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD003" "value": "rectangleSegmentD003"
}, },
@ -755,9 +755,9 @@ description: Variables in memory after executing enclosure.kcl
3.0 3.0
], ],
"tag": { "tag": {
"commentStart": 4129, "commentStart": 4147,
"end": 4150, "end": 4168,
"start": 4129, "start": 4147,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA003" "value": "rectangleSegmentA003"
}, },
@ -780,9 +780,9 @@ description: Variables in memory after executing enclosure.kcl
3.0 3.0
], ],
"tag": { "tag": {
"commentStart": 4256, "commentStart": 4274,
"end": 4277, "end": 4295,
"start": 4256, "start": 4274,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB003" "value": "rectangleSegmentB003"
}, },
@ -805,9 +805,9 @@ description: Variables in memory after executing enclosure.kcl
172.0 172.0
], ],
"tag": { "tag": {
"commentStart": 4379, "commentStart": 4397,
"end": 4400, "end": 4418,
"start": 4379, "start": 4397,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC003" "value": "rectangleSegmentC003"
}, },
@ -830,9 +830,9 @@ description: Variables in memory after executing enclosure.kcl
172.0 172.0
], ],
"tag": { "tag": {
"commentStart": 4470, "commentStart": 4488,
"end": 4491, "end": 4509,
"start": 4470, "start": 4488,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD003" "value": "rectangleSegmentD003"
}, },
@ -896,9 +896,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -909,9 +909,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -922,9 +922,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -935,9 +935,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },
@ -958,9 +958,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -983,9 +983,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -1008,9 +1008,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -1033,9 +1033,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },
@ -1495,9 +1495,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 476, "commentStart": 485,
"end": 497, "end": 506,
"start": 476, "start": 485,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB001" "value": "rectangleSegmentB001"
}, },
@ -1520,9 +1520,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 599, "commentStart": 608,
"end": 620, "end": 629,
"start": 599, "start": 608,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC001" "value": "rectangleSegmentC001"
}, },
@ -1545,9 +1545,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 690, "commentStart": 699,
"end": 711, "end": 720,
"start": 690, "start": 699,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD001" "value": "rectangleSegmentD001"
}, },
@ -1669,9 +1669,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -1694,9 +1694,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -1719,9 +1719,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -1744,9 +1744,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },
@ -1868,9 +1868,9 @@ description: Variables in memory after executing enclosure.kcl
3.0 3.0
], ],
"tag": { "tag": {
"commentStart": 4129, "commentStart": 4147,
"end": 4150, "end": 4168,
"start": 4129, "start": 4147,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA003" "value": "rectangleSegmentA003"
}, },
@ -1893,9 +1893,9 @@ description: Variables in memory after executing enclosure.kcl
3.0 3.0
], ],
"tag": { "tag": {
"commentStart": 4256, "commentStart": 4274,
"end": 4277, "end": 4295,
"start": 4256, "start": 4274,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB003" "value": "rectangleSegmentB003"
}, },
@ -1918,9 +1918,9 @@ description: Variables in memory after executing enclosure.kcl
172.0 172.0
], ],
"tag": { "tag": {
"commentStart": 4379, "commentStart": 4397,
"end": 4400, "end": 4418,
"start": 4379, "start": 4397,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC003" "value": "rectangleSegmentC003"
}, },
@ -1943,9 +1943,9 @@ description: Variables in memory after executing enclosure.kcl
172.0 172.0
], ],
"tag": { "tag": {
"commentStart": 4470, "commentStart": 4488,
"end": 4491, "end": 4509,
"start": 4470, "start": 4488,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD003" "value": "rectangleSegmentD003"
}, },
@ -2009,9 +2009,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -2022,9 +2022,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -2035,9 +2035,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -2048,9 +2048,9 @@ description: Variables in memory after executing enclosure.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },
@ -2071,9 +2071,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2436, "commentStart": 2445,
"end": 2457, "end": 2466,
"start": 2436, "start": 2445,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentA002" "value": "rectangleSegmentA002"
}, },
@ -2096,9 +2096,9 @@ description: Variables in memory after executing enclosure.kcl
0.0 0.0
], ],
"tag": { "tag": {
"commentStart": 2532, "commentStart": 2550,
"end": 2553, "end": 2571,
"start": 2532, "start": 2550,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentB002" "value": "rectangleSegmentB002"
}, },
@ -2121,9 +2121,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2655, "commentStart": 2673,
"end": 2676, "end": 2694,
"start": 2655, "start": 2673,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentC002" "value": "rectangleSegmentC002"
}, },
@ -2146,9 +2146,9 @@ description: Variables in memory after executing enclosure.kcl
175.0 175.0
], ],
"tag": { "tag": {
"commentStart": 2746, "commentStart": 2764,
"end": 2767, "end": 2785,
"start": 2746, "start": 2764,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "rectangleSegmentD002" "value": "rectangleSegmentD002"
}, },

View File

@ -1597,8 +1597,7 @@ description: Artifact commands exhaust-manifold.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -1609,8 +1608,7 @@ description: Artifact commands exhaust-manifold.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -1621,8 +1619,7 @@ description: Artifact commands exhaust-manifold.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {
@ -1633,8 +1630,7 @@ description: Artifact commands exhaust-manifold.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {

View File

@ -4490,8 +4490,7 @@ description: Artifact commands utility-sink.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {

File diff suppressed because it is too large Load Diff

View File

@ -4,17 +4,19 @@ description: Operations executed mike_stress_test.kcl
--- ---
[ [
{ {
"labeledArgs": {}, "labeledArgs": {
"planeOrSolid": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn", "name": "startSketchOn",
"sourceRange": [], "sourceRange": [],
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": { "unlabeledArg": null
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
}, },
{ {
"labeledArgs": { "labeledArgs": {

View File

@ -26043,8 +26043,10 @@ description: Variables in memory after executing mike_stress_test.kcl
} }
], ],
"on": { "on": {
"artifactId": "[uuid]", "type": "plane",
"id": "[uuid]", "id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
@ -26053,14 +26055,12 @@ description: Variables in memory after executing mike_stress_test.kcl
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane",
"value": "XY",
"xAxis": { "xAxis": {
"x": 1.0, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.0, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Mm"
} }
}, },
"yAxis": { "yAxis": {
@ -26068,7 +26068,7 @@ description: Variables in memory after executing mike_stress_test.kcl
"y": 1.0, "y": 1.0,
"z": 0.0, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Mm"
} }
} }
}, },

View File

@ -4,7 +4,8 @@ description: Error from executing pattern_into_union.kcl
--- ---
KCL Engine error KCL Engine error
× engine: More than 2 solids were passed to the low-level CSG method × engine: Modeling command failed: [ApiError { error_code: InternalEngine,
│ message: "More than 2 solids were passed to the low-level CSG method" }]
╭─[67:1] ╭─[67:1]
66 │ 66 │
67 │ union([base,endTabs]) 67 │ union([base,endTabs])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +0,0 @@
@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)

View File

@ -1,264 +0,0 @@
---
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": []
}
}
]

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

View File

@ -1,62 +0,0 @@
---
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)

View File

@ -417,8 +417,7 @@ description: Artifact commands subtract_regression03.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {

View File

@ -394,8 +394,7 @@ description: Artifact commands subtract_regression05.kcl
"target": "[uuid]", "target": "[uuid]",
"trajectory": "[uuid]", "trajectory": "[uuid]",
"sectional": false, "sectional": false,
"tolerance": 0.0000001, "tolerance": 0.0000001
"relative_to": "trajectory_curve"
} }
}, },
{ {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "kcl-python-bindings" name = "kcl-python-bindings"
version = "0.3.71" version = "0.3.69"
edition = "2021" edition = "2021"
repository = "https://github.com/kittycad/modeling-app" repository = "https://github.com/kittycad/modeling-app"
exclude = ["tests/*", "files/*", "venv/*"] exclude = ["tests/*", "files/*", "venv/*"]

View File

@ -227,31 +227,6 @@ async fn new_context_state(current_file: Option<std::path::PathBuf>) -> Result<(
Ok((ctx, state)) Ok((ctx, state))
} }
/// Parse the kcl code from a file path.
#[pyfunction]
async fn parse(path: String) -> PyResult<()> {
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(())
})
.await
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
}
/// Parse the kcl code.
#[pyfunction]
fn parse_code(code: String) -> PyResult<()> {
let _program = kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
Ok(())
}
/// Execute the kcl code from a file path. /// Execute the kcl code from a file path.
#[pyfunction] #[pyfunction]
async fn execute(path: String) -> PyResult<()> { async fn execute(path: String) -> PyResult<()> {
@ -559,8 +534,6 @@ fn kcl(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<Discovered>()?; m.add_class::<Discovered>()?;
// Add our functions to the module. // 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, m)?)?;
m.add_function(wrap_pyfunction!(execute_code, m)?)?; m.add_function(wrap_pyfunction!(execute_code, m)?)?;
m.add_function(wrap_pyfunction!(execute_and_snapshot, m)?)?; m.add_function(wrap_pyfunction!(execute_and_snapshot, m)?)?;

View File

@ -39,33 +39,6 @@ async def test_kcl_execute():
await kcl.execute(lego_file) 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.
await kcl.parse(lego_file)
@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
kcl.parse_code(code)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_kcl_execute_code(): async def test_kcl_execute_code():
# Read from a file. # Read from a file.
@ -124,7 +97,9 @@ async def test_kcl_execute_and_snapshot():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_kcl_execute_and_snapshot_dir(): async def test_kcl_execute_and_snapshot_dir():
# Read from a file. # 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 image_bytes is not None
assert len(image_bytes) > 0 assert len(image_bytes) > 0
@ -154,12 +129,10 @@ def test_kcl_format():
assert formatted_code is not None assert formatted_code is not None
assert len(formatted_code) > 0 assert len(formatted_code) > 0
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_kcl_format_dir(): async def test_kcl_format_dir():
await kcl.format_dir(car_wheel_dir) await kcl.format_dir(car_wheel_dir)
def test_kcl_lint(): def test_kcl_lint():
# Read from a file. # Read from a file.
with open(os.path.join(files_dir, "box_with_linter_errors.kcl"), "r") as f: with open(os.path.join(files_dir, "box_with_linter_errors.kcl"), "r") as f:

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-test-server" name = "kcl-test-server"
description = "A test server for KCL" description = "A test server for KCL"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "kcl-to-core" name = "kcl-to-core"
description = "Utility methods to convert kcl to engine core executable tests" description = "Utility methods to convert kcl to engine core executable tests"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "kcl-wasm-lib" name = "kcl-wasm-lib"
version = "0.1.71" version = "0.1.69"
edition = "2021" edition = "2021"
repository = "https://github.com/KittyCAD/modeling-app" repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.83" rust-version = "1.83"

View File

@ -29,9 +29,15 @@ import { useSelector } from '@xstate/react'
import type { MouseEventHandler } from 'react' import type { MouseEventHandler } from 'react'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { useRouteLoaderData } from 'react-router-dom' import { useRouteLoaderData } from 'react-router-dom'
import { isPlaywright } from '@src/lib/isPlaywright'
import {
engineStreamZoomToFit,
engineViewIsometricWithGeometryPresent,
engineViewIsometricWithoutGeometryPresent,
} from '@src/lib/utils'
import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants'
import { createThumbnailPNGOnDesktop } from '@src/lib/screenshot' import { createThumbnailPNGOnDesktop } from '@src/lib/screenshot'
import type { SettingsViaQueryString } from '@src/lib/settings/settingsTypes' import type { SettingsViaQueryString } from '@src/lib/settings/settingsTypes'
import { resetCameraPosition } from '@src/lib/resetCameraPosition'
export const EngineStream = (props: { export const EngineStream = (props: {
pool: string | null pool: string | null
@ -98,7 +104,31 @@ export const EngineStream = (props: {
kmp kmp
.then(async () => { .then(async () => {
await resetCameraPosition() // Gotcha: Playwright E2E tests will be zoom_to_fit, when you try to recreate the e2e test manually
// your localhost will do view_isometric. Turn this boolean on to have the same experience when manually
// debugging e2e tests
// We need a padding of 0.1 for zoom_to_fit for all E2E tests since they were originally
// written with zoom_to_fit with padding 0.1
const padding = 0.1
if (isPlaywright()) {
await engineStreamZoomToFit({ engineCommandManager, padding })
} else {
// If the scene is empty you cannot use view_isometric, it will not move the camera
if (kclManager.isAstBodyEmpty(kclManager.ast)) {
await engineViewIsometricWithoutGeometryPresent({
engineCommandManager,
unit:
kclManager.fileSettings.defaultLengthUnit ||
DEFAULT_DEFAULT_LENGTH_UNIT,
})
} else {
await engineViewIsometricWithGeometryPresent({
engineCommandManager,
padding,
})
}
}
if (project && project.path) { if (project && project.path) {
createThumbnailPNGOnDesktop({ createThumbnailPNGOnDesktop({

View File

@ -13,7 +13,6 @@ import { VIEW_NAMES_SEMANTIC } from '@src/lib/constants'
import { sceneInfra } from '@src/lib/singletons' import { sceneInfra } from '@src/lib/singletons'
import { reportRejection } from '@src/lib/trap' import { reportRejection } from '@src/lib/trap'
import { useSettings } from '@src/lib/singletons' import { useSettings } from '@src/lib/singletons'
import { resetCameraPosition } from '@src/lib/resetCameraPosition'
export function useViewControlMenuItems() { export function useViewControlMenuItems() {
const { state: modelingState, send: modelingSend } = useModelingContext() const { state: modelingState, send: modelingSend } = useModelingContext()
@ -39,7 +38,7 @@ export function useViewControlMenuItems() {
<ContextMenuDivider />, <ContextMenuDivider />,
<ContextMenuItem <ContextMenuItem
onClick={() => { onClick={() => {
resetCameraPosition().catch(reportRejection) sceneInfra.camControls.resetCameraPosition().catch(reportRejection)
}} }}
disabled={shouldLockView} disabled={shouldLockView}
> >

View File

@ -111,7 +111,7 @@ function discoverColorsInKCL(
} }
export function parseColorLiteral(colorLiteral: string): ColorData | null { export function parseColorLiteral(colorLiteral: string): ColorData | null {
const literal = colorLiteral.replace(/"/g, '').replace(/'/g, '') const literal = colorLiteral.replace(/"/g, '')
const match = hexRegex.exec(literal) const match = hexRegex.exec(literal)
if (!match) { if (!match) {
return null return null

View File

@ -212,12 +212,6 @@ code {
z-index: 99999999999 !important; z-index: 99999999999 !important;
} }
.cm-rename-popup input {
/* use black text on white background in both light and dark mode */
color: black !important;
background: white !important;
}
@keyframes blink { @keyframes blink {
0%, 0%,
100% { 100% {

View File

@ -151,10 +151,6 @@ export class KclManager {
// These belonged to the previous file // These belonged to the previous file
this.lastSuccessfulOperations = [] this.lastSuccessfulOperations = []
this.lastSuccessfulVariables = {} this.lastSuccessfulVariables = {}
// Without this, when leaving a project which has errors and opening another project which doesn't,
// you'd see the errors from the previous project for a short time until the new code is executed.
this._errors = []
} }
get variables() { get variables() {

View File

@ -23,7 +23,7 @@ import {
getThemeColorForEngine, getThemeColorForEngine,
} from '@src/lib/theme' } from '@src/lib/theme'
import { reportRejection } from '@src/lib/trap' import { reportRejection } from '@src/lib/trap'
import { binaryToUuid, isArray, uuidv4 } from '@src/lib/utils' import { binaryToUuid, uuidv4 } from '@src/lib/utils'
const pingIntervalMs = 1_000 const pingIntervalMs = 1_000
@ -2010,20 +2010,12 @@ export class EngineCommandManager extends EventTarget {
return Promise.reject(EXECUTE_AST_INTERRUPT_ERROR_MESSAGE) return Promise.reject(EXECUTE_AST_INTERRUPT_ERROR_MESSAGE)
} }
try { const resp = await this.sendCommand(id, {
const resp = await this.sendCommand(id, { command,
command, range,
range, idToRangeMap,
idToRangeMap, })
}) return BSON.serialize(resp[0])
return BSON.serialize(resp[0])
} catch (e) {
if (isArray(e) && e.length > 0) {
return Promise.reject(JSON.stringify(e[0]))
}
return Promise.reject(JSON.stringify(e))
}
} }
/** /**
* Common send command function used for both modeling and scene commands * Common send command function used for both modeling and scene commands

View File

@ -31,7 +31,7 @@ const save_ = async (file: ModelingAppFile, toastId: string) => {
) )
toast.success(EXPORT_TOAST_MESSAGES.SUCCESS + ' [TEST]', { toast.success(EXPORT_TOAST_MESSAGES.SUCCESS + ' [TEST]', {
id: toastId, id: toastId,
duration: 10_000, duration: 5_000,
}) })
return return
} }

View File

@ -1,40 +0,0 @@
import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants'
import { isPlaywright } from '@src/lib/isPlaywright'
import { engineCommandManager, kclManager } from '@src/lib/singletons'
import {
engineStreamZoomToFit,
engineViewIsometricWithoutGeometryPresent,
engineViewIsometricWithGeometryPresent,
} from '@src/lib/utils'
/**
* Reset the camera position to a baseline, which is isometric for
* normal users and a deprecated "front-down" view for playwright tests.
*
* Gotcha: Playwright E2E tests will be zoom_to_fit, when you try to recreate the e2e test manually
* your localhost will do view_isometric. Turn this boolean on to have the same experience when manually
* debugging e2e tests
*/
export async function resetCameraPosition() {
// We need a padding of 0.1 for zoom_to_fit for all E2E tests since they were originally
// written with zoom_to_fit with padding 0.1
const padding = 0.1
if (isPlaywright()) {
await engineStreamZoomToFit({ engineCommandManager, padding })
} else {
// If the scene is empty you cannot use view_isometric, it will not move the camera
if (kclManager.isAstBodyEmpty(kclManager.ast)) {
await engineViewIsometricWithoutGeometryPresent({
engineCommandManager,
unit:
kclManager.fileSettings.defaultLengthUnit ||
DEFAULT_DEFAULT_LENGTH_UNIT,
})
} else {
await engineViewIsometricWithGeometryPresent({
engineCommandManager,
padding,
})
}
}
}

View File

@ -139,20 +139,18 @@ export const settingsMachine = setup({
return () => darkModeMatcher?.removeEventListener('change', listener) return () => darkModeMatcher?.removeEventListener('change', listener)
}), }),
registerCommands: fromCallback< registerCommands: fromCallback<
{ type: 'update'; settings: SettingsType }, { type: 'update' },
{ settings: SettingsType; actor: AnyActorRef } { settings: SettingsType; actor: AnyActorRef }
>(({ input, receive, system }) => { >(({ input, receive, system }) => {
// This assumes this actor is running in a system with a command palette // This assumes this actor is running in a system with a command palette
const commandBarActor = system.get(ACTOR_IDS.COMMAND_BAR) const commandBarActor = system.get(ACTOR_IDS.COMMAND_BAR)
// If the user wants to hide the settings commands // If the user wants to hide the settings commands
//from the command bar don't add them. //from the command bar don't add them.
if (settings.commandBar.includeSettings.current === false) { if (settings.commandBar.includeSettings.current === false) return
return
}
let commands: Command[] = [] let commands: Command[] = []
const updateCommands = (newSettings: SettingsType) => const updateCommands = () =>
settingsWithCommandConfigs(newSettings) settingsWithCommandConfigs(input.settings)
.map((type) => .map((type) =>
createSettingsCommand({ createSettingsCommand({
type, type,
@ -177,19 +175,14 @@ export const settingsMachine = setup({
data: { commands: commands }, data: { commands: commands },
}) })
receive(({ type, settings: newSettings }) => { receive((event) => {
if (type !== 'update') { if (event.type !== 'update') return
return
}
removeCommands() removeCommands()
commands = commands = updateCommands()
newSettings.commandBar.includeSettings.current === false
? []
: updateCommands(newSettings)
addCommands() addCommands()
}) })
commands = updateCommands(settings) commands = updateCommands()
addCommands() addCommands()
return () => { return () => {
@ -212,9 +205,7 @@ export const settingsMachine = setup({
const sceneInfra = rootContext.sceneInfra const sceneInfra = rootContext.sceneInfra
const sceneEntitiesManager = rootContext.sceneEntitiesManager const sceneEntitiesManager = rootContext.sceneEntitiesManager
if (!sceneInfra || !sceneEntitiesManager) { if (!sceneInfra || !sceneEntitiesManager) return
return
}
const opposingTheme = getOppositeTheme(context.app.theme.current) const opposingTheme = getOppositeTheme(context.app.theme.current)
sceneInfra.theme = opposingTheme sceneInfra.theme = opposingTheme
sceneEntitiesManager.updateSegmentBaseColor(opposingTheme) sceneEntitiesManager.updateSegmentBaseColor(opposingTheme)
@ -222,17 +213,13 @@ export const settingsMachine = setup({
setAllowOrbitInSketchMode: ({ context, self }) => { setAllowOrbitInSketchMode: ({ context, self }) => {
const rootContext = self.system.get('root').getSnapshot().context const rootContext = self.system.get('root').getSnapshot().context
const sceneInfra = rootContext.sceneInfra const sceneInfra = rootContext.sceneInfra
if (!sceneInfra.camControls) { if (!sceneInfra.camControls) return
return
}
sceneInfra.camControls._setting_allowOrbitInSketchMode = sceneInfra.camControls._setting_allowOrbitInSketchMode =
context.app.allowOrbitInSketchMode.current context.app.allowOrbitInSketchMode.current
// ModelingMachineProvider will do a use effect to trigger the camera engine sync // ModelingMachineProvider will do a use effect to trigger the camera engine sync
}, },
toastSuccess: ({ event }) => { toastSuccess: ({ event }) => {
if (!('data' in event)) { if (!('data' in event)) return
return
}
const eventParts = event.type.replace(/^set./, '').split('.') as [ const eventParts = event.type.replace(/^set./, '').split('.') as [
keyof typeof settings, keyof typeof settings,
string, string,
@ -448,22 +435,6 @@ export const settingsMachine = setup({
actions: ['setSettingAtLevel', 'setThemeColor'], actions: ['setSettingAtLevel', 'setThemeColor'],
}, },
'set.commandBar.includeSettings': {
target: 'persisting settings',
actions: [
'setSettingAtLevel',
'toastSuccess',
sendTo(
'registerCommands',
({ context: { currentProject: _, ...settings } }) => ({
type: 'update',
settings,
})
),
],
},
'set.modeling.defaultUnit': { 'set.modeling.defaultUnit': {
target: 'persisting settings', target: 'persisting settings',
@ -526,13 +497,6 @@ export const settingsMachine = setup({
'setClientTheme', 'setClientTheme',
'setAllowOrbitInSketchMode', 'setAllowOrbitInSketchMode',
'sendThemeToWatcher', 'sendThemeToWatcher',
sendTo(
'registerCommands',
({ context: { currentProject: _, ...settings } }) => ({
type: 'update',
settings,
})
),
], ],
}, },
@ -546,13 +510,6 @@ export const settingsMachine = setup({
'setClientTheme', 'setClientTheme',
'setAllowOrbitInSketchMode', 'setAllowOrbitInSketchMode',
'sendThemeToWatcher', 'sendThemeToWatcher',
sendTo(
'registerCommands',
({ context: { currentProject: _, ...settings } }) => ({
type: 'update',
settings,
})
),
], ],
}, },
@ -572,13 +529,7 @@ export const settingsMachine = setup({
'clearProjectSettings', 'clearProjectSettings',
'clearCurrentProject', 'clearCurrentProject',
'setThemeColor', 'setThemeColor',
sendTo( sendTo('registerCommands', { type: 'update' }),
'registerCommands',
({ context: { currentProject: _, ...settings } }) => ({
type: 'update',
settings,
})
),
], ],
}, },
}, },
@ -631,13 +582,6 @@ export const settingsMachine = setup({
'setClientTheme', 'setClientTheme',
'setAllowOrbitInSketchMode', 'setAllowOrbitInSketchMode',
'sendThemeToWatcher', 'sendThemeToWatcher',
sendTo(
'registerCommands',
({ context: { currentProject: _, ...settings } }) => ({
type: 'update',
settings,
})
),
], ],
}, },
onError: { onError: {
@ -668,13 +612,7 @@ export const settingsMachine = setup({
'setClientTheme', 'setClientTheme',
'setAllowOrbitInSketchMode', 'setAllowOrbitInSketchMode',
'sendThemeToWatcher', 'sendThemeToWatcher',
sendTo( sendTo('registerCommands', { type: 'update' }),
'registerCommands',
({ context: { currentProject: _, ...settings } }) => ({
type: 'update',
settings,
})
),
], ],
}, },
onError: 'idle', onError: 'idle',

View File

@ -1,5 +1,6 @@
import { Dialog, Transition } from '@headlessui/react' import { Dialog, Transition } from '@headlessui/react'
import { Fragment, useEffect, useRef } from 'react' import { Fragment, useEffect, useRef } from 'react'
import { useHotkeys } from 'react-hotkeys-hook'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom' import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import { CustomIcon } from '@src/components/CustomIcon' import { CustomIcon } from '@src/components/CustomIcon'
@ -9,19 +10,14 @@ import { KeybindingsSectionsList } from '@src/components/Settings/KeybindingsSec
import { SettingsSearchBar } from '@src/components/Settings/SettingsSearchBar' import { SettingsSearchBar } from '@src/components/Settings/SettingsSearchBar'
import { SettingsSectionsList } from '@src/components/Settings/SettingsSectionsList' import { SettingsSectionsList } from '@src/components/Settings/SettingsSectionsList'
import { SettingsTabs } from '@src/components/Settings/SettingsTabs' import { SettingsTabs } from '@src/components/Settings/SettingsTabs'
import { useDotDotSlash } from '@src/hooks/useDotDotSlash'
import { PATHS } from '@src/lib/paths' import { PATHS } from '@src/lib/paths'
import type { SettingsLevel } from '@src/lib/settings/settingsTypes' import type { SettingsLevel } from '@src/lib/settings/settingsTypes'
export const Settings = () => { export const Settings = () => {
const navigate = useNavigate() const navigate = useNavigate()
const [searchParams, setSearchParams] = useSearchParams() const [searchParams, setSearchParams] = useSearchParams()
const close = () => { const close = () => navigate(location.pathname.replace(PATHS.SETTINGS, ''))
// This makes sure input texts are saved before closing the dialog (eg. default project name).
if (document.activeElement instanceof HTMLInputElement) {
document.activeElement.blur()
}
navigate(location.pathname.replace(PATHS.SETTINGS, ''))
}
const location = useLocation() const location = useLocation()
const isFileSettings = location.pathname.includes(PATHS.FILE) const isFileSettings = location.pathname.includes(PATHS.FILE)
const searchParamTab = const searchParamTab =
@ -29,6 +25,8 @@ export const Settings = () => {
(isFileSettings ? 'project' : 'user') (isFileSettings ? 'project' : 'user')
const scrollRef = useRef<HTMLDivElement>(null) const scrollRef = useRef<HTMLDivElement>(null)
const dotDotSlash = useDotDotSlash()
useHotkeys('esc', () => navigate(dotDotSlash()))
// Scroll to the hash on load if it exists // Scroll to the hash on load if it exists
useEffect(() => { useEffect(() => {