Compare commits

...

71 Commits

Author SHA1 Message Date
e1da72a0ae Update common points to reflect empty zoom-to-fit 2024-08-05 17:40:06 +02:00
ec2d1999a7 fmt 2024-08-05 16:31:07 +02:00
95683f1cc1 A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) 2024-08-05 14:17:29 +00:00
f48f1c21c1 A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) 2024-08-05 14:16:05 +00:00
5cdf2de89a Reset camera position when artifact graph is cleared 2024-08-05 16:08:28 +02:00
543e809739 Add "report a bug" mention to user menu onboarding step (#3278)
* Mention "report a bug" in user menu onboarding step

* Add to a test so we match QAWolf a bit more

* Re-run CI
2024-08-05 08:24:19 -04:00
61b669cf4e github actions Playwright shard execution (#3199)
* add @snapshot tag to all snapshot-tests

* set workers to 1 on CI

* try sharding on google chrome only

* add retry when navigating to the app (on CI)

* reduce ubuntu-cores to 2

* revert runner back to 8 cores

* re-add retry + enable macos

* Reduce timeouts to 30 minutes

* ensure retry is triggered

* removed sharding when retrying failures

* added --pass-with-no-tests

* ensure failure occurs

* revert failure

* use smaller sized runners

* revert back to supported runner size

* revert to og version

* minimize changes

* yarn fmt

* ensure failure

* undo failure

---------

Co-authored-by: ryanrosello-og <ry@zoo.dev>
2024-08-05 21:30:16 +10:00
75f1aaa824 camera breaks on extrude zoom to fit (#3276) 2024-08-05 16:08:30 +10:00
f4848d7dea Jump to error not lint (#3271)
* dont jump to lints

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

* updates

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

* fix

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-05 02:44:33 +00:00
a0167f6ba6 Coplanar sketch should have diagnostic error. (#3269)
* artifactMapTweak

* typo
2024-08-05 02:04:53 +00:00
e5a26c42e6 Cut release v0.24.8 (#3263) 2024-08-05 10:32:16 +10:00
9c87b124d9 Jump to error code on badge click (#3262)
* add function to scroll to view

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

* scroll into view on click

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

* add test for jump to code with error

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-04 22:59:04 +00:00
21389c089d apply fillets before a shell (#3261)
* add test for fillet and shell

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

* apply fillets before a shell

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-04 15:37:40 -07:00
29f57be8c1 editor repaints any errors when rendered (#3260)
* editor repaints any errors when rendered

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

* Update src/lang/KclSingleton.ts

* fix test

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

* fix typo

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
2024-08-04 15:16:34 -07:00
cd55f07619 Bump serde_json from 1.0.121 to 1.0.122 in /src/wasm-lib (#3235)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.121 to 1.0.122.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.121...v1.0.122)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-04 12:57:54 -07:00
baf7d3dd9d Add print button (#3133)
* add print button

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

* cleanup

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

* generate more types

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

* add a github action to generate machine api-types

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

* fix

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

* New machine-api types

* actually print on the real machine

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* add more

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

* New machine-api types

* get the current machine

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

* New machine-api types

* know when error

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

* updates

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

* updates

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

* fmt

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

* add fmt

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

* New machine-api types

* empty

* empty

* update machine api

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

* New machine-api types

* empty

* New machine-api types

* emptuy

* no circular deps

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

* New machine-api types

* remove recursive dep

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-04 04:51:30 +00:00
54a9a50969 fix bug when engine returns an error on websocket export (#3256)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-04 02:24:06 +00:00
2830c750fa remove unused timeout (#3254) 2024-08-03 23:10:04 +00:00
d3160cd85a Update machine-api spec (#3253)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-03 16:07:42 -07:00
fd1b4c3a32 fix snapshot tests, don't let them silently fail (#3228)
fix snapshots, don't let them silently fail
2024-08-03 22:29:28 +00:00
b0a41c31ac Update machine-api spec (#3252)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-03 15:25:02 -07:00
5825ba575c test for default planes in empty scene (#3249)
* test for default planes in empty scene

* fmt

* skit if webkit

* fmt
2024-08-03 21:34:56 +10:00
e5bec2140e ArtifactGraph reThink (PART 3) (#3140)
* adjust engine connection to opt out of webRTC connection

* refactor start and test setup

* add env to unit test

* spell config update

* fix beforeAll order bug

* initial integration of new artifact map with tests passing

* remove old artifact map and clean up

* graph artifact map

* have graph commited

* have graph commited

* remove bad file

* install playwright

* fmt

* commit permissions

* typo

* flesh out tests more

* Look at this (photo)Graph *in the voice of Nickelback*

* multi highlight

* redo image logic

* add in solid 2d data into artifactMap

* fix snapshots

* stabiles graph images

* Look at this (photo)Graph *in the voice of Nickelback*

* tweak tests

* rename blend to edgeCut

* Look at this (photo)Graph *in the voice of Nickelback*

* fix playw tests

* start of artifact map rename to graph

* rename file

* rename test

* rename clearup

* comments

* docs

* docs proof read

* few tweaks here and there

* typos

* delete get parent logic

* nit, combine if statements

* remove unused param

* fix silly test bug

* rename surfId to sufaceId

* rename types

* update comments

* add comment

* add extra check

* Look at this (photo)Graph *in the voice of Nickelback*

* pull out merge artifact function

* update comments

* fix test

* fmt

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-03 18:08:51 +10:00
7bf6bc3048 Fix computed properties of KCL objects (#3246)
* Fix computed properties of KCL objects

Fixes https://github.com/KittyCAD/modeling-app/issues/3201

* Incorporate Jon's feedback
2024-08-02 22:24:00 -07:00
22f9df73ed Update machine-api spec (#3247)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-02 21:08:20 -07:00
834472e0a6 Update machine-api spec (#3244)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-02 16:13:49 -07:00
bcdf6e314f Cut release v0.24.7 (#3243) 2024-08-02 18:12:58 -04:00
55e9845ade Update machine-api spec (#3242)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-02 14:10:52 -07:00
d61cf882c1 show default planes on empty scene (#3237)
* show default planes on empty sceen

* fmt

* remove log

* fix silly click listener bug

* delete old stuff

* test tweak

* Revert "test tweak"

This reverts commit e9cb4ac4b5.

---------

Co-authored-by: Paul Tagliamonte <paul@zoo.dev>
2024-08-02 14:05:35 -07:00
874d19cbfd Re-get the openPanes from localStorage when navigating between projects (#3241)
* Re-get the openPanes from localStorage when navigating between projects

* fmt
2024-08-02 15:39:05 -04:00
9dcc955760 Regression fix: restarting onboarding in desktop app required two attempts (#3240)
* Fixed onboarding modal issue, revealed race

* Remove logs

* Make common reset onboarding code path
2024-08-02 15:38:39 -04:00
9b594efe53 Have links clickable within tooltips without clicking content below them (#3204)
* Have links clickable within tooltips without clicking content below them

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Re-run CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Re-run CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-02 12:25:57 -04:00
7b9f40c4cb Fix link to keybindings tab in help menu on Windows (#3236) 2024-08-02 10:25:42 -04:00
81b79da90f fix cryptic error (#3234)
* fix cryptic error

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

* Update types.rs

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-01 19:40:22 -07:00
2ad5a880fa rm error pane show badge on code (#3233)
* rm error pane show badge on code

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

* fix playwirght

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* empty

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-01 19:40:16 -07:00
b57a9ba54c open file with url encoded space (#3231)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-01 17:53:42 -07:00
b32f5c1d4e add html report to playwright artifact (#3229)
add htlm report to playwright artifact
2024-08-01 22:09:40 +00:00
b6d4cc7a4e Update machine-api spec (#3226)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-01 14:49:01 -07:00
43a34b191e Upgrade to clap 4.5.13 to fix build error (#3223) 2024-08-01 17:03:05 +00:00
19a93e8deb Cut release v0.24.6 (#3214) 2024-08-01 09:47:25 -04:00
b8c623e1ec sure up test (#3220) 2024-08-01 12:30:08 +00:00
4006c28479 make test fail fast (#3218) 2024-08-01 11:56:59 +00:00
8c932fdb8d unpause vid in next event loop (#3219)
* unpause vid in next event loop

* fmt
2024-08-01 10:53:44 +00:00
a74c715c01 fix 'Engine disconnect & reconnect in sketch mode' test (#3215)
* fix 'Engine disconnect & reconnect in sketch mode' test

* tweak

* tweak 2
2024-08-01 18:39:24 +10:00
1ac39d95f2 Bug fix: prevent KCL error due to colliding AST execution on project switch (#3205)
* Only run "Execute AST" action if defaultUnit setting changes

* A little more logging and catching anywhere we call video.play()
2024-08-01 05:40:14 +00:00
41b1ec94fa Bump clap from 4.5.11 to 4.5.13 in /src/wasm-lib (#3210)
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.11 to 4.5.13.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.11...v4.5.13)

---
updated-dependencies:
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 22:18:40 -07:00
525c803888 Bump toml from 0.8.17 to 0.8.19 in /src/wasm-lib (#3212)
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.17 to 0.8.19.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.17...toml-v0.8.19)

---
updated-dependencies:
- dependency-name: toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 22:18:29 -07:00
2ee1c78aad Add a system for badges to appear on pane buttons (#3208) 2024-08-01 13:29:24 +10:00
dc21034b86 Move KCL programs into their own files (#3200)
* Move KCL programs into their own files

* Move even more
2024-07-31 15:07:56 -05:00
1684786659 Update machine-api spec (#3202)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-31 11:19:36 -07:00
12505b4398 Bump toml from 0.8.16 to 0.8.17 in /src/wasm-lib (#3198)
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.16 to 0.8.17.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.16...toml-v0.8.17)

---
updated-dependencies:
- dependency-name: toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-31 11:08:07 -07:00
115f2fdea2 Simplify the KCL stdlib test codegen (#3196)
This will ensure that the KCL snapshot tests all use the same logic, whether they're in `tests/executor/main.rs` or in the KCL stdlib modules.
2024-07-31 09:54:46 -05:00
0df28abc4b Update machine-api spec (#3197)
YOYO NEW API SPEC!

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-30 19:57:57 -07:00
1e07ea4986 Use better names for engine/KCL tests (#3193)
'serial_test' isn't actually accurate. Two of these tests run in parallel
now. So I renamed it 'kcl_test' as that's what it's actually doing.

In the nextest config, I changed the label from 'serial-integration' to
'uses-engine' because the former isn't true, and also doesn't explain
_why_ it's being limited. The new name explains why we're limiting the
number of tests that can run in parallel.
2024-07-30 16:12:01 -05:00
f34c23d203 Cut release v0.24.5 (#3191) 2024-07-30 15:28:07 -04:00
5295f0ae7d Fix rectangle tool flakiness (#3190)
* Refactor line tool and rectangle tool to share same "no points" code path

* Remove console.log

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Re-run CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-30 18:16:53 +00:00
07a90b3171 Use kcl_input! macro (#3189)
* Use kcl_input! macro

These two lines are equivalent:
`kcl_input!("foo")`
`include_str!("inputs/foo.kcl")`

Simplifies the tests.

* Move more KCL test programs into their own files

* Move twenty-twenty asserts into their own function

* Move more asserts into 'assert_out'
2024-07-30 11:14:37 -05:00
54936f6932 actually fix lint styles (#3187)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-30 07:27:47 +00:00
6e296af507 initialize codemirror lint styles once (#3185)
* fix diagnostic styles

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

* fixes

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

* Revert "fixes"

This reverts commit e7b2411ebc.

* Revert "fix diagnostic styles"

This reverts commit 625099d9c8.

* actual fix

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-30 04:42:05 +00:00
60c152bf14 fix edge functions when after sketch on face/fn (#3184)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-30 04:30:25 +00:00
59de494125 Bump kittycad from 0.3.8 to 0.3.9 in /src/wasm-lib (#3183)
Bumps [kittycad](https://github.com/KittyCAD/kittycad.rs) from 0.3.8 to 0.3.9.
- [Release notes](https://github.com/KittyCAD/kittycad.rs/releases)
- [Commits](https://github.com/KittyCAD/kittycad.rs/compare/v0.3.8...v0.3.9)

---
updated-dependencies:
- dependency-name: kittycad
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-29 20:49:39 -07:00
1c44b01d16 Fix lazy fillet (#3176)
* WIP: Fix lazy fillet

* cleanup

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-07-30 03:22:52 +00:00
789fb83a5d ensure we clear _before_ we execute when there is a race (#3177)
* updates

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

* comment

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-29 19:55:53 -07:00
63fc287742 bugfix: KCL Test Server should clear scene properly (#3174)
There was already a Reset Scene method which properly cleaned up the
3D modeling scene. I didn't know about it, so I wrote my own. But my own
one didn't call the necessary post-clear hooks, so it didn't recreate
the default planes.

This PR calls the right Reset Scene method, so the default planes get
recreated after the scene is cleared.
2024-07-29 20:40:07 -05:00
5e1b91b0e7 wrap with retry - wait on error in gutter (#3137)
* wrap with retry - wait on error in gutter

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)"

This reverts commit 2ca97f90a2.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
2024-07-30 07:16:52 +10:00
a1c2e817a4 internal linter for making sure everything is camel case (#3172)
* updates

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

* add lint rule for object property key

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

* add linter to example shit

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

* fix samples

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

* fix lints

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

* updates

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

* generate docs

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-29 20:18:55 +00:00
6ed4e72e1d KCL execution server can use a local engine (#3171)
Allow the KCL execution server to choose a local engine, instead of just
the remote engine.

Technically this was already possible, via the $LOCAL_ENGINE_ADDR
environment variable. But it was hard to discover this.
2024-07-29 13:43:27 -05:00
6477011c0f Fix to not crash when there's no var declaration (#3168) 2024-07-29 13:09:12 -04:00
cd9dc3e6a5 Move KCL tests into files (#3169) 2024-07-29 12:05:31 -05:00
4b424de5a6 Add a test for onboarding code reset confirmation and persistence (#3167)
* Add a test for onboarding code reset confirmation and persistence

* Don't use PW's `context` it doesn't have our teardown code
2024-07-29 12:50:01 -04:00
0f1b94f8b9 remove suss linter ext we dont use (#3150)
remove suss linter ext we dont use

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-07-29 15:41:02 +00:00
207 changed files with 10468 additions and 4822 deletions

View File

@ -1,3 +1,3 @@
[codespell] [codespell]
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast,ue ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast,ue,afterall
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,./src-tauri/gen/schemas skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,./src-tauri/gen/schemas

View File

@ -20,6 +20,11 @@ concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
permissions:
contents: write
pull-requests: write
actions: read
jobs: jobs:
check-format: check-format:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
@ -85,7 +90,38 @@ jobs:
- run: yarn simpleserver:ci - run: yarn simpleserver:ci
- run: yarn test:nowatch - name: Install Chromium Browser
run: yarn playwright install chromium --with-deps
- name: run unit tests
run: yarn test:nowatch
env:
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- name: check for changes
id: git-check
run: |
git add src/lang/std/artifactMapGraphs
if git status src/lang/std/artifactMapGraphs | grep -q "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT
fi
- name: Commit changes, if any
if: steps.git-check.outputs.modified == 'true'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin
echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }}
# TODO when webkit works on ubuntu remove the os part of the commit message
git commit -am "Look at this (photo)Graph *in the voice of Nickelback*" || true
git push
git push origin ${{ github.head_ref }}
prepare-json-files: prepare-json-files:

View File

@ -0,0 +1,49 @@
name: generate machine-api types
on:
pull_request:
paths:
- 'openapi/machine-api.json'
- '.github/workflows/generate-machine-api-types.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: write
jobs:
generate:
runs-on: 'ubuntu-latest'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn generate:machine-api
- run: yarn fmt
- name: check for changes
id: git-check
run: |
git add .
if git status | grep -q "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT
fi
- name: Commit changes, if any
if: steps.git-check.outputs.modified == 'true'
run: |
git add .
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin
echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }}
git commit -am "New machine-api types" || true
git push
git push origin ${{ github.head_ref }}

View File

@ -13,7 +13,7 @@ permissions:
contents: write contents: write
pull-requests: write pull-requests: write
actions: read actions: read
jobs: jobs:
@ -34,8 +34,13 @@ jobs:
- 'src/wasm-lib/**' - 'src/wasm-lib/**'
playwright-ubuntu: playwright-ubuntu:
timeout-minutes: 60 timeout-minutes: 30
runs-on: ubuntu-latest-8-cores runs-on: ubuntu-latest-8-cores
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
needs: check-rust-changes needs: check-rust-changes
steps: steps:
- name: Tune GitHub-hosted runner network - name: Tune GitHub-hosted runner network
@ -106,13 +111,19 @@ jobs:
- name: build web - name: build web
run: yarn build:local run: yarn build:local
- name: Run ubuntu/chrome snapshots - name: Run ubuntu/chrome snapshots
continue-on-error: true
run: | run: |
yarn playwright test --project="Google Chrome" --update-snapshots e2e/playwright/snapshot-tests.spec.ts yarn playwright test --project="Google Chrome" --retries="3" --update-snapshots --grep=@snapshot --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
env: env:
CI: true CI: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }} snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-ubuntu-snapshot-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
retention-days: 30
overwrite: true
- name: Clean up test-results - name: Clean up test-results
if: always() if: always()
continue-on-error: true continue-on-error: true
@ -143,7 +154,7 @@ jobs:
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: steps.git-check.outputs.modified == 'true' if: steps.git-check.outputs.modified == 'true'
with: with:
name: playwright-report-ubuntu-${{ github.sha }} name: playwright-report-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/ path: playwright-report/
retention-days: 30 retention-days: 30
# if have previous run results, use them # if have previous run results, use them
@ -151,7 +162,7 @@ jobs:
if: always() if: always()
continue-on-error: true continue-on-error: true
with: with:
name: test-results-ubuntu-${{ github.sha }} name: test-results-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
- name: Run ubuntu/chrome flow (with retries) - name: Run ubuntu/chrome flow (with retries)
id: retry id: retry
@ -160,14 +171,14 @@ jobs:
if [[ ! -f "test-results/.last-run.json" ]]; then if [[ ! -f "test-results/.last-run.json" ]]; then
# if no last run artifact, than run plawright normally # if no last run artifact, than run plawright normally
echo "run playwright normally" echo "run playwright normally"
yarn playwright test --project="Google Chrome" e2e/playwright/flow-tests.spec.ts || true yarn playwright test --project="Google Chrome" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
# # send to axiom # # send to axiom
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1 node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
fi fi
retry=1 retry=1
max_retrys=4 max_retrys=4
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues # retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
while [[ $retry -le $max_retrys ]]; do while [[ $retry -le $max_retrys ]]; do
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
@ -175,7 +186,7 @@ jobs:
if [[ $failed_tests -gt 0 ]]; then if [[ $failed_tests -gt 0 ]]; then
echo "retried=true" >>$GITHUB_OUTPUT echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry" echo "run playwright with last failed tests and retry $retry"
yarn playwright test --project="Google Chrome" --last-failed e2e/playwright/flow-tests.spec.ts || true yarn playwright test --project="Google Chrome" --last-failed --grep-invert=@snapshot || true
# send to axiom # send to axiom
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1 node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
retry=$((retry + 1)) retry=$((retry + 1))
@ -188,9 +199,9 @@ jobs:
exit 0 exit 0
fi fi
done done
echo "retried=false" >>$GITHUB_OUTPUT echo "retried=false" >>$GITHUB_OUTPUT
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then if [[ $failed_tests -gt 0 ]]; then
@ -210,21 +221,26 @@ jobs:
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: test-results-ubuntu-${{ github.sha }} name: test-results-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: playwright-report-ubuntu-${{ github.sha }} name: playwright-report-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/ path: playwright-report/
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
playwright-macos: playwright-macos:
timeout-minutes: 60 timeout-minutes: 30
runs-on: macos-14-large runs-on: macos-14
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
needs: check-rust-changes needs: check-rust-changes
steps: steps:
- name: Tune GitHub-hosted runner network - name: Tune GitHub-hosted runner network
@ -300,7 +316,7 @@ jobs:
if: ${{ always() }} if: ${{ always() }}
continue-on-error: true continue-on-error: true
with: with:
name: test-results-macos-${{ github.sha }} name: test-results-macos-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
- name: Run macos/safari flow (with retries) - name: Run macos/safari flow (with retries)
id: retry id: retry
@ -309,14 +325,14 @@ jobs:
if [[ ! -f "test-results/.last-run.json" ]]; then if [[ ! -f "test-results/.last-run.json" ]]; then
# if no last run artifact, than run plawright normally # if no last run artifact, than run plawright normally
echo "run playwright normally" echo "run playwright normally"
yarn playwright test --project="webkit" e2e/playwright/flow-tests.spec.ts || true yarn playwright test --project="webkit" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
# # send to axiom # # send to axiom
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1 node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
fi fi
retry=1 retry=1
max_retrys=4 max_retrys=4
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues # retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
while [[ $retry -le $max_retrys ]]; do while [[ $retry -le $max_retrys ]]; do
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
@ -324,7 +340,7 @@ jobs:
if [[ $failed_tests -gt 0 ]]; then if [[ $failed_tests -gt 0 ]]; then
echo "retried=true" >>$GITHUB_OUTPUT echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry" echo "run playwright with last failed tests and retry $retry"
yarn playwright test --project="webkit" --last-failed e2e/playwright/flow-tests.spec.ts || true yarn playwright test --project="webkit" --last-failed --grep-invert=@snapshot || true
# send to axiom # send to axiom
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1 node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
retry=$((retry + 1)) retry=$((retry + 1))
@ -337,9 +353,9 @@ jobs:
exit 0 exit 0
fi fi
done done
echo "retried=false" >>$GITHUB_OUTPUT echo "retried=false" >>$GITHUB_OUTPUT
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then if [[ $failed_tests -gt 0 ]]; then
@ -354,15 +370,14 @@ jobs:
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ always() }} if: ${{ always() }}
with: with:
name: test-results-macos-${{ github.sha }} name: test-results-macos-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ always() }} if: ${{ always() }}
with: with:
name: playwright-report-macos-${{ github.sha }} name: playwright-report-macos-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/ path: playwright-report/
retention-days: 30 retention-days: 30
overwrite: true overwrite: true

2
.gitignore vendored
View File

@ -39,6 +39,7 @@ src/wasm-lib/grackle/test_json_output
e2e/playwright/playwright-secrets.env e2e/playwright/playwright-secrets.env
e2e/playwright/temp1.png e2e/playwright/temp1.png
e2e/playwright/temp2.png e2e/playwright/temp2.png
e2e/playwright/temp3.png
# exports from snapshot-tests.spec.ts "exports of each format should work" # exports from snapshot-tests.spec.ts "exports of each format should work"
e2e/playwright/export-snapshots/* e2e/playwright/export-snapshots/*
!e2e/playwright/export-snapshots/*.png !e2e/playwright/export-snapshots/*.png
@ -48,6 +49,7 @@ e2e/playwright/export-snapshots/*
/playwright-report/ /playwright-report/
/blob-report/ /blob-report/
/playwright/.cache/ /playwright/.cache/
/src/lang/std/artifactMapCache
## generated files ## generated files

View File

@ -124,7 +124,7 @@ const extrusion = extrude(5, sketch001)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -166,7 +166,7 @@ const extrusion = extrude(5, sketch001)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -180,7 +180,7 @@ const extrusion = extrude(5, sketch001)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -198,7 +198,7 @@ const extrusion = extrude(5, sketch001)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -128,7 +128,7 @@ const extrusion = extrude(5, sketch001)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -170,7 +170,7 @@ const extrusion = extrude(5, sketch001)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -184,7 +184,7 @@ const extrusion = extrude(5, sketch001)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -202,7 +202,7 @@ const extrusion = extrude(5, sketch001)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -43,7 +43,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -85,7 +85,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -99,7 +99,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -117,7 +117,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -455,7 +455,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -497,7 +497,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -511,7 +511,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -529,7 +529,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -42,7 +42,7 @@ const extrusion = extrude(10, sketch001)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -84,7 +84,7 @@ const extrusion = extrude(10, sketch001)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -98,7 +98,7 @@ const extrusion = extrude(10, sketch001)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -116,7 +116,7 @@ const extrusion = extrude(10, sketch001)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -454,7 +454,7 @@ const extrusion = extrude(10, sketch001)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -496,7 +496,7 @@ const extrusion = extrude(10, sketch001)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -510,7 +510,7 @@ const extrusion = extrude(10, sketch001)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -528,7 +528,7 @@ const extrusion = extrude(10, sketch001)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -44,7 +44,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -86,7 +86,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -100,7 +100,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -118,7 +118,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -456,7 +456,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -498,7 +498,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -512,7 +512,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -530,7 +530,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -136,7 +136,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -178,7 +178,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -192,7 +192,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -210,7 +210,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -548,7 +548,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -590,7 +590,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -604,7 +604,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -622,7 +622,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -41,7 +41,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -83,7 +83,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -97,7 +97,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -115,7 +115,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -453,7 +453,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -495,7 +495,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -509,7 +509,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -527,7 +527,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -41,7 +41,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -83,7 +83,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -97,7 +97,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -115,7 +115,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -453,7 +453,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -495,7 +495,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -509,7 +509,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -527,7 +527,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -19,8 +19,8 @@ const exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([10, 0], %) |> line([10, 0], %)
|> arc({ |> arc({
angle_start: 0, angleStart: 0,
angle_end: 280, angleEnd: 280,
radius: 16 radius: 16
}, %) }, %)
|> close(%) |> close(%)
@ -34,9 +34,9 @@ const exampleSketch = startSketchOn('XZ')
```js ```js
{ {
// The end angle. // The end angle.
angle_end: number, angleEnd: number,
// The start angle. // The start angle.
angle_start: number, angleStart: number,
// The radius. // The radius.
radius: number, radius: number,
} | } |
@ -52,7 +52,7 @@ const exampleSketch = startSketchOn('XZ')
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -94,7 +94,7 @@ const exampleSketch = startSketchOn('XZ')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -108,7 +108,7 @@ const exampleSketch = startSketchOn('XZ')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -126,7 +126,7 @@ const exampleSketch = startSketchOn('XZ')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -464,7 +464,7 @@ const exampleSketch = startSketchOn('XZ')
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -506,7 +506,7 @@ const exampleSketch = startSketchOn('XZ')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -520,7 +520,7 @@ const exampleSketch = startSketchOn('XZ')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -538,7 +538,7 @@ const exampleSketch = startSketchOn('XZ')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -47,7 +47,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -89,7 +89,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -103,7 +103,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -121,7 +121,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -459,7 +459,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -501,7 +501,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -515,7 +515,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -533,7 +533,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -149,7 +149,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -163,7 +163,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -181,7 +181,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -223,7 +223,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -237,7 +237,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -549,7 +549,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -563,7 +563,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -581,7 +581,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -623,7 +623,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -637,7 +637,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -82,7 +82,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -96,7 +96,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -114,7 +114,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -324,7 +324,7 @@ const example = extrude(5, exampleSketch)
}, },
} | } |
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -366,7 +366,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -380,7 +380,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -619,7 +619,7 @@ const example = extrude(5, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -661,7 +661,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -675,7 +675,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -693,7 +693,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -42,7 +42,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -84,7 +84,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -98,7 +98,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -116,7 +116,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -454,7 +454,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -496,7 +496,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -510,7 +510,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -528,7 +528,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -19,8 +19,8 @@ const example = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([10, 0], %) |> line([10, 0], %)
|> arc({ |> arc({
angle_end: 0, angleStart: 120,
angle_start: 120, angleEnd: 0,
radius: 5 radius: 5
}, %) }, %)
|> line([5, 0], %) |> line([5, 0], %)
@ -41,8 +41,8 @@ const example = startSketchOn('XZ')
const exampleSketch = startSketchOn('XZ') const exampleSketch = startSketchOn('XZ')
|> startProfileAt([-10, 0], %) |> startProfileAt([-10, 0], %)
|> arc({ |> arc({
angle_end: -60, angleStart: 120,
angle_start: 120, angleEnd: -60,
radius: 5 radius: 5
}, %) }, %)
|> line([10, 0], %) |> line([10, 0], %)
@ -67,7 +67,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED) * `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -109,7 +109,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -123,7 +123,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -141,7 +141,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -479,7 +479,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -493,7 +493,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -511,7 +511,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -553,7 +553,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -567,7 +567,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -149,7 +149,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -163,7 +163,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -181,7 +181,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -223,7 +223,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -237,7 +237,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -549,7 +549,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -563,7 +563,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -581,7 +581,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -623,7 +623,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -637,7 +637,7 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -19,10 +19,9 @@ const part001 = startSketchOn('XY')
|> circle([5, 5], 10, %) |> circle([5, 5], 10, %)
|> extrude(10, %) |> extrude(10, %)
|> helix({ |> helix({
angle_start: 0, angleStart: 0,
ccw: true, ccw: true,
revolutions: 16, revolutions: 16
angle_start: 0
}, %) }, %)
``` ```
@ -34,7 +33,7 @@ const part001 = startSketchOn('XY')
```js ```js
{ {
// Start angle (in degrees). // Start angle (in degrees).
angle_start: number, angleStart: number,
// Is the helix rotation counter clockwise? The default is `false`. // Is the helix rotation counter clockwise? The default is `false`.
ccw: string, ccw: string,
// Length of the helix. If this argument is not provided, the height of the extrude group is used. // Length of the helix. If this argument is not provided, the height of the extrude group is used.
@ -51,7 +50,7 @@ const part001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -65,7 +64,7 @@ const part001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -83,7 +82,7 @@ const part001 = startSketchOn('XY')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -125,7 +124,7 @@ const part001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -139,7 +138,7 @@ const part001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -442,7 +441,7 @@ const part001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -456,7 +455,7 @@ const part001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -474,7 +473,7 @@ const part001 = startSketchOn('XY')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -516,7 +515,7 @@ const part001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -530,7 +529,7 @@ const part001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -53,7 +53,7 @@ const example = extrude(1, exampleSketch)
* `hole_sketch_group`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED) * `hole_sketch_group`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -95,7 +95,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -109,7 +109,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -127,7 +127,7 @@ const example = extrude(1, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -457,7 +457,7 @@ const example = extrude(1, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -499,7 +499,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -513,7 +513,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -531,7 +531,7 @@ const example = extrude(1, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -860,7 +860,7 @@ const example = extrude(1, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -902,7 +902,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -916,7 +916,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -934,7 +934,7 @@ const example = extrude(1, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -33,7 +33,7 @@ const example = extrude(5, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -75,7 +75,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -89,7 +89,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -107,7 +107,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -33,7 +33,7 @@ const example = extrude(5, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -75,7 +75,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -89,7 +89,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -107,7 +107,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -46,7 +46,7 @@ const example = extrude(5, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -88,7 +88,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -102,7 +102,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -120,7 +120,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -458,7 +458,7 @@ const example = extrude(5, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -500,7 +500,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -514,7 +514,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -532,7 +532,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -33,7 +33,7 @@ const example = extrude(5, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -75,7 +75,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -89,7 +89,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -107,7 +107,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -445,7 +445,7 @@ const example = extrude(5, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -487,7 +487,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -501,7 +501,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -519,7 +519,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -51,7 +51,7 @@ const example = extrude(1, exampleSketch)
* `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED) * `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -93,7 +93,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -107,7 +107,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -125,7 +125,7 @@ const example = extrude(1, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -55,7 +55,7 @@ const example = extrude(-5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -69,7 +69,7 @@ const example = extrude(-5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -87,7 +87,7 @@ const example = extrude(-5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -129,7 +129,7 @@ const example = extrude(-5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -143,7 +143,7 @@ const example = extrude(-5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -44,7 +44,7 @@ const example = extrude(1, exampleSketch)
* `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED) * `sketch_group_set`: `SketchGroupSet` - A sketch group or a group of sketch groups. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -86,7 +86,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -100,7 +100,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -118,7 +118,7 @@ const example = extrude(1, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -53,7 +53,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -67,7 +67,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -85,7 +85,7 @@ const example = extrude(1, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -127,7 +127,7 @@ const example = extrude(1, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -141,7 +141,7 @@ const example = extrude(1, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -55,7 +55,7 @@ let vase = layer()
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -69,7 +69,7 @@ let vase = layer()
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -87,7 +87,7 @@ let vase = layer()
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -129,7 +129,7 @@ let vase = layer()
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -143,7 +143,7 @@ let vase = layer()
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -34,7 +34,7 @@ const sketch001 = startSketchOn('XY')
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -76,7 +76,7 @@ const sketch001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -90,7 +90,7 @@ const sketch001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -108,7 +108,7 @@ const sketch001 = startSketchOn('XY')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -29,7 +29,7 @@ const sketch001 = startSketchOn('XY')
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -71,7 +71,7 @@ const sketch001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -85,7 +85,7 @@ const sketch001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -103,7 +103,7 @@ const sketch001 = startSketchOn('XY')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -28,7 +28,7 @@ const sketch001 = startSketchOn('XY')
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -70,7 +70,7 @@ const sketch001 = startSketchOn('XY')
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -84,7 +84,7 @@ const sketch001 = startSketchOn('XY')
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -102,7 +102,7 @@ const sketch001 = startSketchOn('XY')
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -250,7 +250,7 @@ uuid |
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -292,7 +292,7 @@ uuid |
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -306,7 +306,7 @@ uuid |
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -324,7 +324,7 @@ uuid |
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -658,7 +658,7 @@ uuid |
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -672,7 +672,7 @@ uuid |
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -690,7 +690,7 @@ uuid |
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -732,7 +732,7 @@ uuid |
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -746,7 +746,7 @@ uuid |
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -137,7 +137,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -151,7 +151,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -169,7 +169,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -211,7 +211,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -225,7 +225,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -528,7 +528,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -542,7 +542,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -560,7 +560,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -602,7 +602,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -616,7 +616,7 @@ shell({ faces: ['end'], thickness: 0.25 }, firstSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,

View File

@ -97,7 +97,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -111,7 +111,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -129,7 +129,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -411,7 +411,7 @@ const example = extrude(5, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -453,7 +453,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -467,7 +467,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -485,7 +485,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -59,7 +59,7 @@ const example = extrude(5, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -101,7 +101,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -115,7 +115,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -133,7 +133,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -106,9 +106,9 @@ const example002 = extrude(5, exampleSketch002)
const a1 = startSketchOn({ const a1 = startSketchOn({
plane: { plane: {
origin: { x: 0, y: 0, z: 0 }, origin: { x: 0, y: 0, z: 0 },
x_axis: { x: 1, y: 0, z: 0 }, xAxis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 1, z: 0 }, yAxis: { x: 0, y: 1, z: 0 },
z_axis: { x: 0, y: 0, z: 1 } zAxis: { x: 0, y: 0, z: 1 }
} }
}) })
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
@ -141,19 +141,19 @@ const a1 = startSketchOn({
z: number, z: number,
}, },
// What should the planes X axis be? // What should the planes X axis be?
x_axis: { xAxis: {
x: number, x: number,
y: number, y: number,
z: number, z: number,
}, },
// What should the planes Y axis be? // What should the planes Y axis be?
y_axis: { yAxis: {
x: number, x: number,
y: number, y: number,
z: number, z: number,
}, },
// The z-axis (normal). // The z-axis (normal).
z_axis: { zAxis: {
x: number, x: number,
y: number, y: number,
z: number, z: number,
@ -166,7 +166,7 @@ const a1 = startSketchOn({
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -180,7 +180,7 @@ const a1 = startSketchOn({
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -198,7 +198,7 @@ const a1 = startSketchOn({
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -578,7 +578,7 @@ const a1 = startSketchOn({
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -592,7 +592,7 @@ const a1 = startSketchOn({
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -610,7 +610,7 @@ const a1 = startSketchOn({
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -84,7 +84,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -98,7 +98,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -116,7 +116,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -454,7 +454,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -496,7 +496,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -510,7 +510,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -528,7 +528,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -33,7 +33,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -75,7 +75,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -89,7 +89,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -107,7 +107,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -445,7 +445,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -487,7 +487,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -501,7 +501,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -519,7 +519,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -36,7 +36,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -78,7 +78,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -92,7 +92,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -110,7 +110,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -448,7 +448,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -490,7 +490,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -504,7 +504,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -522,7 +522,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -36,7 +36,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -78,7 +78,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -92,7 +92,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -110,7 +110,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -448,7 +448,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -490,7 +490,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -504,7 +504,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -522,7 +522,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -34,7 +34,7 @@ const example = extrude(10, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -76,7 +76,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -90,7 +90,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -108,7 +108,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -446,7 +446,7 @@ const example = extrude(10, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -488,7 +488,7 @@ const example = extrude(10, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -502,7 +502,7 @@ const example = extrude(10, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -520,7 +520,7 @@ const example = extrude(10, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -32,7 +32,7 @@ const example = extrude(5, exampleSketch)
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -74,7 +74,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -88,7 +88,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -106,7 +106,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,
@ -444,7 +444,7 @@ const example = extrude(5, exampleSketch)
`SketchGroup` - A sketch group is a collection of paths. `SketchGroup` - A sketch group is a collection of paths.
```js ```js
{ {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: { on: {
@ -486,7 +486,7 @@ const example = extrude(5, exampleSketch)
// Chamfers or fillets on this extrude group. // Chamfers or fillets on this extrude group.
filletOrChamfers: [{ filletOrChamfers: [{
// The engine id of the edge to fillet. // The engine id of the edge to fillet.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this fillet. // The id of the engine command that called this fillet.
id: uuid, id: uuid,
radius: number, radius: number,
@ -500,7 +500,7 @@ const example = extrude(5, exampleSketch)
} | } |
{ {
// The engine id of the edge to chamfer. // The engine id of the edge to chamfer.
edge_id: uuid, edgeId: uuid,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
@ -518,7 +518,7 @@ const example = extrude(5, exampleSketch)
id: uuid, id: uuid,
// The sketch group. // The sketch group.
sketchGroup: { sketchGroup: {
// The id of the sketch group. // The id of the sketch group (this will change when the engine's reference to it changes.
id: uuid, id: uuid,
// What the sketch is on (can be a plane or a face). // What the sketch is on (can be a plane or a face).
on: SketchSurface, on: SketchSurface,

View File

@ -19,6 +19,7 @@ import {
TEST_SETTINGS_ONBOARDING_EXPORT, TEST_SETTINGS_ONBOARDING_EXPORT,
TEST_SETTINGS_ONBOARDING_START, TEST_SETTINGS_ONBOARDING_START,
TEST_CODE_GIZMO, TEST_CODE_GIZMO,
TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW,
TEST_SETTINGS_ONBOARDING_USER_MENU, TEST_SETTINGS_ONBOARDING_USER_MENU,
TEST_SETTINGS_ONBOARDING_PARAMETRIC_MODELING, TEST_SETTINGS_ONBOARDING_PARAMETRIC_MODELING,
} from './storageStates' } from './storageStates'
@ -26,7 +27,7 @@ import * as TOML from '@iarna/toml'
import { LineInputsType } from 'lang/std/sketchcombos' import { LineInputsType } from 'lang/std/sketchcombos'
import { Coords2d } from 'lang/std/sketch' import { Coords2d } from 'lang/std/sketch'
import { KCL_DEFAULT_LENGTH } from 'lib/constants' import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import { EngineCommand } from 'lang/std/artifactMap' import { EngineCommand } from 'lang/std/artifactGraph'
import { onboardingPaths } from 'routes/Onboarding/paths' import { onboardingPaths } from 'routes/Onboarding/paths'
import { bracket } from 'lib/exampleKcl' import { bracket } from 'lib/exampleKcl'
@ -45,9 +46,9 @@ document.addEventListener('mousemove', (e) =>
const deg = (Math.PI * 2) / 360 const deg = (Math.PI * 2) / 360
const commonPoints = { const commonPoints = {
startAt: '[7.19, -9.7]', startAt: '[0.75, -1.01]',
num1: 7.25, num1: 0.75,
num2: 14.44, num2: 1.5,
} }
test.afterEach(async ({ context, page }, testInfo) => { test.afterEach(async ({ context, page }, testInfo) => {
@ -466,7 +467,7 @@ test.describe('Testing Camera Movement', () => {
await expect(page.getByTestId('hover-highlight')).not.toBeVisible() await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
await page.waitForTimeout(100) await page.waitForTimeout(200)
// hover over horizontal line // hover over horizontal line
await u.canvasLocator.hover({ position: { x: 800, y } }) await u.canvasLocator.hover({ position: { x: 800, y } })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({ await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
@ -925,10 +926,10 @@ test.describe('Editor tests', () => {
await expect(page.locator('.cm-lint-marker-error')).toBeVisible() await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
await expect( await expect(
page.locator('.cm-lintRange.cm-lintRange-error').first() page.locator('.cm-lint-marker.cm-lint-marker-error')
).toBeVisible() ).toBeVisible()
await page.locator('.cm-lintRange.cm-lintRange-error').hover() await page.locator('.cm-lint-marker.cm-lint-marker-error').hover()
await expect(page.locator('.cm-diagnosticText').first()).toBeVisible() await expect(page.locator('.cm-diagnosticText').first()).toBeVisible()
await expect( await expect(
page.getByText('Cannot redefine `topAng`').first() page.getByText('Cannot redefine `topAng`').first()
@ -1019,7 +1020,7 @@ test.describe('Editor tests', () => {
|> line([0, -10], %, $revolveAxis) |> line([0, -10], %, $revolveAxis)
|> close(%) |> close(%)
|> extrude(10, %) |> extrude(10, %)
const sketch001 = startSketchOn(box, revolveAxis) const sketch001 = startSketchOn(box, revolveAxis)
|> startProfileAt([5, 10], %) |> startProfileAt([5, 10], %)
|> line([0, -10], %) |> line([0, -10], %)
@ -1045,7 +1046,7 @@ test.describe('Editor tests', () => {
await page.hover('.cm-lint-marker-error') await page.hover('.cm-lint-marker-error')
const searchText = const searchText =
'sketch profile must lie entirely on one side of the revolution axis' 'sketch profile must lie entirely on one side of the revolution axis'
await expect(page.getByText(searchText).first()).toBeVisible() await expect(page.getByText(searchText)).toBeVisible()
}) })
test.describe('Autocomplete works', () => { test.describe('Autocomplete works', () => {
test('with enter/click to accept the completion', async ({ page }) => { test('with enter/click to accept the completion', async ({ page }) => {
@ -2265,6 +2266,50 @@ test.describe('Onboarding tests', () => {
await expect(page.locator('.cm-content')).toContainText('// Shelf Bracket') await expect(page.locator('.cm-content')).toContainText('// Shelf Bracket')
}) })
test('Code resets after confirmation', async ({ page }) => {
const initialCode = `const sketch001 = startSketchOn('XZ')`
// Load the page up with some code so we see the confirmation warning
// when we go to replay onboarding
await page.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, initialCode)
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
// Replay the onboarding
await page.getByRole('link', { name: 'Settings' }).last().click()
const replayButton = page.getByRole('button', { name: 'Replay onboarding' })
await expect(replayButton).toBeVisible()
await replayButton.click()
// Ensure we see the warning, and that the code has not yet updated
await expect(
page.getByText('Replaying onboarding resets your code')
).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(initialCode)
const nextButton = page.getByTestId('onboarding-next')
await expect(nextButton).toBeVisible()
await nextButton.click()
// Ensure we see the introduction and that the code has been reset
await expect(page.getByText('Welcome to Modeling App!')).toBeVisible()
await expect(page.locator('.cm-content')).toContainText('// Shelf Bracket')
// Ensure we persisted the code to local storage.
// Playwright's addInitScript method unfortunately will reset
// this code if we try reloading the page as a test,
// so this is our best way to test persistence afaik.
expect(
await page.evaluate(() => {
return localStorage.getItem('persistCode')
})
).toContain('// Shelf Bracket')
})
test('Click through each onboarding step', async ({ page }) => { test('Click through each onboarding step', async ({ page }) => {
const u = await getUtils(page) const u = await getUtils(page)
@ -2490,18 +2535,29 @@ test.describe('Onboarding tests', () => {
await page.waitForURL('**/file/**', { waitUntil: 'domcontentloaded' }) await page.waitForURL('**/file/**', { waitUntil: 'domcontentloaded' })
// Test that the text in this step is correct // Test that the text in this step is correct
const avatarLocator = await page const sidebar = page.getByTestId('user-sidebar-toggle')
.getByTestId('user-sidebar-toggle') const avatar = sidebar.locator('img')
.locator('img') const onboardingOverlayLocator = page
const onboardingOverlayLocator = await page
.getByTestId('onboarding-content') .getByTestId('onboarding-content')
.locator('div') .locator('div')
.nth(1) .nth(1)
// Expect the avatar to be visible and for the text to reference it // Expect the avatar to be visible and for the text to reference it
await expect(avatarLocator).not.toBeVisible() await expect(avatar).not.toBeVisible()
await expect(onboardingOverlayLocator).toBeVisible() await expect(onboardingOverlayLocator).toBeVisible()
await expect(onboardingOverlayLocator).toContainText('the menu button') await expect(onboardingOverlayLocator).toContainText('the menu button')
// Test we mention what else is in this menu for https://github.com/KittyCAD/modeling-app/issues/2939
// which doesn't deserver its own full test spun up
const userMenuFeatures = [
'manage your account',
'report a bug',
'request a feature',
'sign out',
]
for (const feature of userMenuFeatures) {
await expect(onboardingOverlayLocator).toContainText(feature)
}
}) })
}) })
@ -2579,10 +2635,9 @@ test.describe('Testing selections', () => {
await page.mouse.move(startXPx + PUR * 15, 500 - PUR * 10) await page.mouse.move(startXPx + PUR * 15, 500 - PUR * 10)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible() await expect(page.getByTestId('hover-highlight').first()).toBeVisible()
// bg-yellow-200 is more brittle than hover-highlight, but is closer to the user experience // bg-yellow-300/70 is more brittle than hover-highlight, but is closer to the user experience
// and will be an easy fix if it breaks because we change the colour // and will be an easy fix if it breaks because we change the colour
await expect(page.locator('.bg-yellow-200').first()).toBeVisible() await expect(page.locator('.bg-yellow-300\\/70')).toBeVisible()
// check mousing off, than mousing onto another line // check mousing off, than mousing onto another line
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 15) // mouse off await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 15) // mouse off
await expect(page.getByTestId('hover-highlight')).not.toBeVisible() await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
@ -3034,7 +3089,7 @@ const sketch002 = startSketchOn(launderExtrudeThroughVar, seg02)
await expect(page.getByTestId('hover-highlight').first()).not.toBeVisible() await expect(page.getByTestId('hover-highlight').first()).not.toBeVisible()
await page.mouse.move(flatExtrusionFace[0], flatExtrusionFace[1]) await page.mouse.move(flatExtrusionFace[0], flatExtrusionFace[1])
await expect(page.getByTestId('hover-highlight')).toHaveCount(5) // multiple lines await expect(page.getByTestId('hover-highlight')).toHaveCount(6) // multiple lines
await page.mouse.move(nothing[0], nothing[1]) await page.mouse.move(nothing[0], nothing[1])
await page.waitForTimeout(100) await page.waitForTimeout(100)
await expect(page.getByTestId('hover-highlight').first()).not.toBeVisible() await expect(page.getByTestId('hover-highlight').first()).not.toBeVisible()
@ -3850,6 +3905,39 @@ const extrude001 = extrude(distance001, sketch001)`.replace(
test.describe('Regression tests', () => { test.describe('Regression tests', () => {
// bugs we found that don't fit neatly into other categories // bugs we found that don't fit neatly into other categories
test('bad model has inline error #3251', async ({ page }) => {
// because the model has `line([0,0]..` it is valid code, but the model is invalid
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch2 = startSketchOn("XY")
const sketch001 = startSketchAt([-0, -0])
|> line([0, 0], %)
|> line([-4.84, -5.29], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)`
)
})
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
// error in guter
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-error')
// this is a cryptic error message, fact that all the lines are co-linear from the `line([0,0])` is the issue why
// the close doesn't work
// when https://github.com/KittyCAD/modeling-app/issues/3268 is closed
// this test will need updating
const crypticErrorText = `ApiError`
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
})
test('executes on load', async ({ page }) => { test('executes on load', async ({ page }) => {
const u = await getUtils(page) const u = await getUtils(page)
await page.addInitScript(async () => { await page.addInitScript(async () => {
@ -3975,16 +4063,19 @@ test.describe('Regression tests', () => {
) )
}) })
await page.goto('/') await expect(async () => {
await u.waitForPageLoad() await page.goto('/')
await u.waitForPageLoad()
// error in guter // error in guter
await expect(page.locator('.cm-lint-marker-error')).toBeVisible() await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
await page.waitForTimeout(200) timeout: 1_000,
// expect it still to be there (sometimes it just clears for a bit?) })
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({ await page.waitForTimeout(200)
timeout: 10_000, // expect it still to be there (sometimes it just clears for a bit?)
}) await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
timeout: 1_000,
})
}).toPass({ timeout: 40_000, intervals: [1_000] })
// error text on hover // error text on hover
await page.hover('.cm-lint-marker-error') await page.hover('.cm-lint-marker-error')
@ -4132,12 +4223,15 @@ test.describe('Sketch tests', () => {
await page.setViewportSize({ width: 1200, height: 500 }) await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await u.waitForAuthSkipAppStart()
await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
await expect( await expect(async () => {
page.getByRole('button', { name: 'Edit Sketch' }) await page.mouse.click(700, 200)
).toBeEnabled() await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
await page.getByRole('button', { name: 'Edit Sketch' }).click() await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeEnabled({ timeout: 1000 })
await page.getByRole('button', { name: 'Edit Sketch' }).click()
}).toPass({ timeout: 40_000, intervals: [1_000] })
await page.waitForTimeout(600) // wait for animation await page.waitForTimeout(600) // wait for animation
@ -4853,6 +4947,116 @@ const sketch002 = startSketchOn(extrude001, 'END')
`.replace(/\s/g, '') `.replace(/\s/g, '')
) )
}) })
test('empty-scene default-planes act as expected', async ({
page,
browserName,
}) => {
test.skip(
browserName === 'webkit',
'Skip on Safari until `window.tearDown` is working there'
)
/**
* Tests the following things
* 1) The the planes are there on load because the scene is empty
* 2) The planes don't changes color when hovered initially
* 3) Putting something in the scene makes the planes hidden
* 4) Removing everything from the scene shows the plans again
* 3) Once "start sketch" is click, the planes do respond to hovers
* 4) Selecting a plan works as expected, i.e. sketch mode
* 5) Reloading the scene with something already in the scene means the planes are hidden
*/
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
const XYPlanePoint = { x: 774, y: 116 } as const
const unHoveredColor: [number, number, number] = [47, 47, 93]
expect(
await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor)
).toBeLessThan(8)
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y)
await page.waitForTimeout(200)
// color should not change for having been hovered
expect(
await u.getGreatestPixDiff(XYPlanePoint, unHoveredColor)
).toBeLessThan(8)
await u.openAndClearDebugPanel()
await u.codeLocator.fill(`const sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> xLine(-20, %)
`)
await u.expectCmdLog('[data-message-type="execution-done"]')
const noPlanesColor: [number, number, number] = [30, 30, 30]
expect(
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
).toBeLessThan(3)
await u.clearCommandLogs()
await u.removeCurrentCode()
await u.expectCmdLog('[data-message-type="execution-done"]')
await expect
.poll(() => u.getGreatestPixDiff(XYPlanePoint, unHoveredColor), {
timeout: 5_000,
})
.toBeLessThan(8)
// click start Sketch
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 5 })
const hoveredColor: [number, number, number] = [93, 93, 127]
// now that we're expecting the user to select a plan, it does respond to hover
await expect
.poll(() => u.getGreatestPixDiff(XYPlanePoint, hoveredColor))
.toBeLessThan(8)
await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y)
await page.waitForTimeout(600)
await page.mouse.click(XYPlanePoint.x, XYPlanePoint.y)
await page.waitForTimeout(200)
await page.mouse.click(XYPlanePoint.x + 50, XYPlanePoint.y + 50)
await expect(u.codeLocator)
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([11.8, 9.09], %)
|> line([3.39, -3.39], %)
`)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XZ')
|> startProfileAt([11.8, 9.09], %)
|> line([3.39, -3.39], %)
`
)
})
await page.reload()
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// expect there to be no planes on load since there's something in the scene
expect(
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
).toBeLessThan(3)
})
}) })
test.describe('Testing constraints', () => { test.describe('Testing constraints', () => {
@ -7243,15 +7447,15 @@ test.describe('Test network and connection issues', () => {
.toHaveText(`const sketch001 = startSketchOn('XZ') .toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt(${commonPoints.startAt}, %) |> startProfileAt(${commonPoints.startAt}, %)
|> line([${commonPoints.num1}, 0], %) |> line([${commonPoints.num1}, 0], %)
|> line([-9.16, 8.81], %)`) |> line([-8.84, 8.75], %)`)
await page.waitForTimeout(100) await page.waitForTimeout(100)
await page.mouse.click(startXPx, 500 - PUR * 20) await page.mouse.click(startXPx, 500 - PUR * 20)
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ') .toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt(${commonPoints.startAt}, %) |> startProfileAt(${commonPoints.startAt}, %)
|> line([${commonPoints.num1}, 0], %) |> line([${commonPoints.num1}, 0], %)
|> line([-9.16, 8.81], %) |> line([-8.84, 8.75], %)
|> line([-5.28, 0], %)`) |> line([-5.6, 0], %)`)
// Unequip line tool // Unequip line tool
await page.keyboard.press('Escape') await page.keyboard.press('Escape')
@ -8047,3 +8251,209 @@ test('Sketch on face', async ({ page }) => {
const sketch002 = extrude(${[5, 5]} + 7, sketch002)` const sketch002 = extrude(${[5, 5]} + 7, sketch002)`
await expect(page.locator('.cm-content')).toHaveText(result2.regExp) await expect(page.locator('.cm-content')).toHaveText(result2.regExp)
}) })
test.describe('Code pane and errors', () => {
test('Typing KCL errors induces a badge on the code pane button', async ({
page,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
await page.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, bracket)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Ensure no badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).not.toContainText('notification')
// Delete a character to break the KCL
await u.openKclCodePanel()
await page.getByText('extrude(').click()
await page.keyboard.press('Backspace')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
})
test('Opening and closing the code pane will consistently show error diagnostics', async ({
page,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
await page.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, bracket)
await page.setViewportSize({ width: 1200, height: 900 })
await u.waitForAuthSkipAppStart()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Ensure we have no errors in the gutter.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Ensure no badge is present
const codePaneButton = page.getByRole('button', { name: 'KCL Code pane' })
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).not.toContainText('notification')
// Delete a character to break the KCL
await u.openKclCodePanel()
await page.getByText('extrude(').click()
await page.keyboard.press('Backspace')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.getByText('Unexpected token').first()).toBeVisible()
// Close the code pane
codePaneButton.click()
await page.waitForTimeout(500)
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Open the code pane
u.openKclCodePanel()
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.getByText('Unexpected token').first()).toBeVisible()
})
test('When error is not in view you can click the badge to scroll to it', async ({
page,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
await page.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await page.waitForTimeout(1000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'sketch profile must lie entirely on one side of the revolution axis'
)
.first()
).toBeVisible()
})
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
page,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
await page.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await page.waitForTimeout(1000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// click in the editor to focus it
await page.locator('.cm-content').click()
await page.waitForTimeout(500)
// go to the start of the editor and enter more text which will trigger
// a lint error.
// GO to the start of the editor.
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('Home')
await page.keyboard.type('const foo_bar = 1')
await page.waitForTimeout(500)
await page.keyboard.press('Enter')
// ensure we have a lint error
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'sketch profile must lie entirely on one side of the revolution axis'
)
.first()
).toBeVisible()
})
})

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -86,3 +86,285 @@ export const TEST_CODE_GIZMO = `const part001 = startSketchOn('XZ')
|> close(%) |> close(%)
|> extrude(5 + 7, %) |> extrude(5 + 7, %)
` `
export const TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW = `const width = 50.8
const height = 30
const thickness = 2
const keychainHoleSize = 3
const keychain = startSketchOn("XY")
|> startProfileAt([0, 0], %)
|> lineTo([width, 0], %)
|> lineTo([width, height], %)
|> lineTo([0, height], %)
|> close(%)
|> extrude(thickness, %)
// generated from /home/paultag/Downloads/zma-logomark.svg
fn svg = (surface, origin, depth) => {
let a0 = surface |> startProfileAt([origin[0] + 45.430427, origin[1] + -14.627736], %)
|> bezierCurve({
control1: [ 0, 0.764157 ],
control2: [ 0, 1.528314 ],
to: [ 0, 2.292469 ]
}, %)
|> bezierCurve({
control1: [ -3.03202, 0 ],
control2: [ -6.064039, 0 ],
to: [ -9.09606, 0 ]
}, %)
|> bezierCurve({
control1: [ 0, -1.077657 ],
control2: [ 0, -2.155312 ],
to: [ 0, -3.232969 ]
}, %)
|> bezierCurve({
control1: [ 2.741805, 0 ],
control2: [ 5.483613, 0 ],
to: [ 8.225417, 0 ]
}, %)
|> bezierCurve({
control1: [ -2.740682, -2.961815 ],
control2: [ -5.490342, -5.925794 ],
to: [ -8.225417, -8.886255 ]
}, %)
|> bezierCurve({
control1: [ 0, -0.723995 ],
control2: [ 0, -1.447988 ],
to: [ 0, -2.171981 ]
}, %)
|> bezierCurve({
control1: [ 0.712124, 0.05061 ],
control2: [ 1.511636, -0.09877 ],
to: [ 2.172096, 0.07005 ]
}, %)
|> bezierCurve({
control1: [ 0.68573, 0.740811 ],
control2: [ 1.371459, 1.481622 ],
to: [ 2.057187, 2.222436 ]
}, %)
|> bezierCurve({
control1: [ 0, -0.76416 ],
control2: [ 0, -1.52832 ],
to: [ 0, -2.29248 ]
}, %)
|> bezierCurve({
control1: [ 3.032013, 0 ],
control2: [ 6.064026, 0 ],
to: [ 9.096038, 0 ]
}, %)
|> bezierCurve({
control1: [ 0, 1.077657 ],
control2: [ 0, 2.155314 ],
to: [ 0, 3.232973 ]
}, %)
|> bezierCurve({
control1: [ -2.741312, 0 ],
control2: [ -5.482623, 0 ],
to: [ -8.223936, 0 ]
}, %)
|> bezierCurve({
control1: [ 2.741313, 2.961108 ],
control2: [ 5.482624, 5.922216 ],
to: [ 8.223936, 8.883325 ]
}, %)
|> bezierCurve({
control1: [ 0, 0.724968 ],
control2: [ 0, 1.449938 ],
to: [ 0, 2.174907 ]
}, %)
|> bezierCurve({
control1: [ -0.712656, -0.05145 ],
control2: [ -1.512554, 0.09643 ],
to: [ -2.173592, -0.07298 ]
}, %)
|> bezierCurve({
control1: [ -0.685222, -0.739834 ],
control2: [ -1.370445, -1.479669 ],
to: [ -2.055669, -2.219505 ]
}, %)
|> close(%)
|> extrude(depth, %)
let a1 = surface |> startProfileAt([origin[0] + 57.920488, origin[1] + -15.244943], %)
|> bezierCurve({
control1: [ -2.78904, 0.106635 ],
control2: [ -5.052548, -2.969529 ],
to: [ -4.055141, -5.598369 ]
}, %)
|> bezierCurve({
control1: [ 0.841523, -0.918736 ],
control2: [ 0.439412, -1.541892 ],
to: [ -0.368488, -2.214378 ]
}, %)
|> bezierCurve({
control1: [ -0.418245, -0.448461 ],
control2: [ -0.836489, -0.896922 ],
to: [ -1.254732, -1.345384 ]
}, %)
|> bezierCurve({
control1: [ -2.76806, 2.995359 ],
control2: [ -2.32667, 8.18409 ],
to: [ 0.897655, 10.678932 ]
}, %)
|> bezierCurve({
control1: [ 2.562822, 2.186098 ],
control2: [ 6.605111, 2.28043 ],
to: [ 9.271202, 0.226476 ]
}, %)
|> bezierCurve({
control1: [ -0.743744, -0.797465 ],
control2: [ -1.487487, -1.594932 ],
to: [ -2.231232, -2.392397 ]
}, %)
|> bezierCurve({
control1: [ -0.672938, 0.421422 ],
control2: [ -1.465362, 0.646946 ],
to: [ -2.259264, 0.64512 ]
}, %)
|> close(%)
|> extrude(depth, %)
let a2 = surface |> startProfileAt([origin[0] + 62.19406300000001, origin[1] + -19.500698999999997], %)
|> bezierCurve({
control1: [ 0.302938, 1.281141 ],
control2: [ -1.53575, 2.434288 ],
to: [ -0.10908, 3.279477 ]
}, %)
|> bezierCurve({
control1: [ 0.504637, 0.54145 ],
control2: [ 1.009273, 1.082899 ],
to: [ 1.513909, 1.624348 ]
}, %)
|> bezierCurve({
control1: [ 2.767778, -2.995425 ],
control2: [ 2.327135, -8.184384 ],
to: [ -0.897661, -10.679047 ]
}, %)
|> bezierCurve({
control1: [ -2.562947, -2.186022 ],
control2: [ -6.604089, -2.279606 ],
to: [ -9.271196, -0.227813 ]
}, %)
|> bezierCurve({
control1: [ 0.744231, 0.797952 ],
control2: [ 1.488461, 1.595904 ],
to: [ 2.232692, 2.393856 ]
}, %)
|> bezierCurve({
control1: [ 2.302377, -1.564629 ],
control2: [ 5.793126, -0.15358 ],
to: [ 6.396577, 2.547372 ]
}, %)
|> bezierCurve({
control1: [ 0.08981, 0.346302 ],
control2: [ 0.134865, 0.704078 ],
to: [ 0.13476, 1.061807 ]
}, %)
|> close(%)
|> extrude(depth, %)
let a3 = surface |> startProfileAt([origin[0] + 74.124866, origin[1] + -15.244943], %)
|> bezierCurve({
control1: [ -2.78904, 0.106635 ],
control2: [ -5.052549, -2.969529 ],
to: [ -4.055142, -5.598369 ]
}, %)
|> bezierCurve({
control1: [ 0.841527, -0.918738 ],
control2: [ 0.43941, -1.541892 ],
to: [ -0.368497, -2.214367 ]
}, %)
|> bezierCurve({
control1: [ -0.418254, -0.448466 ],
control2: [ -0.836507, -0.896931 ],
to: [ -1.254761, -1.345395 ]
}, %)
|> bezierCurve({
control1: [ -2.768019, 2.995371 ],
control2: [ -2.326624, 8.184088 ],
to: [ 0.897678, 10.678932 ]
}, %)
|> bezierCurve({
control1: [ 2.56289, 2.186191 ],
control2: [ 6.60516, 2.280307 ],
to: [ 9.271371, 0.226476 ]
}, %)
|> bezierCurve({
control1: [ -0.743808, -0.797465 ],
control2: [ -1.487616, -1.594932 ],
to: [ -2.231424, -2.392397 ]
}, %)
|> bezierCurve({
control1: [ -0.672916, 0.421433 ],
control2: [ -1.465344, 0.646926 ],
to: [ -2.259225, 0.64512 ]
}, %)
|> close(%)
|> extrude(depth, %)
let a4 = surface |> startProfileAt([origin[0] + 77.57333899999998, origin[1] + -16.989262999999998], %)
|> bezierCurve({
control1: [ 0.743298, 0.797463 ],
control2: [ 1.486592, 1.594926 ],
to: [ 2.229888, 2.392389 ]
}, %)
|> bezierCurve({
control1: [ 2.767827, -2.995393 ],
control2: [ 2.327103, -8.184396 ],
to: [ -0.897672, -10.679047 ]
}, %)
|> bezierCurve({
control1: [ -2.562939, -2.186037 ],
control2: [ -6.604077, -2.279589 ],
to: [ -9.271185, -0.227813 ]
}, %)
|> bezierCurve({
control1: [ 0.744243, 0.797952 ],
control2: [ 1.488486, 1.595904 ],
to: [ 2.232729, 2.393856 ]
}, %)
|> bezierCurve({
control1: [ 2.302394, -1.564623 ],
control2: [ 5.793201, -0.153598 ],
to: [ 6.396692, 2.547372 ]
}, %)
|> bezierCurve({
control1: [ 0.32074, 1.215468 ],
control2: [ 0.06159, 2.564765 ],
to: [ -0.690452, 3.573243 ]
}, %)
|> close(%)
|> extrude(depth, %)
const box = startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> line([0, 10], %)
|> line([10, 0], %)
|> line([0, -10], %, $revolveAxis)
|> close(%)
|> extrude(10, %)
const sketch001 = startSketchOn(box, revolveAxis)
|> startProfileAt([5, 10], %)
|> line([0, -10], %)
|> line([2, 0], %)
|> line([0, -10], %)
|> close(%)
|> revolve({
axis: revolveAxis,
angle: 90
}, %)
return 0
}
svg(startSketchOn(keychain, 'end'), [-33, 32], -thickness)
startSketchOn(keychain, 'end')
|> circle([
width / 2,
height - (keychainHoleSize + 1.5)
], keychainHoleSize, %)
|> extrude(-thickness, %)`

View File

@ -1,5 +1,5 @@
import { expect, Page, Download } from '@playwright/test' import { expect, Page, Download } from '@playwright/test'
import { EngineCommand } from 'lang/std/artifactMap' import { EngineCommand } from 'lang/std/artifactGraph'
import os from 'os' import os from 'os'
import fsp from 'fs/promises' import fsp from 'fs/promises'
import pixelMatch from 'pixelmatch' import pixelMatch from 'pixelmatch'
@ -15,6 +15,23 @@ export const TEST_COLORS = {
BLUE: [0, 0, 255] as TestColor, BLUE: [0, 0, 255] as TestColor,
} as const } as const
async function waitForPageLoadWithRetry(page: Page) {
await expect(async () => {
await page.goto('/')
const errorMessage = 'App failed to load - 🔃 Retrying ...'
await expect(page.getByTestId('loading'), errorMessage).not.toBeAttached({
timeout: 20_000,
})
await expect(
page.getByRole('button', { name: 'Start Sketch' }),
errorMessage
).toBeEnabled({
timeout: 20_000,
})
}).toPass({ timeout: 70_000, intervals: [1_000] })
}
async function waitForPageLoad(page: Page) { async function waitForPageLoad(page: Page) {
// wait for all spinners to be gone // wait for all spinners to be gone
await expect(page.getByTestId('loading')).not.toBeAttached({ await expect(page.getByTestId('loading')).not.toBeAttached({
@ -218,9 +235,12 @@ async function waitForAuthAndLsp(page: Page) {
} }
return false return false
}) })
if (process.env.CI) {
await page.goto('/') await waitForPageLoadWithRetry(page)
await waitForPageLoad(page) } else {
await page.goto('/')
await waitForPageLoad(page)
}
return waitForLspPromise return waitForLspPromise
} }
@ -234,6 +254,7 @@ export async function getUtils(page: Page) {
return { return {
waitForAuthSkipAppStart: () => waitForAuthAndLsp(page), waitForAuthSkipAppStart: () => waitForAuthAndLsp(page),
waitForPageLoad: () => waitForPageLoad(page), waitForPageLoad: () => waitForPageLoad(page),
waitForPageLoadWithRetry: () => waitForPageLoadWithRetry(page),
removeCurrentCode: () => removeCurrentCode(page), removeCurrentCode: () => removeCurrentCode(page),
sendCustomCmd: (cmd: EngineCommand) => sendCustomCmd(page, cmd), sendCustomCmd: (cmd: EngineCommand) => sendCustomCmd(page, cmd),
updateCamPosition: async (xyz: [number, number, number]) => { updateCamPosition: async (xyz: [number, number, number]) => {
@ -266,7 +287,7 @@ export async function getUtils(page: Page) {
getSegmentBodyCoords: async (locator: string, px = 30) => { getSegmentBodyCoords: async (locator: string, px = 30) => {
const overlay = page.locator(locator) const overlay = page.locator(locator)
const bbox = await overlay const bbox = await overlay
.boundingBox() .boundingBox({ timeout: 5000 })
.then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 })) .then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 }))
const angle = Number(await overlay.getAttribute('data-overlay-angle')) const angle = Number(await overlay.getAttribute('data-overlay-angle'))
const angleXOffset = Math.cos(((angle - 180) * Math.PI) / 180) * px const angleXOffset = Math.cos(((angle - 180) * Math.PI) / 180) * px

12
flake.lock generated
View File

@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1718470082, "lastModified": 1721933792,
"narHash": "sha256-u2F0MMYE+Efc+ocruTbtU/wWHuYHWcJafp5zJ++n/YE=", "narHash": "sha256-zYVwABlQnxpbaHMfX6Wt9jhyQstFYwN2XjleOJV3VVg=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "3027ba73dfef68eb555fc2fa97aed4e999e74f97", "rev": "2122a9b35b35719ad9a395fe783eabb092df01b1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -43,11 +43,11 @@
"nixpkgs": "nixpkgs_2" "nixpkgs": "nixpkgs_2"
}, },
"locked": { "locked": {
"lastModified": 1718681902, "lastModified": 1721960387,
"narHash": "sha256-E/T7Ge6ayEQe7FVKMJqDBoHyLhRhjc6u9CmU8MyYfy0=", "narHash": "sha256-o21ax+745ETGXrcgc/yUuLw1SI77ymp3xEpJt+w/kks=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "16c8ad83297c278eebe740dea5491c1708960dd1", "rev": "9cbf831c5b20a53354fc12758abd05966f9f1699",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -57,6 +57,7 @@
pkg-config pkg-config
nodejs_22 nodejs_22
yarn
]) ++ pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs; [ ]) ++ pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs; [
libiconv libiconv
darwin.apple_sdk.frameworks.Security darwin.apple_sdk.frameworks.Security

1983
openapi/machine-api.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "untitled-app", "name": "untitled-app",
"version": "0.24.4", "version": "0.24.8",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.17.0", "@codemirror/autocomplete": "^6.17.0",
@ -87,7 +87,8 @@
"bump-jsons": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json && echo \"$(jq --arg v \"$VERSION\" '.version=$v' src-tauri/tauri.conf.json --indent 2)\" > src-tauri/tauri.conf.json", "bump-jsons": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json && echo \"$(jq --arg v \"$VERSION\" '.version=$v' src-tauri/tauri.conf.json --indent 2)\" > src-tauri/tauri.conf.json",
"postinstall": "yarn xstate:typegen", "postinstall": "yarn xstate:typegen",
"xstate:typegen": "yarn xstate typegen \"src/**/*.ts?(x)\"", "xstate:typegen": "yarn xstate typegen \"src/**/*.ts?(x)\"",
"make:dev": "make dev" "make:dev": "make dev",
"generate:machine-api": "npx openapi-typescript ./openapi/machine-api.json -o src/lib/machine-api.d.ts"
}, },
"prettier": { "prettier": {
"trailingComma": "es5", "trailingComma": "es5",
@ -116,6 +117,7 @@
"@tauri-apps/cli": "==2.0.0-beta.13", "@tauri-apps/cli": "==2.0.0-beta.13",
"@testing-library/jest-dom": "^5.14.1", "@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^15.0.2", "@testing-library/react": "^15.0.2",
"@types/d3-force": "^3.0.10",
"@types/mocha": "^10.0.6", "@types/mocha": "^10.0.6",
"@types/node": "^18.19.31", "@types/node": "^18.19.31",
"@types/pixelmatch": "^5.2.6", "@types/pixelmatch": "^5.2.6",
@ -138,6 +140,7 @@
"@wdio/spec-reporter": "^8.36.0", "@wdio/spec-reporter": "^8.36.0",
"@xstate/cli": "^0.5.17", "@xstate/cli": "^0.5.17",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"d3-force": "^3.0.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-react-app": "^7.0.1", "eslint-config-react-app": "^7.0.1",
"eslint-plugin-css-modules": "^2.12.0", "eslint-plugin-css-modules": "^2.12.0",

View File

@ -1,12 +0,0 @@
import { Extension } from '@codemirror/state'
import { linter, forEachDiagnostic, Diagnostic } from '@codemirror/lint'
export default function lspLintExt(): Extension {
return linter((view) => {
let diagnostics: Diagnostic[] = []
forEachDiagnostic(view.state, (d: Diagnostic, from: number, to: number) => {
diagnostics.push(d)
})
return diagnostics
})
}

View File

@ -17,8 +17,8 @@ import type {
PluginSpec, PluginSpec,
ViewPlugin, ViewPlugin,
} from '@codemirror/view' } from '@codemirror/view'
import { setDiagnosticsEffect } from '@codemirror/lint'
import { EditorView, Tooltip } from '@codemirror/view' import { EditorView, Tooltip } from '@codemirror/view'
import { linter } from '@codemirror/lint'
import type { PublishDiagnosticsParams } from 'vscode-languageserver-protocol' import type { PublishDiagnosticsParams } from 'vscode-languageserver-protocol'
import type * as LSP from 'vscode-languageserver-protocol' import type * as LSP from 'vscode-languageserver-protocol'
@ -36,7 +36,6 @@ import lspAutocompleteExt from './autocomplete'
import lspHoverExt from './hover' import lspHoverExt from './hover'
import lspFormatExt from './format' import lspFormatExt from './format'
import lspIndentExt from './indent' import lspIndentExt from './indent'
import lspLintExt from './lint'
import lspSemanticTokensExt from './semantic-tokens' import lspSemanticTokensExt from './semantic-tokens'
const useLast = (values: readonly any[]) => values.reduce((_, v) => v, '') const useLast = (values: readonly any[]) => values.reduce((_, v) => v, '')
@ -216,20 +215,6 @@ export class LanguageServerPlugin implements PluginValue {
if (!this.client.ready) return if (!this.client.ready) return
// TODO(paultag): This is the *wrong* place for this to live.
//
// We need to clear diagnostics before updating the code, because
// if the code shrinks, the errors/diagnostics can go out of range
// of the source code, which cause an exception, breaking all the
// things.
//
// We need some sort of clear diagnostics boolean on the editor
// and we can drop this.
this.view.dispatch({
effects: [setDiagnosticsEffect.of([])],
annotations: [],
})
try { try {
// Update the state (not the editor) with the new code. // Update the state (not the editor) with the new code.
this.client.textDocumentDidChange({ this.client.textDocumentDidChange({
@ -587,8 +572,8 @@ export class LanguageServerPluginSpec
lspFormatExt(plugin), lspFormatExt(plugin),
lspHoverExt(plugin), lspHoverExt(plugin),
lspIndentExt(), lspIndentExt(),
lspLintExt(),
lspSemanticTokensExt(), lspSemanticTokensExt(),
linter(null),
] ]
} }
} }

View File

@ -18,11 +18,12 @@ export default defineConfig({
/* Do not retry */ /* Do not retry */
retries: process.env.CI ? 0 : 0, retries: process.env.CI ? 0 : 0,
/* Different amount of parallelism on CI and local. */ /* Different amount of parallelism on CI and local. */
workers: process.env.CI ? 4 : 4, workers: process.env.CI ? 1 : 4,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [ reporter: [
[process.env.CI ? 'dot' : 'list'], [process.env.CI ? 'dot' : 'list'],
['json', { outputFile: './test-results/report.json' }], ['json', { outputFile: './test-results/report.json' }],
['html'],
], ],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: { use: {

261
src-tauri/Cargo.lock generated
View File

@ -172,7 +172,9 @@ dependencies = [
"kcl-lib", "kcl-lib",
"kittycad", "kittycad",
"log", "log",
"mdns-sd",
"oauth2", "oauth2",
"reqwest 0.12.4",
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-build", "tauri-build",
@ -188,7 +190,7 @@ dependencies = [
"tauri-plugin-shell", "tauri-plugin-shell",
"tauri-plugin-updater", "tauri-plugin-updater",
"tokio", "tokio",
"toml 0.8.14", "toml 0.8.19",
"url", "url",
] ]
@ -286,7 +288,7 @@ dependencies = [
"futures-io", "futures-io",
"futures-lite", "futures-lite",
"parking", "parking",
"polling", "polling 3.7.0",
"rustix", "rustix",
"slab", "slab",
"tracing", "tracing",
@ -332,7 +334,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -367,7 +369,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -407,7 +409,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -550,7 +552,7 @@ dependencies = [
"proc-macro-crate 3.1.0", "proc-macro-crate 3.1.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
"syn_derive", "syn_derive",
] ]
@ -648,6 +650,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "byteorder-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.6.0" version = "1.6.0"
@ -721,7 +729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719"
dependencies = [ dependencies = [
"serde", "serde",
"toml 0.8.14", "toml 0.8.19",
] ]
[[package]] [[package]]
@ -792,9 +800,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.9" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -802,9 +810,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.9" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -816,14 +824,14 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.8" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1073,7 +1081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1083,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1107,7 +1115,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim 0.10.0", "strsim 0.10.0",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1118,7 +1126,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1179,7 +1187,7 @@ checksum = "4078275de501a61ceb9e759d37bdd3d7210e654dbc167ac1a3678ef4435ed57b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
"synstructure", "synstructure",
] ]
@ -1206,7 +1214,7 @@ dependencies = [
[[package]] [[package]]
name = "derive-docs" name = "derive-docs"
version = "0.1.20" version = "0.1.21"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"convert_case 0.6.0", "convert_case 0.6.0",
@ -1216,7 +1224,7 @@ dependencies = [
"regex", "regex",
"serde", "serde",
"serde_tokenstream", "serde_tokenstream",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1227,7 +1235,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1288,7 +1296,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1320,7 +1328,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1383,7 +1391,7 @@ dependencies = [
"cc", "cc",
"memchr", "memchr",
"rustc_version", "rustc_version",
"toml 0.8.14", "toml 0.8.19",
"vswhom", "vswhom",
"winreg 0.52.0", "winreg 0.52.0",
] ]
@ -1427,7 +1435,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1564,6 +1572,17 @@ dependencies = [
"miniz_oxide", "miniz_oxide",
] ]
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"futures-core",
"futures-sink",
"spin",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -1588,7 +1607,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1704,7 +1723,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -1980,7 +1999,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -2008,7 +2027,7 @@ dependencies = [
"inflections", "inflections",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -2083,7 +2102,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -2399,6 +2418,28 @@ dependencies = [
"unicode-normalization", "unicode-normalization",
] ]
[[package]]
name = "if-addrs"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a"
dependencies = [
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "image"
version = "0.25.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
dependencies = [
"bytemuck",
"byteorder-lite",
"num-traits",
"png",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.3" version = "1.9.3"
@ -2571,7 +2612,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-lib" name = "kcl-lib"
version = "0.2.0" version = "0.2.3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"approx", "approx",
@ -2581,6 +2622,7 @@ dependencies = [
"bson", "bson",
"chrono", "chrono",
"clap", "clap",
"convert_case 0.6.0",
"dashmap 6.0.1", "dashmap 6.0.1",
"databake", "databake",
"derive-docs", "derive-docs",
@ -2588,6 +2630,7 @@ dependencies = [
"futures", "futures",
"git_rev", "git_rev",
"gltf-json", "gltf-json",
"image",
"js-sys", "js-sys",
"kittycad", "kittycad",
"lazy_static", "lazy_static",
@ -2602,10 +2645,11 @@ dependencies = [
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-tungstenite", "tokio-tungstenite",
"toml 0.8.14", "toml 0.8.19",
"tower-lsp", "tower-lsp",
"ts-rs", "ts-rs",
"url", "url",
"urlencoding",
"uuid", "uuid",
"validator", "validator",
"wasm-bindgen", "wasm-bindgen",
@ -2628,9 +2672,9 @@ dependencies = [
[[package]] [[package]]
name = "kittycad" name = "kittycad"
version = "0.3.7" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1777b503442fa4666564cc3ab237d456df853a09648a4b2bb09622d25d021a5" checksum = "36b87a9cca545825ba18005c1944b8525fac28867d99984178bf22c79fb5ec25"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -2875,6 +2919,19 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "mdns-sd"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "807457e493076539ff8f202806f9dc2eaa9f13f69701da7ed38eec7a9afd1616"
dependencies = [
"flume",
"if-addrs",
"log",
"polling 2.8.0",
"socket2",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.2" version = "2.7.2"
@ -3368,7 +3425,7 @@ dependencies = [
"regex", "regex",
"regex-syntax 0.8.3", "regex-syntax 0.8.3",
"structmeta", "structmeta",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -3487,7 +3544,7 @@ dependencies = [
"phf_shared 0.11.2", "phf_shared 0.11.2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -3519,9 +3576,9 @@ dependencies = [
[[package]] [[package]]
name = "phonenumber" name = "phonenumber"
version = "0.3.5+8.13.36" version = "0.3.6+8.13.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f174c8db59b620032bd52b655fc97000458850fec0db35fcd4e802b668517ec0" checksum = "11756237b57b8cc5e97dc8b1e70ea436324d30e7075de63b14fd15073a8f692a"
dependencies = [ dependencies = [
"bincode", "bincode",
"either", "either",
@ -3555,7 +3612,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -3614,6 +3671,22 @@ dependencies = [
"miniz_oxide", "miniz_oxide",
] ]
[[package]]
name = "polling"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
dependencies = [
"autocfg",
"bitflags 1.3.2",
"cfg-if",
"concurrent-queue",
"libc",
"log",
"pin-project-lite",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "polling" name = "polling"
version = "3.7.0" version = "3.7.0"
@ -4429,7 +4502,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde_derive_internals", "serde_derive_internals",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4549,7 +4622,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4560,17 +4633,18 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.120" version = "1.0.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
dependencies = [ dependencies = [
"indexmap 2.2.6", "indexmap 2.2.6",
"itoa 1.0.11", "itoa 1.0.11",
"memchr",
"ryu", "ryu",
"serde", "serde",
] ]
@ -4593,14 +4667,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
name = "serde_spanned" name = "serde_spanned"
version = "0.6.6" version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -4614,7 +4688,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4656,7 +4730,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4849,6 +4923,9 @@ name = "spin"
version = "0.9.8" version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
@ -4924,7 +5001,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"structmeta-derive", "structmeta-derive",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4935,7 +5012,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4957,7 +5034,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion", "rustversion",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -4990,9 +5067,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.71" version = "2.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -5008,7 +5085,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -5025,7 +5102,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -5067,7 +5144,7 @@ dependencies = [
"cfg-expr", "cfg-expr",
"heck 0.5.0", "heck 0.5.0",
"pkg-config", "pkg-config",
"toml 0.8.14", "toml 0.8.19",
"version-compare", "version-compare",
] ]
@ -5220,7 +5297,7 @@ dependencies = [
"serde_json", "serde_json",
"tauri-utils", "tauri-utils",
"tauri-winres", "tauri-winres",
"toml 0.8.14", "toml 0.8.19",
"walkdir", "walkdir",
] ]
@ -5242,7 +5319,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
"syn 2.0.71", "syn 2.0.72",
"tauri-utils", "tauri-utils",
"thiserror", "thiserror",
"time", "time",
@ -5260,7 +5337,7 @@ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
"tauri-codegen", "tauri-codegen",
"tauri-utils", "tauri-utils",
] ]
@ -5278,7 +5355,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"tauri-utils", "tauri-utils",
"toml 0.8.14", "toml 0.8.19",
"walkdir", "walkdir",
] ]
@ -5562,7 +5639,7 @@ dependencies = [
"serde_with", "serde_with",
"swift-rs", "swift-rs",
"thiserror", "thiserror",
"toml 0.8.14", "toml 0.8.19",
"url", "url",
"urlpattern", "urlpattern",
"walkdir", "walkdir",
@ -5618,22 +5695,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.62" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.62" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -5730,7 +5807,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -5809,21 +5886,21 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.8.14" version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_edit 0.22.14", "toml_edit 0.22.20",
] ]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.6" version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -5865,15 +5942,15 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.14" version = "0.22.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
dependencies = [ dependencies = [
"indexmap 2.2.6", "indexmap 2.2.6",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"winnow 0.6.6", "winnow 0.6.18",
] ]
[[package]] [[package]]
@ -5930,7 +6007,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -5959,7 +6036,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -6089,7 +6166,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
"termcolor", "termcolor",
] ]
@ -6237,6 +6314,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]] [[package]]
name = "urlpattern" name = "urlpattern"
version = "0.2.0" version = "0.2.0"
@ -6306,7 +6389,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -6405,7 +6488,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -6439,7 +6522,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -6580,7 +6663,7 @@ checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -6686,7 +6769,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -6697,7 +6780,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]
@ -6944,9 +7027,9 @@ dependencies = [
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.6" version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -7149,7 +7232,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.71", "syn 2.0.72",
] ]
[[package]] [[package]]

View File

@ -18,7 +18,9 @@ anyhow = "1"
kcl-lib = { version = "0.2", path = "../src/wasm-lib/kcl" } kcl-lib = { version = "0.2", path = "../src/wasm-lib/kcl" }
kittycad = "0.3.7" kittycad = "0.3.7"
log = "0.4.21" log = "0.4.21"
mdns-sd = "0.11.1"
oauth2 = "4.4.2" oauth2 = "4.4.2"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
serde_json = "1.0" serde_json = "1.0"
tauri = { version = "2.0.0-beta.23", features = [ "devtools", "unstable"] } tauri = { version = "2.0.0-beta.23", features = [ "devtools", "unstable"] }
tauri-plugin-cli = { version = "2.0.0-beta.7" } tauri-plugin-cli = { version = "2.0.0-beta.7" }

View File

@ -370,6 +370,70 @@ fn show_in_folder(app: tauri::AppHandle, path: &str) -> Result<(), InvokeError>
Ok(()) Ok(())
} }
const SERVICE_NAME: &str = "_machine-api._tcp.local.";
async fn find_machine_api() -> Result<Option<String>> {
println!("Looking for machine API...");
// Timeout if no response is received after 5 seconds.
let timeout_duration = std::time::Duration::from_secs(5);
let mdns = mdns_sd::ServiceDaemon::new()?;
// Browse for a service type.
let receiver = mdns.browse(SERVICE_NAME)?;
let resp = tokio::time::timeout(
timeout_duration,
tokio::spawn(async move {
while let Ok(event) = receiver.recv() {
if let mdns_sd::ServiceEvent::ServiceResolved(info) = event {
if let Some(addr) = info.get_addresses().iter().next() {
return Some(format!("{}:{}", addr, info.get_port()));
}
}
}
None
}),
)
.await;
// Shut down.
mdns.shutdown()?;
let Ok(Ok(Some(addr))) = resp else {
return Ok(None);
};
Ok(Some(addr))
}
#[tauri::command]
async fn get_machine_api_ip() -> Result<Option<String>, InvokeError> {
let machine_api = find_machine_api().await.map_err(InvokeError::from_anyhow)?;
Ok(machine_api)
}
#[tauri::command]
async fn list_machines() -> Result<String, InvokeError> {
let machine_api = find_machine_api().await.map_err(InvokeError::from_anyhow)?;
let Some(machine_api) = machine_api else {
// Empty array.
return Ok("[]".to_string());
};
let client = reqwest::Client::new();
let response = client
.get(format!("http://{}/machines", machine_api))
.send()
.await
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
let text = response.text().await.map_err(|e| InvokeError::from_anyhow(e.into()))?;
Ok(text)
}
#[allow(dead_code)] #[allow(dead_code)]
fn open_url_sync(app: &tauri::AppHandle, url: &url::Url) { fn open_url_sync(app: &tauri::AppHandle, url: &url::Url) {
log::debug!("Opening URL: {:?}", url); log::debug!("Opening URL: {:?}", url);
@ -417,6 +481,8 @@ fn main() -> Result<()> {
read_project_settings_file, read_project_settings_file,
write_project_settings_file, write_project_settings_file,
rename_project_directory, rename_project_directory,
get_machine_api_ip,
list_machines
]) ])
.plugin(tauri_plugin_cli::init()) .plugin(tauri_plugin_cli::init())
.plugin(tauri_plugin_deep_link::init()) .plugin(tauri_plugin_deep_link::init())

View File

@ -80,5 +80,5 @@
} }
}, },
"productName": "Zoo Modeling App", "productName": "Zoo Modeling App",
"version": "0.24.4" "version": "0.24.8"
} }

View File

@ -2,7 +2,7 @@ import { MouseEventHandler, useEffect, useMemo, useRef } from 'react'
import { uuidv4 } from 'lib/utils' import { uuidv4 } from 'lib/utils'
import { useHotKeyListener } from './hooks/useHotKeyListener' import { useHotKeyListener } from './hooks/useHotKeyListener'
import { Stream } from './components/Stream' import { Stream } from './components/Stream'
import { EngineCommand } from 'lang/std/artifactMap' import { EngineCommand } from 'lang/std/artifactGraph'
import { throttle } from './lib/utils' import { throttle } from './lib/utils'
import { AppHeader } from './components/AppHeader' import { AppHeader } from './components/AppHeader'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
@ -95,16 +95,16 @@ export function App() {
}) })
const newCmdId = uuidv4() const newCmdId = uuidv4()
if (context.store?.buttonDownInStream === undefined) { if (state.matches('idle.showPlanes')) return
debounceSocketSend({ if (context.store?.buttonDownInStream !== undefined) return
type: 'modeling_cmd_req', debounceSocketSend({
cmd: { type: 'modeling_cmd_req',
type: 'highlight_set_entity', cmd: {
selected_at_window: { x, y }, type: 'highlight_set_entity',
}, selected_at_window: { x, y },
cmd_id: newCmdId, },
}) cmd_id: newCmdId,
} })
} }
return ( return (

View File

@ -40,10 +40,10 @@ export function Toolbar({
return false return false
} }
return isCursorInSketchCommandRange( return isCursorInSketchCommandRange(
engineCommandManager.artifactMap, engineCommandManager.artifactGraph,
context.selectionRanges context.selectionRanges
) )
}, [engineCommandManager.artifactMap, context.selectionRanges]) }, [engineCommandManager.artifactGraph, context.selectionRanges])
const toolbarButtonsRef = useRef<HTMLUListElement>(null) const toolbarButtonsRef = useRef<HTMLUListElement>(null)
const { overallState } = useNetworkContext() const { overallState } = useNetworkContext()
@ -190,49 +190,59 @@ export function Toolbar({
maybeIconConfig[0].onClick(configCallbackProps) maybeIconConfig[0].onClick(configCallbackProps)
} }
> >
<ToolbarItemContents <span
itemConfig={maybeIconConfig[0]} className={!maybeIconConfig[0].showTitle ? 'sr-only' : ''}
configCallbackProps={configCallbackProps} >
/> {maybeIconConfig[0].title}
</span>
</ActionButton> </ActionButton>
<ToolbarItemTooltip
itemConfig={maybeIconConfig[0]}
configCallbackProps={configCallbackProps}
/>
</ActionButtonDropdown> </ActionButtonDropdown>
) )
} }
const itemConfig = maybeIconConfig const itemConfig = maybeIconConfig
return ( return (
<ActionButton <div className="relative" key={itemConfig.id}>
Element="button" <ActionButton
key={itemConfig.id} Element="button"
id={itemConfig.id} key={itemConfig.id}
data-testid={itemConfig.id} id={itemConfig.id}
iconStart={{ data-testid={itemConfig.id}
icon: itemConfig.icon, iconStart={{
className: iconClassName, icon: itemConfig.icon,
bgClassName: bgClassName, className: iconClassName,
}} bgClassName: bgClassName,
className={ }}
'pressed:!text-chalkboard-10 pressed:enabled:hovered:!text-chalkboard-10 ' + className={
buttonBorderClassName + 'pressed:!text-chalkboard-10 pressed:enabled:hovered:!text-chalkboard-10 ' +
' ' + buttonBorderClassName +
buttonBgClassName + ' ' +
(!itemConfig.showTitle ? ' !px-0' : '') buttonBgClassName +
} (!itemConfig.showTitle ? ' !px-0' : '')
name={itemConfig.title} }
aria-description={itemConfig.description} name={itemConfig.title}
aria-pressed={itemConfig.isActive} aria-description={itemConfig.description}
disabled={ aria-pressed={itemConfig.isActive}
disableAllButtons || disabled={
itemConfig.status !== 'available' || disableAllButtons ||
itemConfig.disabled itemConfig.status !== 'available' ||
} itemConfig.disabled
onClick={() => itemConfig.onClick(configCallbackProps)} }
> onClick={() => itemConfig.onClick(configCallbackProps)}
<ToolbarItemContents >
<span className={!itemConfig.showTitle ? 'sr-only' : ''}>
{itemConfig.title}
</span>
</ActionButton>
<ToolbarItemTooltip
itemConfig={itemConfig} itemConfig={itemConfig}
configCallbackProps={configCallbackProps} configCallbackProps={configCallbackProps}
/> />
</ActionButton> </div>
) )
})} })}
</ul> </ul>
@ -250,7 +260,7 @@ export function Toolbar({
* It contains a tooltip with the title, description, and links * It contains a tooltip with the title, description, and links
* and a hotkey listener * and a hotkey listener
*/ */
const ToolbarItemContents = memo(function ToolbarItemContents({ const ToolbarItemTooltip = memo(function ToolbarItemContents({
itemConfig, itemConfig,
configCallbackProps, configCallbackProps,
}: { }: {
@ -272,73 +282,69 @@ const ToolbarItemContents = memo(function ToolbarItemContents({
) )
return ( return (
<> <Tooltip
<span className={!itemConfig.showTitle ? 'sr-only' : ''}> inert={false}
{itemConfig.title} position="bottom"
</span> wrapperClassName="!p-4 !pointer-events-auto"
<Tooltip contentClassName="!text-left text-wrap !text-xs !p-0 !pb-2 flex gap-2 !max-w-none !w-72 flex-col items-stretch"
position="bottom" >
wrapperClassName="!p-4 !pointer-events-auto" <div className="rounded-top flex items-center gap-2 pt-3 pb-2 px-2 bg-chalkboard-20/50 dark:bg-chalkboard-80/50">
contentClassName="!text-left text-wrap !text-xs !p-0 !pb-2 flex gap-2 !max-w-none !w-72 flex-col items-stretch" <span
> className={`text-sm flex-1 ${
<div className="rounded-top flex items-center gap-2 pt-3 pb-2 px-2 bg-chalkboard-20/50 dark:bg-chalkboard-80/50"> itemConfig.status !== 'available'
<span ? 'text-chalkboard-70 dark:text-chalkboard-40'
className={`text-sm flex-1 ${ : ''
itemConfig.status !== 'available' }`}
? 'text-chalkboard-70 dark:text-chalkboard-40' >
: '' {itemConfig.title}
}`} </span>
> {itemConfig.status === 'available' && itemConfig.hotkey ? (
{itemConfig.title} <kbd className="flex-none hotkey">{itemConfig.hotkey}</kbd>
</span> ) : itemConfig.status === 'kcl-only' ? (
{itemConfig.status === 'available' && itemConfig.hotkey ? ( <>
<kbd className="flex-none hotkey">{itemConfig.hotkey}</kbd> <span className="text-wrap font-sans flex-0 text-chalkboard-70 dark:text-chalkboard-40">
) : itemConfig.status === 'kcl-only' ? ( KCL code only
</span>
<CustomIcon
name="code"
className="w-5 h-5 text-chalkboard-70 dark:text-chalkboard-40"
/>
</>
) : (
itemConfig.status === 'unavailable' && (
<> <>
<span className="text-wrap font-sans flex-0 text-chalkboard-70 dark:text-chalkboard-40"> <span className="text-wrap font-sans flex-0 text-chalkboard-70 dark:text-chalkboard-40">
KCL code only In development
</span> </span>
<CustomIcon <CustomIcon
name="code" name="lockClosed"
className="w-5 h-5 text-chalkboard-70 dark:text-chalkboard-40" className="w-5 h-5 text-chalkboard-70 dark:text-chalkboard-40"
/> />
</> </>
) : ( )
itemConfig.status === 'unavailable' && (
<>
<span className="text-wrap font-sans flex-0 text-chalkboard-70 dark:text-chalkboard-40">
In development
</span>
<CustomIcon
name="lockClosed"
className="w-5 h-5 text-chalkboard-70 dark:text-chalkboard-40"
/>
</>
)
)}
</div>
<p className="px-2 text-ch font-sans">{itemConfig.description}</p>
{itemConfig.links.length > 0 && (
<>
<hr className="border-chalkboard-20 dark:border-chalkboard-80" />
<ul className="p-0 px-1 m-0 flex flex-col">
{itemConfig.links.map((link) => (
<li key={link.label} className="contents">
<a
href={link.url}
target="_blank"
rel="noreferrer"
className="flex items-center rounded-sm p-1 no-underline text-inherit hover:bg-primary/10 hover:text-primary dark:hover:bg-chalkboard-70 dark:hover:text-inherit"
>
<span className="flex-1">Open {link.label}</span>
<CustomIcon name="link" className="w-4 h-4" />
</a>
</li>
))}
</ul>
</>
)} )}
</Tooltip> </div>
</> <p className="px-2 text-ch font-sans">{itemConfig.description}</p>
{itemConfig.links.length > 0 && (
<>
<hr className="border-chalkboard-20 dark:border-chalkboard-80" />
<ul className="p-0 px-1 m-0 flex flex-col">
{itemConfig.links.map((link) => (
<li key={link.label} className="contents">
<a
href={link.url}
target="_blank"
rel="noreferrer"
className="flex items-center rounded-sm p-1 no-underline text-inherit hover:bg-primary/10 hover:text-primary dark:hover:bg-chalkboard-70 dark:hover:text-inherit"
>
<span className="flex-1">Open {link.label}</span>
<CustomIcon name="link" className="w-4 h-4" />
</a>
</li>
))}
</ul>
</>
)}
</Tooltip>
) )
}) })

View File

@ -21,7 +21,7 @@ import {
EngineCommandManager, EngineCommandManager,
UnreliableSubscription, UnreliableSubscription,
} from 'lang/std/engineConnection' } from 'lang/std/engineConnection'
import { EngineCommand } from 'lang/std/artifactMap' import { EngineCommand } from 'lang/std/artifactGraph'
import { uuidv4 } from 'lib/utils' import { uuidv4 } from 'lib/utils'
import { deg2Rad } from 'lib/utils2d' import { deg2Rad } from 'lib/utils2d'
import { isReducedMotion, roundOff, throttle } from 'lib/utils' import { isReducedMotion, roundOff, throttle } from 'lib/utils'

View File

@ -102,6 +102,7 @@ export const ClientSideScene = ({
canvas.addEventListener('mousedown', sceneInfra.onMouseDown, false) canvas.addEventListener('mousedown', sceneInfra.onMouseDown, false)
canvas.addEventListener('mouseup', sceneInfra.onMouseUp, false) canvas.addEventListener('mouseup', sceneInfra.onMouseUp, false)
sceneInfra.setSend(send) sceneInfra.setSend(send)
engineCommandManager.modelingSend = send
return () => { return () => {
canvas?.removeEventListener('mousemove', sceneInfra.onMouseMove) canvas?.removeEventListener('mousemove', sceneInfra.onMouseMove)
canvas?.removeEventListener('mousedown', sceneInfra.onMouseDown) canvas?.removeEventListener('mousedown', sceneInfra.onMouseDown)
@ -574,10 +575,10 @@ const ConstraintSymbol = ({
: 'bg-primary/30 dark:bg-primary text-primary dark:text-chalkboard-10 dark:border-transparent group-hover:bg-primary/40 group-hover:border-primary/50 group-hover:brightness-125' : 'bg-primary/30 dark:bg-primary text-primary dark:text-chalkboard-10 dark:border-transparent group-hover:bg-primary/40 group-hover:border-primary/50 group-hover:brightness-125'
} h-[26px] w-[26px] rounded-sm relative m-0 p-0`} } h-[26px] w-[26px] rounded-sm relative m-0 p-0`}
onMouseEnter={() => { onMouseEnter={() => {
editorManager.setHighlightRange(range) editorManager.setHighlightRange([range])
}} }}
onMouseLeave={() => { onMouseLeave={() => {
editorManager.setHighlightRange([0, 0]) editorManager.setHighlightRange([[0, 0]])
}} }}
// disabled={isConstrained || !convertToVarEnabled} // disabled={isConstrained || !convertToVarEnabled}
// disabled={implicitDesc} TODO why does this change styles that are hard to override? // disabled={implicitDesc} TODO why does this change styles that are hard to override?

View File

@ -22,11 +22,9 @@ import {
import { import {
ARROWHEAD, ARROWHEAD,
AXIS_GROUP, AXIS_GROUP,
DEFAULT_PLANES,
DefaultPlane,
defaultPlaneColor,
getSceneScale, getSceneScale,
INTERSECTION_PLANE_LAYER, INTERSECTION_PLANE_LAYER,
OnClickCallbackArgs,
OnMouseEnterLeaveArgs, OnMouseEnterLeaveArgs,
RAYCASTABLE_PLANE, RAYCASTABLE_PLANE,
SEGMENT_LENGTH_LABEL, SEGMENT_LENGTH_LABEL,
@ -78,6 +76,7 @@ import {
} from 'lang/std/sketch' } from 'lang/std/sketch'
import { isOverlap, normaliseAngle, roundOff, throttle } from 'lib/utils' import { isOverlap, normaliseAngle, roundOff, throttle } from 'lib/utils'
import { import {
addStartProfileAt,
createArrayExpression, createArrayExpression,
createCallExpressionStdLib, createCallExpressionStdLib,
createLiteral, createLiteral,
@ -85,11 +84,7 @@ import {
createPipeSubstitution, createPipeSubstitution,
findUniqueName, findUniqueName,
} from 'lang/modifyAst' } from 'lang/modifyAst'
import { import { Selections, getEventForSegmentSelection } from 'lib/selections'
Selections,
getEventForSegmentSelection,
sendSelectEventToEngine,
} from 'lib/selections'
import { getTangentPointFromPreviousArc } from 'lib/utils2d' import { getTangentPointFromPreviousArc } from 'lib/utils2d'
import { createGridHelper, orthoScale, perspScale } from './helpers' import { createGridHelper, orthoScale, perspScale } from './helpers'
import { Models } from '@kittycad/lib' import { Models } from '@kittycad/lib'
@ -200,6 +195,7 @@ export class SceneEntities {
createIntersectionPlane() { createIntersectionPlane() {
if (sceneInfra.scene.getObjectByName(RAYCASTABLE_PLANE)) { if (sceneInfra.scene.getObjectByName(RAYCASTABLE_PLANE)) {
// this.removeIntersectionPlane()
console.warn('createIntersectionPlane called when it already exists') console.warn('createIntersectionPlane called when it already exists')
return return
} }
@ -296,6 +292,51 @@ export class SceneEntities {
if (intersectionPlane) this.scene.remove(intersectionPlane) if (intersectionPlane) this.scene.remove(intersectionPlane)
} }
setupNoPointsListener({
sketchDetails,
afterClick,
}: {
sketchDetails: SketchDetails
afterClick: (args: OnClickCallbackArgs) => void
}) {
// Create a THREEjs plane to raycast clicks onto
this.createIntersectionPlane()
const quaternion = quaternionFromUpNForward(
new Vector3(...sketchDetails.yAxis),
new Vector3(...sketchDetails.zAxis)
)
// Position the click raycast plane
if (this.intersectionPlane) {
this.intersectionPlane.setRotationFromQuaternion(quaternion)
this.intersectionPlane.position.copy(
new Vector3(...(sketchDetails?.origin || [0, 0, 0]))
)
}
sceneInfra.setCallbacks({
onClick: async (args) => {
if (!args) return
if (args.mouseEvent.which !== 1) return
const { intersectionPoint } = args
if (!intersectionPoint?.twoD || !sketchDetails?.sketchPathToNode) return
const addStartProfileAtRes = addStartProfileAt(
kclManager.ast,
sketchDetails.sketchPathToNode,
[intersectionPoint.twoD.x, intersectionPoint.twoD.y]
)
if (trap(addStartProfileAtRes)) return
const { modifiedAst } = addStartProfileAtRes
await kclManager.updateAst(modifiedAst, false)
this.removeIntersectionPlane()
// Now perform the caller-specified action
afterClick(args)
},
})
}
async setupSketch({ async setupSketch({
sketchPathToNode, sketchPathToNode,
forward, forward,
@ -672,21 +713,6 @@ export class SceneEntities {
...this.mouseEnterLeaveCallbacks(), ...this.mouseEnterLeaveCallbacks(),
}) })
} }
setupRectangleOriginListener = () => {
sceneInfra.setCallbacks({
onClick: (args) => {
const twoD = args.intersectionPoint?.twoD
if (!twoD) {
console.warn(`This click didn't have a 2D intersection`, args)
return
}
sceneInfra.modelingSend({
type: 'Add rectangle origin',
data: [twoD.x, twoD.y],
})
},
})
}
setupDraftRectangle = async ( setupDraftRectangle = async (
sketchPathToNode: PathToNode, sketchPathToNode: PathToNode,
forward: [number, number, number], forward: [number, number, number],
@ -704,6 +730,8 @@ export class SceneEntities {
if (trap(_node1)) return Promise.reject(_node1) if (trap(_node1)) return Promise.reject(_node1)
const variableDeclarationName = const variableDeclarationName =
_node1.node?.declarations?.[0]?.id?.name || '' _node1.node?.declarations?.[0]?.id?.name || ''
const startSketchOn = _node1.node?.declarations
const startSketchOnInit = startSketchOn?.[0]?.init
const tags: [string, string, string] = [ const tags: [string, string, string] = [
findUniqueName(_ast, 'rectangleSegmentA'), findUniqueName(_ast, 'rectangleSegmentA'),
@ -711,15 +739,6 @@ export class SceneEntities {
findUniqueName(_ast, 'rectangleSegmentC'), findUniqueName(_ast, 'rectangleSegmentC'),
] ]
const _node2 = getNodeFromPath<VariableDeclaration>(
_ast,
sketchPathToNode || [],
'VariableDeclaration'
)
if (trap(_node2)) return Promise.reject(_node2)
const startSketchOn = _node2.node?.declarations
const startSketchOnInit = startSketchOn?.[0]?.init
startSketchOn[0].init = createPipeExpression([ startSketchOn[0].init = createPipeExpression([
startSketchOnInit, startSketchOnInit,
...getRectangleCallExpressions(rectangleOrigin, tags), ...getRectangleCallExpressions(rectangleOrigin, tags),
@ -1477,146 +1496,6 @@ export class SceneEntities {
this._tearDownSketch(0, resolve, reject, { removeAxis }) this._tearDownSketch(0, resolve, reject, { removeAxis })
}) })
} }
setupDefaultPlaneHover() {
sceneInfra.setCallbacks({
onMouseEnter: ({ selected }) => {
if (!(selected instanceof Mesh && selected.parent)) return
if (selected.parent.userData.type !== DEFAULT_PLANES) return
const type: DefaultPlane = selected.userData.type
selected.material.color = defaultPlaneColor(type, 0.5, 1)
},
onMouseLeave: ({ selected }) => {
if (!(selected instanceof Mesh && selected.parent)) return
if (selected.parent.userData.type !== DEFAULT_PLANES) return
const type: DefaultPlane = selected.userData.type
selected.material.color = defaultPlaneColor(type)
},
onClick: async (args) => {
const { entity_id } = await sendSelectEventToEngine(
args?.mouseEvent,
document.getElementById('video-stream') as HTMLVideoElement,
sceneInfra._streamDimensions
)
let _entity_id = entity_id
if (!_entity_id) return
if (
engineCommandManager.defaultPlanes?.xy === _entity_id ||
engineCommandManager.defaultPlanes?.xz === _entity_id ||
engineCommandManager.defaultPlanes?.yz === _entity_id ||
engineCommandManager.defaultPlanes?.negXy === _entity_id ||
engineCommandManager.defaultPlanes?.negXz === _entity_id ||
engineCommandManager.defaultPlanes?.negYz === _entity_id
) {
const defaultPlaneStrMap: Record<string, DefaultPlaneStr> = {
[engineCommandManager.defaultPlanes.xy]: 'XY',
[engineCommandManager.defaultPlanes.xz]: 'XZ',
[engineCommandManager.defaultPlanes.yz]: 'YZ',
[engineCommandManager.defaultPlanes.negXy]: '-XY',
[engineCommandManager.defaultPlanes.negXz]: '-XZ',
[engineCommandManager.defaultPlanes.negYz]: '-YZ',
}
// TODO can we get this information from rust land when it creates the default planes?
// maybe returned from make_default_planes (src/wasm-lib/src/wasm.rs)
let zAxis: [number, number, number] = [0, 0, 1]
let yAxis: [number, number, number] = [0, 1, 0]
// get unit vector from camera position to target
const camVector = sceneInfra.camControls.camera.position
.clone()
.sub(sceneInfra.camControls.target)
if (engineCommandManager.defaultPlanes?.xy === _entity_id) {
zAxis = [0, 0, 1]
yAxis = [0, 1, 0]
if (camVector.z < 0) {
zAxis = [0, 0, -1]
_entity_id = engineCommandManager.defaultPlanes?.negXy || ''
}
} else if (engineCommandManager.defaultPlanes?.yz === _entity_id) {
zAxis = [1, 0, 0]
yAxis = [0, 0, 1]
if (camVector.x < 0) {
zAxis = [-1, 0, 0]
_entity_id = engineCommandManager.defaultPlanes?.negYz || ''
}
} else if (engineCommandManager.defaultPlanes?.xz === _entity_id) {
zAxis = [0, 1, 0]
yAxis = [0, 0, 1]
_entity_id = engineCommandManager.defaultPlanes?.negXz || ''
if (camVector.y < 0) {
zAxis = [0, -1, 0]
_entity_id = engineCommandManager.defaultPlanes?.xz || ''
}
}
sceneInfra.modelingSend({
type: 'Select default plane',
data: {
type: 'defaultPlane',
planeId: _entity_id,
plane: defaultPlaneStrMap[_entity_id],
zAxis,
yAxis,
},
})
return
}
const artifact = this.engineCommandManager.artifactMap[_entity_id]
// If we clicked on an extrude wall, we climb up the parent Id
// to get the sketch profile's face ID. If we clicked on an endcap,
// we already have it.
const pathId =
artifact?.type === 'extrudeWall' || artifact?.type === 'extrudeCap'
? artifact.pathId
: ''
// tsc cannot infer that target can have extrusions
// from the commandType (why?) so we need to cast it
const path = this.engineCommandManager.artifactMap?.[pathId || '']
const extrusionId =
path?.type === 'startPath' ? path.extrusionIds[0] : ''
// TODO: We get the first extrusion command ID,
// which is fine while backend systems only support one extrusion.
// but we need to more robustly handle resolving to the correct extrusion
// if there are multiple.
const extrusions = this.engineCommandManager.artifactMap?.[extrusionId]
if (artifact?.type !== 'extrudeCap' && artifact?.type !== 'extrudeWall')
return
const faceInfo = await getFaceDetails(_entity_id)
if (!faceInfo?.origin || !faceInfo?.z_axis || !faceInfo?.y_axis) return
const { z_axis, y_axis, origin } = faceInfo
const sketchPathToNode = getNodePathFromSourceRange(
kclManager.ast,
artifact.range
)
const extrudePathToNode = extrusions?.range
? getNodePathFromSourceRange(kclManager.ast, extrusions.range)
: []
sceneInfra.modelingSend({
type: 'Select default plane',
data: {
type: 'extrudeFace',
zAxis: [z_axis.x, z_axis.y, z_axis.z],
yAxis: [y_axis.x, y_axis.y, y_axis.z],
position: [origin.x, origin.y, origin.z].map(
(num) => num / sceneInfra._baseUnitMultiplier
) as [number, number, number],
sketchPathToNode,
extrudePathToNode,
cap: artifact.type === 'extrudeCap' ? artifact.cap : 'none',
faceId: _entity_id,
},
})
return
},
})
}
mouseEnterLeaveCallbacks() { mouseEnterLeaveCallbacks() {
return { return {
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => { onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
@ -1641,7 +1520,7 @@ export class SceneEntities {
) )
if (trap(_node, { suppress: true })) return if (trap(_node, { suppress: true })) return
const node = _node.node const node = _node.node
editorManager.setHighlightRange([node.start, node.end]) editorManager.setHighlightRange([[node.start, node.end]])
const yellow = 0xffff00 const yellow = 0xffff00
colorSegment(selected, yellow) colorSegment(selected, yellow)
const extraSegmentGroup = parent.getObjectByName(EXTRA_SEGMENT_HANDLE) const extraSegmentGroup = parent.getObjectByName(EXTRA_SEGMENT_HANDLE)
@ -1677,10 +1556,10 @@ export class SceneEntities {
} }
return return
} }
editorManager.setHighlightRange([0, 0]) editorManager.setHighlightRange([[0, 0]])
}, },
onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => { onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => {
editorManager.setHighlightRange([0, 0]) editorManager.setHighlightRange([[0, 0]])
const parent = getParentGroup(selected, [ const parent = getParentGroup(selected, [
STRAIGHT_SEGMENT, STRAIGHT_SEGMENT,
TANGENTIAL_ARC_TO_SEGMENT, TANGENTIAL_ARC_TO_SEGMENT,

View File

@ -11,10 +11,8 @@ import {
Raycaster, Raycaster,
Vector2, Vector2,
Group, Group,
PlaneGeometry,
MeshBasicMaterial, MeshBasicMaterial,
Mesh, Mesh,
DoubleSide,
Intersection, Intersection,
Object3D, Object3D,
Object3DEventMap, Object3DEventMap,
@ -48,7 +46,6 @@ export const DEBUG_SHOW_INTERSECTION_PLANE: false = false
export const DEBUG_SHOW_BOTH_SCENES: false = false export const DEBUG_SHOW_BOTH_SCENES: false = false
export const RAYCASTABLE_PLANE = 'raycastable-plane' export const RAYCASTABLE_PLANE = 'raycastable-plane'
export const DEFAULT_PLANES = 'default-planes'
export const X_AXIS = 'xAxis' export const X_AXIS = 'xAxis'
export const Y_AXIS = 'yAxis' export const Y_AXIS = 'yAxis'
@ -72,7 +69,7 @@ interface OnDragCallbackArgs extends OnMouseEnterLeaveArgs {
} }
intersects: Intersection<Object3D<Object3DEventMap>>[] intersects: Intersection<Object3D<Object3DEventMap>>[]
} }
interface OnClickCallbackArgs { export interface OnClickCallbackArgs {
mouseEvent: MouseEvent mouseEvent: MouseEvent
intersectionPoint?: { intersectionPoint?: {
twoD: Vector2 twoD: Vector2
@ -325,16 +322,9 @@ export class SceneInfra {
this.camControls.camera, this.camControls.camera,
this.camControls.target this.camControls.target
) )
const planesGroup = this.scene.getObjectByName(DEFAULT_PLANES)
const axisGroup = this.scene const axisGroup = this.scene
.getObjectByName(AXIS_GROUP) .getObjectByName(AXIS_GROUP)
?.getObjectByName('gridHelper') ?.getObjectByName('gridHelper')
planesGroup &&
planesGroup.scale.set(
scale / this._baseUnitMultiplier,
scale / this._baseUnitMultiplier,
scale / this._baseUnitMultiplier
)
axisGroup?.name === 'gridHelper' && axisGroup.scale.set(scale, scale, scale) axisGroup?.name === 'gridHelper' && axisGroup.scale.set(scale, scale, scale)
} }
@ -632,59 +622,6 @@ export class SceneInfra {
this.onClickCallback({ mouseEvent, intersects }) this.onClickCallback({ mouseEvent, intersects })
} }
} }
showDefaultPlanes() {
const addPlane = (
rotation: { x: number; y: number; z: number }, //
type: DefaultPlane
): Mesh => {
const planeGeometry = new PlaneGeometry(100, 100)
const planeMaterial = new MeshBasicMaterial({
color: defaultPlaneColor(type),
transparent: true,
opacity: 0.0,
side: DoubleSide,
depthTest: false, // needed to avoid transparency issues
})
const plane = new Mesh(planeGeometry, planeMaterial)
plane.rotation.x = rotation.x
plane.rotation.y = rotation.y
plane.rotation.z = rotation.z
plane.userData.type = type
plane.name = type
return plane
}
const planes = [
addPlane({ x: 0, y: Math.PI / 2, z: 0 }, YZ_PLANE),
addPlane({ x: 0, y: 0, z: 0 }, XY_PLANE),
addPlane({ x: -Math.PI / 2, y: 0, z: 0 }, XZ_PLANE),
]
const planesGroup = new Group()
planesGroup.userData.type = DEFAULT_PLANES
planesGroup.name = DEFAULT_PLANES
planesGroup.add(...planes)
planesGroup.traverse((child) => {
if (child instanceof Mesh) {
child.layers.enable(SKETCH_LAYER)
}
})
planesGroup.layers.enable(SKETCH_LAYER)
const sceneScale = getSceneScale(
this.camControls.camera,
this.camControls.target
)
planesGroup.scale.set(
sceneScale / this._baseUnitMultiplier,
sceneScale / this._baseUnitMultiplier,
sceneScale / this._baseUnitMultiplier
)
this.scene.add(planesGroup)
}
removeDefaultPlanes() {
const planesGroup = this.scene.children.find(
({ userData }) => userData.type === DEFAULT_PLANES
)
if (planesGroup) this.scene.remove(planesGroup)
}
updateOtherSelectionColors = (otherSelections: Axis[]) => { updateOtherSelectionColors = (otherSelections: Axis[]) => {
const axisGroup = this.scene.children.find( const axisGroup = this.scene.children.find(
({ userData }) => userData?.type === AXIS_GROUP ({ userData }) => userData?.type === AXIS_GROUP
@ -742,28 +679,3 @@ function baseUnitTomm(baseUnit: BaseUnit) {
return 914.4 return 914.4
} }
} }
export type DefaultPlane =
| 'xy-default-plane'
| 'xz-default-plane'
| 'yz-default-plane'
export const XY_PLANE: DefaultPlane = 'xy-default-plane'
export const XZ_PLANE: DefaultPlane = 'xz-default-plane'
export const YZ_PLANE: DefaultPlane = 'yz-default-plane'
export function defaultPlaneColor(
plane: DefaultPlane,
lowCh = 0.1,
highCh = 0.7
): Color {
switch (plane) {
case XY_PLANE:
return new Color(highCh, lowCh, lowCh)
case XZ_PLANE:
return new Color(lowCh, lowCh, highCh)
case YZ_PLANE:
return new Color(lowCh, highCh, lowCh)
}
return new Color(lowCh, lowCh, lowCh)
}

View File

@ -44,7 +44,7 @@ export function AstExplorer() {
<div <div
className="h-full relative" className="h-full relative"
onMouseLeave={(e) => { onMouseLeave={(e) => {
editorManager.setHighlightRange([0, 0]) editorManager.setHighlightRange([[0, 0]])
}} }}
> >
<pre className="text-xs"> <pre className="text-xs">
@ -113,12 +113,12 @@ function DisplayObj({
hasCursor ? 'bg-violet-100/80 dark:bg-violet-100/25' : '' hasCursor ? 'bg-violet-100/80 dark:bg-violet-100/25' : ''
}`} }`}
onMouseEnter={(e) => { onMouseEnter={(e) => {
editorManager.setHighlightRange([obj?.start || 0, obj.end]) editorManager.setHighlightRange([[obj?.start || 0, obj.end]])
e.stopPropagation() e.stopPropagation()
}} }}
onMouseMove={(e) => { onMouseMove={(e) => {
e.stopPropagation() e.stopPropagation()
editorManager.setHighlightRange([obj?.start || 0, obj.end]) editorManager.setHighlightRange([[obj?.start || 0, obj.end]])
}} }}
onClick={(e) => { onClick={(e) => {
send({ send({

View File

@ -124,7 +124,11 @@ function CommandBarHeader({ children }: React.PropsWithChildren<{}>) {
4 4
) )
) : typeof argValue === 'object' ? ( ) : typeof argValue === 'object' ? (
JSON.stringify(argValue) arg.valueSummary ? (
arg.valueSummary(argValue)
) : (
JSON.stringify(argValue)
)
) : ( ) : (
<em>{argValue}</em> <em>{argValue}</em>
) )

View File

@ -541,6 +541,16 @@ const CustomIconMap = {
/> />
</svg> </svg>
), ),
printer3d: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M16 5H4V7.5H7V7V6H8H9H10V7V7.5H16V5ZM17 7.5V8.5V15V16V17H16V16H15H14H6H5H4V17H3V16V15V8.5V7.5V5V4H4H16H17V5V7.5ZM4 8.5V15H5V13.5V13H5.5H14.5H15V13.5V15H16V8.5H10V9H9V10L8.5 10.5L8 10V9H7V8.5H4ZM14 14V15H6V14H14ZM8 7H9V8H8V7Z"
fill="currentColor"
/>
</svg>
),
polygon: ( polygon: (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path

View File

@ -5,6 +5,8 @@ import { CustomIcon } from './CustomIcon'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate } from 'react-router-dom'
import { createAndOpenNewProject } from 'lib/tauriFS' import { createAndOpenNewProject } from 'lib/tauriFS'
import { paths } from 'lib/paths' import { paths } from 'lib/paths'
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
import { useLspContext } from './LspProvider'
const HelpMenuDivider = () => ( const HelpMenuDivider = () => (
<div className="h-[1px] bg-chalkboard-110 dark:bg-chalkboard-80" /> <div className="h-[1px] bg-chalkboard-110 dark:bg-chalkboard-80" />
@ -12,16 +14,18 @@ const HelpMenuDivider = () => (
export function HelpMenu(props: React.PropsWithChildren) { export function HelpMenu(props: React.PropsWithChildren) {
const location = useLocation() const location = useLocation()
const { onProjectOpen } = useLspContext()
const filePath = useAbsoluteFilePath()
const isInProject = location.pathname.includes(paths.FILE) const isInProject = location.pathname.includes(paths.FILE)
const navigate = useNavigate() const navigate = useNavigate()
const { settings } = useSettingsAuthContext() const { settings } = useSettingsAuthContext()
return ( return (
<Popover className="relative"> <Popover className="relative">
<Popover.Button className="border-none p-0 m-0 rounded-full grid place-content-center"> <Popover.Button className="grid p-0 m-0 border-none rounded-full place-content-center">
<CustomIcon <CustomIcon
name="questionMark" name="questionMark"
className="w-7 h-7 rounded-full bg-chalkboard-110 dark:bg-chalkboard-80 text-chalkboard-10" className="rounded-full w-7 h-7 bg-chalkboard-110 dark:bg-chalkboard-80 text-chalkboard-10"
/> />
<span className="sr-only">Help and resources</span> <span className="sr-only">Help and resources</span>
<Tooltip position="top-right" wrapperClassName="ui-open:hidden"> <Tooltip position="top-right" wrapperClassName="ui-open:hidden">
@ -30,7 +34,7 @@ export function HelpMenu(props: React.PropsWithChildren) {
</Popover.Button> </Popover.Button>
<Popover.Panel <Popover.Panel
as="ul" as="ul"
className="absolute right-0 left-auto bottom-full mb-1 w-64 py-2 flex flex-col gap-1 align-stretch text-chalkboard-10 dark:text-inherit bg-chalkboard-110 dark:bg-chalkboard-100 rounded shadow-lg border border-solid border-chalkboard-110 dark:border-chalkboard-80 text-sm m-0 p-0" className="absolute right-0 left-auto flex flex-col w-64 gap-1 p-0 py-2 m-0 mb-1 text-sm border border-solid rounded shadow-lg bottom-full align-stretch text-chalkboard-10 dark:text-inherit bg-chalkboard-110 dark:bg-chalkboard-100 border-chalkboard-110 dark:border-chalkboard-80"
> >
<HelpMenuItem <HelpMenuItem
as="a" as="a"
@ -84,7 +88,12 @@ export function HelpMenu(props: React.PropsWithChildren) {
</HelpMenuItem> </HelpMenuItem>
<HelpMenuItem <HelpMenuItem
as="button" as="button"
onClick={() => navigate('settings?tab=keybindings')} onClick={() => {
const targetPath = location.pathname.includes(paths.FILE)
? filePath + paths.SETTINGS
: paths.HOME + paths.SETTINGS
navigate(targetPath + '?tab=keybindings')
}}
> >
Keyboard shortcuts Keyboard shortcuts
</HelpMenuItem> </HelpMenuItem>
@ -99,9 +108,9 @@ export function HelpMenu(props: React.PropsWithChildren) {
}, },
}) })
if (isInProject) { if (isInProject) {
navigate('onboarding') navigate(filePath + paths.ONBOARDING.INDEX)
} else { } else {
createAndOpenNewProject(navigate) createAndOpenNewProject({ onProjectOpen, navigate })
} }
}} }}
> >
@ -128,7 +137,7 @@ function HelpMenuItem({
}: HelpMenuItemProps) { }: HelpMenuItemProps) {
const baseClassName = 'block px-2 py-1 hover:bg-chalkboard-80' const baseClassName = 'block px-2 py-1 hover:bg-chalkboard-80'
return ( return (
<li className="m-0 p-0"> <li className="p-0 m-0">
{as === 'a' ? ( {as === 'a' ? (
<a <a
{...(props as React.ComponentProps<'a'>)} {...(props as React.ComponentProps<'a'>)}

View File

@ -10,6 +10,7 @@ import { coreDump } from 'lang/wasm'
import toast from 'react-hot-toast' import toast from 'react-hot-toast'
import { CoreDumpManager } from 'lib/coredump' import { CoreDumpManager } from 'lib/coredump'
import openWindow from 'lib/openWindow' import openWindow from 'lib/openWindow'
import { NetworkMachineIndicator } from './NetworkMachineIndicator'
export function LowerRightControls({ export function LowerRightControls({
children, children,
@ -100,6 +101,7 @@ export function LowerRightControls({
Settings Settings
</Tooltip> </Tooltip>
</Link> </Link>
<NetworkMachineIndicator className={linkOverrideClassName} />
<NetworkHealthIndicator /> <NetworkHealthIndicator />
<HelpMenu /> <HelpMenu />
</menu> </menu>

View File

@ -1,5 +1,5 @@
import { useMachine } from '@xstate/react' import { useMachine } from '@xstate/react'
import React, { createContext, useEffect, useRef } from 'react' import React, { createContext, useEffect, useMemo, useRef } from 'react'
import { import {
AnyStateMachine, AnyStateMachine,
ContextFrom, ContextFrom,
@ -8,7 +8,12 @@ import {
StateFrom, StateFrom,
assign, assign,
} from 'xstate' } from 'xstate'
import { SetSelections, modelingMachine } from 'machines/modelingMachine' import {
SetSelections,
getPersistedContext,
modelingMachine,
modelingMachineDefaultContext,
} from 'machines/modelingMachine'
import { useSetupEngineManager } from 'hooks/useSetupEngineManager' import { useSetupEngineManager } from 'hooks/useSetupEngineManager'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { import {
@ -23,6 +28,7 @@ import {
editorManager, editorManager,
sceneEntitiesManager, sceneEntitiesManager,
} from 'lib/singletons' } from 'lib/singletons'
import { machineManager } from 'lib/machineManager'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import { applyConstraintHorzVertDistance } from './Toolbar/SetHorzVertDistance' import { applyConstraintHorzVertDistance } from './Toolbar/SetHorzVertDistance'
import { import {
@ -72,7 +78,7 @@ import { err, trap } from 'lib/trap'
import { useCommandsContext } from 'hooks/useCommandsContext' import { useCommandsContext } from 'hooks/useCommandsContext'
import { modelingMachineEvent } from 'editor/manager' import { modelingMachineEvent } from 'editor/manager'
import { hasValidFilletSelection } from 'lang/modifyAst/addFillet' import { hasValidFilletSelection } from 'lang/modifyAst/addFillet'
import { uuidv4 } from 'lib/utils' import { ExportIntent } from 'lang/std/engineConnection'
type MachineContext<T extends AnyStateMachine> = { type MachineContext<T extends AnyStateMachine> = {
state: StateFrom<T> state: StateFrom<T>
@ -100,6 +106,7 @@ export const ModelingMachineProvider = ({
} = useSettingsAuthContext() } = useSettingsAuthContext()
const token = auth?.context?.token const token = auth?.context?.token
const streamRef = useRef<HTMLDivElement>(null) const streamRef = useRef<HTMLDivElement>(null)
const persistedContext = useMemo(() => getPersistedContext(), [])
let [searchParams] = useSearchParams() let [searchParams] = useSearchParams()
const pool = searchParams.get('pool') const pool = searchParams.get('pool')
@ -122,6 +129,13 @@ export const ModelingMachineProvider = ({
const [modelingState, modelingSend, modelingActor] = useMachine( const [modelingState, modelingSend, modelingActor] = useMachine(
modelingMachine, modelingMachine,
{ {
context: {
...modelingMachineDefaultContext,
store: {
...modelingMachineDefaultContext.store,
...persistedContext,
},
},
actions: { actions: {
'disable copilot': () => { 'disable copilot': () => {
editorManager.setCopilotEnabled(false) editorManager.setCopilotEnabled(false)
@ -143,7 +157,9 @@ export const ModelingMachineProvider = ({
kclManager.executeCode().then(() => { kclManager.executeCode().then(() => {
if (engineCommandManager.engineConnection?.idleMode) return if (engineCommandManager.engineConnection?.idleMode) return
store.videoElement?.play() store.videoElement?.play().catch((e) => {
console.warn('Video playing was prevented', e)
})
}) })
})() })()
}, },
@ -337,8 +353,57 @@ export const ModelingMachineProvider = ({
return {} return {}
}), }),
Make: async (_, event) => {
if (event.type !== 'Make' || TEST) return
// Check if we already have an export intent.
if (engineCommandManager.exportIntent) {
toast.error('Already exporting')
return
}
// Set the export intent.
engineCommandManager.exportIntent = ExportIntent.Make
console.log('making', event.data)
// Set the current machine.
machineManager.currentMachine = event.data.machine
const format: Models['OutputFormat_type'] = {
type: 'stl',
coords: {
forward: {
axis: 'y',
direction: 'negative',
},
up: {
axis: 'z',
direction: 'positive',
},
},
storage: 'ascii',
units: defaultUnit.current,
selection: { type: 'default_scene' },
}
toast.promise(
exportFromEngine({
format: format,
}),
{
loading: 'Starting print...',
success: 'Started print successfully',
error: 'Error while starting print',
}
)
},
'Engine export': async (_, event) => { 'Engine export': async (_, event) => {
if (event.type !== 'Export' || TEST) return if (event.type !== 'Export' || TEST) return
if (engineCommandManager.exportIntent) {
toast.error('Already exporting')
return
}
// Set the export intent.
engineCommandManager.exportIntent = ExportIntent.Save
console.log('exporting', event.data) console.log('exporting', event.data)
const format = { const format = {
...event.data, ...event.data,
@ -432,7 +497,7 @@ export const ModelingMachineProvider = ({
if (!isSingleCursorInPipe(selectionRanges, kclManager.ast)) if (!isSingleCursorInPipe(selectionRanges, kclManager.ast))
return false return false
return !!isCursorInSketchCommandRange( return !!isCursorInSketchCommandRange(
engineCommandManager.artifactMap, engineCommandManager.artifactGraph,
selectionRanges selectionRanges
) )
}, },

View File

@ -22,7 +22,7 @@ import {
historyKeymap, historyKeymap,
history, history,
} from '@codemirror/commands' } from '@codemirror/commands'
import { lintGutter, lintKeymap } from '@codemirror/lint' import { diagnosticCount, lintGutter, lintKeymap } from '@codemirror/lint'
import { import {
foldGutter, foldGutter,
foldKeymap, foldKeymap,
@ -193,6 +193,13 @@ export const KclEditorPane = () => {
if (_editorView === null) return if (_editorView === null) return
editorManager.setEditorView(_editorView) editorManager.setEditorView(_editorView)
// On first load of this component, ensure we show the current errors
// in the editor.
// Make sure we don't add them twice.
if (diagnosticCount(_editorView.state) === 0) {
kclManager.setDiagnosticsForCurrentErrors()
}
}} }}
/> />
</div> </div>

View File

@ -27,27 +27,3 @@ export const LogsPane = () => {
</div> </div>
) )
} }
export const KclErrorsPane = () => {
const theme = useResolvedTheme()
const { errors } = useKclContext()
return (
<div className="overflow-hidden">
<div className="absolute inset-0 p-2 flex flex-col overflow-auto">
<ReactJsonTypeHack
src={errors}
collapsed={1}
collapseStringsAfterLength={60}
enableClipboard={false}
displayArrayKey={false}
displayDataTypes={false}
displayObjectSize={true}
indentWidth={2}
quotesOnKeys={false}
name={false}
theme={theme === 'light' ? 'rjv-default' : 'monokai'}
/>
</div>
</div>
)
}

View File

@ -3,28 +3,41 @@ import {
faBugSlash, faBugSlash,
faCode, faCode,
faCodeCommit, faCodeCommit,
faExclamationCircle,
faSquareRootVariable, faSquareRootVariable,
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
import { KclEditorMenu } from 'components/ModelingSidebar/ModelingPanes/KclEditorMenu' import { KclEditorMenu } from 'components/ModelingSidebar/ModelingPanes/KclEditorMenu'
import { CustomIconName } from 'components/CustomIcon' import { CustomIconName } from 'components/CustomIcon'
import { KclEditorPane } from 'components/ModelingSidebar/ModelingPanes/KclEditorPane' import { KclEditorPane } from 'components/ModelingSidebar/ModelingPanes/KclEditorPane'
import { ReactNode } from 'react' import { MouseEventHandler, ReactNode } from 'react'
import { MemoryPane, MemoryPaneMenu } from './MemoryPane' import { MemoryPane, MemoryPaneMenu } from './MemoryPane'
import { KclErrorsPane, LogsPane } from './LoggingPanes' import { LogsPane } from './LoggingPanes'
import { DebugPane } from './DebugPane' import { DebugPane } from './DebugPane'
import { FileTreeInner, FileTreeMenu } from 'components/FileTree' import { FileTreeInner, FileTreeMenu } from 'components/FileTree'
import { useKclContext } from 'lang/KclProvider'
import { editorManager } from 'lib/singletons'
export type SidebarType = export type SidebarType =
| 'code' | 'code'
| 'debug' | 'debug'
| 'export' | 'export'
| 'files' | 'files'
| 'kclErrors'
| 'logs' | 'logs'
| 'lspMessages' | 'lspMessages'
| 'variables' | 'variables'
export interface BadgeInfo {
value: (props: PaneCallbackProps) => boolean | number
onClick?: MouseEventHandler<any>
}
/**
* This interface can be extended as more context is needed for the panes
* to determine if they should show their badges or not.
*/
interface PaneCallbackProps {
kclContext: ReturnType<typeof useKclContext>
}
export type SidebarPane = { export type SidebarPane = {
id: SidebarType id: SidebarType
title: string title: string
@ -33,6 +46,7 @@ export type SidebarPane = {
Content: ReactNode | React.FC Content: ReactNode | React.FC
Menu?: ReactNode | React.FC Menu?: ReactNode | React.FC
hideOnPlatform?: 'desktop' | 'web' hideOnPlatform?: 'desktop' | 'web'
showBadge?: BadgeInfo
} }
export const sidebarPanes: SidebarPane[] = [ export const sidebarPanes: SidebarPane[] = [
@ -43,6 +57,15 @@ export const sidebarPanes: SidebarPane[] = [
Content: KclEditorPane, Content: KclEditorPane,
keybinding: 'Shift + C', keybinding: 'Shift + C',
Menu: KclEditorMenu, Menu: KclEditorMenu,
showBadge: {
value: ({ kclContext }) => {
return kclContext.errors.length
},
onClick: (e) => {
e.preventDefault()
editorManager.scrollToFirstErrorDiagnosticIfExists()
},
},
}, },
{ {
id: 'files', id: 'files',
@ -68,13 +91,6 @@ export const sidebarPanes: SidebarPane[] = [
Content: LogsPane, Content: LogsPane,
keybinding: 'Shift + L', keybinding: 'Shift + L',
}, },
{
id: 'kclErrors',
title: 'KCL Errors',
icon: faExclamationCircle,
Content: KclErrorsPane,
keybinding: 'Shift + E',
},
{ {
id: 'debug', id: 'debug',
title: 'Debug', title: 'Debug',

View File

@ -1,6 +1,6 @@
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { Resizable } from 're-resizable' import { Resizable } from 're-resizable'
import { useCallback, useMemo } from 'react' import { MouseEventHandler, useCallback, useMemo } from 'react'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import { SidebarType, sidebarPanes } from './ModelingPanes' import { SidebarType, sidebarPanes } from './ModelingPanes'
import Tooltip from 'components/Tooltip' import Tooltip from 'components/Tooltip'
@ -12,13 +12,21 @@ import { useModelingContext } from 'hooks/useModelingContext'
import { CustomIconName } from 'components/CustomIcon' import { CustomIconName } from 'components/CustomIcon'
import { useCommandsContext } from 'hooks/useCommandsContext' import { useCommandsContext } from 'hooks/useCommandsContext'
import { IconDefinition } from '@fortawesome/free-solid-svg-icons' import { IconDefinition } from '@fortawesome/free-solid-svg-icons'
import { useKclContext } from 'lang/KclProvider'
import { machineManager } from 'lib/machineManager'
interface ModelingSidebarProps { interface ModelingSidebarProps {
paneOpacity: '' | 'opacity-20' | 'opacity-40' paneOpacity: '' | 'opacity-20' | 'opacity-40'
} }
interface BadgeInfoComputed {
value: number | boolean
onClick?: MouseEventHandler<any>
}
export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) { export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
const { commandBarSend } = useCommandsContext() const { commandBarSend } = useCommandsContext()
const kclContext = useKclContext()
const { settings } = useSettingsAuthContext() const { settings } = useSettingsAuthContext()
const onboardingStatus = settings.context.app.onboardingStatus const onboardingStatus = settings.context.app.onboardingStatus
const { send, context } = useModelingContext() const { send, context } = useModelingContext()
@ -43,7 +51,30 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
data: { name: 'Export', groupId: 'modeling' }, data: { name: 'Export', groupId: 'modeling' },
}), }),
}, },
{
id: 'make',
title: 'Make part',
icon: 'printer3d',
iconClassName: '!p-0',
keybinding: 'Ctrl + Shift + M',
action: async () => {
commandBarSend({
type: 'Find and select command',
data: { name: 'Make', groupId: 'modeling' },
})
},
hide: () => machineManager.machineCount() === 0,
hideOnPlatform: 'web',
},
] ]
const filteredActions: SidebarAction[] = sidebarActions.filter(
(action) =>
(!action.hide || (action.hide instanceof Function && !action.hide())) &&
(!action.hideOnPlatform ||
(isTauri()
? action.hideOnPlatform === 'web'
: action.hideOnPlatform === 'desktop'))
)
// // Filter out the debug panel if it's not supposed to be shown // // Filter out the debug panel if it's not supposed to be shown
// // TODO: abstract out for allowing user to configure which panes to show // // TODO: abstract out for allowing user to configure which panes to show
@ -62,6 +93,18 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
[sidebarPanes, showDebugPanel.current] [sidebarPanes, showDebugPanel.current]
) )
const paneBadgeMap: Record<SidebarType, BadgeInfoComputed> = useMemo(() => {
return filteredPanes.reduce((acc, pane) => {
if (pane.showBadge) {
acc[pane.id] = {
value: pane.showBadge.value({ kclContext }),
onClick: pane.showBadge.onClick,
}
}
return acc
}, {} as Record<SidebarType, BadgeInfoComputed>)
}, [kclContext.errors])
const togglePane = useCallback( const togglePane = useCallback(
(newPane: SidebarType) => { (newPane: SidebarType) => {
send({ send({
@ -120,26 +163,34 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
paneIsOpen={context.store?.openPanes.includes(pane.id)} paneIsOpen={context.store?.openPanes.includes(pane.id)}
onClick={() => togglePane(pane.id)} onClick={() => togglePane(pane.id)}
aria-pressed={context.store?.openPanes.includes(pane.id)} aria-pressed={context.store?.openPanes.includes(pane.id)}
showBadge={paneBadgeMap[pane.id]}
/> />
))} ))}
</ul> </ul>
<hr className="w-full border-chalkboard-20 dark:border-chalkboard-80" /> {filteredActions.length > 0 && (
<ul id="sidebar-actions" className="w-fit p-2 flex flex-col gap-2"> <>
{sidebarActions.map((action) => ( <hr className="w-full border-chalkboard-20 dark:border-chalkboard-80" />
<ModelingPaneButton <ul
key={action.id} id="sidebar-actions"
paneConfig={{ className="w-fit p-2 flex flex-col gap-2"
id: action.id, >
title: action.title, {filteredActions.map((action) => (
icon: action.icon, <ModelingPaneButton
keybinding: action.keybinding, key={action.id}
iconClassName: action.iconClassName, paneConfig={{
iconSize: 'md', id: action.id,
}} title: action.title,
onClick={action.action} icon: action.icon,
/> keybinding: action.keybinding,
))} iconClassName: action.iconClassName,
</ul> iconSize: 'md',
}}
onClick={action.action}
/>
))}
</ul>
</>
)}
</ul> </ul>
<ul <ul
id="pane-section" id="pane-section"
@ -186,12 +237,14 @@ interface ModelingPaneButtonProps
} }
onClick: () => void onClick: () => void
paneIsOpen?: boolean paneIsOpen?: boolean
showBadge?: BadgeInfoComputed
} }
function ModelingPaneButton({ function ModelingPaneButton({
paneConfig, paneConfig,
onClick, onClick,
paneIsOpen, paneIsOpen,
showBadge,
...props ...props
}: ModelingPaneButtonProps) { }: ModelingPaneButtonProps) {
useHotkeys(paneConfig.keybinding, onClick, { useHotkeys(paneConfig.keybinding, onClick, {
@ -199,42 +252,68 @@ function ModelingPaneButton({
}) })
return ( return (
<button <div id={paneConfig.id + '-button-holder'}>
className="pointer-events-auto flex items-center justify-center border-transparent dark:border-transparent p-0 m-0 rounded-sm !outline-0 focus-visible:border-primary" <button
onClick={onClick} className="pointer-events-auto flex items-center justify-center border-transparent dark:border-transparent p-0 m-0 rounded-sm !outline-0 focus-visible:border-primary"
name={paneConfig.title} onClick={onClick}
data-testid={paneConfig.id + '-pane-button'} name={paneConfig.title}
{...props} data-testid={paneConfig.id + '-pane-button'}
> {...props}
<ActionIcon
icon={paneConfig.icon}
className={'p-1 ' + paneConfig.iconClassName || ''}
size={paneConfig.iconSize || 'sm'}
iconClassName={
paneIsOpen
? ' !text-chalkboard-10'
: '!text-chalkboard-80 dark:!text-chalkboard-30'
}
bgClassName={
'rounded-sm ' + (paneIsOpen ? '!bg-primary' : '!bg-transparent')
}
/>
<span className="sr-only">
{paneConfig.title}
{paneIsOpen !== undefined ? ` pane` : ''}
</span>
<Tooltip
position="right"
contentClassName="max-w-none flex items-center gap-4"
hoverOnly
> >
<span className="flex-1"> <ActionIcon
icon={paneConfig.icon}
className={'p-1 ' + paneConfig.iconClassName || ''}
size={paneConfig.iconSize || 'sm'}
iconClassName={
paneIsOpen
? ' !text-chalkboard-10'
: '!text-chalkboard-80 dark:!text-chalkboard-30'
}
bgClassName={
'rounded-sm ' + (paneIsOpen ? '!bg-primary' : '!bg-transparent')
}
/>
<span className="sr-only">
{paneConfig.title} {paneConfig.title}
{paneIsOpen !== undefined ? ` pane` : ''} {paneIsOpen !== undefined ? ` pane` : ''}
</span> </span>
<kbd className="hotkey text-xs capitalize">{paneConfig.keybinding}</kbd> <Tooltip
</Tooltip> position="right"
</button> contentClassName="max-w-none flex items-center gap-4"
hoverOnly
>
<span className="flex-1">
{paneConfig.title}
{paneIsOpen !== undefined ? ` pane` : ''}
</span>
<kbd className="hotkey text-xs capitalize">
{paneConfig.keybinding}
</kbd>
</Tooltip>
</button>
{!!showBadge?.value && (
<p
id={`${paneConfig.id}-badge`}
className={
'absolute m-0 p-0 top-1 right-0 w-3 h-3 flex items-center justify-center text-[10px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer'
}
onClick={showBadge.onClick}
title={`Click to view ${showBadge.value} notification${
Number(showBadge.value) > 1 ? 's' : ''
}`}
>
<span className="sr-only">&nbsp;has&nbsp;</span>
{typeof showBadge.value === 'number' ? (
<span>{showBadge.value}</span>
) : (
<span className="sr-only">a</span>
)}
<span className="sr-only">
&nbsp;notification{Number(showBadge.value) > 1 ? 's' : ''}
</span>
</p>
)}
</div>
) )
} }
@ -246,4 +325,5 @@ export type SidebarAction = {
keybinding: string keybinding: string
action: () => void action: () => void
hideOnPlatform?: 'desktop' | 'web' hideOnPlatform?: 'desktop' | 'web'
hide?: boolean | (() => boolean)
} }

View File

@ -103,8 +103,8 @@ export const NetworkHealthIndicator = () => {
'rounded-sm ' + overallConnectionStateColor[overallState].bg 'rounded-sm ' + overallConnectionStateColor[overallState].bg
} }
/> />
<Tooltip position="top-right"> <Tooltip position="top-right" wrapperClassName="ui-open:hidden">
Network Health ({NETWORK_HEALTH_TEXT[overallState]}) Network health ({NETWORK_HEALTH_TEXT[overallState]})
</Tooltip> </Tooltip>
</Popover.Button> </Popover.Button>
<Popover.Panel <Popover.Panel

View File

@ -0,0 +1,62 @@
import { Popover } from '@headlessui/react'
import Tooltip from './Tooltip'
import { machineManager } from 'lib/machineManager'
import { isTauri } from 'lib/isTauri'
import { CustomIcon } from './CustomIcon'
export const NetworkMachineIndicator = ({
className,
}: {
className?: string
}) => {
const machineCount = Object.keys(machineManager.machines).length
return isTauri() ? (
<Popover className="relative">
<Popover.Button
className={
'flex items-center p-0 border-none bg-transparent dark:bg-transparent relative ' +
(className || '')
}
data-testid="network-machine-toggle"
>
<CustomIcon name="printer3d" className="w-5 h-5" />
{machineCount > 0 && (
<p aria-hidden className="flex items-center justify-center text-xs">
{machineCount}
</p>
)}
<Tooltip position="top-right" wrapperClassName="ui-open:hidden">
Network machines ({machineCount})
</Tooltip>
</Popover.Button>
<Popover.Panel
className="absolute right-0 left-auto bottom-full mb-1 w-64 flex flex-col gap-1 align-stretch bg-chalkboard-10 dark:bg-chalkboard-90 rounded shadow-lg border border-solid border-chalkboard-20/50 dark:border-chalkboard-80/50 text-sm"
data-testid="network-popover"
>
<div className="flex items-center justify-between p-2 rounded-t-sm bg-chalkboard-20 dark:bg-chalkboard-80">
<h2 className="text-sm font-sans font-normal">Network machines</h2>
<p
data-testid="network"
className="font-bold text-xs uppercase px-2 py-1 rounded-sm"
>
{machineCount}
</p>
</div>
{machineCount > 0 && (
<ul className="divide-y divide-chalkboard-20 dark:divide-chalkboard-80">
{Object.entries(machineManager.machines).map(
([hostname, machine]) => (
<li key={hostname} className={'px-2 py-4 gap-1 last:mb-0 '}>
<p className="">{machine.model || machine.manufacturer}</p>
<p className="text-chalkboard-60 dark:text-chalkboard-50 text-xs">
Hostname {hostname}
</p>
</li>
)
)}
</ul>
)}
</Popover.Panel>
</Popover>
) : null
}

View File

@ -12,6 +12,7 @@ import { useCommandsContext } from 'hooks/useCommandsContext'
import { CustomIcon } from './CustomIcon' import { CustomIcon } from './CustomIcon'
import { useLspContext } from './LspProvider' import { useLspContext } from './LspProvider'
import { engineCommandManager } from 'lib/singletons' import { engineCommandManager } from 'lib/singletons'
import { machineManager } from 'lib/machineManager'
import usePlatform from 'hooks/usePlatform' import usePlatform from 'hooks/usePlatform'
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath' import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
import Tooltip from './Tooltip' import Tooltip from './Tooltip'
@ -90,12 +91,14 @@ function ProjectMenuPopover({
const { commandBarState, commandBarSend } = useCommandsContext() const { commandBarState, commandBarSend } = useCommandsContext()
const { onProjectClose } = useLspContext() const { onProjectClose } = useLspContext()
const exportCommandInfo = { name: 'Export', groupId: 'modeling' } const exportCommandInfo = { name: 'Export', groupId: 'modeling' }
const makeCommandInfo = { name: 'Make', groupId: 'modeling' }
const findCommand = (obj: { name: string; groupId: string }) => const findCommand = (obj: { name: string; groupId: string }) =>
Boolean( Boolean(
commandBarState.context.commands.find( commandBarState.context.commands.find(
(c) => c.name === obj.name && c.groupId === obj.groupId (c) => c.name === obj.name && c.groupId === obj.groupId
) )
) )
const machineCount = machineManager.machineCount()
// We filter this memoized list so that no orphan "break" elements are rendered. // We filter this memoized list so that no orphan "break" elements are rendered.
const projectMenuItems = useMemo<(ActionButtonProps | 'break')[]>( const projectMenuItems = useMemo<(ActionButtonProps | 'break')[]>(
@ -144,6 +147,32 @@ function ProjectMenuPopover({
}), }),
}, },
'break', 'break',
{
id: 'make',
Element: 'button',
className: !isTauri() ? 'hidden' : '',
children: (
<>
<span>Make current part</span>
{!findCommand(makeCommandInfo) && (
<Tooltip
position="right"
wrapperClassName="!max-w-none min-w-fit"
>
Awaiting engine connection
</Tooltip>
)}
</>
),
disabled: !findCommand(makeCommandInfo) || machineCount === 0,
onClick: () => {
commandBarSend({
type: 'Find and select command',
data: makeCommandInfo,
})
},
},
'break',
{ {
id: 'go-home', id: 'go-home',
Element: 'button', Element: 'button',

View File

@ -19,7 +19,8 @@ import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/tauriFS'
import { paths } from 'lib/paths' import { paths } from 'lib/paths'
import { useDotDotSlash } from 'hooks/useDotDotSlash' import { useDotDotSlash } from 'hooks/useDotDotSlash'
import { sep } from '@tauri-apps/api/path' import { sep } from '@tauri-apps/api/path'
import { ForwardedRef, forwardRef } from 'react' import { ForwardedRef, forwardRef, useEffect } from 'react'
import { useLspContext } from 'components/LspProvider'
interface AllSettingsFieldsProps { interface AllSettingsFieldsProps {
searchParamTab: SettingsLevel searchParamTab: SettingsLevel
@ -33,9 +34,10 @@ export const AllSettingsFields = forwardRef(
) => { ) => {
const location = useLocation() const location = useLocation()
const navigate = useNavigate() const navigate = useNavigate()
const { onProjectOpen } = useLspContext()
const dotDotSlash = useDotDotSlash() const dotDotSlash = useDotDotSlash()
const { const {
settings: { send, context }, settings: { send, context, state },
} = useSettingsAuthContext() } = useSettingsAuthContext()
const projectPath = const projectPath =
@ -48,19 +50,37 @@ export const AllSettingsFields = forwardRef(
) )
: undefined : undefined
function restartOnboarding() { async function restartOnboarding() {
send({ send({
type: `set.app.onboardingStatus`, type: `set.app.onboardingStatus`,
data: { level: 'user', value: '' }, data: { level: 'user', value: '' },
}) })
if (isFileSettings) {
navigate(dotDotSlash(1) + paths.ONBOARDING.INDEX)
} else {
createAndOpenNewProject(navigate)
}
} }
/**
* A "listener" for the XState to return to "idle" state
* when the user resets the onboarding, using the callback above
*/
useEffect(() => {
async function navigateToOnboardingStart() {
if (
state.context.app.onboardingStatus.user === '' &&
state.matches('idle')
) {
if (isFileSettings) {
// If we're in a project, first navigate to the onboarding start here
// so we can trigger the warning screen if necessary
navigate(dotDotSlash(1) + paths.ONBOARDING.INDEX)
} else {
// If we're in the global settings, create a new project and navigate
// to the onboarding start in that project
await createAndOpenNewProject({ onProjectOpen, navigate })
}
}
}
navigateToOnboardingStart()
}, [isFileSettings, navigate, state])
return ( return (
<div className="relative overflow-y-auto"> <div className="relative overflow-y-auto">
<div ref={scrollRef} className="flex flex-col gap-4 px-2"> <div ref={scrollRef} className="flex flex-col gap-4 px-2">

View File

@ -175,11 +175,35 @@ export const SettingsAuthProviderBase = ({
id: `${event.type}.success`, id: `${event.type}.success`,
}) })
}, },
'Execute AST': () => { 'Execute AST': (context, event) => {
kclManager.isFirstRender = true try {
kclManager.executeCode(true).then(() => { const allSettingsIncludesUnitChange =
kclManager.isFirstRender = false event.type === 'Set all settings' &&
}) event.settings?.modeling?.defaultUnit?.current !==
context.modeling.defaultUnit.current
const resetSettingsIncludesUnitChange =
event.type === 'Reset settings' &&
context.modeling.defaultUnit.current !==
settings?.modeling?.defaultUnit?.default
if (
event.type === 'set.modeling.defaultUnit' ||
allSettingsIncludesUnitChange ||
resetSettingsIncludesUnitChange
) {
kclManager.isFirstRender = true
kclManager.executeCode(true).then(() => {
kclManager.isFirstRender = false
})
} else {
// For any future logging we'd like to do
// console.log(
// 'Not re-executing AST because the settings change did not affect the code interpretation'
// )
}
} catch (e) {
console.error('Error executing AST after settings change', e)
}
}, },
}, },
services: { services: {

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