Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
d3a4fd8b55 | |||
2be7107cca | |||
94f194a984 | |||
4fe880a970 | |||
8f5fbfc273 | |||
e660f52bb0 | |||
d74fdd9369 | |||
334145f0be | |||
c24073b6ae |
28
.github/workflows/e2e-tests.yml
vendored
28
.github/workflows/e2e-tests.yml
vendored
@ -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: Rust Cache
|
- name: Use 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,20 +133,17 @@ jobs:
|
|||||||
id: deps-install
|
id: deps-install
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
- name: Cache Playwright Browsers
|
- name: Cache 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 Playwright Browsers
|
- name: Install browsers
|
||||||
run: npm run playwright install --with-deps
|
run: npm run playwright install --with-deps
|
||||||
|
|
||||||
- name: build web
|
- name: Capture snapshots
|
||||||
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
|
||||||
@ -170,7 +167,7 @@ jobs:
|
|||||||
retention-days: 30
|
retention-days: 30
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|
||||||
- name: Check for changes
|
- name: Check diff
|
||||||
if: ${{ github.ref != 'refs/heads/main' }}
|
if: ${{ github.ref != 'refs/heads/main' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
id: git-check
|
id: git-check
|
||||||
@ -181,9 +178,8 @@ jobs:
|
|||||||
else echo "modified=false" >> $GITHUB_OUTPUT
|
else echo "modified=false" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Commit changes, if any
|
- name: Commit changes
|
||||||
# TODO: find a more reliable way to detect visual changes
|
if: ${{ steps.git-check.outputs.modified == 'true' }}
|
||||||
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
|
||||||
@ -193,7 +189,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 -m "A snapshot a day keeps the bugs away! 📷🐛" || true
|
git commit --message "Update snapshots" || 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
@ -251786,7 +251786,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": false,
|
"required": false,
|
||||||
"description": "What is the sweep relative to? Can be either 'sketchPlane' or 'trajectoryCurve'. Defaults to sketchPlane.",
|
"description": "What is the sweep relative to? Can be either 'sketchPlane' or 'trajectoryCurve'. Defaults to trajectoryCurve.",
|
||||||
"labelRequired": true
|
"labelRequired": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -256720,7 +256720,7 @@
|
|||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"// Create a spring by sweeping around a helix path.\n\n// Create a helix around the Z axis.\nhelixPath = helix(\n angleStart = 0,\n ccw = true,\n revolutions = 4,\n length = 10,\n radius = 5,\n axis = Z,\n)\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn(YZ)\n |> circle(center = [0, 0], radius = 1)\n |> sweep(path = helixPath)",
|
"// Create a spring by sweeping around a helix path.\n\n// Create a helix around the Z axis.\nhelixPath = helix(\n angleStart = 0,\n ccw = true,\n revolutions = 4,\n length = 10,\n radius = 5,\n axis = Z,\n)\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn(YZ)\n |> circle(center = [0, 0], radius = 1)\n |> sweep(path = helixPath, relativeTo = \"sketchPlane\")",
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,4 +1,3 @@
|
|||||||
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'
|
||||||
@ -9,6 +8,7 @@ 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,6 +873,50 @@ 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,
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
34
rust/Cargo.lock
generated
34
rust/Cargo.lock
generated
@ -535,7 +535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -963,7 +963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1746,7 +1746,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1815,7 +1815,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.70"
|
version = "0.1.71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1826,7 +1826,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
version = "0.1.70"
|
version = "0.1.71"
|
||||||
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.70"
|
version = "0.1.71"
|
||||||
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.70"
|
version = "0.2.71"
|
||||||
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.70"
|
version = "0.1.71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1895,7 +1895,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.2.70"
|
version = "0.2.71"
|
||||||
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.70"
|
version = "0.3.71"
|
||||||
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.70"
|
version = "0.1.71"
|
||||||
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.70"
|
version = "0.1.71"
|
||||||
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.70"
|
version = "0.1.71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bson",
|
"bson",
|
||||||
@ -2987,7 +2987,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3306,7 +3306,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3900,7 +3900,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4753,7 +4753,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.70"
|
version = "0.1.71"
|
||||||
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"
|
||||||
|
@ -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.70"
|
version = "0.1.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -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.70"
|
version = "0.1.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.70"
|
version = "0.1.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||||
publish = false
|
publish = false
|
||||||
|
@ -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.70"
|
version = "0.2.71"
|
||||||
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
|
||||||
|
@ -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.70"
|
version = "0.2.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -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: 24 },
|
start: tower_lsp::lsp_types::Position { line: 4, character: 25 },
|
||||||
end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
|
end: tower_lsp::lsp_types::Position { line: 4, character: 32 },
|
||||||
},
|
},
|
||||||
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: 24 },
|
start: tower_lsp::lsp_types::Position { line: 4, character: 25 },
|
||||||
end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
|
end: tower_lsp::lsp_types::Position { line: 4, character: 32 },
|
||||||
},
|
},
|
||||||
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: 24 },
|
start: tower_lsp::lsp_types::Position { line: 4, character: 25 },
|
||||||
end: tower_lsp::lsp_types::Position { line: 4, character: 33 },
|
end: tower_lsp::lsp_types::Position { line: 4, character: 32 },
|
||||||
},
|
},
|
||||||
color: tower_lsp::lsp_types::Color {
|
color: tower_lsp::lsp_types::Color {
|
||||||
red: 1.0,
|
red: 1.0,
|
||||||
|
@ -438,8 +438,15 @@ 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: literal.as_source_range().to_lsp_range(code),
|
range: fixed_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,
|
||||||
@ -498,7 +505,11 @@ 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) => {
|
||||||
if literal.start == pos_start && literal.end == pos_end && literal.value.is_color().is_some() {
|
// Account for the quotes in the literal.
|
||||||
|
if (literal.start + 1) == pos_start
|
||||||
|
&& (literal.end - 1) == pos_end
|
||||||
|
&& literal.value.is_color().is_some()
|
||||||
|
{
|
||||||
found.replace(true);
|
found.replace(true);
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
@ -2729,6 +2729,17 @@ 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),
|
||||||
@ -3143,12 +3154,14 @@ 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),
|
||||||
)),
|
)),
|
||||||
@ -3164,6 +3177,18 @@ 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 {
|
||||||
@ -5055,6 +5080,30 @@ bar = 1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sensible_error_when_using_keyword_as_arg_label() {
|
||||||
|
for (i, program) in ["pow(2, fn = 8)"].into_iter().enumerate() {
|
||||||
|
let tokens = crate::parsing::token::lex(program, ModuleId::default()).unwrap();
|
||||||
|
let err = match fn_call_kw.parse(tokens.as_slice()) {
|
||||||
|
Err(e) => e,
|
||||||
|
Ok(ast) => {
|
||||||
|
eprintln!("{ast:#?}");
|
||||||
|
panic!("Expected this to error but it didn't");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let cause = err.inner().cause.as_ref().unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
cause.message, "`fn` is not the name of an argument (it's a reserved keyword)",
|
||||||
|
"failed test {i}: {program}"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
cause.source_range.start(),
|
||||||
|
program.find("fn").unwrap(),
|
||||||
|
"failed test {i}: {program}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[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() {
|
||||||
|
@ -3092,3 +3092,24 @@ mod error_revolve_on_edge_get_edge {
|
|||||||
super::execute(TEST_NAME, true).await
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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::Args,
|
std::{patterns::GeometryTrait, 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.id = solid_out_id;
|
solid.set_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.id = extra_solid_ids[0];
|
solid.set_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.id = solid_out_id;
|
solid.set_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.id = extra_solid_ids[0];
|
solid.set_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.id = solid_out_id;
|
solid.set_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.id = extra_solid_ids[0];
|
solid.set_id(extra_solid_ids[0]);
|
||||||
new_solids.push(solid.clone());
|
new_solids.push(solid.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ fn array_to_point2d(
|
|||||||
.map(|val| val.as_point2d().unwrap())
|
.map(|val| val.as_point2d().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GeometryTrait: Clone {
|
pub 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,6 +608,7 @@ 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>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,6 +642,8 @@ 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 {
|
||||||
|
@ -112,7 +112,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// // Create a spring by sweeping around the helix path.
|
/// // 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)
|
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
@ -167,7 +167,7 @@ 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 sketchPlane."},
|
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" },
|
||||||
},
|
},
|
||||||
@ -191,14 +191,13 @@ async fn inner_sweep(
|
|||||||
};
|
};
|
||||||
let relative_to = match relative_to.as_deref() {
|
let relative_to = match relative_to.as_deref() {
|
||||||
Some("sketchPlane") => RelativeTo::SketchPlane,
|
Some("sketchPlane") => RelativeTo::SketchPlane,
|
||||||
Some("trajectoryCurve") => RelativeTo::TrajectoryCurve,
|
Some("trajectoryCurve") | None => RelativeTo::TrajectoryCurve,
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
return Err(KclError::Syntax(crate::errors::KclErrorDetails {
|
return Err(KclError::Syntax(crate::errors::KclErrorDetails {
|
||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
message: "If you provide relativeTo, it must either be 'sketchPlane' or 'trajectoryCurve'".to_owned(),
|
message: "If you provide relativeTo, it must either be 'sketchPlane' or 'trajectoryCurve'".to_owned(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
None => RelativeTo::default(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut solids = Vec::new();
|
let mut solids = Vec::new();
|
||||||
|
@ -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)
|
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -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)
|
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -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)
|
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -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)
|
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```kcl
|
/// ```kcl
|
||||||
|
@ -5122,7 +5122,7 @@ description: Artifact commands bench.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -5134,7 +5134,7 @@ description: Artifact commands bench.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -906,7 +906,7 @@ description: Artifact commands cold-plate.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5576,7 +5576,7 @@ description: Artifact commands cpu-cooler.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -6111,7 +6111,7 @@ description: Artifact commands cpu-cooler.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -9469,7 +9469,7 @@ description: Artifact commands cpu-cooler.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -9601,7 +9601,7 @@ description: Artifact commands cpu-cooler.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -10120,7 +10120,7 @@ description: Artifact commands cpu-cooler.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -10252,7 +10252,7 @@ description: Artifact commands cpu-cooler.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1598,7 +1598,7 @@ description: Artifact commands exhaust-manifold.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1610,7 +1610,7 @@ description: Artifact commands exhaust-manifold.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1622,7 +1622,7 @@ description: Artifact commands exhaust-manifold.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1634,7 +1634,7 @@ description: Artifact commands exhaust-manifold.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4491,7 +4491,7 @@ description: Artifact commands utility-sink.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
1060
rust/kcl-lib/tests/sketch_on_face_union/artifact_commands.snap
Normal file
1060
rust/kcl-lib/tests/sketch_on_face_union/artifact_commands.snap
Normal file
File diff suppressed because it is too large
Load Diff
3671
rust/kcl-lib/tests/sketch_on_face_union/ast.snap
Normal file
3671
rust/kcl-lib/tests/sketch_on_face_union/ast.snap
Normal file
File diff suppressed because it is too large
Load Diff
58
rust/kcl-lib/tests/sketch_on_face_union/input.kcl
Normal file
58
rust/kcl-lib/tests/sketch_on_face_union/input.kcl
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
// Define parameters
|
||||||
|
trussSupportAngle = 15
|
||||||
|
height = 120
|
||||||
|
thickness = 4
|
||||||
|
|
||||||
|
sketch001 = startSketchOn(YZ)
|
||||||
|
profile001 = startProfile(sketch001, at = [60, 0])
|
||||||
|
|> xLine(length = -120, tag = $bottomFace)
|
||||||
|
|> yLine(length = 12)
|
||||||
|
|> angledLine(angle = 25, endAbsoluteX = 0, tag = $tag001)
|
||||||
|
|> angledLine(angle = -25, endAbsoluteX = 60)
|
||||||
|
|> close()
|
||||||
|
|
||||||
|
profile002 = startProfile(sketch001, at = [60-thickness, thickness])
|
||||||
|
|> xLine(endAbsolute = thickness/2)
|
||||||
|
|> yLine(endAbsolute = segEndY(tag001)-thickness) // update
|
||||||
|
|> angledLine(endAbsoluteX = profileStartX(%), angle = -25)
|
||||||
|
|> close(%)
|
||||||
|
|
||||||
|
profile003 = startProfile(sketch001, at = [-60+thickness, thickness])
|
||||||
|
|> xLine(endAbsolute = -thickness/2)
|
||||||
|
|> yLine(endAbsolute = segEndY(tag001)-thickness) // update
|
||||||
|
|> angledLine(endAbsoluteX = profileStartX(%), angle = 205)
|
||||||
|
|> close(%)
|
||||||
|
|
||||||
|
profile004 = subtract2d(profile001, tool = profile002)
|
||||||
|
subtract2d(profile001, tool = profile003)
|
||||||
|
|
||||||
|
body001 = extrude(profile001, length = 2)
|
||||||
|
|
||||||
|
sketch002 = startSketchOn(offsetPlane(YZ, offset = .1))
|
||||||
|
profile006 = startProfile(sketch002, at = [thickness/2-1, 14])
|
||||||
|
|> angledLine(angle = 30, length = 25)
|
||||||
|
|> angledLine(angle = -25, length = 5)
|
||||||
|
|> angledLine(angle = 210, endAbsoluteX = profileStartX(%))
|
||||||
|
|> close(%)
|
||||||
|
|> extrude(%, length = 1.8)
|
||||||
|
|
||||||
|
profile007 = startProfile(sketch002, at = [-thickness/2+1, 14])
|
||||||
|
|> angledLine(angle = 150, length = 25)
|
||||||
|
|> angledLine(angle = 205, length = 5)
|
||||||
|
|> angledLine(angle = -30, endAbsoluteX = profileStartX(%))
|
||||||
|
|> close(%)
|
||||||
|
|> extrude(%, length = 1.8)
|
||||||
|
|
||||||
|
newSketch = body001 + profile006 + profile007
|
||||||
|
|
||||||
|
leg001Sketch = startSketchOn(newSketch, face = bottomFace)
|
||||||
|
legProfile001 = startProfile(leg001Sketch, at = [-60, 0])
|
||||||
|
|> xLine(%, length = 4)
|
||||||
|
|> yLine(%, length = 2)
|
||||||
|
|> xLine(%, endAbsolute = profileStartX(%))
|
||||||
|
|> close(%)
|
||||||
|
|
||||||
|
leg001 = extrude(legProfile001, length = 48)
|
||||||
|
|> rotate(axis = [0, 0, 1.0], angle = -90)
|
264
rust/kcl-lib/tests/sketch_on_face_union/ops.snap
Normal file
264
rust/kcl-lib/tests/sketch_on_face_union/ops.snap
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Operations executed sketch_on_face_union.kcl
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"labeledArgs": {},
|
||||||
|
"name": "startSketchOn",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Plane",
|
||||||
|
"artifact_id": "[uuid]"
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"tool": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "subtract2d",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"tool": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "subtract2d",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"length": {
|
||||||
|
"value": {
|
||||||
|
"type": "Number",
|
||||||
|
"value": 2.0,
|
||||||
|
"ty": {
|
||||||
|
"type": "Default",
|
||||||
|
"len": {
|
||||||
|
"type": "Inches"
|
||||||
|
},
|
||||||
|
"angle": {
|
||||||
|
"type": "Degrees"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "extrude",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {},
|
||||||
|
"name": "startSketchOn",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Plane",
|
||||||
|
"artifact_id": "[uuid]"
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "KclStdLibCall",
|
||||||
|
"name": "offsetPlane",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Plane",
|
||||||
|
"artifact_id": "[uuid]"
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
},
|
||||||
|
"labeledArgs": {
|
||||||
|
"offset": {
|
||||||
|
"value": {
|
||||||
|
"type": "Number",
|
||||||
|
"value": 0.1,
|
||||||
|
"ty": {
|
||||||
|
"type": "Default",
|
||||||
|
"len": {
|
||||||
|
"type": "Inches"
|
||||||
|
},
|
||||||
|
"angle": {
|
||||||
|
"type": "Degrees"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"length": {
|
||||||
|
"value": {
|
||||||
|
"type": "Number",
|
||||||
|
"value": 1.8,
|
||||||
|
"ty": {
|
||||||
|
"type": "Default",
|
||||||
|
"len": {
|
||||||
|
"type": "Inches"
|
||||||
|
},
|
||||||
|
"angle": {
|
||||||
|
"type": "Degrees"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "extrude",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"length": {
|
||||||
|
"value": {
|
||||||
|
"type": "Number",
|
||||||
|
"value": 1.8,
|
||||||
|
"ty": {
|
||||||
|
"type": "Default",
|
||||||
|
"len": {
|
||||||
|
"type": "Inches"
|
||||||
|
},
|
||||||
|
"angle": {
|
||||||
|
"type": "Degrees"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "extrude",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"face": {
|
||||||
|
"value": {
|
||||||
|
"type": "TagIdentifier",
|
||||||
|
"value": "bottomFace",
|
||||||
|
"artifact_id": "[uuid]"
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "startSketchOn",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Solid",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"labeledArgs": {
|
||||||
|
"length": {
|
||||||
|
"value": {
|
||||||
|
"type": "Number",
|
||||||
|
"value": 48.0,
|
||||||
|
"ty": {
|
||||||
|
"type": "Default",
|
||||||
|
"len": {
|
||||||
|
"type": "Inches"
|
||||||
|
},
|
||||||
|
"angle": {
|
||||||
|
"type": "Degrees"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "extrude",
|
||||||
|
"sourceRange": [],
|
||||||
|
"type": "StdLibCall",
|
||||||
|
"unlabeledArg": {
|
||||||
|
"value": {
|
||||||
|
"type": "Sketch",
|
||||||
|
"value": {
|
||||||
|
"artifactId": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
2639
rust/kcl-lib/tests/sketch_on_face_union/program_memory.snap
Normal file
2639
rust/kcl-lib/tests/sketch_on_face_union/program_memory.snap
Normal file
File diff suppressed because it is too large
Load Diff
BIN
rust/kcl-lib/tests/sketch_on_face_union/rendered_model.png
Normal file
BIN
rust/kcl-lib/tests/sketch_on_face_union/rendered_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
62
rust/kcl-lib/tests/sketch_on_face_union/unparsed.snap
Normal file
62
rust/kcl-lib/tests/sketch_on_face_union/unparsed.snap
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of unparsing sketch_on_face_union.kcl
|
||||||
|
---
|
||||||
|
@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
// Define parameters
|
||||||
|
trussSupportAngle = 15
|
||||||
|
height = 120
|
||||||
|
thickness = 4
|
||||||
|
|
||||||
|
sketch001 = startSketchOn(YZ)
|
||||||
|
profile001 = startProfile(sketch001, at = [60, 0])
|
||||||
|
|> xLine(length = -120, tag = $bottomFace)
|
||||||
|
|> yLine(length = 12)
|
||||||
|
|> angledLine(angle = 25, endAbsoluteX = 0, tag = $tag001)
|
||||||
|
|> angledLine(angle = -25, endAbsoluteX = 60)
|
||||||
|
|> close()
|
||||||
|
|
||||||
|
profile002 = startProfile(sketch001, at = [60 - thickness, thickness])
|
||||||
|
|> xLine(endAbsolute = thickness / 2)
|
||||||
|
|> yLine(endAbsolute = segEndY(tag001) - thickness) // update
|
||||||
|
|> angledLine(endAbsoluteX = profileStartX(%), angle = -25)
|
||||||
|
|> close(%)
|
||||||
|
|
||||||
|
profile003 = startProfile(sketch001, at = [-60 + thickness, thickness])
|
||||||
|
|> xLine(endAbsolute = -thickness / 2)
|
||||||
|
|> yLine(endAbsolute = segEndY(tag001) - thickness) // update
|
||||||
|
|> angledLine(endAbsoluteX = profileStartX(%), angle = 205)
|
||||||
|
|> close(%)
|
||||||
|
|
||||||
|
profile004 = subtract2d(profile001, tool = profile002)
|
||||||
|
subtract2d(profile001, tool = profile003)
|
||||||
|
|
||||||
|
body001 = extrude(profile001, length = 2)
|
||||||
|
|
||||||
|
sketch002 = startSketchOn(offsetPlane(YZ, offset = .1))
|
||||||
|
profile006 = startProfile(sketch002, at = [thickness / 2 - 1, 14])
|
||||||
|
|> angledLine(angle = 30, length = 25)
|
||||||
|
|> angledLine(angle = -25, length = 5)
|
||||||
|
|> angledLine(angle = 210, endAbsoluteX = profileStartX(%))
|
||||||
|
|> close(%)
|
||||||
|
|> extrude(%, length = 1.8)
|
||||||
|
|
||||||
|
profile007 = startProfile(sketch002, at = [-thickness / 2 + 1, 14])
|
||||||
|
|> angledLine(angle = 150, length = 25)
|
||||||
|
|> angledLine(angle = 205, length = 5)
|
||||||
|
|> angledLine(angle = -30, endAbsoluteX = profileStartX(%))
|
||||||
|
|> close(%)
|
||||||
|
|> extrude(%, length = 1.8)
|
||||||
|
|
||||||
|
newSketch = body001 + profile006 + profile007
|
||||||
|
|
||||||
|
leg001Sketch = startSketchOn(newSketch, face = bottomFace)
|
||||||
|
legProfile001 = startProfile(leg001Sketch, at = [-60, 0])
|
||||||
|
|> xLine(%, length = 4)
|
||||||
|
|> yLine(%, length = 2)
|
||||||
|
|> xLine(%, endAbsolute = profileStartX(%))
|
||||||
|
|> close(%)
|
||||||
|
|
||||||
|
leg001 = extrude(legProfile001, length = 48)
|
||||||
|
|> rotate(axis = [0, 0, 1.0], angle = -90)
|
@ -418,7 +418,7 @@ description: Artifact commands subtract_regression03.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -395,7 +395,7 @@ description: Artifact commands subtract_regression05.kcl
|
|||||||
"trajectory": "[uuid]",
|
"trajectory": "[uuid]",
|
||||||
"sectional": false,
|
"sectional": false,
|
||||||
"tolerance": 0.0000001,
|
"tolerance": 0.0000001,
|
||||||
"relative_to": "sketch_plane"
|
"relative_to": "trajectory_curve"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-python-bindings"
|
name = "kcl-python-bindings"
|
||||||
version = "0.3.70"
|
version = "0.3.71"
|
||||||
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/*"]
|
||||||
|
@ -227,6 +227,31 @@ 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<()> {
|
||||||
@ -534,6 +559,8 @@ 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)?)?;
|
||||||
|
@ -39,6 +39,33 @@ 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.
|
||||||
@ -97,9 +124,7 @@ 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(
|
image_bytes = await kcl.execute_and_snapshot(car_wheel_dir, kcl.ImageFormat.Jpeg)
|
||||||
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
|
||||||
|
|
||||||
@ -129,10 +154,12 @@ 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:
|
||||||
|
@ -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.70"
|
version = "0.1.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
@ -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.70"
|
version = "0.1.71"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-wasm-lib"
|
name = "kcl-wasm-lib"
|
||||||
version = "0.1.70"
|
version = "0.1.71"
|
||||||
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"
|
||||||
|
@ -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, '')
|
const literal = colorLiteral.replace(/"/g, '').replace(/'/g, '')
|
||||||
const match = hexRegex.exec(literal)
|
const match = hexRegex.exec(literal)
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return null
|
return null
|
||||||
|
@ -212,6 +212,12 @@ 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% {
|
||||||
|
Reference in New Issue
Block a user