Compare commits

...

24 Commits

Author SHA1 Message Date
83d22a4f5f Release kcl 44 (#5570) 2025-02-28 09:56:19 -06:00
7003b19a70 Release kcl 42 (#5569) 2025-02-28 09:50:32 -06:00
687ef1429d make code dryer, (#5566)
make code dryer, inner_run used to be recursive i didnt realize it changed

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-28 19:24:48 +13:00
b1b00a9a22 Fix Toolbar flash bug (during sketchMode animation (#5564)
* fix toolbar flash during animation

* add regression test

* fmt

* test tweak

* fmt
2025-02-28 04:50:01 +00:00
a0924bcfa3 Save the rust version of settings (#5563)
* ensure we save the correct value for the settings versus relying on tomlStringify

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more exact functions

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fmt

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-27 19:35:39 -05:00
5ce22e2de8 better track the root source code (#5558)
* better track the root source code

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix mut self

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-27 22:34:01 +00:00
850c5c62d1 Fix overflow in KCL command palette input (#5559)
Closes #4719.
2025-02-27 20:18:32 +00:00
b31786c9ab Add step to E2E test to verify Backspace doesn't dismiss command palette (#5557) 2025-02-27 18:58:17 +00:00
936549d60f Fix nightly changelog (#5550) 2025-02-27 11:00:56 -05:00
0babbcff49 Remove skipWin tag on point-and-click e2e tests (#5531)
* Remove skipWin tag on point-and-click e2e tests

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-27 09:34:15 -05:00
02c2e80b31 Remove hole from toolbar (#5543)
* Remove hole from toolbar
Fixes #5542

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-27 09:33:57 -05:00
da236d9a3e Fix switching between KCL arguments (#5512)
* Fix switching between KCL arguments

Needed to imperatively send a transaction to the editor, since it
doesn't get re-rendered when switching from one KCL-type arg to another.

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

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

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

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

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

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

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

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2025-02-27 10:01:08 +00:00
1104d908c0 Improve hover tool tips and function docs (#5538)
* Improve hover tool tips and function docs

Signed-off-by: Nick Cameron <nrc@ncameron.org>

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

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-27 22:03:37 +13:00
2efea3ec06 export shit i need (#5539)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-27 05:15:52 +00:00
775007ef0d clean stale docs (#5536)
clean-stale-docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-27 03:44:28 +00:00
f490e7d6fe better errors from rust to lsp for execution errors (#5526)
* better errors start

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* conversions

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* miette update

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* related errrors test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* a bit better

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* regenerate other errors

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add diagnostics test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-27 03:29:59 +00:00
89bc93e4cd Add default planes to std (#5433)
* Type ascription

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Support negation of planes

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Add default planes to std

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Don't double wrap docs files in const_

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-02-27 15:58:58 +13:00
12edb6375d Fix a units bug in multi-module projects (#5529)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-02-27 15:46:41 +13:00
8d9bba02d6 add pattern3d tests that now work that were being used for debugging (#3862)
* more samples for useOriginal

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-26 20:23:27 -05:00
56e100fad7 Transform std lib functions (#5067)
* transform

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* u[dates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-26 17:45:19 -07:00
38f7a4089e Add in the basics for Import ordering (#5524)
* Add in the basics for Import ordering

This will walk AST for import notes, and build up a mapping of
relationships tying in the target of the import (the "dependency")
to our current program (the "dependent").

This allows us to build up a mapping of what dependency and reverse
dependency relationships look like, in order to sort dependencies by
topologically sorting them.

Since I wanted to enable some parallelism here long-term, this returns
the (kinda awkward) `Vec<Vec<String>>` type.

This is a list of list of dependency targets which can safely be run
concurrently, because they have no dependency relationship to eachother.
Each list of dependencies should be gated, and start the next list of
dependencies after the first is complely done. This isn't ideal and will
change long-term, but for now this will work to enable very basic
opportunistic parallelism.

* clippy v1.0

* allow this

this lint doesn't apply here, order doesn't matter. Elsewhere in this
program where order does matter we do the intermediate vec.

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2025-02-27 00:26:19 +00:00
91f5465e2d Revert "Correct hovering highlights on HiDPI screens + correct 2 flakey tests" (#5535)
* Revert "Correct hovering highlights on HiDPI screens + correct 2 flakey tests…"

This reverts commit 5743b9ced0.

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-26 15:49:13 -08:00
58a9c60d0b Test code examples in docs and add docs for per-file settings (#5474)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-02-27 09:34:55 +13:00
725c4d95f8 prompt-to-edit API request snapshot testing infrastructure (#5514)
* POC write output to json

* move to cmd bar

* write files

* clean up

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

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

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

* tweak

* tweak

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

* update fmt ignore etc

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

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-27 05:44:40 +11:00
223 changed files with 31723 additions and 1083 deletions

View File

@ -1,3 +1,4 @@
src/wasm-lib/* src/wasm-lib/*
*.typegen.ts *.typegen.ts
packages/codemirror-lsp-client/dist/* packages/codemirror-lsp-client/dist/*
e2e/playwright/snapshots/prompt-to-edit/*

View File

@ -386,7 +386,7 @@ jobs:
# see https://github.com/actions/checkout/issues/1471 # see https://github.com/actions/checkout/issues/1471
git fetch --prune --unshallow --tags git fetch --prune --unshallow --tags
export TAG="nightly-${VERSION}" export TAG="nightly-${VERSION}"
export PREVIOUS_TAG=$(git describe --tags --match="nightly-v[0-9]*" --abbrev=0) export PREVIOUS_TAG=$(git tag --list --sort=-committerdate "nightly-v[0-9]*" | head -n2 | tail -n1)
export NOTES=$(./scripts/get-nightly-changelog.sh) export NOTES=$(./scripts/get-nightly-changelog.sh)
yarn files:set-notes yarn files:set-notes

View File

@ -167,7 +167,7 @@ jobs:
shell: bash shell: bash
id: git-check id: git-check
run: | run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
if git status | grep -q "Changes to be committed" if git status | grep -q "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT else echo "modified=false" >> $GITHUB_OUTPUT
@ -176,7 +176,7 @@ jobs:
if: steps.git-check.outputs.modified == 'true' if: steps.git-check.outputs.modified == 'true'
shell: bash shell: bash
run: | run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]" git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git

1
.gitignore vendored
View File

@ -71,3 +71,4 @@ venv
# electron # electron
out/ out/
*.snap.new

View File

@ -10,6 +10,7 @@ target
src/wasm-lib/pkg src/wasm-lib/pkg
src/wasm-lib/kcl/bindings src/wasm-lib/kcl/bindings
e2e/playwright/export-snapshots e2e/playwright/export-snapshots
e2e/playwright/snapshots/prompt-to-edit
# XState generated files # XState generated files

View File

@ -1,15 +0,0 @@
---
title: "QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
QUARTER_TURN: number(deg) = 90deg
```

View File

@ -1,15 +0,0 @@
---
title: "THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -9,7 +9,11 @@ Returns the angle to match the given length for x.
```js ```js
angleToMatchLengthX(tag: TagIdentifier, to: number, sketch: Sketch) -> number angleToMatchLengthX(
tag: TagIdentifier,
to: number,
sketch: Sketch,
) -> number
``` ```

View File

@ -9,7 +9,11 @@ Returns the angle to match the given length for y.
```js ```js
angleToMatchLengthY(tag: TagIdentifier, to: number, sketch: Sketch) -> number angleToMatchLengthY(
tag: TagIdentifier,
to: number,
sketch: Sketch,
) -> number
``` ```

View File

@ -9,7 +9,11 @@ Draw a line segment relative to the current origin using the polar
measure of some angle and distance. measure of some angle and distance.
```js ```js
angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch angledLine(
data: AngledLineData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> yLineTo(15, %) |> yLineTo(15, %)
|> angledLine({ angle = 30, length = 15 }, %) |> angledLine({ angle = 30, length = 15 }, %)

View File

@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
along some angle (in degrees) for some relative length in the 'x' dimension. along some angle (in degrees) for some relative length in the 'x' dimension.
```js ```js
angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch angledLineOfXLength(
data: AngledLineData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
### Examples ### Examples
```js ```js
sketch001 = startSketchOn('XZ') sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLineOfXLength({ angle = 45, length = 10 }, %, $edge1) |> angledLineOfXLength({ angle = 45, length = 10 }, %, $edge1)
|> angledLineOfXLength({ angle = -15, length = 20 }, %, $edge2) |> angledLineOfXLength({ angle = -15, length = 20 }, %, $edge2)

View File

@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
along some angle (in degrees) for some relative length in the 'y' dimension. along some angle (in degrees) for some relative length in the 'y' dimension.
```js ```js
angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch angledLineOfYLength(
data: AngledLineData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [10, 0]) |> line(end = [10, 0])
|> angledLineOfYLength({ angle = 45, length = 10 }, %) |> angledLineOfYLength({ angle = 45, length = 10 }, %)

View File

@ -9,7 +9,11 @@ Draw an angled line from the current origin, constructing a line segment
such that the newly created line intersects the desired target line segment. such that the newly created line intersects the desired target line segment.
```js ```js
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag?: TagDeclarator) -> Sketch angledLineThatIntersects(
data: AngledLineThatIntersectsData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(endAbsolute = [5, 10]) |> line(endAbsolute = [5, 10])
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect) |> line(endAbsolute = [-10, 10], tag = $lineToIntersect)

View File

@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
along some angle (in degrees) for some length, ending at the provided value in the 'x' dimension. along some angle (in degrees) for some length, ending at the provided value in the 'x' dimension.
```js ```js
angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch angledLineToX(
data: AngledLineToData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLineToX({ angle = 30, to = 10 }, %) |> angledLineToX({ angle = 30, to = 10 }, %)
|> line(end = [0, 10]) |> line(end = [0, 10])

View File

@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
along some angle (in degrees) for some length, ending at the provided value in the 'y' dimension. along some angle (in degrees) for some length, ending at the provided value in the 'y' dimension.
```js ```js
angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch angledLineToY(
data: AngledLineToData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLineToY({ angle = 60, to = 20 }, %) |> angledLineToY({ angle = 60, to = 20 }, %)
|> line(end = [-20, 0]) |> line(end = [-20, 0])

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,11 @@ The arc is constructed such that the current position of the sketch is placed al
Unless this makes a lot of sense and feels like what you're looking for to construct your shape, you're likely looking for tangentialArc. Unless this makes a lot of sense and feels like what you're looking for to construct your shape, you're likely looking for tangentialArc.
```js ```js
arc(data: ArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch arc(
data: ArcData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -31,7 +35,7 @@ arc(data: ArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [10, 0]) |> line(end = [10, 0])
|> arc({ |> arc({

View File

@ -9,7 +9,11 @@ Draw a 3 point arc.
The arc is constructed such that the start point is the current position of the sketch and two more points defined as the end and interior point. The interior point is placed between the start point and end point. The radius of the arc will be controlled by how far the interior point is placed from the start and end. The arc is constructed such that the start point is the current position of the sketch and two more points defined as the end and interior point. The interior point is placed between the start point and end point. The radius of the arc will be controlled by how far the interior point is placed from the start and end.
```js ```js
arcTo(data: ArcToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch arcTo(
data: ArcToData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ arcTo(data: ArcToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> arcTo({ end = [10, 0], interior = [5, 5] }, %) |> arcTo({ end = [10, 0], interior = [5, 5] }, %)
|> close() |> close()

View File

@ -9,7 +9,10 @@ Check a value at runtime, and raise an error if the argument provided
is false. is false.
```js ```js
assert(data: bool, message: string) -> () assert(
data: bool,
message: string,
) -> ()
``` ```

View File

@ -9,7 +9,12 @@ Check that a numerical value equals another at runtime,
otherwise raise an error. otherwise raise an error.
```js ```js
assertEqual(left: number, right: number, epsilon: number, message: string) -> () assertEqual(
left: number,
right: number,
epsilon: number,
message: string,
) -> ()
``` ```

View File

@ -9,7 +9,11 @@ Check that a numerical value is greater than another at runtime,
otherwise raise an error. otherwise raise an error.
```js ```js
assertGreaterThan(left: number, right: number, message: string) -> () assertGreaterThan(
left: number,
right: number,
message: string,
) -> ()
``` ```

View File

@ -9,7 +9,11 @@ Check that a numerical value is greater than or equal to another at runtime,
otherwise raise an error. otherwise raise an error.
```js ```js
assertGreaterThanOrEq(left: number, right: number, message: string) -> () assertGreaterThanOrEq(
left: number,
right: number,
message: string,
) -> ()
``` ```

View File

@ -9,7 +9,11 @@ Check that a numerical value is less than to another at runtime,
otherwise raise an error. otherwise raise an error.
```js ```js
assertLessThan(left: number, right: number, message: string) -> () assertLessThan(
left: number,
right: number,
message: string,
) -> ()
``` ```

View File

@ -9,7 +9,11 @@ Check that a numerical value is less than or equal to another at runtime,
otherwise raise an error. otherwise raise an error.
```js ```js
assertLessThanOrEq(left: number, right: number, message: string) -> () assertLessThanOrEq(
left: number,
right: number,
message: string,
) -> ()
``` ```

View File

@ -9,7 +9,10 @@ Compute the four quadrant arctangent of Y and X (in radians).
```js ```js
atan2(y: number, x: number) -> number atan2(
y: number,
x: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -9,7 +9,11 @@ Draw a smooth, continuous, curved line segment from the current origin to
the desired (x, y), using a number of control points to shape the curve's shape. the desired (x, y), using a number of control points to shape the curve's shape.
```js ```js
bezierCurve(data: BezierData, sketch: Sketch, tag?: TagDeclarator) -> Sketch bezierCurve(
data: BezierData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ bezierCurve(data: BezierData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [0, 10]) |> line(end = [0, 10])
|> bezierCurve({ |> bezierCurve({

View File

@ -9,7 +9,12 @@ Cut a straight transitional edge along a tagged path.
Chamfer is similar in function and use to a fillet, except a fillet will blend the transition along an edge, rather than cut a sharp, straight transitional edge. Chamfer is similar in function and use to a fillet, except a fillet will blend the transition along an edge, rather than cut a sharp, straight transitional edge.
```js ```js
chamfer(solid: Solid, length: number, tags: [EdgeReference], tag?: TagDeclarator) -> Solid chamfer(
solid: Solid,
length: number,
tags: [EdgeReference],
tag?: TagDeclarator,
) -> Solid
``` ```

View File

@ -9,7 +9,11 @@ Construct a 2-dimensional circle, of the specified radius, centered at
the provided (x, y) origin point. the provided (x, y) origin point.
```js ```js
circle(data: CircleData, sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclarator) -> Sketch circle(
data: CircleData,
sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator,
) -> Sketch
``` ```

View File

@ -9,7 +9,13 @@ Construct a circle derived from 3 points.
```js ```js
circleThreePoint(p1: [number], p2: [number], p3: [number], sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclarator) -> Sketch circleThreePoint(
p1: [number],
p2: [number],
p3: [number],
sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator,
) -> Sketch
``` ```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,15 +0,0 @@
---
title: "HALF_TURN"
excerpt: ""
layout: manual
---
```js
HALF_TURN: number(deg) = 180deg
```

File diff suppressed because one or more lines are too long

View File

@ -1,15 +0,0 @@
---
title: "QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
QUARTER_TURN: number(deg) = 90deg
```

File diff suppressed because one or more lines are too long

View File

@ -1,15 +0,0 @@
---
title: "THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -1,5 +1,5 @@
--- ---
title: "ZERO" title: "std::XY"
excerpt: "" excerpt: ""
layout: manual layout: manual
--- ---
@ -9,7 +9,7 @@ layout: manual
```js ```js
ZERO: number = 0 std::XY
``` ```

View File

@ -1,5 +1,5 @@
--- ---
title: "ZERO" title: "std::XZ"
excerpt: "" excerpt: ""
layout: manual layout: manual
--- ---
@ -9,7 +9,7 @@ layout: manual
```js ```js
ZERO: number = 0 std::XZ
``` ```

View File

@ -1,5 +1,5 @@
--- ---
title: "HALF_TURN" title: "std::YZ"
excerpt: "" excerpt: ""
layout: manual layout: manual
--- ---
@ -9,7 +9,7 @@ layout: manual
```js ```js
HALF_TURN: number(deg) = 180deg std::YZ
``` ```

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,10 @@ Extend a 2-dimensional sketch through a third dimension in order to
create new 3-dimensional volume, or if extruded into an existing volume, cut into an existing solid. create new 3-dimensional volume, or if extruded into an existing volume, cut into an existing solid.
```js ```js
extrude(sketchSet: SketchSet, length: number) -> SolidSet extrude(
sketchSet: SketchSet,
length: number,
) -> SolidSet
``` ```

View File

@ -9,7 +9,13 @@ Blend a transitional edge along a tagged path, smoothing the sharp edge.
Fillet is similar in function and use to a chamfer, except a chamfer will cut a sharp transition along an edge while fillet will smoothly blend the transition. Fillet is similar in function and use to a chamfer, except a chamfer will cut a sharp transition along an edge while fillet will smoothly blend the transition.
```js ```js
fillet(solid: Solid, radius: number, tags: [EdgeReference], tolerance?: number, tag?: TagDeclarator) -> Solid fillet(
solid: Solid,
radius: number,
tags: [EdgeReference],
tolerance?: number,
tag?: TagDeclarator,
) -> Solid
``` ```

View File

@ -9,7 +9,14 @@ Create a helix.
```js ```js
helix(revolutions: number, angleStart: number, ccw?: bool, radius: number, axis: Axis3dOrEdgeReference, length?: number) -> HelixValue helix(
revolutions: number,
angleStart: number,
ccw?: bool,
radius: number,
axis: Axis3dOrEdgeReference,
length?: number,
) -> HelixValue
``` ```

View File

@ -9,7 +9,10 @@ Create a helix on a cylinder.
```js ```js
helixRevolutions(data: HelixRevolutionsData, solid: Solid) -> Solid helixRevolutions(
data: HelixRevolutionsData,
solid: Solid,
) -> Solid
``` ```

View File

@ -9,7 +9,10 @@ Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch.
```js ```js
hole(holeSketch: SketchSet, sketch: Sketch) -> Sketch hole(
holeSketch: SketchSet,
sketch: Sketch,
) -> Sketch
``` ```
@ -28,7 +31,7 @@ hole(holeSketch: SketchSet, sketch: Sketch) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XY') exampleSketch = startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [0, 5]) |> line(end = [0, 5])
|> line(end = [5, 0]) |> line(end = [5, 0])
@ -44,7 +47,7 @@ example = extrude(exampleSketch, length = 1)
```js ```js
fn squareHoleSketch() { fn squareHoleSketch() {
squareSketch = startSketchOn('-XZ') squareSketch = startSketchOn(-XZ)
|> startProfileAt([-1, -1], %) |> startProfileAt([-1, -1], %)
|> line(end = [2, 0]) |> line(end = [2, 0])
|> line(end = [0, 2]) |> line(end = [0, 2])
@ -53,7 +56,7 @@ fn squareHoleSketch() {
return squareSketch return squareSketch
} }
exampleSketch = startSketchOn('-XZ') exampleSketch = startSketchOn(-XZ)
|> circle({ center = [0, 0], radius = 3 }, %) |> circle({ center = [0, 0], radius = 3 }, %)
|> hole(squareHoleSketch(), %) |> hole(squareHoleSketch(), %)
example = extrude(exampleSketch, length = 1) example = extrude(exampleSketch, length = 1)

View File

@ -9,7 +9,10 @@ Make the inside of a 3D object hollow.
Remove volume from a 3-dimensional shape such that a wall of the provided thickness remains around the exterior of the shape. Remove volume from a 3-dimensional shape such that a wall of the provided thickness remains around the exterior of the shape.
```js ```js
hollow(thickness: number, solid: Solid) -> Solid hollow(
thickness: number,
solid: Solid,
) -> Solid
``` ```

View File

@ -15,7 +15,10 @@ For formats lacking unit data (such as STL, OBJ, or PLY files), the default unit
Note: The import command currently only works when using the native Modeling App. Note: The import command currently only works when using the native Modeling App.
```js ```js
import(filePath: String, options?: ImportFormat) -> ImportedGeometry import(
filePath: String,
options?: ImportFormat,
) -> ImportedGeometry
``` ```

View File

@ -6,13 +6,22 @@ layout: manual
## Table of Contents ## Table of Contents
* [Types](kcl/types) ### Language
* [Modules](kcl/modules)
* [Known Issues](kcl/KNOWN-ISSUES) * [`Types`](kcl/types)
* [`Modules`](kcl/modules)
* [`Settings`](kcl/settings)
* [`Known Issues`](kcl/known-issues)
### Standard library
* **`std`** * **`std`**
* [`HALF_TURN`](kcl/const_std-HALF_TURN) * [`HALF_TURN`](kcl/const_std-HALF_TURN)
* [`QUARTER_TURN`](kcl/const_std-QUARTER_TURN) * [`QUARTER_TURN`](kcl/const_std-QUARTER_TURN)
* [`THREE_QUARTER_TURN`](kcl/const_std-THREE_QUARTER_TURN) * [`THREE_QUARTER_TURN`](kcl/const_std-THREE_QUARTER_TURN)
* [`XY`](kcl/const_std-XY)
* [`XZ`](kcl/const_std-XZ)
* [`YZ`](kcl/const_std-YZ)
* [`ZERO`](kcl/const_std-ZERO) * [`ZERO`](kcl/const_std-ZERO)
* [`abs`](kcl/abs) * [`abs`](kcl/abs)
* [`acos`](kcl/acos) * [`acos`](kcl/acos)
@ -90,7 +99,9 @@ layout: manual
* [`reduce`](kcl/reduce) * [`reduce`](kcl/reduce)
* [`rem`](kcl/rem) * [`rem`](kcl/rem)
* [`revolve`](kcl/revolve) * [`revolve`](kcl/revolve)
* [`rotate`](kcl/rotate)
* [`round`](kcl/round) * [`round`](kcl/round)
* [`scale`](kcl/scale)
* [`segAng`](kcl/segAng) * [`segAng`](kcl/segAng)
* [`segEnd`](kcl/segEnd) * [`segEnd`](kcl/segEnd)
* [`segEndX`](kcl/segEndX) * [`segEndX`](kcl/segEndX)
@ -110,6 +121,7 @@ layout: manual
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative) * [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
* [`toDegrees`](kcl/toDegrees) * [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians) * [`toRadians`](kcl/toRadians)
* [`translate`](kcl/translate)
* [`xLine`](kcl/xLine) * [`xLine`](kcl/xLine)
* [`xLineTo`](kcl/xLineTo) * [`xLineTo`](kcl/xLineTo)
* [`yLine`](kcl/yLine) * [`yLine`](kcl/yLine)

View File

@ -9,7 +9,10 @@ Compute the angle of the given leg for x.
```js ```js
legAngX(hypotenuse: number, leg: number) -> number legAngX(
hypotenuse: number,
leg: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -9,7 +9,10 @@ Compute the angle of the given leg for y.
```js ```js
legAngY(hypotenuse: number, leg: number) -> number legAngY(
hypotenuse: number,
leg: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -9,7 +9,10 @@ Compute the length of the given leg.
```js ```js
legLen(hypotenuse: number, leg: number) -> number legLen(
hypotenuse: number,
leg: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -9,7 +9,12 @@ Extend the current sketch with a new straight line.
```js ```js
line(sketch: Sketch, endAbsolute?: [number], end?: [number], tag?: TagDeclarator) -> Sketch line(
sketch: Sketch,
endAbsolute?: [number],
end?: [number],
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -30,7 +35,7 @@ line(sketch: Sketch, endAbsolute?: [number], end?: [number], tag?: TagDeclarator
### Examples ### Examples
```js ```js
triangle = startSketchOn("XZ") triangle = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
// The 'end' argument means it ends at exactly [10, 0]. // The 'end' argument means it ends at exactly [10, 0].
// This is an absolute measurement, it is NOT relative to // This is an absolute measurement, it is NOT relative to
@ -41,7 +46,7 @@ triangle = startSketchOn("XZ")
|> close() |> close()
|> extrude(length = 5) |> extrude(length = 5)
box = startSketchOn("XZ") box = startSketchOn(XZ)
|> startProfileAt([10, 10], %) |> startProfileAt([10, 10], %)
// The 'to' argument means move the pen this much. // The 'to' argument means move the pen this much.
// So, [10, 0] is a relative distance away from the current point. // So, [10, 0] is a relative distance away from the current point.

View File

@ -9,7 +9,13 @@ Create a 3D surface or solid by interpolating between two or more sketches.
The sketches need to closed and on the same plane. The sketches need to closed and on the same plane.
```js ```js
loft(sketches: [Sketch], vDegree: NonZeroU32, bezApproximateRational: bool, baseCurveIndex?: integer, tolerance?: number) -> Solid loft(
sketches: [Sketch],
vDegree: NonZeroU32,
bezApproximateRational: bool,
baseCurveIndex?: integer,
tolerance?: number,
) -> Solid
``` ```

View File

@ -9,7 +9,10 @@ Compute the logarithm of the number with respect to an arbitrary base.
The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10. The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10.
```js ```js
log(num: number, base: number) -> number log(
num: number,
base: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -9,7 +9,10 @@ Apply a function to every element of a list.
Given a list like `[a, b, c]`, and a function like `f`, returns `[f(a), f(b), f(c)]` Given a list like `[a, b, c]`, and a function like `f`, returns `[f(a), f(b), f(c)]`
```js ```js
map(array: [KclValue], mapFn: FunctionSource) -> [KclValue] map(
array: [KclValue],
mapFn: FunctionSource,
) -> [KclValue]
``` ```

View File

@ -11,7 +11,10 @@ Only works on unclosed sketches for now.
Mirror occurs around a local sketch axis rather than a global axis. Mirror occurs around a local sketch axis rather than a global axis.
```js ```js
mirror2d(data: Mirror2dData, sketchSet: SketchSet) -> [Sketch] mirror2d(
data: Mirror2dData,
sketchSet: SketchSet,
) -> [Sketch]
``` ```

View File

@ -20,7 +20,7 @@ export fn increment(x) {
Other files in the project can now import functions that have been exported. Other files in the project can now import functions that have been exported.
This makes them available to use in another file. This makes them available to use in another file.
``` ```norun
// main.kcl // main.kcl
import increment from "util.kcl" import increment from "util.kcl"
@ -48,13 +48,13 @@ export fn decrement(x) {
When importing, you can import multiple functions at once. When importing, you can import multiple functions at once.
``` ```norun
import increment, decrement from "util.kcl" import increment, decrement from "util.kcl"
``` ```
Imported symbols can be renamed for convenience or to avoid name collisions. Imported symbols can be renamed for convenience or to avoid name collisions.
``` ```norun
import increment as inc, decrement as dec from "util.kcl" import increment as inc, decrement as dec from "util.kcl"
``` ```
@ -63,13 +63,13 @@ import increment as inc, decrement as dec from "util.kcl"
`import` can also be used to import files from other CAD systems. The format of the statement is the `import` can also be used to import files from other CAD systems. The format of the statement is the
same as for KCL files. You can only import the whole file, not items from it. E.g., same as for KCL files. You can only import the whole file, not items from it. E.g.,
``` ```norun
import "tests/inputs/cube.obj" import "tests/inputs/cube.obj"
// Use `cube` just like a KCL object. // Use `cube` just like a KCL object.
``` ```
``` ```norun
import "tests/inputs/cube-2.sldprt" as cube import "tests/inputs/cube-2.sldprt" as cube
// Use `cube` just like a KCL object. // Use `cube` just like a KCL object.
@ -78,7 +78,7 @@ import "tests/inputs/cube-2.sldprt" as cube
You can make the file format explicit using a format attribute (useful if using a different You can make the file format explicit using a format attribute (useful if using a different
extension), e.g., extension), e.g.,
``` ```norun
@(format = obj) @(format = obj)
import "tests/inputs/cube" import "tests/inputs/cube"
``` ```
@ -87,7 +87,7 @@ For formats lacking unit data (such as STL, OBJ, or PLY files), the default
unit of measurement is millimeters. Alternatively you may specify the unit unit of measurement is millimeters. Alternatively you may specify the unit
by using an attirbute. Likewise, you can also specify a coordinate system. E.g., by using an attirbute. Likewise, you can also specify a coordinate system. E.g.,
``` ```norun
@(unitLength = ft, coords = opengl) @(unitLength = ft, coords = opengl)
import "tests/inputs/cube.obj" import "tests/inputs/cube.obj"
``` ```

View File

@ -9,7 +9,10 @@ Offset a plane by a distance along its normal.
For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it. For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it.
```js ```js
offsetPlane(plane: PlaneData, offset: number) -> Plane offsetPlane(
plane: PlaneData,
offset: number,
) -> Plane
``` ```

View File

@ -9,7 +9,14 @@ Repeat a 2-dimensional sketch some number of times along a partial or
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained. complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
```js ```js
patternCircular2d(sketchSet: SketchSet, instances: integer, center: [number], arcDegrees: number, rotateDuplicates: bool, useOriginal?: bool) -> [Sketch] patternCircular2d(
sketchSet: SketchSet,
instances: integer,
center: [number],
arcDegrees: number,
rotateDuplicates: bool,
useOriginal?: bool,
) -> [Sketch]
``` ```

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,13 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount
of distance between each repetition, some specified number of times. of distance between each repetition, some specified number of times.
```js ```js
patternLinear2d(sketchSet: SketchSet, instances: integer, distance: number, axis: [number], useOriginal?: bool) -> [Sketch] patternLinear2d(
sketchSet: SketchSet,
instances: integer,
distance: number,
axis: [number],
useOriginal?: bool,
) -> [Sketch]
``` ```

File diff suppressed because one or more lines are too long

View File

@ -35,7 +35,12 @@ The transform function returns a transform object. All properties of the object
- `rotation.origin` (either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local") - `rotation.origin` (either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local")
```js ```js
patternTransform(solidSet: SolidSet, instances: integer, transform: FunctionSource, useOriginal?: bool) -> [Solid] patternTransform(
solidSet: SolidSet,
instances: integer,
transform: FunctionSource,
useOriginal?: bool,
) -> [Solid]
``` ```

View File

@ -9,7 +9,12 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
```js ```js
patternTransform2d(sketchSet: SketchSet, instances: integer, transform: FunctionSource, useOriginal?: bool) -> [Sketch] patternTransform2d(
sketchSet: SketchSet,
instances: integer,
transform: FunctionSource,
useOriginal?: bool,
) -> [Sketch]
``` ```

View File

@ -9,7 +9,11 @@ Create a regular polygon with the specified number of sides that is either inscr
```js ```js
polygon(data: PolygonData, sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclarator) -> Sketch polygon(
data: PolygonData,
sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator,
) -> Sketch
``` ```

View File

@ -9,7 +9,10 @@ Compute the number to a power.
```js ```js
pow(num: number, pow: number) -> number pow(
num: number,
pow: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -27,7 +27,7 @@ profileStart(sketch: Sketch) -> [number]
### Examples ### Examples
```js ```js
sketch001 = startSketchOn('XY') sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %) |> startProfileAt([5, 2], %)
|> angledLine({ angle = 120, length = 50 }, %, $seg01) |> angledLine({ angle = 120, length = 50 }, %, $seg01)
|> angledLine({ |> angledLine({

View File

@ -27,7 +27,7 @@ profileStartX(sketch: Sketch) -> number
### Examples ### Examples
```js ```js
sketch001 = startSketchOn('XY') sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %) |> startProfileAt([5, 2], %)
|> angledLine([-26.6, 50], %) |> angledLine([-26.6, 50], %)
|> angledLine([90, 50], %) |> angledLine([90, 50], %)

View File

@ -27,7 +27,7 @@ profileStartY(sketch: Sketch) -> number
### Examples ### Examples
```js ```js
sketch001 = startSketchOn('XY') sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %) |> startProfileAt([5, 2], %)
|> angledLine({ angle = -60, length = 14 }, %) |> angledLine({ angle = -60, length = 14 }, %)
|> angledLineToY({ angle = 30, to = profileStartY(%) }, %) |> angledLineToY({ angle = 30, to = profileStartY(%) }, %)

View File

@ -9,7 +9,10 @@ Append an element to the end of an array.
Returns a new array with the element appended. Returns a new array with the element appended.
```js ```js
push(array: [KclValue], elem: KclValue) -> KclValue push(
array: [KclValue],
elem: KclValue,
) -> KclValue
``` ```

View File

@ -9,7 +9,11 @@ Take a starting value. Then, for each element of an array, calculate the next va
using the previous value and the element. using the previous value and the element.
```js ```js
reduce(array: [KclValue], start: KclValue, reduceFn: FunctionSource) -> KclValue reduce(
array: [KclValue],
start: KclValue,
reduceFn: FunctionSource,
) -> KclValue
``` ```

View File

@ -9,7 +9,10 @@ Compute the remainder after dividing `num` by `div`.
If `num` is negative, the result will be too. If `num` is negative, the result will be too.
```js ```js
rem(num: number, divisor: number) -> number rem(
num: number,
divisor: number,
) -> number
``` ```
### Tags ### Tags

View File

@ -11,7 +11,10 @@ This, like extrude, is able to create a 3-dimensional solid from a 2-dimensional
Revolve occurs around a local sketch axis rather than a global axis. Revolve occurs around a local sketch axis rather than a global axis.
```js ```js
revolve(data: RevolveData, sketch: Sketch) -> Solid revolve(
data: RevolveData,
sketch: Sketch,
) -> Solid
``` ```

109
docs/kcl/rotate.md Normal file

File diff suppressed because one or more lines are too long

63
docs/kcl/scale.md Normal file

File diff suppressed because one or more lines are too long

30
docs/kcl/settings.md Normal file
View File

@ -0,0 +1,30 @@
---
title: "KCL settings"
excerpt: "Documentation of settings for the KCL language and Zoo Modeling App."
layout: manual
---
# Per-file settings
Settings which affect a single file are configured using the settings attribute.
This must be at the top of the KCL file (comments before the attribute are permitted).
E.g.,
```
// The settings attribute.
@settings(defaultLengthUnit = in)
// The rest of your KCL code goes below...
x = 42 // Represents 42 inches.
```
The settings attribute may contain multiple properties separated by commas.
Valid properties are:
- `defaultLengthUnit`: the default length unit to use for numbers declared in this file.
- Accepted values: `mm`, `cm`, `m`, `in` (inches), `ft` (feet), `yd` (yards).
- `defaultAngleUnit`: the default angle unit to use for numbers declared in this file.
- Accepted values: `deg` (degrees), `rad` (radians).
These settings override any project-wide settings (configured in project.toml or via the UI).

View File

@ -9,7 +9,11 @@ Remove volume from a 3-dimensional shape such that a wall of the
provided thickness remains, taking volume starting at the provided face, leaving it open in that direction. provided thickness remains, taking volume starting at the provided face, leaving it open in that direction.
```js ```js
shell(solidSet: SolidSet, thickness: number, faces: [FaceTag]) -> SolidSet shell(
solidSet: SolidSet,
thickness: number,
faces: [FaceTag],
) -> SolidSet
``` ```

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

@ -9,7 +9,11 @@ Draw a curved line segment along part of an imaginary circle.
The arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle. The arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle.
```js ```js
tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch tangentialArc(
data: TangentialArcData,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> S
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ angle = 60, length = 10 }, %) |> angledLine({ angle = 60, length = 10 }, %)
|> tangentialArc({ radius = 10, offset = -120 }, %) |> tangentialArc({ radius = 10, offset = -120 }, %)

View File

@ -9,7 +9,11 @@ Starting at the current sketch's origin, draw a curved line segment along
some part of an imaginary circle until it reaches the desired (x, y) coordinates. some part of an imaginary circle until it reaches the desired (x, y) coordinates.
```js ```js
tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch tangentialArcTo(
to: [number],
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ angle = 60, length = 10 }, %) |> angledLine({ angle = 60, length = 10 }, %)
|> tangentialArcTo([15, 15], %) |> tangentialArcTo([15, 15], %)

View File

@ -9,7 +9,11 @@ Starting at the current sketch's origin, draw a curved line segment along
some part of an imaginary circle until it reaches a point the given (x, y) distance away. some part of an imaginary circle until it reaches a point the given (x, y) distance away.
```js ```js
tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch tangentialArcToRelative(
delta: [number],
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) ->
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ angle = 45, length = 10 }, %) |> angledLine({ angle = 45, length = 10 }, %)
|> tangentialArcToRelative([0, -10], %) |> tangentialArcToRelative([0, -10], %)

61
docs/kcl/translate.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -74,18 +74,15 @@ fn myFn(x) {
As you can see above `myFn` just returns whatever it is given. As you can see above `myFn` just returns whatever it is given.
KCL's early drafts used positional arguments, but we now use keyword arguments. If you declare a KCL's early drafts used positional arguments, but we now use keyword arguments:
function like this:
``` ```
// If you declare a function like this
fn add(left, right) { fn add(left, right) {
return left + right return left + right
} }
```
You can call it like this: // You can call it like this:
```
total = add(left = 1, right = 2) total = add(left = 1, right = 2)
``` ```
@ -111,14 +108,14 @@ three = add(1, delta = 2)
It can be hard to read repeated function calls, because of all the nested brackets. It can be hard to read repeated function calls, because of all the nested brackets.
``` ```norun
i = 1 i = 1
x = h(g(f(i))) x = h(g(f(i)))
``` ```
You can make this easier to read by breaking it into many declarations, but that is a bit annoying. You can make this easier to read by breaking it into many declarations, but that is a bit annoying.
``` ```norun
i = 1 i = 1
x0 = f(i) x0 = f(i)
x1 = g(x0) x1 = g(x0)
@ -133,12 +130,12 @@ the `%` in the right-hand side.
So, this means `x |> f(%) |> g(%)` is shorthand for `g(f(x))`. The code example above, with its So, this means `x |> f(%) |> g(%)` is shorthand for `g(f(x))`. The code example above, with its
somewhat-clunky `x0` and `x1` constants could be rewritten as somewhat-clunky `x0` and `x1` constants could be rewritten as
``` ```norun
i = 1 i = 1
x = i x = i
|> f(%) |> f(%)
|> g(%) |> g(%)
|> h(%) |> h(%)
``` ```
This helps keep your code neat and avoid unnecessary declarations. This helps keep your code neat and avoid unnecessary declarations.
@ -147,12 +144,12 @@ This helps keep your code neat and avoid unnecessary declarations.
Say you have a long pipeline of sketch functions, like this: Say you have a long pipeline of sketch functions, like this:
``` ```norun
startSketch() startSketchOn('XZ')
|> line(%, end = [3, 4]) |> line(%, end = [3, 4])
|> line(%, end = [10, 10]) |> line(%, end = [10, 10])
|> line(%, end = [-13, -14]) |> line(%, end = [-13, -14])
|> close(%) |> close(%)
``` ```
In this example, each function call outputs a sketch, and it gets put into the next function call via In this example, each function call outputs a sketch, and it gets put into the next function call via
@ -162,12 +159,12 @@ If a function call uses an unlabeled first parameter, it will default to `%` if
means that `|> line(%, end = [3, 4])` and `|> line(end = [3, 4])` are equivalent! So the above means that `|> line(%, end = [3, 4])` and `|> line(end = [3, 4])` are equivalent! So the above
could be rewritten as could be rewritten as
``` ```norun
startSketch() startSketchOn('XZ')
|> line(end = [3, 4]) |> line(end = [3, 4])
|> line(end = [10, 10]) |> line(end = [10, 10])
|> line(end = [-13, -14]) |> line(end = [-13, -14])
|> close() |> close()
``` ```
Note that we are still in the process of migrating KCL's standard library to use keyword arguments. So some Note that we are still in the process of migrating KCL's standard library to use keyword arguments. So some
@ -184,7 +181,7 @@ Tags are used to give a name (tag) to a specific path.
The syntax for declaring a tag is `$myTag` you would use it in the following The syntax for declaring a tag is `$myTag` you would use it in the following
way: way:
``` ```norun
startSketchOn('XZ') startSketchOn('XZ')
|> startProfileAt(origin, %) |> startProfileAt(origin, %)
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001) |> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
@ -216,7 +213,7 @@ use the tag `rectangleSegmentA001` in any function or expression in the file.
However if the code was written like this: However if the code was written like this:
``` ```norun
fn rect(origin) { fn rect(origin) {
return startSketchOn('XZ') return startSketchOn('XZ')
|> startProfileAt(origin, %) |> startProfileAt(origin, %)
@ -244,7 +241,7 @@ However you likely want to use those tags somewhere outside the `rect` function.
Tags are accessible through the sketch group they are declared in. Tags are accessible through the sketch group they are declared in.
For example the following code works. For example the following code works.
``` ```norun
fn rect(origin) { fn rect(origin) {
return startSketchOn('XZ') return startSketchOn('XZ')
|> startProfileAt(origin, %) |> startProfileAt(origin, %)

View File

@ -34,6 +34,18 @@ A custom plane.
----
A custom plane which has not been sent to the engine. It must be sent before it is used.
**enum:** `Uninit`
---- ----

View File

@ -9,7 +9,11 @@ Draw a line relative to the current origin to a specified distance away
from the current position along the 'x' axis. from the current position along the 'x' axis.
```js ```js
xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch xLine(
length: number,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> xLine(15, %) |> xLine(15, %)
|> angledLine({ angle = 80, length = 15 }, %) |> angledLine({ angle = 80, length = 15 }, %)

View File

@ -9,7 +9,11 @@ Draw a line parallel to the X axis, that ends at the given X.
E.g. if the previous line ended at (1, 1), then xLineTo(4) draws a line from (1, 1) to (4, 1) E.g. if the previous line ended at (1, 1), then xLineTo(4) draws a line from (1, 1) to (4, 1)
```js ```js
xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch xLineTo(
to: number,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> xLineTo(15, %) |> xLineTo(15, %)
|> angledLine({ angle = 80, length = 15 }, %) |> angledLine({ angle = 80, length = 15 }, %)

View File

@ -9,7 +9,11 @@ Draw a line relative to the current origin to a specified distance away
from the current position along the 'y' axis. from the current position along the 'y' axis.
```js ```js
yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch yLine(
length: number,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn('XZ') exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> yLine(15, %) |> yLine(15, %)
|> angledLine({ angle = 30, length = 15 }, %) |> angledLine({ angle = 30, length = 15 }, %)

View File

@ -9,7 +9,11 @@ Draw a line parallel to the Y axis, that ends at the given Y.
E.g. if the previous line ended at (1, 1), then yLineTo(4) draws a line from (1, 1) to (1, 4) E.g. if the previous line ended at (1, 1), then yLineTo(4) draws a line from (1, 1) to (1, 4)
```js ```js
yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch yLineTo(
to: number,
sketch: Sketch,
tag?: TagDeclarator,
) -> Sketch
``` ```
@ -29,7 +33,7 @@ yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = 45 }, %) |> angledLine({ angle = 50, length = 45 }, %)
|> yLineTo(0, %) |> yLineTo(0, %)

View File

@ -3,6 +3,7 @@ import { HomePageFixture } from './fixtures/homePageFixture'
import { getUtils } from './test-utils' import { getUtils } from './test-utils'
import { EngineCommand } from 'lang/std/artifactGraph' import { EngineCommand } from 'lang/std/artifactGraph'
import { uuidv4 } from 'lib/utils' import { uuidv4 } from 'lib/utils'
import { SceneFixture } from './fixtures/sceneFixture'
test.describe( test.describe(
'Can create sketches on all planes and their back sides', 'Can create sketches on all planes and their back sides',
@ -11,16 +12,17 @@ test.describe(
const sketchOnPlaneAndBackSideTest = async ( const sketchOnPlaneAndBackSideTest = async (
page: Page, page: Page,
homePage: HomePageFixture, homePage: HomePageFixture,
scene: SceneFixture,
plane: string, plane: string,
clickCoords: { x: number; y: number } clickCoords: { x: number; y: number }
) => { ) => {
const u = await getUtils(page) const u = await getUtils(page)
const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
// FIXME: Cannot use scene.waitForExecutionDone() since there is no KCL code const XYPlanRed: [number, number, number] = [98, 50, 51]
await page.waitForTimeout(10000) await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
await u.openDebugPanel() await u.openDebugPanel()
const coord = const coord =
@ -43,7 +45,7 @@ test.describe(
}, },
} }
const code = `sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.9, -1.22], sketch001)` const code = `sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.91, -1.22], sketch001)`
await u.openDebugPanel() await u.openDebugPanel()
@ -56,17 +58,14 @@ test.describe(
await u.closeDebugPanel() await u.closeDebugPanel()
await page.mouse.click(clickCoords.x, clickCoords.y) await page.mouse.click(clickCoords.x, clickCoords.y)
await page.waitForTimeout(300) // wait for animation await page.waitForTimeout(600) // wait for animation
await expect( await expect(
page.getByRole('button', { name: 'line Line', exact: true }) page.getByRole('button', { name: 'line Line', exact: true })
).toBeVisible() ).toBeVisible()
// draw a line
const startXPx = 600
await u.closeDebugPanel() await u.closeDebugPanel()
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await page.mouse.click(707, 393)
await expect(page.locator('.cm-content')).toHaveText(code) await expect(page.locator('.cm-content')).toHaveText(code)
@ -81,49 +80,50 @@ test.describe(
await u.clearCommandLogs() await u.clearCommandLogs()
await u.removeCurrentCode() await u.removeCurrentCode()
} }
test('XY', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest(
page,
homePage,
'XY',
{ x: 600, y: 388 } // red plane
// { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too.
)
})
test('YZ', async ({ page, homePage }) => { const planeConfigs = [
await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', { {
x: 700, plane: 'XY',
y: 250, coords: { x: 600, y: 388 },
}) // green plane description: 'red plane',
}) },
{
plane: 'YZ',
coords: { x: 700, y: 250 },
description: 'green plane',
},
{
plane: 'XZ',
coords: { x: 684, y: 427 },
description: 'blue plane',
},
{
plane: '-XY',
coords: { x: 600, y: 118 },
description: 'back of red plane',
},
{
plane: '-YZ',
coords: { x: 700, y: 219 },
description: 'back of green plane',
},
{
plane: '-XZ',
coords: { x: 700, y: 80 },
description: 'back of blue plane',
},
]
test('XZ', async ({ page, homePage }) => { for (const config of planeConfigs) {
await sketchOnPlaneAndBackSideTest(page, homePage, '-XZ', { test(config.plane, async ({ page, homePage, scene }) => {
x: 700, await sketchOnPlaneAndBackSideTest(
y: 80, page,
}) // blue plane homePage,
}) scene,
config.plane,
test('-XY', async ({ page, homePage }) => { config.coords
await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', { )
x: 600, })
y: 118, }
}) // back of red plane
})
test('-YZ', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', {
x: 700,
y: 219,
}) // back of green plan
})
test('-XZ', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest(page, homePage, 'XZ', {
x: 700,
y: 427,
}) // back of blue plane
})
} }
) )

View File

@ -125,6 +125,12 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
await expect(cmdSearchBar).toBeVisible() await expect(cmdSearchBar).toBeVisible()
await expect(cmdSearchBar).toBeFocused() await expect(cmdSearchBar).toBeFocused()
await test.step(`Pressing backspace in the command selection step does not dismiss`, async () => {
await page.keyboard.press('Backspace')
await expect(cmdSearchBar).toBeVisible()
await expect(cmdSearchBar).toBeFocused()
})
// Try typing in the command bar // Try typing in the command bar
await cmdSearchBar.fill(commandName) await cmdSearchBar.fill(commandName)
await expect(commandOption).toBeVisible() await expect(commandOption).toBeVisible()

View File

@ -1,5 +1,7 @@
import type { Page, Locator } from '@playwright/test' import type { Page, Locator, Route, Request } from '@playwright/test'
import { expect } from '@playwright/test' import { expect, TestInfo } from '@playwright/test'
import * as fs from 'fs'
import * as path from 'path'
type CmdBarSerialised = type CmdBarSerialised =
| { | {
@ -187,4 +189,71 @@ export class CmdBarFixture {
selectOption = (options: Parameters<typeof this.page.getByRole>[1]) => { selectOption = (options: Parameters<typeof this.page.getByRole>[1]) => {
return this.page.getByRole('option', options) return this.page.getByRole('option', options)
} }
/**
* Captures a snapshot of the request sent to the text-to-cad API endpoint
* and saves it to a file named after the current test.
*
* The snapshot file will be saved in the specified directory with a filename
* derived from the test's full path (including describe blocks).
*
* @param testInfoInOrderToGetTestTitle The TestInfo object from the test context
* @param customOutputDir Optional custom directory for the output file
*/
async captureTextToCadRequestSnapshot(
testInfoInOrderToGetTestTitle: TestInfo,
customOutputDir = 'e2e/playwright/snapshots/prompt-to-edit'
) {
// First sanitize each title component individually
const sanitizedTitleComponents = [
...testInfoInOrderToGetTestTitle.titlePath.slice(0, -1), // Get all parent titles
testInfoInOrderToGetTestTitle.title, // Add the test title
].map(
(component) =>
component
.replace(/[^a-z0-9]/gi, '-') // Replace non-alphanumeric chars with hyphens
.toLowerCase()
.replace(/-+/g, '-') // Replace multiple consecutive hyphens with a single one
.replace(/^-|-$/g, '') // Remove leading/trailing hyphens
)
// Join the sanitized components with -- as a clear separator
const sanitizedTestName = sanitizedTitleComponents.join('--')
// Create the output path
const outputPath = path.join(
customOutputDir,
`${sanitizedTestName}.snap.json`
)
// Create a handler function that saves request bodies to a file
const requestHandler = (route: Route, request: Request) => {
try {
const requestBody = request.postDataJSON()
// Ensure directory exists
const dir = path.dirname(outputPath)
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true })
}
// Write the request body to the file
fs.writeFileSync(outputPath, JSON.stringify(requestBody, null, 2))
console.log(`Saved text-to-cad API request to: ${outputPath}`)
} catch (error) {
console.error('Error processing text-to-cad request:', error)
}
// Use void to explicitly mark the promise as ignored
void route.continue()
}
// Start monitoring requests
await this.page.route('**/ml/text-to-cad/iteration', requestHandler)
console.log(
`Monitoring text-to-cad API requests. Output will be saved to: ${outputPath}`
)
}
} }

View File

@ -82,16 +82,6 @@ export class ToolbarFixture {
startSketchPlaneSelection = async () => startSketchPlaneSelection = async () =>
doAndWaitForImageDiff(this.page, () => this.startSketchBtn.click(), 500) doAndWaitForImageDiff(this.page, () => this.startSketchBtn.click(), 500)
exitSketch = async () => {
await this.exitSketchBtn.click()
await expect(
this.page.getByRole('button', { name: 'Start Sketch' })
).toBeVisible()
await expect(
this.page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
}
editSketch = async () => { editSketch = async () => {
await this.editSketchBtn.first().click() await this.editSketchBtn.first().click()
// One of the rare times we want to allow a arbitrary wait // One of the rare times we want to allow a arbitrary wait

View File

@ -9,7 +9,7 @@ import { Locator } from '@playwright/test'
// test file is for testing point an click code gen functionality that's not sketch mode related // test file is for testing point an click code gen functionality that's not sketch mode related
test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => { test.describe('Point-and-click tests', () => {
test('verify extruding circle works', async ({ test('verify extruding circle works', async ({
context, context,
homePage, homePage,
@ -170,7 +170,8 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
}) })
await test.step('Clean up so that `_sketchOnAChamfer` util can be called again', async () => { await test.step('Clean up so that `_sketchOnAChamfer` util can be called again', async () => {
await toolbar.exitSketch() await toolbar.exitSketchBtn.click()
await scene.waitForExecutionDone()
}) })
await test.step('Check there is no errors after code created in previous steps executes', async () => { await test.step('Check there is no errors after code created in previous steps executes', async () => {
await editor.expectState({ await editor.expectState({
@ -201,9 +202,7 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
}, file) }, file)
await page.setBodyDimensions({ width: 1000, height: 500 }) await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
await expect( await scene.waitForExecutionDone()
page.getByTestId('model-state-indicator-receive-reliable')
).toBeVisible()
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene) const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
@ -391,7 +390,6 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
}, file) }, file)
await page.setBodyDimensions({ width: 1000, height: 500 }) await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
await scene.waitForExecutionDone() await scene.waitForExecutionDone()
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene) const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)

View File

@ -0,0 +1,98 @@
import { test, expect } from './zoo-test'
/* eslint-disable jest/no-conditional-expect */
/**
* Snapshot Tests for Text-to-CAD API Requests
*
* These tests are primarily designed to capture the requests sent to the Text-to-CAD API
* rather than to verify application behavior. Unlike regular tests, these tests:
*
* 1. Don't assert much about the application's response or state changes
* 2. Focus on setting up specific scenarios and triggering API requests
* 3. Use the captureTextToCadRequestSnapshot() method to save request payloads to snapshot files
*
* The main purpose is to maintain a collection of real-world API request examples that can be:
* - Used for regression testing the (AI) API
* - Referenced when making changes to the Text-to-CAD integration, particularly the meta-prompts
* the frontend adds to the user's prompt
*
* These tests intentionally don't wait for or verify responses, as we're primarily
* interested in capturing the outgoing requests for documentation and analysis.
*
*/
const file = `sketch001 = startSketchOn('XZ')
profile001 = startProfileAt([57.81, 250.51], sketch001)
|> line(end = [121.13, 56.63], tag = $seg02)
|> line(end = [83.37, -34.61], tag = $seg01)
|> line(end = [19.66, -116.4])
|> line(end = [-221.8, -41.69])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude001 = extrude(profile001, length = 200)
sketch002 = startSketchOn('XZ')
|> startProfileAt([-73.64, -42.89], %)
|> xLine(173.71, %)
|> line(end = [-22.12, -94.4])
|> xLine(-156.98, %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude002 = extrude(sketch002, length = 50)
sketch003 = startSketchOn('XY')
|> startProfileAt([52.92, 157.81], %)
|> angledLine([0, 176.4], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
53.4
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude003 = extrude(sketch003, length = 20)
`
test(
`change colour`,
{ tag: '@snapshot' },
async ({ context, homePage, cmdBar, editor, page, scene }) => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
const body1CapCoords = { x: 571, y: 351 }
const [clickBody1Cap] = scene.makeMouseHelpers(
body1CapCoords.x,
body1CapCoords.y
)
const yellow: [number, number, number] = [179, 179, 131]
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
await test.step('wait for scene to load select body and check selection came through', async () => {
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
await clickBody1Cap()
await scene.expectPixelColor(yellow, body1CapCoords, 20)
await editor.expectState({
highlightedCode: '',
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
diagnostics: [],
})
})
await test.step('fire off edit prompt', async () => {
await cmdBar.captureTextToCadRequestSnapshot(test.info())
await cmdBar.openCmdBar('promptToEdit')
// being specific about the color with a hex means asserting pixel color is more stable
await page
.getByTestId('cmd-bar-arg-value')
.fill('make this neon green please, use #39FF14')
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(submittingToast).toBeVisible()
})
}
)

View File

@ -629,6 +629,39 @@ extrude001 = extrude(sketch001, length = 50)
) )
}) })
}) })
test(`Toolbar doesn't show modeling tools during sketch plane selection animation`, async ({
page,
homePage,
toolbar,
}) => {
await test.step('Load an empty file', async () => {
await page.addInitScript(async () => {
localStorage.setItem('persistCode', '')
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
})
const toolBarMode = () =>
page.locator('[data-currentMode]').getAttribute('data-currentMode')
await test.step('Start sketch and select a plane', async () => {
await expect.poll(toolBarMode).toEqual('modeling')
// Click the start sketch button
await toolbar.startSketchPlaneSelection()
// Click on a default plane at position [700, 200]
await page.mouse.click(700, 200)
// Check that the modeling toolbar doesn't appear during the animation
// The animation typically takes around 500ms, so we'll check for a second
await expect.poll(toolBarMode, { timeout: 1000 }).not.toEqual('modeling')
// After animation completes, we should see the sketching toolbar
await expect.poll(toolBarMode).toEqual('sketching')
})
})
}) })
async function clickExportButton(page: Page) { async function clickExportButton(page: Page) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Some files were not shown because too many files have changed in this diff Show More