Compare commits

...

25 Commits

Author SHA1 Message Date
61807e7629 KCL: Make shell stdlib fn use keyword arguments (#5293)
Before:

```
shell({ faces = ['end'], thickness = caseThickness }, case)
```

After:
```
shell(case, faces = ['end'], thickness = caseThickness)
```
2025-02-07 02:03:12 +00:00
357bbffce5 refactor: Rename function to not have unneeded prefix (#5292) 2025-02-06 19:54:58 -05:00
6ac9c49773 KCL: Patterns of patterns can use the original sketch/solid as target (#5284)
Right now, if you model something like this box with a button:

<img width="413" alt="Screenshot 2025-02-06 at 3 08 03 PM" src="https://github.com/user-attachments/assets/04818a70-7cf3-4ee3-b8c5-df5959ac10db" />

Let's say you want to pattern the button, and repeat it a second time. If you try, you'll actually pattern the entire model (box + button).

<img width="486" alt="Screenshot 2025-02-06 at 3 08 52 PM" src="https://github.com/user-attachments/assets/09fc28d9-5d80-4ab3-b4dc-b8de2945fcba" />

Why? Because right now, when you sketch on a face (like the button was), both the box and the button share the same ID. All extrusions from a solid will share the same ID, because they all refer to the same composite solid.

This is helpful in some ways -- arguably the solid _is_ just one big complex shape now -- but it's not helpful in other ways. What if I want to only pattern the button? Luckily there's an original ID for the button part, which is still stored. So we just need a way to tell the pattern stdlib functions whether to use the target's main ID or its original ID. This PR adds a new optional bool, `useOriginal`, to patterns. It's false by default, to keep backwards-compatibility (make sure that old KCL code doesn't change).

This PR is based on https://github.com/KittyCAD/modeling-app/pull/3914. It's based on work Serena and I are doing to fix a bug (engine does not allow patterning a 3D solid which was sketched on a face of another solid). @gserena01 our test program is now:

```
w = 400

case = startSketchOn('XY')
  |> startProfileAt([-w, -w], %)
  |> line(endAbsolute = [-w, w])
  |> line(endAbsolute = [w, -w])
  |> line(endAbsolute = [-w, -w])
  |> close()
  |> extrude(length = 200)

bump1 = startSketchOn(case, 'end')
  |> circle({ center = [-50, -50], radius = 40 }, %)
  |> extrude(length = 20)

// We pass in "bump1" here since we want to pattern just this object on the face.
useOriginal = true
target = bump1
transform = {
  axis = [1, 0, 0],
  instances = 3,
  distance = -100
}
patternLinear3d(transform, target, useOriginal)
```

If you change the `useOriginal = true` to `false` you can see the difference.
2025-02-06 17:46:47 -06:00
020497cde2 Don't close the command palette on backspace (#5291)
* Don't close the command palette on backspace

It leads to awkward UX like the one reported in #5007. Users can still
go back between arguments using <kbd>Backspace</kbd> on an empty
argument, but to close it they have to hit <kbd>Escape</kbd>,
<kbd>Cmd+K</kbd>, or click the close button.

* fmt
'
2025-02-06 16:28:35 -05:00
688852a5df Bump @types/mocha from 10.0.7 to 10.0.10 (#5028)
Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 10.0.7 to 10.0.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha)

---
updated-dependencies:
- dependency-name: "@types/mocha"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 15:17:14 -05:00
6c635bd70d refactor: Remove dead code to update the artifact graph after mock execution (#5158)
Remove dead code to update the artifact graph after mock execution
2025-02-06 17:56:19 +00:00
1c0a38a1e2 Update lower-right corner units menu to read and edit inline settings annotations if present (#5212)
* WIP show annotation length unit setting in LowerRightControls if present

* Add logic for changing settings annotation if it's present

* Add E2E test

* Cleanup lints, fmt, tsc, logs

* Change to use settings from Rust helper function

- Fix thrown error to use the cause field
- Fix function names to not use "get"

* Remove unneeded constants

* Post-merge fixups

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

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

* Add back `ImportStatement` to make tsc happy (thanks @jtran!)

* fmt

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-06 17:37:13 +00:00
019cb815f9 Fix resizing view breaking app on high DPI displays (#5275)
* Fix resizing view breaking app on high DPI displays

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 12:06:50 -05:00
c8653beae7 updating onboarding bracket with SSI (#5281)
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 16:15:21 +00:00
9ea3cb51ba Bump miette from 7.2.0 to 7.5.0 in /src/wasm-lib (#5224)
Bumps [miette](https://github.com/zkat/miette) from 7.2.0 to 7.5.0.
- [Release notes](https://github.com/zkat/miette/releases)
- [Changelog](https://github.com/zkat/miette/blob/main/CHANGELOG.md)
- [Commits](https://github.com/zkat/miette/commits)

---
updated-dependencies:
- dependency-name: miette
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-06 08:06:10 -08:00
e0de0493ab Skip prompt-to-edit playwright tests on windows (#5290)
* Skip prompt-to-edit playwright tests on windows

* Fix lint

* Fix test hookk

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

* Clear bad snapshots

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-06 09:45:12 -05:00
11cac0c30e Skip text-to-cad playwright tests on windows (#5286) 2025-02-06 08:48:17 -05:00
4de50edf5a Bump @types/node from 22.7.8 to 22.13.1 (#5262)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.8 to 22.13.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 10:51:07 +00:00
bebace193d Add artifact ID to KCL values that have them (#5205)
* Add artifact ID to KCL values that have them

* Fix tests to use new fields

* Update output after adding artifact IDs

* Update docs
2025-02-05 23:50:00 -05:00
f4d5578faf Revert "Disable text-to-cad tests post kw arg merge" (#5255)
* Revert "Disable text-to-cad tests post kw arg merge (#5252)"

This reverts commit 8a9d50226f.

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

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

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

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

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

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

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

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

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-05 20:40:29 -05:00
fed922cfb8 Fix to invalidate execution cache when top-level annotations change (#5238)
* Fix to invalidate cache when top-level annotations change

* Change to BTreeMap to allow deterministic iteration

* Fix execution cache to look at annotations
2025-02-06 01:23:29 +00:00
2b7325655b Fix dumb use of non-platform agnostic separator (#5279)
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-02-06 01:04:03 +00:00
d3b02b8c5b Upgrade rust toolchain to 1.84.1 (#5211)
* Upgrade rust toolchain to 1.84.1

* Fix lint warnings
2025-02-05 19:51:54 -05:00
9008fb636f Add edit flows for extrude and offset plane operations (#5045)
* Start implementing a "prepareToEdit" callback for extrude

* Start of generic edit flow for operations

* Actually invoking command bar send generically on double-click

* Refactor: break out non-React hook helper to calculate Kcl expression value

* Add unit tests, fmt

* Integrate helper to get calculated KclExpression

* Clean up unused imports, simplify use of `programMemoryFromVariables`

* Implement basic extrude editing

* Refactor: move DefaultPlanesStr to its own lib file

* Add support for editing offset planes

* Add Edit right-click menu option

* Turn off edit flow for sketch for now

* Add e2e tests for sketch and offset plane editing, fix bug found with offset plane editing

* Add failing e2e extrude edit test

* Remove action version of extrude AST mod

* Fix behavior when adding a constant while editing operation, fixing e2e test

* Patch in changes from 61b02b5703

* Remove shell's prepareToEdit

* Add other Surface types to `artifactIsPlaneWithPaths`

* refactor: rename `item` to `operation`

* Allow `prepareToEdit` to fail with a toast, signal sketch-on-offset is unimplemented

* Rework sketch e2e test to test several working and failing cases

* Fix tsc errors related to making `codeRef` optional

* Make basic error messages more friendly

* fmt

* Reset modifyAst.ts to main

* Fix broken artifactGraph unit test

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

* Remove unused import

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

* Make the offset plane insert at the end, not one before

* Fix bug caught by e2e test failure with "Command needs review" logic

* Update src/machines/modelingMachine.ts

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

* Remove console logs per @pierremtb

* Update src/components/CommandBar/CommandBarHeader.tsx

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

* Use better programMemory init thanks @jtran

* Fix tsc post merge of #5068

* Fix logic for `artifactIsPlaneWithPaths` post-merge

* Need to disable the sketch-on-face case now that artifactGraph is in Rust. Will active in a future PR (cc @jtran)

* Re-run CI after snapshots

* Update FeatureTreePane to not use `useCommandsContext`, missed during merge

* Fix merge issue, import location change on edited file

* fix click test step, which I believe is waiting for context scripts to load

* Convert toolbarFixture.exeIndicator to getter

We need to convert all these selectors on fixtures to getters, because
they can go stale if called on the fixture constructor.

* Missed a dumb little thing in toolbarFixture.ts

* Fix goof with merge

* fmt

* Another dumb missed thing during merge

I gotta get used to the LazyGit merge tool I'm not good at it yet

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

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

* Conver sceneFixture's exeIndicator to a getter

Locators on fixtures will be frozen from the time of the fixture's
initialization, I'm increasingly convinced

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

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

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

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

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

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

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

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

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

* Post-kwargs E2E test cleanup

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

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

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-05 19:33:40 -05:00
eb4048cd16 change helix to kw args (#5274)
* update

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

* updates

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

* remove old file

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-02-05 23:58:32 +00:00
c30b161e95 Fix docs to use the new snapshots (#5282) 2025-02-05 18:28:15 -05:00
0e68d03612 Update cargo test snapshots after camera change (#5280) 2025-02-05 18:22:58 -05:00
95fd14eedc Update gizmo e2e flow test camera values (#5278)
* Update gizmo e2e flow test camera values

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-05 17:21:35 -05:00
3c367426c6 remove lineTo.md (#5276)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-02-05 13:48:14 -08:00
a277cce636 Fix fetch:samples script after kwargs merge (#5272)
* Fix fetch:samples script after kwargs merge

* Second instance

* Better fix back to before #5249
2025-02-05 16:16:10 -05:00
387 changed files with 21959 additions and 2390 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
```js
patternTransform2d(total_instances: integer, transform_function: FunctionParam, solid_set: SketchSet) -> [Sketch]
patternTransform2d(total_instances: integer, transform_function: FunctionParam, solid_set: SketchSet, use_original?: bool) -> [Sketch]
```
@ -20,6 +20,7 @@ patternTransform2d(total_instances: integer, transform_function: FunctionParam,
| `total_instances` | `integer` | | Yes |
| `transform_function` | `FunctionParam` | | Yes |
| `solid_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `use_original` | `bool` | | 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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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 it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
---
title: "ArtifactId"
excerpt: ""
layout: manual
---
**Type:** `string` (`uuid`)

View File

@ -20,5 +20,6 @@ Data for a circular pattern on a 2D sketch.
| `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No |
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
| `useOriginal` |`boolean`| If the target being patterned is itself a pattern, then, should you use the original solid, or the pattern? | No |

View File

@ -21,5 +21,6 @@ Data for a circular pattern on a 3D model.
| `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No |
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
| `useOriginal` |`boolean`| If the target being patterned is itself a pattern, then, should you use the original solid, or the pattern? | No |

View File

@ -17,6 +17,7 @@ A face.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |`string`| The id of the face. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |`string`| The tag of the face. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the faces X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the faces Y axis be? | No |

View File

@ -17,6 +17,7 @@ A helix.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |`string`| The id of the helix. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |

View File

@ -1,26 +0,0 @@
---
title: "HelixData"
excerpt: "Data for a helix."
layout: manual
---
Data for a helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
| `length` |`number`| Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. | No |
| `radius` |`number`| Radius of the helix. | No |
| `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No |

View File

@ -17,6 +17,7 @@ A helix.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |`string`| The id of the helix. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `revolutions` |`number`| Number of revolutions. | No |
| `angleStart` |`number`| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |

View File

@ -17,6 +17,7 @@ A plane.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |`string`| The id of the plane. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A plane. | No |
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the planes X axis be? | No |

View File

@ -21,6 +21,8 @@ A sketch is a collection of paths.
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |`string`| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch is a collection of paths. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -30,6 +30,8 @@ A sketch is a collection of paths.
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |`string`| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch or a group of sketches. | No |
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |

View File

@ -26,6 +26,7 @@ A plane.
|----------|------|-------------|----------|
| `type` |enum: `plane`| | No |
| `id` |`string`| The id of the plane. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A sketch type. | No |
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the planes X axis be? | No |
@ -50,6 +51,7 @@ A face.
|----------|------|-------------|----------|
| `type` |enum: `face`| | No |
| `id` |`string`| The id of the face. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |`string`| The tag of the face. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the faces X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the faces Y axis be? | No |

View File

@ -17,6 +17,7 @@ An solid is a collection of extrude surfaces.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |`string`| The id of the solid. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID of the solid. Unlike `id`, this doesn't change. | No |
| `value` |`[` [`ExtrudeSurface`](/docs/kcl/types/ExtrudeSurface) `]`| The extrude surfaces. | No |
| `sketch` |[`Sketch`](/docs/kcl/types/Sketch)| The sketch. | No |
| `height` |`number`| The height of the solid. | No |

View File

@ -26,6 +26,7 @@ An solid is a collection of extrude surfaces.
|----------|------|-------------|----------|
| `type` |enum: `solid`| | No |
| `id` |`string`| The id of the solid. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID of the solid. Unlike `id`, this doesn't change. | No |
| `value` |`[` [`ExtrudeSurface`](/docs/kcl/types/ExtrudeSurface) `]`| The extrude surfaces. | No |
| `sketch` |[`Sketch`](/docs/kcl/types/Sketch)| The sketch. | No |
| `height` |`number`| The height of the solid. | No |

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

@ -35,6 +35,30 @@ sketch002 = startSketchOn(plane001)
extrude001 = extrude(sketch002, length = 10)
`
const FEAUTRE_TREE_SKETCH_CODE = `sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> angledLine([0, 4], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
2
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close(%)
extrude001 = extrude(sketch001, length = 10)
sketch002 = startSketchOn(extrude001, rectangleSegmentB001)
|> circle({
center = [-1, 2],
radius = .5
}, %)
plane001 = offsetPlane('XZ', -5)
sketch003 = startSketchOn(plane001)
|> circle({ center = [0, 0], radius = 5 }, %)
`
test.describe('Feature Tree pane', () => {
test(
'User can go to definition and go to function definition',
@ -124,4 +148,267 @@ test.describe('Feature Tree pane', () => {
})
}
)
test(
`User can edit sketch (but not on offset plane yet) from the feature tree`,
{ tag: '@electron' },
async ({ context, homePage, scene, editor, toolbar, page }) => {
const unavailableToastMessage = page.getByText(
'Editing sketches on faces or offset planes through the feature tree is not yet supported'
)
await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'test-sample')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.writeFile(
join(bracketDir, 'main.kcl'),
FEAUTRE_TREE_SKETCH_CODE,
'utf-8'
)
})
await test.step('setup test', async () => {
await homePage.expectState({
projectCards: [
{
title: 'test-sample',
fileCount: 1,
},
],
sortBy: 'last-modified-desc',
})
await homePage.openProject('test-sample')
await scene.waitForExecutionDone()
await toolbar.openFeatureTreePane()
})
await test.step('On a default plane should work', async () => {
await (await toolbar.getFeatureTreeOperation('Sketch', 0)).dblclick()
await expect(
toolbar.exitSketchBtn,
'We should be in sketch mode now'
).toBeVisible()
await editor.expectState({
highlightedCode: '',
diagnostics: [],
activeLines: ["sketch001 = startSketchOn('XZ')"],
})
await toolbar.exitSketchBtn.click()
})
await test.step('On an extrude face should *not* work', async () => {
// Tooltip is getting in the way of clicking, so I'm first closing the pane
await toolbar.closeFeatureTreePane()
await (await toolbar.getFeatureTreeOperation('Sketch', 1)).dblclick()
await expect(
unavailableToastMessage,
'We should see a toast message about this'
).toBeVisible()
await unavailableToastMessage.waitFor({ state: 'detached' })
// TODO - turn on once we update the artifactGraph in Rust
// to include the proper source location for the extrude face
// await expect(
// toolbar.exitSketchBtn,
// 'We should be in sketch mode now'
// ).toBeVisible()
// await editor.expectState({
// highlightedCode: '',
// diagnostics: [],
// activeLines: ['|>circle({center=[-1,2],radius=.5},%)'],
// })
// await toolbar.exitSketchBtn.click()
})
await test.step('On an offset plane should *not* work', async () => {
// Tooltip is getting in the way of clicking, so I'm first closing the pane
await toolbar.closeFeatureTreePane()
await (await toolbar.getFeatureTreeOperation('Sketch', 2)).dblclick()
await editor.expectState({
highlightedCode: '',
diagnostics: [],
activeLines: ['|>circle({center=[0,0],radius=5},%)'],
})
await expect(
toolbar.exitSketchBtn,
'We should not be in sketch mode now'
).not.toBeVisible()
await expect(
page.getByText(
'Editing sketches on faces or offset planes through the feature tree is not yet supported'
),
'We should see a toast message about this'
).toBeVisible()
})
}
)
test(`User can edit an extrude operation from the feature tree`, async ({
context,
homePage,
scene,
editor,
toolbar,
cmdBar,
page,
}) => {
const initialInput = '23'
const initialCode = `sketch001 = startSketchOn('XZ')
|> circle({ center = [0, 0], radius = 5 }, %)
renamedExtrude = extrude(sketch001, length = ${initialInput})`
const newConstantName = 'distance001'
const expectedCode = `sketch001 = startSketchOn('XZ')
|> circle({ center = [0, 0], radius = 5 }, %)
${newConstantName} = 23
renamedExtrude = extrude(sketch001, length = ${newConstantName})`
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'test-sample')
await fsp.mkdir(testDir, { recursive: true })
await fsp.writeFile(join(testDir, 'main.kcl'), initialCode, 'utf-8')
})
await test.step('setup test', async () => {
await homePage.expectState({
projectCards: [
{
title: 'test-sample',
fileCount: 1,
},
],
sortBy: 'last-modified-desc',
})
await homePage.openProject('test-sample')
await scene.waitForExecutionDone()
await toolbar.openFeatureTreePane()
})
await test.step('Double click on the extrude operation', async () => {
await (await toolbar.getFeatureTreeOperation('Extrude', 0))
.first()
.dblclick()
await editor.expectState({
highlightedCode: '',
diagnostics: [],
activeLines: [
`renamedExtrude = extrude(sketch001, length = ${initialInput})`,
],
})
await cmdBar.expectState({
commandName: 'Extrude',
stage: 'arguments',
currentArgKey: 'distance',
currentArgValue: initialInput,
headerArguments: {
Selection: '1 face',
Distance: initialInput,
},
highlightedHeaderArg: 'distance',
})
})
await test.step('Add a named constant for distance argument and submit', async () => {
await expect(cmdBar.currentArgumentInput).toBeVisible()
const addVariableButton = page.getByRole('button', {
name: 'Create new variable',
})
await addVariableButton.click()
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'review',
headerArguments: {
Selection: '1 face',
// The calculated value is shown in the argument summary
Distance: initialInput,
},
commandName: 'Extrude',
})
await cmdBar.progressCmdBar()
await editor.expectState({
highlightedCode: '',
diagnostics: [],
activeLines: [
`renamedExtrude = extrude(sketch001, length = ${newConstantName})`,
],
})
await editor.expectEditor.toContain(expectedCode, {
shouldNormalise: true,
})
})
})
test(`User can edit an offset plane operation from the feature tree`, async ({
context,
homePage,
scene,
editor,
toolbar,
cmdBar,
}) => {
const testCode = (value: string) => `p = offsetPlane('XY', ${value})`
const initialInput = '10'
const initialCode = testCode(initialInput)
const newInput = '5 + 10'
const expectedCode = testCode(newInput)
await context.folderSetupFn(async (dir) => {
const testDir = join(dir, 'test-sample')
await fsp.mkdir(testDir, { recursive: true })
await fsp.writeFile(join(testDir, 'main.kcl'), initialCode, 'utf-8')
})
await test.step('setup test', async () => {
await homePage.expectState({
projectCards: [
{
title: 'test-sample',
fileCount: 1,
},
],
sortBy: 'last-modified-desc',
})
await homePage.openProject('test-sample')
await scene.waitForExecutionDone()
await toolbar.openFeatureTreePane()
})
await test.step('Double click on the offset plane operation', async () => {
await (await toolbar.getFeatureTreeOperation('Offset Plane', 0))
.first()
.dblclick()
await editor.expectState({
highlightedCode: '',
diagnostics: [],
activeLines: [initialCode],
})
await cmdBar.expectState({
commandName: 'Offset plane',
stage: 'arguments',
currentArgKey: 'distance',
currentArgValue: initialInput,
headerArguments: {
Plane: '1 plane',
Distance: initialInput,
},
highlightedHeaderArg: 'distance',
})
})
await test.step('Edit the distance argument and submit', async () => {
await expect(cmdBar.currentArgumentInput).toBeVisible()
await cmdBar.currentArgumentInput.locator('.cm-content').fill(newInput)
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'review',
headerArguments: {
Plane: '1 plane',
// We show the calculated value in the argument summary
Distance: '15',
},
commandName: 'Offset plane',
})
await cmdBar.progressCmdBar()
await editor.expectState({
highlightedCode: '',
diagnostics: [],
activeLines: [expectedCode],
})
})
})
})

View File

@ -26,11 +26,18 @@ type CmdBarSerialised =
export class CmdBarFixture {
public page: Page
cmdBarOpenBtn!: Locator
cmdBarElement!: Locator
constructor(page: Page) {
this.page = page
this.cmdBarOpenBtn = page.getByTestId('command-bar-open-button')
this.cmdBarElement = page.getByTestId('command-bar')
}
get currentArgumentInput() {
return this.page.getByTestId('cmd-bar-arg-value')
}
reConstruct = (page: Page) => {
this.page = page
}

View File

@ -38,7 +38,10 @@ export class SceneFixture {
public page: Page
public streamWrapper!: Locator
public loadingIndicator!: Locator
private exeIndicator!: Locator
get exeIndicator() {
return this.page.getByTestId('model-state-indicator-execution-done')
}
constructor(page: Page) {
this.page = page
@ -64,7 +67,6 @@ export class SceneFixture {
reConstruct = (page: Page) => {
this.page = page
this.exeIndicator = page.getByTestId('model-state-indicator-execution-done')
this.streamWrapper = page.getByTestId('stream')
this.loadingIndicator = this.streamWrapper.getByTestId('loading')
}

View File

@ -29,7 +29,6 @@ export class ToolbarFixture {
createFileBtn!: Locator
fileCreateToast!: Locator
filePane!: Locator
exeIndicator!: Locator
treeInputField!: Locator
/** The sidebar button for the Feature Tree pane */
featureTreeId = 'feature-tree' as const
@ -62,15 +61,16 @@ export class ToolbarFixture {
this.filePane = page.locator('#files-pane')
this.featureTreePane = page.locator('#feature-tree-pane')
this.fileCreateToast = page.getByText('Successfully created')
this.exeIndicator = page.getByTestId(
'model-state-indicator-receive-reliable'
)
}
get logoLink() {
return this.page.getByTestId('app-logo')
}
get exeIndicator() {
return this.page.getByTestId('model-state-indicator-receive-reliable')
}
startSketchPlaneSelection = async () =>
doAndWaitForImageDiff(this.page, () => this.startSketchBtn.click(), 500)
@ -139,7 +139,8 @@ export class ToolbarFixture {
}
/**
* Get a specific operation button from the Feature Tree pane
* Get a specific operation button from the Feature Tree pane.
* Index is 0-based.
*/
async getFeatureTreeOperation(operationName: string, operationIndex: number) {
await this.openFeatureTreePane()

View File

@ -1890,7 +1890,7 @@ chamfer04 = chamfer({ length = 5, tags = [getOppositeEdge(seg02)]}, extrude001
const testPoint = { x: 575, y: 200 }
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const shellDeclaration =
"shell001 = shell({ faces = ['end'], thickness = 5 }, extrude001)"
"shell001 = shell(extrude001, faces = ['end'], thickness = 5)"
await test.step(`Look for the grey of the shape`, async () => {
await scene.expectPixelColor([127, 127, 127], testPoint, 15)
@ -1990,8 +1990,7 @@ extrude001 = extrude(sketch001, length = 40)
const [clickOnWall] = scene.makeMouseHelpers(testPoint.x, testPoint.y + 70)
const mutatedCode = 'xLine(-40, %, $seg01)'
const shellDeclaration =
"shell001 = shell({ faces = ['end', seg01], thickness = 5}, extrude001)"
const formattedOutLastLine = '}, extrude001)'
"shell001 = shell(extrude001, faces = ['end', seg01], thickness = 5)"
await test.step(`Look for the grey of the shape`, async () => {
await scene.expectPixelColor([99, 99, 99], testPoint, 15)
@ -2034,7 +2033,7 @@ extrude001 = extrude(sketch001, length = 40)
await editor.expectEditor.toContain(shellDeclaration)
await editor.expectState({
diagnostics: [],
activeLines: [formattedOutLastLine],
activeLines: [shellDeclaration],
highlightedCode: '',
})
await scene.expectPixelColor([49, 49, 49], testPoint, 15)
@ -2088,9 +2087,8 @@ extrude002 = extrude(sketch002, length = 50)
// One dumb hardcoded screen pixel value
const testPoint = { x: 550, y: 295 }
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const shellDeclaration = `shell001 = shell({ faces = ['end'], thickness = 5 }, ${
hasExtrudesInPipe ? 'sketch002' : 'extrude002'
})`
const shellTarget = hasExtrudesInPipe ? 'sketch002' : 'extrude002'
const shellDeclaration = `shell001 = shell(${shellTarget}, faces = ['end'], thickness = 5)`
await test.step(`Look for the grey of the shape`, async () => {
await toolbar.closePane('code')

View File

@ -35,106 +35,108 @@ sketch003 = startSketchOn('XY')
extrude003 = extrude(sketch003, length = 20)
`
test.fixme('Check the happy path, for basic changing color', () => {
const cases = [
{
desc: 'User accepts change',
shouldReject: false,
},
{
desc: 'User rejects change',
shouldReject: true,
},
] as const
for (const { desc, shouldReject } of cases) {
test(`${desc}`, async ({
context,
homePage,
cmdBar,
editor,
page,
scene,
}) => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
test.describe('Check the happy path, for basic changing color', () => {
const cases = [
{
desc: 'User accepts change',
shouldReject: false,
},
{
desc: 'User rejects change',
shouldReject: true,
},
] as const
for (const { desc, shouldReject } of cases) {
test(`${desc}`, async ({
context,
homePage,
cmdBar,
editor,
page,
scene,
}) => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
const body1CapCoords = { x: 571, y: 351 }
const greenCheckCoords = { x: 565, y: 345 }
const body2WallCoords = { x: 609, y: 153 }
const [clickBody1Cap] = scene.makeMouseHelpers(
body1CapCoords.x,
body1CapCoords.y
)
const yellow: [number, number, number] = [179, 179, 131]
const green: [number, number, number] = [108, 152, 75]
const notGreen: [number, number, number] = [132, 132, 132]
const body2NotGreen: [number, number, number] = [88, 88, 88]
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
const successToast = page.getByText('Prompt to edit successful')
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
const rejectBtn = page.getByRole('button', { name: 'close Reject' })
const body1CapCoords = { x: 571, y: 351 }
const greenCheckCoords = { x: 565, y: 345 }
const body2WallCoords = { x: 609, y: 153 }
const [clickBody1Cap] = scene.makeMouseHelpers(
body1CapCoords.x,
body1CapCoords.y
)
const yellow: [number, number, number] = [179, 179, 131]
const green: [number, number, number] = [108, 152, 75]
const notGreen: [number, number, number] = [132, 132, 132]
const body2NotGreen: [number, number, number] = [88, 88, 88]
const submittingToast = page.getByText(
'Submitting to Text-to-CAD API...'
)
const successToast = page.getByText('Prompt to edit successful')
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
const rejectBtn = page.getByRole('button', { name: 'close Reject' })
await test.step('wait for scene to load select body and check selection came through', async () => {
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
await clickBody1Cap()
await scene.expectPixelColor(yellow, body1CapCoords, 20)
await editor.expectState({
highlightedCode: '',
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
diagnostics: [],
await test.step('wait for scene to load select body and check selection came through', async () => {
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
await clickBody1Cap()
await scene.expectPixelColor(yellow, body1CapCoords, 20)
await editor.expectState({
highlightedCode: '',
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
diagnostics: [],
})
})
})
await test.step('fire off edit prompt', async () => {
await cmdBar.openCmdBar('promptToEdit')
// being specific about the color with a hex means asserting pixel color is more stable
await page
.getByTestId('cmd-bar-arg-value')
.fill('make this neon green please, use #39FF14')
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(submittingToast).toBeVisible()
await expect(submittingToast).not.toBeVisible({ timeout: 2 * 60_000 }) // can take a while
await expect(successToast).toBeVisible()
})
await test.step('verify initial change', async () => {
await scene.expectPixelColor(green, greenCheckCoords, 15)
await scene.expectPixelColor(body2NotGreen, body2WallCoords, 15)
await editor.expectEditor.toContain('appearance({')
})
if (!shouldReject) {
await test.step('check accept works and can be "undo"ed', async () => {
await acceptBtn.click()
await expect(successToast).not.toBeVisible()
await test.step('fire off edit prompt', async () => {
await cmdBar.openCmdBar('promptToEdit')
// being specific about the color with a hex means asserting pixel color is more stable
await page
.getByTestId('cmd-bar-arg-value')
.fill('make this neon green please, use #39FF14')
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(submittingToast).toBeVisible()
await expect(submittingToast).not.toBeVisible({ timeout: 2 * 60_000 }) // can take a while
await expect(successToast).toBeVisible()
})
await test.step('verify initial change', async () => {
await scene.expectPixelColor(green, greenCheckCoords, 15)
await scene.expectPixelColor(body2NotGreen, body2WallCoords, 15)
await editor.expectEditor.toContain('appearance({')
// ctrl-z works after accepting
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up('ControlOrMeta')
await editor.expectEditor.not.toContain('appearance({')
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
})
} else {
await test.step('check reject works', async () => {
await rejectBtn.click()
await expect(successToast).not.toBeVisible()
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
await editor.expectEditor.not.toContain('appearance({')
})
}
})
}
})
if (!shouldReject) {
await test.step('check accept works and can be "undo"ed', async () => {
await acceptBtn.click()
await expect(successToast).not.toBeVisible()
await scene.expectPixelColor(green, greenCheckCoords, 15)
await editor.expectEditor.toContain('appearance({')
// ctrl-z works after accepting
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up('ControlOrMeta')
await editor.expectEditor.not.toContain('appearance({')
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
})
} else {
await test.step('check reject works', async () => {
await rejectBtn.click()
await expect(successToast).not.toBeVisible()
await scene.expectPixelColor(notGreen, greenCheckCoords, 15)
await editor.expectEditor.not.toContain('appearance({')
})
}
})
}
})
test.describe('bad path', { tag: ['@skipWin'] }, () => {
test(`bad edit prompt`, async ({
context,
homePage,

View File

@ -253,7 +253,7 @@ extrude001 = extrude(sketch001, length = 50)
|>
example = extrude(exampleSketch, length = 5)
shell({ faces: ['end'], thickness: 0.25 }, exampleSketch)`
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
)
})
@ -314,6 +314,7 @@ extrude001 = extrude(sketch001, length = 50)
)
test('when engine fails export we handle the failure and alert the user', async ({
scene,
page,
homePage,
}) => {
@ -383,10 +384,7 @@ extrude001 = extrude(sketch001, length = 50)
await page.keyboard.press('End')
await page.keyboard.press('Enter')
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await scene.waitForExecutionDone()
// Now try exporting

View File

@ -15,6 +15,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
page,
context,
homePage,
scene,
}) => {
const u = await getUtils(page)
const selectionsSnippets = {
@ -75,6 +76,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
// wait for execution done
await u.openDebugPanel()

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