Compare commits

...

16 Commits

Author SHA1 Message Date
5ebd5c8dbb Enhance helixes (#4973)
* updates

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

* updates

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

* updates

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

* allow a helix to go into a sweep

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

* fix clippy

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

* updates

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

* udpates

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

* updates

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

* snapshots

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

* docs

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

* docs

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

* fix

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

* updates

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

* updates

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

* updates

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

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

* updates

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

* updates

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

* docs

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

* updates

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

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

* em,pty

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

* updates

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-08 03:10:53 +00:00
a9ceaf2678 fix: make error for missing a closing bracket clearer (#4974)
* fix: make error for missing a closing bracket clearer

* Fix test for error message

---------

Co-authored-by: Tom Pridham <pridham.tom@gmail.com>
2025-01-08 01:55:07 +00:00
c8afd3399b Dead code clean up (smol PR) (#4653)
* general clean up

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

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

* trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-08 01:46:05 +00:00
5dda4828c6 Bump react-modal from 3.16.1 to 3.16.3 (#4924)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.16.1 to 3.16.3.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.16.1...v3.16.3)

---
updated-dependencies:
- dependency-name: react-modal
  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>
2025-01-07 15:24:24 -08:00
72acab752c Bump async-trait from 0.1.83 to 0.1.85 in /src/wasm-lib (#4969)
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.83 to 0.1.85.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.83...0.1.85)

---
updated-dependencies:
- dependency-name: async-trait
  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>
2025-01-07 12:54:16 -08:00
81df38ad1c Bump happy-dom from 15.11.7 to 16.3.0 (#4925)
* Bump happy-dom from 15.11.7 to 16.3.0

Bumps [happy-dom](https://github.com/capricorn86/happy-dom) from 15.11.7 to 16.3.0.
- [Release notes](https://github.com/capricorn86/happy-dom/releases)
- [Commits](https://github.com/capricorn86/happy-dom/compare/v15.11.7...v16.3.0)

---
updated-dependencies:
- dependency-name: happy-dom
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

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

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-07 20:51:15 +00:00
0576a2bef1 Bump react-hotkeys-hook from 4.5.1 to 4.6.1 (#4953)
Bumps [react-hotkeys-hook](https://github.com/JohannesKlauss/react-keymap-hook) from 4.5.1 to 4.6.1.
- [Release notes](https://github.com/JohannesKlauss/react-keymap-hook/releases)
- [Changelog](https://github.com/JohannesKlauss/react-hotkeys-hook/blob/main/CHANGELOG.md)
- [Commits](https://github.com/JohannesKlauss/react-keymap-hook/compare/v4.5.1...v4.6.1)

---
updated-dependencies:
- dependency-name: react-hotkeys-hook
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 20:46:57 +00:00
4b2f6b4647 refactor: Remove unused UpdaterModal component (#4791) 2025-01-07 15:28:33 -05:00
69edaa4183 implementing array pop (#4806)
* implementing naive array pop

* multi-profile follow up. (#4802)

* multi-profile work

* fix enter sketch on cap

* fix coderef problem for walls and caps

* allow sketch mode entry from circle

* clean up

* update snapshot

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

* trigger CI

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

* add test

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

* fix how expression index is corrected, to make compatible with offset planes

* another test

* tweak test

* more test tweaks

* break up test to fix it hopfully

* fix onboarding test

* remove bad comment

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* get ready to bump (kcl-lib and friends) world (#4794)

get ready to bump world

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

* Revert multi-profile (#4812)

* Revert "multi-profile follow up. (#4802)"

This reverts commit 2b2ed470c1.

* Revert "multi profile (#4532)"

This reverts commit 04e586d07b.

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

* Re-run CI after snapshots

* Re-run CI after snapshots

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Re-run CI after snapshots

* Add `fixme` to onboarding test

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Add tracking of operations for the feature tree (#4746)

* Add operations tracking for the timeline

* Change to only track certain stdlib functions as operations

* Update gen files

* Add operations to simulation snapshot tests

* Add tracking of positional function calls

* Fix generated field names to be camel case in TS

* Fix generated TS field names to match and better docs

* Fix order of ops with patternTransform

* Fix sweep to be included

* Add new expected test outputs

* Add tracking for startSketchOn

* Update ops output to include startSketchOn

* Fix serde field name

* Fix output field name

* Add tracking of operations that fail

* Add snapshots of operations even when there's a KCL execution error

* Add ops output for error executions

* Add operations output to executor error

* Update op source ranges

* Remove tracking of circle() and polygon() since they're not needed

* Update output without circle and polygon

* Fix to track patternCircular3d and patternLinear3d

* Remove tracking for mirror2d

* Update ops output

* Fix to track the correct source range of function definitions

---------

Co-authored-by: Frank Noirot <frank@zoo.dev>

* Change KCL completion to use new object/record syntax (#4815)

* Reserve syntax for units of measure (#4783)

* Allow underscores but only for un-referenced names

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

* Support numeric suffixes for UoM types

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

* UoM type arguments

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

* warnings -> non-fatal errors

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

* type ascription

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

---------

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

* Whole module imports (#4767)

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

* Support completions from import statements (#4768)

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

* Implements boolean logical and/or in kcl  (#4678)

* redoing bool logic impl on latest main

* adding snapshot tests (removing .new)

* removing accidental change smh:(

* accepting client side scene snapshot

* accepting png snapshot and triggering ci

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

* accepting png again?

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* accepting grid visibility snapshot

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* accepting png snapshot

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* accepting png snapshot

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

* accepting png snapshot

* rerunning simtest creation to get ops.snap files

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* Annotations syntax and per-file default units preparatory work (#4822)

* Parse annotations

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

* Propagate settings from annotations to exec_state

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

---------

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

* KCL: Unlabeled first param defaults to % (#4817)

Part of #4600

KCL functions can declare one special argument that doesn't require a label on its parameter when called.

This PR will default that arg to % (the current pipeline) if not given.

* Deprecate startSketchAt() stdlib function (#4819)

* Deprecate startSketchAt() stdlib function

* Remove uses of startSketchAt() from the doc tests

* Update docs

* Add dry-run validation for Loft (#4820)

* WIP: mess with shell selection validation
Will eventually fix #4711

* Update from main

* WIP: not working yet

* Working loft dry run validator

* Clean up shell (still not working)

* Bump kittycad-modeling-cmds

* Clean up

* Add logging

* Add proper object_id and face_id mapping, still not working for shell

* Fix faceId

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Add dry-run validation to Loft
Checks one box for #4711

* Add extra check for non solid2ds

---------

Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Double click label on sketch to dimension  (#4816)

* feat: double click segment label to dimension length, POC, need to clean up code!

* fix: cleaning up the PR for review

* fix: cleaning for the PR. Adding more comments and moving some logic

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

* fix: mergining main, auto linter and tsc fixes. Need to make some more

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

* fix: tsc errors are resolved

* chore: added test for constraint

* fix: fixing overlay bug since length labels can now be clicked.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* KCL: Show beautiful Miette errors when a KCL example test fails (#4829)

* KCL: Show beautiful Miette errors when a KCL example test fails

Background: KCL example tests are generated from the stdlib KCL examples in the `#[stdlib]` macro in derive-docs.

Problem: When these tests fail, they output a really unhelpful error message like Kcl(Semantic(KclErrorDetails { source_ranges: [156, 160, 0], message: "Expected a sketch but found array" } )).

Solution: Use miette. Now the errors highlight the KCL code that failed and show exactly what went wrong, on which line, presenting nice diagnostics that look like cargo/rustc output.

* Update helix snapshots

* Move all tests over to electron (#4484)

* Move all tests over to electron

* Pass the correct param to playwright-electron.sh

* Add shebang to script and add macos-14-large as a target

* Get sketch-tests.spec.ts passing in electron

* Try out 4 workers

* Got testing-segment-overlays passing

* Pass testing-selections.spec.ts

* Go back to fix up sketch-tests test

* Pass various.spec.ts, by far the hardest one

* Pass can-sketch-on-all-planes... with ease

* Pass command bar tests

* fmt

* Completely fix code mirror text navigating for tests

* Pass debug pane tests

* Pass desktop export tests

* Pass editor tests

* Pass file tree tests

* Pass onboarding tests

* Corrected a fixme in file-tree.spec!

* Painfully fix hardcoded coordinates in point-click.spec

* Pass machine.spec tests

* Pass projects, fought hard with filechooser

* Pass regresion-tests.spec tests

* Pass network and connection tests

* Pass camera-movement.spec tests

* Extreme time eaten by gizmo test fixes. All passing now.

* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)

* Pass another painful spec suite: testing-settings

* Pass perspective-toggle, interesting note

* Pass samples loading tests

* Pass app header tests

* Pass text-to-cad tests

* Pass segment-overlays (minor ache) and ability to switch to web if needed :)

* Fix a ton of syntax changes and deflake 2 more tests (pain)

* Correct all tsc errors

* Remove to-electron script

* Add an f-ton of shit because playwright doesnt want S P R E A D

* Try CI again

* Stop snapshots of exports (already test in e2e)

* Fix flake in double click editor

* Hopefully help CI flake

* Fixmes, fixmes everywhere

* One more fixme to settings

* Skip another code pane flake

* Port jess's projects.spec tests

* fixup

* Reuse electron window; difficult task

* Rebased and refixed

* Remove duplicate cases

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

* Reduce the workers to something CI can handle

* Lower it further, we need to think about the others

* Update package.json

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Update package.json

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Fix the last tests and tsc errors

* Timeout to 120 and windows-2022-16core

* Fix windows runner detection, enable concurrency temporarily

* Hopefully this time fix windows runner detection

* Comment out Vector, add back removed camera test code

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* Fix camera tests again

* Massively deflake a whole class of tests

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

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

* Try new CI and fix small onboarding test

* Derp

* No github tuning

* Try mac

* Add back all the OS

* Lord, hallow be thy name

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* One last try with window-16-cores

* Trigger CI

* Try AWS Windows runner

* Passing on windows locally with a few skips

* Skip more win tests, add back all three oses

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* Add two more fixmes

* 2 more fixmes

* skip segment overlays on win32

* Another fixme

* Trigger CI

* Trigger CI

* Quick clean up

* Move all tests over to electron

* Pass the correct param to playwright-electron.sh

* Add shebang to script and add macos-14-large as a target

* Get sketch-tests.spec.ts passing in electron

* Try out 4 workers

* Got testing-segment-overlays passing

* Pass testing-selections.spec.ts

* Go back to fix up sketch-tests test

* Pass various.spec.ts, by far the hardest one

* Pass can-sketch-on-all-planes... with ease

* Pass command bar tests

* fmt

* Completely fix code mirror text navigating for tests

* Pass debug pane tests

* Pass desktop export tests

* Pass editor tests

* Pass file tree tests

* Pass onboarding tests

* Corrected a fixme in file-tree.spec!

* Painfully fix hardcoded coordinates in point-click.spec

* Pass machine.spec tests

* Pass projects, fought hard with filechooser

* Pass regresion-tests.spec tests

* Pass network and connection tests

* Pass camera-movement.spec tests

* Extreme time eaten by gizmo test fixes. All passing now.

* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)

* Pass another painful spec suite: testing-settings

* Pass perspective-toggle, interesting note

* Pass samples loading tests

* Pass app header tests

* Pass text-to-cad tests

* Pass segment-overlays (minor ache) and ability to switch to web if needed :)

* Fix a ton of syntax changes and deflake 2 more tests (pain)

* Correct all tsc errors

* Remove to-electron script

* Add an f-ton of shit because playwright doesnt want S P R E A D

* Try CI again

* Stop snapshots of exports (already test in e2e)

* Fix flake in double click editor

* Hopefully help CI flake

* Fixmes, fixmes everywhere

* One more fixme to settings

* Skip another code pane flake

* Port jess's projects.spec tests

* fixup

* Reuse electron window; difficult task

* Rebased and refixed

* Remove duplicate cases

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

* Reduce the workers to something CI can handle

* Lower it further, we need to think about the others

* Update package.json

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Update package.json

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Fix the last tests and tsc errors

* Timeout to 120 and windows-2022-16core

* Fix windows runner detection, enable concurrency temporarily

* Hopefully this time fix windows runner detection

* Comment out Vector, add back removed camera test code

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* Fix camera tests again

* Massively deflake a whole class of tests

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)

* Try new CI and fix small onboarding test

* Derp

* No github tuning

* Try mac

* Add back all the OS

* Lord, hallow be thy name

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Try AWS Windows runner

* Passing on windows locally with a few skips

* Trigger CI

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

* fmt, tsc, lint

* Enable two fixmes again

* Fix lint, codespell, fmt

* Fix lint

* Don't run e2e on draft, add back concurrency, clean up

* One last windows skip

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>

* Add blank line to discord bot message (#4814)

* Add blank link to discord bot message

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* Trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Implement some basic cache program generation (#4840)

Implement some basic cache program generation

A bit ago, @jessfraz added the ability to control reexecution from the
executor. When we did this, it used the digest to determine if there
was a code change rather than a non-code change (whitespace, comment,
etc).

This allows the creation of a new program to be run without clearing the
scene. This, in conjunction with being able to delete Engine objects by
ID will allow us to do some clever stuff when incrementally executing
a program.

I'm still working on something a bit more advanced, but a good first
step to derisk some of the caching behavior here fully is to implement a
basic "changed program" stub.

This process the ast programs (old and new) if it doesn't exactly match.
This would have been a complete refresh before this commit.

 1) Check all overlapping top-level statements of the body of the new and
    old AST and ensure they all match.
      - If this is true, this means that one of the two AST programs has more
        elements then the other, and they all otherwise match (addition or
        deletion of the end of the program). We continue to #2 in this
        case.
      - If this is false, we have a meaingful difference in a section of
        overlapping code. This will result in a cache miss and rebuild
        the scene. We short-cut here and the scene is rebuilt.

 2) Check the lengths of the two bodies.
   - If they're the same, we shouldn't have even been called. We will
     short-cut with a noop cache return (no clear, no program).
   - if the old ast is longer, we've removed instructions from the
     program. We can't delete things now, so this will result in a cache
     miss and rebuild the scene. We short-cut here and the scene is
     rebuilt.
   - If the new ast is longer, we have an insertion of code at the end.

 3) construct a new program using only the new elements from the new
    ast, and return a `CacheResult` that *does not clear the scene*.
    This means nothing will be rebuilt, and only a new object will polp
    onto the scene. This is the first case where we diverge with
    existing behavior.

Signed-off-by: Paul R. Tagliamonte <paul@zoo.dev>

* Fix mac issue after electron test migration PR (#4842)

Fix mac issue after electron test migration pR

* Remove guards from modeling commands in the toolbar (#4800)

* Remove guards from modeling commands in the toolbar

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Remove the deprecated function, update doc comment for the one still in use

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* Remove more selection check functions that are no longer used

* Update E2E tests that assumed the extrude button could be disabled due to selection

* Update a few fillet tests that expected the button to disable based on selection

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

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

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

* Trigger CI

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* Trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>

* Prompt to edit (#4830)

* initial plumbing for getting the new option into the cmd-bar

* start of prompt edit

* update AI poll

* add spinner

* more prompt engineering

* add success toast, allowing user's to reject code

* select code that changed in prompt to edit

* selection in scene should not disappear when opening prompt cmd

* tweak

* fmt

* add tests

* some clean up

* clean up

* fix tests

* Yeet telemetry to text to cad endpoint (#4847)

yeet telemetry to text to cad endpoint

* Tweak prompt wording (#4846)

tweak prompt wording

* update discord bot (#4837)

* Re-enable test 'code pane closed at start' after electron migration (#4841)

* Re-enable 'code pane closed at start'
Relates to #4838

* Enable test on current branch

* Revert "Enable test on current branch"

This reverts commit 0d970b9ad6.

* Add 3-point circle tool (#4832)

* Add 3-point circle tool

This adds a 1st pass for the 3-point circle tool.

There is disabled code to drag around the 3 points and redraw the circle and
a triangle created by those points. It will be enabled in a follow-up PR
when we have circle3Point in the stdlib.

For now, all it does is after the 3rd click, will insert circle center-radius
KCL code for users to modify.

* PR comments

* First draft of a feature tree pane (#4782)

* Fix e2e default planes tests to use mask on state indicator (#4849)

* Fix e2e default planes tests to use mask on state indicator

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* Trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix: don't error on failure to fetch privacy settings (#4799)

* fix: dont error on failure to fetch privacy settings

* Add console warning when we ignore it

---------

Co-authored-by: Tom Pridham <pridham.tom@gmail.com>

* Match package license to LICENSE file (#4882)

* Remove the old Loft GitHub issue link in the toolbar (#4848)

Now that it's available, it shouldn't be there anymore.

* Fix fuzz crate lints and update deps (#4873)

* Fix fuzz to use new API

* Fix fuzz Cargo.toml lints and update lock

* Use app foreground color for focus outline button color so there's no hue collision (#4894)

Towards #4851

* Add support for float numbers in rem() arguments (#4858)

* Add support for float numbers in rem() arguments

* Update docs

* Rename to prevent name collision in docs

* Update docs after rename to NumberArg

* Fix parameter types to follow naming convention

* Change doc comment description to not refer to floating point

* Update docs after NumberArg doc change

* Change function to be more condensed

* Change to not try to preserve ints

* Update docs to use f64

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

* Trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Add auto-retries to macOS build notarization (#4892)

* Add DEBUG=electron-notarize* to build-apps

* Force IS_RELEASE: true

* Temp: Disable version setting based on tag

* Remove deprecated notarize.teamId and add retry logic

* Revert "Remove deprecated notarize.teamId and add retry logic"

This reverts commit 6ff98d784d.

* Retry only on macOS

* Better retry logic for macOS

* Use nick-fields/retry

* Clean up Temp: commits for PR

* Clean up

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

* Trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump nanoid from 3.3.7 to 3.3.8 (#4731)

Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 3.3.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Enable enter for autocompletions in the command palette KCL input (#4896)

* Enable enter for autocompletions in the command palette KCL input

* Oops I commented out code for the variable name input
Thanks for the catch @pierremtb

---------

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Bump rollup from 4.21.0 to 4.29.1 (#4888)

* Bump rollup from 4.21.0 to 4.29.1

Bumps [rollup](https://github.com/rollup/rollup) from 4.21.0 to 4.29.1.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.21.0...v4.29.1)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

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

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Louder Windows codesign errors (#4762)

* WIP: Silent failure in signWin.js
Fixes #4582

* Temp: force release build

* Fake throw

* Temp: another test

* Clean up for merge

* Add parsing keyword function calls inside pipelines (#4907)

Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>

* Remove draft PR filter on e2e tests (#4908)

* Add three point circle stdlib function (#4893)

* Add parsing keyword function calls inside pipelines

Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>

* Add three point circle stdlib function

* Generate new documentation

* Fix 20:20 for the circle three point test

* Convert to using keyword arguments

* Wtf yo

* Remove unused structure

* Use the new simulation tests

* Regenerate documentation

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>

* Move the base CodeMirror KCL support to a local package (#4897)

* Move CodeMirror LRLanguage to new file

This separates the base language support from the LSP and color picker.

* Move the base CodeMirror KCL support to a local package

* Start CodeMirror grammar tests

* Exclude vitest config in tsconfig

* Add KCL path to tsconfig

* Remove stray import

* Drop extension from import

* Use __filename for commonjs compat

* Check exec return before access

* Build ES and CJS to dist

* Format

* Exclude all.test.ts from codespell

This is to work around "fileTests" imported from Lezer. Future codespell versions look
like they'll allow the code to be annotated, which would be nicer.

---------

Co-authored-by: Matt Mundell <matt@mundell.me>

* Fix typo in README (#3843)

Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>

* remove backwards compatibility for snake case in objects (#4920)

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

* CM KCL: Support `=` in record init (#4933)

Support `=` in record init

Co-authored-by: Matt Mundell <matt@mundell.me>

* Bump clap from 4.5.21 to 4.5.23 in /src/wasm-lib (#4928)

Bumps [clap](https://github.com/clap-rs/clap) from 4.5.21 to 4.5.23.
- [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.21...clap_complete-v4.5.23)

---
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>

* Bump @kittycad/lib from 2.0.7 to 2.0.12 (#4922)

Bumps [@kittycad/lib](https://github.com/KittyCAD/kittycad.ts) from 2.0.7 to 2.0.12.
- [Release notes](https://github.com/KittyCAD/kittycad.ts/releases)
- [Commits](https://github.com/KittyCAD/kittycad.ts/compare/v2.0.7...v2.0.12)

---
updated-dependencies:
- dependency-name: "@kittycad/lib"
  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>

* Bump anyhow from 1.0.94 to 1.0.95 in /src/wasm-lib (#4929)

Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.94 to 1.0.95.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.94...1.0.95)

---
updated-dependencies:
- dependency-name: anyhow
  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>

* Bump url from 2.5.3 to 2.5.4 in /src/wasm-lib (#4930)

Bumps [url](https://github.com/servo/rust-url) from 2.5.3 to 2.5.4.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.5.3...v2.5.4)

---
updated-dependencies:
- dependency-name: url
  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>

* Bump wasm-streams from 0.4.1 to 0.4.2 in /src/wasm-lib (#4926)

Bumps [wasm-streams](https://github.com/MattiasBuelens/wasm-streams) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/MattiasBuelens/wasm-streams/releases)
- [Changelog](https://github.com/MattiasBuelens/wasm-streams/blob/main/CHANGELOG.md)
- [Commits](https://github.com/MattiasBuelens/wasm-streams/compare/v0.4.1...v0.4.2)

---
updated-dependencies:
- dependency-name: wasm-streams
  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>

* Bump @csstools/postcss-oklab-function from 4.0.2 to 4.0.7 (#4923)

Bumps [@csstools/postcss-oklab-function](https://github.com/csstools/postcss-plugins/tree/HEAD/plugins/postcss-oklab-function) from 4.0.2 to 4.0.7.
- [Changelog](https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-oklab-function/CHANGELOG.md)
- [Commits](https://github.com/csstools/postcss-plugins/commits/HEAD/plugins/postcss-oklab-function)

---
updated-dependencies:
- dependency-name: "@csstools/postcss-oklab-function"
  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>

* fix: writes to disk when the user accepts the prompt to edit (#4942)

* fix: writes to disk when the user accepts the prompt to edit

* fix: then catch

* Make circle3Point tool an actor (#4906)

* Reduce the amount of data sent to TS and make new fields opt-in (#4913)

* Reduce the amount of data sent back to JS/TS from WASM

* Remove unneeded derives since we shouldn't expose these types

* Alias type to be clearer

* Bump syn from 2.0.87 to 2.0.95 to be compatible with modeling-cmds 0.… (#4945)

Bump syn from 2.0.87 to 2.0.95 to be compatible with modeling-cmds 0.2.86

* fix out of range error (#4931)

* fix out of range error

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

* updates

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

* remove console logs

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

* add a regression test

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

---------

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

* Run chrome e2e snapshots only on linux (#4947)

* Run chrome e2e snapshots only on linux

* Wtf is this 1-indexed

* Force 1/1 sharding

* Add TODO

* Nadro/3079/screenshot improvements (#3917)

* chore: swapped screenshot to only use the video stream

* feat: video stream screenshot, native electron screenshot

* fix: auto tsc, fmt, xgen, lint

* fix: fixing tsc errors

* fix: removing debug console.log

* fix: renaming ScreenShot to Screenshot

* fix: deleting console log from debugging

* fix: bug with what source was referenced

* fix: using a productName

* fix: improving usage for native screenshots and detecthing support

* fix: fmt

* chore: updated rust test documentation

* fix: typo in readme

* fix: leaving package.json and yarn.lock the same as main??

* bump

* bump

* bump again

* bump again2

* feat: implemented zoom to fit on code change if previous AST was empty (#3925)

* feat: implemented zoom to fit on code change if previous AST was empty

* feat: implementing selectAll text logic to enable select all and copy and paste and zoom to fit will work

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

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

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

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

* fix: clarifying comment in _isAstEmpty

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

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

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

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

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

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

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

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

* bump

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* bump again

* fix: fixing new type since this branch is old

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

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)

* bump

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

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

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: 49fl <ircsurfer33@gmail.com>

* Add dependabot group for all serde dependencies (#4944)

* Fix formatting of dependabot.yml

* Add dependabot group for all serde dependencies

* CM KCL: = and => are optional in fn declarations (#4941)

CM KCL: `=` and `=>` are optional in fn declarations

Co-authored-by: Matt Mundell <matt@mundell.me>

* Bump ts-rs from 10.0.0 to 10.1.0 (#4949)

* Add toolbar buttons for text-to-cad and prompt-to-edit (#4938)

* Add toolbar buttons for text-to-cad and prompt-to-edit
Resolves #4890

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

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

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

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

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

* `preventDefault` on <kbd>Enter</kbd> with textarea input so buttons aren't clicked as well

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)

* Trigger CI

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>

* Bump quote from 1.0.37 to 1.0.38 in /src/wasm-lib (#4951)

Bumps [quote](https://github.com/dtolnay/quote) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.37...1.0.38)

---
updated-dependencies:
- dependency-name: quote
  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>

* array pop with unlabled kw arg

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Signed-off-by: Paul R. Tagliamonte <paul@zoo.dev>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
Co-authored-by: 49fl <ircsurfer33@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
Co-authored-by: Paul Tagliamonte <paul@zoo.dev>
Co-authored-by: Josh Gomez <114548659+jgomez720@users.noreply.github.com>
Co-authored-by: Tom Pridham <pridham.tom@gmail.com>
Co-authored-by: Matt Mundell <32057441+mattmundell@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Matt Mundell <matt@mundell.me>
Co-authored-by: alteous <david@harvey-macaulay.com>
2025-01-07 20:24:24 +00:00
2eb7c382bf Bump @codemirror/lint from 6.8.1 to 6.8.4 (#4955)
Bumps [@codemirror/lint](https://github.com/codemirror/lint) from 6.8.1 to 6.8.4.
- [Changelog](https://github.com/codemirror/lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lint/compare/6.8.1...6.8.4)

---
updated-dependencies:
- dependency-name: "@codemirror/lint"
  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>
2025-01-07 20:23:07 +00:00
38913ecb98 Bump three and @types/three (#4956)
Bumps [three](https://github.com/mrdoob/three.js) and [@types/three](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/three). These dependencies needed to be updated together.

Updates `three` from 0.166.1 to 0.172.0
- [Release notes](https://github.com/mrdoob/three.js/releases)
- [Commits](https://github.com/mrdoob/three.js/commits)

Updates `@types/three` from 0.163.0 to 0.172.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/three)

---
updated-dependencies:
- dependency-name: three
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/three"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 20:19:58 +00:00
debd06129f CM KCL: numbers must have digits after dot (#4963)
Co-authored-by: Matt Mundell <matt@mundell.me>
2025-01-07 12:19:31 -08:00
d38bd342a0 Bump winnow from 0.6.20 to 0.6.22 in /src/wasm-lib (#4954)
Bumps [winnow](https://github.com/winnow-rs/winnow) from 0.6.20 to 0.6.22.
- [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md)
- [Commits](https://github.com/winnow-rs/winnow/compare/v0.6.20...v0.6.22)

---
updated-dependencies:
- dependency-name: winnow
  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>
2025-01-07 20:16:56 +00:00
f026f10335 Bump zip from 2.2.0 to 2.2.2 in /src/wasm-lib (#4952)
Bumps [zip](https://github.com/zip-rs/zip2) from 2.2.0 to 2.2.2.
- [Release notes](https://github.com/zip-rs/zip2/releases)
- [Changelog](https://github.com/zip-rs/zip2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zip-rs/zip2/compare/v2.2.0...v2.2.2)

---
updated-dependencies:
- dependency-name: zip
  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>
2025-01-07 18:06:37 +00:00
895d7ebc6d Bump the serde-dependencies group in /src/wasm-lib with 2 updates (#4950)
Bumps the serde-dependencies group in /src/wasm-lib with 2 updates: [serde_json](https://github.com/serde-rs/json) and [serde](https://github.com/serde-rs/serde).


Updates `serde_json` from 1.0.133 to 1.0.135
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.133...v1.0.135)

Updates `serde` from 1.0.216 to 1.0.217
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.216...v1.0.217)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 17:55:33 +00:00
65edf17a44 Bump quote from 1.0.37 to 1.0.38 in /src/wasm-lib (#4951)
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.37...1.0.38)

---
updated-dependencies:
- dependency-name: quote
  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>
2025-01-07 09:14:32 -08:00
89 changed files with 9896 additions and 1576 deletions

View File

@ -24,3 +24,5 @@ once fixed in engine will just start working here with no language changes.
chamfer cases work currently.
- **Appearance**: Changing the appearance on a loft does not work.
- **Helix**: Currently sweeping a helix does not work.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -48,6 +48,7 @@ layout: manual
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix)
* [`helixRevolutions`](kcl/helixRevolutions)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`import`](kcl/import)
@ -81,6 +82,7 @@ layout: manual
* [`pi`](kcl/pi)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon)
* [`pop`](kcl/pop)
* [`pow`](kcl/pow)
* [`profileStart`](kcl/profileStart)
* [`profileStartX`](kcl/profileStartX)

39
docs/kcl/pop.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,19 +1,19 @@
---
title: "AxisOrEdgeReference"
excerpt: "Axis or tagged edge."
title: "Axis2dOrEdgeReference"
excerpt: "A 2D axis or tagged edge."
layout: manual
---
Axis or tagged edge.
A 2D axis or tagged edge.
**This schema accepts any of the following:**
Axis and origin.
2D axis and origin.
[`AxisAndOrigin`](/docs/kcl/types/AxisAndOrigin)
[`AxisAndOrigin2d`](/docs/kcl/types/AxisAndOrigin2d)

View File

@ -0,0 +1,42 @@
---
title: "Axis3dOrEdgeReference"
excerpt: "A 3D axis or tagged edge."
layout: manual
---
A 3D axis or tagged edge.
**This schema accepts any of the following:**
3D axis and origin.
[`AxisAndOrigin3d`](/docs/kcl/types/AxisAndOrigin3d)
----
Tagged edge.
[`EdgeReference`](/docs/kcl/types/EdgeReference)
----

View File

@ -1,10 +1,10 @@
---
title: "AxisAndOrigin"
excerpt: "Axis and origin."
title: "AxisAndOrigin2d"
excerpt: "A 2D axis and origin."
layout: manual
---
Axis and origin.
A 2D axis and origin.

View File

@ -0,0 +1,105 @@
---
title: "AxisAndOrigin3d"
excerpt: "A 3D axis and origin."
layout: manual
---
A 3D axis and origin.
**This schema accepts exactly one of the following:**
X-axis.
**enum:** `X`
----
Y-axis.
**enum:** `Y`
----
Z-axis.
**enum:** `Z`
----
Flip the X-axis.
**enum:** `-X`
----
Flip the Y-axis.
**enum:** `-Y`
----
Flip the Z-axis.
**enum:** `-Z`
----
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `custom` |`object`| | No |
----

25
docs/kcl/types/Helix.md Normal file
View File

@ -0,0 +1,25 @@
---
title: "Helix"
excerpt: "A helix."
layout: manual
---
A helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |`string`| The id of the helix. | No |
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -1,10 +1,10 @@
---
title: "HelixData"
excerpt: "Data for helices."
excerpt: "Data for a helix."
layout: manual
---
Data for helices.
Data for a helix.
**Type:** `object`
@ -19,6 +19,8 @@ Data for helices.
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
| `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No |
| `length` |`number`| Length of the helix. | No |
| `radius` |`number`| Radius of the helix. | No |
| `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No |

View File

@ -0,0 +1,24 @@
---
title: "HelixRevolutionsData"
excerpt: "Data for helix revolutions."
layout: manual
---
Data for helix revolutions.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
| `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No |

View File

@ -0,0 +1,25 @@
---
title: "HelixValue"
excerpt: "A helix."
layout: manual
---
A helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |`string`| The id of the helix. | No |
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -285,6 +285,27 @@ An solid is a collection of extrude surfaces.
| `value` |`[` [`Solid`](/docs/kcl/types/Solid) `]`| | No |
----
A helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No |
| `value` |`string`| The id of the helix. | No |
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
----
Data for an imported geometry.

View File

@ -16,6 +16,6 @@ Data for a mirror.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `axis` |[`AxisOrEdgeReference`](/docs/kcl/types/AxisOrEdgeReference)| Axis to use as mirror. | No |
| `axis` |[`Axis2dOrEdgeReference`](/docs/kcl/types/Axis2dOrEdgeReference)| Axis to use as mirror. | No |

View File

@ -17,7 +17,7 @@ Data for revolution surfaces.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `angle` |`number` (**maximum:** 360.0) (**minimum:** -360.0)| Angle to revolve (in degrees). Default is 360. | No |
| `axis` |[`AxisOrEdgeReference`](/docs/kcl/types/AxisOrEdgeReference)| Axis of revolution. | No |
| `axis` |[`Axis2dOrEdgeReference`](/docs/kcl/types/Axis2dOrEdgeReference)| Axis of revolution. | No |
| `tolerance` |`number`| Tolerance for the revolve operation. | No |

View File

@ -16,7 +16,7 @@ Data for a sweep.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `path` |[`Sketch`](/docs/kcl/types/Sketch)| The path to sweep along. | No |
| `path` |[`SweepPath`](/docs/kcl/types/SweepPath)| The path to sweep along. | No |
| `sectional` |`boolean`| If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. | No |
| `tolerance` |`number`| Tolerance for the sweep operation. | No |

View File

@ -0,0 +1,42 @@
---
title: "SweepPath"
excerpt: "A path to sweep along."
layout: manual
---
A path to sweep along.
**This schema accepts any of the following:**
A path to sweep along.
[`Sketch`](/docs/kcl/types/Sketch)
----
A path to sweep along.
[`Helix`](/docs/kcl/types/Helix)
----

View File

@ -39,8 +39,8 @@ test.describe('Sketch tests', () => {
${startProfileAt1}
|> arc({
radius = screwRadius,
angle_start = 0,
angle_end = 360
angleStart = 0,
angleEnd = 360
}, %)
part001 = startSketchOn('XY')
@ -60,8 +60,8 @@ test.describe('Sketch tests', () => {
|> yLine(wireOffset, %)
|> arc({
radius = wireRadius,
angle_start = 0,
angle_end = 180
angleStart = 0,
angleEnd = 180
}, %)
|> yLine(-wireOffset, %)
|> xLine(-width / 4, %)

View File

@ -389,25 +389,25 @@ test.describe('Testing selections', () => {
await expect(u.codeLocator).toContainText(`sketch005 = startSketchOn({
plane = {
origin = { x = 0, y = -50, z = 0 },
x_axis = { x = 1, y = 0, z = 0 },
y_axis = { x = 0, y = 0, z = 1 },
z_axis = { x = 0, y = -1, z = 0 }
xAxis = { x = 1, y = 0, z = 0 },
yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 0, y = -1, z = 0 }
}
})`)
await expect(u.codeLocator).toContainText(`sketch003 = startSketchOn({
plane = {
origin = { x = 116.53, y = 0, z = 163.25 },
x_axis = { x = -0.81, y = 0, z = 0.58 },
y_axis = { x = 0, y = -1, z = 0 },
z_axis = { x = 0.58, y = 0, z = 0.81 }
xAxis = { x = -0.81, y = 0, z = 0.58 },
yAxis = { x = 0, y = -1, z = 0 },
zAxis = { x = 0.58, y = 0, z = 0.81 }
}
})`)
await expect(u.codeLocator).toContainText(`sketch002 = startSketchOn({
plane = {
origin = { x = -91.74, y = 0, z = 80.89 },
x_axis = { x = -0.66, y = 0, z = -0.75 },
y_axis = { x = 0, y = -1, z = 0 },
z_axis = { x = -0.75, y = 0, z = 0.66 }
xAxis = { x = -0.66, y = 0, z = -0.75 },
yAxis = { x = 0, y = -1, z = 0 },
zAxis = { x = -0.75, y = 0, z = 0.66 }
}
})`)

View File

@ -15,7 +15,7 @@
"@codemirror/autocomplete": "^6.17.0",
"@codemirror/commands": "^6.6.0",
"@codemirror/language": "^6.10.3",
"@codemirror/lint": "^6.8.1",
"@codemirror/lint": "^6.8.4",
"@codemirror/search": "^6.5.6",
"@codemirror/state": "^6.4.1",
"@codemirror/theme-one-dark": "^6.1.2",
@ -52,13 +52,13 @@
"react": "^18.3.1",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-hotkeys-hook": "^4.5.1",
"react-hotkeys-hook": "^4.6.1",
"react-json-view": "^1.21.3",
"react-modal": "^3.16.1",
"react-modal": "^3.16.3",
"react-modal-promise": "^1.0.2",
"react-router-dom": "^6.28.0",
"sketch-helpers": "^0.0.4",
"three": "^0.166.1",
"three": "^0.172.0",
"ua-parser-js": "^1.0.37",
"uuid": "^11.0.2",
"vscode-jsonrpc": "^8.2.1",
@ -166,7 +166,7 @@
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.1",
"@types/react-modal": "^3.16.3",
"@types/three": "^0.163.0",
"@types/three": "^0.172.0",
"@types/ua-parser-js": "^0.7.39",
"@types/uuid": "^9.0.8",
"@types/wicg-file-system-access": "^2023.10.5",
@ -186,7 +186,7 @@
"eslint-plugin-css-modules": "^2.12.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-suggest-no-throw": "^1.0.0",
"happy-dom": "^15.11.7",
"happy-dom": "^16.3.0",
"http-server": "^14.1.1",
"husky": "^9.1.5",
"kill-port": "^2.0.1",

View File

@ -85,7 +85,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* }
@tokens {
String[isolate] { "'" ("\\" _ | !['\\])* "'" | '"' ("\\" _ | !["\\])* '"' }
Number { "." @digit+ | @digit+ ("." @digit*)? }
Number { "." @digit+ | @digit+ ("." @digit+)? }
@precedence { Number, "." }
AddOp { "+" | "-" }

View File

@ -0,0 +1,43 @@
# spaced
a = [0 .. 1]
==>
Program(VariableDeclaration(VariableDefinition,
Equals,
ArrayExpression(IntegerRange(Number,
Number))))
# compact
a = [0..1]
==>
Program(VariableDeclaration(VariableDefinition,
Equals,
ArrayExpression(IntegerRange(Number,
Number))))
# expr spaced
a = [start .. start + 10]
==>
Program(VariableDeclaration(VariableDefinition,
Equals,
ArrayExpression(IntegerRange(VariableName,
BinaryExpression(VariableName,
AddOp,
Number)))))
# expr compact
a = [start..start + 10]
==>
Program(VariableDeclaration(VariableDefinition,
Equals,
ArrayExpression(IntegerRange(VariableName,
BinaryExpression(VariableName,
AddOp,
Number)))))

View File

@ -1,42 +0,0 @@
import { fireEvent, render, screen } from '@testing-library/react'
import { vi } from 'vitest'
import { UpdaterModal } from './UpdaterModal'
describe('UpdaterModal tests', () => {
test('Renders the modal', () => {
const callback = vi.fn()
const data = {
version: '1.2.3',
date: '2021-22-23T21:22:23Z',
body: 'This is the body.',
}
render(
<UpdaterModal
isOpen={true}
onReject={() => {}}
onResolve={callback}
instanceId=""
open={false}
close={(res) => {}}
version={data.version}
date={data.date}
body={data.body}
/>
)
expect(screen.getByTestId('update-version')).toHaveTextContent(data.version)
const updateButton = screen.getByTestId('update-button-update')
expect(updateButton).toBeEnabled()
fireEvent.click(updateButton)
expect(callback.mock.calls).toHaveLength(1)
expect(callback.mock.lastCall[0]).toEqual({ wantUpdate: true })
const cancelButton = screen.getByTestId('update-button-cancel')
expect(cancelButton).toBeEnabled()
fireEvent.click(cancelButton)
expect(callback.mock.calls).toHaveLength(2)
expect(callback.mock.lastCall[0]).toEqual({ wantUpdate: false })
})
})

View File

@ -1,87 +0,0 @@
import { create, InstanceProps } from 'react-modal-promise'
import { ActionButton } from './ActionButton'
import { Logo } from './Logo'
import { Marked } from '@ts-stack/markdown'
type ModalResolve = {
wantUpdate: boolean
}
type ModalReject = boolean
type UpdaterModalProps = InstanceProps<ModalResolve, ModalReject> & {
version: string
date?: string
body?: string
}
export const createUpdaterModal = create<
UpdaterModalProps,
ModalResolve,
ModalReject
>
export const UpdaterModal = ({
onResolve,
version,
date,
body,
}: UpdaterModalProps) => (
<div className="fixed inset-0 z-50 grid place-content-center bg-chalkboard-110/50">
<div className="max-w-3xl min-w-[45rem] p-8 rounded bg-chalkboard-10 dark:bg-chalkboard-90">
<div className="flex items-center">
<h1 className="flex-grow text-3xl font-bold">New version available!</h1>
<Logo className="h-9" />
</div>
<div className="my-4 flex items-baseline">
<span
className="px-3 py-1 text-xl rounded-full bg-energy-10 text-energy-80"
data-testid="update-version"
>
v{version}
</span>
<span className="ml-4 text-sm text-gray-400">Published on {date}</span>
</div>
{/* TODO: fix list bullets */}
{body && (
<div
className="my-4 max-h-60 overflow-y-auto"
dangerouslySetInnerHTML={{
__html: Marked.parse(body, {
gfm: true,
breaks: true,
sanitize: true,
}),
}}
></div>
)}
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => onResolve({ wantUpdate: false })}
iconStart={{
icon: 'close',
bgClassName: 'bg-destroy-80',
iconClassName: 'text-destroy-20 group-hover:text-destroy-10',
}}
className="hover:border-destroy-40 hover:bg-destroy-10/50 dark:hover:bg-destroy-80/50"
data-testid="update-button-cancel"
>
Not now
</ActionButton>
<ActionButton
Element="button"
onClick={() => onResolve({ wantUpdate: true })}
iconStart={{
icon: 'arrowRight',
bgClassName: 'dark:bg-chalkboard-80',
}}
className="dark:hover:bg-chalkboard-80/50"
data-testid="update-button-update"
>
Update
</ActionButton>
</div>
</div>
</div>
)

View File

@ -47,7 +47,7 @@ describe('parsing errors', () => {
const result = parse(code)
if (err(result)) throw result
const error = result.errors[0]
expect(error.message).toBe('Unexpected token: (')
expect(error.sourceRange).toEqual([27, 28, 0])
expect(error.message).toBe('Array is missing a closing bracket(`]`)')
expect(error.sourceRange).toEqual([28, 29, 0])
})
})

View File

@ -1,6 +1,6 @@
import {
Program,
_executor,
executor,
ProgramMemory,
kclLint,
emptyExecState,
@ -64,7 +64,7 @@ export async function executeAst({
try {
const execState = await (programMemoryOverride
? enginelessExecutor(ast, programMemoryOverride)
: _executor(ast, engineCommandManager))
: executor(ast, engineCommandManager))
await engineCommandManager.waitForAllCommands()

View File

@ -806,9 +806,9 @@ sketch001 = startSketchOn('XZ')
sketch002 = startSketchOn({
plane = {
origin = { x = 1, y = 2, z = 3 },
x_axis = { x = 4, y = 5, z = 6 },
y_axis = { x = 7, y = 8, z = 9 },
z_axis = { x = 10, y = 11, z = 12 }
xAxis = { x = 4, y = 5, z = 6 },
yAxis = { x = 7, y = 8, z = 9 },
zAxis = { x = 10, y = 11, z = 12 }
}
})
|> startProfileAt([-12.55, 2.89], %)
@ -862,9 +862,9 @@ sketch001 = startSketchOn('XZ')
sketch002 = startSketchOn({
plane = {
origin = { x = 1, y = 2, z = 3 },
x_axis = { x = 4, y = 5, z = 6 },
y_axis = { x = 7, y = 8, z = 9 },
z_axis = { x = 10, y = 11, z = 12 }
xAxis = { x = 4, y = 5, z = 6 },
yAxis = { x = 7, y = 8, z = 9 },
zAxis = { x = 10, y = 11, z = 12 }
}
})
|> startProfileAt([-12.55, 2.89], %)

View File

@ -1278,17 +1278,17 @@ export async function deleteFromSelection(
y: roundLiteral(faceDetails.origin.y),
z: roundLiteral(faceDetails.origin.z),
}),
x_axis: createObjectExpression({
xAxis: createObjectExpression({
x: roundLiteral(faceDetails.x_axis.x),
y: roundLiteral(faceDetails.x_axis.y),
z: roundLiteral(faceDetails.x_axis.z),
}),
y_axis: createObjectExpression({
yAxis: createObjectExpression({
x: roundLiteral(faceDetails.y_axis.x),
y: roundLiteral(faceDetails.y_axis.y),
z: roundLiteral(faceDetails.y_axis.z),
}),
z_axis: createObjectExpression({
zAxis: createObjectExpression({
x: roundLiteral(faceDetails.z_axis.x),
y: roundLiteral(faceDetails.z_axis.y),
z: roundLiteral(faceDetails.z_axis.z),

View File

@ -506,22 +506,6 @@ export const executor = async (
return Promise.reject(programMemoryOverride)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
engineCommandManager.startNewSession()
const _programMemory = await _executor(
node,
engineCommandManager,
programMemoryOverride
)
await engineCommandManager.waitForAllCommands()
return _programMemory
}
export const _executor = async (
node: Node<Program>,
engineCommandManager: EngineCommandManager,
programMemoryOverride: ProgramMemory | Error | null = null
): Promise<ExecState> => {
if (programMemoryOverride !== null && err(programMemoryOverride))
return Promise.reject(programMemoryOverride)

View File

@ -1,20 +1,16 @@
import {
Program,
ProgramMemory,
_executor,
executor,
SourceRange,
ExecState,
} from '../lang/wasm'
import {
EngineCommandManager,
EngineCommandManagerEvents,
} from 'lang/std/engineConnection'
import { EngineCommandManager } from 'lang/std/engineConnection'
import { EngineCommand } from 'lang/std/artifactGraph'
import { Models } from '@kittycad/lib'
import { v4 as uuidv4 } from 'uuid'
import { DefaultPlanes } from 'wasm-lib/kcl/bindings/DefaultPlanes'
import { err, reportRejection } from 'lib/trap'
import { toSync } from './utils'
import { err } from 'lib/trap'
import { Node } from 'wasm-lib/kcl/bindings/Node'
type WebSocketResponse = Models['WebSocketResponse_type']
@ -94,36 +90,7 @@ export async function enginelessExecutor(
}) as any as EngineCommandManager
// eslint-disable-next-line @typescript-eslint/no-floating-promises
mockEngineCommandManager.startNewSession()
const execState = await _executor(ast, mockEngineCommandManager, pmo)
const execState = await executor(ast, mockEngineCommandManager, pmo)
await mockEngineCommandManager.waitForAllCommands()
return execState
}
export async function executor(
ast: Node<Program>,
pmo: ProgramMemory = ProgramMemory.empty()
): Promise<ExecState> {
const engineCommandManager = new EngineCommandManager()
engineCommandManager.start({
setIsStreamReady: () => {},
setMediaStream: () => {},
width: 0,
height: 0,
makeDefaultPlanes: () => {
return new Promise((resolve) => resolve(defaultPlanes))
},
})
return new Promise((resolve) => {
engineCommandManager.addEventListener(
EngineCommandManagerEvents.SceneReady,
toSync(async () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
engineCommandManager.startNewSession()
const execState = await _executor(ast, engineCommandManager, pmo)
await engineCommandManager.waitForAllCommands()
resolve(execState)
}, reportRejection)
)
})
}

View File

@ -181,9 +181,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.83"
version = "0.1.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
dependencies = [
"proc-macro2",
"quote",
@ -1819,9 +1819,9 @@ dependencies = [
[[package]]
name = "kittycad-modeling-cmds"
version = "0.2.79"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a9cab4476455be70ea57643c31444068b056d091bd348cab6044c0d8ad7fcc"
checksum = "65e34a8eeb4fff5167666d1f2bc36c95d08ab3a0f736a02c8d33a8cde21cfd8d"
dependencies = [
"anyhow",
"chrono",
@ -2687,9 +2687,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@ -3200,9 +3200,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
@ -3218,9 +3218,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
@ -3240,9 +3240,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.133"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
dependencies = [
"indexmap 2.7.0",
"itoa",
@ -4609,9 +4609,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.20"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980"
dependencies = [
"memchr",
]
@ -4748,9 +4748,9 @@ dependencies = [
[[package]]
name = "zip"
version = "2.2.0"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494"
checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45"
dependencies = [
"arbitrary",
"crc32fast",
@ -4758,5 +4758,5 @@ dependencies = [
"displaydoc",
"indexmap 2.7.0",
"memchr",
"thiserror 1.0.68",
"thiserror 2.0.0",
]

View File

@ -16,7 +16,7 @@ gloo-utils = "0.2.0"
kcl-lib = { path = "kcl" }
kittycad.workspace = true
lazy_static = "1.5.0"
serde_json = "1.0.128"
serde_json = "1.0.135"
tokio = { version = "1.41.1", features = ["sync"] }
toml = "0.8.19"
uuid = { version = "1.11.0", features = ["v4", "js", "serde"] }
@ -76,7 +76,7 @@ members = [
[workspace.dependencies]
http = "1"
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
kittycad-modeling-cmds = { version = "0.2.79", features = ["websocket"] }
kittycad-modeling-cmds = { version = "0.2.86", features = ["websocket"] }
[workspace.lints.clippy]
assertions_on_result_states = "warn"

View File

@ -18,7 +18,7 @@ once_cell = "1.20.2"
proc-macro2 = "1"
quote = "1"
regex = "1.11"
serde = { version = "1.0.214", features = ["derive"] }
serde = { version = "1.0.217", features = ["derive"] }
serde_tokenstream = "0.2"
syn = { version = "2.0.95", features = ["full"] }

View File

@ -10,8 +10,8 @@ anyhow = "1.0.95"
hyper = { version = "0.14.29", features = ["http1", "server", "tcp"] }
kcl-lib = { version = "0.2", path = "../kcl" }
pico-args = "0.5.0"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.128"
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.135"
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
[lints]

View File

@ -14,7 +14,7 @@ path = "src/tool.rs"
[dependencies]
anyhow = "1"
async-trait = "0.1.81"
async-trait = "0.1.85"
indexmap = "2.7.0"
kcl-lib = { path = "../kcl" }
kittycad = { workspace = true, features = ["clap"] }

View File

@ -13,7 +13,7 @@ keywords = ["kcl", "KittyCAD", "CAD"]
[dependencies]
anyhow = { version = "1.0.95", features = ["backtrace"] }
async-recursion = "1.1.1"
async-trait = "0.1.83"
async-trait = "0.1.85"
base64 = "0.22.1"
chrono = "0.4.38"
clap = { version = "4.5.23", default-features = false, optional = true, features = [
@ -54,8 +54,8 @@ schemars = { version = "0.8.17", features = [
"uuid1",
"preserve_order",
] }
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.128"
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.135"
sha2 = "0.10.8"
tabled = { version = "0.15.0", optional = true }
thiserror = "2.0.0"
@ -73,8 +73,8 @@ urlencoding = "2.1.3"
uuid = { version = "1.11.0", features = ["v4", "js", "serde"] }
validator = { version = "0.19.0", features = ["derive"] }
web-time = "1.1"
winnow = "0.6.18"
zip = { version = "2.0.0", default-features = false }
winnow = "0.6.22"
zip = { version = "2.2.2", default-features = false }
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = { version = "0.3.72" }

View File

@ -535,7 +535,11 @@ fn generate_type(
|| name == "CircularPattern3dData"
|| name == "LinearPattern2dData"
|| name == "LinearPattern3dData"
|| name == "Mirror2dData")
|| name == "Mirror2dData"
|| name == "Axis2dOrEdgeReference"
|| name == "Axis3dOrEdgeReference"
|| name == "AxisAndOrigin2d"
|| name == "AxisAndOrigin3d")
{
return Err(anyhow::anyhow!("Type name is not pascal cased: {}", name));
}

View File

@ -7,7 +7,9 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclErrorDetails,
exec::{ProgramMemory, Sketch},
execution::{Face, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet, TagIdentifier},
execution::{
Face, Helix, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet, TagIdentifier,
},
parsing::{
ast::types::{FunctionExpression, KclNone, LiteralValue, TagDeclarator, TagNode},
token::NumericSuffix,
@ -72,6 +74,7 @@ pub enum KclValue {
Solids {
value: Vec<Box<Solid>>,
},
Helix(Box<Helix>),
ImportedGeometry(ImportedGeometry),
#[ts(skip)]
Function {
@ -141,6 +144,7 @@ impl From<KclValue> for Vec<SourceRange> {
KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Sketch { value } => to_vec_sr(&value.meta),
KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Helix(e) => to_vec_sr(&e.meta),
KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta),
KclValue::Function { meta, .. } => to_vec_sr(&meta),
KclValue::Plane(p) => to_vec_sr(&p.meta),
@ -171,6 +175,7 @@ impl From<&KclValue> for Vec<SourceRange> {
KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Sketch { value } => to_vec_sr(&value.meta),
KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Helix(x) => to_vec_sr(&x.meta),
KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta),
KclValue::Function { meta, .. } => to_vec_sr(meta),
KclValue::Plane(p) => to_vec_sr(&p.meta),
@ -206,6 +211,7 @@ impl KclValue {
KclValue::Sketches { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(),
KclValue::Solid(x) => x.meta.clone(),
KclValue::Solids { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(),
KclValue::Helix(x) => x.meta.clone(),
KclValue::ImportedGeometry(x) => x.meta.clone(),
KclValue::Function { meta, .. } => meta.clone(),
KclValue::Module { meta, .. } => meta.clone(),
@ -264,6 +270,7 @@ impl KclValue {
KclValue::Solids { .. } => "Solids",
KclValue::Sketch { .. } => "Sketch",
KclValue::Sketches { .. } => "Sketches",
KclValue::Helix(_) => "Helix",
KclValue::ImportedGeometry(_) => "ImportedGeometry",
KclValue::Function { .. } => "Function",
KclValue::Plane(_) => "Plane",

View File

@ -702,6 +702,23 @@ pub struct ImportedGeometry {
pub meta: Vec<Metadata>,
}
/// A helix.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Helix {
/// The id of the helix.
pub value: uuid::Uuid,
/// Number of revolutions.
pub revolutions: f64,
/// Start angle (in degrees).
pub angle_start: f64,
/// Is the helix rotation counter clockwise?
pub ccw: bool,
#[serde(rename = "__meta")]
pub meta: Vec<Metadata>,
}
/// A plane.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]

View File

@ -12,6 +12,7 @@ use winnow::{
token::{any, one_of, take_till},
};
use super::{ast::types::LabelledExpression, token::NumericSuffix};
use crate::{
docs::StdLibFn,
errors::{CompilationError, Severity, Tag},
@ -33,8 +34,6 @@ use crate::{
SourceRange,
};
use super::{ast::types::LabelledExpression, token::NumericSuffix};
thread_local! {
/// The current `ParseContext`. `None` if parsing is not currently happening on this thread.
static CTXT: RefCell<Option<ParseContext>> = const { RefCell::new(None) };
@ -683,8 +682,8 @@ pub enum NonCodeOr<T> {
fn array(i: &mut TokenSlice) -> PResult<Expr> {
alt((
array_empty.map(Box::new).map(Expr::ArrayExpression),
array_elem_by_elem.map(Box::new).map(Expr::ArrayExpression),
array_end_start.map(Box::new).map(Expr::ArrayRangeExpression),
array_elem_by_elem.map(Box::new).map(Expr::ArrayExpression),
))
.parse_next(i)
}
@ -732,7 +731,20 @@ pub(crate) fn array_elem_by_elem(i: &mut TokenSlice) -> PResult<Node<ArrayExpres
.context(expected("array contents, a list of elements (like [1, 2, 3])"))
.parse_next(i)?;
ignore_whitespace(i);
let end = close_bracket(i)?.end;
let end = close_bracket(i)
.map_err(|e| {
if let Some(mut err) = e.clone().into_inner() {
err.cause = Some(CompilationError::fatal(
open.as_source_range(),
"Array is missing a closing bracket(`]`)",
));
ErrMode::Cut(err)
} else {
// ErrMode::Incomplete, not sure if it's actually possible to end up with this here
e
}
})?
.end;
// Sort the array's elements (i.e. expression nodes) from the noncode nodes.
let (elements, non_code_nodes): (Vec<_>, HashMap<usize, _>) = elements.into_iter().enumerate().fold(
@ -4319,6 +4331,13 @@ let myBox = box([0,0], -3, -16, -10)
assert_no_err(some_program_string);
}
#[test]
fn test_parse_missing_closing_bracket() {
let some_program_string = r#"
sketch001 = startSketchOn('XZ') |> startProfileAt([90.45, 119.09, %)"#;
assert_err(some_program_string, "Array is missing a closing bracket(`]`)", [51, 52]);
}
#[test]
fn warn_object_expr() {
let some_program_string = "{ foo: bar }";

View File

@ -1677,3 +1677,66 @@ mod circle_three_point {
super::execute(TEST_NAME, true).await
}
}
mod array_elem_pop {
const TEST_NAME: &str = "array_elem_pop";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[test]
fn unparse() {
super::unparse(TEST_NAME)
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, false).await
}
}
mod array_elem_pop_empty_fail {
const TEST_NAME: &str = "array_elem_pop_empty_fail";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[test]
fn unparse() {
super::unparse(TEST_NAME)
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, false).await
}
}
mod array_elem_pop_fail {
const TEST_NAME: &str = "array_elem_pop_fail";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[test]
fn unparse() {
super::unparse(TEST_NAME)
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, false).await
}
}

View File

@ -8,12 +8,12 @@ use super::shapes::PolygonType;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
ExecState, ExecutorContext, ExtrudeSurface, KclObjectFields, KclValue, Metadata, Sketch, SketchSet,
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSet,
SketchSurface, Solid, SolidSet, TagIdentifier,
},
parsing::ast::types::TagNode,
source_range::SourceRange,
std::{shapes::SketchOrSurface, sketch::FaceTag, FnAsArg},
std::{shapes::SketchOrSurface, sketch::FaceTag, sweep::SweepPath, FnAsArg},
ModuleId,
};
@ -634,7 +634,7 @@ where
message: format!(
"Argument at index {i} was supposed to be type {} but found {}",
type_name::<T>(),
arg.value.human_friendly_type()
arg.value.human_friendly_type(),
),
source_ranges: arg.source_ranges(),
}));
@ -1105,13 +1105,34 @@ impl<'a> FromKclValue<'a> for super::appearance::AppearanceData {
}
impl<'a> FromKclValue<'a> for super::helix::HelixData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, revolutions);
let_field_of!(obj, length);
let_field_of!(obj, ccw?);
let_field_of!(obj, radius);
let_field_of!(obj, axis);
let ccw = ccw.unwrap_or_default();
let angle_start = obj.get("angleStart")?.as_f64()?;
Some(Self {
revolutions,
angle_start,
ccw,
length,
radius,
axis,
})
}
}
impl<'a> FromKclValue<'a> for super::helix::HelixRevolutionsData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, revolutions);
let_field_of!(obj, length?);
let_field_of!(obj, ccw?);
let ccw = ccw.unwrap_or_default();
let angle_start = obj.get("angleStart").or_else(|| obj.get("angle_start"))?.as_f64()?;
let angle_start = obj.get("angleStart")?.as_f64()?;
Some(Self {
revolutions,
angle_start,
@ -1159,8 +1180,8 @@ impl<'a> FromKclValue<'a> for super::sketch::ArcData {
let obj = arg.as_object()?;
let_field_of!(obj, radius);
let case1 = || {
let angle_start = obj.get("angleStart").or_else(|| obj.get("angle_start"))?.as_f64()?;
let angle_end = obj.get("angleEnd").or_else(|| obj.get("angle_end"))?.as_f64()?;
let angle_start = obj.get("angleStart")?.as_f64()?;
let angle_end = obj.get("angleEnd")?.as_f64()?;
Some(Self::AnglesAndRadius {
angle_start,
angle_end,
@ -1256,21 +1277,9 @@ impl<'a> FromKclValue<'a> for super::sketch::PlaneData {
let obj = arg.as_object()?;
let_field_of!(obj, plane, &KclObjectFields);
let origin = plane.get("origin").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
let x_axis = plane
.get("xAxis")
.or_else(|| plane.get("x_axis"))
.and_then(FromKclValue::from_kcl_val)
.map(Box::new)?;
let y_axis = plane
.get("yAxis")
.or_else(|| plane.get("y_axis"))
.and_then(FromKclValue::from_kcl_val)
.map(Box::new)?;
let z_axis = plane
.get("zAxis")
.or_else(|| plane.get("z_axis"))
.and_then(FromKclValue::from_kcl_val)
.map(Box::new)?;
let x_axis = plane.get("xAxis").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
let y_axis = plane.get("yAxis").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
let z_axis = plane.get("zAxis").and_then(FromKclValue::from_kcl_val).map(Box::new)?;
Some(Self::Plane {
origin,
x_axis,
@ -1442,7 +1451,7 @@ impl<'a> FromKclValue<'a> for super::sketch::SketchData {
}
}
impl<'a> FromKclValue<'a> for super::revolve::AxisAndOrigin {
impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin2d {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
// Case 1: predefined planes.
if let Some(s) = arg.as_str() {
@ -1463,6 +1472,29 @@ impl<'a> FromKclValue<'a> for super::revolve::AxisAndOrigin {
}
}
impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin3d {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
// Case 1: predefined planes.
if let Some(s) = arg.as_str() {
return match s {
"X" | "x" => Some(Self::X),
"Y" | "y" => Some(Self::Y),
"Z" | "z" => Some(Self::Z),
"-X" | "-x" => Some(Self::NegX),
"-Y" | "-y" => Some(Self::NegY),
"-Z" | "-z" => Some(Self::NegZ),
_ => None,
};
}
// Case 2: custom planes.
let obj = arg.as_object()?;
let_field_of!(obj, custom, &KclObjectFields);
let_field_of!(custom, origin);
let_field_of!(custom, axis);
Some(Self::Custom { axis, origin })
}
}
impl<'a> FromKclValue<'a> for super::fillet::EdgeReference {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let id = arg.as_uuid().map(Self::Uuid);
@ -1471,9 +1503,17 @@ impl<'a> FromKclValue<'a> for super::fillet::EdgeReference {
}
}
impl<'a> FromKclValue<'a> for super::revolve::AxisOrEdgeReference {
impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis2dOrEdgeReference {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = super::revolve::AxisAndOrigin::from_kcl_val;
let case1 = super::axis_or_reference::AxisAndOrigin2d::from_kcl_val;
let case2 = super::fillet::EdgeReference::from_kcl_val;
case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge))
}
}
impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis3dOrEdgeReference {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = super::axis_or_reference::AxisAndOrigin3d::from_kcl_val;
let case2 = super::fillet::EdgeReference::from_kcl_val;
case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge))
}
@ -1584,6 +1624,24 @@ impl<'a> FromKclValue<'a> for Sketch {
Some(value.as_ref().to_owned())
}
}
impl<'a> FromKclValue<'a> for Helix {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::Helix(value) = arg else {
return None;
};
Some(value.as_ref().to_owned())
}
}
impl<'a> FromKclValue<'a> for SweepPath {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = Sketch::from_kcl_val;
let case2 = Helix::from_kcl_val;
case1(arg)
.map(Self::Sketch)
.or_else(|| case2(arg).map(|arg0: Helix| Self::Helix(Box::new(arg0))))
}
}
impl<'a> FromKclValue<'a> for String {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::String { value, meta: _ } = arg else {

View File

@ -256,3 +256,55 @@ pub async fn push(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
};
inner_push(array, elem, &args).await
}
/// Remove the last element from an array.
///
/// Returns a new array with the last element removed.
///
/// ```no_run
/// arr = [1, 2, 3, 4]
/// new_arr = pop(arr)
/// assertEqual(new_arr[0], 1, 0.00001, "1 is the first element of the array")
/// assertEqual(new_arr[1], 2, 0.00001, "2 is the second element of the array")
/// assertEqual(new_arr[2], 3, 0.00001, "3 is the third element of the array")
/// ```
#[stdlib {
name = "pop",
keywords = true,
unlabeled_first = true,
arg_docs = {
array = "The array to pop from. Must not be empty.",
}
}]
async fn inner_pop(array: Vec<KclValue>, args: &Args) -> Result<KclValue, KclError> {
if array.is_empty() {
return Err(KclError::Semantic(KclErrorDetails {
message: "Cannot pop from an empty array".to_string(),
source_ranges: vec![args.source_range],
}));
}
// Create a new array with all elements except the last one
let new_array = array[..array.len() - 1].to_vec();
Ok(KclValue::Array {
value: new_array,
meta: vec![args.source_range.into()],
})
}
pub async fn pop(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
// Extract the array from the arguments
let val = args.get_unlabeled_kw_arg("array")?;
let meta = vec![args.source_range];
let KclValue::Array { value: array, meta: _ } = val else {
let actual_type = val.human_friendly_type();
return Err(KclError::Semantic(KclErrorDetails {
source_ranges: meta,
message: format!("You can't pop from a value of type {actual_type}, only an array"),
}));
};
inner_pop(array, &args).await
}

View File

@ -0,0 +1,233 @@
//! Types for referencing an axis or edge.
use anyhow::Result;
use kcmc::length_unit::LengthUnit;
use kittycad_modeling_cmds::{self as kcmc};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{errors::KclError, std::fillet::EdgeReference};
/// A 2D axis or tagged edge.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(untagged)]
pub enum Axis2dOrEdgeReference {
/// 2D axis and origin.
Axis(AxisAndOrigin2d),
/// Tagged edge.
Edge(EdgeReference),
}
/// A 2D axis and origin.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum AxisAndOrigin2d {
/// X-axis.
#[serde(rename = "X", alias = "x")]
X,
/// Y-axis.
#[serde(rename = "Y", alias = "y")]
Y,
/// Flip the X-axis.
#[serde(rename = "-X", alias = "-x")]
NegX,
/// Flip the Y-axis.
#[serde(rename = "-Y", alias = "-y")]
NegY,
Custom {
/// The axis.
axis: [f64; 2],
/// The origin.
origin: [f64; 2],
},
}
impl AxisAndOrigin2d {
/// Get the axis and origin.
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
let (axis, origin) = match self {
AxisAndOrigin2d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::Custom { axis, origin } => ([axis[0], axis[1], 0.0], [origin[0], origin[1], 0.0]),
};
Ok((
kcmc::shared::Point3d {
x: axis[0],
y: axis[1],
z: axis[2],
},
kcmc::shared::Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(origin[2]),
},
))
}
}
/// A 3D axis or tagged edge.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(untagged)]
pub enum Axis3dOrEdgeReference {
/// 3D axis and origin.
Axis(AxisAndOrigin3d),
/// Tagged edge.
Edge(EdgeReference),
}
/// A 3D axis and origin.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum AxisAndOrigin3d {
/// X-axis.
#[serde(rename = "X", alias = "x")]
X,
/// Y-axis.
#[serde(rename = "Y", alias = "y")]
Y,
/// Z-axis.
#[serde(rename = "Z", alias = "z")]
Z,
/// Flip the X-axis.
#[serde(rename = "-X", alias = "-x")]
NegX,
/// Flip the Y-axis.
#[serde(rename = "-Y", alias = "-y")]
NegY,
/// Flip the Z-axis.
#[serde(rename = "-Z", alias = "-z")]
NegZ,
Custom {
/// The axis.
axis: [f64; 3],
/// The origin.
origin: [f64; 3],
},
}
impl AxisAndOrigin3d {
/// Get the axis and origin.
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
let (axis, origin) = match self {
AxisAndOrigin3d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::Z => ([0.0, 0.0, 1.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::NegZ => ([0.0, 0.0, -1.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::Custom { axis, origin } => {
([axis[0], axis[1], axis[2]], [origin[0], origin[1], origin[2]])
}
};
Ok((
kcmc::shared::Point3d {
x: axis[0],
y: axis[1],
z: axis[2],
},
kcmc::shared::Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(origin[2]),
},
))
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use crate::std::axis_or_reference::{
Axis2dOrEdgeReference, Axis3dOrEdgeReference, AxisAndOrigin2d, AxisAndOrigin3d,
};
#[test]
fn test_deserialize_revolve_axis_2d() {
let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::X);
let mut str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, "\"X\"");
str_json = "\"Y\"".to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Y));
str_json = "\"-Y\"".to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegY));
str_json = "\"-x\"".to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegX));
let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom {
axis: [0.0, -1.0],
origin: [1.0, 0.0],
});
str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0],"origin":[1.0,0.0]}}"#);
str_json = r#"{"custom": {"axis": [0,-1], "origin": [1,2.0]}}"#.to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(
data,
Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom {
axis: [0.0, -1.0],
origin: [1.0, 2.0]
})
);
}
#[test]
fn test_deserialize_revolve_axis_3d() {
let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::X);
let mut str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, "\"X\"");
str_json = "\"Y\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Y));
str_json = "\"Z\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Z));
str_json = "\"-Y\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegY));
str_json = "\"-x\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegX));
str_json = "\"-z\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegZ));
let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom {
axis: [0.0, -1.0, 0.0],
origin: [1.0, 0.0, 0.0],
});
str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0,0.0],"origin":[1.0,0.0,0.0]}}"#);
str_json = r#"{"custom": {"axis": [0,-1,0], "origin": [1,2.0,0]}}"#.to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(
data,
Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom {
axis: [0.0, -1.0, 0.0],
origin: [1.0, 2.0, 0.0]
})
);
}
}

View File

@ -9,14 +9,145 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, KclValue, Solid},
std::Args,
execution::{ExecState, Helix as HelixValue, KclValue, Solid},
std::{axis_or_reference::Axis3dOrEdgeReference, Args},
};
/// Data for helices.
/// Data for a helix.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct HelixData {
/// Number of revolutions.
pub revolutions: f64,
/// Start angle (in degrees).
#[serde(rename = "angleStart")]
pub angle_start: f64,
/// Is the helix rotation counter clockwise?
/// The default is `false`.
#[serde(default)]
pub ccw: bool,
/// Length of the helix.
pub length: f64,
/// Radius of the helix.
pub radius: f64,
/// Axis to use as mirror.
pub axis: Axis3dOrEdgeReference,
}
/// Create a helix.
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let data: HelixData = args.get_data()?;
let helix = inner_helix(data, exec_state, args).await?;
Ok(KclValue::Helix(helix))
}
/// Create a helix.
///
/// ```no_run
/// // Create a helix around the Z axis.
/// helixPath = helix({
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// length = 10,
/// radius = 5,
/// axis = 'Z',
/// })
///
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('YZ')
/// |> circle({ center = [0, 0], radius = 1 }, %)
/// //|> sweep({ path = helixPath }, %)
/// ```
///
/// ```no_run
/// // Create a helix around an edge.
/// /*helper001 = startSketchOn('XZ')
/// |> startProfileAt([0, 0], %)
/// |> line([0, 10], %, $edge001)
///
/// helixPath = helix({
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// length = 10,
/// radius = 5,
/// axis = edge001,
/// })
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('XY')
/// |> circle({ center = [0, 0], radius = 1 }, %)
/// |> sweep({ path = helixPath }, %)*/
/// ```
#[stdlib {
name = "helix",
feature_tree_operation = true,
}]
async fn inner_helix(data: HelixData, exec_state: &mut ExecState, args: Args) -> Result<Box<HelixValue>, KclError> {
let id = exec_state.next_uuid();
let helix_result = Box::new(HelixValue {
value: id,
revolutions: data.revolutions,
angle_start: data.angle_start,
ccw: data.ccw,
meta: vec![args.source_range.into()],
});
if args.ctx.is_mock() {
return Ok(helix_result);
}
match data.axis {
Axis3dOrEdgeReference::Axis(axis) => {
let (axis, origin) = axis.axis_and_origin()?;
args.batch_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityMakeHelixFromParams {
radius: data.radius,
is_clockwise: !data.ccw,
length: LengthUnit(data.length),
revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start),
axis,
center: origin,
}),
)
.await?;
}
Axis3dOrEdgeReference::Edge(_edge) => {
/*let edge_id = edge.get_engine_id(exec_state, &args)?;
args.batch_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityMakeHelixFromEdge {
radius: data.radius,
is_clockwise: !data.ccw,
length: LengthUnit(data.length),
revolutions: data.revolutions,
start_angle: Angle::from_degrees(data.angle_start),
edge_id,
}),
)
.await?;*/
return Err(KclError::Unimplemented(crate::errors::KclErrorDetails {
message: "Helix around edge is not yet implemented".to_string(),
source_ranges: vec![args.source_range],
}));
}
};
Ok(helix_result)
}
/// Data for helix revolutions.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct HelixRevolutionsData {
/// Number of revolutions.
pub revolutions: f64,
/// Start angle (in degrees).
@ -32,10 +163,10 @@ pub struct HelixData {
}
/// Create a helix on a cylinder.
pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid): (HelixData, Box<Solid>) = args.get_data_and_solid()?;
pub async fn helix_revolutions(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid): (HelixRevolutionsData, Box<Solid>) = args.get_data_and_solid()?;
let solid = inner_helix(data, solid, exec_state, args).await?;
let solid = inner_helix_revolutions(data, solid, exec_state, args).await?;
Ok(KclValue::Solid(solid))
}
@ -45,18 +176,18 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// part001 = startSketchOn('XY')
/// |> circle({ center: [5, 5], radius: 10 }, %)
/// |> extrude(10, %)
/// |> helix({
/// |> helixRevolutions({
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// }, %)
/// ```
#[stdlib {
name = "helix",
name = "helixRevolutions",
feature_tree_operation = true,
}]
async fn inner_helix(
data: HelixData,
async fn inner_helix_revolutions(
data: HelixRevolutionsData,
solid: Box<Solid>,
exec_state: &mut ExecState,
args: Args,

View File

@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, KclValue, Sketch, SketchSet},
std::{revolve::AxisOrEdgeReference, Args},
std::{axis_or_reference::Axis2dOrEdgeReference, Args},
};
/// Data for a mirror.
@ -19,7 +19,7 @@ use crate::{
#[serde(rename_all = "camelCase")]
pub struct Mirror2dData {
/// Axis to use as mirror.
pub axis: AxisOrEdgeReference,
pub axis: Axis2dOrEdgeReference,
}
/// Mirror a sketch.
@ -117,7 +117,7 @@ async fn inner_mirror_2d(
}
match data.axis {
AxisOrEdgeReference::Axis(axis) => {
Axis2dOrEdgeReference::Axis(axis) => {
let (axis, origin) = axis.axis_and_origin()?;
args.batch_modeling_cmd(
@ -130,7 +130,7 @@ async fn inner_mirror_2d(
)
.await?;
}
AxisOrEdgeReference::Edge(edge) => {
Axis2dOrEdgeReference::Edge(edge) => {
let edge_id = edge.get_engine_id(exec_state, &args)?;
args.batch_modeling_cmd(

View File

@ -4,6 +4,7 @@ pub mod appearance;
pub mod args;
pub mod array;
pub mod assert;
pub mod axis_or_reference;
pub mod chamfer;
pub mod convert;
pub mod extrude;
@ -107,12 +108,14 @@ lazy_static! {
Box::new(crate::std::array::Reduce),
Box::new(crate::std::array::Map),
Box::new(crate::std::array::Push),
Box::new(crate::std::array::Pop),
Box::new(crate::std::chamfer::Chamfer),
Box::new(crate::std::fillet::Fillet),
Box::new(crate::std::fillet::GetOppositeEdge),
Box::new(crate::std::fillet::GetNextAdjacentEdge),
Box::new(crate::std::fillet::GetPreviousAdjacentEdge),
Box::new(crate::std::helix::Helix),
Box::new(crate::std::helix::HelixRevolutions),
Box::new(crate::std::shell::Shell),
Box::new(crate::std::shell::Hollow),
Box::new(crate::std::revolve::Revolve),

View File

@ -10,11 +10,7 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Sketch, Solid},
std::{
extrude::do_post_extrude,
fillet::{default_tolerance, EdgeReference},
Args,
},
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args},
};
/// Data for revolution surfaces.
@ -26,74 +22,12 @@ pub struct RevolveData {
#[schemars(range(min = -360.0, max = 360.0))]
pub angle: Option<f64>,
/// Axis of revolution.
pub axis: AxisOrEdgeReference,
pub axis: Axis2dOrEdgeReference,
/// Tolerance for the revolve operation.
#[serde(default)]
pub tolerance: Option<f64>,
}
/// Axis or tagged edge.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(untagged)]
pub enum AxisOrEdgeReference {
/// Axis and origin.
Axis(AxisAndOrigin),
/// Tagged edge.
Edge(EdgeReference),
}
/// Axis and origin.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum AxisAndOrigin {
/// X-axis.
#[serde(rename = "X", alias = "x")]
X,
/// Y-axis.
#[serde(rename = "Y", alias = "y")]
Y,
/// Flip the X-axis.
#[serde(rename = "-X", alias = "-x")]
NegX,
/// Flip the Y-axis.
#[serde(rename = "-Y", alias = "-y")]
NegY,
Custom {
/// The axis.
axis: [f64; 2],
/// The origin.
origin: [f64; 2],
},
}
impl AxisAndOrigin {
/// Get the axis and origin.
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
let (axis, origin) = match self {
AxisAndOrigin::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin::Custom { axis, origin } => ([axis[0], axis[1], 0.0], [origin[0], origin[1], 0.0]),
};
Ok((
kcmc::shared::Point3d {
x: axis[0],
y: axis[1],
z: axis[2],
},
kcmc::shared::Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(origin[2]),
},
))
}
}
/// Revolve a sketch around an axis.
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch): (RevolveData, Sketch) = args.get_data_and_sketch()?;
@ -266,7 +200,7 @@ async fn inner_revolve(
let id = exec_state.next_uuid();
match data.axis {
AxisOrEdgeReference::Axis(axis) => {
Axis2dOrEdgeReference::Axis(axis) => {
let (axis, origin) = axis.axis_and_origin()?;
args.batch_modeling_cmd(
id,
@ -281,7 +215,7 @@ async fn inner_revolve(
)
.await?;
}
AxisOrEdgeReference::Edge(edge) => {
Axis2dOrEdgeReference::Edge(edge) => {
let edge_id = edge.get_engine_id(exec_state, &args)?;
args.batch_modeling_cmd(
id,
@ -298,47 +232,3 @@ async fn inner_revolve(
do_post_extrude(sketch, 0.0, exec_state, args).await
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use crate::std::revolve::{AxisAndOrigin, AxisOrEdgeReference};
#[test]
fn test_deserialize_revolve_axis() {
let data = AxisOrEdgeReference::Axis(AxisAndOrigin::X);
let mut str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, "\"X\"");
str_json = "\"Y\"".to_string();
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, AxisOrEdgeReference::Axis(AxisAndOrigin::Y));
str_json = "\"-Y\"".to_string();
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, AxisOrEdgeReference::Axis(AxisAndOrigin::NegY));
str_json = "\"-x\"".to_string();
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, AxisOrEdgeReference::Axis(AxisAndOrigin::NegX));
let data = AxisOrEdgeReference::Axis(AxisAndOrigin::Custom {
axis: [0.0, -1.0],
origin: [1.0, 0.0],
});
str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0],"origin":[1.0,0.0]}}"#);
str_json = r#"{"custom": {"axis": [0,-1], "origin": [1,2.0]}}"#.to_string();
let data: AxisOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(
data,
AxisOrEdgeReference::Axis(AxisAndOrigin::Custom {
axis: [0.0, -1.0],
origin: [1.0, 2.0]
})
);
}
}

View File

@ -9,16 +9,25 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, KclValue, Sketch, Solid},
execution::{ExecState, Helix, KclValue, Sketch, Solid},
std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
};
/// A path to sweep along.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(untagged)]
pub enum SweepPath {
Sketch(Sketch),
Helix(Box<Helix>),
}
/// Data for a sweep.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
pub struct SweepData {
/// The path to sweep along.
pub path: Sketch,
pub path: SweepPath,
/// If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components.
pub sectional: Option<bool>,
/// Tolerance for the sweep operation.
@ -77,6 +86,26 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// path: sweepPath,
/// }, %)
/// ```
///
/// ```no_run
/// // Create a spring by sweeping around a helix path.
///
/// // Create a helix around the Z axis.
/// helixPath = helix({
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// length = 10,
/// radius = 5,
/// axis = 'Z',
/// })
///
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('YZ')
/// |> circle({ center = [0, 0], radius = 1 }, %)
/// //|> sweep({ path = helixPath }, %)
/// ```
#[stdlib {
name = "sweep",
feature_tree_operation = true,
@ -92,7 +121,10 @@ async fn inner_sweep(
id,
ModelingCmd::from(mcmd::Sweep {
target: sketch.id.into(),
trajectory: data.path.id.into(),
trajectory: match data.path {
SweepPath::Sketch(sketch) => sketch.id.into(),
SweepPath::Helix(helix) => helix.value.into(),
},
sectional: data.sectional.unwrap_or(false),
tolerance: LengthUnit(data.tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
}),

View File

@ -0,0 +1,377 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing array_elem_pop.kcl
---
{
"Ok": {
"body": [
{
"declaration": {
"end": 15,
"id": {
"end": 3,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"init": {
"elements": [
{
"end": 8,
"raw": "1",
"start": 7,
"type": "Literal",
"type": "Literal",
"value": 1.0
},
{
"end": 11,
"raw": "2",
"start": 10,
"type": "Literal",
"type": "Literal",
"value": 2.0
},
{
"end": 14,
"raw": "3",
"start": 13,
"type": "Literal",
"type": "Literal",
"value": 3.0
}
],
"end": 15,
"start": 6,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 15,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 35,
"id": {
"end": 24,
"name": "new_arr1",
"start": 16,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 34,
"name": "arr",
"start": 31,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 30,
"name": "pop",
"start": 27,
"type": "Identifier"
},
"end": 35,
"start": 27,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 16,
"type": "VariableDeclarator"
},
"end": 35,
"kind": "const",
"start": 16,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 60,
"id": {
"end": 44,
"name": "new_arr2",
"start": 36,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 59,
"name": "new_arr1",
"start": 51,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 50,
"name": "pop",
"start": 47,
"type": "Identifier"
},
"end": 60,
"start": 47,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 36,
"type": "VariableDeclarator"
},
"end": 60,
"kind": "const",
"start": 36,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 85,
"id": {
"end": 69,
"name": "new_arr3",
"start": 61,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 84,
"name": "new_arr2",
"start": 76,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 75,
"name": "pop",
"start": 72,
"type": "Identifier"
},
"end": 85,
"start": 72,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 61,
"type": "VariableDeclarator"
},
"end": 85,
"kind": "const",
"start": 61,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"end": 159,
"expression": {
"arguments": [
{
"computed": false,
"end": 109,
"object": {
"end": 106,
"name": "new_arr1",
"start": 98,
"type": "Identifier",
"type": "Identifier"
},
"property": {
"end": 108,
"raw": "0",
"start": 107,
"type": "Literal",
"type": "Literal",
"value": 0.0
},
"start": 98,
"type": "MemberExpression",
"type": "MemberExpression"
},
{
"end": 112,
"raw": "1",
"start": 111,
"type": "Literal",
"type": "Literal",
"value": 1.0
},
{
"end": 121,
"raw": "0.00001",
"start": 114,
"type": "Literal",
"type": "Literal",
"value": 0.00001
},
{
"end": 158,
"raw": "\"element 0 should not have changed\"",
"start": 123,
"type": "Literal",
"type": "Literal",
"value": "element 0 should not have changed"
}
],
"callee": {
"end": 97,
"name": "assertEqual",
"start": 86,
"type": "Identifier"
},
"end": 159,
"start": 86,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 86,
"type": "ExpressionStatement",
"type": "ExpressionStatement"
},
{
"end": 233,
"expression": {
"arguments": [
{
"computed": false,
"end": 183,
"object": {
"end": 180,
"name": "new_arr1",
"start": 172,
"type": "Identifier",
"type": "Identifier"
},
"property": {
"end": 182,
"raw": "1",
"start": 181,
"type": "Literal",
"type": "Literal",
"value": 1.0
},
"start": 172,
"type": "MemberExpression",
"type": "MemberExpression"
},
{
"end": 186,
"raw": "2",
"start": 185,
"type": "Literal",
"type": "Literal",
"value": 2.0
},
{
"end": 195,
"raw": "0.00001",
"start": 188,
"type": "Literal",
"type": "Literal",
"value": 0.00001
},
{
"end": 232,
"raw": "\"element 1 should not have changed\"",
"start": 197,
"type": "Literal",
"type": "Literal",
"value": "element 1 should not have changed"
}
],
"callee": {
"end": 171,
"name": "assertEqual",
"start": 160,
"type": "Identifier"
},
"end": 233,
"start": 160,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 160,
"type": "ExpressionStatement",
"type": "ExpressionStatement"
},
{
"end": 307,
"expression": {
"arguments": [
{
"computed": false,
"end": 257,
"object": {
"end": 254,
"name": "new_arr2",
"start": 246,
"type": "Identifier",
"type": "Identifier"
},
"property": {
"end": 256,
"raw": "0",
"start": 255,
"type": "Literal",
"type": "Literal",
"value": 0.0
},
"start": 246,
"type": "MemberExpression",
"type": "MemberExpression"
},
{
"end": 260,
"raw": "1",
"start": 259,
"type": "Literal",
"type": "Literal",
"value": 1.0
},
{
"end": 269,
"raw": "0.00001",
"start": 262,
"type": "Literal",
"type": "Literal",
"value": 0.00001
},
{
"end": 306,
"raw": "\"element 0 should not have changed\"",
"start": 271,
"type": "Literal",
"type": "Literal",
"value": "element 0 should not have changed"
}
],
"callee": {
"end": 245,
"name": "assertEqual",
"start": 234,
"type": "Identifier"
},
"end": 307,
"start": 234,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 234,
"type": "ExpressionStatement",
"type": "ExpressionStatement"
}
],
"end": 308,
"start": 0
}
}

View File

@ -0,0 +1,7 @@
arr = [1, 2, 3]
new_arr1 = pop(arr)
new_arr2 = pop(new_arr1)
new_arr3 = pop(new_arr2)
assertEqual(new_arr1[0], 1, 0.00001, "element 0 should not have changed")
assertEqual(new_arr1[1], 2, 0.00001, "element 1 should not have changed")
assertEqual(new_arr2[0], 1, 0.00001, "element 0 should not have changed")

View File

@ -0,0 +1,5 @@
---
source: kcl/src/simulation_tests.rs
description: Operations executed array_elem_pop.kcl
---
[]

View File

@ -0,0 +1,168 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing array_elem_pop.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"arr": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"__meta": [
{
"sourceRange": [
7,
8,
0
]
}
]
},
{
"type": "Number",
"value": 2.0,
"__meta": [
{
"sourceRange": [
10,
11,
0
]
}
]
},
{
"type": "Number",
"value": 3.0,
"__meta": [
{
"sourceRange": [
13,
14,
0
]
}
]
}
],
"__meta": [
{
"sourceRange": [
6,
15,
0
]
}
]
},
"new_arr1": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"__meta": [
{
"sourceRange": [
7,
8,
0
]
}
]
},
{
"type": "Number",
"value": 2.0,
"__meta": [
{
"sourceRange": [
10,
11,
0
]
}
]
}
],
"__meta": [
{
"sourceRange": [
27,
35,
0
]
}
]
},
"new_arr2": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"__meta": [
{
"sourceRange": [
7,
8,
0
]
}
]
}
],
"__meta": [
{
"sourceRange": [
47,
60,
0
]
}
]
},
"new_arr3": {
"type": "Array",
"value": [],
"__meta": [
{
"sourceRange": [
72,
85,
0
]
}
]
}
},
"parent": null
}
],
"currentEnv": 0,
"return": null
}

View File

@ -0,0 +1,76 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing array_elem_pop_empty_fail.kcl
---
{
"Ok": {
"body": [
{
"declaration": {
"end": 8,
"id": {
"end": 3,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"init": {
"elements": [],
"end": 8,
"start": 6,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 8,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 24,
"id": {
"end": 13,
"name": "fail",
"start": 9,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 23,
"name": "arr",
"start": 20,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 19,
"name": "pop",
"start": 16,
"type": "Identifier"
},
"end": 24,
"start": 16,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 9,
"type": "VariableDeclarator"
},
"end": 24,
"kind": "const",
"start": 9,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 25,
"start": 0
}
}

View File

@ -0,0 +1,12 @@
---
source: kcl/src/simulation_tests.rs
description: Error from executing array_elem_pop_empty_fail.kcl
---
KCL Semantic error
× semantic: Cannot pop from an empty array
╭─[2:8]
1 │ arr = []
2 │ fail = pop(arr)
· ────────
╰────

View File

@ -0,0 +1,2 @@
arr = []
fail = pop(arr)

View File

@ -0,0 +1,5 @@
---
source: kcl/src/simulation_tests.rs
description: Operations executed array_elem_pop_empty_fail.kcl
---
[]

View File

@ -0,0 +1,141 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing array_elem_pop_fail.kcl
---
{
"Ok": {
"body": [
{
"declaration": {
"end": 15,
"id": {
"end": 3,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"init": {
"elements": [
{
"end": 8,
"raw": "1",
"start": 7,
"type": "Literal",
"type": "Literal",
"value": 1.0
},
{
"end": 11,
"raw": "2",
"start": 10,
"type": "Literal",
"type": "Literal",
"value": 2.0
},
{
"end": 14,
"raw": "3",
"start": 13,
"type": "Literal",
"type": "Literal",
"value": 3.0
}
],
"end": 15,
"start": 6,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 15,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 36,
"id": {
"end": 25,
"name": "pushedArr",
"start": 16,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 35,
"name": "arr",
"start": 32,
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
"end": 31,
"name": "pop",
"start": 28,
"type": "Identifier"
},
"end": 36,
"start": 28,
"type": "CallExpression",
"type": "CallExpression"
},
"start": 16,
"type": "VariableDeclarator"
},
"end": 36,
"kind": "const",
"start": 16,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"declaration": {
"end": 56,
"id": {
"end": 41,
"name": "fail",
"start": 37,
"type": "Identifier"
},
"init": {
"computed": false,
"end": 56,
"object": {
"end": 53,
"name": "pushedArr",
"start": 44,
"type": "Identifier",
"type": "Identifier"
},
"property": {
"end": 55,
"raw": "2",
"start": 54,
"type": "Literal",
"type": "Literal",
"value": 2.0
},
"start": 44,
"type": "MemberExpression",
"type": "MemberExpression"
},
"start": 37,
"type": "VariableDeclarator"
},
"end": 56,
"kind": "const",
"start": 37,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 57,
"start": 0
}
}

View File

@ -0,0 +1,12 @@
---
source: kcl/src/simulation_tests.rs
description: Error from executing array_elem_pop_fail.kcl
---
KCL UndefinedValue error
× undefined value: The array doesn't have any item at index 2
╭─[3:8]
2 │ pushedArr = pop(arr)
3 │ fail = pushedArr[2]
· ────────────
╰────

View File

@ -0,0 +1,3 @@
arr = [1, 2, 3]
pushedArr = pop(arr)
fail = pushedArr[2]

View File

@ -0,0 +1,5 @@
---
source: kcl/src/simulation_tests.rs
description: Operations executed array_elem_pop_fail.kcl
---
[]

View File

@ -1,13 +1,14 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing helix_ccw.kcl
snapshot_kind: text
---
{
"Ok": {
"body": [
{
"declaration": {
"end": 188,
"end": 199,
"id": {
"end": 7,
"name": "part001",
@ -151,90 +152,90 @@ description: Result of parsing helix_ccw.kcl
{
"arguments": [
{
"end": 184,
"end": 195,
"properties": [
{
"end": 135,
"end": 146,
"key": {
"end": 130,
"end": 141,
"name": "revolutions",
"start": 119,
"start": 130,
"type": "Identifier"
},
"start": 119,
"start": 130,
"type": "ObjectProperty",
"value": {
"end": 135,
"end": 146,
"raw": "16",
"start": 133,
"start": 144,
"type": "Literal",
"type": "Literal",
"value": 16.0
}
},
{
"end": 158,
"end": 169,
"key": {
"end": 154,
"end": 165,
"name": "angleStart",
"start": 144,
"start": 155,
"type": "Identifier"
},
"start": 144,
"start": 155,
"type": "ObjectProperty",
"value": {
"end": 158,
"end": 169,
"raw": "0",
"start": 157,
"start": 168,
"type": "Literal",
"type": "Literal",
"value": 0.0
}
},
{
"end": 177,
"end": 188,
"key": {
"end": 170,
"end": 181,
"name": "ccw",
"start": 167,
"start": 178,
"type": "Identifier"
},
"start": 167,
"start": 178,
"type": "ObjectProperty",
"value": {
"end": 177,
"end": 188,
"raw": "true",
"start": 173,
"start": 184,
"type": "Literal",
"type": "Literal",
"value": true
}
}
],
"start": 110,
"start": 121,
"type": "ObjectExpression",
"type": "ObjectExpression"
},
{
"end": 187,
"start": 186,
"end": 198,
"start": 197,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"end": 109,
"name": "helix",
"end": 120,
"name": "helixRevolutions",
"start": 104,
"type": "Identifier"
},
"end": 188,
"end": 199,
"start": 104,
"type": "CallExpression",
"type": "CallExpression"
}
],
"end": 188,
"end": 199,
"start": 10,
"type": "PipeExpression",
"type": "PipeExpression"
@ -242,14 +243,14 @@ description: Result of parsing helix_ccw.kcl
"start": 0,
"type": "VariableDeclarator"
},
"end": 188,
"end": 199,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 189,
"end": 200,
"start": 0
}
}

View File

@ -1,7 +1,7 @@
part001 = startSketchOn('XY')
|> circle({ center = [5, 5], radius = 10 }, %)
|> extrude(10, %)
|> helix({
|> helixRevolutions({
revolutions = 16,
angleStart = 0,
ccw = true

View File

@ -53,23 +53,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
110,
184,
121,
195,
0
]
},
"solid": {
"sourceRange": [
186,
187,
197,
198,
0
]
}
},
"name": "helix",
"name": "helixRevolutions",
"sourceRange": [
104,
188,
199,
0
],
"type": "StdLibCall",

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@ triangleHeight = 200
plumbusLen = 100
radius = 80
circ = {
angle_start = 0,
angle_end = 360,
angleStart = 0,
angleEnd = 360,
radius = radius
}

View File

@ -8,16 +8,16 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
154,
158,
152,
156,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
140,
159,
138,
157,
0
],
"type": "StdLibCall",
@ -27,23 +27,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
389,
387,
401,
0
]
},
"sketch_set": {
"sourceRange": [
403,
0
]
},
"sketch_set": {
"sourceRange": [
405,
406,
404,
0
]
}
},
"name": "extrude",
"sourceRange": [
381,
407,
379,
405,
0
],
"type": "StdLibCall",
@ -53,15 +53,15 @@ snapshot_kind: text
"type": "UserDefinedFunctionCall",
"name": "circl",
"functionSourceRange": [
417,
567,
415,
565,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": [
574,
588,
572,
586,
0
]
},
@ -69,23 +69,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
452,
453,
450,
451,
0
]
},
"tag": {
"sourceRange": [
455,
459,
453,
457,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
438,
460,
436,
458,
0
],
"type": "StdLibCall",
@ -98,23 +98,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
616,
614,
624,
0
]
},
"sketch_set": {
"sourceRange": [
626,
0
]
},
"sketch_set": {
"sourceRange": [
628,
629,
627,
0
]
}
},
"name": "extrude",
"sourceRange": [
608,
630,
606,
628,
0
],
"type": "StdLibCall",
@ -124,23 +124,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
643,
763,
641,
761,
0
]
},
"solid": {
"sourceRange": [
765,
766,
763,
764,
0
]
}
},
"name": "fillet",
"sourceRange": [
636,
767,
634,
765,
0
],
"type": "StdLibCall",
@ -150,15 +150,15 @@ snapshot_kind: text
"type": "UserDefinedFunctionCall",
"name": "circl",
"functionSourceRange": [
417,
567,
415,
565,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": [
773,
786,
771,
784,
0
]
},
@ -166,23 +166,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
452,
453,
450,
451,
0
]
},
"tag": {
"sourceRange": [
455,
459,
453,
457,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
438,
460,
436,
458,
0
],
"type": "StdLibCall",
@ -195,23 +195,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
814,
824,
812,
822,
0
]
},
"sketch_set": {
"sourceRange": [
826,
827,
824,
825,
0
]
}
},
"name": "extrude",
"sourceRange": [
806,
828,
804,
826,
0
],
"type": "StdLibCall",
@ -221,23 +221,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
841,
961,
839,
959,
0
]
},
"solid": {
"sourceRange": [
963,
964,
961,
962,
0
]
}
},
"name": "fillet",
"sourceRange": [
834,
965,
832,
963,
0
],
"type": "StdLibCall",

View File

@ -4,6 +4,6 @@ const height = 3
const body = startSketchOn('XY')
|> startProfileAt([center[0]+radius, center[1]], %)
|> arc({angle_end: 360, angle_start: 0, radius: radius}, %)
|> arc({angleEnd: 360, angleStart: 0, radius: radius}, %)
|> close(%)
|> extrude(height, %)

View File

@ -12,9 +12,9 @@ const extrude000 = extrude(1.0, sketch000)
const plane005 = {
plane: {
origin: [0.0, 0.0, 1.0],
x_axis: [0.707107, 0.707107, 0.0],
y_axis: [-0.0, 0.0, 1.0],
z_axis: [0.707107, -0.707107, 0.0]
xAxis: [0.707107, 0.707107, 0.0],
yAxis: [-0.0, 0.0, 1.0],
zAxis: [0.707107, -0.707107, 0.0]
}
}

View File

@ -28,9 +28,9 @@ fn rectShape = (pos, w, l) => {
const bracketPlane = {
plane: {
origin: { x: 0, y: length / 2 + thk, z: 0 },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 0, z: 1 },
z_axis: { x: 0, y: -1, z: 0 }
xAxis: { x: 1, y: 0, z: 0 },
yAxis: { x: 0, y: 0, z: 1 },
zAxis: { x: 0, y: -1, z: 0 }
}
}

View File

@ -28,9 +28,9 @@ fn rectShape = (pos, w, l) => {
const bracketPlane = {
plane: {
origin: { x: 0, y: length / 2 + thk, z: 0 },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 0, z: 1 },
z_axis: { x: 0, y: -1, z: 0 }
xAxis: { x: 1, y: 0, z: 0 },
yAxis: { x: 0, y: 0, z: 1 },
zAxis: { x: 0, y: -1, z: 0 }
}
}
@ -67,9 +67,9 @@ const bracketBody = bs
const tabPlane = {
plane: {
origin: { x: 0, y: 0, z: depth + thk },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 1, z: 0 },
z_axis: { x: 0, y: 0, z: 1 }
xAxis: { x: 1, y: 0, z: 0 },
yAxis: { x: 0, y: 1, z: 0 },
zAxis: { x: 0, y: 0, z: 1 }
}
}
@ -133,9 +133,9 @@ const tabsL = startSketchOn(tabPlane)
const retPlane = {
plane: {
origin: { x: -width / 2 + 20, y: 0, z: 0 },
x_axis: { x: 0, y: 1, z: 0 },
y_axis: { x: 0, y: 0, z: 1 },
z_axis: { x: 1, y: 0, z: 0 }
xAxis: { x: 0, y: 1, z: 0 },
yAxis: { x: 0, y: 0, z: 1 },
zAxis: { x: 1, y: 0, z: 0 }
}
}

View File

@ -1,4 +1,4 @@
const part001 = startSketchOn('XY')
|> circle({ center: [5, 5], radius: 10 }, %)
|> extrude(10, %)
|> helix({revolutions: 16, angle_start: 0}, %)
|> helixRevolutions({revolutions = 16, angleStart = 0}, %)

View File

@ -1,4 +1,4 @@
const part001 = startSketchOn('XY')
|> circle({ center: [5, 5], radius: 10 }, %)
|> extrude(-10, %)
|> helix({revolutions: 16, angle_start: 0}, %)
|> helixRevolutions({revolutions = 16, angleStart = 0}, %)

View File

@ -1,4 +1,4 @@
const part001 = startSketchOn('XY')
|> circle({ center: [5, 5], radius: 10 }, %)
|> extrude(10, %)
|> helix({revolutions: 16, angle_start: 0, length: 3}, %)
|> helixRevolutions({revolutions = 16, angleStart = 0, length = 3}, %)

View File

@ -2,13 +2,13 @@
const plane94894440791888 = {
plane: {
origin: [0.005000000000000001, 0.01, -0.005],
x_axis: [
xAxis: [
0.9285064634886234,
0.37131623619207604,
0.0
],
y_axis: [-0.0, 0.0, 1.0],
z_axis: [
yAxis: [-0.0, 0.0, 1.0],
zAxis: [
0.37131623619207604,
-0.9285064634886234,
0.0

View File

@ -2,13 +2,13 @@
const plane94894440791888 = {
plane: {
origin: [0.005000000000000001, 0.01, -0.005],
x_axis: [
xAxis: [
0.9285064634886234,
0.37131623619207604,
0.0
],
y_axis: [-0.0, 0.0, 1.0],
z_axis: [
yAxis: [-0.0, 0.0, 1.0],
zAxis: [
0.37131623619207604,
-0.9285064634886234,
0.0

View File

@ -13,8 +13,8 @@ const sketch001 = startSketchOn('XZ')
|> startProfileAt([0, depth - templateGap], %)
|> xLine(length001, %, $seg01)
|> arc({
angle_end: 0,
angle_start: 90,
angleEnd: 0,
angleStart: 90,
radius: radius - templateGap
}, %)
|> yLineTo(-templateGap * 2 - (templateDiameter / 2), %, $seg05)
@ -26,8 +26,8 @@ const sketch001 = startSketchOn('XZ')
|> xLine(segLen(seg04, %), %)
|> yLine(segLen(seg05, %), %)
|> arc({
angle_end: 90,
angle_start: 180,
angleEnd: 90,
angleStart: 180,
radius: radius - templateGap
}, %)
|> lineTo([profileStartX(%), profileStartY(%)], %)

View File

@ -285,7 +285,7 @@ async fn optional_params() {
fn other_circle = (pos, radius, tag?) => {
sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> arc({angle_end: 360, angle_start: 0, radius: radius}, %)
|> arc({angleEnd: 360, angleStart: 0, radius: radius}, %)
|> close(%)
|> extrude(2, %)
@ -1160,8 +1160,8 @@ async fn kcl_test_plumbus_fillets() {
sg = startSketchOn(ext, face)
|> startProfileAt([pos[0] + radius, pos[1]], %)
|> arc({
angle_end: 360,
angle_start: 0,
angleEnd: 360,
angleStart: 0,
radius: radius
}, %, $arc1)
|> close(%)
@ -1235,9 +1235,9 @@ async fn kcl_test_member_expression_in_params() {
y: originStart[1],
z: originStart[2],
},
x_axis: { x: 0, y: 0, z: -1 },
y_axis: { x: 1, y: 0, z: 0 },
z_axis: { x: 0, y: 1, z: 0 }
xAxis: { x: 0, y: 0, z: -1 },
yAxis: { x: 1, y: 0, z: 0 },
zAxis: { x: 0, y: 1, z: 0 }
}
})
|> circle({ center: [0, 0], radius: capDia / 2 }, %)
@ -1732,8 +1732,8 @@ async fn kcl_test_arc_error_same_start_end() {
let code = r#"startSketchOn('XY')
|> startProfileAt([10, 0], %)
|> arc({
angle_start: 180,
angle_end: 180,
angleStart: 180,
angleEnd: 180,
radius: 1.5
}, %)
|> close(%)
@ -1749,7 +1749,7 @@ async fn kcl_test_arc_error_same_start_end() {
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"type: KclErrorDetails { source_ranges: [SourceRange([57, 140, 0])], message: "Arc start and end angles must be different" }"#
r#"type: KclErrorDetails { source_ranges: [SourceRange([57, 138, 0])], message: "Arc start and end angles must be different" }"#
);
}

View File

@ -1236,13 +1236,13 @@
"@lezer/lr" "^1.0.0"
style-mod "^4.0.0"
"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.1":
version "6.8.1"
resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.1.tgz#6427848815baaf68c08e98c7673b804d3d8c0e7f"
integrity sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==
"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.4":
version "6.8.4"
resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.4.tgz#7d8aa5d1a6dec89ffcc23ad45ddca2e12e90982d"
integrity sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==
dependencies:
"@codemirror/state" "^6.0.0"
"@codemirror/view" "^6.0.0"
"@codemirror/view" "^6.35.0"
crelt "^1.0.5"
"@codemirror/search@^6.0.0", "@codemirror/search@^6.5.6":
@ -1254,10 +1254,12 @@
"@codemirror/view" "^6.0.0"
crelt "^1.0.5"
"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.1", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1":
version "6.4.1"
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.1.tgz#da57143695c056d9a3c38705ed34136e2b68171b"
integrity sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==
"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.1", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1", "@codemirror/state@^6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.0.tgz#e98dde85620618651543152fe1c2483300a0ccc9"
integrity sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==
dependencies:
"@marijn/find-cluster-break" "^1.0.0"
"@codemirror/theme-one-dark@^6.1.2":
version "6.1.2"
@ -1269,12 +1271,12 @@
"@codemirror/view" "^6.0.0"
"@lezer/highlight" "^1.0.0"
"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0":
version "6.29.1"
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.29.1.tgz#9c6c6f8a15e12df1b7e9d136dcbf4ff90b81ef71"
integrity sha512-7r+DlO/QFwPqKp73uq5mmrS4TuLPUVotbNOKYzN3OLP5ScrOVXcm4g13/48b6ZXGhdmzMinzFYqH0vo+qihIkQ==
"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0", "@codemirror/view@^6.35.0":
version "6.36.1"
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.1.tgz#3c543b8fd72c96b30c4b2b1464d1ebce7e0c5c4b"
integrity sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ==
dependencies:
"@codemirror/state" "^6.4.0"
"@codemirror/state" "^6.5.0"
style-mod "^4.1.0"
w3c-keyname "^2.2.4"
@ -2073,6 +2075,11 @@
lodash "^4.17.15"
tmp-promise "^3.0.2"
"@marijn/find-cluster-break@^1.0.0":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8"
integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==
"@nabla/vite-plugin-eslint@^2.0.5":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@nabla/vite-plugin-eslint/-/vite-plugin-eslint-2.0.5.tgz#f99333a9fe26442e497fd6af269803453b8c4c68"
@ -2372,7 +2379,7 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
"@tweenjs/tween.js@^23.1.1", "@tweenjs/tween.js@~23.1.1":
"@tweenjs/tween.js@^23.1.1", "@tweenjs/tween.js@~23.1.3":
version "23.1.3"
resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-23.1.3.tgz#eff0245735c04a928bb19c026b58c2a56460539d"
integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==
@ -2640,14 +2647,15 @@
dependencies:
"@types/jest" "*"
"@types/three@^0.163.0":
version "0.163.0"
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.163.0.tgz#96f5440fcd39452d2c84dfe0c9b7a9cf0247b9e6"
integrity sha512-uIdDhsXRpQiBUkflBS/i1l3JX14fW6Ot9csed60nfbZNXHDTRsnV2xnTVwXcgbvTiboAR4IW+t+lTL5f1rqIqA==
"@types/three@^0.172.0":
version "0.172.0"
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.172.0.tgz#5094852dfa781d2fe1c65eb1b4985a4aa99858b7"
integrity sha512-LrUtP3FEG26Zg5WiF0nbg8VoXiKokBLTcqM2iLvM9vzcfEiYmmBAPGdBgV0OYx9fvWlY3R/3ERTZcD9X5sc0NA==
dependencies:
"@tweenjs/tween.js" "~23.1.1"
"@tweenjs/tween.js" "~23.1.3"
"@types/stats.js" "*"
"@types/webxr" "*"
"@webgpu/types" "*"
fflate "~0.8.2"
meshoptimizer "~0.18.1"
@ -2860,6 +2868,11 @@
dependencies:
debug "^4.3.4"
"@webgpu/types@*":
version "0.1.52"
resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.52.tgz#239995418d86de927269aca54cbadfbee04eb03a"
integrity sha512-eI883Nlag2hGIkhXxAnq8s4APpqXWuPL3Gbn2ghiU12UjLvfCbVqHK4XfXl3eLRTatqcMmeK7jws7IwWsGfbzw==
"@xmldom/xmldom@^0.8.8":
version "0.8.10"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
@ -4496,11 +4509,6 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
@ -5692,12 +5700,11 @@ graphemer@^1.4.0:
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
happy-dom@^15.11.7:
version "15.11.7"
resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-15.11.7.tgz#db9854f11e5dd3fd4ab20cbbcfdf7bd9e17cd971"
integrity sha512-KyrFvnl+J9US63TEzwoiJOQzZBJY7KgBushJA8X61DMbNsH+2ONkDuLDnCnwUiPTF42tLoEmrPyoqbenVA5zrg==
happy-dom@^16.3.0:
version "16.3.0"
resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-16.3.0.tgz#e138b5692cdff8e1e25d02b7730d320b4a151f65"
integrity sha512-Q71RaIhyS21vhW17Tpa5W36yqQXIlE1TZ0A0Gguts8PShUSQE/7fBgxYGxgm3+5y0gF6afdlAVHLQqgrIcfRzg==
dependencies:
entities "^4.5.0"
webidl-conversions "^7.0.0"
whatwg-mimetype "^3.0.0"
@ -7803,10 +7810,10 @@ react-hot-toast@^2.4.1:
dependencies:
goober "^2.1.10"
react-hotkeys-hook@^4.5.1:
version "4.5.1"
resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-4.5.1.tgz#990260ecc7e5a431414148a93b02a2f1a9707897"
integrity sha512-scAEJOh3Irm0g95NIn6+tQVf/OICCjsQsC9NBHfQws/Vxw4sfq1tDQut5fhTEvPraXhu/sHxRd9lOtxzyYuNAg==
react-hotkeys-hook@^4.6.1:
version "4.6.1"
resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-4.6.1.tgz#db9066c07377a1c8be067a238ab16e328266345a"
integrity sha512-XlZpbKUj9tkfgPgT9gA+1p7Ey6vFIZHttUjPqpTdyT5nqQ8mHL7elxvSbaC+dpSiHUSmr21Ya1mDxBZG3aje4Q==
react-is@^16.13.1:
version "16.13.1"
@ -7843,10 +7850,10 @@ react-modal-promise@^1.0.2:
resolved "https://registry.yarnpkg.com/react-modal-promise/-/react-modal-promise-1.0.2.tgz#122620b7f19eec73683affadfa77c543d88edc40"
integrity sha512-dqT618ROhG8qh1+O6EZkia5ELw3zaZWGpMX2YfEH4bgwYENPuFonqKw1W70LFx3K/SCZvVBcD6UYEI12yzYXzg==
react-modal@^3.16.1:
version "3.16.1"
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b"
integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==
react-modal@^3.16.3:
version "3.16.3"
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.3.tgz#c412d41915782e3c261253435d01468e2439b11b"
integrity sha512-yCYRJB5YkeQDQlTt17WGAgFJ7jr2QYcWa1SHqZ3PluDmnKJ/7+tVU+E6uKyZ0nODaeEj+xCpK4LcSnKXLMC0Nw==
dependencies:
exenv "^1.2.0"
prop-types "^15.7.2"
@ -8854,10 +8861,10 @@ thenify-all@^1.0.0:
dependencies:
any-promise "^1.0.0"
three@^0.166.1:
version "0.166.1"
resolved "https://registry.yarnpkg.com/three/-/three-0.166.1.tgz#322cfc48fff4e751cd47d61fd1558c387d098d7c"
integrity sha512-LtuafkKHHzm61AQA1be2MAYIw1IjmhOUxhBa0prrLpEMWbV7ijvxCRHjSgHPGp2493wLBzwKV46tA9nivLEgKg==
three@^0.172.0:
version "0.172.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.172.0.tgz#6944a72f8439e8f7e4b034c8539ec82f5ebe0082"
integrity sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==
thunky@^1.0.2:
version "1.1.0"