Compare commits

...

92 Commits

Author SHA1 Message Date
3c23cada8e Release KCL 80 (#7391) 2025-06-05 20:34:58 +00:00
81782b04ec Rename and reorder contributor guide sections (#7387) 2025-06-05 15:06:15 -04:00
9ade6676b7 Fix docs for loft (#7389) 2025-06-05 19:05:46 +00:00
86e5c37678 Make web end-to-end tests exclusive with desktop (#7388)
* Make web end-to-end tests exclusive with desktop

* Use double quotes to support Windows
2025-06-05 13:42:36 -04:00
8c36d742e5 Add mirror2d operations to Feature Tree (#7308)
* Add mirror2d operations

* Update output
2025-06-05 12:52:53 -04:00
f6a3a3d0cd Change to use nodePath instead of sourceRange for Operations (#7320)
* Add NodePath to operations

* Change to use nodePath to get pathToNode instead of sourceRange

* Add additional node path unit test

* Update output

* Fix import statement NodePaths

* Update output

* Factor into function
2025-06-05 12:24:34 -04:00
b5f81cb84a Run fmt (#7383) 2025-06-05 11:46:48 -04:00
4bb17c192f Stabilize multiprofile sketch test further (#7373)
* increase timeout after rectangle tool is clicked from 200ms -> 400ms

* Delay after each primitive mouse interaction

* Update snapshots

* Update snapshots

---------

Co-authored-by: jacebrowning <jacebrowning@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-06-05 11:28:40 -04:00
51ce55e782 Remove nested <button> elements (#7291)
* remove nested <button> elements to avoid dom warning about nested buttons

* keep using Popover.Button to allow popover functionality

* fmt

* match ShareButton margin to main branch to make snapshot tests happy
2025-06-05 17:24:04 +02:00
427d55d13e KCL: Optimization, ty Jon (#7379)
This avoids a clone
2025-06-05 08:34:16 -05:00
4575b32dbc KCL parser: Allow .prop or [index] to follow any expression (#7371)
Previously in a member expression like `foo.x` or `foo[3]`, `foo` had to be an identifier. You could not do something like `f().x` (and if you tried, you got a cryptic error). Rather than make the error better, we should just accept any expression to be the LHS of a member expression (aka its 'object').

This does knock our "parse lots of function calls" from 58 to 55 calls before it stack overflows. But I think it's fine, we'll address this in https://github.com/KittyCAD/modeling-app/pull/6226 when I get back to it.

Closes https://github.com/KittyCAD/modeling-app/issues/7273
2025-06-05 09:23:48 -04:00
9136fb0d1b KCL: Improve error messages for var referenced in own definition (#7374)
Jon pointed out that my new error message wasn't showing up in some
cases, and it should store/restore the previous var being defined.
2025-06-04 23:48:15 -05:00
33d5a9cdc1 Execution refactoring (#7376)
* Move import graph to execution

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

* Refactor artifact handling

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

* Refactor caching to separate global state from per-module state

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-06-05 15:56:43 +12:00
c25dfabc94 Stronger types and better error handling in executeMock (#7370)
This brings the `execute_mock` function into line with the `execute` function, which I tweaked in https://github.com/KittyCAD/modeling-app/pull/7351. Now mock execution, like real execution, will always return a properly-formatted KCL error, instead of any possible JS value.

Also, incidentally, I noticed that send_response always succeeds, so I changed it from Result<()> to void.
2025-06-04 18:24:24 -04:00
4502ad62b2 Fix vite warning (#7360)
Specifically this warning:
```
[vite] warning: This case clause will never be evaluated because it duplicates an earlier case clause
|      case 'angledLine':
|      case 'startProfile':
|      case 'arcTo':
|           ^
|        return fnName
|      default:
```
2025-06-04 17:08:06 -04:00
5235a731ba Move sketch functions to KCL; remove Rust decl dead code (#7335)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-06-04 15:41:01 -04:00
5ceb92d117 Try to avoid the black screen again & improve error messages (#7327)
* Fix the black screen of death

* fmt

* make check

* Clean up

* Fix up zoom to fit

* Change how emulateNetworkConditions work

* Do NOT use browser's offline/online mechanisms

* Fix test

* Improve network error messages

* Signal offline when failed event comes in

* Don't use logic on components that only want a loader

* Remove unnecessary pause state transition

---------

Co-authored-by: jacebrowning <jacebrowning@gmail.com>
2025-06-04 13:59:22 -04:00
ff92c73ac4 Update dependabot config (#7362) 2025-06-04 10:08:54 -04:00
bbb6fffbcc Allow edit for Translate and Rotate in Feature Tree (#7345)
* WIP: Wire up edit on transforms to the new feature tree standalone ops
Fixes #7338

* Clean up diff

* Oopsie
2025-06-04 09:35:01 -04:00
37fca0d1df #7326 Fix "Zoom to fit to shared model on web" test (#7328)
* fix test

* fix e2e test in another way so it doesnt break unit tests

* Cleanup

* Update src/hooks/useQueryParamEffects.ts

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

* hasAskToOpen should only be used if not in desktop

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-06-04 09:37:25 +02:00
e3694e4781 Fix crash while editing code while in sketch mode (#7284)
* Fix crash by checking bounds

* Add unit test
2025-06-04 12:10:09 +10:00
f97bdaf8b7 Release KCL 79 (#7347) 2025-06-03 22:04:56 -04:00
3f3693e12d Type ascription produces two incompatible fields (#7355)
# Symptoms

This code produces a big ugly confusing error in the frontend, see #7340.

# Root cause

I added a new test case, with an unknown type. In `ast.snap` under `body[0].declaration.init.ty` there two different `type` fields in the AST node for the type's name, and they have conflicting values Primitive and Identifier.

<img width="602" alt="Screenshot 2025-06-03 at 4 04 55 PM" src="https://github.com/user-attachments/assets/913a0fa0-3e8d-473f-bb64-003d44915be0" />

# Solution

Change the `enum PrimitiveType` variant from `Named(Node<Identifier>)` to `Named { name: Node<Identifier> }` so that the fields nest differently.

Now the error correctly points out to the user that the type `NotARealType` can't be found. Much better error message that shows the user the problem.

# Alternative solutions

Stop the duplicated JSON fields altogether. I tried this previously in https://github.com/KittyCAD/modeling-app/pull/4369 but it was very involved, and I didn't think it was worth it. Maybe I should reopen that PR and solve this properly.

Closes #7340
2025-06-03 20:05:40 -04:00
73660d1db8 Bump criterion from 0.5.1 to 0.6.0 (#7357) 2025-06-04 09:34:34 +10:00
c373f33507 KCL: Fix format 2025-06-04 09:04:35 +10:00
2dc76a71cc Stabilize test: "Can edit a sketch with multiple profiles, dragging segments to edit them, and adding one new profile" (#7356) 2025-06-03 18:20:06 -04:00
ce42966f2b Upgrade to Rust 1.87 (#7346)
I ignored some new clippy lints about large differences between enum variants.
We can always revisit these later (the compiler suggests boxing them so
that the enum variants are similar size)
2025-06-03 17:32:24 -04:00
b47b9c9613 KCL: Emit proper errors in unexpected edge cases (#7351)
There's some bug in the frontend or KCL somewhere, which results in the TypeScript frontend sending an AST (serialized to JSON) to the KCL executor, but the JSON cannot be deserialized into an AST. If this happens, it's a bug in ZDS, not a user error. 

The problem is that this sort of error will cause the frontend to silently stop rendering KCL, and it won't show the user any errors. They need to open up the console and look at the error there, and even if they do, it's hard to understand.

This PR changes how we report these unexpected errors due to bugs in ZDS. ZDS should not silently stop working, it should at least print a half-decent error like this:

<img width="527" alt="nicer error" src="https://github.com/user-attachments/assets/1bb37a64-0915-4472-849c-d146f397356b" />

## Fix

Right now, the wasm library exports a function `execute`. It previous returned an error as a String if one occurred. The frontend assumed this error string would be JSON that matched the schema `KclErrorWithOutputs`. This was not always true! For example, if something couldn't be serialized to JSON, we'd take the raw Serde error and stringify that. It wouldn't match `KclErrorWithOutputs`.

Now I've changed `execute` so that if it errors, it'll returns a JsValue not a string. So that's one check (can this string be deserialized into a JSON object) that can be removed -- it'll return a JSON object directly now. The next check is "does this JSON object conform to the KclErrorWithOutputs schema". To prove that's correct, I changed `execute` to be a thin wrapper around `fn execute_typed` which returns `Result<ExecOutcome, KclErrorWithOutputs>`. Now we know the error will be the right type.
2025-06-03 15:37:17 -05:00
2af2144f89 Add query parameter to skip the embedded "sign in" view (#7352)
Add query parameter to skip sign-in view if not necessary
2025-06-03 16:23:23 -04:00
bd37c488ee Fix trackball, finally add an E2E test for it (#7341)
* Fix orbit style setting not updating in camControls

* Break apart camera movement tests, add trackball to orbit one

* I don't think zoom was actually testing changes, this fixes that

* test refactor: pass in expected cam pos, not its inverse

* Lints

* Lint fix broke the test, fix fix

* Gah biome whyyy did you format other test names like that?
2025-06-03 14:56:19 -04:00
a3551e4b2f Bump csscolorparser from 0.7.0 to 0.7.2 (#7344) 2025-06-03 11:50:09 -05:00
d3979edb41 KCL: Better error message when using var in its own definition (#7339)
I thought I did this in https://github.com/KittyCAD/modeling-app/pull/7325, but I forgot to actually set the better message.

Actually fixes, for real this time, https://github.com/KittyCAD/modeling-app/issues/6072 this time.
2025-06-03 16:46:28 +00:00
095a7a575b Bump tokio-tungstenite from 0.24.0 to 0.26.2 (#7329) 2025-06-03 10:16:22 -05:00
b5c8ca05a5 Fix whitespace in updater toast (#7331)
pierremtb/adhoc/whitespace-fix-updater-toast
2025-06-03 10:15:42 -04:00
33f7badf41 point and click-ify mounting plate (#7287)
* point and click-ify mounting plate

* Update kcl-samples simulation test output

* Update public/kcl-samples/mounting-plate/main.kcl

* Update public/kcl-samples/mounting-plate/main.kcl

* fix

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-06-03 08:10:37 -04:00
569935c21f Move segment functions to KCL (#7333)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-06-03 15:15:51 +12:00
7680605085 KCL: Fix 'cryptic' error when referencing a variable in its own declaration (#7325)
Previously, `x = cos(x)` would just say "`x` is undefined". Now it says that `x` cannot be referenced in its own definition, try using a different variable instead.

To do this, I've added a new `Option<String>` field to the mod-local executor context, tracking the current variable declaration. This means cloning some strings, implying a small performance hit. I think it's fine, for the better diagnostics.

In the future we could refactor this to use a &str or store variable labels in stack-allocated strings like docs.rs/compact_str or something.

Closes https://github.com/KittyCAD/modeling-app/issues/6072
2025-06-02 18:25:55 -04:00
2bb6c74f42 Update error message after engine change (#7330) 2025-06-02 18:05:46 -04:00
faf4d42b6a Update getSketchExprsFromSelection to use codeRef.pathToNode (#6737) 2025-06-02 16:49:41 -04:00
8dd2a86191 Make sweep tests more point-and-click like and clean up pathToNode retrieval (#6963)
WIP: udpate sweep point-and-click tests and mess with pathToNode
Fixes #6952
2025-06-02 16:49:20 -04:00
13c4de77c3 Fix broken WASM test (#7324)
Previous PR (#7321) was set to automerge, but apparently the npm-unit-test
CI target doesn't block merges if it fails. Fixed now.
2025-06-02 15:56:49 -04:00
e29ee9d1ca KCL: Use named fields for KclError (#7321)
We've changed the unnamed field of `KclError` variants to a named called `details`.

To clarify: previously KCL errors looked like this:

```rust
pub enum KclError {
    Lexical(KclErrorDetails),
    Syntax(KclErrorDetails),
```

Now they look like this:

```rust
pub enum KclError {
    Lexical { details: KclErrorDetails },
    Syntax { details: KclErrorDetails },
}
```

This lets us more easily add fields to the errors. For example, in the UndefinedValue case, adding a field for what the undefined name was. This PR refactors the code to make my PR in https://github.com/KittyCAD/modeling-app/pull/7309 much easier.

Pure refactor, should not change any behaviour.
2025-06-02 14:30:57 -04:00
b7437e949a Update generated output to try to fix flakiness (#7323) 2025-06-02 13:36:41 -04:00
08781ff010 Add transform operations to the Feature Tree (#7307)
* Add transform operations

* Update output

* Add scale icon
2025-06-02 10:32:36 -04:00
eb79b1f746 #7227 Fix project not saving when dragging a segment (#7276)
* fix bug of not saving project when dragging a segment, add a test

* Update e2e/playwright/projects.spec.ts

Co-authored-by: Jace Browning <jacebrowning@gmail.com>

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
2025-06-02 09:28:23 +02:00
8df81b2753 Update URL in Discord Bot (#7306) 2025-05-30 14:36:45 -07:00
e75a604c64 Fix the link for plan upgrades (#7305) 2025-05-30 16:54:07 -04:00
0624e42822 Add more detail to close() docs (#7300)
* Add more detail to close() docs

* Run gen
2025-05-30 16:05:32 -04:00
1c07e8af5b Add hysteresis and EMA to ping to avoid flickering network badge (#7197)
* Don't use WEAK and yellow

* fmt && lint && tsc

* Fix up the rebase & dark mode colors

* Update src/hooks/useNetworkStatus.tsx

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

* Change Weak to Ok

* Change Connected to Strong

* fmt

* Sync selectors for start sketch

* Remove unused test-util brought back in a rebase

* Align the other OKs

* Add an else statement to overallState

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-30 15:50:05 -04:00
5fccaad0e7 KCL: Fix cryptic error on unexpected tokens in fn call (#7295)
This program:
```kcl
1
|> extrude(
  length=depth,
})
```

was giving this bad error:

```
unexpected token |>
```

Now it gives

```kcl
There was an unexpected }. Try removing it.
```

and it correctly puts the diagnostic on the extra }.

Fixes https://github.com/KittyCAD/modeling-app/issues/6126
2025-05-30 14:57:05 -04:00
a506f7f698 KCL: Fix cryptic error when missing commas between arguments (#7297)
Previously, this KCL

```
arc(
    endAbsolute = [0, 50]
    interiorAbsolute = [-50, 0]
)
```

gave the error `This argument has a label, but no value. Put some value after the equals sign`.

Now it gives this much better error `Missing comma between arguments, try adding a comma in`, and its source range (red underline) is on the whitespace which was missing a comma:

<img width="666" src="https://github.com/user-attachments/assets/aa5035f5-f748-4dab-b918-b81b05733323" />

Thanks for reporting this @benjamaan476
2025-05-30 13:20:06 -05:00
1bb96cd878 Release KCL 78 (#7298) 2025-05-30 13:48:17 -04:00
b63b0e538a Fix to not have infinite console errors editing tangentialArc (#7296) 2025-05-30 12:58:47 -04:00
5118198cec Add variable name to operations display in Feature Tree (#7274)
* Add variable name to operations in Feature Tree

* small design tweak

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
2025-05-30 11:09:01 -04:00
1611244b94 Revert "Fix the black screen of death" (#7292)
Revert "Fix the black screen of death (#7238)"

This reverts commit 46b6707e3a.
2025-05-30 10:36:33 -04:00
227ad31fc2 #4376 UI should generate relative tangentialArc (#7189)
* first step of UI using trelative angentialArc

* use tangentialArcTo when snapping to one of the axes

* remove duplications via tangentialArcHelpers

* update test: snapToProfile start only works for current profile

* add test: Can add multiple profiles to a sketch (all tool types)

* update test: Straight line snapping to previous tangent

* fixes for removing individual constraints (should keep endAbsolute for lines, tangentialArcs)

* fix fnNameToToolTipFromSegment arcTo

* update snapshot test to use relative tangentialArc

* stabilize some snapshot tests

* stabilize and update Inch snapshot test on ubuntu

* fix tsc

* stabilize and update Millimeter scale snapshot test on ubuntu

* update snapshot for Inch scale test

* Update snapshots

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-30 14:44:31 +02:00
80e3dc9095 Move more functions to KCL decls (#7266)
* Move some sketch functions to KCL

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

* Move asserts to KCL

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

* sweep, loft -> KCL

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

* Move pattern transforms to KCL

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-29 19:00:16 -04:00
46b6707e3a Fix the black screen of death (#7238)
* Fix the black screen of death

* fmt

* make check

* Clean up

* Fix up zoom to fit

* Change how emulateNetworkConditions work

* Do NOT use browser's offline/online mechanisms

* Fix test
2025-05-29 15:02:12 -04:00
0eebb76bfd Update Bone Plate (#7260)
* Add clock

* update bone plate

* header check

* adding nick b's comments

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-29 09:59:27 -07:00
464372e7ed Use the same OS images for web and desktop e2e (#7275) 2025-05-29 12:51:11 -04:00
75dff9f775 Remove CI-only page load retry loop (#7272)
Remove CI-only page load retry
2025-05-29 12:35:02 -04:00
5f6d810fbb KCL: Fix autocomplete snippet for color (#7270)
Fixes https://github.com/KittyCAD/modeling-app/issues/7269

Tested both locally in the app, and via unit test.
2025-05-29 10:15:28 -04:00
55e1ec7dad Rename desktop e2e scripts and tags for consistency (#7240)
* Rename desktop e2e scripts and tags for consistency

* Show local command in main test step

* Restore 'e2e' prefix to clarify GitHub UI

* Add web script to contributor guide
2025-05-29 09:29:03 -04:00
b123dacc41 Replace overlay e2e test with integration tests (#7218)
* expand xstate unit tests

* remove .only 🙄

* add tests for remove constraints (with todos)

* expand to invididual constraints too

* re-organise

* fix tests

* fmt

* remove log

* clean up

* type clean up

* add delete tests too

* remove redundant tests<

* fix e2e

* lints
2025-05-29 22:31:57 +10:00
87e3588ceb Refactoring: use typed versions of args getters (#7262)
* Replace uses of get_unlabeled_kw_arg with _typed version

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

* Remove more untyped arg getters

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-29 00:48:47 -04:00
c4d2e33a99 ball joint rod end sample (#7215)
* ball joint sample

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

* Update public/kcl-samples/ball-joint-rod-end/main.kcl

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

* Update public/kcl-samples/ball-joint-rod-end/main.kcl

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

* Update kcl-samples simulation test output

* Update public/kcl-samples/ball-joint-rod-end/main.kcl

* Update public/kcl-samples/ball-joint-rod-end/main.kcl

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-28 22:02:29 -04:00
2ac05508bc Move edge functions to KCL (#7259)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-29 10:14:04 +12:00
5c6d4fbf5a Add diameter arg to arc and tangentialArc (#7247)
Both these functions previously took a `radius`. If you previously used
the radius arg, you can keep using it, or you can use `diameter` instead.
2025-05-28 17:05:37 -04:00
aaff027830 fix symbol rename for unlabeled arg (#7244)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-28 15:50:18 -04:00
355a450c09 Move transform functions to KCL (#7239)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-28 15:15:04 -04:00
21f4fcb041 Add a hotkey for reset camera position, display hotkeys for it and center on selection (#7243) 2025-05-28 14:52:07 -04:00
37aea72a88 Bubble up the message from an error body if it exists (#7202) 2025-05-28 14:51:50 -04:00
783b6ed76c Treat singletons and arrays as subtypes rather than coercible (#7181)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-28 16:29:23 +12:00
9dfb67cf61 Declare appearance function in KCL (#7220)
Move appearance to KCL

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-27 23:25:27 +00:00
889c72ec60 Add clock (#7206)
* Add clock

* update minute hand params

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

* Update kcl-samples simulation test output

* add better parameterization

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-27 16:08:15 -07:00
067e193780 Move solids functions to KCL (#7214)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-27 20:37:54 +00:00
77730196ae Accept n+ as array lengths (#7212)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-27 19:55:28 +00:00
dba0173cc3 Parse union types of arrays and objects (#7213)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-27 19:42:42 +00:00
8f4327ab6b Disable subtract_regression08 artifact graph test (#7233) 2025-05-27 14:47:02 -04:00
cc2769e907 Upgrade to winnow 0.7 (#7198) 2025-05-27 14:24:22 -04:00
91b6db0ba5 Don't access id when editing a shell without a VariableDeclaration (#7232) 2025-05-27 14:20:32 -04:00
8bae76000c Run end-to-end tests against the web app (#7171)
* Run end-to-end tests against the web app

* Capture logs for web tests
2025-05-27 14:11:31 -04:00
f502e445cc Don't error when editing via feature tree if no angle arg is present in revolve, use 360deg (#7230)
* Don't error if no `angle` arg is present in revolve, use `360`

KCL uses a default value if the keyword argument isn't present, so the
feature tree edit flow should do the same. In the future these should
flow from the same source of truth so that the feature tree doesn't have
to duplicate default arg values like this.

* Use `360deg` for more definite UoM
2025-05-27 16:51:19 +00:00
083bfe6ec2 Only consider staight lines for colinear check when doing a full revolve (#7209)
* Only consider staight lines for colinear check

* Neaten up code and add test

* Sir, a second sphere has hit the unit test

* Update test snapshots

---------

Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
2025-05-27 14:44:32 +01:00
2c1a5ff5c4 Clarify release instructions (#7193) 2025-05-27 09:28:02 -04:00
0c2785df67 Round floats in simulation tests to 3dp (#7211)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-26 11:17:12 +12:00
fa9d5a0104 KCL: Another example of how to use hex color strings (#7195) 2025-05-23 23:09:37 -04:00
678433d2b3 Bubble up the actual error message in the Text-to-CAD toast message (#7201)
So that users can see if they're blocked, for example.
2025-05-24 00:00:42 +00:00
30bd307931 [Fix]: Corrected camera's projection when engine idle reconnects (#7173)
* fix: implemented a fix to read from settings before restoring camera view and log if it desyncs

* fix: reverting testing code

* fix: always enable ortho scale enabled mode

* fix: fixed the ortho_scale_enabled boolean, do not touch it. Set it to true and never touch it again
2025-05-23 17:30:05 -04:00
08dfaba7f7 Updating the rail to modern practice (#7180)
* Updating the rail to modern practice

* rename 8020 to generic T-slot
2025-05-23 20:59:44 +00:00
eb2327827b Release KCL 77 (#7188) 2025-05-23 18:54:04 +00:00
1f53dd1357 KCL: [number; 3] to RGB hex string color function (#7184)
Closes https://github.com/KittyCAD/modeling-app/issues/6805. Enables users to programatically construct colors, which will be helpful for 

- Applying color to visualize program execution and help debugging
- Doing weird cool shit
2025-05-23 13:53:58 -05:00
882 changed files with 176770 additions and 356023 deletions

View File

@ -7,11 +7,11 @@ if [[ ! -f "test-results/.last-run.json" ]]; then
# If no last run artifact, than run Playwright normally
echo "run playwright normally"
if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron -- --shard=$1/$2 || true
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:desktop -- --shard=$1/$2 || true
elif [[ "$3" == *windows* ]]; then
npm run test:playwright:electron -- --grep=@windows --shard=$1/$2 || true
npm run test:e2e:desktop -- --grep=@windows --shard=$1/$2 || true
elif [[ "$3" == *macos* ]]; then
npm run test:playwright:electron -- --grep=@macos --shard=$1/$2 || true
npm run test:e2e:desktop -- --grep=@macos --shard=$1/$2 || true
else
echo "Do not run Playwright. Unable to detect os runtime."
exit 1
@ -31,11 +31,11 @@ while [[ $retry -le $max_retries ]]; do
echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry"
if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:playwright:electron -- --last-failed || true
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:desktop -- --last-failed || true
elif [[ "$3" == *windows* ]]; then
npm run test:playwright:electron -- --grep=@windows --last-failed || true
npm run test:e2e:desktop -- --grep=@windows --last-failed || true
elif [[ "$3" == *macos* ]]; then
npm run test:playwright:electron -- --grep=@macos --last-failed || true
npm run test:e2e:desktop -- --grep=@macos --last-failed || true
else
echo "Do not run playwright. Unable to detect os runtime."
exit 1

853
.github/dependabot.yml vendored

File diff suppressed because it is too large Load Diff

View File

@ -20,9 +20,11 @@ permissions:
jobs:
prepare-wasm:
# separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps:
- uses: actions/checkout@v4
- id: filter
@ -100,10 +102,13 @@ jobs:
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
snapshots:
name: playwright:snapshots:ubuntu
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
needs: [prepare-wasm]
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
name: e2e:snapshots
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
@ -131,10 +136,9 @@ jobs:
cache: 'npm'
- name: Install dependencies
id: deps-install
run: npm install
- name: Cache browsers
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
@ -144,7 +148,7 @@ jobs:
- name: Install browsers
run: npm run playwright install --with-deps
- name: Test snapshots
- name: npm run test:snapshots
uses: nick-fields/retry@v3.0.2
with:
shell: bash
@ -207,12 +211,96 @@ jobs:
git push
git push origin ${{ github.head_ref }}
electron:
web:
needs: [prepare-wasm]
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- os: namespace-profile-macos-8-cores
- os: windows-latest-8-cores
runs-on: ${{ matrix.os }}
name: e2e:web (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }})
env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} (shard ${{ matrix.shardIndex }})
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- uses: actions/download-artifact@v4
name: prepared-wasm
- name: Copy prepared Wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
- name: Install browsers
run: npm run playwright install --with-deps
- name: Start Vector
if: ${{ !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: npm run test:e2e:web
uses: nick-fields/retry@v3.0.2
with:
shell: bash
command: npm run test:e2e:web
timeout_minutes: 5
max_attempts: 5
env:
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
TAB_API_URL: ${{ secrets.TAB_API_URL }}
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: e2e:web
TARGET: web
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
with:
path: playwright-report/
include-hidden-files: true
retention-days: 30
overwrite: true
desktop:
needs: [prepare-wasm]
strategy:
fail-fast: false
matrix:
@ -255,13 +343,17 @@ jobs:
shardIndex: 2
shardTotal: 2
runs-on: ${{ matrix.os }}
name: e2e:desktop (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}, shard ${{ matrix.shardIndex }})
env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
name: prepared-wasm
- name: Copy prepared wasm
- name: Copy prepared Wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
@ -277,19 +369,16 @@ jobs:
id: deps-install
run: npm install
- name: Cache Playwright Browsers
- name: Download browser cache
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
- name: Install Playwright Browsers
- name: Install browsers
run: npm run playwright install --with-deps
- name: Build web
run: npm run tronb:vite:dev
- name: Start Vector
if: ${{ !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
@ -297,6 +386,9 @@ jobs:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: Build app
run: npm run tronb:vite:dev
- uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
continue-on-error: true
@ -304,7 +396,7 @@ jobs:
name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/
- name: Run playwright/electron flow (with retries)
- name: npm run test:e2e:desktop
id: retry
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
uses: nick-fields/retry@v3.0.2

View File

@ -1,6 +1,6 @@
# Contributor Guide
## Running a development build
## Installing dependencies
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
@ -31,7 +31,9 @@ npm run install:rust:windows
npm run install:wasm-pack:cargo
```
Then to build the WASM layer, run:
## Building the app
To build the WASM layer, run:
```
# macOS/Linux
@ -74,7 +76,7 @@ enable third-party cookies. You can enable third-party cookies by clicking on
the eye with a slash through it in the URL bar, and clicking on "Enable
Third-Party Cookies".
## Desktop
### Developing with Electron
To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then:
@ -88,109 +90,7 @@ Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (
To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables).
## Checking out commits / Bisecting
Which commands from setup are one off vs. need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale:
```bash
npm install
npm run build:wasm
npm start
```
## Before submitting a PR
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
- `npm run fmt`
- `npm run tsc`
- `npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Release a new version
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
https://github.com/KittyCAD/modeling-app/issues/new
#### 2. Push a new tag
Decide on a `v`-prefixed semver `VERSION` (eg. `v1.2.3`) with the team and tag the repo, eg. on latest main:
```
git tag $VERSION
git push origin $VERSION
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
A prompt should show up asking for a downgrade to the last release version. Running through that at the end of testing
and making sure the current release candidate has the ability to be updated to what electron-updater points to is critical,
but what is actually being downloaded and installed isn't.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing.
```
# Windows (PowerShell)
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
# macOS
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
# Linux
./Zoo Design Studio-{version}-{arch}-linux.AppImage
```
#### 4. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 5. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
## Fuzzing the parser
Make sure you install cargo fuzz:
```bash
$ cargo install cargo-fuzz
```
```bash
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
For more information on fuzzing you can check out
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
## Tests
## Running tests
### Playwright tests
@ -200,7 +100,7 @@ Prepare these system dependencies:
#### Snapshot tests (Google Chrome on Ubuntu only)
Only Ubunu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
Only Ubuntu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace.
```
npm run playwright -- install chrome
@ -208,14 +108,21 @@ npm run test:snapshots
```
You may use `-- --update-snapshots` as needed.
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
#### Desktop tests (Electron on all platforms)
```
npm run playwright -- install chromium
npm run test:playwright:electron:local
npm run test:e2e:desktop:local
```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Web tests (Google Chrome on all platforms)
```
npm run test:e2e:web
```
#### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
@ -301,8 +208,103 @@ then run tests that target the KCL language:
npm run test:rust
```
### Fuzzing the parser
Make sure you install cargo fuzz:
```bash
$ cargo install cargo-fuzz
```
```bash
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
For more information on fuzzing you can check out
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
### Logging
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
To enable memory metrics, build with `--features dhat-heap`.
## Proposing changes
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
- `npm run fmt`
- `npm run tsc`
- `npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Shipping releases
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
https://github.com/KittyCAD/modeling-app/issues/new
#### 2. Push a new tag
Decide on a `v`-prefixed semver `VERSION` (e.g. `v1.2.3`) with the team and tag the repo on the latest main:
```
git tag $VERSION --message=""
git push origin $VERSION
```
This will trigger the `build-apps` workflow to set the version, build & sign the apps, and generate release files.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in step 2).
Manually test against [this list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
A prompt should show up asking for a downgrade to the last release version. Running through that at the end of testing
and making sure the current release candidate has the ability to be updated to what electron-updater points to is critical,
but what is actually being downloaded and installed isn't.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing.
```
# Windows (PowerShell)
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
# macOS
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
# Linux
./Zoo Design Studio-{version}-{arch}-linux.AppImage
```
#### 4. Bump the KCL version
Follow the instructions [here](./rust/README.md) to publish new crates.
This ensures that the KCL accepted by the app is also accepted by the CLI.
#### 5. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
Click **Generate release notes** as a starting point to discuss the changelog in the issue. Once done, make sure **Set as the latest release** is checked, and click **Publish release**.
A new `publish-apps-release` workflow will start and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 6. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.

View File

@ -120,19 +120,18 @@ test-e2e: test-e2e-$(TARGET)
.PHONY: test-e2e-web
test-e2e-web: install build ## Run the web e2e tests
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
ifdef E2E_GREP
npm run chrome:test -- --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
npm run test:e2e:web -- --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else
npm run chrome:test -- --headed --workers='100%'
npm run test:e2e:web -- --headed --workers='100%'
endif
.PHONY: test-e2e-desktop
test-e2e-desktop: install build ## Run the desktop e2e tests
ifdef E2E_GREP
npm run test:playwright:electron -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
npm run test:e2e:desktop -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else
npm run test:playwright:electron -- --workers='100%'
npm run test:e2e:desktop -- --workers='100%'
endif
###############################################################################

View File

@ -16,15 +16,16 @@ There are some useful functions for working with arrays in the standard library,
Arrays have their own types: `[T]` where `T` is the type of the elements of the array, for example, `[string]` means an array of `string`s and `[any]` means an array of any values.
Array types can also include length information: `[T; n]` denotes an array of length `n` (where `n` is a number literal) and `[T; 1+]` denotes an array whose length is at least one (i.e., a non-empty array). E.g., `[string; 1+]` and `[number(mm); 3]` are valid array types.
Array types can also include length information: `[T; n]` denotes an array of length `n` (where `n` is a number literal) and `[T; n+]` denotes an array whose length is at least `n`. The common case for that is `[T; 1+]`, i.e., a non-empty array. E.g., `[string; 1+]` and `[number(mm); 3]` are valid array types.
## Ranges
Ranges are a succinct way to create an array of sequential numbers. The syntax is `[start .. end]` where `start` and `end` evaluate to whole numbers (integers). Ranges are inclusive of the start and end. The end must be greater than the start. Examples:
Ranges are a succinct way to create an array of sequential numbers. The syntax is `[start .. end]` where `start` and `end` evaluate to whole numbers (integers). Ranges are inclusive of the start and end. The end must be greater than the start. A range which is exclusive of its end is written with `<end`. Examples:
```kcl,norun
[0..3] // [0, 1, 2, 3]
[3..10] // [3, 4, 5, 6, 7, 8, 9, 10]
[3..<10] // [3, 4, 5, 6, 7, 8, 9]
x = 2
[x..x+1] // [2, 3]
```

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

@ -1,11 +1,11 @@
---
title: "reduce"
subtitle: "Function in std::array"
excerpt: ""
excerpt: "Take a starting value. Then, for each element of an array, calculate the next value, using the previous value and the element."
layout: manual
---
Take a starting value. Then, for each element of an array, calculate the next value, using the previous value and the element.
```kcl
reduce(
@ -15,8 +15,7 @@ reduce(
): any
```
Take a starting value. Then, for each element of an array, calculate the next value,
using the previous value and the element.
### Arguments
@ -28,7 +27,7 @@ using the previous value and the element.
### Returns
[`any`](/docs/kcl-std/types/std-types-any)
[`any`](/docs/kcl-std/types/std-types-any) - The [`any`](/docs/kcl-std/types/std-types-any) type is the type of all possible values in KCL. I.e., if a function accepts an argument with type [`any`](/docs/kcl-std/types/std-types-any), then it can accept any value.
### Examples

View File

@ -0,0 +1,49 @@
---
title: "assert"
subtitle: "Function in std"
excerpt: "Check a value meets some expected conditions at runtime. Program terminates with an error if conditions aren't met. If you provide multiple conditions, they will all be checked and all must be met."
layout: manual
---
Check a value meets some expected conditions at runtime. Program terminates with an error if conditions aren't met. If you provide multiple conditions, they will all be checked and all must be met.
```kcl
assert(
@actual: number,
isGreaterThan?: number,
isLessThan?: number,
isGreaterThanOrEqual?: number,
isLessThanOrEqual?: number,
isEqualTo?: number,
tolerance?: number,
error?: string,
)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `actual` | [`number`](/docs/kcl-std/types/std-types-number) | Value to check. If this is the boolean value true, assert passes. Otherwise it fails.. | Yes |
| `isGreaterThan` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is greater than this. | No |
| `isLessThan` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than this. | No |
| `isGreaterThanOrEqual` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is greater than or equal to this. | No |
| `isLessThanOrEqual` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than or equal to this. | No |
| `isEqualTo` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than or equal to this. | No |
| `tolerance` | [`number`](/docs/kcl-std/types/std-types-number) | If `isEqualTo` is used, this is the tolerance to allow for the comparison. This tolerance is used because KCL's number system has some floating-point imprecision when used with very large decimal places. | No |
| `error` | [`string`](/docs/kcl-std/types/std-types-string) | If the value was false, the program will terminate with this error message | No |
### Examples
```kcl
n = 10
assert(n, isEqualTo = 10)
assert(n, isGreaterThanOrEqual = 0, isLessThan = 100, error = "number should be between 0 and 100")
assert(1.0000000000012, isEqualTo = 1, tolerance = 0.0001, error = "number should be almost exactly 1")
```

View File

@ -0,0 +1,35 @@
---
title: "assertIs"
subtitle: "Function in std"
excerpt: "Asserts that a value is the boolean value true."
layout: manual
---
Asserts that a value is the boolean value true.
```kcl
assertIs(
@actual: bool,
error?: string,
)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `actual` | [`bool`](/docs/kcl-std/types/std-types-bool) | Value to check. If this is the boolean value true, assert passes. Otherwise it fails.. | Yes |
| `error` | [`string`](/docs/kcl-std/types/std-types-string) | If the value was false, the program will terminate with this error message | No |
### Examples
```kcl
kclIsFun = true
assertIs(kclIsFun)
```

View File

@ -1,11 +1,11 @@
---
title: "polar"
subtitle: "Function in std::math"
excerpt: ""
excerpt: "Convert polar/sphere (azimuth, elevation, distance) coordinates to cartesian (x/y/z grid) coordinates."
layout: manual
---
Convert polar/sphere (azimuth, elevation, distance) coordinates to cartesian (x/y/z grid) coordinates.
```kcl
polar(
@ -14,8 +14,7 @@ polar(
): Point2d
```
Convert polar/sphere (azimuth, elevation, distance) coordinates to
cartesian (x/y/z grid) coordinates.
### Arguments

View File

@ -1,11 +1,11 @@
---
title: "rem"
subtitle: "Function in std::math"
excerpt: ""
excerpt: "Compute the remainder after dividing `num` by `div`. If `num` is negative, the result will be too."
layout: manual
---
Compute the remainder after dividing `num` by `div`. If `num` is negative, the result will be too.
```kcl
rem(
@ -14,8 +14,7 @@ rem(
): number
```
Compute the remainder after dividing `num` by `div`.
If `num` is negative, the result will be too.
### Arguments

View File

@ -10,13 +10,13 @@ Draw a line segment relative to the current origin using the polar measure of so
```kcl
angledLine(
@sketch: Sketch,
angle: number,
length?: number,
lengthX?: number,
lengthY?: number,
endAbsoluteX?: number,
endAbsoluteY?: number,
tag?: TagDeclarator,
angle: number(Angle),
length?: number(Length),
lengthX?: number(Length),
lengthY?: number(Length),
endAbsoluteX?: number(Length),
endAbsoluteY?: number(Length),
tag?: tag,
): Sketch
```
@ -27,13 +27,13 @@ angledLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `angle` | [`number`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthX` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthY` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteX` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteY` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `length` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthX` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteX` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
### Returns
@ -46,7 +46,10 @@ angledLine(
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> yLine(endAbsolute = 15)
|> angledLine(angle = 30, length = 15)
|> angledLine(
angle = 30,
length = 15,
)
|> line(end = [8, -10])
|> yLine(endAbsolute = 0)
|> close()

View File

@ -10,10 +10,10 @@ Draw an angled line from the current origin, constructing a line segment such th
```kcl
angledLineThatIntersects(
@sketch: Sketch,
angle: number,
intersectTag: TagIdentifier,
offset?: number,
tag?: TagDeclarator,
angle: number(Angle),
intersectTag: tag,
offset?: number(Length),
tag?: tag,
): Sketch
```
@ -24,10 +24,10 @@ angledLineThatIntersects(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `angle` | [`number`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `intersectTag` | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The tag of the line to intersect with | Yes |
| `offset` | [`number`](/docs/kcl-std/types/std-types-number) | The offset from the intersecting line. Defaults to 0. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `intersectTag` | [`tag`](/docs/kcl-std/types/std-types-tag) | The tag of the line to intersect with. | Yes |
| `offset` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The offset from the intersecting line. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
### Returns
@ -42,7 +42,11 @@ exampleSketch = startSketchOn(XZ)
|> line(endAbsolute = [5, 10])
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|> line(endAbsolute = [0, 20])
|> angledLineThatIntersects(angle = 80, intersectTag = lineToIntersect, offset = 10)
|> angledLineThatIntersects(
angle = 80,
intersectTag = lineToIntersect,
offset = 10,
)
|> close()
example = extrude(exampleSketch, length = 10)

View File

@ -10,30 +10,37 @@ Draw a curved line segment along an imaginary circle.
```kcl
arc(
@sketch: Sketch,
angleStart?: number,
angleEnd?: number,
radius?: number,
angleStart?: number(Angle),
angleEnd?: number(Angle),
radius?: number(Length),
diameter?: number(Length),
interiorAbsolute?: Point2d,
endAbsolute?: Point2d,
tag?: TagDeclarator,
tag?: tag,
): Sketch
```
The arc is constructed such that the current position of the sketch is placed along an imaginary circle of the specified radius, at angleStart degrees. The resulting arc is the segment of the imaginary circle from that origin point to angleEnd, radius away from the center of the imaginary circle.
The arc is constructed such that the current position of the sketch is
placed along an imaginary circle of the specified radius, at angleStart
degrees. The resulting arc is the segment of the imaginary circle from
that origin point to angleEnd, radius away from the center of the imaginary
circle.
Unless this makes a lot of sense and feels like what you're looking for to construct your shape, you're likely looking for tangentialArc.
Unless this makes a lot of sense and feels like what you're looking
for to construct your shape, you're likely looking for tangentialArc.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `angleStart` | [`number`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc start? | No |
| `angleEnd` | [`number`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc end? | No |
| `radius` | [`number`](/docs/kcl-std/types/std-types-number) | How large should the circle be? | No |
| `interiorAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd` | No |
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Where should this arc end? Requires `interiorAbsolute`. Incompatible with `angleStart` or `angleEnd` | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `angleStart` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc start? | No |
| `angleEnd` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc end? | No |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How large should the circle be? Incompatible with `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How large should the circle be? Incompatible with `radius`. | No |
| `interiorAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Where should this arc end? Requires `interiorAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this arc. | No |
### Returns
@ -46,7 +53,11 @@ Unless this makes a lot of sense and feels like what you're looking for to const
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [10, 0])
|> arc(angleStart = 0, angleEnd = 280, radius = 16)
|> arc(
angleStart = 0,
angleEnd = 280,
radius = 16
)
|> close()
example = extrude(exampleSketch, length = 10)
```
@ -56,7 +67,10 @@ example = extrude(exampleSketch, length = 10)
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> arc(endAbsolute = [10, 0], interiorAbsolute = [5, 5])
|> arc(
endAbsolute = [10,0],
interiorAbsolute = [5,5]
)
|> close()
example = extrude(exampleSketch, length = 10)
```

File diff suppressed because one or more lines are too long

View File

@ -1,15 +1,15 @@
---
title: "circle"
subtitle: "Function in std::sketch"
excerpt: ""
excerpt: "Construct a 2-dimensional circle, of the specified radius, centered at the provided (x, y) origin point."
layout: manual
---
Construct a 2-dimensional circle, of the specified radius, centered at the provided (x, y) origin point.
```kcl
circle(
@sketch_or_surface: Sketch | Plane | Face,
@sketchOrSurface: Sketch | Plane | Face,
center: Point2d,
radius?: number(Length),
diameter?: number(Length),
@ -17,14 +17,13 @@ circle(
): Sketch
```
Construct a 2-dimensional circle, of the specified radius, centered at
the provided (x, y) origin point.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch_or_surface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the circle. | Yes |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the circle. Incompatible with `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The diameter of the circle. Incompatible with `radius`. | No |

View File

@ -9,11 +9,11 @@ Construct a circle derived from 3 points.
```kcl
circleThreePoint(
@sketchSurfaceOrGroup: Sketch | Plane | Face,
@sketchOrSurface: Sketch | Plane | Face,
p1: Point2d,
p2: Point2d,
p3: Point2d,
tag?: TagDeclarator,
tag?: tag,
): Sketch
```
@ -23,11 +23,11 @@ circleThreePoint(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on. | Yes |
| `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on. | Yes |
| `p1` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | 1st point to derive the circle. | Yes |
| `p2` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | 2nd point to derive the circle. | Yes |
| `p3` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | 3rd point to derive the circle. | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Identifier for the circle to reference elsewhere. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Identifier for the circle to reference elsewhere. | No |
### Returns
@ -38,7 +38,7 @@ circleThreePoint(
```kcl
exampleSketch = startSketchOn(XY)
|> circleThreePoint(p1 = [10, 10], p2 = [20, 8], p3 = [15, 5])
|> circleThreePoint(p1 = [10,10], p2 = [20,8], p3 = [15,5])
|> extrude(length = 5)
```

File diff suppressed because one or more lines are too long

View File

@ -9,31 +9,32 @@ Extend a 2-dimensional sketch through a third dimension in order to create new 3
```kcl
extrude(
@sketches: [Sketch],
length: number,
@sketches: [Sketch; 1+],
length: number(Length),
symmetric?: bool,
bidirectionalLength?: number,
tagStart?: TagDeclarator,
tagEnd?: TagDeclarator,
): [Solid]
bidirectionalLength?: number(Length),
tagStart?: tag,
tagEnd?: tag,
): [Solid; 1+]
```
You can provide more than one sketch to extrude, and they will all be extruded in the same direction.
You can provide more than one sketch to extrude, and they will all be
extruded in the same direction.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch or sketches should be extruded | Yes |
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | How far to extrude the given sketches | Yes |
| `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch or sketches should be extruded. | Yes |
| `length` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How far to extrude the given sketches. | Yes |
| `symmetric` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch. | No |
| `bidirectionalLength` | [`number`](/docs/kcl-std/types/std-types-number) | If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. | No |
| `tagStart` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the start of the extrusion, i.e. the original sketch | No |
| `tagEnd` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch | No |
| `bidirectionalLength` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. | No |
| `tagStart` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the start of the extrusion, i.e. the original sketch. | No |
| `tagEnd` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch. | No |
### Returns
[`[Solid]`](/docs/kcl-std/types/std-types-Solid)
[`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid)
### Examples
@ -42,10 +43,18 @@ You can provide more than one sketch to extrude, and they will all be extruded i
example = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [10, 0])
|> arc(angleStart = 120, angleEnd = 0, radius = 5)
|> arc(
angleStart = 120,
angleEnd = 0,
radius = 5,
)
|> line(end = [5, 0])
|> line(end = [0, 10])
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve(
control1 = [-10, 0],
control2 = [2, 10],
end = [-5, 10],
)
|> line(end = [-5, -2])
|> close()
|> extrude(length = 10)
@ -56,10 +65,18 @@ example = startSketchOn(XZ)
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [-10, 0])
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> arc(
angleStart = 120,
angleEnd = -60,
radius = 5,
)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve(
control1 = [-3, 0],
control2 = [2, 10],
end = [-5, 10],
)
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()
@ -72,10 +89,18 @@ example = extrude(exampleSketch, length = 10)
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [-10, 0])
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> arc(
angleStart = 120,
angleEnd = -60,
radius = 5,
)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve(
control1 = [-3, 0],
control2 = [2, 10],
end = [-5, 10],
)
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()
@ -88,10 +113,18 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [-10, 0])
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> arc(
angleStart = 120,
angleEnd = -60,
radius = 5,
)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve(
control1 = [-3, 0],
control2 = [2, 10],
end = [-5, 10],
)
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()

View File

@ -8,7 +8,7 @@ layout: manual
Get the shared edge between two faces.
```kcl
getCommonEdge(faces: [TagIdentifier]): Uuid
getCommonEdge(faces: [tag; 2]): Edge
```
@ -17,11 +17,11 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `faces` | [`[TagIdentifier]`](/docs/kcl-lang/types#TagIdentifier) | The tags of the faces you want to find the common edge between | Yes |
| `faces` | `[tag; 2]` | The tags of the faces you want to find the common edge between. | Yes |
### Returns
`Uuid`
[`Edge`](/docs/kcl-std/types/std-types-Edge) - An edge of a solid.
### Examples
@ -29,17 +29,16 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
```kcl
// Get an edge shared between two faces, created after a chamfer.
scale = 20
part001 = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> line(end = [0, scale])
|> line(end = [scale, 0])
|> line(end = [0, -scale])
|> close(tag = $line0)
|> extrude(length = 20, tagEnd = $end0)
// We tag the chamfer to reference it later.
|> chamfer(length = 10, tags = [getOppositeEdge(line0)], tag = $chamfer0)
|> startProfile(at = [0, 0])
|> line(end = [0, scale])
|> line(end = [scale, 0])
|> line(end = [0, -scale])
|> close(tag = $line0)
|> extrude(length = 20, tagEnd = $end0)
// We tag the chamfer to reference it later.
|> chamfer(length = 10, tags = [getOppositeEdge(line0)], tag = $chamfer0)
// Get the shared edge between the chamfer and the extrusion.
commonEdge = getCommonEdge(faces = [chamfer0, end0])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ layout: manual
Extract the 'x' axis value of the last line segment in the provided 2-d sketch.
```kcl
lastSegX(@sketch: Sketch): number
lastSegX(@sketch: Sketch): number(Length)
```
@ -17,11 +17,11 @@ lastSegX(@sketch: Sketch): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | The sketch whose line segment is being queried | Yes |
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | The sketch whose line segment is being queried. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Extract the 'y' axis value of the last line segment in the provided 2-d sketch.
```kcl
lastSegY(@sketch: Sketch): number
lastSegY(@sketch: Sketch): number(Length)
```
@ -17,11 +17,11 @@ lastSegY(@sketch: Sketch): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | The sketch whose line segment is being queried | Yes |
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | The sketch whose line segment is being queried. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

View File

@ -12,7 +12,7 @@ line(
@sketch: Sketch,
endAbsolute?: Point2d,
end?: Point2d,
tag?: TagDeclarator,
tag?: tag,
): Sketch
```
@ -25,7 +25,7 @@ line(
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Which absolute point should this line go to? Incompatible with `end`. | No |
| `end` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | How far away (along the X and Y axes) should this line go? Incompatible with `endAbsolute`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
### Returns

File diff suppressed because one or more lines are too long

View File

@ -9,13 +9,13 @@ Repeat a 2-dimensional sketch some number of times along a partial or complete c
```kcl
patternCircular2d(
@sketchSet: [Sketch],
instances: number,
@sketches: [Sketch; 1+],
instances: number(_),
center: Point2d,
arcDegrees?: number,
arcDegrees?: number(Angle),
rotateDuplicates?: bool,
useOriginal?: bool,
): [Sketch]
): [Sketch; 1+]
```
@ -24,16 +24,16 @@ patternCircular2d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSet` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch(es) to pattern | Yes |
| `instances` | [`number`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | The sketch(es) to duplicate. | Yes |
| `instances` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center about which to make the pattern. This is a 2D vector. | Yes |
| `arcDegrees` | [`number`](/docs/kcl-std/types/std-types-number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. Defaults to 360. | No |
| `rotateDuplicates` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether or not to rotate the duplicates as they are copied. Defaults to true. | No |
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
| `arcDegrees` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
| `rotateDuplicates` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether or not to rotate the duplicates as they are copied. | No |
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No |
### Returns
[`[Sketch]`](/docs/kcl-std/types/std-types-Sketch)
[`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch)
### Examples
@ -49,7 +49,7 @@ exampleSketch = startSketchOn(XZ)
center = [0, 0],
instances = 13,
arcDegrees = 360,
rotateDuplicates = true,
rotateDuplicates = true
)
example = extrude(exampleSketch, length = 1)

File diff suppressed because one or more lines are too long

View File

@ -9,9 +9,9 @@ Create a regular polygon with the specified number of sides that is either inscr
```kcl
polygon(
@sketchSurfaceOrGroup: Sketch | Plane | Face,
radius: number,
numSides: u64,
@sketchOrSurface: Sketch | Plane | Face,
radius: number(Length),
numSides: number(_),
center: Point2d,
inscribed?: bool,
): Sketch
@ -23,11 +23,11 @@ polygon(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on | Yes |
| `radius` | [`number`](/docs/kcl-std/types/std-types-number) | The radius of the polygon | Yes |
| `numSides` | `u64` | The number of sides in the polygon | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center point of the polygon | Yes |
| `inscribed` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius | No |
| `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on. | Yes |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the polygon. | Yes |
| `numSides` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of sides in the polygon. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center point of the polygon. | Yes |
| `inscribed` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius. | No |
### Returns
@ -40,11 +40,11 @@ polygon(
// Create a regular hexagon inscribed in a circle of radius 10
hex = startSketchOn(XY)
|> polygon(
radius = 10,
numSides = 6,
center = [0, 0],
inscribed = true,
)
radius = 10,
numSides = 6,
center = [0, 0],
inscribed = true,
)
example = extrude(hex, length = 5)
```
@ -55,11 +55,11 @@ example = extrude(hex, length = 5)
// Create a square circumscribed around a circle of radius 5
square = startSketchOn(XY)
|> polygon(
radius = 5.0,
numSides = 4,
center = [10, 10],
inscribed = false,
)
radius = 5.0,
numSides = 4,
center = [10, 10],
inscribed = false,
)
example = extrude(square, length = 5)
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ layout: manual
Compute the angle (in degrees) of the provided line segment.
```kcl
segAng(@tag: TagIdentifier): number
segAng(@tag: tag): number(Angle)
```
@ -17,11 +17,11 @@ segAng(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Angle)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Compute the ending point of the provided line segment.
```kcl
segEnd(@tag: TagIdentifier): Point2d
segEnd(@tag: tag): Point2d
```
@ -17,7 +17,7 @@ segEnd(@tag: TagIdentifier): Point2d
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
@ -39,9 +39,9 @@ cube = startSketchOn(XY)
fn cylinder(radius, tag) {
return startSketchOn(XY)
|> startProfile(at = [0, 0])
|> circle(radius = radius, center = segEnd(tag))
|> extrude(length = radius)
|> startProfile(at = [0, 0])
|> circle(radius = radius, center = segEnd(tag) )
|> extrude(length = radius)
}
cylinder(radius = 1, tag = line1)

View File

@ -8,7 +8,7 @@ layout: manual
Compute the ending point of the provided line segment along the 'x' axis.
```kcl
segEndX(@tag: TagIdentifier): number
segEndX(@tag: tag): number(Length)
```
@ -17,11 +17,11 @@ segEndX(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Compute the ending point of the provided line segment along the 'y' axis.
```kcl
segEndY(@tag: TagIdentifier): number
segEndY(@tag: tag): number(Length)
```
@ -17,11 +17,11 @@ segEndY(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Compute the length of the provided line segment.
```kcl
segLen(@tag: TagIdentifier): number
segLen(@tag: tag): number(Length)
```
@ -17,11 +17,11 @@ segLen(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples
@ -29,9 +29,16 @@ segLen(@tag: TagIdentifier): number
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 60, length = 10, tag = $thing)
|> angledLine(
angle = 60,
length = 10,
tag = $thing,
)
|> tangentialArc(angle = -120, radius = 5)
|> angledLine(angle = -60, length = segLen(thing))
|> angledLine(
angle = -60,
length = segLen(thing),
)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -8,7 +8,7 @@ layout: manual
Compute the starting point of the provided line segment.
```kcl
segStart(@tag: TagIdentifier): Point2d
segStart(@tag: tag): Point2d
```
@ -17,7 +17,7 @@ segStart(@tag: TagIdentifier): Point2d
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
@ -39,9 +39,9 @@ cube = startSketchOn(XY)
fn cylinder(radius, tag) {
return startSketchOn(XY)
|> startProfile(at = [0, 0])
|> circle(radius = radius, center = segStart(tag))
|> extrude(length = radius)
|> startProfile(at = [0, 0])
|> circle( radius = radius, center = segStart(tag) )
|> extrude(length = radius)
}
cylinder(radius = 1, tag = line1)

View File

@ -8,7 +8,7 @@ layout: manual
Compute the starting point of the provided line segment along the 'x' axis.
```kcl
segStartX(@tag: TagIdentifier): number
segStartX(@tag: tag): number(Length)
```
@ -17,11 +17,11 @@ segStartX(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Compute the starting point of the provided line segment along the 'y' axis.
```kcl
segStartY(@tag: TagIdentifier): number
segStartY(@tag: tag): number(Length)
```
@ -17,11 +17,11 @@ segStartY(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples
@ -32,7 +32,7 @@ exampleSketch = startSketchOn(XZ)
|> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing)
|> line(end = [-10, 0])
|> line(end = [0, 20 - segStartY(thing)])
|> line(end = [0, 20-segStartY(thing)])
|> line(end = [-10, 0])
|> close()

View File

@ -9,9 +9,9 @@ Start a new profile at a given point.
```kcl
startProfile(
@sketchSurface: Plane | Face,
@startProfileOn: Plane | Face,
at: Point2d,
tag?: TagDeclarator,
tag?: tag,
): Sketch
```
@ -21,9 +21,9 @@ startProfile(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSurface` | [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | What to start the profile on | Yes |
| `startProfileOn` | [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | What to start the profile on. | Yes |
| `at` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Where to start the profile. An absolute point. | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Tag this first starting point | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Tag this first starting point. | No |
### Returns

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

@ -8,7 +8,7 @@ layout: manual
Returns the angle coming out of the end of the segment in degrees.
```kcl
tangentToEnd(@tag: TagIdentifier): number
tangentToEnd(@tag: tag): number(Angle)
```
@ -17,11 +17,11 @@ tangentToEnd(@tag: TagIdentifier): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Angle)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples
@ -32,7 +32,10 @@ pillSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [20, 0])
|> tangentialArc(end = [0, 10], tag = $arc1)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> angledLine(
angle = tangentToEnd(arc1),
length = 20,
)
|> tangentialArc(end = [0, -10])
|> close()
@ -47,7 +50,10 @@ pillSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [0, 20])
|> tangentialArc(endAbsolute = [10, 20], tag = $arc1)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> angledLine(
angle = tangentToEnd(arc1),
length = 20,
)
|> tangentialArc(end = [-10, 0])
|> close()
@ -60,7 +66,10 @@ pillExtrude = extrude(pillSketch, length = 10)
rectangleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [10, 0], tag = $seg1)
|> angledLine(angle = tangentToEnd(seg1), length = 10)
|> angledLine(
angle = tangentToEnd(seg1),
length = 10,
)
|> line(end = [0, 10])
|> line(end = [-20, 0])
|> close()
@ -73,7 +82,11 @@ rectangleExtrude = extrude(rectangleSketch, length = 10)
```kcl
bottom = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> arc(endAbsolute = [10, 10], interiorAbsolute = [5, 1], tag = $arc1)
|> arc(
endAbsolute = [10, 10],
interiorAbsolute = [5, 1],
tag = $arc1,
)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> close()
```
@ -82,7 +95,7 @@ bottom = startSketchOn(XY)
```kcl
circSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 3, tag = $circ)
|> circle(center = [0, 0], radius= 3, tag = $circ)
triangleSketch = startSketchOn(XY)
|> startProfile(at = [-5, 0])

View File

@ -12,13 +12,18 @@ tangentialArc(
@sketch: Sketch,
endAbsolute?: Point2d,
end?: Point2d,
radius?: number,
angle?: number,
tag?: TagDeclarator,
radius?: number(Length),
diameter?: number(Length),
angle?: number(Angle),
tag?: tag,
): Sketch
```
When using radius and angle, draw a curved line segment along part of an imaginary circle. The arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'angle' degrees along the imaginary circle.
When using radius and angle, draw a curved line segment along part of an
imaginary circle. The arc is constructed such that the last line segment is
placed tangent to the imaginary circle of the specified radius. The
resulting arc is the segment of the imaginary circle from that tangent point
for 'angle' degrees along the imaginary circle.
### Arguments
@ -27,9 +32,10 @@ When using radius and angle, draw a curved line segment along part of an imagina
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Which absolute point should this arc go to? Incompatible with `end`, `radius`, and `offset`. | No |
| `end` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | How far away (along the X and Y axes) should this arc go? Incompatible with `endAbsolute`, `radius`, and `offset`. | No |
| `radius` | [`number`](/docs/kcl-std/types/std-types-number) | Radius of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute`. | No |
| `angle` | [`number`](/docs/kcl-std/types/std-types-number) | Offset of the arc in degrees. `radius` must be given. Incompatible with `end` and `endAbsolute`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this arc | No |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Radius of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Diameter of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `radius`. | No |
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Offset of the arc. `radius` must be given. Incompatible with `end` and `endAbsolute`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this arc. | No |
### Returns
@ -41,7 +47,10 @@ When using radius and angle, draw a curved line segment along part of an imagina
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 45, length = 10)
|> angledLine(
angle = 45,
length = 10,
)
|> tangentialArc(end = [0, -10])
|> line(end = [-10, 0])
|> close()
@ -54,7 +63,10 @@ example = extrude(exampleSketch, length = 10)
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(
angle = 60,
length = 10,
)
|> tangentialArc(endAbsolute = [15, 15])
|> line(end = [10, -15])
|> close()
@ -67,9 +79,15 @@ example = extrude(exampleSketch, length = 10)
```kcl
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(
angle = 60,
length = 10,
)
|> tangentialArc(radius = 10, angle = -120)
|> angledLine(angle = -60, length = 10)
|> angledLine(
angle = -60,
length = 10,
)
|> close()
example = extrude(exampleSketch, length = 10)

View File

@ -10,9 +10,9 @@ Draw a line relative to the current origin to a specified distance away from the
```kcl
xLine(
@sketch: Sketch,
length?: number,
endAbsolute?: number,
tag?: TagDeclarator,
length?: number(Length),
endAbsolute?: number(Length),
tag?: tag,
): Sketch
```
@ -23,9 +23,9 @@ xLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | How far away along the X axis should this line go? Incompatible with `endAbsolute`. | No |
| `endAbsolute` | [`number`](/docs/kcl-std/types/std-types-number) | Which absolute X value should this line go to? Incompatible with `length`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `length` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How far away along the X axis should this line go? Incompatible with `endAbsolute`. | No |
| `endAbsolute` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Which absolute X value should this line go to? Incompatible with `length`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
### Returns
@ -38,10 +38,16 @@ xLine(
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> xLine(length = 15)
|> angledLine(angle = 80, length = 15)
|> angledLine(
angle = 80,
length = 15,
)
|> line(end = [8, -10])
|> xLine(length = 10)
|> angledLine(angle = 120, length = 30)
|> angledLine(
angle = 120,
length = 30,
)
|> xLine(length = -15)
|> close()

View File

@ -10,9 +10,9 @@ Draw a line relative to the current origin to a specified distance away from the
```kcl
yLine(
@sketch: Sketch,
length?: number,
endAbsolute?: number,
tag?: TagDeclarator,
length?: number(Length),
endAbsolute?: number(Length),
tag?: tag,
): Sketch
```
@ -23,9 +23,9 @@ yLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | How far away along the Y axis should this line go? Incompatible with `endAbsolute`. | No |
| `endAbsolute` | [`number`](/docs/kcl-std/types/std-types-number) | Which absolute Y value should this line go to? Incompatible with `length`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `length` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How far away along the Y axis should this line go? Incompatible with `endAbsolute`. | No |
| `endAbsolute` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Which absolute Y value should this line go to? Incompatible with `length`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
### Returns
@ -38,7 +38,10 @@ yLine(
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> yLine(length = 15)
|> angledLine(angle = 30, length = 15)
|> angledLine(
angle = 30,
length = 15,
)
|> line(end = [8, -10])
|> yLine(length = -5)
|> close()

File diff suppressed because one or more lines are too long

View File

@ -9,23 +9,26 @@ Intersect returns the shared volume between multiple solids, preserving only ove
```kcl
intersect(
@solids: [Solid],
tolerance?: number,
): [Solid]
@solids: [Solid; 2+],
tolerance?: number(Length),
): [Solid; 1+]
```
Intersect computes the geometric intersection of multiple solid bodies, returning a new solid representing the volume that is common to all input solids. This operation is useful for determining shared material regions, verifying fit, and analyzing overlapping geometries in assemblies.
Intersect computes the geometric intersection of multiple solid bodies,
returning a new solid representing the volume that is common to all input
solids. This operation is useful for determining shared material regions,
verifying fit, and analyzing overlapping geometries in assemblies.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solids` | [`[Solid]`](/docs/kcl-std/types/std-types-Solid) | The solids to intersect. | Yes |
| `tolerance` | [`number`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the intersection operation. | No |
| `solids` | `[Solid; 2+]` | The solids to intersect. | Yes |
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the intersection operation. | No |
### Returns
[`[Solid]`](/docs/kcl-std/types/std-types-Solid)
[`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid)
### Examples
@ -33,20 +36,19 @@ Intersect computes the geometric intersection of multiple solid bodies, returnin
```kcl
// Intersect two cubes using the stdlib functions.
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
}
part001 = cube(center = [0, 0], size = 10)
part002 = cube(center = [7, 3], size = 5)
|> translate(z = 1)
|> translate(z = 1)
intersectedPart = intersect([part001, part002])
```
@ -58,20 +60,19 @@ intersectedPart = intersect([part001, part002])
// NOTE: This will not work when using codemods through the UI.
// Codemods will generate the stdlib function call instead.
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
}
part001 = cube(center = [0, 0], size = 10)
part002 = cube(center = [7, 3], size = 5)
|> translate(z = 1)
|> translate(z = 1)
// This is the equivalent of: intersect([part001, part002])
intersectedPart = part001 & part002

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@ patternTransform(
@solids: [Solid; 1+],
instances: number(_),
transform: fn(number(_)): { },
useOriginal?: boolean,
useOriginal?: bool,
): [Solid; 1+]
```
@ -61,7 +61,7 @@ Its properties are:
| `solids` | [`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid) | The solid(s) to duplicate. | Yes |
| `instances` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `transform` | [`fn(number(_)): { }`](/docs/kcl-std/types/std-types-fn) | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
| `useOriginal` | `boolean` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No |
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No |
### Returns

View File

@ -1,11 +1,11 @@
---
title: "shell"
subtitle: "Function in std::solid"
excerpt: ""
excerpt: "Remove volume from a 3-dimensional shape such that a wall of the provided thickness remains, taking volume starting at the provided face, leaving it open in that direction."
layout: manual
---
Remove volume from a 3-dimensional shape such that a wall of the provided thickness remains, taking volume starting at the provided face, leaving it open in that direction.
```kcl
shell(
@ -15,8 +15,7 @@ shell(
): [Solid]
```
Remove volume from a 3-dimensional shape such that a wall of the
provided thickness remains, taking volume starting at the providedface, leaving it open in that direction.
### Arguments

File diff suppressed because one or more lines are too long

View File

@ -9,9 +9,9 @@ Union two or more solids into a single solid.
```kcl
union(
@solids: [Solid],
tolerance?: number,
): [Solid]
@solids: [Solid; 2+],
tolerance?: number(Length),
): [Solid; 1+]
```
@ -20,12 +20,12 @@ union(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solids` | [`[Solid]`](/docs/kcl-std/types/std-types-Solid) | The solids to union. | Yes |
| `tolerance` | [`number`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the union operation. | No |
| `solids` | `[Solid; 2+]` | The solids to union. | Yes |
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the union operation. | No |
### Returns
[`[Solid]`](/docs/kcl-std/types/std-types-Solid)
[`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid)
### Examples
@ -33,20 +33,19 @@ union(
```kcl
// Union two cubes using the stdlib functions.
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
}
part001 = cube(center = [0, 0], size = 10)
part002 = cube(center = [7, 3], size = 5)
|> translate(z = 1)
|> translate(z = 1)
unionedPart = union([part001, part002])
```
@ -58,20 +57,19 @@ unionedPart = union([part001, part002])
// NOTE: This will not work when using codemods through the UI.
// Codemods will generate the stdlib function call instead.
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
}
part001 = cube(center = [0, 0], size = 10)
part002 = cube(center = [7, 3], size = 5)
|> translate(z = 1)
|> translate(z = 1)
// This is the equivalent of: union([part001, part002])
unionedPart = part001 + part002
@ -84,23 +82,22 @@ unionedPart = part001 + part002
// NOTE: This will not work when using codemods through the UI.
// Codemods will generate the stdlib function call instead.
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
|> close()
|> extrude(length = 10)
}
part001 = cube(center = [0, 0], size = 10)
part002 = cube(center = [7, 3], size = 5)
|> translate(z = 1)
|> translate(z = 1)
// This is the equivalent of: union([part001, part002])
// Programmers will understand `|` as a union operation, but mechanical engineers
// This is the equivalent of: union([part001, part002])
// Programmers will understand `|` as a union operation, but mechanical engineers
// will understand `+`, we made both work.
unionedPart = part001 | part002
```

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

@ -9,13 +9,13 @@ layout: manual
### Functions
* [**std**](/docs/kcl-std/modules/std)
* [`appearance`](/docs/kcl-std/appearance)
* [`assert`](/docs/kcl-std/assert)
* [`assertIs`](/docs/kcl-std/assertIs)
* [`assert`](/docs/kcl-std/functions/std-assert)
* [`assertIs`](/docs/kcl-std/functions/std-assertIs)
* [`clone`](/docs/kcl-std/functions/std-clone)
* [`helix`](/docs/kcl-std/functions/std-helix)
* [`offsetPlane`](/docs/kcl-std/functions/std-offsetPlane)
* [`patternLinear2d`](/docs/kcl-std/patternLinear2d)
* [**std::appearance**](/docs/kcl-std/modules/std-appearance)
* [`appearance::hexString`](/docs/kcl-std/functions/std-appearance-hexString)
* [**std::array**](/docs/kcl-std/modules/std-array)
* [`map`](/docs/kcl-std/functions/std-array-map)
* [`pop`](/docs/kcl-std/functions/std-array-pop)
@ -47,62 +47,64 @@ layout: manual
* [`sqrt`](/docs/kcl-std/functions/std-math-sqrt)
* [`tan`](/docs/kcl-std/functions/std-math-tan)
* [**std::sketch**](/docs/kcl-std/modules/std-sketch)
* [`angledLine`](/docs/kcl-std/angledLine)
* [`angledLineThatIntersects`](/docs/kcl-std/angledLineThatIntersects)
* [`arc`](/docs/kcl-std/arc)
* [`bezierCurve`](/docs/kcl-std/bezierCurve)
* [`angledLine`](/docs/kcl-std/functions/std-sketch-angledLine)
* [`angledLineThatIntersects`](/docs/kcl-std/functions/std-sketch-angledLineThatIntersects)
* [`arc`](/docs/kcl-std/functions/std-sketch-arc)
* [`bezierCurve`](/docs/kcl-std/functions/std-sketch-bezierCurve)
* [`circle`](/docs/kcl-std/functions/std-sketch-circle)
* [`circleThreePoint`](/docs/kcl-std/circleThreePoint)
* [`close`](/docs/kcl-std/close)
* [`extrude`](/docs/kcl-std/extrude)
* [`getCommonEdge`](/docs/kcl-std/getCommonEdge)
* [`getNextAdjacentEdge`](/docs/kcl-std/getNextAdjacentEdge)
* [`getOppositeEdge`](/docs/kcl-std/getOppositeEdge)
* [`getPreviousAdjacentEdge`](/docs/kcl-std/getPreviousAdjacentEdge)
* [`involuteCircular`](/docs/kcl-std/involuteCircular)
* [`lastSegX`](/docs/kcl-std/lastSegX)
* [`lastSegY`](/docs/kcl-std/lastSegY)
* [`line`](/docs/kcl-std/line)
* [`loft`](/docs/kcl-std/loft)
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
* [`circleThreePoint`](/docs/kcl-std/functions/std-sketch-circleThreePoint)
* [`close`](/docs/kcl-std/functions/std-sketch-close)
* [`extrude`](/docs/kcl-std/functions/std-sketch-extrude)
* [`getCommonEdge`](/docs/kcl-std/functions/std-sketch-getCommonEdge)
* [`getNextAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getNextAdjacentEdge)
* [`getOppositeEdge`](/docs/kcl-std/functions/std-sketch-getOppositeEdge)
* [`getPreviousAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getPreviousAdjacentEdge)
* [`involuteCircular`](/docs/kcl-std/functions/std-sketch-involuteCircular)
* [`lastSegX`](/docs/kcl-std/functions/std-sketch-lastSegX)
* [`lastSegY`](/docs/kcl-std/functions/std-sketch-lastSegY)
* [`line`](/docs/kcl-std/functions/std-sketch-line)
* [`loft`](/docs/kcl-std/functions/std-sketch-loft)
* [`patternCircular2d`](/docs/kcl-std/functions/std-sketch-patternCircular2d)
* [`patternLinear2d`](/docs/kcl-std/functions/std-sketch-patternLinear2d)
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
* [`polygon`](/docs/kcl-std/polygon)
* [`profileStart`](/docs/kcl-std/profileStart)
* [`profileStartX`](/docs/kcl-std/profileStartX)
* [`profileStartY`](/docs/kcl-std/profileStartY)
* [`polygon`](/docs/kcl-std/functions/std-sketch-polygon)
* [`profileStart`](/docs/kcl-std/functions/std-sketch-profileStart)
* [`profileStartX`](/docs/kcl-std/functions/std-sketch-profileStartX)
* [`profileStartY`](/docs/kcl-std/functions/std-sketch-profileStartY)
* [`revolve`](/docs/kcl-std/functions/std-sketch-revolve)
* [`segAng`](/docs/kcl-std/segAng)
* [`segEnd`](/docs/kcl-std/segEnd)
* [`segEndX`](/docs/kcl-std/segEndX)
* [`segEndY`](/docs/kcl-std/segEndY)
* [`segLen`](/docs/kcl-std/segLen)
* [`segStart`](/docs/kcl-std/segStart)
* [`segStartX`](/docs/kcl-std/segStartX)
* [`segStartY`](/docs/kcl-std/segStartY)
* [`startProfile`](/docs/kcl-std/startProfile)
* [`startSketchOn`](/docs/kcl-std/startSketchOn)
* [`subtract2d`](/docs/kcl-std/subtract2d)
* [`sweep`](/docs/kcl-std/sweep)
* [`tangentToEnd`](/docs/kcl-std/tangentToEnd)
* [`tangentialArc`](/docs/kcl-std/tangentialArc)
* [`xLine`](/docs/kcl-std/xLine)
* [`yLine`](/docs/kcl-std/yLine)
* [`segAng`](/docs/kcl-std/functions/std-sketch-segAng)
* [`segEnd`](/docs/kcl-std/functions/std-sketch-segEnd)
* [`segEndX`](/docs/kcl-std/functions/std-sketch-segEndX)
* [`segEndY`](/docs/kcl-std/functions/std-sketch-segEndY)
* [`segLen`](/docs/kcl-std/functions/std-sketch-segLen)
* [`segStart`](/docs/kcl-std/functions/std-sketch-segStart)
* [`segStartX`](/docs/kcl-std/functions/std-sketch-segStartX)
* [`segStartY`](/docs/kcl-std/functions/std-sketch-segStartY)
* [`startProfile`](/docs/kcl-std/functions/std-sketch-startProfile)
* [`startSketchOn`](/docs/kcl-std/functions/std-sketch-startSketchOn)
* [`subtract2d`](/docs/kcl-std/functions/std-sketch-subtract2d)
* [`sweep`](/docs/kcl-std/functions/std-sketch-sweep)
* [`tangentToEnd`](/docs/kcl-std/functions/std-sketch-tangentToEnd)
* [`tangentialArc`](/docs/kcl-std/functions/std-sketch-tangentialArc)
* [`xLine`](/docs/kcl-std/functions/std-sketch-xLine)
* [`yLine`](/docs/kcl-std/functions/std-sketch-yLine)
* [**std::solid**](/docs/kcl-std/modules/std-solid)
* [`appearance`](/docs/kcl-std/functions/std-solid-appearance)
* [`chamfer`](/docs/kcl-std/functions/std-solid-chamfer)
* [`fillet`](/docs/kcl-std/functions/std-solid-fillet)
* [`hollow`](/docs/kcl-std/functions/std-solid-hollow)
* [`intersect`](/docs/kcl-std/intersect)
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
* [`patternLinear3d`](/docs/kcl-std/patternLinear3d)
* [`intersect`](/docs/kcl-std/functions/std-solid-intersect)
* [`patternCircular3d`](/docs/kcl-std/functions/std-solid-patternCircular3d)
* [`patternLinear3d`](/docs/kcl-std/functions/std-solid-patternLinear3d)
* [`patternTransform`](/docs/kcl-std/functions/std-solid-patternTransform)
* [`shell`](/docs/kcl-std/functions/std-solid-shell)
* [`subtract`](/docs/kcl-std/subtract)
* [`union`](/docs/kcl-std/union)
* [`subtract`](/docs/kcl-std/functions/std-solid-subtract)
* [`union`](/docs/kcl-std/functions/std-solid-union)
* [**std::transform**](/docs/kcl-std/modules/std-transform)
* [`mirror2d`](/docs/kcl-std/functions/std-transform-mirror2d)
* [`rotate`](/docs/kcl-std/rotate)
* [`scale`](/docs/kcl-std/scale)
* [`translate`](/docs/kcl-std/translate)
* [`rotate`](/docs/kcl-std/functions/std-transform-rotate)
* [`scale`](/docs/kcl-std/functions/std-transform-scale)
* [`translate`](/docs/kcl-std/functions/std-transform-translate)
* [**std::units**](/docs/kcl-std/modules/std-units)
* [`units::toCentimeters`](/docs/kcl-std/functions/std-units-toCentimeters)
* [`units::toDegrees`](/docs/kcl-std/functions/std-units-toDegrees)
@ -142,11 +144,7 @@ layout: manual
See also the [types overview](/docs/kcl-lang/types)
* [**Primitive types**](/docs/kcl-lang/types)
* [`End`](/docs/kcl-lang/types#End)
* [`ImportedGeometry`](/docs/kcl-std/types/std-types-ImportedGeometry)
* [`Start`](/docs/kcl-lang/types#Start)
* [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator)
* [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier)
* [`any`](/docs/kcl-std/types/std-types-any)
* [`bool`](/docs/kcl-std/types/std-types-bool)
* [`fn`](/docs/kcl-std/types/std-types-fn)

View File

@ -0,0 +1,16 @@
---
title: "appearance"
subtitle: "Module in std"
excerpt: ""
layout: manual
---
## Functions and constants
* [`appearance::hexString`](/docs/kcl-std/functions/std-appearance-hexString)

View File

@ -12,44 +12,45 @@ This module contains functions for creating and manipulating sketches, and makin
## Functions and constants
* [`angledLine`](/docs/kcl-std/angledLine)
* [`angledLineThatIntersects`](/docs/kcl-std/angledLineThatIntersects)
* [`arc`](/docs/kcl-std/arc)
* [`bezierCurve`](/docs/kcl-std/bezierCurve)
* [`angledLine`](/docs/kcl-std/functions/std-sketch-angledLine)
* [`angledLineThatIntersects`](/docs/kcl-std/functions/std-sketch-angledLineThatIntersects)
* [`arc`](/docs/kcl-std/functions/std-sketch-arc)
* [`bezierCurve`](/docs/kcl-std/functions/std-sketch-bezierCurve)
* [`circle`](/docs/kcl-std/functions/std-sketch-circle)
* [`circleThreePoint`](/docs/kcl-std/circleThreePoint)
* [`close`](/docs/kcl-std/close)
* [`extrude`](/docs/kcl-std/extrude)
* [`getCommonEdge`](/docs/kcl-std/getCommonEdge)
* [`getNextAdjacentEdge`](/docs/kcl-std/getNextAdjacentEdge)
* [`getOppositeEdge`](/docs/kcl-std/getOppositeEdge)
* [`getPreviousAdjacentEdge`](/docs/kcl-std/getPreviousAdjacentEdge)
* [`involuteCircular`](/docs/kcl-std/involuteCircular)
* [`lastSegX`](/docs/kcl-std/lastSegX)
* [`lastSegY`](/docs/kcl-std/lastSegY)
* [`line`](/docs/kcl-std/line)
* [`loft`](/docs/kcl-std/loft)
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
* [`circleThreePoint`](/docs/kcl-std/functions/std-sketch-circleThreePoint)
* [`close`](/docs/kcl-std/functions/std-sketch-close)
* [`extrude`](/docs/kcl-std/functions/std-sketch-extrude)
* [`getCommonEdge`](/docs/kcl-std/functions/std-sketch-getCommonEdge)
* [`getNextAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getNextAdjacentEdge)
* [`getOppositeEdge`](/docs/kcl-std/functions/std-sketch-getOppositeEdge)
* [`getPreviousAdjacentEdge`](/docs/kcl-std/functions/std-sketch-getPreviousAdjacentEdge)
* [`involuteCircular`](/docs/kcl-std/functions/std-sketch-involuteCircular)
* [`lastSegX`](/docs/kcl-std/functions/std-sketch-lastSegX)
* [`lastSegY`](/docs/kcl-std/functions/std-sketch-lastSegY)
* [`line`](/docs/kcl-std/functions/std-sketch-line)
* [`loft`](/docs/kcl-std/functions/std-sketch-loft)
* [`patternCircular2d`](/docs/kcl-std/functions/std-sketch-patternCircular2d)
* [`patternLinear2d`](/docs/kcl-std/functions/std-sketch-patternLinear2d)
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
* [`polygon`](/docs/kcl-std/polygon)
* [`profileStart`](/docs/kcl-std/profileStart)
* [`profileStartX`](/docs/kcl-std/profileStartX)
* [`profileStartY`](/docs/kcl-std/profileStartY)
* [`polygon`](/docs/kcl-std/functions/std-sketch-polygon)
* [`profileStart`](/docs/kcl-std/functions/std-sketch-profileStart)
* [`profileStartX`](/docs/kcl-std/functions/std-sketch-profileStartX)
* [`profileStartY`](/docs/kcl-std/functions/std-sketch-profileStartY)
* [`revolve`](/docs/kcl-std/functions/std-sketch-revolve)
* [`segAng`](/docs/kcl-std/segAng)
* [`segEnd`](/docs/kcl-std/segEnd)
* [`segEndX`](/docs/kcl-std/segEndX)
* [`segEndY`](/docs/kcl-std/segEndY)
* [`segLen`](/docs/kcl-std/segLen)
* [`segStart`](/docs/kcl-std/segStart)
* [`segStartX`](/docs/kcl-std/segStartX)
* [`segStartY`](/docs/kcl-std/segStartY)
* [`startProfile`](/docs/kcl-std/startProfile)
* [`startSketchOn`](/docs/kcl-std/startSketchOn)
* [`subtract2d`](/docs/kcl-std/subtract2d)
* [`sweep`](/docs/kcl-std/sweep)
* [`tangentToEnd`](/docs/kcl-std/tangentToEnd)
* [`tangentialArc`](/docs/kcl-std/tangentialArc)
* [`xLine`](/docs/kcl-std/xLine)
* [`yLine`](/docs/kcl-std/yLine)
* [`segAng`](/docs/kcl-std/functions/std-sketch-segAng)
* [`segEnd`](/docs/kcl-std/functions/std-sketch-segEnd)
* [`segEndX`](/docs/kcl-std/functions/std-sketch-segEndX)
* [`segEndY`](/docs/kcl-std/functions/std-sketch-segEndY)
* [`segLen`](/docs/kcl-std/functions/std-sketch-segLen)
* [`segStart`](/docs/kcl-std/functions/std-sketch-segStart)
* [`segStartX`](/docs/kcl-std/functions/std-sketch-segStartX)
* [`segStartY`](/docs/kcl-std/functions/std-sketch-segStartY)
* [`startProfile`](/docs/kcl-std/functions/std-sketch-startProfile)
* [`startSketchOn`](/docs/kcl-std/functions/std-sketch-startSketchOn)
* [`subtract2d`](/docs/kcl-std/functions/std-sketch-subtract2d)
* [`sweep`](/docs/kcl-std/functions/std-sketch-sweep)
* [`tangentToEnd`](/docs/kcl-std/functions/std-sketch-tangentToEnd)
* [`tangentialArc`](/docs/kcl-std/functions/std-sketch-tangentialArc)
* [`xLine`](/docs/kcl-std/functions/std-sketch-xLine)
* [`yLine`](/docs/kcl-std/functions/std-sketch-yLine)

View File

@ -12,14 +12,15 @@ This module contains functions for modifying solids, e.g., by adding a fillet or
## Functions and constants
* [`appearance`](/docs/kcl-std/functions/std-solid-appearance)
* [`chamfer`](/docs/kcl-std/functions/std-solid-chamfer)
* [`fillet`](/docs/kcl-std/functions/std-solid-fillet)
* [`hollow`](/docs/kcl-std/functions/std-solid-hollow)
* [`intersect`](/docs/kcl-std/intersect)
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
* [`patternLinear3d`](/docs/kcl-std/patternLinear3d)
* [`intersect`](/docs/kcl-std/functions/std-solid-intersect)
* [`patternCircular3d`](/docs/kcl-std/functions/std-solid-patternCircular3d)
* [`patternLinear3d`](/docs/kcl-std/functions/std-solid-patternLinear3d)
* [`patternTransform`](/docs/kcl-std/functions/std-solid-patternTransform)
* [`shell`](/docs/kcl-std/functions/std-solid-shell)
* [`subtract`](/docs/kcl-std/subtract)
* [`union`](/docs/kcl-std/union)
* [`subtract`](/docs/kcl-std/functions/std-solid-subtract)
* [`union`](/docs/kcl-std/functions/std-solid-union)

View File

@ -13,7 +13,7 @@ This module contains functions for transforming sketches and solids.
## Functions and constants
* [`mirror2d`](/docs/kcl-std/functions/std-transform-mirror2d)
* [`rotate`](/docs/kcl-std/rotate)
* [`scale`](/docs/kcl-std/scale)
* [`translate`](/docs/kcl-std/translate)
* [`rotate`](/docs/kcl-std/functions/std-transform-rotate)
* [`scale`](/docs/kcl-std/functions/std-transform-scale)
* [`translate`](/docs/kcl-std/functions/std-transform-translate)

View File

@ -15,6 +15,7 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui
## Modules
* [`appearance::appearance`](/docs/kcl-std/modules/std-appearance)
* [`array`](/docs/kcl-std/modules/std-array)
* [`math`](/docs/kcl-std/modules/std-math)
* [`sketch`](/docs/kcl-std/modules/std-sketch)
@ -35,11 +36,9 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui
* [`Y`](/docs/kcl-std/consts/std-Y)
* [`YZ`](/docs/kcl-std/consts/std-YZ)
* [`Z`](/docs/kcl-std/consts/std-Z)
* [`appearance`](/docs/kcl-std/appearance)
* [`assert`](/docs/kcl-std/assert)
* [`assertIs`](/docs/kcl-std/assertIs)
* [`assert`](/docs/kcl-std/functions/std-assert)
* [`assertIs`](/docs/kcl-std/functions/std-assertIs)
* [`clone`](/docs/kcl-std/functions/std-clone)
* [`helix`](/docs/kcl-std/functions/std-helix)
* [`offsetPlane`](/docs/kcl-std/functions/std-offsetPlane)
* [`patternLinear2d`](/docs/kcl-std/patternLinear2d)

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,13 @@
---
title: "any"
subtitle: "Type in std::types"
excerpt: ""
excerpt: "The [`any`](/docs/kcl-std/types/std-types-any) type is the type of all possible values in KCL. I.e., if a function accepts an argument with type [`any`](/docs/kcl-std/types/std-types-any), then it can accept any value."
layout: manual
---
The [`any`](/docs/kcl-std/types/std-types-any) type is the type of all possible values in KCL. I.e., if a function accepts an argument with type [`any`](/docs/kcl-std/types/std-types-any), then it can accept any value.
The [`any`](/docs/kcl-std/types/std-types-any) type is the type of all possible values in KCL. I.e., if a function accepts an argument
with type [`any`](/docs/kcl-std/types/std-types-any), then it can accept any value.
### Examples

View File

@ -5,7 +5,7 @@ import * as fsp from 'fs/promises'
test.describe('Electron app header tests', () => {
test(
'Open Command Palette button has correct shortcut',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -30,7 +30,7 @@ test.describe('Electron app header tests', () => {
test(
'User settings has correct shortcut',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, toolbar }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })

View File

@ -4,7 +4,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Authentication tests', () => {
test(
`The user can sign out and back in`,
{ tag: ['@electron'] },
{ tag: ['@desktop'] },
async ({ page, homePage, signInPage, toolbar, tronApp }) => {
if (!tronApp) {
fail()

View File

@ -265,6 +265,7 @@ middle(0)
})
await expect(
page.getByText(`assert failed: Expected 0 to be greater than 0 but it wasn't
assert()
check()
middle()`)
).toBeVisible()
@ -275,7 +276,7 @@ middle()`)
test(
'Opening multiple panes persists when switching projects',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
// Setup multiple projects.
await context.folderSetupFn(async (dir) => {
@ -346,7 +347,7 @@ test(
test(
'external change of file contents are reflected in editor',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const PROJECT_DIR_NAME = 'lee-was-here'
const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {

View File

@ -519,7 +519,7 @@ test.describe('Command bar tests', () => {
`Zoom to fit to shared model on web`,
{ tag: ['@web'] },
async ({ page, scene }) => {
if (process.env.PLATFORM !== 'web') {
if (process.env.TARGET !== 'web') {
// This test is web-only
// TODO: re-enable on CI as part of a new @web test suite
return
@ -534,7 +534,7 @@ profile001 = startProfile(sketch001, at = [-484.34, 484.95])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
`
const targetURL = `?create-file&name=test&units=mm&code=${encodeURIComponent(btoa(code))}&ask-open-desktop`
const targetURL = `?create-file=true&name=test&units=mm&code=${encodeURIComponent(btoa(code))}&ask-open-desktop=true`
await page.goto(page.url() + targetURL)
expect(page.url()).toContain(targetURL)
})

View File

@ -10,7 +10,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test(
'export works on the first try',
{ tag: ['@electron', '@macos', '@windows', '@skipLocalEngine'] },
{ tag: ['@desktop', '@macos', '@windows', '@skipLocalEngine'] },
async ({ page, context, scene, tronApp, cmdBar }, testInfo) => {
if (!tronApp) {
fail()

View File

@ -964,8 +964,6 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // accepting the auto complete, not a new line
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
await page.keyboard.type('12')
@ -984,8 +982,6 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Enter')
// finish line with comment
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
await page.keyboard.type('5')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
@ -1001,8 +997,8 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfile(%, at = [0, 12])
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
|> startProfile(at = [0, 12])
|> xLine(length = 5) // lin`.replaceAll('\n', '')
)
// expect there to be no KCL errors
@ -1040,8 +1036,6 @@ sketch001 = startSketchOn(XZ)
await page.waitForTimeout(100)
await page.keyboard.press('Tab') // accepting the auto complete, not a new line
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
await page.keyboard.type('12')
await page.waitForTimeout(100)
@ -1057,7 +1051,6 @@ sketch001 = startSketchOn(XZ)
await page.waitForTimeout(100)
// press arrow down then tab to accept xLine
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Tab')
// finish line with comment
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
@ -1076,8 +1069,8 @@ sketch001 = startSketchOn(XZ)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfile(%, at = [0, 12])
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
|> startProfile(at = [0, 12])
|> xLine(length = 5) // lin`.replaceAll('\n', '')
)
})
})
@ -1337,7 +1330,7 @@ sketch001 = startSketchOn(XZ)
test(
`Can import a local OBJ file`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'cube')

View File

@ -57,7 +57,7 @@ sketch003 = startSketchOn(plane001)
test.describe('Feature Tree pane', () => {
test(
'User can go to definition and go to function definition',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, homePage, scene, editor, toolbar, cmdBar, page }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'test-sample')
@ -150,7 +150,7 @@ test.describe('Feature Tree pane', () => {
test(
`User can edit sketch (but not on offset plane yet) from the feature tree`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, homePage, scene, editor, toolbar, page }) => {
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)

View File

@ -13,7 +13,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('integrations tests', () => {
test(
'Creating a new file or switching file while in sketchMode should exit sketchMode',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context, homePage, scene, editor, toolbar, cmdBar }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'test-sample')
@ -100,7 +100,7 @@ test.describe('when using the file tree to', () => {
test(
`rename ${fromFile} to ${toFile}, and doesn't crash on reload and settings load`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const { panesOpen, pasteCodeInEditor, renameFile, editorTextMatches } =
await getUtils(page, test)
@ -142,7 +142,7 @@ test.describe('when using the file tree to', () => {
test(
`create many new files of the same name, incrementing their names`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const { panesOpen, createNewFile } = await getUtils(page, test)
@ -174,7 +174,7 @@ test.describe('when using the file tree to', () => {
test(
'create a new file with the same name as an existing file cancels the operation',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, homePage, scene, editor, toolbar }, testInfo) => {
const projectName = 'cube'
const mainFile = 'main.kcl'
@ -240,7 +240,7 @@ test.describe('when using the file tree to', () => {
test(
`create new folders and that doesn't trigger a navigation`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ page, homePage, scene, toolbar, cmdBar }) => {
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -260,7 +260,7 @@ test.describe('when using the file tree to', () => {
test(
'deleting all files recreates a default main.kcl with no code',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const { panesOpen, pasteCodeInEditor, deleteFile, editorTextMatches } =
await getUtils(page, test)
@ -291,7 +291,7 @@ test.describe('when using the file tree to', () => {
test(
'loading small file, then large, then back to small',
{
tag: '@electron',
tag: '@desktop',
},
async ({ page }, testInfo) => {
const {
@ -361,7 +361,7 @@ test.describe('when using the file tree to', () => {
test.describe('Renaming in the file tree', () => {
test(
'A file you have open',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -450,7 +450,7 @@ test.describe('Renaming in the file tree', () => {
test(
'A file you do not have open',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -536,7 +536,7 @@ test.describe('Renaming in the file tree', () => {
test(
`A folder you're not inside`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -618,7 +618,7 @@ test.describe('Renaming in the file tree', () => {
test(
`A folder you are inside`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -721,7 +721,7 @@ test.describe('Renaming in the file tree', () => {
test.describe('Deleting items from the file pane', () => {
test(
`delete file when main.kcl exists, navigate to main.kcl`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'testProject')
@ -786,7 +786,7 @@ test.describe('Deleting items from the file pane', () => {
test(
`Delete folder we are not in, don't navigate`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -840,7 +840,7 @@ test.describe('Deleting items from the file pane', () => {
test(
`Delete folder we are in, navigate to main.kcl`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(join(dir, 'Test Project'), { recursive: true })
@ -906,7 +906,7 @@ test.describe('Deleting items from the file pane', () => {
// Copied from tests above.
test(
`external deletion of project navigates back home`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const TEST_PROJECT_NAME = 'Test Project'
const { dir: projectsDirName } = await context.folderSetupFn(
@ -970,7 +970,7 @@ test.describe('Deleting items from the file pane', () => {
// Similar to the above
test(
`external deletion of file in sub-directory updates the file tree and recreates it on code editor typing`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const TEST_PROJECT_NAME = 'Test Project'
const { dir: projectsDirName } = await context.folderSetupFn(
@ -1045,7 +1045,7 @@ test.describe('Deleting items from the file pane', () => {
test.describe('Undo and redo do not keep history when navigating between files', () => {
test(
`open a file, change something, open a different file, hitting undo should do nothing`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'testProject')
@ -1112,7 +1112,7 @@ test.describe('Undo and redo do not keep history when navigating between files',
test(
`open a file, change something, undo it, open a different file, hitting redo should do nothing`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'testProject')
@ -1212,7 +1212,7 @@ test.describe('Undo and redo do not keep history when navigating between files',
test(
`cloned file has an incremented name and same contents`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, context, homePage }, testInfo) => {
const { panesOpen, cloneFile } = await getUtils(page, test)

View File

@ -394,7 +394,7 @@ const fixturesBasedOnProcessEnvPlatform = {
},
}
if (process.env.PLATFORM === 'web') {
if (process.env.TARGET === 'web') {
Object.assign(fixturesBasedOnProcessEnvPlatform, fixturesForWeb)
} else {
Object.assign(fixturesBasedOnProcessEnvPlatform, fixturesForElectron)

View File

@ -126,7 +126,7 @@ export class HomePageFixture {
/** Returns the project name in case caller has used the default and needs it */
goToModelingScene = async (name = 'testDefault') => {
// On web this is a no-op. There is no project view.
if (process.env.PLATFORM === 'web') return ''
if (process.env.TARGET === 'web') return ''
await this.createAndGoToProject(name)
return name

View File

@ -5,7 +5,7 @@ import * as fsp from 'fs/promises'
test.describe('Import UI tests', () => {
test(
'shows toast when trying to sketch on imported face, and hovering over imported geometry should NOT highlight any code',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ context, page, homePage, toolbar, scene, editor, cmdBar }) => {
await context.folderSetupFn(async (dir) => {
const projectDir = path.join(dir, 'import-test')

View File

@ -6,7 +6,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test(
'When machine-api server not found butt is disabled and shows the reason',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'bracket')
@ -43,7 +43,7 @@ test(
test(
'When machine-api server not found home screen & project status shows the reason',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'bracket')

View File

@ -13,7 +13,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
*/
test.describe(
'Native file menu',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
() => {
test('Home page', async ({ tronApp, cmdBar, page, homePage }) => {
if (!tronApp) fail()

View File

@ -43,7 +43,7 @@ async function insertPartIntoAssembly(
test.describe('Point-and-click assemblies tests', () => {
test(
`Insert kcl parts into assembly as whole module import`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -188,7 +188,7 @@ test.describe('Point-and-click assemblies tests', () => {
await page.waitForTimeout(10000)
await editor.expectEditor.toContain(
`
import "nested/twice/main.kcl" as main
import "nested/twice/main.kcl" as main
`,
{ shouldNormalise: true }
)
@ -198,7 +198,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
`Can still translate, rotate, and delete inserted parts even with non standard code`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -394,7 +394,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
`Insert the bracket part into an assembly and transform it`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -585,7 +585,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
`Insert foreign parts into assembly and delete them`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,
@ -736,7 +736,7 @@ test.describe('Point-and-click assemblies tests', () => {
test(
'Assembly gets reexecuted when imported models are updated externally',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ context, page, homePage, scene, toolbar, cmdBar, tronApp }) => {
if (!tronApp) {
fail()
@ -826,7 +826,7 @@ foreign
test(
`Point-and-click clone`,
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({
context,
page,

View File

@ -1766,7 +1766,7 @@ loft001 = loft([sketch001, sketch002])
sketch001 = startSketchOn(YZ)
profile001 = circle(sketch001, center = [0, 0], radius = 500)
sketch002 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
profile002 = startProfile(sketch002, at = [0, 0])
|> xLine(length = -500)
|> tangentialArc(endAbsolute = [-2000, 500])`,
},
@ -1782,7 +1782,7 @@ profile001 = startProfile(sketch001, at = [-400, -400])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
sketch002 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
profile002 = startProfile(sketch002, at = [0, 0])
|> xLine(length = -500)
|> tangentialArc(endAbsolute = [-2000, 500])`,
},
@ -1810,9 +1810,9 @@ sketch002 = startSketchOn(XZ)
testPoint.x - 50,
testPoint.y
)
const sweepDeclaration = 'sweep001 = sweep(profile001, path = sketch002)'
const sweepDeclaration = 'sweep001 = sweep(profile001, path = profile002)'
const editedSweepDeclaration =
'sweep001 = sweep(profile001, path = sketch002, sectional = true)'
'sweep001 = sweep(profile001, path = profile002, sectional = true)'
await test.step(`Look for sketch001`, async () => {
await toolbar.closePane('code')

View File

@ -17,7 +17,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
test(
'projects reload if a new one is created, deleted, or renamed externally',
{ tag: ['@electron', '@macos', '@windows'] },
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ context, page }, testInfo) => {
let externalCreatedProjectName = 'external-created-project'
@ -63,7 +63,7 @@ test(
test(
'click help/keybindings from home page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -81,7 +81,7 @@ test(
test(
'click help/keybindings from project page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -112,7 +112,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' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page, editor }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -169,7 +169,8 @@ test(
// error text on hover
await page.hover('.cm-lint-marker-error')
const crypticErrorText = `The arg tag was given, but it was the wrong type`
const crypticErrorText =
'tag requires a value with type `tag`, but found string'
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
// black pixel means the scene has been cleared.
@ -184,7 +185,7 @@ test(
test(
'open a file in a project works and renders, open another file in different project that is empty, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -244,7 +245,7 @@ test(
test(
'open a file in a project works and renders, open empty file, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -310,7 +311,7 @@ test(
test(
'open a file in a project works and renders, open another file in the same project with errors, it should clear the scene',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -367,7 +368,8 @@ test(
// error text on hover
await page.hover('.cm-lint-marker-error')
const crypticErrorText = `The arg tag was given, but it was the wrong type`
const crypticErrorText =
'tag requires a value with type `tag`, but found string'
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
// black pixel means the scene has been cleared.
@ -382,7 +384,7 @@ test(
test(
'when code with error first loads you get errors in console',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, editor }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(path.join(dir, 'broken-code'), { recursive: true })
@ -405,7 +407,8 @@ test(
// error text on hover
await page.hover('.cm-lint-marker-error')
const crypticErrorText = `The arg tag was given, but it was the wrong type`
const crypticErrorText =
'tag requires a value with type `tag`, but found string'
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
}
)
@ -416,7 +419,7 @@ test.describe('Can export from electron app', () => {
for (const method of exportMethods) {
test(
`Can export using ${method}`,
{ tag: ['@electron', '@skipLocalEngine'] },
{ tag: ['@desktop', '@skipLocalEngine'] },
async ({ scene, cmdBar, context, page, tronApp }, testInfo) => {
if (!tronApp) {
fail()
@ -507,7 +510,7 @@ test.describe('Can export from electron app', () => {
})
test(
'Rename and delete projects, also spam arrow keys when renaming',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
@ -723,7 +726,7 @@ test(
test(
'pressing "delete" on home screen should do nothing',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, homePage }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
@ -753,7 +756,7 @@ test(
test.describe(`Project management commands`, () => {
test(
`Rename from project page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_rename`
await context.folderSetupFn(async (dir) => {
@ -815,7 +818,7 @@ test.describe(`Project management commands`, () => {
test(
`Delete from project page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_delete`
await context.folderSetupFn(async (dir) => {
@ -869,7 +872,7 @@ test.describe(`Project management commands`, () => {
)
test(
`Rename from home page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, homePage, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_rename`
await context.folderSetupFn(async (dir) => {
@ -927,7 +930,7 @@ test.describe(`Project management commands`, () => {
)
test(
`Delete from home page`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
const projectName = `my_project_to_delete`
await context.folderSetupFn(async (dir) => {
@ -1103,7 +1106,7 @@ test(`Create a few projects using the default project name`, async ({
test(
'File in the file pane should open with a single click',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, homePage, page }, testInfo) => {
const projectName = 'router-template-slate'
await context.folderSetupFn(async (dir) => {
@ -1145,7 +1148,7 @@ test(
test(
'Nested directories in project without main.kcl do not create main.kcl',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
let testDir: string | undefined
await context.folderSetupFn(async (dir) => {
@ -1202,7 +1205,7 @@ test(
test(
'Deleting projects, can delete individual project, can still create projects after deleting all',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectData = [
['router-template-slate', 'cylinder.kcl'],
@ -1280,7 +1283,7 @@ test(
test(
'Can load a file with CRLF line endings',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, scene, cmdBar }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const routerTemplateDir = path.join(dir, 'router-template-slate')
@ -1312,7 +1315,7 @@ test(
test(
'Can sort projects on home page',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectData = [
['router-template-slate', 'cylinder.kcl'],
@ -1419,7 +1422,7 @@ test(
test(
'When the project folder is empty, user can create new project and open it.',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page }, testInfo) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -1515,7 +1518,7 @@ extrude001 = extrude(sketch001, length = 200)`)
test(
'Opening a project should successfully load the stream, (regression test that this also works when switching between projects)',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, cmdBar, homePage, scene }, testInfo) => {
await context.folderSetupFn(async (dir) => {
await fsp.mkdir(path.join(dir, 'router-template-slate'), {
@ -1628,7 +1631,7 @@ test(
test(
'You can change the root projects directory and nothing is lost',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page, tronApp, homePage }, testInfo) => {
if (!tronApp) {
fail()
@ -1735,7 +1738,7 @@ test(
test(
'Search projects on desktop home',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
const projectData = [
['basic bracket', 'focusrite_scarlett_mounting_bracket.kcl'],
@ -1791,7 +1794,7 @@ test(
test(
'file pane is scrollable when there are many files',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const testDir = path.join(dir, 'testProject')
@ -1892,7 +1895,7 @@ test(
test(
'select all in code editor does not actually select all, just what is visible (regression)',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
// rust/kcl-lib/e2e/executor/inputs/mike_stress_test.kcl
@ -1950,7 +1953,7 @@ test(
test(
'Settings persist across restarts',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, toolbar }, testInfo) => {
await test.step('We can change a user setting like theme', async () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -1982,7 +1985,7 @@ test(
test(
'Original project name persist after onboarding',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ page, toolbar }, testInfo) => {
const nextButton = page.getByTestId('onboarding-next')
await page.setBodyDimensions({ width: 1200, height: 500 })
@ -2022,7 +2025,7 @@ test(
test(
'project name with foreign characters should open',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'العربية')
@ -2067,7 +2070,7 @@ test(
test(
'import from nested directory',
{ tag: ['@electron', '@windows', '@macos'] },
{ tag: ['@desktop', '@windows', '@macos'] },
async ({ scene, cmdBar, context, page }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
@ -2116,3 +2119,74 @@ test(
})
}
)
test(
'segment position changes persist after dragging and reopening project',
{ tag: '@desktop' },
async ({ scene, cmdBar, context, page, editor, toolbar }, testInfo) => {
const projectName = 'segment-drag-test'
await context.folderSetupFn(async (dir) => {
const projectDir = path.join(dir, projectName)
await fsp.mkdir(projectDir, { recursive: true })
await fsp.writeFile(
path.join(projectDir, 'main.kcl'),
`sketch001 = startSketchOn(XZ)
profile001 = startProfile(sketch001, at = [0, 0])
|> line(end = [0, 6])
|> line(end = [10, 0])
|> line(end = [-8, -5])
`
)
})
await page.setBodyDimensions({ width: 1200, height: 600 })
const u = await getUtils(page)
await test.step('Opening the project and entering sketch mode', async () => {
await expect(page.getByText(projectName)).toBeVisible()
await page.getByText(projectName).click()
await scene.settled(cmdBar)
// go to sketch mode
await (await toolbar.getFeatureTreeOperation('Sketch', 0)).dblclick()
// Without this, "add axis n grid" action runs after editing the sketch and invokes codeManager.writeToFile()
// so we wait for that action to run first before we start editing the sketch and making sure it's saving
// because of those edits.
await page.waitForTimeout(2000)
})
const changedLine = 'line(end = [-6.54, -4.99])'
await test.step('Dragging the line endpoint to modify it', async () => {
// Get the last line's endpoint position
const lineEnd = await u.getBoundingBox('[data-overlay-index="3"]')
await page.mouse.move(lineEnd.x, lineEnd.y - 5)
await page.mouse.down()
await page.mouse.move(lineEnd.x + 80, lineEnd.y)
await page.mouse.up()
await editor.expectEditor.toContain(changedLine)
// Exit sketch mode
await page.keyboard.press('Escape')
await page.waitForTimeout(100)
})
await test.step('Going back to dashboard', async () => {
await page.getByTestId('app-logo').click()
await page.waitForTimeout(1000)
})
await test.step('Reopening the project and verifying changes are saved', async () => {
await page.getByText(projectName).click()
await scene.settled(cmdBar)
// Check if new line coordinates were saved
await editor.expectEditor.toContain(changedLine)
})
}
)

View File

@ -63,7 +63,7 @@ test.describe('edit with AI example snapshots', () => {
test(
`change colour`,
// TODO this is more of a snapshot, but atm it needs to be manually run locally to update the files
{ tag: ['@electron'] },
{ tag: ['@desktop'] },
async ({ context, homePage, cmdBar, editor, page, scene }) => {
const project = 'test-dir'
await context.folderSetupFn(async (dir) => {

View File

@ -558,7 +558,7 @@ extrude002 = extrude(profile002, length = 150)
test(
`Network health indicator only appears in modeling view`,
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')

View File

@ -17,7 +17,7 @@ test.describe('Share link tests', () => {
`Open in desktop app with ${codeLength}-long code ${isWindows && showsErrorOnWindows ? 'shows error' : "doesn't show error"}`,
{ tag: ['@web'] },
async ({ page }) => {
if (process.env.PLATFORM !== 'web') {
if (process.env.TARGET !== 'web') {
// This test is web-only
// TODO: re-enable on CI as part of a new @web test suite
return

View File

@ -749,7 +749,7 @@ sketch001 = startSketchOn(XZ)
// expect the code to have changed
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfile(at = [8.41, -9.97])
|> startProfile(at = [8.41, -9.97])
|> line(end = [12.73, -0.09])
|> line(end = [1.99, 2.06])
|> tangentialArc(endAbsolute = [24.95, -5.38])
@ -1733,7 +1733,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
await page.waitForTimeout(600)
})
const codeFromTangentialArc = ` |> tangentialArc(endAbsolute = [39.49, 88.22])`
const codeFromTangentialArc = ` |> tangentialArc(end = [-10.82, 144.95])`
await test.step('check that tangential tool does not snap to other profile starts', async () => {
await toolbar.selectTangentialArc()
await page.waitForTimeout(1000)
@ -1755,7 +1755,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
// check pixel is now gray at tanArcLocation to verify code has executed
await scene.expectPixelColor([26, 26, 26], tanArcLocation, 15)
await editor.expectEditor.not.toContain(
`tangentialArc(endAbsolute = [39.49, 88.22])`
`tangentialArc(end = [-10.82, 144.95])`
)
})
@ -1955,7 +1955,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
await endArcStartLine()
await editor.expectEditor.toContain(
`|> tangentialArc(endAbsolute = [16.61, 4.14])`
`|> tangentialArc(end = [2.98, -7.52])`
)
// Add a three-point arc segment
@ -2329,16 +2329,18 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
await page.mouse.down()
await rectDragTo()
await page.mouse.up()
await page.waitForTimeout(200)
await editor.expectEditor.toContain(
`angledLine(angle = -7, length = 10.27, tag = $rectangleSegmentA001)`
)
})
await test.step('edit existing circl', async () => {
await test.step('edit existing circle', async () => {
await circleEdge()
await page.mouse.down()
await dragCircleTo()
await page.mouse.up()
await page.waitForTimeout(200)
await editor.expectEditor.toContain(
`profile003 = circle(sketch001, center = [6.92, -4.2], radius = 4.81)`
)
@ -2349,6 +2351,7 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
await page.mouse.down()
await circ3PEnd()
await page.mouse.up()
await page.waitForTimeout(200)
await editor.expectEditor.toContain(
`profile004 = circleThreePoint(
sketch001,
@ -2362,7 +2365,7 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
await test.step('add new profile', async () => {
await toolbar.rectangleBtn.click()
await page.waitForTimeout(100)
await page.waitForTimeout(200)
await rectStart()
await editor.expectEditor.toContain(
`profile005 = startProfile(sketch001, at = [15.68, -3.84])`
@ -3181,7 +3184,7 @@ test.describe('Redirecting to home page and back to the original file should cle
sketch001 = startSketchOn(XZ)
profile001 = startProfile(sketch001, at = [0, 0])
|> line(end = [191.39, 191.39])
|> tangentialArc(endAbsolute = [287.08, 95.69], tag = $seg01)
|> tangentialArc(end = [95.69, -95.7], tag = $seg01)
|> angledLine(angle = tangentToEnd(seg01), length = 135.34)
|> arc(interiorAbsolute = [191.39, -95.69], endAbsolute = [287.08, -95.69], tag = $seg02)
|> angledLine(angle = tangentToEnd(seg02) + turns::HALF_TURN, length = 270.67)

View File

@ -375,22 +375,22 @@ test.describe(
await expect(u.codeLocator).toHaveText(code)
await toolbar.selectTangentialArc()
await page.waitForTimeout(100)
await page.waitForTimeout(200)
// click to continue profile
await page.mouse.click(813, 392)
await page.waitForTimeout(100)
await page.waitForTimeout(300)
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
code += `
|> tangentialArc(endAbsolute = [551.2, -62.01])`
|> tangentialArc(end = [184.31, 184.31])`
await expect(u.codeLocator).toHaveText(code)
// click tangential arc tool again to unequip it
// it will be available directly in the toolbar since it was last equipped
await toolbar.tangentialArcBtn.click()
await page.waitForTimeout(100)
await page.waitForTimeout(1000)
// screen shot should show the sketch
await expect(page).toHaveScreenshot({
@ -472,20 +472,20 @@ test.describe(
await expect(u.codeLocator).toHaveText(code)
await toolbar.selectTangentialArc()
await page.waitForTimeout(100)
await page.waitForTimeout(200)
// click to continue profile
await page.mouse.click(813, 392)
await page.waitForTimeout(100)
await page.waitForTimeout(300)
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
code += `
|> tangentialArc(endAbsolute = [551.2, -62.01])`
|> tangentialArc(end = [184.31, 184.31])`
await expect(u.codeLocator).toHaveText(code)
await toolbar.tangentialArcBtn.click()
await page.waitForTimeout(100)
await page.waitForTimeout(1000)
// screen shot should show the sketch
await expect(page).toHaveScreenshot({
@ -823,7 +823,7 @@ test('theme persists', async ({ page, context, homePage }) => {
uploadThroughput: -1,
})
await expect(networkToggle).toContainText('Connected')
await expect(networkToggle).toContainText('Network health (Strong)')
await expect(page.getByText('building scene')).not.toBeVisible()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 58 KiB

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