Compare commits
6 Commits
nrc-refact
...
paultag/ma
Author | SHA1 | Date | |
---|---|---|---|
eea823e0bc | |||
a1b875062f | |||
0924dd4f60 | |||
6b7f200564 | |||
1a7339fb70 | |||
c1a450b15e |
@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast,ue,afterall
|
||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock,./openapi/*.json,./src/lib/machine-api.d.ts
|
||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock
|
||||
|
84
.github/workflows/build-test-publish-apps.yml
vendored
@ -25,7 +25,6 @@ jobs:
|
||||
runs-on: ubuntu-22.04 # seperate job on Ubuntu for easy string manipulations (compared to Windows)
|
||||
outputs:
|
||||
version: ${{ steps.export_version.outputs.version }}
|
||||
notes: ${{ steps.export_version.outputs.notes }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@ -52,22 +51,12 @@ jobs:
|
||||
run: |
|
||||
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
||||
|
||||
# TODO: see if we need to inject updater nightly URL here https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Non-release build, commit {0}', github.sha) }}
|
||||
run: |
|
||||
echo "$NOTES" > release-notes.md
|
||||
cat release-notes.md
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: prepared-files
|
||||
path: |
|
||||
package.json
|
||||
src/wasm-lib/pkg/wasm_lib*
|
||||
release-notes.md
|
||||
|
||||
- id: export_version
|
||||
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
|
||||
@ -84,13 +73,10 @@ jobs:
|
||||
path: |
|
||||
electron-builder.yml
|
||||
|
||||
- id: export_notes
|
||||
run: echo "notes=`cat release-notes.md'`" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Prepare electron-builder.yml file for updater test
|
||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||
run: |
|
||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test-release-notes"' electron-builder.yml
|
||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||
@ -105,13 +91,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-14
|
||||
platform: mac
|
||||
- os: windows-2022
|
||||
platform: win
|
||||
- os: ubuntu-22.04
|
||||
platform: linux
|
||||
os: [macos-14, windows-2022, ubuntu-22.04]
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
@ -138,7 +118,6 @@ jobs:
|
||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||
mkdir src/wasm-lib/pkg
|
||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
|
||||
cp prepared-files/release-notes.md release-notes.md
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
if: ${{ github.event_name == 'schedule' }}
|
||||
@ -194,29 +173,17 @@ jobs:
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: out-arm64-${{ matrix.platform }}
|
||||
# first two will pick both Zoo Modeling App-$VERSION-arm64-win.exe and Zoo Modeling App-$VERSION-win.exe
|
||||
path: |
|
||||
out/*-${{ env.VERSION_NO_V }}-win.*
|
||||
out/*-${{ env.VERSION_NO_V }}-arm64-win.*
|
||||
out/*-arm64-mac.*
|
||||
out/*-arm64-linux.*
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: out-x64-${{ matrix.platform }}
|
||||
path: |
|
||||
out/*-x64-win.*
|
||||
out/*-x64-mac.*
|
||||
out/*-x86_64-linux.*
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ env.BUILD_RELEASE == 'true' }}
|
||||
with:
|
||||
name: out-yml
|
||||
name: out-arm64-${{ matrix.os }}
|
||||
path: |
|
||||
out/Zoo*arm64*.*
|
||||
out/latest*.yml
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: out-x64-${{ matrix.os }}
|
||||
path: |
|
||||
out/Zoo*x*64*.*
|
||||
|
||||
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
@ -236,20 +203,16 @@ jobs:
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||
with:
|
||||
name: updater-test-arm64-${{ matrix.platform }}
|
||||
name: updater-test-arm64-${{ matrix.os }}
|
||||
path: |
|
||||
out/*-arm64-win.exe
|
||||
out/*-arm64-mac.dmg
|
||||
out/*-arm64-linux.AppImage
|
||||
out/Zoo*arm64*.*
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||
with:
|
||||
name: updater-test-x64-${{ matrix.platform }}
|
||||
name: updater-test-x64-${{ matrix.os }}
|
||||
path: |
|
||||
out/*-x64-win.exe
|
||||
out/*-x64-mac.dmg
|
||||
out/*-x86_64-linux.AppImage
|
||||
out/Zoo*x64*.*
|
||||
|
||||
|
||||
publish-apps-release:
|
||||
@ -262,7 +225,7 @@ jobs:
|
||||
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
||||
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
|
||||
PUB_DATE: ${{ github.event_name == 'release' && github.event.release.created_at || github.event.repository.updated_at }}
|
||||
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
||||
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Non-release build, commit {0}', github.sha) }}
|
||||
BUCKET_DIR: ${{ github.event_name == 'schedule' && 'dl.kittycad.io/releases/modeling-app/nightly' || 'dl.kittycad.io/releases/modeling-app' }}
|
||||
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
||||
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
||||
@ -271,37 +234,32 @@ jobs:
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-arm64-win
|
||||
name: out-arm64-windows-2022
|
||||
path: out
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-x64-win
|
||||
name: out-x64-windows-2022
|
||||
path: out
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-arm64-mac
|
||||
name: out-arm64-macos-14
|
||||
path: out
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-x64-mac
|
||||
name: out-x64-macos-14
|
||||
path: out
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-arm64-linux
|
||||
name: out-arm64-ubuntu-22.04
|
||||
path: out
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-x64-linux
|
||||
path: out
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: out-yml
|
||||
name: out-x64-ubuntu-22.04
|
||||
path: out
|
||||
|
||||
- name: Generate the download static endpoint
|
||||
|
13
.github/workflows/static-analysis.yml
vendored
@ -37,6 +37,10 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
|
||||
- run: yarn build:wasm
|
||||
|
||||
yarn-tsc:
|
||||
@ -66,6 +70,10 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- run: yarn install
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
|
||||
- run: yarn lint
|
||||
|
||||
python-codespell:
|
||||
@ -93,6 +101,11 @@ jobs:
|
||||
cache: 'yarn'
|
||||
|
||||
- run: yarn install
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
|
||||
- run: yarn build:wasm
|
||||
|
||||
- run: yarn simpleserver:bg
|
||||
|
78
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
## Zoo Modeling App
|
||||
|
||||
download at [zoo.dev/modeling-app/download](https://zoo.dev/modeling-app/download)
|
||||
live at [app.zoo.dev](https://app.zoo.dev/)
|
||||
|
||||
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
|
||||
|
||||
@ -57,7 +57,7 @@ yarn install
|
||||
followed by:
|
||||
|
||||
```
|
||||
yarn build:wasm
|
||||
yarn build:wasm-dev
|
||||
```
|
||||
|
||||
or if you have the gh cli installed
|
||||
@ -66,15 +66,15 @@ or if you have the gh cli installed
|
||||
./get-latest-wasm-bundle.sh # this will download the latest main wasm bundle
|
||||
```
|
||||
|
||||
That will build the WASM binary and put in the `public` dir (though gitignored).
|
||||
That will build the WASM binary and put in the `public` dir (though gitignored)
|
||||
|
||||
Finally, to run the web app only, run:
|
||||
finally, to run the web app only, run:
|
||||
|
||||
```
|
||||
yarn start
|
||||
```
|
||||
|
||||
If you're not an KittyCAD employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to localhost:3000 again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again.
|
||||
If you're not an KittyCAD employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens ofcourse, then navigate to localhost:3000 again. Note that navigating to localhost:3000/signin removes your token so you will need to set the token again.
|
||||
|
||||
### Development environment variables
|
||||
|
||||
@ -91,13 +91,13 @@ Third-Party Cookies".
|
||||
|
||||
## Desktop
|
||||
|
||||
To spin up the desktop app, `yarn install` and `yarn build:wasm` need to have been done before hand then
|
||||
To spin up the desktop app, `yarn install` and `yarn build:wasm-dev` need to have been done before hand then
|
||||
|
||||
```
|
||||
yarn tron:start
|
||||
yarn electron:start
|
||||
```
|
||||
|
||||
This will start the application and hot-reload on changes.
|
||||
This will start the application and hot-reload on changed.
|
||||
|
||||
Devtools can be opened with the usual Cmd/Ctrl-Shift-I.
|
||||
|
||||
@ -128,18 +128,7 @@ Before you submit a contribution PR to this repo, please ensure that:
|
||||
|
||||
## Release a new version
|
||||
|
||||
#### 1. Bump the versions by running `./make-release.sh`
|
||||
|
||||
The `./make-release.sh` script has git commands to pull main but to be sure you can run the following git commands to have a fresh `main` locally.
|
||||
|
||||
```
|
||||
git branch -D main
|
||||
git checkout main
|
||||
git pull origin
|
||||
./make-release.sh
|
||||
# Copy within the back ticks and paste the stdout of the change log
|
||||
git push --set-upstream origin <branch name created from ./make-release.sh>
|
||||
```
|
||||
#### 1. Bump the versions by running `./make-release.sh` and create a Cut Release PR
|
||||
|
||||
That will create the branch with the updated json files for you:
|
||||
- run `./make-release.sh` or `./make-release.sh patch` for a patch update;
|
||||
@ -148,50 +137,28 @@ That will create the branch with the updated json files for you:
|
||||
|
||||
After it runs you should just need the push the branch and open a PR.
|
||||
|
||||
#### 2. Create a Cut Release PR
|
||||
|
||||
When you open the PR copy the change log from the output of the `./make-release.sh` script into the description of the PR.
|
||||
|
||||
**Important:** Pull request title needs to be prefixed with `Cut release v` to build in release mode and a few other things to test in the best context possible, the intent would be for instance to have `Cut release v1.2.3` for the `v1.2.3` release candidate.
|
||||
**Important:** It needs to be prefixed with `Cut release v` to build in release mode and a few other things to test in the best context possible, the intent would be for instance to have `Cut release v1.2.3` for the `v1.2.3` release candidate.
|
||||
|
||||
The PR may then serve as a place to discuss the human-readable changelog and extra QA. The `make-release.sh` tool suggests a changelog for you too to be used as PR description, just make sure to delete lines that are not user facing.
|
||||
|
||||
#### 3. Manually test artifacts from the Cut Release PR
|
||||
#### 2. Smoke test artifacts from the Cut Release PR
|
||||
|
||||
##### Release builds
|
||||
The release builds can be find under the `artifact` zip, at the very bottom of the `ci` action page for each commit on this branch.
|
||||
|
||||
The release builds can be found under the `out-{platform}` zip, at the very bottom of the `build-publish-apps` summary page for each commit on this branch.
|
||||
We don't have a strict process, but click around and check for anything obvious, posting results as comments in the Cut Release PR.
|
||||
|
||||
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the Cut Release PR.
|
||||
The other `ci` output in Cut Release PRs is `updater-test`, because we don't have a way to test this fully automated, we have a semi-automated process. Download updater-test zip file, install the app, run it, expect an updater prompt to a dummy v0.99.99, install it and check that the app comes back at that version (on both macOS and Windows).
|
||||
|
||||
##### Updater-test builds
|
||||
|
||||
The other `build-publish-apps` output in Cut Release PRs is `updater-test-{platform}`. As we don't have a way to test this fully automatically, we have a semi-automated process. For macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
||||
|
||||
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
||||
|
||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
|
||||
```
|
||||
# Windows (PowerShell)
|
||||
& 'C:\Program Files\Zoo Modeling App\Zoo Modeling App.exe'
|
||||
|
||||
# macOS
|
||||
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
|
||||
|
||||
# Linux
|
||||
./Zoo Modeling App-{version}-{arch}-linux.AppImage
|
||||
```
|
||||
|
||||
#### 4. Merge the Cut Release PR
|
||||
#### 3. Merge the Cut Release PR
|
||||
|
||||
This will kick the `create-release` action, that creates a _Draft_ release out of this Cut Release PR merge after less than a minute, with the new version as title and Cut Release PR as description.
|
||||
|
||||
|
||||
#### 5. Publish the release
|
||||
#### 4. Publish the release
|
||||
|
||||
Head over to https://github.com/KittyCAD/modeling-app/releases, the draft release corresponding to the merged Cut Release PR should show up at the top as _Draft_. Click on it, verify the content, and hit _Publish_.
|
||||
|
||||
#### 6. Profit
|
||||
#### 5. Profit
|
||||
|
||||
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter.
|
||||
|
||||
@ -352,16 +319,7 @@ Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testin
|
||||
|
||||
```bash
|
||||
cd src/wasm-lib
|
||||
KITTYCAD_API_TOKEN=XXX cargo test -- --test-threads=1
|
||||
```
|
||||
|
||||
Where `XXX` is an API token from the production engine (NOT the dev environment).
|
||||
|
||||
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
|
||||
|
||||
```
|
||||
cd src/wasm-lib
|
||||
KITTYCAD_API_TOKEN=XXX cargo run nextest
|
||||
cargo test
|
||||
```
|
||||
|
||||
### Mapping CI CD jobs to local commands
|
||||
|
@ -9,7 +9,7 @@ Draw a line segment relative to the current origin using the polar
|
||||
measure of some angle and distance.
|
||||
|
||||
```js
|
||||
angledLine(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLine(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some relative length in the 'x' dimension.
|
||||
|
||||
```js
|
||||
angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sket
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some relative length in the 'y' dimension.
|
||||
|
||||
```js
|
||||
angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sket
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw an angled line from the current origin, constructing a line segment
|
||||
such that the newly created line intersects the desired target line segment.
|
||||
|
||||
```js
|
||||
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineThatIntersectsData`](/docs/kcl/types/AngledLineThatIntersectsData) | Data for drawing an angled line that intersects with a given line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineToData`](/docs/kcl/types/AngledLineToData) | Data to draw an angled line to a point. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineToData`](/docs/kcl/types/AngledLineToData) | Data to draw an angled line to a point. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -11,7 +11,7 @@ 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.
|
||||
|
||||
```js
|
||||
arc(data: ArcData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
arc(data: ArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ arc(data: ArcData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`ArcData`](/docs/kcl/types/ArcData) | Data to draw an arc. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
bezierCurve(data: BezierData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
bezierCurve(data: BezierData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ bezierCurve(data: BezierData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`BezierData`](/docs/kcl/types/BezierData) | Data to draw a bezier curve. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
chamfer(data: ChamferData, solid: Solid, tag?: TagNode) -> Solid
|
||||
chamfer(data: ChamferData, solid: Solid, tag?: TagDeclarator) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ chamfer(data: ChamferData, solid: Solid, tag?: TagNode) -> Solid
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`ChamferData`](/docs/kcl/types/ChamferData) | Data for chamfers. | Yes |
|
||||
| `solid` | [`Solid`](/docs/kcl/types/Solid) | An solid is a collection of extrude surfaces. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Construct a 2-dimensional circle, of the specified radius, centered at
|
||||
the provided (x, y) origin point.
|
||||
|
||||
```js
|
||||
circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagNode) -> Sketch
|
||||
circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagNode
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`CircleData`](/docs/kcl/types/CircleData) | Data for drawing an circle | Yes |
|
||||
| `sketch_surface_or_group` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Construct a line segment from the current origin back to the profile's
|
||||
origin, ensuring the resulting 2-dimensional sketch is not open-ended.
|
||||
|
||||
```js
|
||||
close(sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
close(sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ close(sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
fillet(data: FilletData, solid: Solid, tag?: TagNode) -> Solid
|
||||
fillet(data: FilletData, solid: Solid, tag?: TagDeclarator) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ fillet(data: FilletData, solid: Solid, tag?: TagNode) -> Solid
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`FilletData`](/docs/kcl/types/FilletData) | Data for fillets. | Yes |
|
||||
| `solid` | [`Solid`](/docs/kcl/types/Solid) | An solid is a collection of extrude surfaces. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line relative to the current origin to a specified (x, y) away
|
||||
from the current position.
|
||||
|
||||
```js
|
||||
line(delta: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
line(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ line(delta: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `delta` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line from the current origin to some absolute (x, y) point.
|
||||
|
||||
|
||||
```js
|
||||
lineTo(to: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
lineTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ lineTo(to: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -36,7 +36,7 @@ exampleSketch = startSketchOn('XZ')
|
||||
|> close(%)
|
||||
|> patternCircular2d({
|
||||
center: [0, 0],
|
||||
instances: 13,
|
||||
repetitions: 12,
|
||||
arcDegrees: 360,
|
||||
rotateDuplicates: true
|
||||
}, %)
|
||||
|
@ -35,7 +35,7 @@ example = extrude(-5, exampleSketch)
|
||||
|> patternCircular3d({
|
||||
axis: [1, -1, 0],
|
||||
center: [10, -20, 0],
|
||||
instances: 11,
|
||||
repetitions: 10,
|
||||
arcDegrees: 360,
|
||||
rotateDuplicates: true
|
||||
}, %)
|
||||
|
@ -32,7 +32,7 @@ exampleSketch = startSketchOn('XZ')
|
||||
|> circle({ center: [0, 0], radius: 1 }, %)
|
||||
|> patternLinear2d({
|
||||
axis: [1, 0],
|
||||
instances: 7,
|
||||
repetitions: 6,
|
||||
distance: 4
|
||||
}, %)
|
||||
|
||||
|
@ -38,7 +38,7 @@ exampleSketch = startSketchOn('XZ')
|
||||
example = extrude(1, exampleSketch)
|
||||
|> patternLinear3d({
|
||||
axis: [1, 0, 1],
|
||||
instances: 7,
|
||||
repetitions: 6,
|
||||
distance: 6
|
||||
}, %)
|
||||
```
|
||||
|
@ -9,7 +9,7 @@ Start a new profile at a given point.
|
||||
|
||||
|
||||
```js
|
||||
startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagNode) -> Sketch
|
||||
startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagNode) -> Sk
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `[number]` | | Yes |
|
||||
| `sketch_surface` | [`SketchSurface`](/docs/kcl/types/SketchSurface) | A sketch type. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
25628
docs/kcl/std.json
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`TangentialArcData`](/docs/kcl/types/TangentialArcData) | Data to draw a tangential arc. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
tangentialArcTo(to: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ tangentialArcTo(to: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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.
|
||||
|
||||
```js
|
||||
tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagNode) -> Sketc
|
||||
|----------|------|-------------|----------|
|
||||
| `delta` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -18,7 +18,7 @@ A base path.
|
||||
|----------|------|-------------|----------|
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -82,78 +82,6 @@ Raise a number to a power.
|
||||
|
||||
|
||||
|
||||
----
|
||||
Are two numbers equal?
|
||||
|
||||
**enum:** `==`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Are two numbers not equal?
|
||||
|
||||
**enum:** `!=`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left greater than right
|
||||
|
||||
**enum:** `>`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left greater than or equal to right
|
||||
|
||||
**enum:** `>=`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left less than right
|
||||
|
||||
**enum:** `<`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left less than or equal to right
|
||||
|
||||
**enum:** `<=`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
@ -22,10 +22,12 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `kind` |[`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -41,9 +43,10 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -58,10 +61,13 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`BinaryExpression`](/docs/kcl/types/BinaryExpression)| | No |
|
||||
| `kind` |[`BinaryExpression`](/docs/kcl/types/BinaryExpression)| | No |
|
||||
| `type` |enum: `BinaryExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`BinaryOperator`](/docs/kcl/types/BinaryOperator)| | No |
|
||||
| `left` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `right` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -76,10 +82,13 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`CallExpression`](/docs/kcl/types/CallExpression)| | No |
|
||||
| `kind` |[`CallExpression`](/docs/kcl/types/CallExpression)| | No |
|
||||
| `type` |enum: `CallExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `callee` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `arguments` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `optional` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -94,10 +103,12 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`UnaryExpression`](/docs/kcl/types/UnaryExpression)| | No |
|
||||
| `kind` |[`UnaryExpression`](/docs/kcl/types/UnaryExpression)| | No |
|
||||
| `type` |enum: `UnaryExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`UnaryOperator`](/docs/kcl/types/UnaryOperator)| | No |
|
||||
| `argument` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -112,10 +123,13 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `kind` |[`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -130,10 +144,14 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`IfExpression`](/docs/kcl/types/IfExpression)| | No |
|
||||
| `kind` |[`IfExpression`](/docs/kcl/types/IfExpression)| | No |
|
||||
| `type` |enum: `IfExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `else_ifs` |`[` [`ElseIf`](/docs/kcl/types/ElseIf) `]`| | No |
|
||||
| `final_else` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -22,10 +22,11 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`ImportStatement`](/docs/kcl/types/ImportStatement)| | No |
|
||||
| `kind` |[`ImportStatement`](/docs/kcl/types/ImportStatement)| | No |
|
||||
| `type` |enum: `ExpressionStatement`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `expression` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -40,10 +41,12 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`ExpressionStatement`](/docs/kcl/types/ExpressionStatement)| | No |
|
||||
| `kind` |[`ExpressionStatement`](/docs/kcl/types/ExpressionStatement)| | No |
|
||||
| `type` |enum: `VariableDeclaration`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `declarations` |`[` [`VariableDeclarator`](/docs/kcl/types/VariableDeclarator) `]`| | No |
|
||||
| `kind` |[`VariableKind`](/docs/kcl/types/VariableKind)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -58,28 +61,11 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`VariableDeclaration`](/docs/kcl/types/VariableDeclaration)| | No |
|
||||
| `kind` |[`VariableDeclaration`](/docs/kcl/types/VariableDeclaration)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`ReturnStatement`](/docs/kcl/types/ReturnStatement)| | No |
|
||||
| `kind` |[`ReturnStatement`](/docs/kcl/types/ReturnStatement)| | No |
|
||||
| `type` |enum: `ReturnStatement`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `argument` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -16,7 +16,7 @@ Data for a circular pattern on a 2D sketch.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||
| `repetitions` |[`Uint`](/docs/kcl/types/Uint)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No |
|
||||
| `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No |
|
||||
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
|
||||
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
|
||||
|
@ -16,7 +16,7 @@ Data for a circular pattern on a 3D model.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||
| `repetitions` |[`Uint`](/docs/kcl/types/Uint)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No |
|
||||
| `axis` |`[number, number, number]`| The axis around which to make the pattern. This is a 3D vector. | No |
|
||||
| `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No |
|
||||
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
|
||||
|
@ -28,7 +28,7 @@ A fillet.
|
||||
| `id` |`string`| The id of the engine command that called this fillet. | No |
|
||||
| `radius` |`number`| | No |
|
||||
| `edgeId` |`string`| The engine id of the edge to fillet. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -48,7 +48,7 @@ A chamfer.
|
||||
| `id` |`string`| The id of the engine command that called this chamfer. | No |
|
||||
| `length` |`number`| | No |
|
||||
| `edgeId` |`string`| The engine id of the edge to chamfer. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -15,8 +15,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `then_val` |[`UnboxedNode_for_Program`](/docs/kcl/types/UnboxedNode_for_Program)| | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -23,10 +23,12 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `kind` |[`Literal`](/docs/kcl/types/Literal)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -42,9 +44,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -60,9 +63,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `kind` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -77,10 +81,13 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`BinaryExpression`](/docs/kcl/types/BinaryExpression)| | No |
|
||||
| `kind` |[`BinaryExpression`](/docs/kcl/types/BinaryExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `BinaryExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`BinaryOperator`](/docs/kcl/types/BinaryOperator)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `left` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `right` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -96,9 +103,11 @@ An expression can be evaluated to yield a single KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`FunctionExpression`](/docs/kcl/types/FunctionExpression)| | No |
|
||||
| `kind` |[`FunctionExpression`](/docs/kcl/types/FunctionExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `params` |`[` [`Parameter`](/docs/kcl/types/Parameter) `]`| | No |
|
||||
| `body` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -113,10 +122,13 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`CallExpression`](/docs/kcl/types/CallExpression)| | No |
|
||||
| `kind` |[`CallExpression`](/docs/kcl/types/CallExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `CallExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `callee` |[`Identifier`](/docs/kcl/types/Identifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `arguments` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `optional` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -131,10 +143,12 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`PipeExpression`](/docs/kcl/types/PipeExpression)| | No |
|
||||
| `kind` |[`PipeExpression`](/docs/kcl/types/PipeExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `PipeExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `body` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -149,10 +163,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`PipeSubstitution`](/docs/kcl/types/PipeSubstitution)| | No |
|
||||
| `kind` |[`PipeSubstitution`](/docs/kcl/types/PipeSubstitution)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `PipeSubstitution`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -167,10 +181,12 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`ArrayExpression`](/docs/kcl/types/ArrayExpression)| | No |
|
||||
| `kind` |[`ArrayExpression`](/docs/kcl/types/ArrayExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `ArrayExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `elements` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -185,10 +201,12 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`ArrayRangeExpression`](/docs/kcl/types/ArrayRangeExpression)| | No |
|
||||
| `kind` |[`ArrayRangeExpression`](/docs/kcl/types/ArrayRangeExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `ObjectExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `properties` |`[` [`ObjectProperty`](/docs/kcl/types/ObjectProperty) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -203,10 +221,13 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`ObjectExpression`](/docs/kcl/types/ObjectExpression)| | No |
|
||||
| `kind` |[`ObjectExpression`](/docs/kcl/types/ObjectExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -221,10 +242,12 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `kind` |[`MemberExpression`](/docs/kcl/types/MemberExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `UnaryExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`UnaryOperator`](/docs/kcl/types/UnaryOperator)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `argument` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -239,28 +262,14 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`UnaryExpression`](/docs/kcl/types/UnaryExpression)| | No |
|
||||
| `kind` |[`UnaryExpression`](/docs/kcl/types/UnaryExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`IfExpression`](/docs/kcl/types/IfExpression)| | No |
|
||||
| `kind` |[`IfExpression`](/docs/kcl/types/IfExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `type` |enum: `IfExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `else_ifs` |`[` [`ElseIf`](/docs/kcl/types/ElseIf) `]`| | No |
|
||||
| `final_else` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -26,7 +26,7 @@ An extrude plane.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `extrudePlane`| | No |
|
||||
| `faceId` |`string`| The face id for the extrude plane. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
@ -46,7 +46,7 @@ An extruded arc.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `extrudeArc`| | No |
|
||||
| `faceId` |`string`| The face id for the extrude plane. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
@ -66,7 +66,7 @@ Geometry metadata.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `chamfer`| | No |
|
||||
| `faceId` |`string`| The id for the chamfer surface. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
@ -86,7 +86,7 @@ Geometry metadata.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `fillet`| | No |
|
||||
| `faceId` |`string`| The id for the fillet surface. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
|
@ -15,8 +15,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `params` |`[` [`Parameter`](/docs/kcl/types/Parameter) `]`| | No |
|
||||
| `body` |[`UnboxedNode_for_Program`](/docs/kcl/types/UnboxedNode_for_Program)| | No |
|
||||
| `body` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -15,6 +15,8 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
title: "ImportItem"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `name` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| Name of the item to import. | No |
|
||||
| `alias` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| Rename the item using an identifier after "as". | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
title: "ItemVisibility"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**enum:** `default`, `export`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "KclValue"
|
||||
excerpt: "Any KCL value."
|
||||
excerpt: "A memory item."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Any KCL value.
|
||||
A memory item.
|
||||
|
||||
|
||||
|
||||
@ -59,9 +59,10 @@ Any KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `kind` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| Any KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -79,7 +80,7 @@ A plane.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Plane`| | No |
|
||||
| `id` |`string`| The id of the plane. | No |
|
||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Any KCL value. | No |
|
||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A memory item. | No |
|
||||
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
||||
@ -182,8 +183,8 @@ Data for an imported geometry.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Function`| | No |
|
||||
| `expression` |[`UnboxedNode_for_FunctionExpression`](/docs/kcl/types/UnboxedNode_for_FunctionExpression)| Any KCL value. | No |
|
||||
| `memory` |[`ProgramMemory`](/docs/kcl/types/ProgramMemory)| Any KCL value. | No |
|
||||
| `expression` |[`FunctionExpression`](/docs/kcl/types/FunctionExpression)| A memory item. | No |
|
||||
| `memory` |[`ProgramMemory`](/docs/kcl/types/ProgramMemory)| A memory item. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ Data for a linear pattern on a 2D sketch.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||
| `repetitions` |[`Uint`](/docs/kcl/types/Uint)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No |
|
||||
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
|
||||
| `axis` |`[number, number]`| The axis of the pattern. This is a 2D vector. | No |
|
||||
|
||||
|
@ -16,7 +16,7 @@ Data for a linear pattern on a 3D model.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||
| `repetitions` |[`Uint`](/docs/kcl/types/Uint)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No |
|
||||
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
|
||||
| `axis` |`[number, number, number]`| The axis of the pattern. | No |
|
||||
|
||||
|
@ -23,9 +23,10 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -40,10 +41,12 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `kind` |[`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -22,10 +22,13 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `kind` |[`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -41,9 +44,10 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -16,7 +16,7 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `nonCodeNodes` |`object`| | No |
|
||||
| `start` |`[` [`UnboxedNode_for_NonCodeNode`](/docs/kcl/types/UnboxedNode_for_NonCodeNode) `]`| | No |
|
||||
| `start` |`[` [`NonCodeNode`](/docs/kcl/types/NonCodeNode) `]`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -15,6 +15,8 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`NonCodeValue`](/docs/kcl/types/NonCodeValue)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -15,7 +15,9 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `key` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `key` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `value` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -16,7 +16,7 @@ Parameter of a KCL function.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `identifier` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| The parameter's label or name. | No |
|
||||
| `identifier` |[`Identifier`](/docs/kcl/types/Identifier)| The parameter's label or name. | No |
|
||||
| `optional` |`boolean`| Is the parameter optional? | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -27,7 +27,7 @@ A path that goes to a point.
|
||||
| `type` |enum: `ToPoint`| | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ A arc that is tangential to the last path segment that goes to a point
|
||||
| `ccw` |`boolean`| arc's direction | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ A arc that is tangential to the last path segment
|
||||
| `ccw` |`boolean`| arc's direction | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ a complete arc
|
||||
| `ccw` |`boolean`| arc's direction | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ A path that is horizontal.
|
||||
| `x` |`number`| The x coordinate. | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -137,7 +137,7 @@ An angled line to.
|
||||
| `y` |`number`| The y coordinate. | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -157,7 +157,7 @@ A base path.
|
||||
| `type` |enum: `Base`| | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -16,8 +16,10 @@ A KCL program top level, or function body.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `body` |`[` [`BodyItem`](/docs/kcl/types/BodyItem) `]`| | No |
|
||||
| `nonCodeMeta` |[`UnboxedNode_for_NonCodeMeta`](/docs/kcl/types/UnboxedNode_for_NonCodeMeta)| A KCL program top level, or function body. | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| A KCL program top level, or function body. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line relative to the current origin to a specified distance away
|
||||
from the current position along the 'x' axis.
|
||||
|
||||
```js
|
||||
xLine(length: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ xLine(length: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `length` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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)
|
||||
|
||||
```js
|
||||
xLineTo(to: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ xLineTo(to: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line relative to the current origin to a specified distance away
|
||||
from the current position along the 'y' axis.
|
||||
|
||||
```js
|
||||
yLine(length: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ yLine(length: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `length` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ 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)
|
||||
|
||||
```js
|
||||
yLineTo(to: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ yLineTo(to: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -313,45 +313,3 @@ test(
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'external change of file contents are reflected in editor',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const PROJECT_DIR_NAME = 'lee-was-here'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDir,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
||||
await fsp.mkdir(aProjectDir, { recursive: true })
|
||||
},
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await test.step('Open the project', async () => {
|
||||
await expect(page.getByText(PROJECT_DIR_NAME)).toBeVisible()
|
||||
await page.getByText(PROJECT_DIR_NAME).click()
|
||||
await u.waitForPageLoad()
|
||||
})
|
||||
|
||||
await u.openFilePanel()
|
||||
await u.openKclCodePanel()
|
||||
|
||||
await test.step('Write to file externally and check for changed content', async () => {
|
||||
const content = 'ha he ho ho ha blap scap be dap'
|
||||
await fsp.writeFile(
|
||||
join(projectsDir, PROJECT_DIR_NAME, 'main.kcl'),
|
||||
content
|
||||
)
|
||||
await u.editorTextMatches(content)
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
@ -1,80 +0,0 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
function countNewlines(input: string): number {
|
||||
let count = 0
|
||||
for (const char of input) {
|
||||
if (char === '\n') {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
test.describe('Debug pane', () => {
|
||||
test('Artifact IDs in the artifact graph are stable across code edits', async ({
|
||||
page,
|
||||
context,
|
||||
}) => {
|
||||
const code = `sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([1, 1], %)
|
||||
`
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
const tree = page.getByTestId('debug-feature-tree')
|
||||
const segment = tree.locator('li', {
|
||||
hasText: 'segIds:',
|
||||
hasNotText: 'paths:',
|
||||
})
|
||||
|
||||
await test.step('Test setup', async () => {
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openKclCodePanel()
|
||||
await u.openDebugPanel()
|
||||
// Set the code in the code editor.
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(code, { delay: 0 })
|
||||
// Scroll to the feature tree.
|
||||
await tree.scrollIntoViewIfNeeded()
|
||||
// Expand the feature tree.
|
||||
await tree.getByText('Feature Tree').click()
|
||||
// Just expanded the details, making the element taller, so scroll again.
|
||||
await tree.getByText('Plane').first().scrollIntoViewIfNeeded()
|
||||
})
|
||||
// Extract the artifact IDs from the debug feature tree.
|
||||
const initialSegmentIds = await segment.innerText({ timeout: 5_000 })
|
||||
// The artifact ID should include a UUID.
|
||||
expect(initialSegmentIds).toMatch(
|
||||
/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
|
||||
)
|
||||
await test.step('Move cursor to the bottom of the code editor', async () => {
|
||||
// Focus on the code editor.
|
||||
await u.codeLocator.click()
|
||||
// Make sure the cursor is at the end of the code.
|
||||
const lines = countNewlines(code) + 1
|
||||
for (let i = 0; i < lines; i++) {
|
||||
await page.keyboard.press('ArrowDown')
|
||||
}
|
||||
})
|
||||
await test.step('Enter a comment', async () => {
|
||||
await page.keyboard.type('|> line([2, 2], %)', { delay: 0 })
|
||||
// Wait for keyboard input debounce and updated artifact graph.
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
const newSegmentIds = await segment.innerText()
|
||||
// Strip off the closing bracket.
|
||||
const initialIds = initialSegmentIds.slice(0, initialSegmentIds.length - 1)
|
||||
expect(newSegmentIds.slice(0, initialIds.length)).toEqual(initialIds)
|
||||
})
|
||||
})
|
@ -104,7 +104,7 @@ test(
|
||||
},
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBeGreaterThan(300_000)
|
||||
.toBe(431341)
|
||||
|
||||
// clean up output.gltf
|
||||
await fsp.rm('output.gltf')
|
||||
@ -179,7 +179,7 @@ test(
|
||||
},
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBeGreaterThan(100_000)
|
||||
.toBe(102040)
|
||||
|
||||
// clean up output.gltf
|
||||
await fsp.rm('output.gltf')
|
||||
|
@ -1,16 +1,6 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import fsp from 'fs/promises'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import {
|
||||
darkModeBgColor,
|
||||
darkModePlaneColorXZ,
|
||||
executorInputPath,
|
||||
getUtils,
|
||||
setup,
|
||||
setupElectron,
|
||||
tearDown,
|
||||
} from './test-utils'
|
||||
import { join } from 'path'
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
@ -984,84 +974,4 @@ test.describe('Editor tests', () => {
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
})
|
||||
|
||||
test(
|
||||
`Can use the import stdlib function on a local OBJ file`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const bracketDir = join(dir, 'cube')
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cube.obj'),
|
||||
join(bracketDir, 'cube.obj')
|
||||
)
|
||||
await fsp.writeFile(join(bracketDir, 'main.kcl'), '')
|
||||
},
|
||||
})
|
||||
const viewportSize = { width: 1200, height: 500 }
|
||||
await page.setViewportSize(viewportSize)
|
||||
|
||||
// Locators and constants
|
||||
const u = await getUtils(page)
|
||||
const projectLink = page.getByRole('link', { name: 'cube' })
|
||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||
const locationToHavColor = async (
|
||||
position: { x: number; y: number },
|
||||
color: [number, number, number]
|
||||
) => {
|
||||
return u.getGreatestPixDiff(position, color)
|
||||
}
|
||||
const notTheOrigin = {
|
||||
x: viewportSize.width * 0.55,
|
||||
y: viewportSize.height * 0.3,
|
||||
}
|
||||
const origin = { x: viewportSize.width / 2, y: viewportSize.height / 2 }
|
||||
const errorIndicators = page.locator('.cm-lint-marker-error')
|
||||
|
||||
await test.step(`Open the empty file, see the default planes`, async () => {
|
||||
await projectLink.click()
|
||||
await u.waitForPageLoad()
|
||||
await expect
|
||||
.poll(
|
||||
async () => locationToHavColor(notTheOrigin, darkModePlaneColorXZ),
|
||||
{
|
||||
timeout: 5000,
|
||||
message: 'XZ plane color is visible',
|
||||
}
|
||||
)
|
||||
.toBeLessThan(15)
|
||||
})
|
||||
await test.step(`Write the import function line`, async () => {
|
||||
await u.codeLocator.fill(`import('cube.obj')`)
|
||||
await page.waitForTimeout(800)
|
||||
})
|
||||
await test.step(`Reset the camera before checking`, async () => {
|
||||
await u.doAndWaitForCmd(async () => {
|
||||
await gizmo.click({ button: 'right' })
|
||||
await resetCameraButton.click()
|
||||
}, 'zoom_to_fit')
|
||||
})
|
||||
await test.step(`Verify that we see the imported geometry and no errors`, async () => {
|
||||
await expect(errorIndicators).toHaveCount(0)
|
||||
await expect
|
||||
.poll(async () => locationToHavColor(origin, darkModePlaneColorXZ), {
|
||||
timeout: 3000,
|
||||
message: 'Plane color should not be visible',
|
||||
})
|
||||
.toBeGreaterThan(15)
|
||||
await expect
|
||||
.poll(async () => locationToHavColor(origin, darkModeBgColor), {
|
||||
timeout: 3000,
|
||||
message: 'Background color should not be visible',
|
||||
})
|
||||
.toBeGreaterThan(15)
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -960,171 +960,4 @@ _test.describe('Deleting items from the file pane', () => {
|
||||
'TODO - delete folder we are in, with no main.kcl',
|
||||
async () => {}
|
||||
)
|
||||
|
||||
// Copied from tests above.
|
||||
_test(
|
||||
`external deletion of project navigates back home`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const TEST_PROJECT_NAME = 'Test Project'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME), { recursive: true })
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME, 'folderToDelete'), {
|
||||
recursive: true,
|
||||
})
|
||||
await fsp.copyFile(
|
||||
executorInputPath('basic_fillet_cube_end.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'main.kcl')
|
||||
)
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cylinder.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'folderToDelete', 'someFileWithin.kcl')
|
||||
)
|
||||
},
|
||||
})
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Constants and locators
|
||||
const projectCard = page.getByText(TEST_PROJECT_NAME)
|
||||
const projectMenuButton = page.getByTestId('project-sidebar-toggle')
|
||||
const folderToDelete = page.getByRole('button', {
|
||||
name: 'folderToDelete',
|
||||
})
|
||||
const fileWithinFolder = page.getByRole('listitem').filter({
|
||||
has: page.getByRole('button', { name: 'someFileWithin.kcl' }),
|
||||
})
|
||||
|
||||
await _test.step(
|
||||
'Open project and navigate into folderToDelete',
|
||||
async () => {
|
||||
await projectCard.click()
|
||||
await u.waitForPageLoad()
|
||||
await _expect(projectMenuButton).toContainText('main.kcl')
|
||||
await u.closeKclCodePanel()
|
||||
await u.openFilePanel()
|
||||
|
||||
await folderToDelete.click()
|
||||
await _expect(fileWithinFolder).toBeVisible()
|
||||
await fileWithinFolder.click()
|
||||
await _expect(projectMenuButton).toContainText('someFileWithin.kcl')
|
||||
}
|
||||
)
|
||||
|
||||
// Point of divergence. Delete the project folder and see if it goes back
|
||||
// to the home view.
|
||||
await _test.step(
|
||||
'Delete projectsDirName/<project-name> externally',
|
||||
async () => {
|
||||
await fsp.rm(join(projectsDirName, TEST_PROJECT_NAME), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
await _test.step('Check the app is back on the home view', async () => {
|
||||
const projectsDirLink = page.getByText('Loaded from')
|
||||
await _expect(projectsDirLink).toBeVisible()
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
// Similar to the above
|
||||
_test(
|
||||
`external deletion of file in sub-directory updates the file tree and recreates it on code editor typing`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const TEST_PROJECT_NAME = 'Test Project'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME), { recursive: true })
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME, 'folderToDelete'), {
|
||||
recursive: true,
|
||||
})
|
||||
await fsp.copyFile(
|
||||
executorInputPath('basic_fillet_cube_end.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'main.kcl')
|
||||
)
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cylinder.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'folderToDelete', 'someFileWithin.kcl')
|
||||
)
|
||||
},
|
||||
})
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Constants and locators
|
||||
const projectCard = page.getByText(TEST_PROJECT_NAME)
|
||||
const projectMenuButton = page.getByTestId('project-sidebar-toggle')
|
||||
const folderToDelete = page.getByRole('button', {
|
||||
name: 'folderToDelete',
|
||||
})
|
||||
const fileWithinFolder = page.getByRole('listitem').filter({
|
||||
has: page.getByRole('button', { name: 'someFileWithin.kcl' }),
|
||||
})
|
||||
|
||||
await _test.step(
|
||||
'Open project and navigate into folderToDelete',
|
||||
async () => {
|
||||
await projectCard.click()
|
||||
await u.waitForPageLoad()
|
||||
await _expect(projectMenuButton).toContainText('main.kcl')
|
||||
|
||||
await u.openFilePanel()
|
||||
|
||||
await folderToDelete.click()
|
||||
await _expect(fileWithinFolder).toBeVisible()
|
||||
await fileWithinFolder.click()
|
||||
await _expect(projectMenuButton).toContainText('someFileWithin.kcl')
|
||||
}
|
||||
)
|
||||
|
||||
await _test.step(
|
||||
'Delete projectsDirName/<project-name> externally',
|
||||
async () => {
|
||||
await fsp.rm(
|
||||
join(
|
||||
projectsDirName,
|
||||
TEST_PROJECT_NAME,
|
||||
'folderToDelete',
|
||||
'someFileWithin.kcl'
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
await _test.step('Check the file is gone in the file tree', async () => {
|
||||
await _expect(
|
||||
page.getByTestId('file-pane-scroll-container')
|
||||
).not.toContainText('someFileWithin.kcl')
|
||||
})
|
||||
|
||||
await _test.step(
|
||||
'Check the file is back in the file tree after typing in code editor',
|
||||
async () => {
|
||||
await u.pasteCodeInEditor('hello = 1')
|
||||
await _expect(
|
||||
page.getByTestId('file-pane-scroll-container')
|
||||
).toContainText('someFileWithin.kcl')
|
||||
}
|
||||
)
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -13,13 +13,6 @@ type mouseParams = {
|
||||
pixelDiff: number
|
||||
}
|
||||
|
||||
type SceneSerialised = {
|
||||
camera: {
|
||||
position: [number, number, number]
|
||||
target: [number, number, number]
|
||||
}
|
||||
}
|
||||
|
||||
export class SceneFixture {
|
||||
public page: Page
|
||||
|
||||
@ -29,22 +22,6 @@ export class SceneFixture {
|
||||
this.page = page
|
||||
this.reConstruct(page)
|
||||
}
|
||||
private _serialiseScene = async (): Promise<SceneSerialised> => {
|
||||
const camera = await this.getCameraInfo()
|
||||
|
||||
return {
|
||||
camera,
|
||||
}
|
||||
}
|
||||
|
||||
expectState = async (expected: SceneSerialised) => {
|
||||
return expect
|
||||
.poll(() => this._serialiseScene(), {
|
||||
message: `Expected scene state to match`,
|
||||
})
|
||||
.toEqual(expected)
|
||||
}
|
||||
|
||||
reConstruct = (page: Page) => {
|
||||
this.page = page
|
||||
|
||||
@ -54,7 +31,7 @@ export class SceneFixture {
|
||||
makeMouseHelpers = (
|
||||
x: number,
|
||||
y: number,
|
||||
{ steps }: { steps: number } = { steps: 20 }
|
||||
{ steps }: { steps: number } = { steps: 5000 }
|
||||
) =>
|
||||
[
|
||||
(clickParams?: mouseParams) => {
|
||||
@ -110,36 +87,6 @@ export class SceneFixture {
|
||||
)
|
||||
await closeDebugPanel(this.page)
|
||||
}
|
||||
/** Forces a refresh of the camera position and target displayed
|
||||
* in the debug panel and then returns the values of the fields
|
||||
*/
|
||||
async getCameraInfo() {
|
||||
await openAndClearDebugPanel(this.page)
|
||||
await sendCustomCmd(this.page, {
|
||||
type: 'modeling_cmd_req',
|
||||
cmd_id: uuidv4(),
|
||||
cmd: {
|
||||
type: 'default_camera_get_settings',
|
||||
},
|
||||
})
|
||||
await this.waitForExecutionDone()
|
||||
const position = await Promise.all([
|
||||
this.page.getByTestId('cam-x-position').inputValue().then(Number),
|
||||
this.page.getByTestId('cam-y-position').inputValue().then(Number),
|
||||
this.page.getByTestId('cam-z-position').inputValue().then(Number),
|
||||
])
|
||||
const target = await Promise.all([
|
||||
this.page.getByTestId('cam-x-target').inputValue().then(Number),
|
||||
this.page.getByTestId('cam-y-target').inputValue().then(Number),
|
||||
this.page.getByTestId('cam-z-target').inputValue().then(Number),
|
||||
])
|
||||
await closeDebugPanel(this.page)
|
||||
return {
|
||||
position,
|
||||
target,
|
||||
}
|
||||
}
|
||||
|
||||
waitForExecutionDone = async () => {
|
||||
await expect(this.exeIndicator).toBeVisible()
|
||||
}
|
||||
@ -167,17 +114,4 @@ export class SceneFixture {
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
get gizmo() {
|
||||
return this.page.locator('[aria-label*=gizmo]')
|
||||
}
|
||||
|
||||
async clickGizmoMenuItem(name: string) {
|
||||
await this.gizmo.click({ button: 'right' })
|
||||
const buttonToTest = this.page.getByRole('button', {
|
||||
name: name,
|
||||
})
|
||||
await expect(buttonToTest).toBeVisible()
|
||||
await buttonToTest.click()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test, expect, Page } from '@playwright/test'
|
||||
import {
|
||||
doExport,
|
||||
executorInputPath,
|
||||
@ -255,7 +255,7 @@ test.describe('Can export from electron app', () => {
|
||||
},
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBeGreaterThan(300_000)
|
||||
.toBe(431341)
|
||||
|
||||
// clean up output.gltf
|
||||
await fsp.rm('output.gltf')
|
||||
@ -618,30 +618,31 @@ test(
|
||||
'Deleting projects, can delete individual project, can still create projects after deleting all',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const projectData = [
|
||||
['router-template-slate', 'cylinder.kcl'],
|
||||
['bracket', 'focusrite_scarlett_mounting_braket.kcl'],
|
||||
['lego', 'lego.kcl'],
|
||||
]
|
||||
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
// Do these serially to ensure the order is correct
|
||||
for (const [name, file] of projectData) {
|
||||
await fsp.mkdir(join(dir, name), { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath(file),
|
||||
join(dir, name, `main.kcl`)
|
||||
)
|
||||
// Wait 1s between each project to ensure the order is correct
|
||||
await new Promise((r) => setTimeout(r, 1_000))
|
||||
}
|
||||
},
|
||||
})
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
page.on('console', console.log)
|
||||
|
||||
const createProjectAndRenameItTest = async ({
|
||||
name,
|
||||
page,
|
||||
}: {
|
||||
name: string
|
||||
page: Page
|
||||
}) => {
|
||||
await test.step(`Create and rename project ${name}`, async () => {
|
||||
await createProjectAndRenameIt({ name, page })
|
||||
})
|
||||
}
|
||||
|
||||
// we need to create the folders so that the order is correct
|
||||
// creating them ahead of time with fs tools means they all have the same timestamp
|
||||
await createProjectAndRenameItTest({ name: 'router-template-slate', page })
|
||||
await createProjectAndRenameItTest({ name: 'bracket', page })
|
||||
await createProjectAndRenameItTest({ name: 'lego', page })
|
||||
|
||||
await test.step('delete the middle project, i.e. the bracket project', async () => {
|
||||
const project = page.getByText('bracket')
|
||||
|
||||
@ -743,26 +744,8 @@ test(
|
||||
'Can sort projects on home page',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const projectData = [
|
||||
['router-template-slate', 'cylinder.kcl'],
|
||||
['bracket', 'focusrite_scarlett_mounting_braket.kcl'],
|
||||
['lego', 'lego.kcl'],
|
||||
]
|
||||
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
// Do these serially to ensure the order is correct
|
||||
for (const [name, file] of projectData) {
|
||||
await fsp.mkdir(join(dir, name), { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath(file),
|
||||
join(dir, name, `main.kcl`)
|
||||
)
|
||||
// Wait 1s between each project to ensure the order is correct
|
||||
await new Promise((r) => setTimeout(r, 1_000))
|
||||
}
|
||||
},
|
||||
})
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
@ -770,6 +753,24 @@ test(
|
||||
|
||||
page.on('console', console.log)
|
||||
|
||||
const createProjectAndRenameItTest = async ({
|
||||
name,
|
||||
page,
|
||||
}: {
|
||||
name: string
|
||||
page: Page
|
||||
}) => {
|
||||
await test.step(`Create and rename project ${name}`, async () => {
|
||||
await createProjectAndRenameIt({ name, page })
|
||||
})
|
||||
}
|
||||
|
||||
// we need to create the folders so that the order is correct
|
||||
// creating them ahead of time with fs tools means they all have the same timestamp
|
||||
await createProjectAndRenameItTest({ name: 'router-template-slate', page })
|
||||
await createProjectAndRenameItTest({ name: 'bracket', page })
|
||||
await createProjectAndRenameItTest({ name: 'lego', page })
|
||||
|
||||
await test.step('should be shorted by modified initially', async () => {
|
||||
const lastModifiedButton = page.getByRole('button', {
|
||||
name: 'Last Modified',
|
||||
@ -851,7 +852,7 @@ test(
|
||||
}
|
||||
)
|
||||
|
||||
test.fixme(
|
||||
test(
|
||||
'When the project folder is empty, user can create new project and open it.',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
@ -861,12 +862,6 @@ test.fixme(
|
||||
|
||||
page.on('console', console.log)
|
||||
|
||||
// Locators and constants
|
||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||
const pointOnModel = { x: 660, y: 250 }
|
||||
const expectedStartCamZPosition = 15633.47
|
||||
|
||||
// expect to see text "No Projects found"
|
||||
await expect(page.getByText('No Projects found')).toBeVisible()
|
||||
|
||||
@ -879,7 +874,16 @@ test.fixme(
|
||||
|
||||
await page.getByText('project-000').click()
|
||||
|
||||
await u.waitForPageLoad()
|
||||
await expect(page.getByTestId('loading')).toBeAttached()
|
||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
||||
timeout: 20_000,
|
||||
})
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeEnabled({
|
||||
timeout: 20_000,
|
||||
})
|
||||
|
||||
await page.locator('.cm-content').fill(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([-87.4, 282.92], %)
|
||||
@ -889,28 +893,8 @@ test.fixme(
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
extrude001 = extrude(200, sketch001)`)
|
||||
await page.waitForTimeout(800)
|
||||
|
||||
async function getCameraZValue() {
|
||||
return page
|
||||
.getByTestId('cam-z-position')
|
||||
.inputValue()
|
||||
.then((value) => parseFloat(value))
|
||||
}
|
||||
|
||||
await test.step(`Reset camera`, async () => {
|
||||
await u.openDebugPanel()
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForCmd(async () => {
|
||||
await gizmo.click({ button: 'right' })
|
||||
await resetCameraButton.click()
|
||||
}, 'zoom_to_fit')
|
||||
await expect
|
||||
.poll(getCameraZValue, {
|
||||
message: 'Camera Z should be at expected position after reset',
|
||||
})
|
||||
.toEqual(expectedStartCamZPosition)
|
||||
})
|
||||
const pointOnModel = { x: 660, y: 250 }
|
||||
|
||||
// gray at this pixel means the stream has loaded in the most
|
||||
// user way we can verify it (pixel color)
|
||||
@ -918,7 +902,7 @@ extrude001 = extrude(200, sketch001)`)
|
||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [143, 143, 143]), {
|
||||
timeout: 10_000,
|
||||
})
|
||||
.toBeLessThan(30)
|
||||
.toBeLessThan(15)
|
||||
|
||||
await expect(async () => {
|
||||
await page.mouse.move(0, 0, { steps: 5 })
|
||||
|
@ -471,7 +471,7 @@ test(
|
||||
|
||||
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
||||
|
||||
await page.waitForTimeout(1000)
|
||||
await page.waitForTimeout(300)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
@ -521,6 +521,7 @@ test(
|
||||
const startXPx = 600
|
||||
|
||||
// Equip the rectangle tool
|
||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||
await page
|
||||
.getByRole('button', { name: 'rectangle Corner rectangle', exact: true })
|
||||
.click()
|
||||
@ -528,7 +529,6 @@ test(
|
||||
// Draw the rectangle
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
||||
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 })
|
||||
await page.waitForTimeout(800)
|
||||
|
||||
// Ensure the draft rectangle looks the same as it usually does
|
||||
await expect(page).toHaveScreenshot({
|
||||
@ -670,7 +670,6 @@ test.describe(
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask: [page.getByTestId('model-state-indicator')],
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
@ -688,7 +687,6 @@ test.describe(
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask: [page.getByTestId('model-state-indicator')],
|
||||
})
|
||||
})
|
||||
|
||||
@ -896,7 +894,7 @@ test(
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(2000)
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
@ -940,7 +938,7 @@ test(
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(2000)
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
@ -47,14 +47,6 @@ export const commonPoints = {
|
||||
num2: 14.44,
|
||||
}
|
||||
|
||||
/** A semi-reliable color to check the default XZ plane on
|
||||
* in dark mode in the default camera position
|
||||
*/
|
||||
export const darkModePlaneColorXZ: [number, number, number] = [50, 50, 99]
|
||||
|
||||
/** A semi-reliable color to check the default dark mode bg color against */
|
||||
export const darkModeBgColor: [number, number, number] = [27, 27, 27]
|
||||
|
||||
export const editorSelector = '[role="textbox"][data-language="kcl"]'
|
||||
type PaneId = 'variables' | 'code' | 'files' | 'logs'
|
||||
|
||||
@ -471,9 +463,6 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
return test_?.step(
|
||||
`Create and select project with text "${hasText}"`,
|
||||
async () => {
|
||||
// Without this, we get unreliable project creation. It's probably
|
||||
// due to a race between the FS being read and clicking doing something.
|
||||
await page.waitForTimeout(100)
|
||||
await page.getByTestId('home-new-file').click()
|
||||
const projectLinksPost = page.getByTestId('project-link')
|
||||
await projectLinksPost.filter({ hasText }).click()
|
||||
@ -503,11 +492,6 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
|
||||
createNewFile: async (name: string) => {
|
||||
return test?.step(`Create a file named ${name}`, async () => {
|
||||
// If the application is in the middle of connecting a stream
|
||||
// then creating a new file won't work in the end.
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await page.getByTestId('create-file-button').click()
|
||||
await page.getByTestId('file-rename-field').fill(name)
|
||||
await page.keyboard.press('Enter')
|
||||
@ -890,8 +874,8 @@ export async function setupElectron({
|
||||
appSettings
|
||||
? { settings: appSettings }
|
||||
: {
|
||||
...TEST_SETTINGS,
|
||||
settings: {
|
||||
...TEST_SETTINGS,
|
||||
app: {
|
||||
...TEST_SETTINGS.app,
|
||||
projectDirectory: projectDirName,
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { _test, _expect } from './playwright-deprecated'
|
||||
import { test } from './fixtures/fixtureSetup'
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { TEST_CODE_GIZMO } from './storageStates'
|
||||
|
||||
_test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
_test.afterEach(async ({ page }, testInfo) => {
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
_test.describe('Testing Gizmo', () => {
|
||||
test.describe('Testing Gizmo', () => {
|
||||
const cases = [
|
||||
{
|
||||
testDescription: 'top view',
|
||||
@ -57,7 +57,7 @@ _test.describe('Testing Gizmo', () => {
|
||||
expectedCameraTarget,
|
||||
testDescription,
|
||||
} of cases) {
|
||||
_test(`check ${testDescription}`, async ({ page, browserName }) => {
|
||||
test(`check ${testDescription}`, async ({ page, browserName }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript((TEST_CODE_GIZMO) => {
|
||||
localStorage.setItem('persistCode', TEST_CODE_GIZMO)
|
||||
@ -117,30 +117,30 @@ _test.describe('Testing Gizmo', () => {
|
||||
|
||||
await Promise.all([
|
||||
// position
|
||||
_expect(page.getByTestId('cam-x-position')).toHaveValue(
|
||||
expect(page.getByTestId('cam-x-position')).toHaveValue(
|
||||
expectedCameraPosition.x.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-y-position')).toHaveValue(
|
||||
expect(page.getByTestId('cam-y-position')).toHaveValue(
|
||||
expectedCameraPosition.y.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-z-position')).toHaveValue(
|
||||
expect(page.getByTestId('cam-z-position')).toHaveValue(
|
||||
expectedCameraPosition.z.toString()
|
||||
),
|
||||
// target
|
||||
_expect(page.getByTestId('cam-x-target')).toHaveValue(
|
||||
expect(page.getByTestId('cam-x-target')).toHaveValue(
|
||||
expectedCameraTarget.x.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-y-target')).toHaveValue(
|
||||
expect(page.getByTestId('cam-y-target')).toHaveValue(
|
||||
expectedCameraTarget.y.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-z-target')).toHaveValue(
|
||||
expect(page.getByTestId('cam-z-target')).toHaveValue(
|
||||
expectedCameraTarget.z.toString()
|
||||
),
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
_test('Context menu and popover menu', async ({ page }) => {
|
||||
test('Context menu and popover menu', async ({ page }) => {
|
||||
const testCase = {
|
||||
testDescription: 'Right view',
|
||||
expectedCameraPosition: { x: 5660.02, y: -152, z: 26 },
|
||||
@ -196,7 +196,7 @@ _test.describe('Testing Gizmo', () => {
|
||||
const buttonToTest = page.getByRole('button', {
|
||||
name: testCase.testDescription,
|
||||
})
|
||||
await _expect(buttonToTest).toBeVisible()
|
||||
await expect(buttonToTest).toBeVisible()
|
||||
await buttonToTest.click()
|
||||
|
||||
// Now assert we've moved to the correct view
|
||||
@ -215,23 +215,23 @@ _test.describe('Testing Gizmo', () => {
|
||||
|
||||
await Promise.all([
|
||||
// position
|
||||
_expect(page.getByTestId('cam-x-position')).toHaveValue(
|
||||
expect(page.getByTestId('cam-x-position')).toHaveValue(
|
||||
testCase.expectedCameraPosition.x.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-y-position')).toHaveValue(
|
||||
expect(page.getByTestId('cam-y-position')).toHaveValue(
|
||||
testCase.expectedCameraPosition.y.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-z-position')).toHaveValue(
|
||||
expect(page.getByTestId('cam-z-position')).toHaveValue(
|
||||
testCase.expectedCameraPosition.z.toString()
|
||||
),
|
||||
// target
|
||||
_expect(page.getByTestId('cam-x-target')).toHaveValue(
|
||||
expect(page.getByTestId('cam-x-target')).toHaveValue(
|
||||
testCase.expectedCameraTarget.x.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-y-target')).toHaveValue(
|
||||
expect(page.getByTestId('cam-y-target')).toHaveValue(
|
||||
testCase.expectedCameraTarget.y.toString()
|
||||
),
|
||||
_expect(page.getByTestId('cam-z-target')).toHaveValue(
|
||||
expect(page.getByTestId('cam-z-target')).toHaveValue(
|
||||
testCase.expectedCameraTarget.z.toString()
|
||||
),
|
||||
])
|
||||
@ -242,60 +242,8 @@ _test.describe('Testing Gizmo', () => {
|
||||
const gizmoPopoverButton = page.getByRole('button', {
|
||||
name: 'view settings',
|
||||
})
|
||||
await _expect(gizmoPopoverButton).toBeVisible()
|
||||
await expect(gizmoPopoverButton).toBeVisible()
|
||||
await gizmoPopoverButton.click()
|
||||
await _expect(buttonToTest).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe(`Testing gizmo, fixture-based`, () => {
|
||||
test('Center on selection from menu', async ({
|
||||
app,
|
||||
cmdBar,
|
||||
editor,
|
||||
toolbar,
|
||||
scene,
|
||||
}) => {
|
||||
test.skip(
|
||||
process.platform === 'win32',
|
||||
'Fails on windows in CI, can not be replicated locally on windows.'
|
||||
)
|
||||
|
||||
await test.step(`Setup`, async () => {
|
||||
const file = await app.getInputFile('test-circle-extrude.kcl')
|
||||
await app.initialise(file)
|
||||
await scene.expectState({
|
||||
camera: {
|
||||
position: [4982.21, -23865.37, 13810.64],
|
||||
target: [4982.21, 0, 2737.1],
|
||||
},
|
||||
})
|
||||
})
|
||||
const [clickCircle, moveToCircle] = scene.makeMouseHelpers(582, 217)
|
||||
|
||||
await test.step(`Select an edge of this circle`, async () => {
|
||||
const circleSnippet =
|
||||
'circle({ center: [318.33, 168.1], radius: 182.8 }, %)'
|
||||
await moveToCircle()
|
||||
await clickCircle()
|
||||
await editor.expectState({
|
||||
activeLines: [circleSnippet.slice(-5)],
|
||||
highlightedCode: circleSnippet,
|
||||
diagnostics: [],
|
||||
})
|
||||
})
|
||||
|
||||
await test.step(`Center on selection from menu`, async () => {
|
||||
await scene.clickGizmoMenuItem('Center view on selection')
|
||||
})
|
||||
|
||||
await test.step(`Verify the camera moved`, async () => {
|
||||
await scene.expectState({
|
||||
camera: {
|
||||
position: [0, -23865.37, 11073.54],
|
||||
target: [0, 0, 0],
|
||||
},
|
||||
})
|
||||
})
|
||||
await expect(buttonToTest).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
@ -1208,12 +1208,6 @@ extrude001 = extrude(50, sketch001)
|
||||
test('Deselecting line tool should mean nothing happens on click', async ({
|
||||
page,
|
||||
}) => {
|
||||
/**
|
||||
* If the line tool is clicked when the state is 'No Points' it will exit Sketch mode.
|
||||
* This is the same exact workflow as pressing ESC.
|
||||
*
|
||||
* To continue to test this workflow, we now enter sketch mode and place a single point before exiting the line tool.
|
||||
*/
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
@ -1234,7 +1228,6 @@ extrude001 = extrude(50, sketch001)
|
||||
200
|
||||
)
|
||||
|
||||
// Clicks the XZ Plane in the page
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
@ -1243,11 +1236,6 @@ extrude001 = extrude(50, sketch001)
|
||||
|
||||
await page.waitForTimeout(600)
|
||||
|
||||
// Place a point because the line tool will exit if no points are pressed
|
||||
await page.mouse.click(650, 200)
|
||||
await page.waitForTimeout(600)
|
||||
|
||||
// Code before exiting the tool
|
||||
let previousCodeContent = await page.locator('.cm-content').innerText()
|
||||
|
||||
// deselect the line tool by clicking it
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
executorInputPath,
|
||||
} from './test-utils'
|
||||
import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes'
|
||||
import { SETTINGS_FILE_NAME, PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
|
||||
import {
|
||||
TEST_SETTINGS_KEY,
|
||||
TEST_SETTINGS_CORRUPTED,
|
||||
@ -344,7 +343,7 @@ test.describe('Testing settings', () => {
|
||||
|
||||
// Selectors and constants
|
||||
const errorHeading = page.getByRole('heading', {
|
||||
name: 'An unexpected error occurred',
|
||||
name: 'An unextected error occurred',
|
||||
})
|
||||
const projectDirLink = page.getByText('Loaded from')
|
||||
|
||||
@ -373,7 +372,7 @@ test.describe('Testing settings', () => {
|
||||
|
||||
// Selectors and constants
|
||||
const errorHeading = page.getByRole('heading', {
|
||||
name: 'An unexpected error occurred',
|
||||
name: 'An unextected error occurred',
|
||||
})
|
||||
const projectDirLink = page.getByText('Loaded from')
|
||||
|
||||
@ -385,118 +384,6 @@ test.describe('Testing settings', () => {
|
||||
}
|
||||
)
|
||||
|
||||
// It was much easier to test the logo color than the background stream color.
|
||||
test(
|
||||
'user settings reload on external change, on project and modeling view',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
appSettings: {
|
||||
app: {
|
||||
// Doesn't matter what you set it to. It will
|
||||
// default to 264.5
|
||||
themeColor: '0',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
const logoLink = page.getByTestId('app-logo')
|
||||
const projectDirLink = page.getByText('Loaded from')
|
||||
|
||||
await test.step('Wait for project view', async () => {
|
||||
await expect(projectDirLink).toBeVisible()
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '264.5')
|
||||
})
|
||||
|
||||
const changeColor = async (color: string) => {
|
||||
const tempSettingsFilePath = join(projectDirName, SETTINGS_FILE_NAME)
|
||||
let tomlStr = await fsp.readFile(tempSettingsFilePath, 'utf-8')
|
||||
tomlStr = tomlStr.replace(/(themeColor = ")[0-9]+(")/, `$1${color}$2`)
|
||||
await fsp.writeFile(tempSettingsFilePath, tomlStr)
|
||||
}
|
||||
|
||||
await test.step('Check color of logo changed', async () => {
|
||||
await changeColor('99')
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '99')
|
||||
})
|
||||
|
||||
await test.step('Check color of logo changed when in modeling view', async () => {
|
||||
await page.getByRole('button', { name: 'New project' }).click()
|
||||
await page.getByTestId('project-link').first().click()
|
||||
await page.getByRole('button', { name: 'Dismiss' }).click()
|
||||
await changeColor('58')
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '58')
|
||||
})
|
||||
|
||||
await test.step('Check going back to projects view still changes the color', async () => {
|
||||
await logoLink.click()
|
||||
await expect(projectDirLink).toBeVisible()
|
||||
await changeColor('21')
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '21')
|
||||
})
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'project settings reload on external change',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
const logoLink = page.getByTestId('app-logo')
|
||||
const projectDirLink = page.getByText('Loaded from')
|
||||
|
||||
await test.step('Wait for project view', async () => {
|
||||
await expect(projectDirLink).toBeVisible()
|
||||
})
|
||||
|
||||
const projectLinks = page.getByTestId('project-link')
|
||||
const oldCount = await projectLinks.count()
|
||||
await page.getByRole('button', { name: 'New project' }).click()
|
||||
await expect(projectLinks).toHaveCount(oldCount + 1)
|
||||
await projectLinks.filter({ hasText: 'project-000' }).first().click()
|
||||
|
||||
const changeColorFs = async (color: string) => {
|
||||
const tempSettingsFilePath = join(
|
||||
projectDirName,
|
||||
'project-000',
|
||||
PROJECT_SETTINGS_FILE_NAME
|
||||
)
|
||||
await fsp.writeFile(
|
||||
tempSettingsFilePath,
|
||||
`[settings.app]\nthemeColor = "${color}"`
|
||||
)
|
||||
}
|
||||
|
||||
await test.step('Check the color is first starting as we expect', async () => {
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '264.5')
|
||||
})
|
||||
|
||||
await test.step('Check color of logo changed', async () => {
|
||||
await changeColorFs('99')
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '99')
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
`Closing settings modal should go back to the original file being viewed`,
|
||||
{ tag: '@electron' },
|
||||
|
@ -32,10 +32,10 @@ win:
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
# - target: msi
|
||||
# arch:
|
||||
# - x64
|
||||
# - arm64
|
||||
- target: msi
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
signingHashAlgorithms:
|
||||
- sha256
|
||||
sign: "./sign-win.js"
|
||||
@ -47,9 +47,9 @@ win:
|
||||
mimeType: text/vnd.zoo.kcl
|
||||
description: Zoo KCL File
|
||||
role: Editor
|
||||
# msi:
|
||||
# oneClick: false
|
||||
# perMachine: true
|
||||
msi:
|
||||
oneClick: false
|
||||
perMachine: true
|
||||
nsis:
|
||||
oneClick: false
|
||||
perMachine: true
|
||||
@ -73,5 +73,3 @@ publish:
|
||||
- provider: generic
|
||||
url: https://dl.zoo.dev/releases/modeling-app
|
||||
channel: latest
|
||||
releaseInfo:
|
||||
releaseNotesFile: release-notes.md
|
||||
|
14
interface.d.ts
vendored
@ -20,11 +20,11 @@ export interface IElectronAPI {
|
||||
version: typeof process.env.version
|
||||
watchFileOn: (
|
||||
path: string,
|
||||
key: string,
|
||||
callback: (eventType: string, path: string) => void
|
||||
) => void
|
||||
readFile: typeof fs.readFile
|
||||
watchFileOff: (path: string, key: string) => void
|
||||
watchFileOff: (path: string) => void
|
||||
watchFileObliterate: () => void
|
||||
readFile: (path: string) => ReturnType<fs.readFile>
|
||||
writeFile: (
|
||||
path: string,
|
||||
data: string | Uint8Array
|
||||
@ -68,15 +68,11 @@ export interface IElectronAPI {
|
||||
}
|
||||
}
|
||||
kittycad: (access: string, args: any) => any
|
||||
listMachines: (machineApiIp: string) => Promise<MachinesListing>
|
||||
listMachines: () => Promise<MachinesListing>
|
||||
getMachineApiIp: () => Promise<string | null>
|
||||
onUpdateDownloadStart: (
|
||||
callback: (value: { version: string }) => void
|
||||
) => Electron.IpcRenderer
|
||||
onUpdateDownloaded: (
|
||||
callback: (value: { version: string; releaseNotes: string }) => void
|
||||
callback: (value: string) => void
|
||||
) => Electron.IpcRenderer
|
||||
onUpdateError: (callback: (value: { error: Error }) => void) => Electron
|
||||
appRestart: () => void
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ echo ""
|
||||
echo "Suggested changelog:"
|
||||
echo "\`\`\`"
|
||||
echo "## What's Changed"
|
||||
git log $(git describe --tags --match="v[0-9]*" --abbrev=0)..HEAD --oneline --pretty=format:%s | grep -v Bump | grep -v 'Cut release v' | awk '{print "* "toupper(substr($0,0,1))substr($0,2)}'
|
||||
git log $(git describe --tags --abbrev=0)..HEAD --oneline --pretty=format:%s | grep -v Bump | grep -v 'Cut release v' | awk '{print "* "toupper(substr($0,0,1))substr($0,2)}'
|
||||
echo ""
|
||||
echo "**Full Changelog**: https://github.com/KittyCAD/modeling-app/compare/${latest_tag}...${new_version}"
|
||||
echo "\`\`\`"
|
||||
|
@ -36,297 +36,38 @@
|
||||
"description": "Extra machine-specific information regarding a connected machine.",
|
||||
"oneOf": [
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"moonraker"
|
||||
],
|
||||
"type": "string"
|
||||
"Moonraker": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
"Moonraker"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"usb"
|
||||
],
|
||||
"type": "string"
|
||||
"Usb": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
"Usb"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"current_stage": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Stage"
|
||||
}
|
||||
],
|
||||
"description": "The current stage of the machine as defined by Bambu which can include errors, etc.",
|
||||
"nullable": true
|
||||
},
|
||||
"nozzle_diameter": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/NozzleDiameter"
|
||||
}
|
||||
],
|
||||
"description": "The nozzle diameter of the machine."
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"bambu"
|
||||
],
|
||||
"type": "string"
|
||||
"Bambu": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"nozzle_diameter",
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FdmHardwareConfiguration": {
|
||||
"description": "Configuration for a FDM-based printer.",
|
||||
"properties": {
|
||||
"filaments": {
|
||||
"description": "The filaments the printer has access to.",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Filament"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nozzle_diameter": {
|
||||
"description": "Diameter of the extrusion nozzle, in mm.",
|
||||
"format": "double",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"filaments",
|
||||
"nozzle_diameter"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Filament": {
|
||||
"description": "Information about the filament being used in a FDM printer.",
|
||||
"properties": {
|
||||
"color": {
|
||||
"description": "The color (as hex without the `#`) of the filament, this is likely specific to the manufacturer.",
|
||||
"maxLength": 6,
|
||||
"minLength": 6,
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"material": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/FilamentMaterial"
|
||||
}
|
||||
],
|
||||
"description": "The material that the filament is made of."
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of the filament, this is likely specfic to the manufacturer.",
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"material"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FilamentMaterial": {
|
||||
"description": "The material that the filament is made of.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Polylactic acid based plastics",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"pla"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Pla support",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"pla_support"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "acrylonitrile butadiene styrene based plastics",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"abs"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "polyethylene terephthalate glycol based plastics",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"petg"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "unsuprisingly, nylon based",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"nylon"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "thermoplastic polyurethane based urethane material",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"tpu"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "polyvinyl alcohol based material",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"pva"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "high impact polystyrene based material",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"hips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "composite material with stuff in other stuff, something like PLA mixed with carbon fiber, kevlar, or fiberglass",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"composite"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"HardwareConfiguration": {
|
||||
"description": "The hardware configuration of a machine.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "No configuration is possible. This isn't the same conceptually as an `Option<HardwareConfiguration>`, because this indicates we positively know there is no possible configuration changes that are possible with this method of manufcture.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Hardware configuration specific to FDM based printers",
|
||||
"properties": {
|
||||
"config": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/FdmHardwareConfiguration"
|
||||
}
|
||||
],
|
||||
"description": "The configuration for the FDM printer."
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"fdm"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"config",
|
||||
"type"
|
||||
"Bambu"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
@ -344,14 +85,6 @@
|
||||
"description": "Additional, per-machine information which is specific to the underlying machine type.",
|
||||
"nullable": true
|
||||
},
|
||||
"hardware_configuration": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/HardwareConfiguration"
|
||||
}
|
||||
],
|
||||
"description": "Information about how the Machine is currently configured."
|
||||
},
|
||||
"id": {
|
||||
"description": "Machine Identifier (ID) for the specific Machine.",
|
||||
"type": "string"
|
||||
@ -381,12 +114,6 @@
|
||||
"description": "Maximum part size that can be manufactured by this device. This may be some sort of theoretical upper bound, getting close to this limit seems like maybe a bad idea.\n\nThis may be `None` if the maximum size is not knowable by the Machine API.\n\nWhat \"close\" means is up to you!",
|
||||
"nullable": true
|
||||
},
|
||||
"progress": {
|
||||
"description": "Progress of the current print, if printing.",
|
||||
"format": "double",
|
||||
"nullable": true,
|
||||
"type": "number"
|
||||
},
|
||||
"state": {
|
||||
"allOf": [
|
||||
{
|
||||
@ -397,7 +124,6 @@
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hardware_configuration",
|
||||
"id",
|
||||
"machine_type",
|
||||
"make_model",
|
||||
@ -431,111 +157,57 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "If a print state can not be resolved at this time, an Unknown may be returned.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"enum": [
|
||||
"Unknown"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Idle, and ready for another job.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"idle"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"enum": [
|
||||
"Idle"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Running a job -- 3D printing or CNC-ing a part.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"running"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"enum": [
|
||||
"Running"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Machine is currently offline or unreachable.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"offline"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"enum": [
|
||||
"Offline"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Job is underway but halted, waiting for some action to take place.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"paused"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"enum": [
|
||||
"Paused"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Job is finished, but waiting manual action to move back to Idle.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"complete"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"enum": [
|
||||
"Complete"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"description": "The printer has failed and is in an unknown state that may require manual attention to resolve. The inner value is a human readable description of what specifically has failed.",
|
||||
"properties": {
|
||||
"message": {
|
||||
"description": "A human-readable message describing the failure.",
|
||||
"Failed": {
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"enum": [
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
"Failed"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
@ -547,54 +219,21 @@
|
||||
{
|
||||
"description": "Use light to cure a resin to build up layers.",
|
||||
"enum": [
|
||||
"stereolithography"
|
||||
"Stereolithography"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Fused Deposition Modeling, layers of melted plastic.",
|
||||
"enum": [
|
||||
"fused_deposition"
|
||||
"FusedDeposition"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "\"Computer numerical control\" - machine that grinds away material from a hunk of material to construct a part.",
|
||||
"enum": [
|
||||
"cnc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"NozzleDiameter": {
|
||||
"description": "A nozzle diameter.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "0.2mm.",
|
||||
"enum": [
|
||||
"0.2"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "0.4mm.",
|
||||
"enum": [
|
||||
"0.4"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "0.6mm.",
|
||||
"enum": [
|
||||
"0.6"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "0.8mm.",
|
||||
"enum": [
|
||||
"0.8"
|
||||
"Cnc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
@ -645,15 +284,6 @@
|
||||
"machine_id": {
|
||||
"description": "The machine id to print to.",
|
||||
"type": "string"
|
||||
},
|
||||
"slicer_configuration": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SlicerConfiguration"
|
||||
}
|
||||
],
|
||||
"description": "Requested design-specific slicer configurations.",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@ -662,283 +292,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SlicerConfiguration": {
|
||||
"description": "The slicer configuration is a set of parameters that are passed to the slicer to control how the gcode is generated.",
|
||||
"properties": {
|
||||
"filament_idx": {
|
||||
"description": "The filament to use for the print.",
|
||||
"format": "uint",
|
||||
"minimum": 0,
|
||||
"nullable": true,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"Stage": {
|
||||
"description": "The print stage. These come from: https://github.com/SoftFever/OrcaSlicer/blob/431978baf17961df90f0d01871b0ad1d839d7f5d/src/slic3r/GUI/DeviceManager.cpp#L78",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Nothing.",
|
||||
"enum": [
|
||||
"nothing"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Empty.",
|
||||
"enum": [
|
||||
"empty"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Auto bed leveling.",
|
||||
"enum": [
|
||||
"auto_bed_leveling"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Heatbed preheating.",
|
||||
"enum": [
|
||||
"heatbed_preheating"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Sweeping XY mech mode.",
|
||||
"enum": [
|
||||
"sweeping_xy_mech_mode"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Changing filament.",
|
||||
"enum": [
|
||||
"changing_filament"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "M400 pause.",
|
||||
"enum": [
|
||||
"m400_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to filament runout.",
|
||||
"enum": [
|
||||
"paused_due_to_filament_runout"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Heating hotend.",
|
||||
"enum": [
|
||||
"heating_hotend"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating extrusion.",
|
||||
"enum": [
|
||||
"calibrating_extrusion"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Scanning bed surface.",
|
||||
"enum": [
|
||||
"scanning_bed_surface"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Inspecting first layer.",
|
||||
"enum": [
|
||||
"inspecting_first_layer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Identifying build plate type.",
|
||||
"enum": [
|
||||
"identifying_build_plate_type"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating micro lidar.",
|
||||
"enum": [
|
||||
"calibrating_micro_lidar"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Homing toolhead.",
|
||||
"enum": [
|
||||
"homing_toolhead"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Cleaning nozzle tip.",
|
||||
"enum": [
|
||||
"cleaning_nozzle_tip"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Checking extruder temperature.",
|
||||
"enum": [
|
||||
"checking_extruder_temperature"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Printing was paused by the user.",
|
||||
"enum": [
|
||||
"printing_was_paused_by_the_user"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Pause of front cover falling.",
|
||||
"enum": [
|
||||
"pause_of_front_cover_falling"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating micro lidar.",
|
||||
"enum": [
|
||||
"calibrating_micro_lidar2"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating extrusion flow.",
|
||||
"enum": [
|
||||
"calibrating_extrusion_flow"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to nozzle temperature malfunction.",
|
||||
"enum": [
|
||||
"paused_due_to_nozzle_temperature_malfunction"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to heat bed temperature malfunction.",
|
||||
"enum": [
|
||||
"paused_due_to_heat_bed_temperature_malfunction"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Filament unloading.",
|
||||
"enum": [
|
||||
"filament_unloading"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Skip step pause.",
|
||||
"enum": [
|
||||
"skip_step_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Filament loading.",
|
||||
"enum": [
|
||||
"filament_loading"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Motor noise calibration.",
|
||||
"enum": [
|
||||
"motor_noise_calibration"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to AMS lost.",
|
||||
"enum": [
|
||||
"paused_due_to_ams_lost"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to low speed of the heat break fan.",
|
||||
"enum": [
|
||||
"paused_due_to_low_speed_of_the_heat_break_fan"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to chamber temperature control error.",
|
||||
"enum": [
|
||||
"paused_due_to_chamber_temperature_control_error"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Cooling chamber.",
|
||||
"enum": [
|
||||
"cooling_chamber"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused by the Gcode inserted by the user.",
|
||||
"enum": [
|
||||
"paused_by_the_gcode_inserted_by_the_user"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Motor noise showoff.",
|
||||
"enum": [
|
||||
"motor_noise_showoff"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Nozzle filament covered detected pause.",
|
||||
"enum": [
|
||||
"nozzle_filament_covered_detected_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Cutter error pause.",
|
||||
"enum": [
|
||||
"cutter_error_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "First layer error pause.",
|
||||
"enum": [
|
||||
"first_layer_error_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Nozzle clog pause.",
|
||||
"enum": [
|
||||
"nozzle_clog_pause"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Volume": {
|
||||
"description": "Set of three values to represent the extent of a 3-D Volume. This contains the width, depth, and height values, generally used to represent some maximum or minimum.\n\nAll measurements are in millimeters.",
|
||||
"properties": {
|
||||
@ -1072,34 +425,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/metrics": {
|
||||
"get": {
|
||||
"operationId": "get_metrics",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"title": "String",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "successful operation"
|
||||
},
|
||||
"4XX": {
|
||||
"$ref": "#/components/responses/Error"
|
||||
},
|
||||
"5XX": {
|
||||
"$ref": "#/components/responses/Error"
|
||||
}
|
||||
},
|
||||
"summary": "List available machines and their statuses",
|
||||
"tags": [
|
||||
"hidden"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/ping": {
|
||||
"get": {
|
||||
"operationId": "ping",
|
||||
@ -1167,13 +492,6 @@
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"description": "Hidden API endpoints that should not show up in the docs.",
|
||||
"externalDocs": {
|
||||
"url": "https://docs.zoo.dev/api/machines"
|
||||
},
|
||||
"name": "hidden"
|
||||
},
|
||||
{
|
||||
"description": "Utilities for making parts and discovering machines.",
|
||||
"externalDocs": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zoo-modeling-app",
|
||||
"version": "0.26.0",
|
||||
"version": "0.25.5",
|
||||
"private": true,
|
||||
"productName": "Zoo Modeling App",
|
||||
"author": {
|
||||
@ -26,7 +26,7 @@
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@headlessui/react": "^1.7.19",
|
||||
"@headlessui/tailwindcss": "^0.2.0",
|
||||
"@kittycad/lib": "2.0.7",
|
||||
"@kittycad/lib": "^2.0.1",
|
||||
"@lezer/highlight": "^1.2.1",
|
||||
"@lezer/lr": "^1.4.1",
|
||||
"@react-hook/resize-observer": "^2.0.1",
|
||||
@ -36,7 +36,6 @@
|
||||
"@xstate/inspect": "^0.8.0",
|
||||
"@xstate/react": "^4.1.1",
|
||||
"bonjour-service": "^1.2.1",
|
||||
"chokidar": "^4.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"decamelize": "^6.0.0",
|
||||
"electron-squirrel-startup": "^1.0.1",
|
||||
|
@ -893,7 +893,6 @@ export class CameraControls {
|
||||
type: 'zoom_to_fit',
|
||||
object_ids: [], // leave empty to zoom to all objects
|
||||
padding: 0.2, // padding around the objects
|
||||
animated: false, // don't animate the zoom for now
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ import {
|
||||
import { ActionButton } from 'components/ActionButton'
|
||||
import { err, reportRejection, trap } from 'lib/trap'
|
||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
|
||||
const [isCamMoving, setIsCamMoving] = useState(false)
|
||||
@ -202,7 +201,7 @@ const Overlay = ({
|
||||
let xAlignment = overlay.angle < 0 ? '0%' : '-100%'
|
||||
let yAlignment = overlay.angle < -90 || overlay.angle >= 90 ? '0%' : '-100%'
|
||||
|
||||
const _node1 = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
const _node1 = getNodeFromPath<CallExpression>(
|
||||
kclManager.ast,
|
||||
overlay.pathToNode,
|
||||
'CallExpression'
|
||||
@ -382,7 +381,7 @@ export async function deleteSegment({
|
||||
pathToNode: PathToNode
|
||||
sketchDetails: SketchDetails | null
|
||||
}) {
|
||||
let modifiedAst: UnboxedNode<Program> | Error = kclManager.ast
|
||||
let modifiedAst: Program | Error = kclManager.ast
|
||||
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
||||
|
||||
const shouldContinueSegDelete = dependentRanges.length
|
||||
@ -409,7 +408,6 @@ export async function deleteSegment({
|
||||
|
||||
const testExecute = await executeAst({
|
||||
ast: modifiedAst,
|
||||
idGenerator: kclManager.execState.idGenerator,
|
||||
useFakeExecutor: true,
|
||||
engineCommandManager: engineCommandManager,
|
||||
})
|
||||
|
@ -92,7 +92,6 @@ import { err, reportRejection, trap } from 'lib/trap'
|
||||
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
||||
import { Point3d } from 'wasm-lib/kcl/bindings/Point3d'
|
||||
import { SegmentInputs } from 'lang/std/stdTypes'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
type DraftSegment = 'line' | 'tangentialArcTo'
|
||||
|
||||
@ -370,14 +369,14 @@ export class SceneEntities {
|
||||
selectionRanges,
|
||||
}: {
|
||||
sketchPathToNode: PathToNode
|
||||
maybeModdedAst: UnboxedNode<Program>
|
||||
maybeModdedAst: Program
|
||||
draftExpressionsIndices?: { start: number; end: number }
|
||||
forward: [number, number, number]
|
||||
up: [number, number, number]
|
||||
position?: [number, number, number]
|
||||
selectionRanges?: Selections
|
||||
}): Promise<{
|
||||
truncatedAst: UnboxedNode<Program>
|
||||
truncatedAst: Program
|
||||
programMemoryOverride: ProgramMemory
|
||||
sketch: Sketch
|
||||
variableDeclarationName: string
|
||||
@ -392,14 +391,12 @@ export class SceneEntities {
|
||||
const { truncatedAst, programMemoryOverride, variableDeclarationName } =
|
||||
prepared
|
||||
|
||||
const { execState } = await executeAst({
|
||||
const { programMemory } = await executeAst({
|
||||
ast: truncatedAst,
|
||||
useFakeExecutor: true,
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
programMemoryOverride,
|
||||
idGenerator: kclManager.execState.idGenerator,
|
||||
})
|
||||
const programMemory = execState.memory
|
||||
const sketch = sketchFromPathToNode({
|
||||
pathToNode: sketchPathToNode,
|
||||
ast: maybeModdedAst,
|
||||
@ -562,7 +559,7 @@ export class SceneEntities {
|
||||
}
|
||||
updateAstAndRejigSketch = async (
|
||||
sketchPathToNode: PathToNode,
|
||||
modifiedAst: UnboxedNode<Program> | Error,
|
||||
modifiedAst: Program | Error,
|
||||
forward: [number, number, number],
|
||||
up: [number, number, number],
|
||||
origin: [number, number, number]
|
||||
@ -804,14 +801,12 @@ export class SceneEntities {
|
||||
updateRectangleSketch(sketchInit, x, y, tags[0])
|
||||
}
|
||||
|
||||
const { execState } = await executeAst({
|
||||
const { programMemory } = await executeAst({
|
||||
ast: truncatedAst,
|
||||
useFakeExecutor: true,
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
programMemoryOverride,
|
||||
idGenerator: kclManager.execState.idGenerator,
|
||||
})
|
||||
const programMemory = execState.memory
|
||||
this.sceneProgramMemory = programMemory
|
||||
const sketch = sketchFromKclValue(
|
||||
programMemory.get(variableDeclarationName),
|
||||
@ -853,14 +848,12 @@ export class SceneEntities {
|
||||
await kclManager.executeAstMock(_ast)
|
||||
sceneInfra.modelingSend({ type: 'Finish rectangle' })
|
||||
|
||||
const { execState } = await executeAst({
|
||||
const { programMemory } = await executeAst({
|
||||
ast: _ast,
|
||||
useFakeExecutor: true,
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
programMemoryOverride,
|
||||
idGenerator: kclManager.execState.idGenerator,
|
||||
})
|
||||
const programMemory = execState.memory
|
||||
|
||||
// Prepare to update the THREEjs scene
|
||||
this.sceneProgramMemory = programMemory
|
||||
@ -972,14 +965,12 @@ export class SceneEntities {
|
||||
modded = moddedResult.modifiedAst
|
||||
}
|
||||
|
||||
const { execState } = await executeAst({
|
||||
const { programMemory } = await executeAst({
|
||||
ast: modded,
|
||||
useFakeExecutor: true,
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
programMemoryOverride,
|
||||
idGenerator: kclManager.execState.idGenerator,
|
||||
})
|
||||
const programMemory = execState.memory
|
||||
this.sceneProgramMemory = programMemory
|
||||
const sketch = sketchFromKclValue(
|
||||
programMemory.get(variableDeclarationName),
|
||||
@ -1178,7 +1169,7 @@ export class SceneEntities {
|
||||
}
|
||||
prepareTruncatedMemoryAndAst = (
|
||||
sketchPathToNode: PathToNode,
|
||||
ast?: UnboxedNode<Program>,
|
||||
ast?: Program,
|
||||
draftSegment?: DraftSegment
|
||||
) =>
|
||||
prepareTruncatedMemoryAndAst(
|
||||
@ -1199,7 +1190,7 @@ export class SceneEntities {
|
||||
sketchPathToNode: PathToNode
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
draftInfo?: {
|
||||
truncatedAst: UnboxedNode<Program>
|
||||
truncatedAst: Program
|
||||
programMemoryOverride: ProgramMemory
|
||||
variableDeclarationName: string
|
||||
}
|
||||
@ -1235,7 +1226,7 @@ export class SceneEntities {
|
||||
const dragTo: [number, number] = [intersection2d.x, intersection2d.y]
|
||||
let modifiedAst = draftInfo ? draftInfo.truncatedAst : { ...kclManager.ast }
|
||||
|
||||
const _node = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
const _node = getNodeFromPath<CallExpression>(
|
||||
modifiedAst,
|
||||
pathToNode,
|
||||
'CallExpression'
|
||||
@ -1247,7 +1238,7 @@ export class SceneEntities {
|
||||
|
||||
let modded:
|
||||
| {
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
modifiedAst: Program
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
| Error
|
||||
@ -1326,14 +1317,12 @@ export class SceneEntities {
|
||||
// don't want to mod the user's code yet as they have't committed to the change yet
|
||||
// plus this would be the truncated ast being recast, it would be wrong
|
||||
codeManager.updateCodeEditor(code)
|
||||
const { execState } = await executeAst({
|
||||
const { programMemory } = await executeAst({
|
||||
ast: truncatedAst,
|
||||
useFakeExecutor: true,
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
programMemoryOverride,
|
||||
idGenerator: kclManager.execState.idGenerator,
|
||||
})
|
||||
const programMemory = execState.memory
|
||||
this.sceneProgramMemory = programMemory
|
||||
|
||||
const maybeSketch = programMemory.get(variableDeclarationName)
|
||||
@ -1542,7 +1531,7 @@ export class SceneEntities {
|
||||
if (parent?.userData?.pathToNode) {
|
||||
const updatedAst = parse(recast(kclManager.ast))
|
||||
if (trap(updatedAst)) return
|
||||
const _node = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
const _node = getNodeFromPath<CallExpression>(
|
||||
updatedAst,
|
||||
parent.userData.pathToNode,
|
||||
'CallExpression'
|
||||
@ -1677,12 +1666,12 @@ export type DefaultPlaneStr = 'XY' | 'XZ' | 'YZ' | '-XY' | '-XZ' | '-YZ'
|
||||
|
||||
function prepareTruncatedMemoryAndAst(
|
||||
sketchPathToNode: PathToNode,
|
||||
ast: UnboxedNode<Program>,
|
||||
ast: Program,
|
||||
programMemory: ProgramMemory,
|
||||
draftSegment?: DraftSegment
|
||||
):
|
||||
| {
|
||||
truncatedAst: UnboxedNode<Program>
|
||||
truncatedAst: Program
|
||||
programMemoryOverride: ProgramMemory
|
||||
variableDeclarationName: string
|
||||
}
|
||||
@ -1690,7 +1679,7 @@ function prepareTruncatedMemoryAndAst(
|
||||
const bodyIndex = Number(sketchPathToNode?.[1]?.[0]) || 0
|
||||
const _ast = structuredClone(ast)
|
||||
|
||||
const _node = getNodeFromPath<UnboxedNode<VariableDeclaration>>(
|
||||
const _node = getNodeFromPath<VariableDeclaration>(
|
||||
_ast,
|
||||
sketchPathToNode || [],
|
||||
'VariableDeclaration'
|
||||
@ -1740,15 +1729,15 @@ function prepareTruncatedMemoryAndAst(
|
||||
).body.slice(-1)[0].start = lastPipeItem.start
|
||||
|
||||
_ast.end = lastPipeItem.end
|
||||
const varDec = _ast.body[bodyIndex] as UnboxedNode<VariableDeclaration>
|
||||
const varDec = _ast.body[bodyIndex] as VariableDeclaration
|
||||
varDec.end = lastPipeItem.end
|
||||
const declarator = varDec.declarations[0]
|
||||
declarator.end = lastPipeItem.end
|
||||
const init = declarator.init as UnboxedNode<PipeExpression>
|
||||
const init = declarator.init as PipeExpression
|
||||
init.end = lastPipeItem.end
|
||||
init.body.slice(-1)[0].end = lastPipeItem.end
|
||||
}
|
||||
const truncatedAst: UnboxedNode<Program> = {
|
||||
const truncatedAst: Program = {
|
||||
..._ast,
|
||||
body: [structuredClone(_ast.body[bodyIndex])],
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ export function useCalc({
|
||||
engineCommandManager,
|
||||
useFakeExecutor: true,
|
||||
programMemoryOverride: kclManager.programMemory.clone(),
|
||||
}).then(({ execState }) => {
|
||||
}).then(({ programMemory }) => {
|
||||
const resultDeclaration = ast.body.find(
|
||||
(a) =>
|
||||
a.type === 'VariableDeclaration' &&
|
||||
@ -166,7 +166,7 @@ export function useCalc({
|
||||
const init =
|
||||
resultDeclaration?.type === 'VariableDeclaration' &&
|
||||
resultDeclaration?.declarations?.[0]?.init
|
||||
const result = execState.memory?.get('__result__')?.value
|
||||
const result = programMemory?.get('__result__')?.value
|
||||
setCalcResult(typeof result === 'number' ? String(result) : 'NAN')
|
||||
init && setValueNode(init)
|
||||
})
|
||||
|
@ -135,9 +135,7 @@ function CommandArgOptionInput({
|
||||
<Combobox.Input
|
||||
id="option-input"
|
||||
ref={inputRef}
|
||||
onChange={(event) =>
|
||||
!event.target.disabled && setQuery(event.target.value)
|
||||
}
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
className="flex-grow px-2 py-1 border-b border-b-chalkboard-100 dark:border-b-chalkboard-80 !bg-transparent focus:outline-none"
|
||||
onKeyDown={(event) => {
|
||||
if (event.metaKey && event.key === 'k')
|
||||
@ -177,18 +175,9 @@ function CommandArgOptionInput({
|
||||
<Combobox.Option
|
||||
key={option.name}
|
||||
value={option}
|
||||
disabled={option.disabled}
|
||||
className="flex items-center gap-2 px-4 py-1 first:mt-2 last:mb-2 ui-active:bg-primary/10 dark:ui-active:bg-chalkboard-90"
|
||||
>
|
||||
<p
|
||||
className={`flex-grow ${
|
||||
(option.disabled &&
|
||||
'text-chalkboard-70 dark:text-chalkboard-50 cursor-not-allowed') ||
|
||||
''
|
||||
}`}
|
||||
>
|
||||
{option.name}
|
||||
</p>
|
||||
<p className="flex-grow">{option.name} </p>
|
||||
{option.value === currentOption?.value && (
|
||||
<small className="text-chalkboard-70 dark:text-chalkboard-50">
|
||||
current
|
||||
|
@ -91,7 +91,7 @@ function CommandBarSelectionInput({
|
||||
<form id="arg-form" onSubmit={handleSubmit}>
|
||||
<label
|
||||
className={
|
||||
'relative flex flex-col mx-4 my-4 ' +
|
||||
'relative flex items-center mx-4 my-4 ' +
|
||||
(!hasSubmitted || canSubmitSelection || 'text-destroy-50')
|
||||
}
|
||||
>
|
||||
@ -100,18 +100,13 @@ function CommandBarSelectionInput({
|
||||
: `Please select ${
|
||||
arg.multiple ? 'one or more ' : 'one '
|
||||
}${getSemanticSelectionType(arg.selectionTypes).join(' or ')}`}
|
||||
{arg.warningMessage && (
|
||||
<p className="text-warn-80 bg-warn-10 px-2 py-1 rounded-sm mt-3 mr-2 -mb-2 w-full text-sm cursor-default">
|
||||
{arg.warningMessage}
|
||||
</p>
|
||||
)}
|
||||
<input
|
||||
id="selection"
|
||||
name="selection"
|
||||
ref={inputRef}
|
||||
required
|
||||
placeholder="Select an entity with your mouse"
|
||||
className="absolute inset-0 w-full h-full opacity-0 cursor-default"
|
||||
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Backspace') {
|
||||
stepBack()
|
||||
|