Compare commits

...

153 Commits

Author SHA1 Message Date
1a912f58a6 WIP 2025-04-30 10:33:04 -05:00
320740cfb7 Stop parsing CallExpression positional 2025-04-30 10:26:40 -05:00
f1fdf48834 tidy up modeling diagram (#6594)
* neaten modeling diagram

* moar
2025-04-30 10:10:30 +02:00
bae875382c Replace plane strings with literals (#6592)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-30 05:13:11 +00:00
14ce66bcc1 Fix to have stable sorting for end cap artifacts (#6589)
* Fix to have stable sorting for end cap artifacts

* Update output
2025-04-30 04:34:35 +00:00
644c561815 Declare std::math in KCL (BREAKING) (#6588)
Declare std::math in KCL

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-30 03:59:19 +00:00
5f31f3a6b3 Lint suggestion variables on non-camelCase (#6590)
* initial

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

* updates

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-30 15:41:40 +12:00
a0afe9dd0e bump kcl and friends in prep for release (#6591)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-30 15:39:13 +12:00
9c29756a38 lint default planes and add a suggestion (#6587)
lint default planes and other plane cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-30 02:11:02 +00:00
bf63b21d74 [BUG] circle and threePointArc and other overlay fixes (#6409)
* fix length constrainting

* conflicet

* fix circle center constraints

* fix up circle remove constraints more and add test

* fix three point arc overlays and add test for it

* fixes

* console log

* fix tangential arc stuff

* fmt

* fix unit test

* fix console error when selectiong arc
2025-04-30 02:08:45 +00:00
0ea0d1703e Remove deprecated syntax (#6561)
* Remove deprecated syntax

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

* fix one test

* fix sketch on revolved face test

* fix test: empty-scene default-planes act as expected

* fix up more tests

* another fix

* remove another const

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
2025-04-30 13:12:40 +12:00
29b8a442c2 Codemirror lsp enhance (#6580)
* codemirror side

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

* codemirror actions

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

* codemirror actions

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

* code mirror now shows lint suggestions

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

* fix hanging params with test

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

* updates for signature help

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

* fix clone

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

* add tests

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

* add tests

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

* clippy

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

* clippy

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

* updates

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

* Update packages/codemirror-lsp-client/src/plugin/lsp.ts

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* z-index

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

* playwright tests

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

* updates

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-04-29 20:57:02 -04:00
844f229b5a Remove trig functions from prelude and change their unit handling (BREAKING) (#6565)
Remove trig functions from prelude and change their unit handling

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-30 12:40:11 +12:00
fa51b4bbbc Post-kwargs cleanup (#6571)
* Remove dead code
* Stop creating CallExpression and instead create CallExpressionKw
2025-04-29 16:05:45 -05:00
1fa6e1eccc Name shards consistently (#6582) 2025-04-29 16:39:08 -04:00
44b810ee0a Partition nextest runs (#6574)
* Partition nextest runs

* move name back to 'cargo test'

* Fix duplicate name

There were two jobs both named `build-test-artifacts`. Changed the latter
to `run-test-artifacts`

* cd into rust/ before running nextest

* Get token when running the tests

* Try getting archive into correct dir via different method

* Bump shards to 6

* Replace llvm-cov with nextest

* Adjust job name

* Remove unnecessary comments

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
2025-04-29 16:28:13 -04:00
a9998be176 Remove unneeded derive Deserialize (#6579)
This revealed that one of our variants is never constructed.
2025-04-29 12:17:41 -07:00
5e200aebcc [Feature]: Load external model becomes Add file to project, global application add file to project with home page update. (#6506)
* chore: saving off skeleton

* fix: saving skeleton

* chore: skeleton for loading projects from project directory path

* chore: cleaning up useless state transition to be an on event direct to action state

* fix: new structure for web vs desktop vs react machine provider code

* chore: saving off skeleton

* fix: skeleton logic for react? going to move it from a string to obj.string

* fix: trying to prevent error element unmount on global react components. This is bricking JS state

* fix: we are so back

* chore: implemented navigating to specfic KCL file

* chore: implementing renaming project

* chore: deleting project

* fix: auto fixes

* fix: old debug/testing file oops

* chore: generic create new file

* chore: skeleton for web create file provide

* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?

* chore: save off progress before deleting other project implementation, a few missing features still

* chore: trying a different init skeleton? most likely will migrate

* chore: first attempt of purging projects context provider

* chore: enabling toast for some machine state

* chore: enabling more toast success and error

* chore: writing read write state to the system io based on the project path

* fix: tsc fixes

* fix: use file system watcher, navigate to project after creation via the requestProjectName

* chore: open project command, hooks vs snapshot context helpers

* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.

* fix: codespell fixes

* chore: implementing more project commands

* chore: PR improvements for root.tsx

* chore: leaving comment about new Router.tsx layout

* fix: removing debugging code

* fix: rewriting component for readability

* fix: improving web initialization

* chore: implementing import file from url which is not actually that?

* fix: clearing search params on import file from url

* fix: fixed two e2e tests, forgot needsReview when making new command

* fix: fixing some import from url business logic to pass e2e tests

* chore: script for diffing circular deps +/-

* fix: formatting

* fix: massive fix for circular depsga!

* fix: trying to fix some errors and auto fmt

* fix: updating deps

* fix: removing debugging code

* fix: big clean up

* fix: more deletion

* fix: tsc cleanup

* fix: TSC TSC TSC TSC!

* fix: typo fix

* fix: clear query params on web only, desktop not required

* fix: removing unused code

* fmt

* Bring back `trap` removed in merge

* Use explicit types instead of `any`s on arg configs

* Add project commands directly to command palette

* fix: deleting debugging code, from PR review

* fix: this got added back(?)

* fix: using referred type

* fix: more PR clean up

* fix: big block comment for xstate architecture decision

* fix: more pr comment fixes

* fix: saving off logic, need a big cleanup because I hacked it together to get a POC

* fix: extra business?

* fix: merge conflict just added them back why dude

* fix: more PR comments

* fix: big ciruclar deps fix, commandBarActor in appActor

* chore: writing e2e test, still need to fix 3 bugs

* chore: adding more scenarios

* fix: formatting

* fix: fixing tsc errors

* chore: deleting the old text to cad and using the new application level one, almost there

* fix: prompt to edit works

* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file

* fix: settings for highlight edges now works

* chore: adding another e2e test

* fix: cleaning up e2e tests and writing more of them

* fix: tsc type

* chore: more e2e improvements, unique project name  in text to cad

* chore: e2e tests should be good to go

* fix: gotcha comment

* fix: enabled web t2c, codespell fixes

* fix: fixing merge conflcits??

* feat: implemented load external for kcl samples

* feat: load external model from disk

* fix: trying to delete old stuff

* fix: all command trigger locations now have defaults for current project

* fix: gotcha comment for the future

* chore: hiding import file from url command, two separate commands for 3d and kcl file adding

* chore: commands are now add file to project, 3rd iteration

* fix: t2c in file menu fixed

* chore: updating file menu for new global actions

* fix: auto fixes

* fix: the command bar arg flow for web add kcl file seems backwards?

* chore: updated home layout, added create from kcl sample button

* chore: remapping some menu actions

* fix: fixing open dialog copy

* fix: an e2e test

* fix: fixed e2e tests

* fix: fixed e2e tests

* fix: auto fixes

* fix: pr clean up

* fix: removing console log

* fix: PR updates

* fix: the reviewed stage boolean required the expected state to change. Also I progressed the command bar too soon

* fix: no idea how this passed locally yesterday? I removed the {dir} unused but I need the function's logic but not the return value...

* fix: should be good to go?

---------

Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-29 13:04:45 -05:00
e0cd3efc64 fix edge cuts & clone (#6572)
* fix edge cuts & clone

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

* updates

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

* fix edge_id

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

* code comemnt

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-29 16:51:52 +00:00
77e3efde9a Deterministic parallelized snaps (#6527)
* initial pass

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>

changes

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

more updates

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

more updates

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

serde variant name

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

fixes

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

updates

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

some sort

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

some sort

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

some sort

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

some sort

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

some sort

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

some sort

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

some sort

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

some sort

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

some sort

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

some sort

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>

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>

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>

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>

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>

sort the edges

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

fixes

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

u[dates

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

u[dates

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>

cleanups

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>

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>

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>

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>

add bs-to-kcl

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>

* fixes

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

* updates

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

* fixes

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

* fixes

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-29 13:38:52 +00:00
a173a82d59 Remove skips to align with new way of opting-in tests (#6560) 2025-04-29 08:50:19 -04:00
4d2bc18c2f Fix lint after #6558 (#6562) 2025-04-29 15:23:50 +10:00
aca5fdb521 Remove some deprecated functions from std (#6531)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-28 20:24:18 -04:00
8867258e47 Notify TAB API to share a summary report on PRs (#6544)
* Notify TAB API to share a summary report on PRs

* wip: break a test

* Revert "wip: break a test"

This reverts commit 80c3793cbd.
2025-04-28 19:30:42 -04:00
f6cb725268 [bug]: Chokidar + reading projects spams multiple times (#6558)
fix: do not double or triple load reading folders from disk due to file system watcher when deleting
2025-04-28 19:15:20 -04:00
1bd570ceb9 Remove unnecessary docs (#6559)
These aren't used anymore
2025-04-28 22:42:01 +00:00
1c87298b44 Migrate more functions to use kwargs (#6551)
These little helper functions (legAng, segLen etc) were already using keyword arguments, but when the frontend created AST nodes, it was creating them as CallExpression not CallExpressionKw. We have backwards-compatibility so it's fine, but we should not be relying on that anymore.

This PR should not have any user-observable change.
2025-04-28 22:21:37 +00:00
3a23ec1bee Create std::units module (#6528)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-29 08:41:31 +12:00
d96a4d3337 Improvements to axis handling (#6530)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-29 08:29:22 +12:00
94452cce88 ability to set suggestions on lints (#6535)
* fix the lint tests which were not compiling

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

* updates

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

* apply sugggestions for offsetplanes

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

* updates

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

* diagnostics and suggestions for offset planes

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-29 07:07:10 +12:00
2e754f2a11 BREAKING: Change to disallow indexing KCL records/objects with strings (#6529)
* Change to disallow indexing records/objects with strings

* Update output

* Remove outdated sim test

* Fix tests
2025-04-28 12:08:47 -04:00
719136937e #4852 Add test for delete line segments in sketch mode using keyboard (#6543)
* wip hack to delete line segments

* unrelated: clean up console

* better check if current selection is segment before deletion

* lint

* add test for delete segment with key
2025-04-28 11:32:55 -04:00
e207552255 Home: Update read blog icon to glasses (#6541) 2025-04-28 14:47:15 +00:00
1835e49191 Remove docs for deleted KCL functions (#6540)
These functions were removed as part of our big 1.0 kwargs work,
so their docs page should have been deleted, but we forgot to.
2025-04-28 14:43:24 +00:00
145c28bbd5 Remove unused Arc button from toolbar (#6539) 2025-04-28 14:32:43 +00:00
a58a3361b6 #4852 Delete line segments in sketch mode using keyboard (#6407)
* wip hack to delete line segments

* unrelated: clean up console

* better check if current selection is segment before deletion

* lint
2025-04-28 10:27:11 -04:00
efba773635 Move operations on solids to be declared in KCL (#6462)
* Declare chamfer in KCL

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

* Ignore more in the simulation tests

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

* Declare fillet in KCL

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

* Move shell and hollow to KCL

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-28 14:20:38 +12:00
4439229ad2 turn back on the test i tturned off (#6522)
* random other cahnges

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

* turn back on test

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

* docs

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

* lots of enhancements

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

* cleanup

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

* updates

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

* mesh test

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

* mesh test

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

* check panics

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

* updates

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

* check panics

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

* check panics

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

* cleanup

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

* if running in vitest make single threadedd

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

* check if running in vitest

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

* console logs

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-27 23:54:32 +00:00
0dcb8baf64 Post-kwargs cleanup (#6524)
Remove unused positional argument code.
2025-04-27 07:59:32 -07:00
921adcb3eb bump kcl lib nad friends (#6521)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-27 02:13:51 -04:00
24465cf463 Parallelize the artifact graph only time suck (#6482)
* parallelize the artifact only time suck

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

updates

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

make wasm safe

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

updates

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

* artifact graph things

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

* updates

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-27 04:21:26 +00:00
d0b0365f75 Delete unused copilot tests (#6518)
Delete unused tests
2025-04-26 23:47:43 +00:00
0f88598dc0 BREAKING: Migrate math functions to keyword args (#6491) 2025-04-26 23:33:41 +00:00
d7e80b3cc7 Assemblies: Point-and-click Clone (#6478)
* WIP: Assemblies: Point-and-click Clone
Fixes #6209

* Make assemblies commands available for release
Fixes #6497

* Break insert out of the group, new icon, add Clone disabled

* Add rotate thanks to @franknoirot

* Update relevant snapshots

* Fix pathToNode

* Add clone to stdlibmap

* Cleaned more things

* Add custom icon

* Add variable name for clone

* Add e2e test for import and translated import

* Remove stale comment

* Add test for selection based extrude clone

* First batch of suggestions from @lee-at-zoo-corp, tysm!

* Clean up test names

* Second batch of @lee-at-zoo-corp's suggestion for modelingMachine error handling
2025-04-26 22:26:39 +00:00
25bb95a66e Fix just command to match test function rename (#6517) 2025-04-26 15:23:27 -07:00
6e115c19d5 KCL: Migrate hole to kwargs (#6382)
Previously:

`|> hole(circle(radius = 2, center = p), %)`

Now:

`|> subtract2d(tool = circle(radius = 2, center = p))`
2025-04-26 15:31:51 -05:00
5a18f551aa Adjust sharding to account for more tests being run (#6509) 2025-04-26 19:45:52 +00:00
0426967bf7 Rework home layout to have a sidebar (#6423)
* chore: saving off skeleton

* fix: saving skeleton

* chore: skeleton for loading projects from project directory path

* chore: cleaning up useless state transition to be an on event direct to action state

* fix: new structure for web vs desktop vs react machine provider code

* chore: saving off skeleton

* fix: skeleton logic for react? going to move it from a string to obj.string

* fix: trying to prevent error element unmount on global react components. This is bricking JS state

* fix: we are so back

* chore: implemented navigating to specfic KCL file

* chore: implementing renaming project

* chore: deleting project

* fix: auto fixes

* fix: old debug/testing file oops

* chore: generic create new file

* chore: skeleton for web create file provide

* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?

* chore: save off progress before deleting other project implementation, a few missing features still

* chore: trying a different init skeleton? most likely will migrate

* chore: first attempt of purging projects context provider

* chore: enabling toast for some machine state

* chore: enabling more toast success and error

* chore: writing read write state to the system io based on the project path

* fix: tsc fixes

* fix: use file system watcher, navigate to project after creation via the requestProjectName

* chore: open project command, hooks vs snapshot context helpers

* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.

* fix: codespell fixes

* chore: implementing more project commands

* chore: PR improvements for root.tsx

* chore: leaving comment about new Router.tsx layout

* fix: removing debugging code

* fix: rewriting component for readability

* fix: improving web initialization

* chore: implementing import file from url which is not actually that?

* fix: clearing search params on import file from url

* fix: fixed two e2e tests, forgot needsReview when making new command

* fix: fixing some import from url business logic to pass e2e tests

* chore: script for diffing circular deps +/-

* fix: formatting

* fix: massive fix for circular depsga!

* fix: trying to fix some errors and auto fmt

* fix: updating deps

* fix: removing debugging code

* fix: big clean up

* fix: more deletion

* fix: tsc cleanup

* fix: TSC TSC TSC TSC!

* fix: typo fix

* fix: clear query params on web only, desktop not required

* fix: removing unused code

* fmt

* Bring back `trap` removed in merge

* Use explicit types instead of `any`s on arg configs

* Add project commands directly to command palette

* fix: deleting debugging code, from PR review

* fix: this got added back(?)

* fix: using referred type

* fix: more PR clean up

* fix: big block comment for xstate architecture decision

* fix: more pr comment fixes

* fix: saving off logic, need a big cleanup because I hacked it together to get a POC

* fix: extra business?

* fix: merge conflict just added them back why dude

* fix: more PR comments

* fix: big ciruclar deps fix, commandBarActor in appActor

* chore: writing e2e test, still need to fix 3 bugs

* chore: adding more scenarios

* fix: formatting

* fix: fixing tsc errors

* chore: deleting the old text to cad and using the new application level one, almost there

* fix: prompt to edit works

* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file

* fix: settings for highlight edges now works

* chore: adding another e2e test

* fix: cleaning up e2e tests and writing more of them

* fix: tsc type

* chore: more e2e improvements, unique project name  in text to cad

* chore: e2e tests should be good to go

* fix: gotcha comment

* fix: enabled web t2c, codespell fixes

* fix: fixing merge conflcits??

* fix: t2c is back

* Rework home layout to have a sidebar

fmt I think

* Add two links to the bottom of the sidebar

Mostly to visually anchor it

* Tweak some style things

* update test util whose locator needs to change

* tsc and fmt

* Stupid heading change broke the dang E2E tests

* Make that heading locator a part of the home page fixture

* pierremtb/new-snaps-for-frank (#6516)

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

---------

Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-26 15:55:01 +00:00
9d893d8f0b Remove syntax not supported on all platforms (#6513)
* Remove syntax not supported on all platforms

https://github.com/KittyCAD/modeling-app/actions/runs/14677571075/job/41196471368

* Update dependencies
2025-04-26 05:39:56 +00:00
8de648f0db getCommonEdge as default way of filleting (#6043)
* Common edge faces into artifact graph

* clean up

* kingdom of tags

* add tests

* hook up tags with edge treatments

* update unit tests

* update e2e

* clean up

* more fix up after main merge

* fmt

* revolve fix

* fix new circular dependency

* fix revolve

* remove numbers from circ deps, makes diffs bad

* sim test updates

* try and get tests working

* update

* Fix tsc error

---------

Co-authored-by: max-mrgrsk <156543465+max-mrgrsk@users.noreply.github.com>
Co-authored-by: max <margorskyi@gmail.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-04-26 04:00:28 +00:00
50f8131d83 Kwargs: map and reduce (#6480)
Migrate array's `map`, `reduce` and `push` functions to use keyword arguments.
2025-04-25 19:09:03 -05:00
5a4f8bd522 [Feature]: Enable Text-to-CAD at the application level (#6501)
* chore: saving off skeleton

* fix: saving skeleton

* chore: skeleton for loading projects from project directory path

* chore: cleaning up useless state transition to be an on event direct to action state

* fix: new structure for web vs desktop vs react machine provider code

* chore: saving off skeleton

* fix: skeleton logic for react? going to move it from a string to obj.string

* fix: trying to prevent error element unmount on global react components. This is bricking JS state

* fix: we are so back

* chore: implemented navigating to specfic KCL file

* chore: implementing renaming project

* chore: deleting project

* fix: auto fixes

* fix: old debug/testing file oops

* chore: generic create new file

* chore: skeleton for web create file provide

* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?

* chore: save off progress before deleting other project implementation, a few missing features still

* chore: trying a different init skeleton? most likely will migrate

* chore: first attempt of purging projects context provider

* chore: enabling toast for some machine state

* chore: enabling more toast success and error

* chore: writing read write state to the system io based on the project path

* fix: tsc fixes

* fix: use file system watcher, navigate to project after creation via the requestProjectName

* chore: open project command, hooks vs snapshot context helpers

* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.

* fix: codespell fixes

* chore: implementing more project commands

* chore: PR improvements for root.tsx

* chore: leaving comment about new Router.tsx layout

* fix: removing debugging code

* fix: rewriting component for readability

* fix: improving web initialization

* chore: implementing import file from url which is not actually that?

* fix: clearing search params on import file from url

* fix: fixed two e2e tests, forgot needsReview when making new command

* fix: fixing some import from url business logic to pass e2e tests

* chore: script for diffing circular deps +/-

* fix: formatting

* fix: massive fix for circular depsga!

* fix: trying to fix some errors and auto fmt

* fix: updating deps

* fix: removing debugging code

* fix: big clean up

* fix: more deletion

* fix: tsc cleanup

* fix: TSC TSC TSC TSC!

* fix: typo fix

* fix: clear query params on web only, desktop not required

* fix: removing unused code

* fmt

* Bring back `trap` removed in merge

* Use explicit types instead of `any`s on arg configs

* Add project commands directly to command palette

* fix: deleting debugging code, from PR review

* fix: this got added back(?)

* fix: using referred type

* fix: more PR clean up

* fix: big block comment for xstate architecture decision

* fix: more pr comment fixes

* fix: saving off logic, need a big cleanup because I hacked it together to get a POC

* fix: extra business?

* fix: merge conflict just added them back why dude

* fix: more PR comments

* fix: big ciruclar deps fix, commandBarActor in appActor

* chore: writing e2e test, still need to fix 3 bugs

* chore: adding more scenarios

* fix: formatting

* fix: fixing tsc errors

* chore: deleting the old text to cad and using the new application level one, almost there

* fix: prompt to edit works

* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file

* fix: settings for highlight edges now works

* chore: adding another e2e test

* fix: cleaning up e2e tests and writing more of them

* fix: tsc type

* chore: more e2e improvements, unique project name  in text to cad

* chore: e2e tests should be good to go

* fix: gotcha comment

* fix: enabled web t2c, codespell fixes

* fix: fixing merge conflcits??

* fix: t2c is back

* Remove spaces in command bar test

* fmt

---------

Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
Co-authored-by: lee-at-zoo-corp <lee@zoo.dev>
2025-04-25 19:04:47 -04:00
f8e53d941d Change so that var definitions can be a module's return value (#6504)
* Change so that var definitions can be a module's return value

* Change car wheel assembly to use the new return mechanism

* Add sim test

* Update output

* Update module docs

* Add safety check to only work with modules

* Fix to use updated keyword args
2025-04-25 21:55:54 +00:00
717a2039cb Restore quoting of union greps (#6510) 2025-04-25 21:21:41 +00:00
6e7c44fca7 Migrate from unmaintained tempdir to tempfile (#6476) 2025-04-25 17:19:04 -04:00
ffbe20b586 Kwargs: startProfileAt (#6424)
Previous:

```
startProfileAt([x, y], %)
startProfileAt([x, y], sketch001)
```

New:
```
startProfile(%, at = [x, y])
startProfile(sketch001, at = [x, y])
```
2025-04-25 21:01:35 +00:00
9547e95e9d Feature tree loading indicator is too big and requires scroll to see (#6508)
Fixes #6477
2025-04-25 19:58:33 +00:00
a1f31f4348 Update test to check for the correct units toast message (#6505) 2025-04-25 14:19:54 -04:00
604e244395 Make assemblies commands available for release (#6498)
* Make assemblies commands available for release
Fixes #6497

* Break insert out of the group, new icon, add Clone disabled

* Add rotate thanks to @franknoirot

* Update relevant snapshots

* Trigger CI
2025-04-25 16:49:11 +00:00
fe22a67cf6 #5184 Ability to toggle default planes visibility (#6333)
* add first version of DefaultPlanes to FeatureTreePane

* fix lint issues

* don't show default planes UI in sketch mode

* lint

* toggling default planes: implementation in xstate

* revert malformed modelingMachine.ts

* lint

* save and restore default plane visibility when returning to modeling mode

* fmt

* tsc

* introduce new cleanup state with actor when exiting sketch mode

* temp remove restore default plane visibility - causes error on starting up a project

* set selection filter after executeAst - this is a wip hacky fix

* remove unused early return: this also caused plane selection to only work with double click

* lint

* no need to set selection filter to curves only, we want faces to be selectable in modeling mode, even though this means default planes are also selectable

* tightening types for visibility map

* lint

* cleanups

* fix border issue when visibility toggle is not active and props.visible === true

* ui updates on FeatureTreePane/default planes

* no pointer cursor for unselectable default planes

* show default planes initially even for non-empty projects

* dont show default planes initially when project is not empty

* fix test: Only show axis planes when there are no errors

* fixes for sketch tests

* better initialize for planes

* lint

* fix uneccessary 'reset camera position' in sketch entry

* revert hiding/showing content depending on artifact graph for tests

* only show default planes when there are no errors

* disable Restore default plane visibility, was causing temporary flashing of default planes when exiting sketch mode

* Always show default plane visibility toggles, regardless of being on/off

* revert modelingMachine to original idle states to avoid 'zoom_to_fit' test regression - probably racing condition

* fmt
2025-04-25 18:21:19 +02:00
885d2afaa3 Make boolean commands available for release (#6500)
* Make boolean commands available for release
Fixes #6499

* Update src/lib/commandBarConfigs/modelingCommandConfig.ts

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-04-25 15:18:17 +00:00
be4a32a59e Switch to dynamically disabling broken tests (#6492)
* Switch to dynamically disabling broken tests

* Remove stale comment

* Fix nested tests
2025-04-25 10:49:22 -04:00
c501d3bfbf Fix whole module import deletion in feature tree (#6456)
* Fix whole module import deletion in feature tree
Fixes #6447

* Delete both

* Fix tests

* Lint

* Clean up for review

* Update src/lang/modifyAst.ts

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* Add extra error case

* Update e2e/playwright/point-click-assemblies.spec.ts

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-04-25 16:45:51 +02:00
0ef1483e11 Stabilize test by allowing more time before clicking object (#6495)
stabilize test by allowing more time before clicking object
2025-04-25 08:55:32 -04:00
bbaaf86e4d pre commit fmt (#6470)
* setup

* remove pre-push

* undo weird fmt
2025-04-25 04:58:58 -04:00
6a0e10f8ab Test all platforms hourly (#6494) 2025-04-25 04:58:13 -04:00
5c0ca52291 Foreign imports go thru parallelization too (#6488)
* start of parallelizing forign imports

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

* clippy

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

* remove_printlns

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

* remove shit that doesnt work

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

* remove shit that doesnt work

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

* put back

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

* put back

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

* put back

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

* multiple

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

* updates

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

* remove println

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

* updates

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

* clone docs

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

* add whole module import docs

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

* add whole module import docs

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-25 03:25:02 +00:00
bff13f6bfe Opt-in tests that cover Windows-specific capabilities (#6489)
* Opt-in tests that cover Windows-specific capabilities

* Remove unnecessary quotes
2025-04-25 00:50:26 +00:00
6001b71f06 Add Open in New Window and reexecution on import change (#6379)
* Quick prototype: open in new window in file tree

* WIP: refresh on imported file change

* Fix up reexecution

* Clean up

* Add test 'Assembly gets reexecuted when imported models are updated externally'

* Clean up
2025-04-25 09:02:18 +10:00
bd1e68a4c8 turn on fillets UI in prod (#6474)
* turn on fillets

* delete status property re-Pierre

---------

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-24 17:22:28 -04:00
8589f8fc5f Opt-in tests that cover macOS-specific capabilities (#6486) 2025-04-24 17:15:11 -04:00
6641e1178b bump three point arc to be the default (#6464)
* bump three point arc up

* Update tests to select tangential arc from dropdown

* Fix another test that used tangential arc

* Fix up snapshot tests' use of Tangential Arc

---------

Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-25 06:40:33 +10:00
6e0f1e71b2 add a test for coercing a nested array (#6326)
* add a test for coercing a nested array

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

* fix test

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

* add console log

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

* add console log

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

* add test for what we get back on no_outputs error

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

* remove my log

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

* move test

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Paul Tagliamonte <paul@zoo.dev>
2025-04-24 19:37:44 +00:00
0e945b6457 properly close the context (#6485)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-24 19:37:22 +00:00
19155a9132 Fix logout issue on desktop (#6450)
* WIP: Fix logout issue on desktop
Fixes #5640

* Fix test with addInitScript
2025-04-24 15:29:17 -04:00
305d613d40 Nadro/adhoc/system io machine (#6352)
* chore: saving off skeleton

* fix: saving skeleton

* chore: skeleton for loading projects from project directory path

* chore: cleaning up useless state transition to be an on event direct to action state

* fix: new structure for web vs desktop vs react machine provider code

* chore: saving off skeleton

* fix: skeleton logic for react? going to move it from a string to obj.string

* fix: trying to prevent error element unmount on global react components. This is bricking JS state

* fix: we are so back

* chore: implemented navigating to specfic KCL file

* chore: implementing renaming project

* chore: deleting project

* fix: auto fixes

* fix: old debug/testing file oops

* chore: generic create new file

* chore: skeleton for web create file provide

* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?

* chore: save off progress before deleting other project implementation, a few missing features still

* chore: trying a different init skeleton? most likely will migrate

* chore: first attempt of purging projects context provider

* chore: enabling toast for some machine state

* chore: enabling more toast success and error

* chore: writing read write state to the system io based on the project path

* fix: tsc fixes

* fix: use file system watcher, navigate to project after creation via the requestProjectName

* chore: open project command, hooks vs snapshot context helpers

* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.

* fix: codespell fixes

* chore: implementing more project commands

* chore: PR improvements for root.tsx

* chore: leaving comment about new Router.tsx layout

* fix: removing debugging code

* fix: rewriting component for readability

* fix: improving web initialization

* chore: implementing import file from url which is not actually that?

* fix: clearing search params on import file from url

* fix: fixed two e2e tests, forgot needsReview when making new command

* fix: fixing some import from url business logic to pass e2e tests

* chore: script for diffing circular deps +/-

* fix: formatting

* fix: massive fix for circular depsga!

* fix: trying to fix some errors and auto fmt

* fix: updating deps

* fix: removing debugging code

* fix: big clean up

* fix: more deletion

* fix: tsc cleanup

* fix: TSC TSC TSC TSC!

* fix: typo fix

* fix: clear query params on web only, desktop not required

* fix: removing unused code

* fmt

* Bring back `trap` removed in merge

* Use explicit types instead of `any`s on arg configs

* Add project commands directly to command palette

* fix: deleting debugging code, from PR review

* fix: this got added back(?)

* fix: using referred type

* fix: more PR clean up

* fix: big block comment for xstate architecture decision

* fix: more pr comment fixes

* fix: merge conflict just added them back why dude

* fix: more PR comments

* fix: big ciruclar deps fix, commandBarActor in appActor

---------

Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-24 13:32:49 -05:00
95f2caacab Fix testing-selections test / clicking on empty space (#6481)
fix clicking on empty space which happened to click on UI, causing the test to fail
2025-04-24 17:46:07 +00:00
8f61ee1d2f Change getOppositeEdge, getNextAdjacentEdge, and getPreviousAdjacentEdge to keyword args (#6469)
* Change getOppositeEdge, getNextAdjacentEdge, and getPreviousAdjacentEdge to keyword args

* Update generated docs
2025-04-24 12:39:37 -04:00
b02dbd4fe6 Kwargs: leg helpers (#6459)
legLen, legAngX, legAngY moved to keyword arguments
2025-04-24 09:53:19 -05:00
668f6671a9 BREAKING: Remove angleToMatchLengthX and angleToMatchLengthY (#6451)
* Remove angleToMatchLengthX and angleToMatchLengthY from constraint code generation

* Change KCL stdlib functions to be deprecated

* Remove references from TS tests

* Remove angleToMatchLengthX and angleToMatchLengthY

* Update docs

* Fix file paths
2025-04-24 14:33:27 +00:00
f6387eb7e9 fmt (#6473) 2025-04-24 13:10:06 +00:00
83a87b046f Declare std::offsetPlane in KCL (#6344)
* Declare std::offsetPlane in KCL

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

* Use two axes to define planes in KCL

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-24 22:01:27 +12:00
20c2ce3bac Shorten tronapp setup fail (#6362)
* shorten tron app setup fail

* fmt

* more tweaks to tronapp setup

* bump initial timeout back to 120s

* Update e2e/playwright/zoo-test.ts

---------

Co-authored-by: Zookeeper Lee <lee@zoo.dev>
2025-04-24 06:35:57 +00:00
2956f9ed55 YOU FOOLS I WON THE CONTEST (#6328)
* dodec

* fmt

* comment

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

* Fix so that just commands regenerate ast output

* overwrite

* Update just command to include manifest

* Update generated output

* merge main post

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-04-24 06:08:45 +00:00
510d74f2c7 Add clone (#5462)
* 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>

updates

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

update the extrude idds

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

updates

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

fix sample

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

better docs

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

fix the start and end tag

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

better docs

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

updates

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

new tests

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

codespell

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>

* fix examples

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

* fix some stuff

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

* fixes

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>

* add another test for fillet

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

* Update rust/kcl-lib/src/std/clone.rs

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* fixes

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

* add sweep test

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

* revolve test;

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

* Update rust/kcl-lib/src/std/clone.rs

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* add another test for fillet

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

* allow cloning an imported geometry;

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

* allow for imported geometry

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

* updates

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

* update docs

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-04-24 04:26:09 +00:00
457ab28f74 Appearance import fixes (#6466)
* fix appearance imports

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

* fix appearance

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-24 00:43:16 +00:00
1502f923ee KCL bugfix: CallExpressionKw was not usable as math operand (#6460)
Closes https://github.com/KittyCAD/modeling-app/issues/4992
2025-04-23 21:21:57 +00:00
f03a684eec Modeling view appearance final tweaks (#6425)
* Remove bug button from LowerRightControls

There is a "report a bug" button in the help menus, both native and
lower-right corner. This is overkill, and users are not using coredump
well.

* Remove coredump from refresh UI button

* Add a "Refresh app" command to palette

* Update snapshots

* Rework "Refresh and report bug" menu item to "Report a bug"

* Add refresh button to sidebar

* Convert upper-right refresh button to Share

* Tweak styles of command button

* Make anonymous user icon same size as known user image

* Remove ModelStateIndicator

* Use hotkeyDisplay for the sidebar too

* Update snapshots

* Remove tooltip from command bar open button

* tsc, lint, and fmt
2025-04-23 15:20:45 -04:00
45e17c50e7 docs: Add docs for creating simulation tests (#6453) 2025-04-23 11:59:07 -07:00
6bf74379a7 Kwargs: hollow (#6438) 2025-04-23 18:35:33 +00:00
01c6fd53fa Fix Cargo.lock (#6452) 2025-04-23 17:39:35 +00:00
f8306c0275 Try running with 8 macOS cores again (#6420)
* Revert "Disable all macOS testing for now (#6395)"

This reverts commit fbc3251c3f.

* Try running with 8 macOS cores again
2025-04-23 13:10:09 -04:00
900ef9e18d Release KCL 63 (#6446) 2025-04-23 12:35:16 -04:00
a46186573c Kwargs: profileStart/x/y (#6439) 2025-04-23 15:21:58 +00:00
90f6c1bb04 Fix Back button on SignIn page & Add Cancel button (#6415)
* Back button on SignIn page leads to Home page
Fixes #6413

* Add regression test for the bug, and for new cancel button

* Full sign in e2e test

* Good bot

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-04-23 15:12:33 +00:00
41d946b339 Remove Spline and Text tools from sketch mode toolbar (#6427)
* Remove Spline and Text tool from sketch toolbar

* Update sketch-related snapshots

* Update snapshots
2025-04-23 13:06:51 +00:00
b7385d5f25 Turn on units of measure (BREAKING CHANGE) (#6343)
* Turn on uom checks

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

* Convert all lengths to mm for engine calls

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 22:58:35 +00:00
3d22f6cd66 Only save one version of tag info per epoch (#6429)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-23 09:22:52 +12:00
9730e3f5b3 KCL: Rephrase confusing error msg (#6436)
Before:

  × undefined value: memory item key `foo` is not defined

Now:

  × undefined value: `foo` is not defined
2025-04-22 20:24:53 +00:00
29d6b22d63 Restore tests that use Text-to-CAD (#6284) 2025-04-22 14:55:10 -04:00
f99e44e371 Kwargs: assert functions (#6406)
Closes https://github.com/KittyCAD/modeling-app/issues/6408
2025-04-22 17:44:52 +00:00
8be36d3d16 Update known-issues.md (#6428)
* Update known-issues.md

* Update known-issues.md

Little more description.

---------

Co-authored-by: Josh Gomez <114548659+jgomez720@users.noreply.github.com>
2025-04-22 17:18:35 +00:00
bc1742af48 Remove bold mono font (#6414)
* Remove all use of bold mono font
A few mono font points are left, mostly for numbers which look better in
monospace.

* Update snapshots
2025-04-22 15:17:47 +00:00
e4080cc184 Allow snapshot tests to report status (#6430) 2025-04-22 10:39:21 -04:00
18de6ccb59 #6417 Fix svg attribute names, add new eslint rule (#6418)
* fix svg attribute names, add new eslint rule

* tabs -> spaces
2025-04-22 09:15:38 -04:00
f00ea4cf5e Use TAB API to determine when merges are blocked (#6405)
* Use TAB API to determine when merges are blocked

* Enable a test that is known to fail
2025-04-22 09:02:02 -04:00
c5539be814 Warn if settings (or other inner attributes) are not at the top of a file (#6426)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 14:43:09 +12:00
f5d6a12d8c Remove unused KCL file (#6383) 2025-04-21 23:59:30 +00:00
e4e18dfd4b Coerce the result of a function call to the function's return type (#6309)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 11:00:53 +12:00
30ee547ce4 More consistency in 'Create project' and 'Share part via Zoo link' buttons and commands (#6378)
Polish: More consistency in 'Create project' and 'Share part via Zoo link' buttons and commands
2025-04-21 15:08:51 -04:00
f8ca6ad746 BREAKING: Change polygon to keyword args (#6385)
* Change polygon to keyword args

* Update docs

* Update generated output

* Update docs to mention the default for inscribed

* Appease clippy

* Remove tag parameter

* Update docs since removing tag

* Remove inscribed from autocomplete snippet since the default is true
2025-04-21 18:29:32 +00:00
7a90d029e1 Update onboarding interactive numbers test to use editor fixture, take 2 (#6399)
Update onboarding interactive numbers test to use editor fixture

Trying to bring it down from the leaderboard of failed tests.

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-21 14:34:20 +00:00
2900858171 Bump the minor group across 1 directory with 8 updates (#6411)
Bumps the minor group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@csstools/postcss-oklab-function](https://github.com/csstools/postcss-plugins/tree/HEAD/plugins/postcss-oklab-function) | `4.0.8` | `4.0.9` |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.51.1` | `1.52.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.14.0` | `22.14.1` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `4.3.4` | `4.4.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.29.1` | `8.30.1` |
| [rollup](https://github.com/rollup/rollup) | `4.39.0` | `4.40.0` |



Updates `@csstools/postcss-oklab-function` from 4.0.8 to 4.0.9
- [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)

Updates `@playwright/test` from 1.51.1 to 1.52.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.51.1...v1.52.0)

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

Updates `@vitejs/plugin-react` from 4.3.4 to 4.4.1
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@4.4.1/packages/plugin-react)

Updates `typescript-eslint` from 8.29.1 to 8.30.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/typescript-eslint)

Updates `rollup` from 4.39.0 to 4.40.0
- [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.39.0...v4.40.0)

Updates `@typescript-eslint/eslint-plugin` from 8.29.1 to 8.30.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.29.1 to 8.30.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@csstools/postcss-oklab-function"
  dependency-version: 4.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor
- dependency-name: "@playwright/test"
  dependency-version: 1.52.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: "@types/node"
  dependency-version: 22.14.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 4.4.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: typescript-eslint
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: rollup
  dependency-version: 4.40.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 12:42:14 +00:00
0dee219e46 Check for local name clash with existing variables in Insert flow (#6375)
Check for local name alias clashes with extisting var in Insert flow
Fixes #6230
2025-04-21 10:35:43 +00:00
790613e708 KCL: Convert bezierCurve to use keyword args (#6381) 2025-04-20 20:10:27 -05:00
0a35722595 Silence snapshot failures for now (#6403) 2025-04-19 10:59:53 +00:00
f30fc376ee Allow deletion of only item in AST (#6335)
* Update test to check for deletion of only operation

* Allow updateEditorWithAstAndWriteToFile to clear AST

* Update src/lang/codeManager.ts

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* Weave `isDeleting` through to `deleteSelectionPromise`

* fmt

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-19 05:27:23 -04:00
8c1a95833d clean up sketch mode cmd (#6397) 2025-04-18 21:15:19 -04:00
4f1ba1be01 Fix error message whitelist to use updated message (#6404) 2025-04-18 23:27:34 +00:00
90acc00369 Kwargs migration: arc/arcTo (#6334) 2025-04-18 17:40:44 -05:00
e4fe8a4440 Fix CSG commands to be included in the artifact graph (#6391)
* Fix CSG commands to be included in the artifact graph

* Update output
2025-04-18 22:35:17 +00:00
fbc3251c3f Disable all macOS testing for now (#6395) 2025-04-18 21:37:33 +00:00
a0f3f0f50e Fix KCLError to have a real message (#6396)
* Fix KCLError to have a real message

* Remove unneeded error exception
2025-04-18 17:13:09 -04:00
dad0d5488f Support any installation path for rust toolchain (#6380) 2025-04-18 20:28:38 +00:00
77773fb052 ci: Add error to console exception (#6392)
* Add error to console exception

* Ignore in codespell

* Increase retry on snapshots

* Fixme's all around

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-18 15:51:13 -04:00
1240ca6f21 Revert "Update onboarding interactive numbers test to use editor fixture" (#6393)
Revert "Update onboarding interactive numbers test to use editor fixture (#6356)"

This reverts commit c77bb92da9.
2025-04-18 14:57:40 -04:00
ce3a6ad286 Revert "Remove all use of bold mono font" (#6394)
Revert "Remove all use of bold mono font (#6373)"

This reverts commit 03c4121ab7.
2025-04-18 14:57:10 -04:00
a20f420a55 Add fixmes to failing e2e tests (#6388)
* Add fixmes to bad snapshots tests

* max attempts to 5 on snapshots

* Skip revolve on windows

* Another one

* Add fixme to edit with ML snapshot test

* fmt

* Use absolute import, fix lint

* Disable another test

---------

Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-18 14:14:23 -04:00
03c4121ab7 Remove all use of bold mono font (#6373)
* Remove all use of bold mono font
A few mono font points are left, mostly for numbers which look better in
monospace.

* make React happy with `clipRule`
2025-04-18 14:11:20 -04:00
8c2c877817 Bump crossbeam-channel from 0.5.14 to 0.5.15 in /rust in the security group (#6354)
Bump crossbeam-channel in /rust in the security group

Bumps the security group in /rust with 1 update: [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam).


Updates `crossbeam-channel` from 0.5.14 to 0.5.15
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.14...crossbeam-channel-0.5.15)

---
updated-dependencies:
- dependency-name: crossbeam-channel
  dependency-version: 0.5.15
  dependency-type: indirect
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-18 14:10:54 -04:00
c77bb92da9 Update onboarding interactive numbers test to use editor fixture (#6356)
Trying to bring it down from the leaderboard of failed tests.

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-18 14:06:23 -04:00
bd4bad0020 allow sending async commands to engine (#6342)
* start of async

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

check at end if the async commands completed

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

run at the end of inner_run

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

set import as async

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>

add to the wasm side

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

updates

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

fmt

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

* fire

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

* flake

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

* fixup for awaiting on import

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>

* fix mock

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

* fix mock

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

* updates

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

* fixes

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

* add a test where we import then do a bunch of other stuff

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

* updates

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

* fixup to see

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

* fixups

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

* fix tests

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

* updates

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

* cross platform time

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

* fixes

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>

* another appearance tests

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

* new docs and tests

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

* updates

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

* dont loop so tight

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

* fixes

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-17 17:22:19 -07:00
0b9889e313 Double the timeout in sketch editing test (#6376) 2025-04-17 14:32:11 -04:00
f9fbaa2298 Add files via upload (#6227)
* Add files via upload

Adding parametric pc fan and bottle

* Update and rename globals.kcl to parameters.kcl

* Update fan-housing.kcl

* Update fan-housing.kcl

* Update fan.kcl

* Update motor.kcl

* Update parameters.kcl

* Update kcl-samples simulation test output

* Update main.kcl

avoiding fn imports

* Update kcl-samples simulation test output

* remove functions

* angledLine kwargs

* tangentalArc kwargs

* Update kcl-samples simulation test output

* Update housing middle

more tweaks because I just can't help myself

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: jgomez720 <114548659+jgomez720@users.noreply.github.com>
2025-04-17 17:46:56 +00:00
6f2d127c4f Assemblies: Set translate and rotate via point-and-click (#6167)
* WIP: Add point-and-click Import for geometry
Will eventually fix #6120
Right now the whole loop is there but the codemod doesn't work yet

* Better pathToNOde, log on non-working cm dispatch call

* Add workaround to updateModelingState not working

* Back to updateModelingState with a skip flag

* Better todo

* Change working from Import to Insert, cleanups

* Sister command in kclCommands to populate file options

* Improve path selector

* Unsure: move importAstMod to kclCommands onSubmit 😶

* Add e2e test

* Clean up for review

* Add native file menu entry and test

* No await yo lint said so

* WIP: UX improvements around foreign file imports
Fixes #6152

* WIP: Set translate and rotate via point-and-click on imports. Boilerplate code
Will eventually close #6020

* Full working loop of rotate and translate pipe mutation, including edits, only on module imports. VERY VERBOSE

* Add first e2e test for set transform. Bunch of caveats listed as TODOs

* @lrev-Dev's suggestion to remove a comment

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>

* Update to scene.settled(cmdBar)

* Add partNNN default name for alias

* Lint

* Lint

* Fix unit tests

* Add sad path insert test
Thanks @Irev-Dev for the suggestion

* Add step insert test

* Lint

* Add test for second foreign import thru file tree click

* WIP: Add point-and-click Load to copy files from outside the project into the project
Towards #6210

* Move Insert button to modeling toolbar, update menus and toolbars

* Add default value for local name alias

* Aligning tests

* Fix tests

* Add padding for filenames starting with a digit

* Lint

* Lint

* Update snapshots

* Merge branch 'main' into pierremtb/issue6210-Add-point-and-click-Load-to-copy-files-from-outside-the-project-into-the-project

* Add disabled transform subbutton

* Allow start of Transform flow from toolbar with selection

* Merge kcl-samples and local disk load into one 'Load external model' command

* Fix em tests

* Fix test

* Add test for file pick import, better input

* Fix non .kcl loading

* Lint

* Update snapshots

* Fix issue leading to test failure

* Fix clone test

* Add note

* Fix nested clone issue

* Clean up for review

* Add valueSummary for path

* Fix test after path change

* Clean up for review

* Support much wider range for transform

* Set display names

* Bug fixed itself moment...

* Add test for extrude tranform

* Oops missed a thing

* Clean up selection arg

* More tests incl for variable stuff

* Fix imports

* Add supportsTransform: true on all solids returning operations

* Fix edit flow on variables, add test

* Split transform command into translate and rotate

* Clean up and comment

* Clean up operations.ts

* Add comment

* Improve assemblies test

* Support more things

* Typo

* Fix test after unit change on import

* Last clean up for review

* Fix remaining test

---------

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
2025-04-17 15:44:31 +00:00
056a4d4a22 [FIX]: "Connecting to engine" overlay shows too often (#6350)
* Use the engineStreamState that's available right there silly

* fix lint

* Just look at playing/paused

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
2025-04-17 12:49:31 +00:00
bab79331cb #6367 Tangent snapping improvements (#6369)
* fix snapping line being culled

* make snap line more grayed out

* make snapping tolerance smaller
2025-04-17 08:26:05 -04:00
16bbc970ae fix sketch flash part 2 (#6366) 2025-04-17 08:15:54 -04:00
0f1cff316c add toast for selections we don't recognise (#6370)
* ad toast for selections we don't recognise

* remove log
2025-04-17 21:32:13 +10:00
938a2bae13 Fix to not duplicate arg labels on constrained sketches (#6337) 2025-04-17 07:16:55 +00:00
3324835b72 ci: Fix so that just commands regenerate ast output (#6338)
* Fix so that just commands regenerate ast output

* Update just command to include manifest

* Fix overwrite-sim-test kcl_samples to generate manifest

This is the command used in CI.
2025-04-17 06:03:58 +00:00
1628ea86b2 Remove pixel color checks (#6365) 2025-04-17 14:25:45 +10:00
be119248a6 put execution benchmarks behind flag (#6364)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-16 21:23:30 -07:00
ac75181f7f fix bug and remove flash in sketch mode (#6346)
* fix bug and remove flash

* add test

* fix tests

* fix tests
2025-04-17 10:10:27 +10:00
d9fe78171f parallelized modules from kcl (#6206)
* wip

* sketch a bit more; going to pull this out of tests next

* wip

* lock start things

* this was a bad idea

* Revert "this was a bad idea"

This reverts commit a2092e7ed6.

* prepare prelude before spawning

* error

* poop

* yike

* :(

* ok

* Reapply "this was a bad idea"

This reverts commit fafdf41093.

* chip away more

* man this is bad

* fix rebase add feature flag

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

* get rid of execution kind

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

* clippy

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

* logs

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

* updates

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

* no extra executes

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

* race w batch

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

* cluppy

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

* no printlns

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

* no printlns

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

* fix source ranges

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

* batch shit

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

* fixes

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

* updates

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

* fix

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

* fix some bugs

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

* fix error

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

* cut 1

* preserve mem

* re-ad deep_clone

the helper we were calling was pushing a new call, which was hanging
out. we can skip the middleman since we already have something properly
prepared, just without a stdlib in some cases.

* skip non-kcl

* clean up source range bug

* error message changed

the uuids also changed because the error is hit before execute even
starts.

* typo

* rensnapshot a few

* order things

* MAYBE REVERT LATER:

attempt at an ordering

* snapsnap

* Revert "snapsnap"

This reverts commit 7350b32c7d.

* Revert "MAYBE REVERT LATER:"

This reverts commit ab49f3e85f.

* ugh

* poop

* poop2

* lint

* tranche 1

* more

* more snaps

* snap

* more

* update

* MAYBE REVERT THIS

* cache multi-file

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

* addd tests

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

* set to false

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

* add test outputs

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

* clippy

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

* kcl-py-bindings uses carwheel

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

* update snapshots

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: Paul R. Tagliamonte <paul@zoo.dev>
Co-authored-by: Paul Tagliamonte <paultag@gmail.com>
2025-04-16 11:52:14 -07:00
5586646a60 Fix insta version in Cargo.toml to match lock file (#6348)
Cargo decided to downgrade `windows-sys` for some reason.
2025-04-16 17:50:39 +00:00
e955e783f4 KCL: Error when user sets a keyword arg multiple times (#6339)
Previously, KCL would silently ignore any duplicated keyword args, setting the parameter to one arbitrarily-chosen argument. Now this is instead a parse error. 

I've tested that
1. The error message makes sense
2. The error is on a reasonable part of the source code
3. The error doesn't prevent other kinds of parse errors being picked up later

Thanks for noticing this one Frank!
2025-04-16 11:18:45 -05:00
9162c4d723 Split out the contributor guide (#6347) 2025-04-16 15:48:36 +00:00
f345a07bcd Update helix e2e test to account for 90deg engine change (#6341)
The engine fixed the start angle for helices, but our e2e test has a
pixel check so it broke. I made the test change the `startAngle` by
`-90` rather than try to hunt around for a new working pixel value.
2025-04-16 00:09:58 +00:00
f5e3b4bbe7 Update helix snapshots (#6340)
Engine fixed a bug where helices were starting at the wrong position. Requires updating the snapshots.
2025-04-15 17:15:37 -05:00
941911ed30 docs: Fix syntax error and deprecated string planes in types.md (#6332) 2025-04-15 17:42:24 +00:00
599bd2d958 Switch to a 6-core profile for mac (#6323)
* Switch to a 6-core profile for mac

* Bump workers percentage to optimize for CPU count (#6329)

* Bump macOS workers percentage to optimize for CPU count

* Handle floor math

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
2025-04-15 13:07:16 -04:00
a847c7f608 Release KCL 62 (#6330) 2025-04-15 15:53:01 +00:00
1668 changed files with 6156095 additions and 314325 deletions

View File

@ -1,3 +1,3 @@
[codespell] [codespell]
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,.package-lock.json,**/package-lock.json,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo,./src/lib/machine-api.d.ts skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,./e2e/playwright/lib/console-error-whitelist.ts,.package-lock.json,**/package-lock.json,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo,./src/lib/machine-api.d.ts

View File

@ -19,6 +19,11 @@
"plugin:jsx-a11y/recommended", "plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended" "plugin:react-hooks/recommended"
], ],
"settings": {
"react": {
"version": "detect"
}
},
"rules": { "rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead. "no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error", "@typescript-eslint/no-array-constructor": "error",
@ -61,6 +66,7 @@
"jsx-a11y/click-events-have-key-events": "off", "jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off", "jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off", "jsx-a11y/no-noninteractive-element-interactions": "off",
"react/no-unknown-property": "error",
"no-restricted-globals": [ "no-restricted-globals": [
"error", "error",
{ {

View File

@ -26,8 +26,8 @@ max_retries=1
# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues # Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues
while [[ $retry -le $max_retries ]]; do while [[ $retry -le $max_retries ]]; do
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) status=$(jq -r '.status' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then if [[ "$status" == "failed" ]]; then
echo "retried=true" >>$GITHUB_OUTPUT echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry" echo "run playwright with last failed tests and retry $retry"
if [[ "$3" == *ubuntu* ]]; then if [[ "$3" == *ubuntu* ]]; then
@ -56,10 +56,11 @@ done
echo "retried=false" >>$GITHUB_OUTPUT echo "retried=false" >>$GITHUB_OUTPUT
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) status=$(jq -r '.status' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then if [[ "$status" == "failed" ]]; then
# If it still fails after 3 retries, then fail the job # If it still fails after retries, then fail the job
exit 1 exit 1
fi fi
fi fi
exit 0 exit 0

View File

@ -26,12 +26,8 @@ name: cargo bench
jobs: jobs:
cargo-bench: cargo-bench:
name: cargo bench name: cargo bench
runs-on: runs-on: ubuntu-latest
- runs-on=${{ github.run_id }}
- runner=32cpu-linux-x64
- extras=s3-cache
steps: steps:
- uses: runs-on/action@v1
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Use correct Rust toolchain - name: Use correct Rust toolchain
shell: bash shell: bash
@ -50,13 +46,12 @@ jobs:
- name: Build the benchmark target(s) - name: Build the benchmark target(s)
run: | run: |
cd rust cd rust
cargo codspeed build --measurement-mode walltime cargo codspeed build
- name: Run the benchmarks - name: Run the benchmarks
uses: CodSpeedHQ/action@v3 uses: CodSpeedHQ/action@v3
with: with:
working-directory: rust working-directory: rust
run: cargo codspeed run run: cargo codspeed run
token: ${{ secrets.CODSPEED_TOKEN }} token: ${{ secrets.CODSPEED_TOKEN }}
mode: walltime
env: env:
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN }} KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN }}

View File

@ -13,10 +13,14 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
name: cargo test name: cargo test
jobs: jobs:
cargotest: build-test-artifacts:
name: cargo test name: Build test artifacts
runs-on: ubuntu-latest-8-cores runs-on:
- runs-on=${{ github.run_id }}
- runner=8cpu-linux-x64
- extras=s3-cache
steps: steps:
- uses: runs-on/action@v1
- uses: actions/create-github-app-token@v1 - uses: actions/create-github-app-token@v1
id: app-token id: app-token
with: with:
@ -39,7 +43,6 @@ jobs:
env: env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }} GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }} OS_NAME: ${{ env.OS_NAME }}
- uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest - uses: taiki-e/install-action@nextest
- name: Install just - name: Install just
uses: taiki-e/install-action@just uses: taiki-e/install-action@just
@ -81,11 +84,10 @@ jobs:
run: | run: |
set -euo pipefail set -euo pipefail
cd rust cd rust
cargo nextest run --workspace --retries=2 --no-fail-fast --profile ci simulation_tests::kcl_samples 2>&1 | tee /tmp/github-actions.log cargo nextest run --workspace --features artifact-graph --retries=2 --no-fail-fast --profile ci simulation_tests::kcl_samples 2>&1 | tee /tmp/github-actions.log
env: env:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}} KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
RUST_BACKTRACE: full RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: Commit differences - name: Commit differences
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure' if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
shell: bash shell: bash
@ -118,23 +120,67 @@ jobs:
# Configure nextest when it's run by insta (via just). # Configure nextest when it's run by insta (via just).
NEXTEST_PROFILE: ci NEXTEST_PROFILE: ci
RUST_BACKTRACE: full RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000 - name: Build and archive tests
- name: cargo test run: |
if: steps.path-changes.outputs.outside-kcl-samples == 'true' cd rust
cargo nextest archive --workspace --features artifact-graph --archive-file nextest-archive.tar.zst
- name: Upload archive to workflow
uses: actions/upload-artifact@v4
with:
name: nextest-archive
path: rust/nextest-archive.tar.zst
run-test-artifacts:
name: cargo test (shard ${{ matrix.partitionIndex}})
runs-on:
- runs-on=${{ github.run_id }}
- runner=32cpu-linux-x64
- extras=s3-cache
needs: build-test-artifacts
strategy:
fail-fast: false
matrix:
partitionIndex: [1, 2, 3, 4, 5, 6]
partitionTotal: [6]
steps:
- uses: runs-on/action@v1
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- name: Start Vector
run: .github/ci-cd-scripts/start-vector-ubuntu.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- uses: taiki-e/install-action@nextest
- name: Download archive
uses: actions/download-artifact@v4
with:
name: nextest-archive
- name: Run tests
shell: bash shell: bash
run: |- run: |-
cp nextest-archive.tar.zst rust/nextest-archive.tar.zst
ls -lah
cd rust cd rust
cargo llvm-cov nextest --workspace --lcov --output-path lcov.info --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log cargo nextest run\
--retries=2 --no-fail-fast -P ci --archive-file nextest-archive.tar.zst \
--partition count:${{ matrix.partitionIndex}}/${{ matrix.partitionTotal }} \
2>&1 | tee /tmp/github-actions.log
env: env:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}} KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
RUST_MIN_STACK: 10485760000
- name: Upload to codecov.io
if: steps.path-changes.outputs.outside-kcl-samples == 'true'
uses: codecov/codecov-action@v5
with:
token: ${{secrets.CODECOV_TOKEN}}
fail_ci_if_error: true
flags: rust
verbose: true
files: lcov.info

View File

@ -3,7 +3,6 @@ on:
push: push:
branches: branches:
- main - main
- all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
pull_request: pull_request:
schedule: schedule:
- cron: 0 * * * * # hourly - cron: 0 * * * * # hourly
@ -226,8 +225,8 @@ jobs:
with: with:
shell: bash shell: bash
command: npm run test:snapshots command: npm run test:snapshots
timeout_minutes: 30 timeout_minutes: 5
max_attempts: 3 max_attempts: 5
env: env:
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }} snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
@ -278,28 +277,42 @@ jobs:
timeout-minutes: 60 timeout-minutes: 60
env: env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}:${{ matrix.shardIndex }}:${{ matrix.shardTotal }} name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} (shard ${{ matrix.shardIndex }})
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# TODO: enable namespace-profile-windows-latest once available # TODO: enable namespace-profile-windows-latest once available
os: include:
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64" - os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- namespace-profile-macos-8-cores shardIndex: 1
- windows-latest-8-cores shardTotal: 8
shardIndex: [1, 2, 3, 4] - os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardTotal: [4] shardIndex: 2
# Disable macos and windows tests on hourly e2e tests since we only care shardTotal: 8
# about server side changes. - os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
# Technique from https://github.com/joaomcteixeira/python-project-skeleton/pull/31/files shardIndex: 3
isScheduled: shardTotal: 8
- ${{ github.event_name == 'schedule' }} - os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
exclude: shardIndex: 4
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 5
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 6
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 7
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 8
shardTotal: 8
- os: namespace-profile-macos-8-cores - os: namespace-profile-macos-8-cores
isScheduled: true shardIndex: 1
shardTotal: 1
- os: windows-latest-8-cores - os: windows-latest-8-cores
isScheduled: true shardIndex: 1
# TODO: add ref here for main and latest release tag shardTotal: 1
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@ -1,45 +0,0 @@
name: update-e2e-branch
# This is used to sync the `all-e2e` branch with the `main` branch for the
# logic in the test utility `orRunWhenFullSuiteEnabled()` that allows all e2e
# tests to run on a particular branch to analyze failures metrics in Axiom.
on:
schedule:
- cron: '0 * * * *' # runs every hour
permissions:
contents: write
jobs:
update-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Sync with main
run: |
# Create the branch
git checkout all-e2e || git checkout -b all-e2e
# Reset to main
git fetch origin
git reset --hard origin/main
# Get a new SHA to prevent overwriting the commit status on main
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git commit --allow-empty --message="[all-e2e] $(git log --max-count=1 --pretty=%B)"
# Overwrite the branch
git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git
git push --force origin all-e2e

View File

@ -5,6 +5,6 @@ command = "vscode-eslint-language-server"
[[language]] [[language]]
name = "typescript" name = "typescript"
auto-format = true auto-format = true
formatter = { command = "node_modules/.bin/prettier", args = ["--parser", "typescript"] } formatter = { command = "./node_modules/@biomejs/biome/bin/biome", args = ["format", "--write", "--stdin-file-path=foo.ts"] }
language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ] # language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]

1
.husky/pre-commit Executable file
View File

@ -0,0 +1 @@
npm run fmt

View File

@ -1,4 +0,0 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run fmt-check

432
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,432 @@
# Contributor Guide
## Running a development build
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
On Windows, it's also recommended to [upgrade your PowerShell version](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5#winget), we're using 7.
Then in the repo run the following to install and use the node version specified in `.nvmrc`. You might need to specify your processor architecture with `--arch arm64` or `--arch x64` if it's not autodetected.
```
fnm install --corepack-enabled
fnm use
```
Install the NPM dependencies with:
```
npm install
```
This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. We have package scripts to run rustup, see `package.json` for reference:
```
# macOS/Linux
npm run install:rust
npm run install:wasm-pack:sh
# Windows
npm run install:rust:windows
npm run install:wasm-pack:cargo
```
Then to build the WASM layer, run:
```
# macOS/Linux
npm run build:wasm
# Windows
npm run build:wasm:windows
```
Or if you have the `gh` cli installed and want to download the latest main wasm bundle. Note that on Windows, you need to associate .ps1 files with PowerShell, which can be done via the right click menu, selecting `C:\Program Files\PowerShell\7\pwsh.exe`, and you can install tools like `gh` via `npm run install:tools:windows`.
```
# macOS/Linux
npm run fetch:wasm
# Windows
npm run fetch:wasm:windows
```
That will build the WASM binary and put in the `public` dir (though gitignored).
Finally, to run the web app only, run:
```
npm start
```
If you're not a Zoo employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development.local` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to `localhost:3000` again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again.
### Development environment variables
The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service.
### Developing in Chrome
Chrome is in the process of rolling out a new default which
[blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/).
If you're having trouble logging into the `modeling-app`, you may need to
enable third-party cookies. You can enable third-party cookies by clicking on
the eye with a slash through it in the URL bar, and clicking on "Enable
Third-Party Cookies".
## Desktop
To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then:
```
npm run tron:start
```
This will start the application and hot-reload on changes.
Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (Linux and Windows).
To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables).
## Checking out commits / Bisecting
Which commands from setup are one off vs. need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale:
```bash
npm install
npm run build:wasm
npm start # or npm run build:local && npm run serve for slower but more production-like build
```
## Before submitting a PR
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
- `npm run fmt`
- `npm run tsc`
- `npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Release a new version
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
https://github.com/KittyCAD/modeling-app/issues/new
#### 2. Push a new tag
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
```
VERSION=$(./scripts/semantic-release.sh)
git tag $VERSION
git push origin --tags
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
##### Updater-test builds
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
```
# Windows (PowerShell)
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
# macOS
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
# Linux
./Zoo Design Studio-{version}-{arch}-linux.AppImage
```
#### 4. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 5. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
## Fuzzing the parser
Make sure you install cargo fuzz:
```bash
$ cargo install cargo-fuzz
```
```bash
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
For more information on fuzzing you can check out
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
## Tests
### Playwright tests
You will need a `./e2e/playwright/playwright-secrets.env` file:
```bash
$ touch ./e2e/playwright/playwright-secrets.env
$ cat ./e2e/playwright/playwright-secrets.env
token=<dev.zoo.dev/account/api-tokens>
snapshottoken=<zoo.dev/account/api-tokens>
```
or use `export` to set the environment variables `token` and `snapshottoken`.
#### Snapshot tests (Google Chrome on Ubuntu only)
Only Ubunu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace.
```
npm run playwright -- install chrome
npm run test:snapshots
```
You may use `-- --update-snapshots` as needed.
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
```
npm run playwright -- install chromium
npm run test:playwright:electron:local
```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
With the extension you can set a breakpoint after `waitForDefaultPlanesVisibilityChange` in order to skip app loading, then the vscode debugger's "step over" is much better for being able to stay at the right level of abstraction as you debug the code.
If you want to limit to a single browser use `--project="webkit"` or `firefox`, `Google Chrome`
Or comment out browsers in `playwright.config.ts`.
note chromium has encoder compat issues which is why were testing against the branded 'Google Chrome'
You may consider using the VSCode extension, it's useful for running individual threads, but some some reason the "record a test" is locked to chromium with we can't use. A work around is to us the CI `npm run playwright codegen -b wk --load-storage ./store localhost:3000`
<details>
<summary>
Where `./store` should look like this
</summary>
```JSON
{
"cookies": [],
"origins": [
{
"origin": "http://localhost:3000",
"localStorage": [
{
"name": "store",
"value": "{\"state\":{\"openPanes\":[\"code\"]},\"version\":0}"
},
{
"name": "persistCode",
"value": ""
},
{
"name": "TOKEN_PERSIST_KEY",
"value": "your-token"
}
]
}
]
}
```
</details>
However because much of our tests involve clicking in the stream at specific locations, it's code-gen looks `await page.locator('video').click();` when really we need to use a pixel coord, so I think it's of limited use.
### Unit and component tests
If you already haven't, run the following:
```
npm
npm run build:wasm
npm start
```
and finally:
```
npm run test:unit
```
For individual testing:
```
npm run test abstractSyntaxTree -t "unexpected closed curly brace" --silent=false
```
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro) tests, in interactive mode by default.
### Rust tests
**Dependencies**
- `KITTYCAD_API_TOKEN`
- `cargo-nextest`
- `just`
#### Setting KITTYCAD_API_TOKEN
Use the production zoo.dev token, set this environment variable before running the tests
#### Installing cargonextest
```
cd rust
cargo search cargo-nextest
cargo install cargo-nextest
```
#### just
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
#### Running the tests
```bash
# With just
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
# Make sure you installed cargo-nextest
# Make sure you installed just
cd rust
just test
```
```bash
# Without just
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
# Make sure you installed cargo-nextest
cd rust
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
```
Where `XXX` is an API token from the production engine (NOT the dev environment).
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
```
cd rust
KITTYCAD_API_TOKEN=XXX cargo run nextest
```
### Mapping CI CD jobs to local commands
When you see the CI CD fail on jobs you may wonder three things
- Do I have a bug in my code?
- Is the test flaky?
- Is there a bug in `main`?
To answer these questions the following commands will give you confidence to locate the issue.
#### Static Analysis
Part of the CI CD pipeline performs static analysis on the code. Use the following commands to mimic the CI CD jobs.
The following set of commands should get us closer to one and done commands to instantly retest issues.
```
npm run test-setup
```
> Gotcha, are packages up to date and is the wasm built?
```
npm run tsc
npm run fmt:check
npm run lint
npm run test:unit:local
```
> Gotcha: Our unit tests have integration tests in them. You need to run a localhost server to run the unit tests.
#### E2E Tests
**Playwright Electron**
These E2E tests run in electron. There are tests that are skipped if they are ran in a windows, linux, or macos environment. We can use playwright tags to implement test skipping.
```
npm run test:playwright:electron:local
npm run test:playwright:electron:windows:local
npm run test:playwright:electron:macos:local
npm run test:playwright:electron:ubuntu:local
```
> Why does it say local? The CI CD commands that run in the pipeline cannot be ran locally. A single command will not properly setup the testing environment locally.
#### Some notes on CI
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
How to interpret failing playwright tests?
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
We run on ubuntu and macos, because safari doesn't work on linux because of the dreaded "no RTCPeerConnection variable" error. But linux runs first and then macos for the same reason that we limit the number of parallel tests to 1 because we limit stream connections per user, so tests would start failing we if let them run together.
If something fails on CI you can download the artifact, unzip it and then open `playwright-report/data/<UUID>.zip` with https://trace.playwright.dev/ to see what happened.
#### Getting started writing a playwright test in our app
Besides following the instructions above and using the playwright docs, our app is weird because of the whole stream thing, which means our testing is weird. Because we've just figured out this stuff and therefore docs might go stale quick here's a 15min vid/tutorial
https://github.com/KittyCAD/modeling-app/assets/29681384/6f5e8e85-1003-4fd9-be7f-f36ce833942d
<details>
<summary>
PS: for the debug panel, the following JSON is useful for snapping the camera
</summary>
```JSON
{"type":"modeling_cmd_req","cmd_id":"054e5472-e5e9-4071-92d7-1ce3bac61956","cmd":{"type":"default_camera_look_at","center":{"x":15,"y":0,"z":0},"up":{"x":0,"y":0,"z":1},"vantage":{"x":30,"y":30,"z":30}}}
```
</details>
### Logging
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
To enable memory metrics, build with `--features dhat-heap`.

View File

@ -15,8 +15,8 @@ ifdef WINDOWS
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
else else
CARGO ?= ~/.cargo/bin/cargo CARGO ?= $(shell which cargo || echo ~/.cargo/bin/cargo)
WASM_PACK ?= ~/.cargo/bin/wasm-pack WASM_PACK ?= $(shell which wasm-pack || echo ~/.cargo/bin/wasm-pack)
endif endif
.PHONY: install .PHONY: install

447
README.md
View File

@ -1,8 +1,8 @@
![Zoo Design Studio](/public/zma-logomark-outlined.png) ![Zoo Design Studio](/public/zma-logomark-outlined.png)
## Zoo Design Studio # Zoo Design Studio
download at [zoo.dev/modeling-app/download](https://zoo.dev/modeling-app/download) [zoo.dev/modeling-app](https://zoo.dev/modeling-app)
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev). A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
@ -23,7 +23,7 @@ Design Studio is a _hybrid_ user interface for CAD modeling. You can point-and-c
The 3D view in Design Studio is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine. The 3D view in Design Studio is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine.
## Tools ## Technology
- UI - UI
- [React](https://react.dev/) - [React](https://react.dev/)
@ -38,445 +38,16 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
- Modeling - Modeling
- [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts) - [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts)
[Original demo video](https://drive.google.com/file/d/183_wjqGdzZ8EEZXSqZ3eDcJocYPCyOdC/view?pli=1) ## Get Started
[Original demo slides](https://github.com/user-attachments/files/19010536/demo.pdf) We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
## Get started If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
We recommend downloading the latest application binary from [our Releases page](https://github.com/KittyCAD/modeling-app/releases). If you don't see your platform or architecture supported there, please file an issue. ## Developing
## Running a development build Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
On Windows, it's also recommended to [upgrade your PowerShell version](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5#winget), we're using 7.
Then in the repo run the following to install and use the node version specified in `.nvmrc`. You might need to specify your processor architecture with `--arch arm64` or `--arch x64` if it's not autodetected.
```
fnm install --corepack-enabled
fnm use
```
Install the NPM dependencies with:
```
npm install
```
This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. We have package scripts to run rustup, see `package.json` for reference:
```
# macOS/Linux
npm run install:rust
npm run install:wasm-pack:sh
# Windows
npm run install:rust:windows
npm run install:wasm-pack:cargo
```
Then to build the WASM layer, run:
```
# macOS/Linux
npm run build:wasm
# Windows
npm run build:wasm:windows
```
Or if you have the `gh` cli installed and want to download the latest main wasm bundle. Note that on Windows, you need to associate .ps1 files with PowerShell, which can be done via the right click menu, selecting `C:\Program Files\PowerShell\7\pwsh.exe`, and you can install tools like `gh` via `npm run install:tools:windows`.
```
# macOS/Linux
npm run fetch:wasm
# Windows
npm run fetch:wasm:windows
```
That will build the WASM binary and put in the `public` dir (though gitignored).
Finally, to run the web app only, run:
```
npm start
```
If you're not a Zoo employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development.local` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to `localhost:3000` again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again.
### Development environment variables
The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service.
### Developing in Chrome
Chrome is in the process of rolling out a new default which
[blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/).
If you're having trouble logging into the `modeling-app`, you may need to
enable third-party cookies. You can enable third-party cookies by clicking on
the eye with a slash through it in the URL bar, and clicking on "Enable
Third-Party Cookies".
## Desktop
To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then:
```
npm run tron:start
```
This will start the application and hot-reload on changes.
Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (Linux and Windows).
To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables).
## Checking out commits / Bisecting
Which commands from setup are one off vs. need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale:
```bash
npm install
npm run build:wasm
npm start # or npm run build:local && npm run serve for slower but more production-like build
```
## Before submitting a PR
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
- `npm run fmt`
- `npm run tsc`
- `npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Release a new version
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
https://github.com/KittyCAD/modeling-app/issues/new
#### 2. Push a new tag
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
```
VERSION=$(./scripts/semantic-release.sh)
git tag $VERSION
git push origin --tags
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
##### Updater-test builds
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
```
# Windows (PowerShell)
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
# macOS
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
# Linux
./Zoo Design Studio-{version}-{arch}-linux.AppImage
```
#### 4. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 5. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
## Fuzzing the parser
Make sure you install cargo fuzz:
```bash
$ cargo install cargo-fuzz
```
```bash
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
For more information on fuzzing you can check out
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
## Tests
### Playwright tests
You will need a `./e2e/playwright/playwright-secrets.env` file:
```bash
$ touch ./e2e/playwright/playwright-secrets.env
$ cat ./e2e/playwright/playwright-secrets.env
token=<dev.zoo.dev/account/api-tokens>
snapshottoken=<zoo.dev/account/api-tokens>
```
or use `export` to set the environment variables `token` and `snapshottoken`.
#### Snapshot tests (Google Chrome on Ubuntu only)
Only Ubunu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace.
```
npm run playwright -- install chrome
npm run test:snapshots
```
You may use `-- --update-snapshots` as needed.
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
```
npm run playwright -- install chromium
npm run test:playwright:electron:local
```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
With the extension you can set a breakpoint after `waitForDefaultPlanesVisibilityChange` in order to skip app loading, then the vscode debugger's "step over" is much better for being able to stay at the right level of abstraction as you debug the code.
If you want to limit to a single browser use `--project="webkit"` or `firefox`, `Google Chrome`
Or comment out browsers in `playwright.config.ts`.
note chromium has encoder compat issues which is why were testing against the branded 'Google Chrome'
You may consider using the VSCode extension, it's useful for running individual threads, but some some reason the "record a test" is locked to chromium with we can't use. A work around is to us the CI `npm run playwright codegen -b wk --load-storage ./store localhost:3000`
<details>
<summary>
Where `./store` should look like this
</summary>
```JSON
{
"cookies": [],
"origins": [
{
"origin": "http://localhost:3000",
"localStorage": [
{
"name": "store",
"value": "{\"state\":{\"openPanes\":[\"code\"]},\"version\":0}"
},
{
"name": "persistCode",
"value": ""
},
{
"name": "TOKEN_PERSIST_KEY",
"value": "your-token"
}
]
}
]
}
```
</details>
However because much of our tests involve clicking in the stream at specific locations, it's code-gen looks `await page.locator('video').click();` when really we need to use a pixel coord, so I think it's of limited use.
### Unit and component tests
If you already haven't, run the following:
```
npm
npm run build:wasm
npm start
```
and finally:
```
npm run test:unit
```
For individual testing:
```
npm run test abstractSyntaxTree -t "unexpected closed curly brace" --silent=false
```
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro) tests, in interactive mode by default.
### Rust tests
**Dependencies**
- `KITTYCAD_API_TOKEN`
- `cargo-nextest`
- `just`
#### Setting KITTYCAD_API_TOKEN
Use the production zoo.dev token, set this environment variable before running the tests
#### Installing cargonextest
```
cd rust
cargo search cargo-nextest
cargo install cargo-nextest
```
#### just
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
#### Running the tests
```bash
# With just
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
# Make sure you installed cargo-nextest
# Make sure you installed just
cd rust
just test
```
```bash
# Without just
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
# Make sure you installed cargo-nextest
cd rust
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
```
Where `XXX` is an API token from the production engine (NOT the dev environment).
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
```
cd rust
KITTYCAD_API_TOKEN=XXX cargo run nextest
```
### Mapping CI CD jobs to local commands
When you see the CI CD fail on jobs you may wonder three things
- Do I have a bug in my code?
- Is the test flaky?
- Is there a bug in `main`?
To answer these questions the following commands will give you confidence to locate the issue.
#### Static Analysis
Part of the CI CD pipeline performs static analysis on the code. Use the following commands to mimic the CI CD jobs.
The following set of commands should get us closer to one and done commands to instantly retest issues.
```
npm run test-setup
```
> Gotcha, are packages up to date and is the wasm built?
```
npm run tsc
npm run fmt:check
npm run lint
npm run test:unit:local
```
> Gotcha: Our unit tests have integration tests in them. You need to run a localhost server to run the unit tests.
#### E2E Tests
**Playwright Electron**
These E2E tests run in electron. There are tests that are skipped if they are ran in a windows, linux, or macos environment. We can use playwright tags to implement test skipping.
```
npm run test:playwright:electron:local
npm run test:playwright:electron:windows:local
npm run test:playwright:electron:macos:local
npm run test:playwright:electron:ubuntu:local
```
> Why does it say local? The CI CD commands that run in the pipeline cannot be ran locally. A single command will not properly setup the testing environment locally.
#### Some notes on CI
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
How to interpret failing playwright tests?
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
We run on ubuntu and macos, because safari doesn't work on linux because of the dreaded "no RTCPeerConnection variable" error. But linux runs first and then macos for the same reason that we limit the number of parallel tests to 1 because we limit stream connections per user, so tests would start failing we if let them run together.
If something fails on CI you can download the artifact, unzip it and then open `playwright-report/data/<UUID>.zip` with https://trace.playwright.dev/ to see what happened.
#### Getting started writing a playwright test in our app
Besides following the instructions above and using the playwright docs, our app is weird because of the whole stream thing, which means our testing is weird. Because we've just figured out this stuff and therefore docs might go stale quick here's a 15min vid/tutorial
https://github.com/KittyCAD/modeling-app/assets/29681384/6f5e8e85-1003-4fd9-be7f-f36ce833942d
<details>
<summary>
PS: for the debug panel, the following JSON is useful for snapping the camera
</summary>
```JSON
{"type":"modeling_cmd_req","cmd_id":"054e5472-e5e9-4071-92d7-1ce3bac61956","cmd":{"type":"default_camera_look_at","center":{"x":15,"y":0,"z":0},"up":{"x":0,"y":0,"z":1},"vantage":{"x":30,"y":30,"z":30}}}
```
</details>
## KCL ## KCL
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib). To contribute to the KittyCAD Language, see the [README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib) for KCL.
### Logging
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
To enable memory metrics, build with `--features dhat-heap`.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -44,7 +44,7 @@ angledLine(
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> yLine(endAbsolute = 15) |> yLine(endAbsolute = 15)
|> angledLine(angle = 30, length = 15) |> angledLine(angle = 30, length = 15)
|> line(end = [8, -10]) |> line(end = [8, -10])

View File

@ -38,7 +38,7 @@ angledLineThatIntersects(
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(endAbsolute = [5, 10]) |> line(endAbsolute = [5, 10])
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect) |> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|> line(endAbsolute = [0, 20]) |> line(endAbsolute = [0, 20])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

40
docs/kcl/assertIs.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,8 +10,10 @@ Draw a smooth, continuous, curved line segment from the current origin to the de
```js ```js
bezierCurve( bezierCurve(
data: BezierData,
sketch: Sketch, sketch: Sketch,
control1: [number],
control2: [number],
end: [number],
tag?: TagDeclarator, tag?: TagDeclarator,
): Sketch ): Sketch
``` ```
@ -21,9 +23,11 @@ bezierCurve(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `data` | [`BezierData`](/docs/kcl/types/BezierData) | Data to draw a bezier curve. | Yes | | `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes | | `control1` | [`[number]`](/docs/kcl/types/number) | First control point for the cubic | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No | | `control2` | [`[number]`](/docs/kcl/types/number) | Second control point for the cubic | Yes |
| `end` | [`[number]`](/docs/kcl/types/number) | How far away (along the X and Y axes) should this line go? | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns ### Returns
@ -34,13 +38,9 @@ bezierCurve(
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [0, 10]) |> line(end = [0, 10])
|> bezierCurve({ |> bezierCurve(control1 = [5, 0], control2 = [5, 10], end = [10, 10])
to = [10, 10],
control1 = [5, 0],
control2 = [5, 10]
}, %)
|> line(endAbsolute = [10, 0]) |> line(endAbsolute = [10, 0])
|> close() |> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

258
docs/kcl/clone.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,7 @@ close(
```js ```js
startSketchOn(XZ) startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 10]) |> line(end = [10, 10])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> close() |> close()
@ -43,7 +43,7 @@ startSketchOn(XZ)
```js ```js
exampleSketch = startSketchOn(-XZ) exampleSketch = startSketchOn(-XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> line(end = [0, 10]) |> line(end = [0, 10])
|> close() |> close()

View File

@ -16,7 +16,7 @@ std::math::E: number = 2.71828182845904523536028747135266250_
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> angledLine( |> angledLine(
angle = 30, angle = 30,
length = 2 * E ^ 2, length = 2 * E ^ 2,

View File

@ -9,7 +9,7 @@ The value of `pi`, Archimedes constant (π).
```js ```js
std::math::PI: number = 3.14159265358979323846264338327950288_ std::math::PI: number(_?) = 3.14159265358979323846264338327950288_?
``` ```
### Examples ### Examples
@ -18,7 +18,7 @@ std::math::PI: number = 3.14159265358979323846264338327950288_
circumference = 70 circumference = 70
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = circumference / (2 * PI)) |> circle(center = [0, 0], radius = (circumference / (2 * PI)): number(mm))
example = extrude(exampleSketch, length = 5) example = extrude(exampleSketch, length = 5)
``` ```

View File

@ -16,7 +16,7 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> angledLine( |> angledLine(
angle = 50, angle = 50,
length = 10 * TAU, length = 10 * TAU,

View File

@ -29,7 +29,7 @@ e(): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> angledLine(angle = 30, length = 2 * e() ^ 2) |> angledLine(angle = 30, length = 2 * e() ^ 2)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()

View File

@ -40,20 +40,12 @@ extrude(
```js ```js
example = startSketchOn(XZ) example = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> arc({ |> arc(angleStart = 120, angleEnd = 0, radius = 5)
angleStart = 120,
angleEnd = 0,
radius = 5
}, %)
|> line(end = [5, 0]) |> line(end = [5, 0])
|> line(end = [0, 10]) |> line(end = [0, 10])
|> bezierCurve({ |> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
control1 = [-10, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-5, -2]) |> line(end = [-5, -2])
|> close() |> close()
|> extrude(length = 10) |> extrude(length = 10)
@ -63,19 +55,11 @@ example = startSketchOn(XZ)
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([-10, 0], %) |> startProfile(at = [-10, 0])
|> arc({ |> arc(angleStart = 120, angleEnd = -60, radius = 5)
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> line(end = [10, 0]) |> line(end = [10, 0])
|> line(end = [5, 0]) |> line(end = [5, 0])
|> bezierCurve({ |> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-4, 10]) |> line(end = [-4, 10])
|> line(end = [-5, -2]) |> line(end = [-5, -2])
|> close() |> close()
@ -87,19 +71,11 @@ example = extrude(exampleSketch, length = 10)
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([-10, 0], %) |> startProfile(at = [-10, 0])
|> arc({ |> arc(angleStart = 120, angleEnd = -60, radius = 5)
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> line(end = [10, 0]) |> line(end = [10, 0])
|> line(end = [5, 0]) |> line(end = [5, 0])
|> bezierCurve({ |> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-4, 10]) |> line(end = [-4, 10])
|> line(end = [-5, -2]) |> line(end = [-5, -2])
|> close() |> close()
@ -111,19 +87,11 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([-10, 0], %) |> startProfile(at = [-10, 0])
|> arc({ |> arc(angleStart = 120, angleEnd = -60, radius = 5)
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> line(end = [10, 0]) |> line(end = [10, 0])
|> line(end = [5, 0]) |> line(end = [5, 0])
|> bezierCurve({ |> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-4, 10]) |> line(end = [-4, 10])
|> line(end = [-5, -2]) |> line(end = [-5, -2])
|> close() |> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from centimeters to the current default unit."
layout: manual layout: manual
--- ---
**WARNING:** This function is deprecated.
Converts a number from centimeters to the current default unit. Converts a number from centimeters to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters. No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`. For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from feet to the current default unit."
layout: manual layout: manual
--- ---
**WARNING:** This function is deprecated.
Converts a number from feet to the current default unit. Converts a number from feet to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in feet. No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`. For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from inches to the current default unit."
layout: manual layout: manual
--- ---
**WARNING:** This function is deprecated.
Converts a number from inches to the current default unit. Converts a number from inches to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in inches. No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`. For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from meters to the current default unit."
layout: manual layout: manual
--- ---
**WARNING:** This function is deprecated.
Converts a number from meters to the current default unit. Converts a number from meters to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in meters. No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`. For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from mm to the current default unit."
layout: manual layout: manual
--- ---
**WARNING:** This function is deprecated.
Converts a number from mm to the current default unit. Converts a number from mm to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters. No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`. For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from yards to the current default unit."
layout: manual layout: manual
--- ---
**WARNING:** This function is deprecated.
Converts a number from yards to the current default unit. Converts a number from yards to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in yards. No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`. For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`.

View File

@ -32,7 +32,7 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
scale = 20 scale = 20
part001 = startSketchOn(XY) part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [0, scale]) |> line(end = [0, scale])
|> line(end = [scale, 0]) |> line(end = [scale, 0])
|> line(end = [0, -scale]) |> line(end = [0, -scale])

View File

@ -9,7 +9,7 @@ Get the next adjacent edge to the edge given.
```js ```js
getNextAdjacentEdge(tag: TagIdentifier): Uuid getNextAdjacentEdge(edge: TagIdentifier): Uuid
``` ```
@ -17,7 +17,7 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes | | `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the next adjacent edge of. | Yes |
### Returns ### Returns
@ -28,7 +28,7 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> angledLine(angle = 60, length = 10) |> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10) |> angledLine(angle = 120, length = 10)

View File

@ -9,7 +9,7 @@ Get the opposite edge to the edge given.
```js ```js
getOppositeEdge(tag: TagIdentifier): Uuid getOppositeEdge(edge: TagIdentifier): Uuid
``` ```
@ -17,7 +17,7 @@ getOppositeEdge(tag: TagIdentifier): Uuid
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes | | `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the opposite edge of. | Yes |
### Returns ### Returns
@ -28,7 +28,7 @@ getOppositeEdge(tag: TagIdentifier): Uuid
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> angledLine(angle = 60, length = 10) |> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10) |> angledLine(angle = 120, length = 10)

View File

@ -9,7 +9,7 @@ Get the previous adjacent edge to the edge given.
```js ```js
getPreviousAdjacentEdge(tag: TagIdentifier): Uuid getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
``` ```
@ -17,7 +17,7 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes | | `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the previous adjacent edge of. | Yes |
### Returns ### Returns
@ -28,7 +28,7 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> angledLine(angle = 60, length = 10) |> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10) |> angledLine(angle = 120, length = 10)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,63 +22,30 @@ layout: manual
* [`string`](kcl/types/string) * [`string`](kcl/types/string)
* [`tag`](kcl/types/tag) * [`tag`](kcl/types/tag)
* **std** * **std**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`END`](kcl/consts/std-END) * [`END`](kcl/consts/std-END)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`START`](kcl/consts/std-START) * [`START`](kcl/consts/std-START)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* [`X`](kcl/consts/std-X) * [`X`](kcl/consts/std-X)
* [`XY`](kcl/consts/std-XY) * [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ) * [`XZ`](kcl/consts/std-XZ)
* [`Y`](kcl/consts/std-Y) * [`Y`](kcl/consts/std-Y)
* [`YZ`](kcl/consts/std-YZ) * [`YZ`](kcl/consts/std-YZ)
* [`Z`](kcl/consts/std-Z) * [`Z`](kcl/consts/std-Z)
* [`abs`](kcl/abs)
* [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine) * [`angledLine`](kcl/angledLine)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects) * [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`appearance`](kcl/appearance) * [`appearance`](kcl/appearance)
* [`arc`](kcl/arc) * [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo)
* [`asin`](kcl/asin)
* [`assert`](kcl/assert) * [`assert`](kcl/assert)
* [`assertEqual`](kcl/assertEqual) * [`assertIs`](kcl/assertIs)
* [`assertGreaterThan`](kcl/assertGreaterThan)
* [`assertGreaterThanOrEq`](kcl/assertGreaterThanOrEq)
* [`assertLessThan`](kcl/assertLessThan)
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
* [`atan`](kcl/atan)
* [`atan2`](kcl/atan2)
* [`bezierCurve`](kcl/bezierCurve) * [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer)
* [`circleThreePoint`](kcl/circleThreePoint) * [`circleThreePoint`](kcl/circleThreePoint)
* [`clone`](kcl/clone)
* [`close`](kcl/close) * [`close`](kcl/close)
* [`extrude`](kcl/extrude) * [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`fromCm`](kcl/fromCm)
* [`fromFt`](kcl/fromFt)
* [`fromInches`](kcl/fromInches)
* [`fromM`](kcl/fromM)
* [`fromMm`](kcl/fromMm)
* [`fromYd`](kcl/fromYd)
* [`getCommonEdge`](kcl/getCommonEdge) * [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge) * [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge) * [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge) * [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/std-helix) * [`helix`](kcl/std-helix)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`intersect`](kcl/intersect) * [`intersect`](kcl/intersect)
* [`involuteCircular`](kcl/involuteCircular) * [`involuteCircular`](kcl/involuteCircular)
* [`lastSegX`](kcl/lastSegX) * [`lastSegX`](kcl/lastSegX)
@ -87,15 +54,9 @@ layout: manual
* [`legAngY`](kcl/legAngY) * [`legAngY`](kcl/legAngY)
* [`legLen`](kcl/legLen) * [`legLen`](kcl/legLen)
* [`line`](kcl/line) * [`line`](kcl/line)
* [`ln`](kcl/ln)
* [`loft`](kcl/loft) * [`loft`](kcl/loft)
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`map`](kcl/map) * [`map`](kcl/map)
* [`max`](kcl/max) * [`offsetPlane`](kcl/std-offsetPlane)
* [`min`](kcl/min)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d) * [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d) * [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d) * [`patternLinear2d`](kcl/patternLinear2d)
@ -104,16 +65,13 @@ layout: manual
* [`patternTransform2d`](kcl/patternTransform2d) * [`patternTransform2d`](kcl/patternTransform2d)
* [`polygon`](kcl/polygon) * [`polygon`](kcl/polygon)
* [`pop`](kcl/pop) * [`pop`](kcl/pop)
* [`pow`](kcl/pow)
* [`profileStart`](kcl/profileStart) * [`profileStart`](kcl/profileStart)
* [`profileStartX`](kcl/profileStartX) * [`profileStartX`](kcl/profileStartX)
* [`profileStartY`](kcl/profileStartY) * [`profileStartY`](kcl/profileStartY)
* [`push`](kcl/push) * [`push`](kcl/push)
* [`reduce`](kcl/reduce) * [`reduce`](kcl/reduce)
* [`rem`](kcl/rem)
* [`revolve`](kcl/std-revolve) * [`revolve`](kcl/std-revolve)
* [`rotate`](kcl/rotate) * [`rotate`](kcl/rotate)
* [`round`](kcl/round)
* [`scale`](kcl/scale) * [`scale`](kcl/scale)
* [`segAng`](kcl/segAng) * [`segAng`](kcl/segAng)
* [`segEnd`](kcl/segEnd) * [`segEnd`](kcl/segEnd)
@ -123,33 +81,72 @@ layout: manual
* [`segStart`](kcl/segStart) * [`segStart`](kcl/segStart)
* [`segStartX`](kcl/segStartX) * [`segStartX`](kcl/segStartX)
* [`segStartY`](kcl/segStartY) * [`segStartY`](kcl/segStartY)
* [`shell`](kcl/shell) * [`startProfile`](kcl/startProfile)
* [`sqrt`](kcl/sqrt)
* [`startProfileAt`](kcl/startProfileAt)
* [`startSketchOn`](kcl/startSketchOn) * [`startSketchOn`](kcl/startSketchOn)
* [`subtract`](kcl/subtract) * [`subtract`](kcl/subtract)
* [`subtract2d`](kcl/subtract2d)
* [`sweep`](kcl/sweep) * [`sweep`](kcl/sweep)
* [`tangentToEnd`](kcl/tangentToEnd) * [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc) * [`tangentialArc`](kcl/tangentialArc)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`translate`](kcl/translate) * [`translate`](kcl/translate)
* [`union`](kcl/union) * [`union`](kcl/union)
* [`xLine`](kcl/xLine) * [`xLine`](kcl/xLine)
* [`yLine`](kcl/yLine) * [`yLine`](kcl/yLine)
* **std::math** * **std::math**
* [`E`](kcl/consts/std-math-E) * [`math::E`](kcl/consts/std-math-E)
* [`PI`](kcl/consts/std-math-PI) * [`math::PI`](kcl/consts/std-math-PI)
* [`TAU`](kcl/consts/std-math-TAU) * [`math::TAU`](kcl/consts/std-math-TAU)
* [`cos`](kcl/std-math-cos) * [`math::abs`](kcl/std-math-abs)
* [`polar`](kcl/std-math-polar) * [`math::acos`](kcl/std-math-acos)
* [`sin`](kcl/std-math-sin) * [`math::asin`](kcl/std-math-asin)
* [`tan`](kcl/std-math-tan) * [`math::atan`](kcl/std-math-atan)
* [`math::atan2`](kcl/std-math-atan2)
* [`math::ceil`](kcl/std-math-ceil)
* [`math::cos`](kcl/std-math-cos)
* [`math::floor`](kcl/std-math-floor)
* [`math::ln`](kcl/std-math-ln)
* [`math::log`](kcl/std-math-log)
* [`math::log10`](kcl/std-math-log10)
* [`math::log2`](kcl/std-math-log2)
* [`math::max`](kcl/std-math-max)
* [`math::min`](kcl/std-math-min)
* [`math::polar`](kcl/std-math-polar)
* [`math::pow`](kcl/std-math-pow)
* [`math::rem`](kcl/std-math-rem)
* [`math::round`](kcl/std-math-round)
* [`math::sin`](kcl/std-math-sin)
* [`math::sqrt`](kcl/std-math-sqrt)
* [`math::tan`](kcl/std-math-tan)
* **std::sketch** * **std::sketch**
* [`circle`](kcl/std-sketch-circle) * [`circle`](kcl/std-sketch-circle)
* [`mirror2d`](kcl/std-sketch-mirror2d) * [`mirror2d`](kcl/std-sketch-mirror2d)
* **std::solid**
* [`chamfer`](kcl/std-solid-chamfer)
* [`fillet`](kcl/std-solid-fillet)
* [`hollow`](kcl/std-solid-hollow)
* [`shell`](kcl/std-solid-shell)
* **std::turns** * **std::turns**
* [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN) * [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN)
* [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN) * [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN)
* [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN) * [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN)
* [`turns::ZERO`](kcl/consts/std-turns-ZERO) * [`turns::ZERO`](kcl/consts/std-turns-ZERO)
* **std::types**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* **std::units**
* [`units::toCentimeters`](kcl/std-units-toCentimeters)
* [`units::toDegrees`](kcl/std-units-toDegrees)
* [`units::toFeet`](kcl/std-units-toFeet)
* [`units::toInches`](kcl/std-units-toInches)
* [`units::toMeters`](kcl/std-units-toMeters)
* [`units::toMillimeters`](kcl/std-units-toMillimeters)
* [`units::toRadians`](kcl/std-units-toRadians)
* [`units::toYards`](kcl/std-units-toYards)

View File

@ -34,7 +34,7 @@ int(num: number): number
```js ```js
n = int(ceil(5 / 2)) n = int(ceil(5 / 2))
assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3") assert(n, isEqualTo = 3, error = "5/2 = 2.5, rounded up makes 3")
// Draw n cylinders. // Draw n cylinders.
startSketchOn(XZ) startSketchOn(XZ)
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)

View File

@ -36,7 +36,7 @@ intersect(
fn cube(center, size) { fn cube(center, size) {
return startSketchOn(XY) return startSketchOn(XY)
|> startProfileAt([center[0] - size, center[1] - size], %) |> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size]) |> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size]) |> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size]) |> line(endAbsolute = [center[0] - size, center[1] + size])
@ -61,7 +61,7 @@ intersectedPart = intersect([part001, part002])
fn cube(center, size) { fn cube(center, size) {
return startSketchOn(XY) return startSketchOn(XY)
|> startProfileAt([center[0] - size, center[1] - size], %) |> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size]) |> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size]) |> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size]) |> line(endAbsolute = [center[0] - size, center[1] + size])

View File

@ -42,7 +42,7 @@ involuteCircular(
a = 10 a = 10
b = 14 b = 14
startSketchOn(XZ) startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> involuteCircular(startRadius = a, endRadius = b, angle = 60) |> involuteCircular(startRadius = a, endRadius = b, angle = 60)
|> involuteCircular( |> involuteCircular(
startRadius = a, startRadius = a,

View File

@ -21,4 +21,6 @@ once fixed in engine will just start working here with no language changes.
- **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple - **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple
chamfer cases work currently. chamfer cases work currently.
- **Appearance**: Changing the appearance on a loft does not work. - **Appearance**: Changing the appearance on a loft does not work.
- **CSG Booleans**: Coplanar (bodies that share a plane) unions, subtractions, and intersections are not currently supported.

View File

@ -28,7 +28,7 @@ lastSegX(sketch: Sketch): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [5, 0]) |> line(end = [5, 0])
|> line(end = [20, 5]) |> line(end = [20, 5])
|> line(end = [lastSegX(%), 0]) |> line(end = [lastSegX(%), 0])

View File

@ -28,7 +28,7 @@ lastSegY(sketch: Sketch): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [5, 0]) |> line(end = [5, 0])
|> line(end = [20, 5]) |> line(end = [20, 5])
|> line(end = [0, lastSegY(%)]) |> line(end = [0, lastSegY(%)])

View File

@ -24,8 +24,8 @@ legAngX(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes | | `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes | | `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
### Returns ### Returns
@ -35,7 +35,7 @@ legAngX(
### Examples ### Examples
```js ```js
legAngX(5, 3) legAngX(hypotenuse = 5, leg = 3)
``` ```

View File

@ -24,8 +24,8 @@ legAngY(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes | | `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes | | `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
### Returns ### Returns
@ -35,7 +35,7 @@ legAngY(
### Examples ### Examples
```js ```js
legAngY(5, 3) legAngY(hypotenuse = 5, leg = 3)
``` ```

View File

@ -24,8 +24,8 @@ legLen(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes | | `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes | | `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
### Returns ### Returns
@ -35,7 +35,7 @@ legLen(
### Examples ### Examples
```js ```js
legLen(5, 3) legLen(hypotenuse = 5, leg = 3)
``` ```

View File

@ -36,7 +36,7 @@ line(
```js ```js
triangle = startSketchOn(XZ) triangle = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
// The END argument means it ends at exactly [10, 0]. // The END argument means it ends at exactly [10, 0].
// This is an absolute measurement, it is NOT relative to // This is an absolute measurement, it is NOT relative to
// the start of the sketch. // the start of the sketch.
@ -47,7 +47,7 @@ triangle = startSketchOn(XZ)
|> extrude(length = 5) |> extrude(length = 5)
box = startSketchOn(XZ) box = startSketchOn(XZ)
|> startProfileAt([10, 10], %) |> startProfile(at = [10, 10])
// The 'to' argument means move the pen this much. // The 'to' argument means move the pen this much.
// So, [10, 0] is a relative distance away from the current point. // So, [10, 0] is a relative distance away from the current point.
|> line(end = [10, 0]) |> line(end = [10, 0])

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,7 @@ loft(
```js ```js
// Loft a square and a triangle. // Loft a square and a triangle.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %) |> startProfile(at = [-100, 200])
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
|> line(end = [-200, 0]) |> line(end = [-200, 0])
@ -51,7 +51,7 @@ squareSketch = startSketchOn(XY)
|> close() |> close()
triangleSketch = startSketchOn(offsetPlane(XY, offset = 75)) triangleSketch = startSketchOn(offsetPlane(XY, offset = 75))
|> startProfileAt([0, 125], %) |> startProfile(at = [0, 125])
|> line(end = [-15, -30]) |> line(end = [-15, -30])
|> line(end = [30, 0]) |> line(end = [30, 0])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
@ -65,7 +65,7 @@ loft([squareSketch, triangleSketch])
```js ```js
// Loft a square, a circle, and another circle. // Loft a square, a circle, and another circle.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %) |> startProfile(at = [-100, 200])
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
|> line(end = [-200, 0]) |> line(end = [-200, 0])
@ -90,7 +90,7 @@ loft([
```js ```js
// Loft a square, a circle, and another circle with options. // Loft a square, a circle, and another circle with options.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn(XY)
|> startProfileAt([-100, 200], %) |> startProfile(at = [-100, 200])
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
|> line(end = [-200, 0]) |> line(end = [-200, 0])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@ isolated from other files as a separate module.
When you define a function, you can use `export` before it to make it available When you define a function, you can use `export` before it to make it available
to other modules. to other modules.
``` ```kcl
// util.kcl // util.kcl
export fn increment(x) { export fn increment(x) {
return x + 1 return x + 1
@ -31,11 +31,11 @@ Imported files _must_ be in the same project so that units are uniform across
modules. This means that it must be in the same directory. modules. This means that it must be in the same directory.
Import statements must be at the top-level of a file. It is not allowed to have Import statements must be at the top-level of a file. It is not allowed to have
an `import` statement inside a function or in the body of an if-else. an `import` statement inside a function or in the body of an ifelse.
Multiple functions can be exported in a file. Multiple functions can be exported in a file.
``` ```kcl
// util.kcl // util.kcl
export fn increment(x) { export fn increment(x) {
return x + 1 return x + 1
@ -58,6 +58,215 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
import increment as inc, decrement as dec from "util.kcl" import increment as inc, decrement as dec from "util.kcl"
``` ```
---
## Functions vs `clone`
There are two common patterns for reusing geometry:
1. **Wrap the construction in a function** flexible and fully parametric.
2. **Duplicate an existing object with `clone`** lightningfast, but an exact
duplicate.
### Parametric function example
```kcl
fn cube(center) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
myCube = cube([0, 0])
```
*Pros*
- Any argument can be a parameter size, position, appearance, etc.
- Works great inside loops, arrays, or optimisation sweeps.
*Cons*
- Every invocation rebuilds the entire feature tree.
- **Slower** than a straight duplicate each call is its own render job.
### `clone` example
```kcl
sketch001 = startSketchOn(-XZ)
|> circle(center = [0, 0], radius = 10)
|> extrude(length = 5)
|> appearance(color = "#ff0000", metalness = 90, roughness = 90)
sketch002 = clone(sketch001) // ✓ instant copy
```
*Pros*
- Roughly an O(1) operation we just duplicate the underlying engine handle.
- Perfect when you need ten identical bolts or two copies of the same imported STEP file.
*Cons*
- **Not parametric** the clone is exactly the same shape as the source.
- If you need to tweak dimensions perinstance, youre back to a function.
> **Rule of thumb** Reach for `clone` when the geometry is already what you want. Reach for a function when you need customisation.
---
## Modulelevel parallelism
Under the hood, the Design Studio runs **every module in parallel** where it can. This means:
- The toplevel code of `foo.kcl`, `bar.kcl`, and `baz.kcl` all start executing immediately and concurrently.
- Imports that read foreign files (STEP/OBJ/…) overlap their I/O and background render.
- CPUbound calculations in separate modules get their own worker threads.
### Why modules beat onebigfile
If you shoehorn everything into `main.kcl`, each statement runs sequentially:
```norun
import "big.step" as gizmo // blocks main while reading
gizmo |> translate(x=50) // blocks again while waiting for render
```
Split `gizmo` into its own file and the read/render can overlap whatever else `main.kcl` is doing.
```norun
// gizmo.kcl (worker A)
import "big.step"
// main.kcl (worker B)
import "gizmo.kcl" as gizmo // nonblocking
// ... other setup ...
gizmo |> translate(x=50) // only blocks here
```
### Gotcha: defining but **not** calling functions
Defining a function inside a module is instantaneous we just record the bytecode. The heavy lifting happens when the function is **called**. So:
```norun
// util.kcl
export fn makeBolt(size) { /* … expensive CAD … */ }
```
If `main.kcl` waits until the very end to call `makeBolt`, *none* of that work was parallelised youve pushed the cost back onto the serial tail of your script.
**Better:** call it early or move the invocation into another module.
```norun
// bolt_instance.kcl
import makeBolt from "util.kcl"
bolt = makeBolt(5) // executed in parallel
bolt
```
Now `main.kcl` can `import "bolt_instance.kcl" as bolt` and get the result that was rendered while it was busy doing other things.
---
## Whole module import
You can also import the whole module. This is useful if you want to use the
result of a module as a variable, like a part.
```norun
import "tests/inputs/cube.kcl" as cube
cube
|> translate(x=10)
```
This imports the whole module and makes it available as `cube`. You can then
use it like any other object. The `cube` variable is now a reference to the
result of the module. This means that if you change the module, the `cube`
variable will change as well.
In `cube.kcl`, you cannot have multiple objects. It has to be a single part. If
you have multiple objects, you will get an error. This is because the module is
expected to return a single object that can be used as a variable.
The last expression or variable definition becomes the module's return value.
The module is expected to return a single object that can be used as a variable
by whatever imports it.
So for example, this is allowed:
```norun
... a bunch of code to create cube and cube2 ...
myUnion = union([cube, cube2])
```
You can also do this:
```norun
... a bunch of code to create cube and cube2 ...
union([cube, cube2])
```
Either way, the last line will return the union of the two objects.
Or what you could do instead is:
```norun
... a bunch of code to create cube and cube2 ...
myUnion = union([cube, cube2])
myUnion
```
This will assign the union of the two objects to a variable, and then return it
on the last statement. It's simply another way of doing the same thing.
The final statement is what's important because it's the return value of the
entire module. The module is expected to return a single object that can be used
as a variable by the file that imports it.
---
## Multiple instances of the same import
Whether you are importing a file from another CAD system or a KCL file, that
file represents object(s) in memory. If you import the same file multiple times,
it will only be rendered once.
If you want to have multiple instances of the same object, you can use the
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
```norun
import cube from "tests/inputs/cube.kcl"
cube
|> translate(x=10)
clone(cube)
|> translate(x=20)
```
In the sample above, the `cube` object is imported from a KCL file. The first
instance is translated 10 units in the x direction. The second instance is
cloned and translated 20 units in the x direction. The two instances are now
separate objects in memory, and can be manipulated independently.
Here is an example with a file from another CAD system:
```kcl
import "tests/inputs/cube.step" as cube
cube
|> translate(x=10)
clone(cube)
|> translate(x=20)
```
---
## Importing files from other CAD systems ## Importing files from other CAD systems
`import` can also be used to import files from other CAD systems. The format of the statement is the `import` can also be used to import files from other CAD systems. The format of the statement is the
@ -69,26 +278,18 @@ import "tests/inputs/cube.obj"
// Use `cube` just like a KCL object. // Use `cube` just like a KCL object.
``` ```
```norun ```kcl
import "tests/inputs/cube-2.sldprt" as cube import "tests/inputs/cube.sldprt" as cube
// Use `cube` just like a KCL object. // Use `cube` just like a KCL object.
``` ```
You can make the file format explicit using a format attribute (useful if using a different
extension), e.g.,
```norun
@(format = obj)
import "tests/inputs/cube"
```
For formats lacking unit data (such as STL, OBJ, or PLY files), the default For formats lacking unit data (such as STL, OBJ, or PLY files), the default
unit of measurement is millimeters. Alternatively you may specify the unit unit of measurement is millimeters. Alternatively you may specify the unit
by using an attirbute. Likewise, you can also specify a coordinate system. E.g., by using an attribute. Likewise, you can also specify a coordinate system. E.g.,
```norun ```kcl
@(unitLength = ft, coords = opengl) @(lengthUnit = ft, coords = opengl)
import "tests/inputs/cube.obj" import "tests/inputs/cube.obj"
``` ```
@ -109,3 +310,56 @@ Coordinate systems:
- `zoo` (the default), forward: -Y, up: +Z, handedness: right - `zoo` (the default), forward: -Y, up: +Z, handedness: right
- `opengl`, forward: +Z, up: +Y, handedness: right - `opengl`, forward: +Z, up: +Y, handedness: right
- `vulkan`, forward: +Z, up: -Y, handedness: left - `vulkan`, forward: +Z, up: -Y, handedness: left
---
## Performance deepdive for foreignfile imports
Parallelized foreignfile imports now let you overlap file reads, initialization,
and rendering. To maximize throughput, you need to understand the three distinct
stages—reading, initializing (background render start), and invocation (blocking)
—and structure your code to defer blocking operations until the end.
### Foreign import execution stages
1. **Import (Read / Initialization) Stage**
```kcl
import "tests/inputs/cube.step" as cube
```
- Reads the file from disk and makes its API available.
- Starts engine rendering but **does not block** your script.
- This kickstarts the render pipeline while you keep executing other code.
2. **Invocation (Blocking) Stage**
```kcl
import "tests/inputs/cube.step" as cube
cube
|> translate(z=10) // ← blocks here only
```
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
### Best practices
#### 1. Defer blocking calls
```kcl
import "tests/inputs/cube.step" as cube // 1) Read / Background render starts
// --- perform other operations and calculations here ---
cube
|> translate(z=10) // 2) Blocks only here
```
#### 2. Split heavy work into separate modules
Place computationally expensive or IOheavy work into its own module so it can render in parallel while `main.kcl` continues.
#### Future improvements
Upcoming releases will autoanalyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.

File diff suppressed because one or more lines are too long

View File

@ -40,7 +40,7 @@ patternCircular2d(
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([.5, 25], %) |> startProfile(at = [.5, 25])
|> line(end = [0, 5]) |> line(end = [0, 5])
|> line(end = [-1, 0]) |> line(end = [-1, 0])
|> line(end = [0, -5]) |> line(end = [0, -5])

View File

@ -38,7 +38,7 @@ patternLinear3d(
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [0, 2]) |> line(end = [0, 2])
|> line(end = [3, 1]) |> line(end = [3, 1])
|> line(end = [0, -4]) |> line(end = [0, -4])
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 1)
// Pattern a whole sketch on face. // Pattern a whole sketch on face.
size = 100 size = 100
case = startSketchOn(XY) case = startSketchOn(XY)
|> startProfileAt([-size, -size], %) |> startProfile(at = [-size, -size])
|> line(end = [2 * size, 0]) |> line(end = [2 * size, 0])
|> line(end = [0, 2 * size]) |> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size]) |> tangentialArc(endAbsolute = [-size, size])
@ -85,7 +85,7 @@ patternLinear3d(
// Pattern an object on a face. // Pattern an object on a face.
size = 100 size = 100
case = startSketchOn(XY) case = startSketchOn(XY)
|> startProfileAt([-size, -size], %) |> startProfile(at = [-size, -size])
|> line(end = [2 * size, 0]) |> line(end = [2 * size, 0])
|> line(end = [0, 2 * size]) |> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size]) |> tangentialArc(endAbsolute = [-size, size])

View File

@ -102,7 +102,7 @@ fn cube(length, center) {
p3 = [l + x, -l + y] p3 = [l + x, -l + y]
return startSketchOn(XY) return startSketchOn(XY)
|> startProfileAt(p0, %) |> startProfile(at = p0)
|> line(endAbsolute = p1) |> line(endAbsolute = p1)
|> line(endAbsolute = p2) |> line(endAbsolute = p2)
|> line(endAbsolute = p3) |> line(endAbsolute = p3)
@ -117,7 +117,11 @@ fn transform(i) {
// Move down each time. // Move down each time.
translate = [0, 0, -i * width], translate = [0, 0, -i * width],
// Make the cube longer, wider and flatter each time. // Make the cube longer, wider and flatter each time.
scale = [pow(1.1, i), pow(1.1, i), pow(0.9, i)], scale = [
pow(1.1, exp = i),
pow(1.1, exp = i),
pow(0.9, exp = i)
],
// Turn by 15 degrees each time. // Turn by 15 degrees each time.
rotation = { angle = 15 * i, origin = "local" } rotation = { angle = 15 * i, origin = "local" }
} }
@ -140,7 +144,7 @@ fn cube(length, center) {
p3 = [l + x, -l + y] p3 = [l + x, -l + y]
return startSketchOn(XY) return startSketchOn(XY)
|> startProfileAt(p0, %) |> startProfile(at = p0)
|> line(endAbsolute = p1) |> line(endAbsolute = p1)
|> line(endAbsolute = p2) |> line(endAbsolute = p2)
|> line(endAbsolute = p3) |> line(endAbsolute = p3)
@ -174,7 +178,7 @@ t = 0.005 // taper factor [0-1)
// Defines how to modify each layer of the vase. // Defines how to modify each layer of the vase.
// Each replica is shifted up the Z axis, and has a smoothly-varying radius // Each replica is shifted up the Z axis, and has a smoothly-varying radius
fn transform(replicaId) { fn transform(replicaId) {
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8)) scale = r * math::abs(1 - (t * replicaId)) * (5 + math::cos((replicaId / 8): number(rad)))
return { return {
translate = [0, 0, replicaId * 10], translate = [0, 0, replicaId * 10],
scale = [scale, scale, 0] scale = [scale, scale, 0]
@ -204,13 +208,13 @@ fn transform(i) {
] ]
} }
startSketchOn(XY) startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> polygon({ |> polygon(
radius = 10, radius = 10,
numSides = 4, numSides = 4,
center = [0, 0], center = [0, 0],
inscribed = false inscribed = false,
}, %) )
|> extrude(length = 4) |> extrude(length = 4)
|> patternTransform(instances = 3, transform = transform) |> patternTransform(instances = 3, transform = transform)
``` ```

View File

@ -10,9 +10,11 @@ Create a regular polygon with the specified number of sides that is either inscr
```js ```js
polygon( polygon(
data: PolygonData,
sketchSurfaceOrGroup: SketchOrSurface, sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator, radius: number,
numSides: u64,
center: [number],
inscribed?: bool,
): Sketch ): Sketch
``` ```
@ -21,9 +23,11 @@ polygon(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `data` | [`PolygonData`](/docs/kcl/types/PolygonData) | Data for drawing a polygon | Yes | | `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on | Yes |
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes | | `radius` | [`number`](/docs/kcl/types/number) | The radius of the polygon | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No | | `numSides` | `u64` | The number of sides in the polygon | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center point of the polygon | Yes |
| `inscribed` | [`bool`](/docs/kcl/types/bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius | No |
### Returns ### Returns
@ -35,12 +39,12 @@ polygon(
```js ```js
// Create a regular hexagon inscribed in a circle of radius 10 // Create a regular hexagon inscribed in a circle of radius 10
hex = startSketchOn(XY) hex = startSketchOn(XY)
|> polygon({ |> polygon(
radius = 10, radius = 10,
numSides = 6, numSides = 6,
center = [0, 0], center = [0, 0],
inscribed = true inscribed = true,
}, %) )
example = extrude(hex, length = 5) example = extrude(hex, length = 5)
``` ```
@ -50,12 +54,12 @@ example = extrude(hex, length = 5)
```js ```js
// Create a square circumscribed around a circle of radius 5 // Create a square circumscribed around a circle of radius 5
square = startSketchOn(XY) square = startSketchOn(XY)
|> polygon({ |> polygon(
radius = 5.0, radius = 5.0,
numSides = 4, numSides = 4,
center = [10, 10], center = [10, 10],
inscribed = false inscribed = false,
}, %) )
example = extrude(square, length = 5) example = extrude(square, length = 5)
``` ```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin value.
```js ```js
profileStart(sketch: Sketch): [number] profileStart(profile: Sketch): [number]
``` ```
@ -17,7 +17,7 @@ profileStart(sketch: Sketch): [number]
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes | | `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
### Returns ### Returns
@ -28,7 +28,7 @@ profileStart(sketch: Sketch): [number]
```js ```js
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %) |> startProfile(at = [5, 2])
|> angledLine(angle = 120, length = 50, tag = $seg01) |> angledLine(angle = 120, length = 50, tag = $seg01)
|> angledLine(angle = segAng(seg01) + 120, length = 50) |> angledLine(angle = segAng(seg01) + 120, length = 50)
|> line(end = profileStart(%)) |> line(end = profileStart(%))

View File

@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin's 'x' value.
```js ```js
profileStartX(sketch: Sketch): number profileStartX(profile: Sketch): number
``` ```
@ -17,7 +17,7 @@ profileStartX(sketch: Sketch): number
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes | | `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
### Returns ### Returns
@ -28,7 +28,7 @@ profileStartX(sketch: Sketch): number
```js ```js
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %) |> startProfile(at = [5, 2])
|> angledLine(angle = -26.6, length = 50) |> angledLine(angle = -26.6, length = 50)
|> angledLine(angle = 90, length = 50) |> angledLine(angle = 90, length = 50)
|> angledLine(angle = 30, endAbsoluteX = profileStartX(%)) |> angledLine(angle = 30, endAbsoluteX = profileStartX(%))

View File

@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin's 'y' value.
```js ```js
profileStartY(sketch: Sketch): number profileStartY(profile: Sketch): number
``` ```
@ -17,7 +17,7 @@ profileStartY(sketch: Sketch): number
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes | | `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
### Returns ### Returns
@ -28,7 +28,7 @@ profileStartY(sketch: Sketch): number
```js ```js
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %) |> startProfile(at = [5, 2])
|> angledLine(angle = -60, length = 14) |> angledLine(angle = -60, length = 14)
|> angledLine(angle = 30, endAbsoluteY = profileStartY(%)) |> angledLine(angle = 30, endAbsoluteY = profileStartY(%))
``` ```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -53,7 +53,7 @@ rotate(
### Returns ### Returns
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry. [`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
### Examples ### Examples
@ -63,7 +63,7 @@ rotate(
// Create a path for the sweep. // Create a path for the sweep.
sweepPath = startSketchOn(XZ) sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %) |> startProfile(at = [0.05, 0.05])
|> line(end = [0, 7]) |> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5) |> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0]) |> line(end = [-3, 0])
@ -76,7 +76,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY) sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %) |> subtract2d(tool = pipeHole)
|> sweep(path = sweepPath) |> sweep(path = sweepPath)
|> rotate(roll = 10, pitch = 10, yaw = 90) |> rotate(roll = 10, pitch = 10, yaw = 90)
``` ```
@ -88,7 +88,7 @@ sweepSketch = startSketchOn(XY)
// Create a path for the sweep. // Create a path for the sweep.
sweepPath = startSketchOn(XZ) sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %) |> startProfile(at = [0.05, 0.05])
|> line(end = [0, 7]) |> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5) |> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0]) |> line(end = [-3, 0])
@ -101,7 +101,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY) sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %) |> subtract2d(tool = pipeHole)
|> sweep(path = sweepPath) |> sweep(path = sweepPath)
|> rotate(roll = 10) |> rotate(roll = 10)
``` ```
@ -113,7 +113,7 @@ sweepSketch = startSketchOn(XY)
// Create a path for the sweep. // Create a path for the sweep.
sweepPath = startSketchOn(XZ) sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %) |> startProfile(at = [0.05, 0.05])
|> line(end = [0, 7]) |> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5) |> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0]) |> line(end = [-3, 0])
@ -126,7 +126,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY) sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %) |> subtract2d(tool = pipeHole)
|> sweep(path = sweepPath) |> sweep(path = sweepPath)
|> rotate(axis = [0, 0, 1.0], angle = 90) |> rotate(axis = [0, 0, 1.0], angle = 90)
``` ```
@ -150,7 +150,7 @@ cube
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001) rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61) |> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001)) |> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
@ -160,7 +160,7 @@ rectangleSketch = startProfileAt([-200, 23.86], sketch001)
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ) sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002) sweepPath = startProfile(sketch002, at = [0, 0])
|> yLine(length = 231.81) |> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90) |> tangentialArc(radius = 80, angle = -90)
|> xLine(length = 384.93) |> xLine(length = 384.93)
@ -178,7 +178,7 @@ rotate(parts, axis = [0, 0, 1.0], angle = 90)
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
fn square() { fn square() {
return startProfileAt([-10, 10], sketch001) return startProfile(sketch001, at = [-10, 10])
|> xLine(length = 20) |> xLine(length = 20)
|> yLine(length = -20) |> yLine(length = -20)
|> xLine(length = -20) |> xLine(length = -20)

File diff suppressed because one or more lines are too long

View File

@ -37,7 +37,7 @@ scale(
### Returns ### Returns
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry. [`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
### Examples ### Examples
@ -47,7 +47,7 @@ scale(
// Create a path for the sweep. // Create a path for the sweep.
sweepPath = startSketchOn(XZ) sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %) |> startProfile(at = [0.05, 0.05])
|> line(end = [0, 7]) |> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5) |> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0]) |> line(end = [-3, 0])
@ -60,7 +60,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY) sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %) |> subtract2d(tool = pipeHole)
|> sweep(path = sweepPath) |> sweep(path = sweepPath)
|> scale(z = 2.5) |> scale(z = 2.5)
``` ```
@ -84,7 +84,7 @@ cube
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001) rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61) |> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001)) |> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
@ -94,7 +94,7 @@ rectangleSketch = startProfileAt([-200, 23.86], sketch001)
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ) sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002) sweepPath = startProfile(sketch002, at = [0, 0])
|> yLine(length = 231.81) |> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90) |> tangentialArc(radius = 80, angle = -90)
|> xLine(length = 384.93) |> xLine(length = 384.93)

View File

@ -28,7 +28,7 @@ segAng(tag: TagIdentifier): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
|> line(end = [5, 10], tag = $seg01) |> line(end = [5, 10], tag = $seg01)
|> line(end = [-10, 0]) |> line(end = [-10, 0])

View File

@ -29,7 +29,7 @@ segEnd(tag: TagIdentifier): [number]
```js ```js
w = 15 w = 15
cube = startSketchOn(XY) cube = startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [w, 0], tag = $line1) |> line(end = [w, 0], tag = $line1)
|> line(end = [0, w], tag = $line2) |> line(end = [0, w], tag = $line2)
|> line(end = [-w, 0], tag = $line3) |> line(end = [-w, 0], tag = $line3)
@ -39,7 +39,7 @@ cube = startSketchOn(XY)
fn cylinder(radius, tag) { fn cylinder(radius, tag) {
return startSketchOn(XY) return startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> circle(radius = radius, center = segEnd(tag)) |> circle(radius = radius, center = segEnd(tag))
|> extrude(length = radius) |> extrude(length = radius)
} }

View File

@ -28,7 +28,7 @@ segEndX(tag: TagIdentifier): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [20, 0], tag = $thing) |> line(end = [20, 0], tag = $thing)
|> line(end = [0, 5]) |> line(end = [0, 5])
|> line(end = [segEndX(thing), 0]) |> line(end = [segEndX(thing), 0])

View File

@ -28,7 +28,7 @@ segEndY(tag: TagIdentifier): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [20, 0]) |> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing) |> line(end = [0, 3], tag = $thing)
|> line(end = [-10, 0]) |> line(end = [-10, 0])

View File

@ -28,7 +28,7 @@ segLen(tag: TagIdentifier): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> angledLine(angle = 60, length = 10, tag = $thing) |> angledLine(angle = 60, length = 10, tag = $thing)
|> tangentialArc(angle = -120, radius = 5) |> tangentialArc(angle = -120, radius = 5)
|> angledLine(angle = -60, length = segLen(thing)) |> angledLine(angle = -60, length = segLen(thing))

View File

@ -29,7 +29,7 @@ segStart(tag: TagIdentifier): [number]
```js ```js
w = 15 w = 15
cube = startSketchOn(XY) cube = startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [w, 0], tag = $line1) |> line(end = [w, 0], tag = $line1)
|> line(end = [0, w], tag = $line2) |> line(end = [0, w], tag = $line2)
|> line(end = [-w, 0], tag = $line3) |> line(end = [-w, 0], tag = $line3)
@ -39,7 +39,7 @@ cube = startSketchOn(XY)
fn cylinder(radius, tag) { fn cylinder(radius, tag) {
return startSketchOn(XY) return startSketchOn(XY)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> circle(radius = radius, center = segStart(tag)) |> circle(radius = radius, center = segStart(tag))
|> extrude(length = radius) |> extrude(length = radius)
} }

View File

@ -28,7 +28,7 @@ segStartX(tag: TagIdentifier): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [20, 0], tag = $thing) |> line(end = [20, 0], tag = $thing)
|> line(end = [0, 5]) |> line(end = [0, 5])
|> line(end = [20 - segStartX(thing), 0]) |> line(end = [20 - segStartX(thing), 0])

View File

@ -28,7 +28,7 @@ segStartY(tag: TagIdentifier): number
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfile(at = [0, 0])
|> line(end = [20, 0]) |> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing) |> line(end = [0, 3], tag = $thing)
|> line(end = [-10, 0]) |> line(end = [-10, 0])

File diff suppressed because one or more lines are too long

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