Compare commits

...

195 Commits

Author SHA1 Message Date
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
034366e65e Bugfix: formatter changed [0..<4] to [0..4] (#7186)
In #7179 I added exclusive ranges for KCL, but I forgot to update the
formatter/unparser to handle them. So it was silently changing exclusive-end
ranges to inclusive-end ranges.
2025-05-23 17:03:46 +00:00
cd537cd9c2 Remove the version badge on web signin (#7187)
Thanks @jacebrowning for reporting
2025-05-23 16:52:23 +00:00
22f92942f6 #6567 Code errors disappear when closing and reopening the editor (#7166)
* Fix error of not showing errors when reopening KCL code pane

* add test for errors not shown after reopening code pane

* rename test

* typo in e2e/playwright/editor-tests.spec.ts

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

* lint

* fmt

* fix test: Opening and closing the code pane will consistently show error diagnostics

* PR feedback: use catch(reportRejection) for safeParse

* no need for lint rule

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-23 12:41:37 -04:00
4eee50d79e Remove Owners font from the modeling app (#7185)
Our team started getting *rate limited* with access to the font, which
meant the app wasn't loading for them 😱. I don't want us to risk any
user being rate limited because of a font ever.
2025-05-23 12:33:05 -04:00
125b2c44d4 Clean up release process readme (#7182)
* Clean up release process readme

* Update CONTRIBUTING.md

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

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-23 11:22:39 -04:00
db9e35d686 Fix mirror2d selection by adding artifact graph support (#7178)
* Add artifact graph support for mirror2d

* Update output

* Disable test that can't pass
2025-05-23 11:16:36 -04:00
d0958220fe KCL: End-exclusive ranges like [0..<10] (#7179)
Closes https://github.com/KittyCAD/modeling-app/issues/6843

To clarify:
`[1..10]` is 1, 2, ..., 8, 9, 10
`[1..<10]` is 1, 2, ... 8, 9
2025-05-22 22:13:27 -05:00
fa4b3cfd1b Change artifact panics to runtime errors (#7177)
* Change artifact panics to runtime errors

* Condense format!()

* Remove unwrap
2025-05-22 17:48:19 -04:00
8972f8f109 Fix up the sign-in page's mobile layout (#7176)
@JBEmbedded pointed this out, and we don't want a bad look for website
browsers who click a stray "Try in Browser" link. There's a little
message saying we're working on touch controls for now, and we steal
their signin button.
2025-05-22 21:31:06 +00:00
85ccc6900c Do multiple chamfer/fillet in one API call (#6750)
KCL's `fillet` function takes an array of edges to fillet. Previously this would do `n` fillet API commands, one per edge. This PR combines them all into one call, which should improve performance. You can see the effect in the  artifact_commands snapshots, e.g. `rust/kcl-lib/tests/kcl_samples/axial-fan/artifact_commands.snap` 

Besides performance, this should fix a bug where some KCL fillets would fail, when they should have succeeded. Example from @max-mrgrsk:

```kcl
sketch001 = startSketchOn(XY)
  |> startProfile(at = [-12, -6])
  |> line(end = [0, 12], tag = $seg04)
  |> line(end = [24, 0], tag = $seg03)
  |> line(end = [0, -12], tag = $seg02)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
  |> close()
extrude001 = extrude(
       sketch001,
       length = 12,
       tagEnd = $capEnd001,
       tagStart = $capStart001,
     )
  |> fillet(
       radius = 5,
       tags = [
         getCommonEdge(faces = [seg02, capEnd001]),
         getCommonEdge(faces = [seg01, capEnd001]),
         getCommonEdge(faces = [seg03, capEnd001]),
         getCommonEdge(faces = [seg04, capEnd001])
       ],
     )
```

This program fails on main, but succeeds on this branch.
2025-05-22 21:25:55 +00:00
4e2deca5d8 KCL: Set sensible defaults for pattern 'axis' arg (#7168) 2025-05-22 14:24:21 -05:00
04a2c184d7 KCL: Absolute point bezier curves (#7172)
Previously KCL bezier curves could only use relative control points. Now you can use absolute control points too. 

Here's an example of the new arguments:

```kcl
startSketchOn(XY)
  |> startProfile(at = [300, 300])
  |> bezierCurve(control1Absolute = [600, 300], control2Absolute = [-300, -100], endAbsolute = [600, 300])
  |> close()
  |> extrude(length = 10)
```

Closes https://github.com/KittyCAD/modeling-app/issues/7083
2025-05-22 13:06:06 -04:00
2c7701e2d4 Add markdown rendering to TTC error toast, with component tests (#7170)
Closes #5792. I tried to move these over to our new component test
bucket, but Remark doesn't play nice with that testing setup at least in
my initial attempts.
2025-05-22 13:00:21 -04:00
ae569b61db Use typed KclValue instead of any in sketchFromKclValue (#7144)
* use KclValue instead of any

* no need for any in sketchFromKclValueOptional

* simplify error reason for sketchFromKclValueOptional
2025-05-22 11:15:31 +02:00
0a0e6abd3f KCL: Autocomplete snippets for 'center' should suggest the origin (#7164)
Pattern functions and `polygon` both take a parameter `center` which
defaulted to [3.14, 3.14] for silly reasons. They now default to
[0, 0].
2025-05-22 04:08:34 +00:00
9c7aee32bd KCL: Custom snippet values for kcl-in-kcl (#7163)
In #7156, I allowed KCL to set specific snippet completions for each arg of each function. They're optional -- if you don't set one, it'll fall back to the type-driven defaults.

That PR only worked for KCL stdlib functions defined in Rust. This PR enables the same feature, but for functions defined in KCL.
2025-05-21 22:16:04 -05:00
ed979d807b Fix ascription to array type to not convert units (#7160) 2025-05-22 09:22:30 +12:00
f5c244dbb1 KCL: stdlib macro should now assume all functions use keywords (#7158)
This has been enforced by the parser since #6639, so there's no need for `keywords = true` in every stdlib function anymore.
2025-05-21 21:10:40 +00:00
0ea1e9a6da KCL: Customizable per-arg and per-fn snippet values (#7156)
Before, the LSP snippet for `startProfile` was 

```
startProfile(%, at = [3.14, 3.14])
```

Now it's 

```
startProfile(%, at = [0, 0])
```

This is configured by adding a `snippet_value=` field to the stdlib macro. For example:


```diff
#[stdlib {
    name = "startProfile",
    keywords = true,
    unlabeled_first = true,
    args = {
        sketch_surface = { docs = "What to start the profile on" },
-       at = { docs = "Where to start the profile. An absolute point." },
+       at = { docs = "Where to start the profile. An absolute point.", snippet_value = "[0, 0]" },        tag = { docs = "Tag this first starting point" },
    },
    tags = ["sketch"]
}]
```

## Work for follow-up PRs

 - Make this work for KCL functions defined in KCL, e.g. [`fn circle`](36c8ad439d/rust/kcl-lib/std/sketch.kcl (L31-L32)) -- something like `@(snippet_value = "[0, 0]")` perhaps
 - Go through the stdlib and change defaults where appropriate
2025-05-21 20:18:20 +00:00
a36530d6df Make Create with Zoo ML the default again (#7159) 2025-05-21 18:29:03 +00:00
825d34718a Update telemetry antenna entity names (#7155)
* Update telemetry antenna entity names

Changed the generic sketch and profile entity names to more specific names

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-21 15:46:05 +00:00
d90d445d84 Pass the query parameters through to sign-in flow (#7157)
* Pass the query parameters through to sign-in flow

So users can return to their invoked command after signing in

* Don't run query param commands if not logged in
2025-05-21 15:32:52 +00:00
5976a0cba6 Change to skip asserting the artifact graph for samples (#7153)
* Change to skip asserting the artifact graph for samples

* Fix clippy warning
2025-05-21 14:51:31 +00:00
b50f2f5a2a Link to the dedicated page when there is intent to download (#7152) 2025-05-21 14:20:36 +00:00
f877b52898 Update telemetry antenna (#7150)
* Update telemetry antenna

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-21 10:05:56 -04:00
4a585db637 Link to the new download page (#7149) 2025-05-21 13:42:11 +00:00
4d404bf137 Delete redundant Text-to-CAD tests (#7118) 2025-05-21 13:33:32 +00:00
e644b7e1fc Run the KCL tests every hour to detect regressions (#7139) 2025-05-21 09:21:04 -04:00
aff1684064 Chrome toast touchup (#7148) 2025-05-21 08:47:40 -04:00
d9afc50f91 Nickmccleery/add more samples (#7145) 2025-05-21 12:27:43 +00:00
eb7b4ccda6 Fix web app issue with search params on Safari (#7147)
* pierremtb/adhoc/safari-link-issue

* Fix both places with [...searchParams.entries()]
2025-05-21 12:06:17 +00:00
bbf4f1d251 Add title line which I didn't know did anything important. (#7135) 2025-05-21 09:00:21 +00:00
3cc7859ca5 load samples on web (#7142)
* load samples on web

* Update src/hooks/useQueryParamEffects.ts

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

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-21 07:59:42 +00:00
ab63345c57 Run std lib example tests one at a time (#7127)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-21 05:20:36 +00:00
3df02e02fa Release 76 (#7138) 2025-05-21 02:39:32 +00:00
35f5c62633 Don't race exiting a sketch scene (#7128)
* Turn sketch exit execute into actor, no more racey exits

* Turn sketch exit execute into actor, no more racey exits

* Fix types

---------

Co-authored-by: Frank Noirot <frank@zoo.dev>
2025-05-21 01:09:16 +00:00
0f0fc39d07 Add display of array element types in error messages (#7113)
* Add test showing unhelpful error message

* Add display of array element types in error messages

* Change to prose description

* Update output
2025-05-20 20:50:24 -04:00
a13b6b2b70 Fix open KCL sample via URL query param in browser (#7133)
There is now a `projectName` that isn't included in the query params I
was using and wasn't including in the URLs I was building.
2025-05-20 20:48:23 -04:00
4212b95232 Add KCL importing relative to where you're importing from (#7125)
* add test

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

* Add importing relative to where you're importing from

* Update output

* Remove runtime panics

* Change to debug_assert

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
2025-05-21 00:47:32 +00:00
38a73a603b Update output to match latest (#7129) 2025-05-21 00:45:41 +00:00
c48d9fd4d7 Allow point-and-click Insert to suggest nested files (#7130)
* fix: saving off code

* fix: saving off progress

* chore: implemented kcl sample assembly unique sub dir creation

* fix: removing testing console logs

* fix: cleaning up old comment

* fix: add to file always does subdir/main.kcl now for single files

* fix: auto fmt

* fix: delete project and folder from ttc

* fix: fixed deleting projects and subdirs

* fix: if statement logic fixed for deleting project or subdir

* fix: TTC isProjectNew makes main.kcl not a subdir.

* fix: fixing e2e test

* fix: this should pass now

* pierremtb/make-insert-take-over-the-import-world

* Add test that doesn't work locally yet :(

* Fix test 🤦

* Change splice for push

* Fix up windows path

---------

Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
2025-05-20 20:44:22 -04:00
0753987b5a [Fix]: Allow importing assemblies into exsiting projects and handling the collision (#7108)
* fix: saving off code

* fix: saving off progress

* chore: implemented kcl sample assembly unique sub dir creation

* fix: removing testing console logs

* fix: cleaning up old comment

* fix: add to file always does subdir/main.kcl now for single files

* fix: auto fmt

* fix: delete project and folder from ttc

* fix: fixed deleting projects and subdirs

* fix: if statement logic fixed for deleting project or subdir

* fix: TTC isProjectNew makes main.kcl not a subdir.

* fix: fixing e2e test

* fix: this should pass now
2025-05-20 19:03:54 -04:00
815ff7dc2b more subtract regression tests (#7123)
* more regression tests

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

* snaps

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

* iupdates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-20 16:02:44 -07:00
46684d420d Test nested imports on all platforms (#7126) 2025-05-20 18:45:04 -04:00
eca09984a3 Fix: Follow up Text-to-CAD Edit to fix in browser (#7124)
* fix: web vs desktop who wins

* fix: fixed logic round two :(
2025-05-20 21:11:31 +00:00
ce63c6423e Impove naming in point-and-click Revolve to convey that axis are relative (#7122)
* Better axis options in point-and-click Revolve to convey the axis are relative
Fixes #7121

* Less changes
2025-05-20 16:57:55 -04:00
09699afe82 Fix: Can't go back to Profiles arg in Extrude, Revolve, Loft (#7106)
* Revert "Update failing E2E tests with new behavior, which allows skip with preselection"

This reverts commit d72bee8637.

* Fix: Can't go back to Profiles step in sweep commands
Fixes #7080

* Make it better but still not quite there

* I think I got it: this was likely the real bug making submit fire twice

* Bring timemouts back
2025-05-20 20:07:56 +00:00
36c8ad439d KCL: Add diameter arg to circle (#7116)
Paul's been requesting this for a long time. Now that we're fully using keyword args, this is easy to do.

We should probably add a similar `diameter` arg to `arc`, `tangentialArc`, `polygon` etc. And _maybe_ to `fillet`, but that might not be as helpful.
2025-05-20 19:44:35 +00:00
5dc77ceed5 Only start saving camera after scene is ready (#7120) 2025-05-20 15:12:08 -04:00
c7baa26b2d idiomatic kcl for hip sample (#7095)
* idiomatic kcl for hip sample

* Update kcl-samples simulation test output

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
2025-05-20 11:36:08 -07:00
4d0454abcd Remove old ZMA logos, rip out JS theme state from open-in-desktop view (#7119)
* Remove old ZMA logos, rip out JS theme state from open-in-desktop view

Make this page dumber so that it doesn't break

* Lint and remove kcma refs

---------

Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2025-05-20 18:13:58 +00:00
1dafbf105e Identify distinct test suites (#7109) 2025-05-20 12:56:55 -04:00
773f013115 [Fix]: When loading the modeling page the user's settings for camera projection was ignored (#7111)
* fix: initialization of user camera projection is now used again, ope

* fix: removing comment
2025-05-20 12:46:53 -04:00
c5cd460595 Show error when trying to export at non-top-level (#7110) 2025-05-20 12:43:11 -04:00
845352046b Modeling machine unit tests (#7098)
* successfully transition to sketch idle

* get constraint to mod code

* clean up

* remove .only

* Fixed tsc

---------

Co-authored-by: lee-at-zoo-corp <lee@zoo.dev>
2025-05-20 12:22:52 -04:00
597f1087f9 Fix enter key loop in sweep commands (#7112)
* use effect for focus of command palette submit button, not autoFocus

autoFocus is being overridden by the Headless UI Dialog component's
focus management here
https://headlessui.com/v1/react/dialog#focus-management (we do not have
access to pass back initialFocus in this case). So we can use an effect
to imperatively focus the button when this component is mounted.

* Update sweep tests to submit the command with Enter
2025-05-20 16:04:56 +00:00
511334683a test: Add regression test for importing only at the top level (#7104)
Add regression test for importing only at the top level
2025-05-20 11:43:48 -04:00
223a4ad45d Style the experimental badge to match the website (#7100)
* Style the experimental badge to match the website

* Match the styling of the rest of the app

We don't use all apps monospace fonts anywhere.

* Bring back all caps
2025-05-20 14:57:53 +00:00
edf31ec1d3 Make the textarea command bar input run its resize initially (#7103)
We have a hook to auto-grow the textarea input but it wasn't running
once initially. This is noticable on the onboarding, where we show the
user a long Text-to-CAD Edit prompt that overflows.
2025-05-20 10:56:03 -04:00
1539557005 Always update snapshots if needed (#7105) 2025-05-20 14:34:26 +00:00
1d3ba4e3ac [Fix]: Remove console logs (#7102)
* fix: these got in when they should not have

* fix: spacemacs found wrong eslint again biome thing..
2025-05-20 14:12:32 +00:00
4110aa00db Only update snapshots for tests that repeatedly fail (#7101)
* Only update snapshots for tests that repeatedly fail

* Let TAB silence snapshot capture failures as well
2025-05-20 14:00:33 +00:00
7eb52cda36 Fix: creating a dir ending with .kcl panics the app (#7099)
* Fix: creating a dir ending with .kcl panics the app
Fixes #7082

* Update snapshots

* Update snapshots

* Add test

* tag: ['@electron', '@macos', '@windows']

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-20 13:53:26 +00:00
7872fb9cbd Update snapshots on CI (#7069) 2025-05-20 06:00:31 -04:00
651181e62c Restrict subdirectory imports to main.kcl (#7094)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-20 18:13:17 +12:00
max
38a245f2fc fix typos in the kcl samples (#7078)
typos
2025-05-20 05:47:33 +00:00
1b4289f93f allow nested files imported (#7090)
* allow nested files

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

* fix test

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

* disallow bad things

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

* add playwright test on windows

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

* add playwright test on windows

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

* fixes

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

* updates

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

* updates

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

* fix test

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

* Update rust/kcl-lib/tests/nested_windows_main_kcl/unparsed@main.kcl.snap

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

* updates

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-19 22:42:25 -04:00
d0697c24fd Change Sketch to use the units of the module (#7076)
* Change Sketch to use the units of the module

* Update output
2025-05-19 20:20:47 -04:00
8c24e29081 [Fix]: P2E base path is always the project directory, P2E when completed stays in your current file (#7091)
* fix: fixes for p2e

* fix: yep tsc fixes

* fix: fixing reject workflow and navigate
2025-05-19 20:05:38 -04:00
2b9d26e2ff Make Text-to-CAD Edit the default workflow in the toolbar (#7092)
We want users to make edits first and foremost within projects, so we're
going to surface it as the default workflow button in the toolbar. WIP
until I verify that tests are okay with this.
2025-05-19 19:58:18 -04:00
ab148a7654 Fix: Esc key doesn't work in Text-to-CAD prompt (#7089)
* Fix: Esc key doesn't work in Text-to-CAD prompt
Fixes #7086

* Add e2e test because why not
2025-05-19 23:31:33 +00:00
553e650fbe Add brake disc to samples. (#7059)
* Add brake disc.

* Update kcl-samples simulation test output

* Update public/kcl-samples/brake-rotor/main.kcl

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

* Update public/kcl-samples/brake-rotor/main.kcl

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
2025-05-19 15:24:37 -07:00
9690a24c68 Avoid a spin-lock when auth is never resolved (#7084) 2025-05-19 18:16:07 -04:00
978d5d44a2 rotate a named axis (#7087)
updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-19 22:11:35 +00:00
9df476543a turn on the revolve test (#7075)
* turn on the revolve test

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

* updates

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

* updates

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

* updates

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

* updates

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-19 14:51:44 -07:00
cf303ebe97 Declare pattern transform functions in KCL (#7057)
* Declare pattern transform using KCL

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

* Boolean function param defaults

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

* Parse empty record types in fn types

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-20 08:25:29 +12:00
b1d1d89ca5 Include link to the new book (#7056)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-19 14:49:23 -05:00
3a599d0a0a Release KCL 75 (#7077) 2025-05-19 19:02:38 +00:00
8340f6b906 Give a default value to projectName in Text-to-CAD Create command to allow invocation through command palette (#7061)
Give a default value to projectName

This argument is hidden since it's marked as skip, so browser users who
must now invoke the command through the command palette have no way of
setting the value. Since it is also required, the command palette fails
silently on submission (which we need to fix more broadly). This gives
it a default value so that users can submit properly.
2025-05-19 18:13:47 +00:00
ddb034b14d Show KCL backtraces (#7033)
* Add backtrace to errors

* Add display of backtraces with hints

* Change pane badge to only show count of errors

* Fix property name to not collide with Error superclass

* Increase min stack again

* Add e2e test that checks that the diagnostics are created in CodeMirror

* Remove unneeded code

* Change to the new hotness
2025-05-19 18:13:10 +00:00
bfa2f67393 Add a 1s client side rate limit / cache to billing requests (#7067)
* Add a 1s client side rate limit / cache to billing requests

* Stop using err; use isErr instead
2025-05-19 14:11:33 -04:00
447069a97b Revert "Remove Create with Text-to-CAD from toolbar, make commands in command palette more distinct" (#7068)
Revert "Remove Create with Text-to-CAD from toolbar, make commands in command…"

This reverts commit 5734cc7fc3.
2025-05-19 14:05:18 -04:00
49b78d726a Submit selection to command on unmount of selection arg input (#7047)
* Submit selection to command on unmount of selection arg input

This fixes #7024 by saving the user's selection to the command even if
they click another argument in the command palette's header. It does no
harm to save the selection to the argument, even if it's being torn down
because the user dismissed it has no negative effect.

* Refactor to not auto-submit before selection is cleared on mount

Thanks E2E test suite

* Update failing E2E tests with new behavior, which allows skip with preselection

---------

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-05-19 13:21:43 -04:00
5b4cddd0b0 Fix React re-render (#7038)
feat: memoize share button to avoid re-renders
2025-05-19 12:58:35 -04:00
8878c148ed Fix reset project dir setting (#7064)
* Fix reset project dir setting
Fixes #6432

* Lint
2025-05-19 16:51:08 +00:00
c3c2ded795 Fix cleanup in network status hook (#7034)
fix: remove event listeners on unmount
2025-05-19 11:38:53 -04:00
fb35fdcc38 Disallow segment selection in all sweeps and change Sketches display name to Profiles (#7045)
* Disallow segment selection in sweep, plus displayName: Profiles for clarity
Fixes #7044

* Change selection hints for solid2d to be profile instead of face

* Update tests

* More fixes

* Fix tests following behavior change: we don't select segments in code anymore but profiles
2025-05-19 11:21:29 -04:00
e76ba9921c No onboarding toast if query params (#7060)
* No onboarding toast if query params

* Changed dependences
2025-05-19 09:38:38 -04:00
b19acd550d Type check and coerce arguments to user functions and return values from std Rust functions (#6958)
* Shuffle around function call code

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

* Refactor function calls to share more code

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

* Hack to leave the result of revolve as a singleton rather than array

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

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-19 16:50:15 +12:00
f3e9d110c0 KCL: Default circular pattern rotateDuplicates=true, arcDegrees=360 (#7052)
KCL: Default circular pattern rotateDuplicates=true, arcDeg=360

Seems like most users would want these.
2025-05-19 14:46:00 +12:00
658497da1d Allow same syntax for patterns as mirror revolve (#7054)
* allow named axis for patterns

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

* docs

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

* images

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

* Fix typo

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-05-19 02:25:35 +00:00
bd01059a92 more csg regression tests (#7032)
* more csg regression tests

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

* artifacts

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-18 16:50:51 -07:00
57a977e6be Fix simulation_test file load error (#7042)
Co-authored-by: Lucas Kent <rubickent@gmail.com>
2025-05-18 16:28:59 -07:00
94b0cc1f3e Remove remaining links to nightly (#7051) 2025-05-18 11:21:31 -04:00
5734cc7fc3 Remove Create with Text-to-CAD from toolbar, make commands in command palette more distinct (#7048)
* Remove Create with Text-to-CAD from the toolbar

* Remove "prompt-to-edit" wording, call commands "create" and "edit"

* Use sparkles for the ML feature, not chat

* lints

* Start fixing up tests, there are probably more though

* Fix up a few more tests

* Fix up prompt-to-edit tests (yay using fixtures!)

* Fix native file menu tests

* Update snapshots

* Fix menu test

* Fix snaps

---------

Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-05-18 10:24:48 +00:00
3168c22de7 Remove false positive missing messages for other module SourceRanges (#7050) 2025-05-18 06:21:10 -04:00
3c94fe9047 Make warning toast not appear if the URL has any search params (#7046)
* Make warning toast not appear if the URL has any search params

This should avoid the scenario where someone clicks an "open sample"
type link and dismisses the command palette before they can finish what
they're doing.

* Update src/App.tsx

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

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-18 01:23:43 +00:00
cdd6b56d42 Change wasm init failed banner to a toast (#7043)
* Change wasm init failed banner to a toast
Closes #6976 for good!

* Move :(

* Rm testing bit

* Align left and bot suggestions

* Update src/components/WasmErrToast.tsx

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

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-17 18:01:12 -04:00
75ac3bc61b Replace map with forEach in CLI arg tests (#7035)
test: use forEach for command-line arg cases
2025-05-17 14:20:39 -04:00
29d511d085 [Fix] Updating docs for mirror2d (#7013)
* fix: mirror2d works on closed sketches

* fix: generating docs
2025-05-17 13:00:29 -05:00
max
b0a41939e8 Max's KCL samples (#7041)
* 3d models

* Update kcl-samples simulation test output

* typos

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-17 11:16:22 -04:00
7d2c1061ba Allow global commands to be invoked from the command palette via URL (#6973) 2025-05-17 07:51:25 -04:00
d768073d17 [Fix] Using main.kcl for more of the workflows that generate kcl files (#7017)
* fix: when creating a t2c in a new project make the file name main.kcl

* fix: when creating a sample in a new project and there is only 1 file make the filename main.kcl

* fix: auto fixes

* fix: share links generate main.kcl

* fix: codespell typoe

* fix: fixing E2E tests

* Fix 3 more tests

* fix: share url link e2e file name fix

---------

Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
2025-05-17 03:43:25 +00:00
dc8496c62e Change download-app banner to a toast & permanent button (#7010)
* pierremtb/issue6976-download-app-toast

* Cleaning up, more testing

* we goin places ft. new icon thanks @franknoirot

* Add app-version to masks

* Revert "Add app-version to masks"

This reverts commit 9624c3f434.

* Update dialog logic and snapshots

* Update snapssss

* Hook up settingsActor

* Polish

* Fix snap

* Quick fix, thanks bot

* Cleaning up linksssssssss
2025-05-16 23:25:04 -04:00
1202 changed files with 389085 additions and 383147 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

View File

@ -6,6 +6,7 @@ if [ -z "${TAB_API_URL:-}" ] || [ -z "${TAB_API_KEY:-}" ]; then
fi
project="https://github.com/KittyCAD/modeling-app"
suite="${CI_SUITE:-unit}"
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
@ -13,6 +14,7 @@ echo "Uploading batch results"
curl --silent --request POST \
--header "X-API-Key: ${TAB_API_KEY}" \
--form "project=${project}" \
--form "suite=${suite}" \
--form "branch=${branch}" \
--form "commit=${commit}" \
--form "tests=@test-results/junit.xml" \

853
.github/dependabot.yml vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,22 @@
name: cargo test
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
schedule:
- cron: 0 * * * * # hourly
permissions:
contents: read
pull-requests: write
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
name: cargo test
jobs:
build-test-artifacts:
name: Build test artifacts
@ -88,6 +94,7 @@ jobs:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
ZOO_HOST: https://api.dev.zoo.dev
RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: Commit differences
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
shell: bash
@ -119,6 +126,7 @@ jobs:
# Configure nextest when it's run by insta (via just).
NEXTEST_PROFILE: ci
RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: Build and archive tests
run: |
cd rust
@ -182,6 +190,7 @@ jobs:
env:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
ZOO_HOST: https://api.dev.zoo.dev
RUST_MIN_STACK: 10485760000
- name: Upload results
if: always()
run: .github/ci-cd-scripts/upload-results.sh
@ -190,6 +199,7 @@ jobs:
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:kcl
run-internal-kcl-samples:
name: cargo test (internal-kcl-samples)
runs-on:
@ -238,6 +248,7 @@ jobs:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
ZOO_HOST: https://api.dev.zoo.dev
MODELING_APP_INTERNAL_SAMPLES_SECRET: ${{secrets.MODELING_APP_INTERNAL_SAMPLES_SECRET}}
RUST_MIN_STACK: 10485760000
run-wasm-tests:
name: Run wasm tests
strategy:

View File

@ -1,4 +1,5 @@
name: E2E Tests
on:
push:
branches:
@ -19,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
@ -99,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:
@ -130,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: |
@ -143,7 +148,7 @@ jobs:
- name: Install browsers
run: npm run playwright install --with-deps
- name: Capture snapshots
- name: npm run test:snapshots
uses: nick-fields/retry@v3.0.2
with:
shell: bash
@ -156,6 +161,19 @@ jobs:
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:snapshots
TARGET: web
- name: Update snapshots
if: always()
run: npm run test:snapshots -- --last-failed --update-snapshots
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:snapshots
TARGET: web
- uses: actions/upload-artifact@v4
@ -173,7 +191,7 @@ jobs:
id: git-check
run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
if git status | grep -q "Changes to be committed"
if git status | grep --quiet "Changes to be committed"
then echo "modified=true" >> $GITHUB_OUTPUT
else echo "modified=false" >> $GITHUB_OUTPUT
fi
@ -193,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:
@ -241,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
@ -263,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
@ -283,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
@ -290,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
@ -306,6 +412,7 @@ jobs:
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:desktop
TARGET: desktop
- uses: actions/upload-artifact@v4

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,110 +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
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
```
VERSION=$(./scripts/semantic-release.sh)
git tag $VERSION
git push origin --tags
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files.
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
@ -201,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
@ -209,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.
@ -302,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

@ -4,7 +4,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
## Windows
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Windows and for your processor type.
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for Windows and for your processor type.
2. Once downloaded, run the installer `Zoo Design Studio-{version}-{arch}-win.exe` which should take a few seconds.
@ -12,16 +12,16 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
## macOS
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for macOS and for your processor type.
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for macOS and for your processor type.
2. Once downloaded, open the disk image `Zoo Design Studio-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory.
3. You can then open your `Applications` directory and double-click on `Zoo Design Studio` to open.
## Linux
## Linux
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Linux and for your processor type.
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for Linux and for your processor type.
2. Install the dependencies needed to run the [AppImage format](https://appimage.org/).
- On Ubuntu, install the FUSE library with these commands in a terminal.
@ -29,7 +29,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
sudo apt update
sudo apt install libfuse2
```
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
- Once installed, copy the downloaded `Zoo Design Studio-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`.
- `appimaged` should automatically find it and make it executable. If not, run:

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

@ -2,7 +2,7 @@
# Zoo Design Studio
[zoo.dev/modeling-app](https://zoo.dev/modeling-app)
[zoo.dev/design-studio](https://zoo.dev/design-studio)
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
@ -40,14 +40,8 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
## Get Started
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
We recommend downloading the latest application binary from our [website](https://zoo.dev/design-studio/download). If you don't see your platform or architecture supported there, please file an issue. See the [installation guide](INSTALL.md) for additional instructions.
## Developing
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
## KCL
To contribute to the KittyCAD Language, see the [README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib) for KCL.
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started. To contribute to the KittyCAD Language, see the dedicated [readme](rust/kcl-lib/README.md) for KCL.

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

View File

@ -4,7 +4,7 @@ excerpt: "Documentation of the KCL language for the Zoo Design Studio."
layout: manual
---
This is a reference for KCL. If you are learning KCL, you may prefer the [guide]() which explains
This is a reference for KCL. If you are learning KCL, you may prefer the [guide](https://zoo.dev/docs/kcl-book/intro.html) which explains
things in a more tutorial fashion. See also our documentation of the [standard library](/docs/kcl-std).
## Topics

View File

@ -27,9 +27,6 @@ import increment from "util.kcl"
answer = increment(41)
```
Imported files _must_ be in the same project so that units are uniform across
modules. This means that it must be in the same directory.
Import statements must be at the top-level of a file. It is not allowed to have
an `import` statement inside a function or in the body of an ifelse.
@ -58,6 +55,9 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
import increment as inc, decrement as dec from "util.kcl"
```
You can import files from the current directory or from subdirectories, but if importing from a
subdirectory you can only import `main.kcl`.
---
## Functions vs `clone`
@ -177,7 +177,7 @@ You can also import the whole module. This is useful if you want to use the
result of a module as a variable, like a part.
```norun
import "tests/inputs/cube.kcl" as cube
import "cube.kcl"
cube
|> translate(x=10)
```
@ -229,6 +229,19 @@ The final statement is what's important because it's the return value of the
entire module. The module is expected to return a single object that can be used
as a variable by the file that imports it.
The name of the file or subdirectory is used as the name of the variable within the importing program.
If you want to use a different name, you can do so by using the `as` keyword:
```kcl,norun
import "cube.kcl" // Introduces a new variable called `cube`.
import "cube.kcl" as block // Introduces a new variable called `block`.
import "cube/main.kcl" // Introduces a new variable called `cube`.
import "cube/main.kcl" as block // Introduces a new variable called `block`.
```
If the filename includes hyphens (`-`) or starts with an underscore (`_`), then you must specify a
variable name.
---
## Multiple instances of the same import
@ -241,7 +254,7 @@ If you want to have multiple instances of the same object, you can use the
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
```norun
import cube from "tests/inputs/cube.kcl"
import cube from "cube.kcl"
cube
|> translate(x=10)
@ -257,7 +270,7 @@ separate objects in memory, and can be manipulated independently.
Here is an example with a file from another CAD system:
```kcl
import "tests/inputs/cube.step" as cube
import "tests/inputs/cube.step"
cube
|> translate(x=10)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,22 +1,21 @@
---
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(
@array: [any],
initial: any,
f: fn(any, accum: any): any,
): [any]
): 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

@ -11,7 +11,7 @@ Compute the length of the given leg.
legLen(
hypotenuse: number(Length),
leg: number(Length),
): number(deg)
): number(Length)
```
@ -25,7 +25,7 @@ legLen(
### Returns
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples

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,31 +1,32 @@
---
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),
radius?: number(Length),
diameter?: number(Length),
tag?: tag,
): 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. | 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 |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this circle. | No |
### Returns
@ -51,7 +52,7 @@ exampleSketch = startSketchOn(XZ)
|> line(end = [0, 30])
|> line(end = [-30, 0])
|> close()
|> subtract2d(tool = circle(center = [0, 15], radius = 5))
|> subtract2d(tool = circle(center = [0, 15], diameter = 10))
example = extrude(exampleSketch, length = 5)
```

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,
rotateDuplicates: bool,
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. | Yes |
| `rotateDuplicates` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether or not to rotate the duplicates as they are copied. | Yes |
| `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

@ -1,19 +1,19 @@
---
title: "patternTransform2d"
subtitle: "Function in std::sketch"
excerpt: "Just like patternTransform, but works on 2D sketches not 3D solids."
excerpt: "Just like `patternTransform`, but works on 2D sketches not 3D solids."
layout: manual
---
Just like patternTransform, but works on 2D sketches not 3D solids.
Just like `patternTransform`, but works on 2D sketches not 3D solids.
```kcl
patternTransform2d(
@sketches: [Sketch],
instances: number,
transform: FunctionSource,
useOriginal?: bool,
): [Sketch]
@sketches: [Sketch; 1+],
instances: number(_),
transform: fn(number(_)): { },
useOriginal?: boolean,
): [Sketch; 1+]
```
@ -22,14 +22,14 @@ patternTransform2d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/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 |
| `transform` | `FunctionSource` | 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` | [`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 |
| `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 |
| `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 |
### Returns
[`[Sketch]`](/docs/kcl-std/types/std-types-Sketch)
[`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch)
### Examples

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

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

File diff suppressed because one or more lines are too long

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

View File

@ -14,8 +14,6 @@ mirror2d(
): Sketch
```
Only works on unclosed sketches for now.
Mirror occurs around a local sketch axis rather than a global axis.
### Arguments

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)
* [`patternTransform2d`](/docs/kcl-std/patternTransform2d)
* [`polygon`](/docs/kcl-std/polygon)
* [`profileStart`](/docs/kcl-std/profileStart)
* [`profileStartX`](/docs/kcl-std/profileStartX)
* [`profileStartY`](/docs/kcl-std/profileStartY)
* [`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/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)
* [`patternTransform`](/docs/kcl-std/patternTransform)
* [`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)
* [`patternTransform2d`](/docs/kcl-std/patternTransform2d)
* [`polygon`](/docs/kcl-std/polygon)
* [`profileStart`](/docs/kcl-std/profileStart)
* [`profileStartX`](/docs/kcl-std/profileStartX)
* [`profileStartY`](/docs/kcl-std/profileStartY)
* [`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/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)
* [`patternTransform`](/docs/kcl-std/patternTransform)
* [`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

@ -11,10 +11,11 @@ Contains frequently used constants, functions for interacting with the KittyCAD
The standard library is organised into modules (listed below), but most things are always available in KCL programs.
You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL guide]().
You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL guide](https://zoo.dev/docs/kcl-book/intro.html).
## 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 one or more lines are too long

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

@ -78,11 +78,10 @@ extrude001 = extrude(sketch001, length = 5)`
// Delete a character to break the KCL
await editor.openPane()
await editor.scrollToText('bracketLeg1Sketch, length = thickness)')
await page
.getByText('extrude(bracketLeg1Sketch, length = thickness)')
.click()
await page.keyboard.press('Backspace')
await editor.scrollToText('extrude(%, length = width)')
await page.getByText('extrude(%, length = width)').click()
await page.keyboard.press(')')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
@ -99,16 +98,11 @@ extrude001 = extrude(sketch001, length = 5)`
await page.waitForTimeout(500)
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Open the code pane
await editor.openPane()
// Go to our problematic code again (missing closing paren!)
await editor.scrollToText('extrude(bracketLeg1Sketch, length = thickness')
// Go to our problematic code again
await editor.scrollToText('extrude(%, length = w')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
@ -235,11 +229,54 @@ extrude001 = extrude(sketch001, length = 5)`
.first()
).toBeVisible()
})
test('KCL errors with functions show hints for the entire backtrace', async ({
page,
homePage,
scene,
cmdBar,
editor,
toolbar,
}) => {
await homePage.goToModelingScene()
await scene.settled(cmdBar)
const code = `fn check(@x) {
return assert(x, isGreaterThan = 0)
}
fn middle(@x) {
return check(x)
}
middle(1)
middle(0)
`
await test.step('Set the code with a KCL error', async () => {
await toolbar.openPane('code')
await editor.replaceCode('', code)
})
// This shows all the diagnostics in a way that doesn't require the mouse
// pointer hovering over a coordinate, which would be brittle.
await test.step('Open CodeMirror diagnostics list', async () => {
// Ensure keyboard focus is in the editor.
await page.getByText('fn check(').click()
await page.keyboard.press('ControlOrMeta+Shift+M')
})
await expect(
page.getByText(`assert failed: Expected 0 to be greater than 0 but it wasn't
assert()
check()
middle()`)
).toBeVisible()
// There should be one hint inside middle() and one at the top level.
await expect(page.getByText('Part of the error backtrace')).toHaveCount(2)
})
})
test(
'Opening multiple panes persists when switching projects',
{ tag: '@electron' },
{ tag: '@desktop' },
async ({ context, page }, testInfo) => {
// Setup multiple projects.
await context.folderSetupFn(async (dir) => {
@ -310,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

@ -36,7 +36,10 @@ test.describe('Command bar tests', () => {
await u.closeDebugPanel()
// Click the line of code for xLine.
await page.getByText(`close()`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
await page.getByText(`startProfile(at = [-10, -10])`).click()
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
await page.waitForTimeout(200)
await toolbar.extrudeButton.click()
await cmdBar.expectState({
@ -45,10 +48,10 @@ test.describe('Command bar tests', () => {
currentArgKey: 'sketches',
currentArgValue: '',
headerArguments: {
Sketches: '',
Profiles: '',
Length: '',
},
highlightedHeaderArg: 'sketches',
highlightedHeaderArg: 'Profiles',
})
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
@ -56,7 +59,7 @@ test.describe('Command bar tests', () => {
stage: 'review',
commandName: 'Extrude',
headerArguments: {
Sketches: '1 segment',
Profiles: '1 profile',
Length: '5',
},
})
@ -286,7 +289,7 @@ test.describe('Command bar tests', () => {
await cmdBar.cmdOptions.getByText('Extrude').click()
// Assert that we're on the selection step
await expect(page.getByRole('button', { name: 'sketches' })).toBeDisabled()
await expect(page.getByRole('button', { name: 'Profiles' })).toBeDisabled()
// Select a face
await page.mouse.move(700, 200)
await page.mouse.click(700, 200)
@ -399,7 +402,6 @@ test.describe('Command bar tests', () => {
sortBy: 'last-modified-desc',
})
await page.goto(page.url() + targetURL)
expect(page.url()).toContain(targetURL)
})
await test.step(`Submit the command`, async () => {
@ -410,7 +412,7 @@ test.describe('Command bar tests', () => {
currentArgValue: '',
headerArguments: {
Method: '',
Name: 'test',
Name: 'main.kcl',
Code: '1 line',
},
highlightedHeaderArg: 'method',
@ -421,7 +423,7 @@ test.describe('Command bar tests', () => {
commandName: 'Import file from URL',
headerArguments: {
Method: 'New project',
Name: 'test',
Name: 'main.kcl',
Code: '1 line',
},
})
@ -463,7 +465,6 @@ test.describe('Command bar tests', () => {
sortBy: 'last-modified-desc',
})
await page.goto(page.url() + targetURL)
expect(page.url()).toContain(targetURL)
})
await test.step(`Submit the command`, async () => {
@ -474,7 +475,7 @@ test.describe('Command bar tests', () => {
currentArgValue: '',
headerArguments: {
Method: '',
Name: 'test',
Name: 'main.kcl',
Code: '1 line',
},
highlightedHeaderArg: 'method',
@ -487,7 +488,7 @@ test.describe('Command bar tests', () => {
currentArgValue: '',
headerArguments: {
Method: 'Existing project',
Name: 'test',
Name: 'main.kcl',
ProjectName: '',
Code: '1 line',
},
@ -500,7 +501,7 @@ test.describe('Command bar tests', () => {
headerArguments: {
Method: 'Existing project',
ProjectName: 'testProjectDir',
Name: 'test',
Name: 'main.kcl',
Code: '1 line',
},
})
@ -510,7 +511,7 @@ test.describe('Command bar tests', () => {
await test.step(`Ensure we created the project and are in the modeling scene`, async () => {
await editor.expectEditor.toContain('extrusionDistance = 12')
await toolbar.openPane('files')
await toolbar.expectFileTreeState(['main.kcl', 'test.kcl'])
await toolbar.expectFileTreeState(['main-1.kcl', 'main.kcl'])
})
})
@ -518,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
@ -533,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)
})
@ -661,4 +662,56 @@ c = 3 + a`
`a = 5b = a * amyParameter001 = ${newValue}c = 3 + a`
)
})
test('Command palette can be opened via query parameter', async ({
page,
homePage,
cmdBar,
}) => {
await page.goto(`${page.url()}/?cmd=app.theme&groupId=settings`)
await homePage.expectState({
projectCards: [],
sortBy: 'last-modified-desc',
})
await cmdBar.expectState({
stage: 'arguments',
commandName: 'Settings · app · theme',
currentArgKey: 'value',
currentArgValue: '',
headerArguments: {
Level: 'user',
Value: '',
},
highlightedHeaderArg: 'value',
})
})
test('Text-to-CAD command can be closed with escape while in prompt', async ({
page,
homePage,
cmdBar,
}) => {
await homePage.expectState({
projectCards: [],
sortBy: 'last-modified-desc',
})
await homePage.textToCadBtn.click()
await cmdBar.expectState({
stage: 'arguments',
commandName: 'Text-to-CAD Create',
currentArgKey: 'prompt',
currentArgValue: '',
headerArguments: {
Method: 'New project',
NewProjectName: 'untitled',
Prompt: '',
},
highlightedHeaderArg: 'prompt',
})
await page.keyboard.press('Escape')
await cmdBar.toBeClosed()
await cmdBar.expectState({
stage: 'commandBarClosed',
})
})
})

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 = [3.14, 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 = [3.14, 12])
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
|> startProfile(at = [0, 12])
|> xLine(length = 5) // lin`.replaceAll('\n', '')
)
})
})
@ -1131,6 +1124,8 @@ sketch001 = startSketchOn(XZ)
await page.waitForTimeout(100)
await page.getByText('startProfile(at = [4.61, -14.01])').click()
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
await page.waitForTimeout(200)
await toolbar.extrudeButton.click()
await cmdBar.progressCmdBar()
await cmdBar.expectState({
@ -1138,7 +1133,7 @@ sketch001 = startSketchOn(XZ)
currentArgKey: 'length',
currentArgValue: '5',
headerArguments: {
Sketches: '1 face',
Profiles: '1 profile',
Length: '',
},
highlightedHeaderArg: 'length',
@ -1148,7 +1143,7 @@ sketch001 = startSketchOn(XZ)
await cmdBar.expectState({
stage: 'review',
headerArguments: {
Sketches: '1 face',
Profiles: '1 profile',
Length: '5',
},
commandName: 'Extrude',
@ -1335,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')
@ -1588,4 +1583,38 @@ sketch001 = startSketchOn(XZ)
await expect(page.getByTestId('center-rectangle')).toBeVisible()
})
})
test('syntax errors still show when reopening KCL pane', async ({
page,
homePage,
scene,
cmdBar,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// Wait for connection, this is especially important for this test, because safeParse is invoked when
// connection is established which would interfere with the test if it happened during later steps.
await scene.connectionEstablished()
await scene.settled(cmdBar)
// Code with no error
await u.codeLocator.fill(`x = 7`)
await page.waitForTimeout(200) // allow some time for the error to show potentially
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0)
// Code with error
await u.codeLocator.fill(`x 7`)
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(1)
// Close and reopen KCL code panel
await u.closeKclCodePanel()
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0) // error disappears on close
await u.openKclCodePanel()
// Verify error is still visible
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(1)
})
})

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'
@ -238,9 +238,29 @@ test.describe('when using the file tree to', () => {
}
)
test(
`create new folders and that doesn't trigger a navigation`,
{ tag: ['@desktop', '@macos', '@windows'] },
async ({ page, homePage, scene, toolbar, cmdBar }) => {
await homePage.goToModelingScene()
await scene.settled(cmdBar)
await toolbar.openPane('files')
const { createNewFolder } = await getUtils(page, test)
await createNewFolder('folder')
await createNewFolder('folder.kcl')
await test.step(`Postcondition: folders are created and we didn't navigate`, async () => {
await toolbar.expectFileTreeState(['folder', 'folder.kcl', 'main.kcl'])
await expect(toolbar.fileName).toHaveText('main.kcl')
})
}
)
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)
@ -271,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 {
@ -341,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 })
@ -430,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 })
@ -516,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 })
@ -598,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 })
@ -701,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')
@ -766,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 })
@ -820,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 })
@ -886,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(
@ -950,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(
@ -1025,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')
@ -1092,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')
@ -1192,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

@ -105,14 +105,19 @@ export class CmdBarFixture {
expectState = async (expected: CmdBarSerialised) => {
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
}
/** The method will use buttons OR press enter randomly to progress the cmdbar,
* this could have unexpected results depending on what's focused
*
* TODO: This method assumes the user has a valid input to the current stage,
/**
* This method is used to progress the command bar to the next step, defaulting to clicking the next button.
* Optionally, with the `shouldUseKeyboard` parameter, it will hit `Enter` to progress.
* * TODO: This method assumes the user has a valid input to the current stage,
* and assumes we are past the `pickCommand` step.
*/
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
progressCmdBar = async (shouldUseKeyboard = false) => {
await this.page.waitForTimeout(2000)
if (shouldUseKeyboard) {
await this.page.keyboard.press('Enter')
return
}
const arrowButton = this.page.getByRole('button', {
name: 'arrow right Continue',
})
@ -146,9 +151,7 @@ export class CmdBarFixture {
await this.cmdBarOpenBtn.click()
await expect(this.page.getByPlaceholder('Search commands')).toBeVisible()
if (selectCmd === 'promptToEdit') {
const promptEditCommand = this.page.getByText(
'Use Zoo AI to edit your parts and code.'
)
const promptEditCommand = this.selectOption({ name: 'Text-to-CAD Edit' })
await expect(promptEditCommand.first()).toBeVisible()
await promptEditCommand.first().scrollIntoViewIfNeeded()
await promptEditCommand.first().click()
@ -310,6 +313,11 @@ export class CmdBarFixture {
await expect(this.cmdBarElement).toBeVisible({ timeout: 10_000 })
}
async toBeClosed() {
// Check that the command bar is closed
await expect(this.cmdBarElement).not.toBeVisible({ timeout: 10_000 })
}
async expectArgValue(value: string) {
// Check the placeholder project name exists
const actualArgument = await this.cmdBarElement

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

@ -26,6 +26,7 @@ export class HomePageFixture {
sortByNameBtn!: Locator
appHeader!: Locator
tutorialBtn!: Locator
textToCadBtn!: Locator
constructor(page: Page) {
this.page = page
@ -47,6 +48,7 @@ export class HomePageFixture {
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
this.appHeader = this.page.getByTestId('app-header')
this.tutorialBtn = this.page.getByTestId('home-tutorial-button')
this.textToCadBtn = this.page.getByTestId('home-text-to-cad')
}
private _serialiseSortBy = async (): Promise<
@ -121,11 +123,13 @@ export class HomePageFixture {
await projectCard.click()
}
goToModelingScene = async (name: string = 'testDefault') => {
/** 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
}
isNativeFileMenuCreated = async () => {

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

@ -61,6 +61,7 @@ class MyAPIReporter implements Reporter {
const payload = {
// Required information
project: 'https://github.com/KittyCAD/modeling-app',
suite: process.env.CI_SUITE || 'e2e',
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
test: test.titlePath().slice(2).join(' '),

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()
@ -252,7 +252,7 @@ test.describe(
tronApp,
'Edit.Modify with Zoo Text-To-CAD'
)
await cmdBar.expectCommandName('Prompt-to-edit')
await cmdBar.expectCommandName('Text-to-CAD Edit')
})
await test.step('Modeling.Edit.Edit parameter', async () => {
await page.waitForTimeout(250)
@ -518,7 +518,7 @@ test.describe(
'Design.Create with Zoo Text-To-CAD'
)
await cmdBar.toBeOpened()
await cmdBar.expectCommandName('Text to CAD')
await cmdBar.expectCommandName('Text-to-CAD Create')
})
await test.step('Modeling.Design.Modify with Zoo Text-To-CAD', async () => {
@ -528,7 +528,7 @@ test.describe(
'Design.Modify with Zoo Text-To-CAD'
)
await cmdBar.toBeOpened()
await cmdBar.expectCommandName('Prompt-to-edit')
await cmdBar.expectCommandName('Text-to-CAD Edit')
})
await test.step('Modeling.Help.KCL code samples', async () => {

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