Compare commits

..

28 Commits

Author SHA1 Message Date
cbca63c6e0 WIP: Start synchronizing the enableSketchMode call 2025-02-21 16:57:36 -06:00
b3cd5ef3ba Show visible error when updater call fails (#5455)
* Show visible error when updater call fails due to permissions issue
Fixes #3696

* Update comment for consistency
2025-02-21 21:34:19 +00:00
a094995730 KCL: Chamfer and fillet now use keyword arguments (#5389)
Previously:
`|> fillet({ radius = 5, tags = [seg01] }, %)`
Now:
`|> fillet(radius = 5, tags = [seg01])`

Also tweaks the formatter for keyword argument calls slightly.
2025-02-21 20:41:25 +00:00
46b4b01d23 [Refactor] decouple settingsMachine from React (#5142)
* Remove unnecessary console.log

* Create a global appMachine

* Strip authMachine of side-effects

* Replace react-bound authMachine use with XState actor use

* Fix import goof

* Register auth commands directly!

* Don't provide anything to settingsMachine from React

* Remove unecessary async

* Make it possible to load project settings via a sent event, without React

* Make settingsMachine ready to be an actor

* Remove settingsLoader use

* Replace all useSettingsAuthContext use with direct actor use

* Add logic to clear project settings, fmt

* fmt

* Clear and load project settings from routeLoaders, but using actor

* Remove useRefreshSettings

* Restore use of useToken() that wasn't working for some reason

* Migrate useFileSystemWatcher use to RouteProvider

* Surface wasm_bindgen unavailable error to console

* Remove unnecessary use of Jest settings wrappers

* Replace dynamic import with actor.getSnapshot

* Migrate system theme and theme color watching from useEffects to actors/actions

* Migrate cursor color effect

* Remove unused code that is now in RouteProvider

* Migrate route commands registration further down for now, out of SettingsAuthProvider

* Migrate settings command registration out of SettingsAuthProvider.tsx

* Delete SettingsAuthProvider.tsx!

* Remove unused settingsLoader!

* fmt and remove comments

* Use actor for routeLoader

* Fix project read error due to uninitialized WASM

* Fix user settings load error due to uninitialized WASM

* Move settingsActor into appActor as a spawned child

* Trying to fix unit tests

* Remove unused imports and demo window attachments

* fmt

* Fix testing issues caused by circular dependency

* Add `setThemeColor` to a few actions list it was missing from

* fmt

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

* Fix "Execute AST" action in browser, where currentProject is `undefined`

* Update commands list when currentProject changes

* Fix `clearProjectSettings`, which was passing along non-settings context

* Fix onboarding test that actually needed the onboarding initially dismissed

* Add scrollIntoView to make this test more reliable

* @lf94's feedback I missed

I got distracted by a million other things last week

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

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

This reverts commit 129226c6ef.

* fmt

* revert bad snapshot

* Fix up camera movement test locator

* Fix test that was flipping the user settings without waiting

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

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

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

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

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

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

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

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

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

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

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

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

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

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-21 13:47:36 -05:00
4d1eaf9381 Make Windows elevated perms prompt show app name not description (#5452)
* Change package description to equal title, disable universal installer

* Remove buildUniversalInstaller

* Force build release

* Remove test changes
2025-02-21 16:09:46 +00:00
df3668adc8 Add the runtime value of arguments to operations (#5206) 2025-02-21 10:24:12 -05:00
270781d5cd better testing for making sure we update the cache state on just settings changes (#5445) 2025-02-21 06:08:49 +00:00
96b93f8d51 Review folllow ups (#5444)
* Remove StandardPlane docs

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

* Add a struct for encapsualting an f64 and a type

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-02-21 12:36:21 +13:00
59b1c414f0 fix: E2E test assumes codemirror error is present when it is lazy loaded (#5446)
* fix: test is written incorrectly, assumes codemirror has DOM content when it does not

* fix: auto fmt fixes
2025-02-20 23:33:13 +00:00
fd07b8cff5 Fixes to docs (#5440)
* updates

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

* updates

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

* clenaup

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-20 20:49:27 +00:00
21efb2c0bd Support warning and non-fatal errors when executing (#5431)
* Support warning and non-fatal errors when executing

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

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

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-21 09:30:44 +13:00
30029a63a1 Fix kcl file opening on Windows (double click) on second instance (#5420)
* WIP: Double-clicking on .kcl file on Windows redirects to the home page if the app is already open
Fixes #5412

* Add deep link test case for linux

* Add mac tests

* Lint and win tests

* Fix e2e tests

* Logs everywhere

* windows weird? yup

* More logzzz maybe it's not windows

* Remove :/// replacement. Add catch log

* Fix and clean up

* FIx lint

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

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

* More lint

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

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

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

* Clean up tests further

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-20 15:23:39 -05:00
9f5003cafc Make z-index relation between sketch scene items explicit and colocated (#5435)
* Set up start of semantic z-index layers in tailwind.config.js

* Use first two active semantic z-index layers to fix just this issue
2025-02-20 18:53:35 +00:00
5232e1d40a Bump kcl-samples manifest fallback (#5434)
I think this is going away very soon but I don't want it to annoy
anyone's work in the meantime.
2025-02-20 18:36:22 +00:00
23c25c2b50 Patch test with longer timeout (#5438)
Also adds a TODO with a link to
https://github.com/KittyCAD/modeling-app/issues/5437 to track the
underlying issue
2025-02-20 17:14:43 +00:00
50273c0edc Fix kcl-lib derive-docs version (#5436) 2025-02-20 12:05:36 -05:00
8a03bf50e3 make multiple sketches on same face individually editable (#5430)
make multipl sketches individuall editable
2025-02-20 10:14:35 -05:00
7500ef0065 Declare parts of std in KCL rather than Rust (#5147)
Declare std in KCL
2025-02-20 19:33:21 +13:00
099c48cd63 better docs on solids and sketches (#5428)
* updates

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

* fix docs;

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

* updates

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

* updates

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

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

* parens

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

* parens

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-20 03:48:27 +00:00
f35cd3ef26 Generalise and simplify offsetPlane (#5429)
* Generalise and simplify offsetPlane

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

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

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-20 15:55:29 +13:00
695c432d1e CM KCL: highlight property names, labeled args and annotations (#5386)
* CM KCL: highlight property names in objects

* CM KCL: highlight arg labels in fn calls

* CM KCL: highlight annotations

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

---------

Co-authored-by: Matt Mundell <matt@mundell.me>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-20 01:17:18 +00:00
2835665a6a KCL: Script for releasing (#5422) 2025-02-19 16:56:51 -06:00
45707d2974 More numeric types baby steps (#5388)
* Add units to Paths

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

* Add some NumericType combination functions

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

* Fix docs/json/snippets generation from schemas

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-02-20 10:12:37 +13:00
b2e1d21d45 Add Delete to right-click context menu of feature tree operations (#5302)
* Revert "Revert multi-profile (#4812)"

This reverts commit efe8089b08.

* fix poor 1000ms wait UX

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

* trigger CI

* Add Rust side artifacts for startSketchOn face or plane (#4834)

* Add Rust side artifacts for startSketchOn face or plane

* move ast digging

---------

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

* lint

* lint

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

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

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

* trigger CI

* chore: disabled file watcher which prevents faster file write (#4835)

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

* partial fixes

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

* Trigger CI

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

* Trigger CI

* Fix up all the tests

* Fix partial execution

* wip

* WIP

* wip

* rust changes to make three point confrom to same as others since we're not ready with name params yet

* most of the fix for 3 point circle

* get overlays working for circle three point

* fmt

* fix types

* cargo fmt

* add face codef ref for walls and caps

* fix sketch on face after updates to rust side artifact graph

* some things needed for multi-profile tests

* bad attempts at fixing rust

* more

* more

* fix rust

* more rust fixes

* overlay fix

* remove duplicate test

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

* lint and typing

* maybe fix a unit test

* small thing

* WIP: Add Delete right click menu item to Feature Tree
Copying code around
Fixes #5090

* I don't know why it works

* WIP

* fix circ dep

* fix unit test

* fix some tests

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

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

* Working deletion machine loo

* Working helix deletion

* Extend deletion to more things

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

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

* fix sweep point-and-click test

* fix more tests and add a fix me

* fix more tests

* fix electron specific test

* tsc

* more test tweaks

* update docs

* commint snaps?

* is clippy happy now?

* clippy again

* test works now without me changing anything big-fixed-itself

* small bug

* make three point have cross hair to make it consistent with othe rtools

* fix up state diagram

* fmt

* add draft point for first click of three point circ

* 1 test for three point circle

* 2 test for three point circle

* clean up

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

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

* remove bad doc comment

* remove test skip

* remove onboarding test changes

* Update src/lang/modifyAst.ts

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

* Update output from simulation tests

* Fix to use correct source ranges

This also reduces cloning.

* Change back to skipping face cap none and both

* Update output after changing back to skipping none and both

* Fix clippy warning

* fix profile start snap bug

* WIP: migrate to actor

* add path ids to cap

* fix going into edit sketch

* make other startSketchOn's work

* fix snapshot test

* explain function name

* Update src/lib/rectangleTool.ts

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

* rename error

* remove file tree from diff

* Update src/clientSideScene/segments.ts

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

* nit

* Continue actor migration

* Prevent double write to KCL code on revolve

* Clean up

* Update output after adding cap-to-path graph edge

* Clean up

* Update machine diag

* Update context menu hotkey class

* Fix edit/select sketch-on-cap via feature tree

* clean up for face codeRef

* fix changing tools part way through circle/rect tools

* fix delete of circle profile

* fix close profiles

* fix closing profile bug (tangentArcTo being ignored)

* remove stale comment

* Delete paths associated with sketch when the sketch plane is deleted

* Add support for deleting sketches on caps (not walls)

* get delet working for walls

* make delet of extrusions work for multi profile

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

* Delete the sketch statement too on the cap and wall cases

* Don't write to file in `split-sketch-pipe-if-needed` unless necessary

* Don't wait for file write to complete within `updateEditorWithAstAndWriteToFile`
It is already debounced internally. If we await it, we will have to wait for a debounced timeout

* Fix bad conflict resolution

* Fix a few things post merge

* Add guard back, fixing tests

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

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

* Add e2e test

* Working tests on ubuntu

* Another one

* Update src/machines/featureTreeMachine.ts

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

* Fix sketch test
@Irev-Dev's suggestion

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
Co-authored-by: 49lf <ircsurfer33@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-02-19 18:43:27 +00:00
b98f5605b6 [bugfix] Fix user settings opening (#5414)
* Create .gitattributes

* Fix projectPath URI decoding

* Try to enforce UTF-8 encoding on all files except Windows-specific
scripts

* edit file encoding

* edit gitattributes

* Update kcl-samples

* fmt
2025-02-19 13:31:07 -05:00
c050e03df1 Fix sketch test (#5425)
@Irev-Dev's suggestion
2025-02-19 13:30:53 -05:00
b6fa4325f0 Bump modeling-cmds from 0.2.93 to 0.2.97 (#5327)
* Bump modeling-cmds from 0.2.93 to 0.2.96

Among other things, this switches the default units for imported file
formats to millimeters from meters.

* Fix wasm build error

* Upgrade to the latest modeling-cmds 0.2.97
2025-02-19 10:30:26 -08:00
0804aecc63 Fix typo in error msg (#5411)
Part of https://github.com/KittyCAD/modeling-app/issues/5355
2025-02-19 17:40:17 +00:00
490 changed files with 80032 additions and 31418 deletions

13
.gitattributes vendored Normal file
View File

@ -0,0 +1,13 @@
# Set default behavior to automatically normalize line endings.
* text=auto
# Force batch scripts to always use CRLF line endings so that if a repo is accessed
# in Windows via a file share from Linux, the scripts will work.
*.{cmd,[cC][mM][dD]} text working-tree-encoding=UTF-16LE eol=CRLF
*.{bat,[bB][aA][tT]} text working-tree-encoding=UTF-16LE eol=CRLF
*.{ics,[iI][cC][sS]} text working-tree-encoding=UTF-16LE eol=CRLF
*.{ps1,[iP][sS][1]} text working-tree-encoding=UTF-16LE eol=CRLF
# Force bash scripts to always use LF line endings so that if a repo is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lfol=lf

3
.gitignore vendored
View File

@ -41,9 +41,12 @@ e2e/playwright/playwright-secrets.env
e2e/playwright/temp1.png
e2e/playwright/temp2.png
e2e/playwright/temp3.png
# this will be overridden for specific directories
e2e/playwright/**/*.png
# exports from snapshot-tests.spec.ts "exports of each format should work"
e2e/playwright/export-snapshots/*
!e2e/playwright/export-snapshots/*.png
!e2e/playwright/snapshot-tests.spec.ts-snapshots/*.png
/kcl-samples
/test-results/

15
docs/kcl/HALF_TURN.md Normal file
View File

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

15
docs/kcl/QUARTER_TURN.md Normal file
View File

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

View File

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

15
docs/kcl/ZERO.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "ZERO"
excerpt: ""
layout: manual
---
```js
ZERO: number = 0
```

File diff suppressed because one or more lines are too long

32
docs/kcl/const_E.md Normal file

File diff suppressed because one or more lines are too long

View File

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

28
docs/kcl/const_PI.md Normal file

File diff suppressed because one or more lines are too long

View File

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

32
docs/kcl/const_TAU.md Normal file

File diff suppressed because one or more lines are too long

View File

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

15
docs/kcl/const_ZERO.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "ZERO"
excerpt: ""
layout: manual
---
```js
ZERO: number = 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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,15 @@
---
title: "std::prelude::ZERO"
excerpt: ""
layout: manual
---
```js
std::prelude::ZERO: number = 0
```

File diff suppressed because one or more lines are too long

View File

@ -4,9 +4,11 @@ excerpt: "Return the value of Eulers number `e`."
layout: manual
---
**WARNING:** This function is deprecated.
Return the value of Eulers number `e`.
**DEPRECATED** use the constant E
```js
e() -> number

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

@ -82,11 +82,11 @@ helixPath = helix(
length = 10,
radius = 5,
axis = {
custom = {
axis = [0, 0, 1.0],
origin = [0, 0.25, 0]
}
},
custom = {
axis = [0, 0, 1.0],
origin = [0, 0.25, 0]
}
},
)
// Create a spring by sweeping around the helix path.

View File

@ -18,11 +18,11 @@ helixRevolutions(data: HelixRevolutionsData, solid: Solid) -> Solid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`HelixRevolutionsData`](/docs/kcl/types/HelixRevolutionsData) | Data for helix revolutions. | Yes |
| `solid` | [`Solid`](/docs/kcl/types/Solid) | An solid is a collection of extrude surfaces. | Yes |
| `solid` | [`Solid`](/docs/kcl/types/Solid) | A solid is a collection of extrude surfaces. | Yes |
### Returns
[`Solid`](/docs/kcl/types/Solid) - An solid is a collection of extrude surfaces.
[`Solid`](/docs/kcl/types/Solid) - A solid is a collection of extrude surfaces.
### Examples

View File

@ -18,11 +18,11 @@ hollow(thickness: number, solid: Solid) -> Solid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `thickness` | `number` | | Yes |
| `solid` | [`Solid`](/docs/kcl/types/Solid) | An solid is a collection of extrude surfaces. | Yes |
| `solid` | [`Solid`](/docs/kcl/types/Solid) | A solid is a collection of extrude surfaces. | Yes |
### Returns
[`Solid`](/docs/kcl/types/Solid) - An solid is a collection of extrude surfaces.
[`Solid`](/docs/kcl/types/Solid) - A solid is a collection of extrude surfaces.
### Examples

View File

@ -9,110 +9,117 @@ layout: manual
* [Types](kcl/types)
* [Modules](kcl/modules)
* [Known Issues](kcl/KNOWN-ISSUES)
* [`abs`](kcl/abs)
* [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine)
* [`angledLineOfXLength`](kcl/angledLineOfXLength)
* [`angledLineOfYLength`](kcl/angledLineOfYLength)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`angledLineToX`](kcl/angledLineToX)
* [`angledLineToY`](kcl/angledLineToY)
* [`appearance`](kcl/appearance)
* [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo)
* [`asin`](kcl/asin)
* [`assert`](kcl/assert)
* [`assertEqual`](kcl/assertEqual)
* [`assertGreaterThan`](kcl/assertGreaterThan)
* [`assertGreaterThanOrEq`](kcl/assertGreaterThanOrEq)
* [`assertLessThan`](kcl/assertLessThan)
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
* [`atan`](kcl/atan)
* [`atan2`](kcl/atan2)
* [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer)
* [`circle`](kcl/circle)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`cos`](kcl/cos)
* [`e`](kcl/e)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`ft`](kcl/ft)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix)
* [`helixRevolutions`](kcl/helixRevolutions)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`inch`](kcl/inch)
* [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY)
* [`legAngX`](kcl/legAngX)
* [`legAngY`](kcl/legAngY)
* [`legLen`](kcl/legLen)
* [`line`](kcl/line)
* [`ln`](kcl/ln)
* [`loft`](kcl/loft)
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`m`](kcl/m)
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`mirror2d`](kcl/mirror2d)
* [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d)
* [`patternLinear3d`](kcl/patternLinear3d)
* [`patternTransform`](kcl/patternTransform)
* [`patternTransform2d`](kcl/patternTransform2d)
* [`pi`](kcl/pi)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon)
* [`pop`](kcl/pop)
* [`pow`](kcl/pow)
* [`profileStart`](kcl/profileStart)
* [`profileStartX`](kcl/profileStartX)
* [`profileStartY`](kcl/profileStartY)
* [`push`](kcl/push)
* [`reduce`](kcl/reduce)
* [`rem`](kcl/rem)
* [`revolve`](kcl/revolve)
* [`round`](kcl/round)
* [`segAng`](kcl/segAng)
* [`segEnd`](kcl/segEnd)
* [`segEndX`](kcl/segEndX)
* [`segEndY`](kcl/segEndY)
* [`segLen`](kcl/segLen)
* [`segStart`](kcl/segStart)
* [`segStartX`](kcl/segStartX)
* [`segStartY`](kcl/segStartY)
* [`shell`](kcl/shell)
* [`sin`](kcl/sin)
* [`sqrt`](kcl/sqrt)
* [`startProfileAt`](kcl/startProfileAt)
* [`startSketchOn`](kcl/startSketchOn)
* [`sweep`](kcl/sweep)
* [`tan`](kcl/tan)
* [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc)
* [`tangentialArcTo`](kcl/tangentialArcTo)
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
* [`tau`](kcl/tau)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`xLine`](kcl/xLine)
* [`xLineTo`](kcl/xLineTo)
* [`yLine`](kcl/yLine)
* [`yLineTo`](kcl/yLineTo)
* [`yd`](kcl/yd)
* **`std`**
* [`abs`](kcl/abs)
* [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine)
* [`angledLineOfXLength`](kcl/angledLineOfXLength)
* [`angledLineOfYLength`](kcl/angledLineOfYLength)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`angledLineToX`](kcl/angledLineToX)
* [`angledLineToY`](kcl/angledLineToY)
* [`appearance`](kcl/appearance)
* [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo)
* [`asin`](kcl/asin)
* [`assert`](kcl/assert)
* [`assertEqual`](kcl/assertEqual)
* [`assertGreaterThan`](kcl/assertGreaterThan)
* [`assertGreaterThanOrEq`](kcl/assertGreaterThanOrEq)
* [`assertLessThan`](kcl/assertLessThan)
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
* [`atan`](kcl/atan)
* [`atan2`](kcl/atan2)
* [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer)
* [`circle`](kcl/circle)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`ft`](kcl/ft)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix)
* [`helixRevolutions`](kcl/helixRevolutions)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`inch`](kcl/inch)
* [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY)
* [`legAngX`](kcl/legAngX)
* [`legAngY`](kcl/legAngY)
* [`legLen`](kcl/legLen)
* [`line`](kcl/line)
* [`ln`](kcl/ln)
* [`loft`](kcl/loft)
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`m`](kcl/m)
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`mirror2d`](kcl/mirror2d)
* [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d)
* [`patternLinear3d`](kcl/patternLinear3d)
* [`patternTransform`](kcl/patternTransform)
* [`patternTransform2d`](kcl/patternTransform2d)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon)
* [`pop`](kcl/pop)
* [`pow`](kcl/pow)
* [`profileStart`](kcl/profileStart)
* [`profileStartX`](kcl/profileStartX)
* [`profileStartY`](kcl/profileStartY)
* [`push`](kcl/push)
* [`reduce`](kcl/reduce)
* [`rem`](kcl/rem)
* [`revolve`](kcl/revolve)
* [`round`](kcl/round)
* [`segAng`](kcl/segAng)
* [`segEnd`](kcl/segEnd)
* [`segEndX`](kcl/segEndX)
* [`segEndY`](kcl/segEndY)
* [`segLen`](kcl/segLen)
* [`segStart`](kcl/segStart)
* [`segStartX`](kcl/segStartX)
* [`segStartY`](kcl/segStartY)
* [`shell`](kcl/shell)
* [`sqrt`](kcl/sqrt)
* [`startProfileAt`](kcl/startProfileAt)
* [`startSketchOn`](kcl/startSketchOn)
* [`sweep`](kcl/sweep)
* [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc)
* [`tangentialArcTo`](kcl/tangentialArcTo)
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`xLine`](kcl/xLine)
* [`xLineTo`](kcl/xLineTo)
* [`yLine`](kcl/yLine)
* [`yLineTo`](kcl/yLineTo)
* [`yd`](kcl/yd)
* **`std::math`**
* [`E`](kcl/const_std-math-E)
* [`PI`](kcl/const_std-math-PI)
* [`TAU`](kcl/const_std-math-TAU)
* [`cos`](kcl/std-math-cos)
* [`sin`](kcl/std-math-sin)
* [`tan`](kcl/std-math-tan)
* **`std::prelude`**
* [`HALF_TURN`](kcl/const_std-prelude-HALF_TURN)
* [`QUARTER_TURN`](kcl/const_std-prelude-QUARTER_TURN)
* [`THREE_QUARTER_TURN`](kcl/const_std-prelude-THREE_QUARTER_TURN)
* [`ZERO`](kcl/const_std-prelude-ZERO)

File diff suppressed because one or more lines are too long

View File

@ -25,7 +25,7 @@ loft(sketches: [Sketch], v_degree: NonZeroU32, bez_approximate_rational: bool, b
### Returns
[`Solid`](/docs/kcl/types/Solid) - An solid is a collection of extrude surfaces.
[`Solid`](/docs/kcl/types/Solid) - A solid is a collection of extrude surfaces.
### Examples
@ -95,10 +95,10 @@ circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
loft(
[
squareSketch,
circleSketch0,
circleSketch1
],
squareSketch,
circleSketch0,
circleSketch1
],
baseCurveIndex = 0,
bezApproximateRational = false,
tolerance = 0.000001,

View File

@ -9,7 +9,7 @@ Offset a plane by a distance along its normal.
For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it.
```js
offsetPlane(std_plane: StandardPlane, offset: number) -> Plane
offsetPlane(plane: PlaneData, offset: number) -> Plane
```
@ -17,7 +17,7 @@ offsetPlane(std_plane: StandardPlane, offset: number) -> Plane
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `std_plane` | [`StandardPlane`](/docs/kcl/types/StandardPlane) | Which standard plane (e.g. XY) should this new plane be created from? | Yes |
| `plane` | [`PlaneData`](/docs/kcl/types/PlaneData) | The plane (e.g. 'XY') which this new plane is created from. | Yes |
| `offset` | `number` | Distance from the standard plane this new plane will be created at. | Yes |
### Returns

View File

@ -4,9 +4,11 @@ excerpt: "Return the value of `pi`. Archimedes constant (π)."
layout: manual
---
**WARNING:** This function is deprecated.
Return the value of `pi`. Archimedes constant (π).
**DEPRECATED** use the constant PI
```js
pi() -> number

View File

@ -76,7 +76,7 @@ assertEqual(sum, 6, 0.00001, "1 + 2 + 3 summed is 6")
// Declare a function that sketches a decagon.
fn decagon(radius) {
// Each side of the decagon is turned this many degrees from the previous angle.
stepAngle = 1 / 10 * tau()
stepAngle = 1 / 10 * TAU
// Start the decagon sketch at this point.
startOfDecagonSketch = startSketchOn('XY')
@ -97,7 +97,7 @@ fn decagon(radius) {
/* The `decagon` above is basically like this pseudo-code:
fn decagon(radius):
stepAngle = (1/10) * tau()
stepAngle = (1/10) * TAU
plane = startSketchOn('XY')
startOfDecagonSketch = startProfileAt([(cos(0)*radius), (sin(0) * radius)], plane)

View File

@ -24,7 +24,7 @@ revolve(data: RevolveData, sketch: Sketch) -> Solid
### Returns
[`Solid`](/docs/kcl/types/Solid) - An solid is a collection of extrude surfaces.
[`Solid`](/docs/kcl/types/Solid) - A solid is a collection of extrude surfaces.
### Examples

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,15 @@ layout: manual
Start a new 2-dimensional sketch on a specific plane or face.
### Sketch on Face Behavior
There are some important behaviors to understand when sketching on a face:
The resulting sketch will _include_ the face and thus Solid that was sketched on. So say you were to export the resulting Sketch / Solid from a sketch on a face, you would get both the artifact of the sketch on the face and the parent face / Solid itself.
This is important to understand because if you were to then sketch on the resulting Solid, it would again include the face and parent Solid that was sketched on. This could go on indefinitely.
The point is if you want to export the result of a sketch on a face, you only need to export the final Solid that was created from the sketch on the face, since it will include all the parent faces and Solids.
```js
startSketchOn(data: SketchData, tag?: FaceTag) -> SketchSurface

44
docs/kcl/std-math-cos.md Normal file

File diff suppressed because one or more lines are too long

44
docs/kcl/std-math-sin.md Normal file

File diff suppressed because one or more lines are too long

44
docs/kcl/std-math-tan.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ sweep(sketch: Sketch, path: SweepPath, sectional?: bool, tolerance?: number) ->
### Returns
[`Solid`](/docs/kcl/types/Solid) - An solid is a collection of extrude surfaces.
[`Solid`](/docs/kcl/types/Solid) - A solid is a collection of extrude surfaces.
### Examples

File diff suppressed because one or more lines are too long

View File

@ -4,9 +4,11 @@ excerpt: "Return the value of `tau`. The full circle constant (τ). Equal to 2π
layout: manual
---
**WARNING:** This function is deprecated.
Return the value of `tau`. The full circle constant (τ). Equal to 2π.
**DEPRECATED** use the constant TAU
```js
tau() -> number

View File

@ -266,10 +266,10 @@ myRect = rect([20, 0])
myRect
|> extrude(10, %)
|> fillet({
|> fillet(
radius = 0.5,
tags = [myRect.tags.rectangleSegmentA001]
}, %)
)
```
See how we use the tag `rectangleSegmentA001` in the `fillet` function outside

View File

@ -18,6 +18,7 @@ A base path.
|----------|------|-------------|----------|
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |

View File

@ -1,9 +1,10 @@
---
title: "EnvironmentRef"
excerpt: ""
excerpt: "An index pointing to a snapshot within a specific (unspecified) environment."
layout: manual
---
An index pointing to a snapshot within a specific (unspecified) environment.
[`SnapshotRef`](/docs/kcl/types/SnapshotRef)

View File

@ -28,7 +28,7 @@ An extrude plane.
| `faceId` |`string`| The face id for the extrude plane. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |`string`| The id of the geometry. | No |
| `sourceRange` |`SourceRange`| The source range. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
----
@ -48,7 +48,7 @@ An extruded arc.
| `faceId` |`string`| The face id for the extrude plane. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |`string`| The id of the geometry. | No |
| `sourceRange` |`SourceRange`| The source range. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
----
@ -68,7 +68,7 @@ Geometry metadata.
| `faceId` |`string`| The id for the chamfer surface. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |`string`| The id of the geometry. | No |
| `sourceRange` |`SourceRange`| The source range. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
----
@ -88,7 +88,7 @@ Geometry metadata.
| `faceId` |`string`| The id for the fillet surface. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |`string`| The id of the geometry. | No |
| `sourceRange` |`SourceRange`| The source range. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
----

View File

@ -23,7 +23,7 @@ A face.
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A face. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -11,7 +11,6 @@ A tag for a face.
**This schema accepts any of the following:**
A tag for a face.
[`StartOrEnd`](/docs/kcl/types/StartOrEnd)

View File

@ -17,6 +17,6 @@ Geometry metadata.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |`string`| The id of the geometry. | No |
| `sourceRange` |`SourceRange`| The source range. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |

View File

@ -21,7 +21,7 @@ A helix.
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A helix. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -21,7 +21,7 @@ A helix.
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A helix. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -59,7 +59,7 @@ Any KCL value.
|----------|------|-------------|----------|
| `type` |enum: `Number`| | No |
| `value` |`number`| | No |
| `ty` |[`NumericType`](/docs/kcl/types/NumericType)| Any KCL value. | No |
| `ty` |[`NumericType`](/docs/kcl/types/NumericType)| | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
@ -164,7 +164,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Plane`](/docs/kcl/types/Plane)| | No |
| `value` |[`Plane`](/docs/kcl/types/Plane)| Any KCL value. | No |
| `value` |[`Plane`](/docs/kcl/types/Plane)| A plane. | No |
----
@ -180,7 +180,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Face`](/docs/kcl/types/Face)| | No |
| `value` |[`Face`](/docs/kcl/types/Face)| Any KCL value. | No |
| `value` |[`Face`](/docs/kcl/types/Face)| A face. | No |
----
@ -196,7 +196,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Sketch`](/docs/kcl/types/Sketch)| | No |
| `value` |[`Sketch`](/docs/kcl/types/Sketch)| Any KCL value. | No |
| `value` |[`Sketch`](/docs/kcl/types/Sketch)| A sketch is a collection of paths. | No |
----
@ -228,7 +228,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Solid`](/docs/kcl/types/Solid)| | No |
| `value` |[`Solid`](/docs/kcl/types/Solid)| Any KCL value. | No |
| `value` |[`Solid`](/docs/kcl/types/Solid)| A solid is a collection of extrude surfaces. | No |
----
@ -260,7 +260,7 @@ Any KCL value.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No |
| `value` |[`Helix`](/docs/kcl/types/Helix)| Any KCL value. | No |
| `value` |[`Helix`](/docs/kcl/types/Helix)| A helix. | No |
----
@ -295,7 +295,7 @@ Data for an imported geometry.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Function`| | No |
| `memory` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| Any KCL value. | No |
| `memory` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
@ -312,7 +312,7 @@ Data for an imported geometry.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Module`| | No |
| `value` |[`ModuleId`](/docs/kcl/types/ModuleId)| Any KCL value. | No |
| `value` |[`ModuleId`](/docs/kcl/types/ModuleId)| Identifier of a source file. Uses a u32 to keep the size small. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
@ -329,7 +329,7 @@ Data for an imported geometry.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`KclNone`](/docs/kcl/types/KclNone)| | No |
| `value` |[`KclNone`](/docs/kcl/types/KclNone)| Any KCL value. | No |
| `value` |[`KclNone`](/docs/kcl/types/KclNone)| KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application). | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -16,6 +16,6 @@ Metadata.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `sourceRange` |`SourceRange`| The source range. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |

View File

@ -33,6 +33,7 @@ layout: manual
----
A unit of length.
**Type:** `object`
@ -140,6 +141,7 @@ layout: manual
----
A unit of angle.
**Type:** `object`
@ -209,8 +211,8 @@ layout: manual
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Default`| | No |
| `len` |[`UnitLen`](/docs/kcl/types/UnitLen)| | No |
| `angle` |[`UnitAngle`](/docs/kcl/types/UnitAngle)| | No |
| `len` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `angle` |[`UnitAngle`](/docs/kcl/types/UnitAngle)| A unit of angle. | No |
----

View File

@ -27,6 +27,7 @@ A path that goes to a point.
| `type` |enum: `ToPoint`| | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -49,6 +50,7 @@ A arc that is tangential to the last path segment that goes to a point
| `ccw` |`boolean`| arc's direction | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -71,6 +73,7 @@ A arc that is tangential to the last path segment
| `ccw` |`boolean`| arc's direction | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -94,6 +97,7 @@ a complete arc
| `ccw` |`boolean`| arc's direction This is used to compute the tangential angle. | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -117,6 +121,7 @@ A base path.
| `p3` |`[number, number]`| Point 3 of the circle | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -138,6 +143,7 @@ A path that is horizontal.
| `x` |`number`| The x coordinate. | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -160,6 +166,7 @@ An angled line to.
| `y` |`number`| The y coordinate. | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -180,6 +187,7 @@ A base path.
| `type` |enum: `Base`| | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
@ -203,6 +211,7 @@ A circular arc, not necessarily tangential to the current point.
| `ccw` |`boolean`| True if the arc is counterclockwise. | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |

View File

@ -18,12 +18,12 @@ A plane.
|----------|------|-------------|----------|
| `id` |`string`| The id of the plane. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A plane. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Type for a plane. | No |
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A plane. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -17,6 +17,6 @@ Data for polar coordinates.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `angle` |`number`| The angle of the line (in degrees). | No |
| `length` |`number`| The length of the line. | No |
| `length` |[`TyF64`](/docs/kcl/types/TyF64)| The length of the line. | No |

View File

@ -6,6 +6,40 @@ layout: manual
A sketch is a collection of paths.
When you define a sketch to a variable like:
```kcl
mySketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
```
The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past tense, because the engine has already executed the commands to create the sketch.
The previous sketch commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the sketch any time you call it, you can use a function.
```kcl
fn createSketch() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
}
```
Now, every time you call `createSketch()`, the commands will be executed and a new sketch will be created.
When you assign the result of `createSketch()` to a variable (`mySketch = createSketch()`), you are assigning the executed sketch to that variable. Meaning that the sketch `mySketch` will not be executed again.
You can still execute _new_ commands on the sketch like `extrude`, `revolve`, `loft`, etc. and the sketch will be updated.
**Type:** `object`
@ -23,7 +57,7 @@ A sketch is a collection of paths.
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |`string`| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch is a collection of paths. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -11,7 +11,7 @@ Data for start sketch on. You can start a sketch on a plane or an solid.
**This schema accepts any of the following:**
Data for start sketch on. You can start a sketch on a plane or an solid.
Orientation data that can be used to construct a plane, not a plane in itself.
[`PlaneData`](/docs/kcl/types/PlaneData)
@ -23,7 +23,7 @@ Data for start sketch on. You can start a sketch on a plane or an solid.
----
Data for start sketch on. You can start a sketch on a plane or an solid.
A plane.
[`Plane`](/docs/kcl/types/Plane)
@ -35,7 +35,43 @@ Data for start sketch on. You can start a sketch on a plane or an solid.
----
Data for start sketch on. You can start a sketch on a plane or an solid.
A solid is a collection of extrude surfaces.
When you define a solid to a variable like:
```kcl
myPart = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
|> extrude(length = 6)
```
The `myPart` variable will be an executed [`Solid`](/docs/kcl/types/Solid) object. Executed being past tense, because the engine has already executed the commands to create the solid.
The previous solid commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the solid any time you call it, you can use a function.
```kcl
fn createPart() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
|> extrude(length = 6)
}
```
Now, every time you call `createPart()`, the commands will be executed and a new solid will be created.
When you assign the result of `createPart()` to a variable (`myPart = createPart()`), you are assigning the executed solid to that variable. Meaning that the solid `myPart` will not be executed again.
You can still execute _new_ commands on the solid like `shell`, `fillet`, `chamfer`, etc. and the solid will be updated.
[`Solid`](/docs/kcl/types/Solid)

View File

@ -11,7 +11,7 @@ A sketch surface or a sketch.
**This schema accepts any of the following:**
A sketch surface or a sketch.
A sketch type.
[`SketchSurface`](/docs/kcl/types/SketchSurface)
@ -23,7 +23,41 @@ A sketch surface or a sketch.
----
A sketch surface or a sketch.
A sketch is a collection of paths.
When you define a sketch to a variable like:
```kcl
mySketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
```
The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past tense, because the engine has already executed the commands to create the sketch.
The previous sketch commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the sketch any time you call it, you can use a function.
```kcl
fn createSketch() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
}
```
Now, every time you call `createSketch()`, the commands will be executed and a new sketch will be created.
When you assign the result of `createSketch()` to a variable (`mySketch = createSketch()`), you are assigning the executed sketch to that variable. Meaning that the sketch `mySketch` will not be executed again.
You can still execute _new_ commands on the sketch like `extrude`, `revolve`, `loft`, etc. and the sketch will be updated.
[`Sketch`](/docs/kcl/types/Sketch)

View File

@ -14,6 +14,40 @@ A sketch or a group of sketches.
A sketch is a collection of paths.
When you define a sketch to a variable like:
```kcl
mySketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
```
The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past tense, because the engine has already executed the commands to create the sketch.
The previous sketch commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the sketch any time you call it, you can use a function.
```kcl
fn createSketch() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
}
```
Now, every time you call `createSketch()`, the commands will be executed and a new sketch will be created.
When you assign the result of `createSketch()` to a variable (`mySketch = createSketch()`), you are assigning the executed sketch to that variable. Meaning that the sketch `mySketch` will not be executed again.
You can still execute _new_ commands on the sketch like `extrude`, `revolve`, `loft`, etc. and the sketch will be updated.
**Type:** `object`
@ -32,7 +66,7 @@ A sketch is a collection of paths.
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |`string`| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch or a group of sketches. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -27,12 +27,12 @@ A plane.
| `type` |enum: `plane`| | No |
| `id` |`string`| The id of the plane. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A sketch type. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Type for a plane. | No |
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
@ -57,7 +57,7 @@ A face.
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |

View File

@ -1,10 +1,46 @@
---
title: "Solid"
excerpt: "An solid is a collection of extrude surfaces."
excerpt: "A solid is a collection of extrude surfaces."
layout: manual
---
An solid is a collection of extrude surfaces.
A solid is a collection of extrude surfaces.
When you define a solid to a variable like:
```kcl
myPart = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
|> extrude(length = 6)
```
The `myPart` variable will be an executed [`Solid`](/docs/kcl/types/Solid) object. Executed being past tense, because the engine has already executed the commands to create the solid.
The previous solid commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the solid any time you call it, you can use a function.
```kcl
fn createPart() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
|> extrude(length = 6)
}
```
Now, every time you call `createPart()`, the commands will be executed and a new solid will be created.
When you assign the result of `createPart()` to a variable (`myPart = createPart()`), you are assigning the executed solid to that variable. Meaning that the solid `myPart` will not be executed again.
You can still execute _new_ commands on the solid like `shell`, `fillet`, `chamfer`, etc. and the solid will be updated.
**Type:** `object`
@ -24,7 +60,7 @@ An solid is a collection of extrude surfaces.
| `startCapId` |`string`| The id of the extrusion start cap | No |
| `endCapId` |`string`| The id of the extrusion end cap | No |
| `edgeCuts` |`[` [`EdgeCut`](/docs/kcl/types/EdgeCut) `]`| Chamfers or fillets on this solid. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| An solid is a collection of extrude surfaces. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -12,7 +12,43 @@ A solid or a group of solids.
**This schema accepts exactly one of the following:**
An solid is a collection of extrude surfaces.
A solid is a collection of extrude surfaces.
When you define a solid to a variable like:
```kcl
myPart = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
|> extrude(length = 6)
```
The `myPart` variable will be an executed [`Solid`](/docs/kcl/types/Solid) object. Executed being past tense, because the engine has already executed the commands to create the solid.
The previous solid commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the solid any time you call it, you can use a function.
```kcl
fn createPart() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
|> extrude(length = 6)
}
```
Now, every time you call `createPart()`, the commands will be executed and a new solid will be created.
When you assign the result of `createPart()` to a variable (`myPart = createPart()`), you are assigning the executed solid to that variable. Meaning that the solid `myPart` will not be executed again.
You can still execute _new_ commands on the solid like `shell`, `fillet`, `chamfer`, etc. and the solid will be updated.
**Type:** `object`
@ -33,7 +69,7 @@ An solid is a collection of extrude surfaces.
| `startCapId` |`string`| The id of the extrusion start cap | No |
| `endCapId` |`string`| The id of the extrusion end cap | No |
| `edgeCuts` |`[` [`EdgeCut`](/docs/kcl/types/EdgeCut) `]`| Chamfers or fillets on this solid. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A solid or a group of solids. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -0,0 +1,15 @@
---
title: "SourceRange"
excerpt: ""
layout: manual
---
**Type:** `integer` (`uint`)

View File

@ -1,90 +0,0 @@
---
title: "StandardPlane"
excerpt: "One of the standard planes."
layout: manual
---
One of the standard planes.
**This schema accepts exactly one of the following:**
The XY plane.
**enum:** `XY`
----
The opposite side of the XY plane.
**enum:** `-XY`
----
The XZ plane.
**enum:** `XZ`
----
The opposite side of the XZ plane.
**enum:** `-XZ`
----
The YZ plane.
**enum:** `YZ`
----
The opposite side of the YZ plane.
**enum:** `-YZ`
----

View File

@ -11,7 +11,41 @@ A path to sweep along.
**This schema accepts any of the following:**
A path to sweep along.
A sketch is a collection of paths.
When you define a sketch to a variable like:
```kcl
mySketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
```
The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past tense, because the engine has already executed the commands to create the sketch.
The previous sketch commands will never be executed again, in this case.
If you would like to encapsulate the commands to create the sketch any time you call it, you can use a function.
```kcl
fn createSketch() {
return startSketchOn('XY')
|> startProfileAt([-12, 12], %)
|> line(end = [24, 0])
|> line(end = [0, -24])
|> line(end = [-24, 0])
|> close()
}
```
Now, every time you call `createSketch()`, the commands will be executed and a new sketch will be created.
When you assign the result of `createSketch()` to a variable (`mySketch = createSketch()`), you are assigning the executed sketch to that variable. Meaning that the sketch `mySketch` will not be executed again.
You can still execute _new_ commands on the sketch like `extrude`, `revolve`, `loft`, etc. and the sketch will be updated.
[`Sketch`](/docs/kcl/types/Sketch)
@ -23,7 +57,7 @@ A path to sweep along.
----
A path to sweep along.
A helix.
[`Helix`](/docs/kcl/types/Helix)

21
docs/kcl/types/TyF64.md Normal file
View File

@ -0,0 +1,21 @@
---
title: "TyF64"
excerpt: ""
layout: manual
---
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `n` |`number`| | No |
| `ty` |[`NumericType`](/docs/kcl/types/NumericType)| | No |

View File

@ -1,9 +1,10 @@
---
title: "UnitAngle"
excerpt: ""
excerpt: "A unit of angle."
layout: manual
---
A unit of angle.

View File

@ -1,9 +1,10 @@
---
title: "UnitLen"
excerpt: ""
excerpt: "A unit of length."
layout: manual
---
A unit of length.

View File

@ -82,7 +82,7 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('Enter') // submit
await page.waitForTimeout(100)
await expect(page.locator('.cm-activeLine')).toContainText(
`fillet({ radius = ${KCL_DEFAULT_LENGTH}, tags = [seg01] }, %)`
`fillet( radius = ${KCL_DEFAULT_LENGTH}, tags = [seg01] )`
)
})

View File

@ -13,8 +13,8 @@ import {
import * as TOML from '@iarna/toml'
import { expectPixelColor } from './fixtures/sceneFixture'
// Because onboarding relies on an app setting we need to set it as incompletel
// for all these tests.
// Because our default test settings have the onboardingStatus set to 'dismissed',
// we must set it to empty for the tests where we want to see the onboarding immediately.
test.describe('Onboarding tests', () => {
test(
@ -22,7 +22,7 @@ test.describe('Onboarding tests', () => {
{
appSettings: {
app: {
onboardingStatus: 'incomplete',
onboardingStatus: '',
},
},
cleanProjectDir: true,
@ -63,7 +63,7 @@ test.describe('Onboarding tests', () => {
tag: '@electron',
appSettings: {
app: {
onboardingStatus: 'incomplete',
onboardingStatus: '',
},
},
cleanProjectDir: true,
@ -106,11 +106,6 @@ test.describe('Onboarding tests', () => {
test(
'Code resets after confirmation',
{
appSettings: {
app: {
onboardingStatus: 'incomplete',
},
},
cleanProjectDir: true,
},
async ({ context, page, homePage }) => {
@ -158,7 +153,7 @@ test.describe('Onboarding tests', () => {
{
appSettings: {
app: {
onboardingStatus: 'incomplete',
onboardingStatus: '',
},
},
},
@ -319,7 +314,7 @@ test.describe('Onboarding tests', () => {
{
appSettings: {
app: {
onboardingStatus: 'incomplete',
onboardingStatus: '',
},
},
cleanProjectDir: true,
@ -392,7 +387,7 @@ test.describe('Onboarding tests', () => {
{
appSettings: {
app: {
onboardingStatus: 'incomplete',
onboardingStatus: '',
},
},
cleanProjectDir: true,

View File

@ -5,6 +5,7 @@ import { ToolbarFixture } from './fixtures/toolbarFixture'
import fs from 'node:fs/promises'
import path from 'node:path'
import { getUtils } from './test-utils'
import { Locator } from '@playwright/test'
// test file is for testing point an click code gen functionality that's not sketch mode related
@ -210,12 +211,13 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
cameraPos: { x: 16020, y: -2000, z: 10500 },
cameraTarget: { x: -150, y: -4500, z: -80 },
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
chamfer({length = 30,tags = [
chamfer(length = 30,tags = [
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02),
getOppositeEdge(seg01)
]}, %)`,
],
)`,
afterChamferSelectSnippet:
'sketch002 = startSketchOn(extrude001, seg03)',
@ -235,14 +237,14 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
beforeChamferSnippet: `angledLine([
segAng(rectangleSegmentA001) - 90,
217.26
], %, $seg01)chamfer({
], %, $seg01)chamfer(
length = 30,
tags = [
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02)
]
}, %)`,
)`,
afterChamferSelectSnippet:
'sketch003 = startSketchOn(extrude001, seg04)',
@ -259,13 +261,13 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
clickCoords: { x: 677, y: 87 },
cameraPos: { x: -6200, y: 1500, z: 6200 },
cameraTarget: { x: 8300, y: 1100, z: 4800 },
beforeChamferSnippet: `angledLine([0, 268.43], %, $rectangleSegmentA001)chamfer({
beforeChamferSnippet: `angledLine([0, 268.43], %, $rectangleSegmentA001)chamfer(
length = 30,
tags = [
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02)
]
}, %)`,
)`,
afterChamferSelectSnippet:
'sketch004 = startSketchOn(extrude001, seg05)',
afterRectangle1stClickSnippet:
@ -281,10 +283,9 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
clickCoords: { x: 620, y: 300 },
cameraPos: { x: -1100, y: -7700, z: 1600 },
cameraTarget: { x: 1450, y: 670, z: 4000 },
beforeChamferSnippet: `chamfer({
length = 30,
tags = [getNextAdjacentEdge(yo)]
}, %)`,
beforeChamferSnippet: `chamfer(length = 30, tags = [getNextAdjacentEdge(yo)])`,
beforeChamferSnippetEnd:
'|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)])',
afterChamferSelectSnippet:
'sketch005 = startSketchOn(extrude001, seg06)',
afterRectangle1stClickSnippet:
@ -312,31 +313,16 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|> close()
extrude001 = extrude(sketch001, length = 100)
|> chamfer({
length = 30,
tags = [getOppositeEdge(seg01)]
}, %, $seg03)
|> chamfer({ length = 30, tags = [seg01] }, %, $seg04)
|> chamfer({
length = 30,
tags = [getNextAdjacentEdge(seg02)]
}, %, $seg05)
|> chamfer({
length = 30,
tags = [getNextAdjacentEdge(yo)]
}, %, $seg06)
|> chamfer(length = 30, tags = [getOppositeEdge(seg01)], tag = $seg03)
|> chamfer(length = 30, tags = [seg01], tag = $seg04)
|> chamfer(length = 30, tags = [getNextAdjacentEdge(seg02)], tag = $seg05)
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
sketch005 = startSketchOn(extrude001, seg06)
profile004 = startProfileAt([-23.43, 19.69], sketch005)
profile004=startProfileAt([-23.43,19.69], sketch005)
|> angledLine([0, 9.1], %, $rectangleSegmentA005)
|> angledLine([
segAng(rectangleSegmentA005) - 90,
84.07
], %)
|> angledLine([
segAng(rectangleSegmentA005),
-segLen(rectangleSegmentA005)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> angledLine([segAng(rectangleSegmentA005) - 90, 84.07], %)
|> angledLine([segAng(rectangleSegmentA005), -segLen(rectangleSegmentA005)], %)
|> line(endAbsolute=[profileStartX(%), profileStartY(%)])
|> close()
sketch004 = startSketchOn(extrude001, seg05)
profile003 = startProfileAt([82.57, 322.96], sketch004)
@ -377,7 +363,6 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
`,
{ shouldNormalise: true }
)
@ -414,13 +399,13 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
cameraPos: { x: 16020, y: -2000, z: 10500 },
cameraTarget: { x: -150, y: -4500, z: -80 },
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
chamfer({length=30,tags=[
chamfer(extrude001,length=30,tags=[
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02),
getOppositeEdge(seg01)
]}, extrude001)`,
beforeChamferSnippetEnd: '}, extrude001)',
getOppositeEdge(seg01),
])`,
beforeChamferSnippetEnd: ')',
afterChamferSelectSnippet:
'sketch002 = startSketchOn(extrude001, seg03)',
afterRectangle1stClickSnippet:
@ -446,18 +431,20 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|> close()
extrude001 = extrude(sketch001, length = 100)
chamf = chamfer({
chamf = chamfer(
extrude001,
length = 30,
tags = [getOppositeEdge(seg01)]
}, extrude001, $seg03)
|> chamfer({
tags = [getOppositeEdge(seg01)],
tag = $seg03,
)
|> chamfer(
length = 30,
tags = [
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02)
]
}, %)
],
)
sketch002 = startSketchOn(extrude001, seg03)
profile001 = startProfileAt([205.96, 254.59], sketch002)
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
@ -469,7 +456,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
segAng(rectangleSegmentA002),
-segLen(rectangleSegmentA002)
], %)
|> line(endAbsolute=[profileStartX(%), profileStartY(%)])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
`,
{ shouldNormalise: true }
@ -1491,9 +1478,9 @@ sketch002 = startSketchOn('XZ')
|> close()
extrude001 = extrude(sketch001, length = -12)
`
const firstFilletDeclaration = 'fillet({ radius = 5, tags = [seg01] }, %)'
const firstFilletDeclaration = 'fillet(radius = 5, tags = [seg01])'
const secondFilletDeclaration =
'fillet({ radius = 5, tags = [getOppositeEdge(seg01)] }, %)'
'fillet(radius = 5, tags = [getOppositeEdge(seg01)])'
// Locators
const firstEdgeLocation = { x: 600, y: 193 }
@ -1593,7 +1580,7 @@ extrude001 = extrude(sketch001, length = -12)
await editor.expectEditor.toContain(firstFilletDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: ['|>fillet({radius=5,tags=[seg01]},%)'],
activeLines: ['|> fillet(radius = 5, tags = [seg01])'],
highlightedCode: '',
})
})
@ -1673,7 +1660,7 @@ extrude001 = extrude(sketch001, length = -12)
await editor.expectEditor.toContain(secondFilletDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: ['radius=5,'],
activeLines: ['|>fillet(radius=5,tags=[getOppositeEdge(seg01)])'],
highlightedCode: '',
})
})
@ -1725,18 +1712,17 @@ extrude001 = extrude(sketch001, length = -12)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|> close()
extrude001 = extrude(sketch001, length = -12)
|> fillet({ radius = 5, tags = [seg01] }, %) // fillet01
|> fillet({ radius = 5, tags = [seg02] }, %) // fillet02
fillet03 = fillet({ radius = 5, tags = [getOppositeEdge(seg01)]}, extrude001)
fillet04 = fillet({ radius = 5, tags = [getOppositeEdge(seg02)]}, extrude001)
|> fillet(radius = 5, tags = [seg01]) // fillet01
|> fillet(radius = 5, tags = [seg02]) // fillet02
fillet03 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg01)])
fillet04 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg02)])
`
const pipedFilletDeclaration = 'fillet({ radius = 5, tags = [seg01] }, %)'
const secondPipedFilletDeclaration =
'fillet({ radius = 5, tags = [seg02] }, %)'
const pipedFilletDeclaration = 'fillet(radius = 5, tags = [seg01])'
const secondPipedFilletDeclaration = 'fillet(radius = 5, tags = [seg02])'
const standaloneFilletDeclaration =
'fillet03 = fillet({ radius = 5, tags = [getOppositeEdge(seg01)]}, extrude001)'
'fillet03 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg01)])'
const secondStandaloneFilletDeclaration =
'fillet04 = fillet({ radius = 5, tags = [getOppositeEdge(seg02)]}, extrude001)'
'fillet04 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg02)])'
// Locators
const pipedFilletEdgeLocation = { x: 600, y: 193 }
@ -1870,9 +1856,9 @@ fillet04 = fillet({ radius = 5, tags = [getOppositeEdge(seg02)]}, extrude001)
|> close()
extrude001 = extrude(sketch001, length = -12)
`
const firstChamferDeclaration = 'chamfer({ length = 5, tags = [seg01] }, %)'
const firstChamferDeclaration = 'chamfer(length = 5, tags = [seg01])'
const secondChamferDeclaration =
'chamfer({ length = 5, tags = [getOppositeEdge(seg01)] }, %)'
'chamfer(length = 5, tags = [getOppositeEdge(seg01)])'
// Locators
const firstEdgeLocation = { x: 600, y: 193 }
@ -1963,7 +1949,7 @@ extrude001 = extrude(sketch001, length = -12)
await editor.expectEditor.toContain(firstChamferDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: ['|>chamfer({length=5,tags=[seg01]},%)'],
activeLines: ['|>chamfer(length=5,tags=[seg01])'],
highlightedCode: '',
})
})
@ -2047,7 +2033,7 @@ extrude001 = extrude(sketch001, length = -12)
await editor.expectEditor.toContain(secondChamferDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: ['length=5,'],
activeLines: ['|>chamfer(length=5,tags=[getOppositeEdge(seg01)])'],
highlightedCode: '',
})
})
@ -2095,18 +2081,17 @@ extrude001 = extrude(sketch001, length = -12)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|> close()
extrude001 = extrude(sketch001, length = -12)
|> chamfer({ length = 5, tags = [seg01] }, %) // chamfer01
|> chamfer({ length = 5, tags = [seg02] }, %) // chamfer02
chamfer03 = chamfer({ length = 5, tags = [getOppositeEdge(seg01)]}, extrude001)
chamfer04 = chamfer({ length = 5, tags = [getOppositeEdge(seg02)]}, extrude001)
|> chamfer(length = 5, tags = [seg01]) // chamfer01
|> chamfer(length = 5, tags = [seg02]) // chamfer02
chamfer03 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg01)])
chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])
`
const pipedChamferDeclaration = 'chamfer({ length = 5, tags = [seg01] }, %)'
const secondPipedChamferDeclaration =
'chamfer({ length = 5, tags = [seg02] }, %)'
const pipedChamferDeclaration = 'chamfer(length = 5, tags = [seg01])'
const secondPipedChamferDeclaration = 'chamfer(length = 5, tags = [seg02])'
const standaloneChamferDeclaration =
'chamfer03 = chamfer({ length = 5, tags = [getOppositeEdge(seg01)]}, extrude001)'
'chamfer03 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg01)])'
const secondStandaloneChamferDeclaration =
'chamfer04 = chamfer({ length = 5, tags = [getOppositeEdge(seg02)]}, extrude001)'
'chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])'
// Locators
const pipedChamferEdgeLocation = { x: 600, y: 193 }
@ -2506,6 +2491,94 @@ extrude002 = extrude(sketch002, length = 50)
})
})
const shellPointAndClickDeletionCases = [
{ shouldUseKeyboard: true },
{ shouldUseKeyboard: false },
]
shellPointAndClickDeletionCases.forEach(({ shouldUseKeyboard }) => {
test(`Shell point-and-click deletion (shouldUseKeyboard: ${shouldUseKeyboard})`, async ({
context,
page,
homePage,
scene,
editor,
toolbar,
cmdBar,
}) => {
const sketchCode = `sketch001 = startSketchOn('XY')
profile001 = startProfileAt([-20, 20], sketch001)
|> xLine(40, %)
|> yLine(-60, %)
|> xLine(-40, %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
`
const extrudeCode = `extrude001 = extrude(profile001, length = 40)
`
const shellCode = `shell001 = shell(extrude001, faces = ['end'], thickness = 5)
`
const initialCode = sketchCode + extrudeCode + shellCode
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
await toolbar.openPane('feature-tree')
// One dumb hardcoded screen pixel value
const testPoint = { x: 590, y: 400 }
const extrudeColor: [number, number, number] = [100, 100, 100]
const sketchColor: [number, number, number] = [140, 140, 140]
const defaultPlaneColor: [number, number, number] = [50, 50, 100]
const deleteOperation = async (operationButton: Locator) => {
if (shouldUseKeyboard) {
await operationButton.click({ button: 'left' })
await page.keyboard.press('Backspace')
} else {
await operationButton.click({ button: 'right' })
const editButton = page.getByTestId('context-menu-delete')
await editButton.click()
}
}
await test.step(`Look for the grey of the extrude shape`, async () => {
await scene.expectPixelColor(extrudeColor, testPoint, 20)
})
await test.step('Delete shell and confirm deletion', async () => {
const operationButton = await toolbar.getFeatureTreeOperation(
'Shell',
0
)
await deleteOperation(operationButton)
await scene.expectPixelColor(extrudeColor, testPoint, 20)
await editor.expectEditor.not.toContain(shellCode)
})
await test.step('Delete extrude and confirm deletion', async () => {
const operationButton = await toolbar.getFeatureTreeOperation(
'Extrude',
0
)
await deleteOperation(operationButton)
await editor.expectEditor.not.toContain(extrudeCode)
await scene.expectPixelColor(sketchColor, testPoint, 20)
})
await test.step('Delete sketch and confirm empty scene', async () => {
const operationButton = await toolbar.getFeatureTreeOperation(
'Sketch',
0
)
await deleteOperation(operationButton)
await editor.expectEditor.toContain('')
await scene.expectPixelColor(defaultPlaneColor, testPoint, 20)
})
})
})
test(`Shell dry-run validation rejects sweeps`, async ({
context,
page,

View File

@ -117,7 +117,7 @@ test(
test(
'open a file in a project works and renders, open another file in different project with errors, it should clear the scene',
{ tag: '@electron' },
async ({ context, page }, testInfo) => {
async ({ context, page, editor }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
@ -180,6 +180,11 @@ test(
await page.getByText('broken-code').click()
await page.waitForTimeout(2000)
await editor.scrollToText(
"|> line(end = [0, wallMountL], tag = 'outerEdge')"
)
// error in guter
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
@ -419,7 +424,7 @@ test(
test(
'when code with error first loads you get errors in console',
{ tag: '@electron' },
async ({ context, page }, testInfo) => {
async ({ context, page, editor }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(path.join(dir, 'broken-code'), { recursive: true })
await fsp.copyFile(
@ -429,16 +434,19 @@ test(
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await expect(page.getByText('broken-code')).toBeVisible()
await page.getByText('broken-code').click()
// Gotcha: You can not use scene.waitForExecutionDone() since the KCL code is going to fail
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
// Gotcha: Scroll to the text content in code mirror because CodeMirror lazy loads DOM content
await editor.scrollToText(
"|> line(end = [0, wallMountL], tag = 'outerEdge')"
)
// error in guter
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()

View File

@ -2029,9 +2029,6 @@ profile003 = circle({ center = [6.92, -4.2], radius = 3.16 }, sketch001)
await moveToClearToolBarPopover()
await pointOnSegment({ shouldDbClick: true })
await page.waitForTimeout(600)
await toolbar.lineBtn.click()
await page.waitForTimeout(100)
})
await test.step('select and delete code for a profile', async () => {})
@ -2049,7 +2046,9 @@ profile003 = circle({ center = [6.92, -4.2], radius = 3.16 }, sketch001)
await test.step('add random new var between profiles', async () => {
await page.keyboard.type('myVar = 5')
await page.keyboard.press('Enter')
await page.waitForTimeout(600)
// If this timeout isn't long enough, the test breaks.
// TODO: fix https://github.com/KittyCAD/modeling-app/issues/5437
await page.waitForTimeout(3_000)
})
await sketchIsDrawnProperly()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -358,9 +358,7 @@ test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => {
exact: true,
})
const userSettingsTab = page.getByRole('radio', { name: 'User' })
const mouseControlsSetting = page
.locator('#mouseControls')
.getByRole('combobox')
const mouseControlsSetting = () => page.locator('#camera-controls').first()
const mouseControlSuccesToast = page.getByText(
'Set mouse controls to "Solidworks"'
)
@ -390,7 +388,14 @@ test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => {
await settingsLink.click()
await expect(settingsDialogHeading).toBeVisible()
await userSettingsTab.click()
await mouseControlsSetting.selectOption({ label: 'Solidworks' })
const setting = mouseControlsSetting()
await expect(setting).toBeAttached()
await setting.scrollIntoViewIfNeeded()
await setting.selectOption({ label: 'Solidworks' })
await expect(setting, 'Setting value did not change').toHaveValue(
'Solidworks',
{ timeout: 120_000 }
)
await expect(mouseControlSuccesToast).toBeVisible()
await settingsCloseButton.click()
})

View File

@ -764,15 +764,15 @@ profile003 = startProfileAt([40.16, -120.48], sketch006)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|> close()
extrude001 = extrude(sketch001, length = 100)
|> chamfer({
|> chamfer(
length = 30,
tags = [
seg01,
getNextAdjacentEdge(yo),
getNextAdjacentEdge(seg02),
getOppositeEdge(seg01)
]
}, %)
],
)
`)
await expect(
page.getByTestId('model-state-indicator-execution-done')
@ -810,15 +810,15 @@ profile003 = startProfileAt([40.16, -120.48], sketch006)
await checkCodeAtHoverPosition(
'oppositeChamfer',
oppositeChamfer,
`angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)chamfer({length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)]},%)`,
'}, %)'
`angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)chamfer(length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)],)`,
' )'
)
await checkCodeAtHoverPosition(
'baseChamfer',
baseChamfer,
`angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)chamfer({length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)]},%)`,
'}, %)'
`angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)chamfer(length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)],)`,
' )'
)
await u.openAndClearDebugPanel()
@ -848,15 +848,15 @@ profile003 = startProfileAt([40.16, -120.48], sketch006)
await checkCodeAtHoverPosition(
'adjacentChamfer1',
adjacentChamfer1,
`line(endAbsolute=[profileStartX(%),profileStartY(%)],tag=$seg02)chamfer({length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)]},%)`,
'}, %)'
`line(endAbsolute=[profileStartX(%),profileStartY(%)],tag=$seg02)chamfer(length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)],)`,
' )'
)
await checkCodeAtHoverPosition(
'adjacentChamfer2',
adjacentChamfer2,
`angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)chamfer({length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)]},%)`,
'}, %)'
`angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)chamfer(length=30,tags=[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)],)`,
' )'
)
})
test("Extrude button should be disabled if there's no extrudable geometry when nothing is selected", async ({

View File

@ -633,6 +633,7 @@ test.describe('Testing settings', () => {
`Set default unit to "${unitOfMeasure}" as a user default`
)
await expect(toastMessage).toBeVisible()
await expect(toastMessage).not.toBeVisible()
})
}
await changeUnitOfMeasureInUserTab('in')
@ -945,4 +946,76 @@ fn cube`
).toBeVisible()
})
})
/**
* This test assumes that the default value of the "highlight edges" setting is "on".
*/
test(`Toggle stream settings multiple times`, async ({
page,
scene,
homePage,
context,
toolbar,
cmdBar,
}, testInfo) => {
await context.folderSetupFn(async (dir) => {
const projectDir = join(dir, 'project-000')
await fsp.mkdir(projectDir, { recursive: true })
await fsp.copyFile(
executorInputPath('cube.kcl'),
join(projectDir, 'main.kcl')
)
})
await test.step(`First snapshot`, async () => {
await homePage.openProject('project-000')
await toolbar.closePane('code')
await expect(toolbar.startSketchBtn).toBeEnabled({ timeout: 20_000 })
await scene.clickNoWhere()
})
const toast = (value: boolean) =>
page.getByText(
`Set highlight edges to "${String(value)}" as a user default`
)
const initialPath = testInfo.snapshotPath('toggle-settings-initial.png')
const initialScreenshot = await scene.streamWrapper.screenshot({
path: initialPath,
mask: [page.getByTestId('model-state-indicator')],
})
await test.step(`Toggle highlightEdges off`, async () => {
await cmdBar.openCmdBar()
await cmdBar.chooseCommand('Settings · modeling · highlight edges')
await cmdBar.selectOption({ name: 'off' }).click()
const falseToast = toast(false)
await expect(falseToast).toBeVisible()
await falseToast.waitFor({ state: 'detached' })
})
await expect(scene.streamWrapper).not.toHaveScreenshot(
'toggle-settings-initial.png',
{
maxDiffPixels: 15,
mask: [page.getByTestId('model-state-indicator')],
}
)
await test.step(`Toggle highlightEdges on`, async () => {
await cmdBar.openCmdBar()
await cmdBar.chooseCommand('Settings · modeling · highlight edges')
await cmdBar.selectOption({ name: 'on' }).click()
const trueToast = toast(true)
await expect(trueToast).toBeVisible()
await trueToast.waitFor({ state: 'detached' })
})
await expect(scene.streamWrapper).toHaveScreenshot(
'toggle-settings-initial.png',
{
maxDiffPixels: 15,
mask: [page.getByTestId('model-state-indicator')],
}
)
})
})

1
exp Normal file
View File

@ -0,0 +1 @@
sketch001=startSketchOn('XZ')|>startProfileAt([75.8,317.2],%)//[$startCapTag,$EndCapTag]|>angledLine([0,268.43],%,$rectangleSegmentA001)|>angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)|>angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)|>line(endAbsolute=[profileStartX(%),profileStartY(%)],tag=$seg02)|>close()extrude001=extrude(sketch001,length=100)|>chamfer(length=30,tags=[getOppositeEdge(seg01)],tag=$seg03)|>chamfer(length=30,tags=[seg01],tag=$seg04)|>chamfer(length=30,tags=[getNextAdjacentEdge(seg02)],tag=$seg05)|>chamfer(length=30,tags=[getNextAdjacentEdge(yo)],tag=$seg06)sketch004=startSketchOn(extrude001,seg05)profile003=startProfileAt([82.57,322.96],sketch004)|>angledLine([0,11.16],%,$rectangleSegmentA004)|>angledLine([segAng(rectangleSegmentA004)-90,103.07],%)|>angledLine([segAng(rectangleSegmentA004),-segLen(rectangleSegmentA004)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch003=startSketchOn(extrude001,seg04)profile002=startProfileAt([-209.64,255.28],sketch003)|>angledLine([0,11.56],%,$rectangleSegmentA003)|>angledLine([segAng(rectangleSegmentA003)-90,106.84],%)|>angledLine([segAng(rectangleSegmentA003),-segLen(rectangleSegmentA003)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch002=startSketchOn(extrude001,seg03)profile001=startProfileAt([205.96,254.59],sketch002)|>angledLine([0,11.39],%,$rectangleSegmentA002)|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()

1
got Normal file
View File

@ -0,0 +1 @@
sketch001=startSketchOn('XZ')|>startProfileAt([75.8,317.2],%)//[$startCapTag,$EndCapTag]|>angledLine([0,268.43],%,$rectangleSegmentA001)|>angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)|>angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)|>line(endAbsolute=[profileStartX(%),profileStartY(%)],tag=$seg02)|>close()extrude001=extrude(sketch001,length=100)|>chamfer(length=30,tags=[getOppositeEdge(seg01)],tag=$seg03)|>chamfer(length=30,tags=[seg01],tag=$seg04)|>chamfer(length=30,tags=[getNextAdjacentEdge(seg02)],tag=$seg05)|>chamfer(length=30,tags=[getNextAdjacentEdge(yo)],tag=$seg06)sketch005=startSketchOn(extrude001,seg06)profile004=startProfileAt([-23.43,19.69],sketch005)|>angledLine([0,9.1],%,$rectangleSegmentA005)|>angledLine([segAng(rectangleSegmentA005)-90,84.07],%)|>angledLine([segAng(rectangleSegmentA005),-segLen(rectangleSegmentA005)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch004=startSketchOn(extrude001,seg05)profile003=startProfileAt([82.57,322.96],sketch004)|>angledLine([0,11.16],%,$rectangleSegmentA004)|>angledLine([segAng(rectangleSegmentA004)-90,103.07],%)|>angledLine([segAng(rectangleSegmentA004),-segLen(rectangleSegmentA004)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch003=startSketchOn(extrude001,seg04)profile002=startProfileAt([-209.64,255.28],sketch003)|>angledLine([0,11.56],%,$rectangleSegmentA003)|>angledLine([segAng(rectangleSegmentA003)-90,106.84],%)|>angledLine([segAng(rectangleSegmentA003),-segLen(rectangleSegmentA003)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch002=startSketchOn(extrude001,seg03)profile001=startProfileAt([205.96,254.59],sketch002)|>angledLine([0,11.39],%,$rectangleSegmentA002)|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()

View File

@ -8,7 +8,7 @@
"email": "info@zoo.dev",
"url": "https://zoo.dev"
},
"description": "Edit CAD visually or with code",
"description": "Zoo Modeling App",
"main": ".vite/build/main.js",
"license": "MIT",
"dependencies": {
@ -85,7 +85,7 @@
"fmt": "prettier --write ./src *.ts *.json *.js ./e2e ./packages",
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages",
"fetch:wasm": "./get-latest-wasm-bundle.sh",
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/next/manifest.json",
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/achalmers/kw-fillet-chamfer/manifest.json",
"isomorphic-copy-wasm": "(copy src/wasm-lib/pkg/wasm_lib_bg.wasm public || cp src/wasm-lib/pkg/wasm_lib_bg.wasm public)",
"build:wasm-dev": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt",
"build:wasm": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings && cd ../.. && yarn isomorphic-copy-wasm && yarn fmt",

View File

@ -20,10 +20,14 @@ export const kclHighlight = styleTags({
LineComment: t.lineComment,
BlockComment: t.blockComment,
Shebang: t.meta,
AnnotationName: t.annotation,
PipeSubstitution: t.atom,
VariableDefinition: t.definition(t.variableName),
VariableName: t.variableName,
PropertyName: t.propertyName,
'AnnotationProperty/PropertyName': t.definition(t.propertyName),
'ObjectProperty/PropertyName': t.definition(t.propertyName),
'LabeledArgument/ArgumentLabel': t.definition(t.propertyName),
TagDeclarator: t.tagName,
'( )': t.paren,
'{ }': t.brace,

View File

@ -1,4 +1,11 @@
[
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "3d-boaty/main.kcl",
"multipleFiles": true,
"title": "3D Boaty",
"description": "This is a slight remix of Depep1's original 3D Boaty (https://www.printables.com/model/1141963-3d-boaty). This is a tool used for benchmarking 3D FDM printers for bed adhesion, overhangs, bridging and top surface quality. The name of this file is a bit of misnomer, the shape of the object is a typical park bench."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "80-20-rail/main.kcl",
@ -34,6 +41,13 @@
"title": "Car Wheel Assembly",
"description": "A car wheel assembly with a rotor, tire, and lug nuts."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "color-cube/main.kcl",
"multipleFiles": false,
"title": "Color Cube",
"description": "This is a color cube centered about the origin. It is used to help determine orientation in the scene."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "cycloidal-gear/main.kcl",

View File

@ -6,14 +6,12 @@ import { useHotkeys } from 'react-hotkeys-hook'
import { useLoaderData, useNavigate } from 'react-router-dom'
import { type IndexLoaderData } from 'lib/types'
import { PATHS } from 'lib/paths'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { onboardingPaths } from 'routes/Onboarding/paths'
import { useEngineConnectionSubscriptions } from 'hooks/useEngineConnectionSubscriptions'
import { codeManager, engineCommandManager } from 'lib/singletons'
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
import { isDesktop } from 'lib/isDesktop'
import { useLspContext } from 'components/LspProvider'
import { useRefreshSettings } from 'hooks/useRefreshSettings'
import { ModelingSidebar } from 'components/ModelingSidebar/ModelingSidebar'
import { LowerRightControls } from 'components/LowerRightControls'
import ModalContainer from 'react-modal-promise'
@ -30,6 +28,7 @@ import { useRouteLoaderData } from 'react-router-dom'
import { useEngineCommands } from 'components/EngineCommands'
import { commandBarActor } from 'machines/commandBarMachine'
import { useToken } from 'machines/appMachine'
import { useSettings } from 'machines/appMachine'
maybeWriteToDisk()
.then(() => {})
.catch(() => {})
@ -49,7 +48,6 @@ export function App() {
})
})
useRefreshSettings(PATHS.FILE + 'SETTINGS')
const navigate = useNavigate()
const filePath = useAbsoluteFilePath()
const { onProjectOpen } = useLspContext()
@ -71,7 +69,7 @@ export function App() {
useHotKeyListener()
const { settings } = useSettingsAuthContext()
const settings = useSettings()
const token = useToken()
const coreDumpManager = useMemo(
@ -81,7 +79,7 @@ export function App() {
const {
app: { onboardingStatus },
} = settings.context
} = settings
useHotkeys('backspace', (e) => {
e.preventDefault()

View File

@ -28,10 +28,8 @@ import {
fileLoader,
homeLoader,
onboardingRedirectLoader,
settingsLoader,
telemetryLoader,
} from 'lib/routeLoaders'
import SettingsAuthProvider from 'components/SettingsAuthProvider'
import LspProvider from 'components/LspProvider'
import { KclContextProvider } from 'lang/KclProvider'
import { ASK_TO_OPEN_QUERY_PARAM, BROWSER_PROJECT_NAME } from 'lib/constants'
@ -45,34 +43,28 @@ import { AppStateProvider } from 'AppState'
import { reportRejection } from 'lib/trap'
import { RouteProvider } from 'components/RouteProvider'
import { ProjectsContextProvider } from 'components/ProjectsContextProvider'
import { OpenInDesktopAppHandler } from 'components/OpenInDesktopAppHandler'
import { useToken } from 'machines/appMachine'
import { OpenInDesktopAppHandler } from 'components/OpenInDesktopAppHandler'
const createRouter = isDesktop() ? createHashRouter : createBrowserRouter
const router = createRouter([
{
loader: settingsLoader,
id: PATHS.INDEX,
// TODO: Re-evaluate if this is true
/* Make sure auth is the outermost provider or else we will have
* inefficient re-renders, use the react profiler to see. */
element: (
<OpenInDesktopAppHandler>
<RouteProvider>
<SettingsAuthProvider>
<LspProvider>
<ProjectsContextProvider>
<KclContextProvider>
<AppStateProvider>
<MachineManagerProvider>
<Outlet />
</MachineManagerProvider>
</AppStateProvider>
</KclContextProvider>
</ProjectsContextProvider>
</LspProvider>
</SettingsAuthProvider>
<LspProvider>
<ProjectsContextProvider>
<KclContextProvider>
<AppStateProvider>
<MachineManagerProvider>
<Outlet />
</MachineManagerProvider>
</AppStateProvider>
</KclContextProvider>
</ProjectsContextProvider>
</LspProvider>
</RouteProvider>
</OpenInDesktopAppHandler>
),
@ -120,7 +112,6 @@ const router = createRouter([
children: [
{
id: PATHS.FILE + 'SETTINGS',
loader: settingsLoader,
children: [
{
loader: onboardingRedirectLoader,
@ -166,11 +157,9 @@ const router = createRouter([
index: true,
element: <></>,
id: PATHS.HOME + 'SETTINGS',
loader: settingsLoader,
},
{
path: makeUrlPathRelative(PATHS.SETTINGS),
loader: settingsLoader,
element: <Settings />,
},
{

View File

@ -1335,21 +1335,34 @@ export async function letEngineAnimateAndSyncCamAfter(
engineCommandManager: EngineCommandManager,
entityId: string
) {
await engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'enable_sketch_mode',
adjust_camera: true,
animated: !isReducedMotion(),
ortho: true,
entity_id: entityId,
const enableSketchCmdId = uuidv4()
console.warn('ADAM: enableSketchMode promise has ID', enableSketchCmdId)
await engineCommandManager.sendSceneCommand(
{
type: 'modeling_cmd_req',
cmd_id: enableSketchCmdId,
cmd: {
type: 'enable_sketch_mode',
adjust_camera: true,
animated: !isReducedMotion(),
ortho: true,
entity_id: entityId,
},
},
})
// wait 600ms (animation takes 500, + 100 for safety)
await new Promise((resolve) =>
setTimeout(resolve, isReducedMotion() ? 100 : 600)
false,
// Callback triggers when the enable_sketch_mode finishes successfully.
(_whatever) => {
console.error('ADAM: Hello from the resolvedCb')
window.alert("G'day ADAM and Frank, enable_sketch_mode is done")
},
// Callback triggers when the enable_sketch_mode fails.
(_whatever) => {
console.error('ADAM: Hello from the rejectCb')
window.alert("G'day ADAM and Frank, enable_sketch_mode is FUCKING TOAST")
}
)
// TODO: Wait for one of the two callbacks above to finish.
await engineCommandManager.sendSceneCommand({
// CameraControls subscribes to default_camera_get_settings response events
// firing this at connection ensure the camera's are synced initially

View File

@ -2,7 +2,6 @@ import { useRef, useEffect, useState, useMemo, Fragment } from 'react'
import { useModelingContext } from 'hooks/useModelingContext'
import { cameraMouseDragGuards } from 'lib/cameraControls'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { ARROWHEAD, DEBUG_SHOW_BOTH_SCENES } from './sceneInfra'
import { ReactCameraProperties } from './CameraControls'
import { throttle, toSync } from 'lib/utils'
@ -48,6 +47,7 @@ import { ActionButton } from 'components/ActionButton'
import { err, reportRejection, trap } from 'lib/trap'
import { Node } from 'wasm-lib/kcl/bindings/Node'
import { commandBarActor } from 'machines/commandBarMachine'
import { useSettings } from 'machines/appMachine'
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
const [isCamMoving, setIsCamMoving] = useState(false)
@ -76,8 +76,8 @@ export const ClientSideScene = ({
cameraControls,
}: {
cameraControls: ReturnType<
typeof useSettingsAuthContext
>['settings']['context']['modeling']['mouseControls']['current']
typeof useSettings
>['modeling']['mouseControls']['current']
}) => {
const canvasRef = useRef<HTMLDivElement>(null)
const { state, send, context } = useModelingContext()
@ -179,10 +179,7 @@ const Overlays = () => {
// Set a large zIndex, the overlay for hover dropdown menu on line segments needs to render
// over the length labels on the line segments
return (
<div
className="absolute inset-0 pointer-events-none"
style={{ zIndex: '99999999' }}
>
<div className="absolute inset-0 pointer-events-none z-sketchOverlayDropdown">
{Object.entries(context.segmentOverlays)
.flatMap((a) =>
a[1].map((b) => ({ pathToNodeString: a[0], overlay: b }))

View File

@ -291,6 +291,7 @@ export class SceneInfra {
this.labelRenderer.domElement.style.position = 'absolute'
this.labelRenderer.domElement.style.top = '0px'
this.labelRenderer.domElement.style.pointerEvents = 'none'
this.labelRenderer.domElement.className = 'z-sketchSegmentIndicators'
window.addEventListener('resize', this.onWindowResize)
this.camControls = new CameraControls(

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