Skip to content

Commit bd4bad0

Browse files
authored
allow sending async commands to engine (#6342)
* start of async Signed-off-by: Jess Frazelle <[email protected]> check at end if the async commands completed Signed-off-by: Jess Frazelle <[email protected]> run at the end of inner_run Signed-off-by: Jess Frazelle <[email protected]> set import as async Signed-off-by: Jess Frazelle <[email protected]> updates Signed-off-by: Jess Frazelle <[email protected]> updates Signed-off-by: Jess Frazelle <[email protected]> add to the wasm side Signed-off-by: Jess Frazelle <[email protected]> updates Signed-off-by: Jess Frazelle <[email protected]> fmt Signed-off-by: Jess Frazelle <[email protected]> * fire Signed-off-by: Jess Frazelle <[email protected]> * flake Signed-off-by: Jess Frazelle <[email protected]> * fixup for awaiting on import Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * fix mock Signed-off-by: Jess Frazelle <[email protected]> * fix mock Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * fixes Signed-off-by: Jess Frazelle <[email protected]> * add a test where we import then do a bunch of other stuff Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * fixup to see Signed-off-by: Jess Frazelle <[email protected]> * fixups Signed-off-by: Jess Frazelle <[email protected]> * fix tests���� Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * cross platform time Signed-off-by: Jess Frazelle <[email protected]> * fixes Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * another appearance tests Signed-off-by: Jess Frazelle <[email protected]> * new docs and tests Signed-off-by: Jess Frazelle <[email protected]> * updates Signed-off-by: Jess Frazelle <[email protected]> * dont loop so tight Signed-off-by: Jess Frazelle <[email protected]> * fixes Signed-off-by: Jess Frazelle <[email protected]> --------- Signed-off-by: Jess Frazelle <[email protected]>
1 parent 0b9889e commit bd4bad0

40 files changed

+5681336
-156
lines changed

Diff for: docs/kcl/appearance.md

+20-4
Large diffs are not rendered by default.

Diff for: docs/kcl/modules.md

+95
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,98 @@ Coordinate systems:
109109
- `zoo` (the default), forward: -Y, up: +Z, handedness: right
110110
- `opengl`, forward: +Z, up: +Y, handedness: right
111111
- `vulkan`, forward: +Z, up: -Y, handedness: left
112+
113+
### Performance
114+
115+
Parallelized foreign-file imports now let you overlap file reads, initialization,
116+
and rendering. To maximize throughput, you need to understand the three distinct
117+
stages—reading, initializing (background render start), and invocation (blocking)
118+
—and structure your code to defer blocking operations until the end.
119+
120+
#### Foreign Import Execution Stages
121+
122+
1. **Import (Read) Stage**
123+
```norun
124+
import "tests/inputs/cube.step" as cube
125+
```
126+
- Reads the file from disk and makes its API available.
127+
- **Does _not_** start Engine rendering or block your script.
128+
129+
2. **Initialization (Background Render) Stage**
130+
```norun
131+
import "tests/inputs/cube.step" as cube
132+
133+
myCube = cube // <- This line starts background rendering
134+
```
135+
- Invoking the imported symbol (assignment or plain call) triggers Engine rendering _in the background_.
136+
- This kick‑starts the render pipeline but doesn’t block—you can continue other work while the Engine processes the model.
137+
138+
3. **Invocation (Blocking) Stage**
139+
```norun
140+
import "tests/inputs/cube.step" as cube
141+
142+
myCube = cube
143+
144+
myCube
145+
|> translate(z=10) // <- This line blocks
146+
```
147+
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
148+
- This is the only point where your script will block.
149+
150+
> **Nuance:** Foreign imports differ from pure KCL modules—calling the same import symbol multiple times (e.g., `screw` twice) starts background rendering twice.
151+
152+
#### Best Practices
153+
154+
##### 1. Defer Blocking Calls
155+
Initialize early but delay all transformations until after your heavy computation:
156+
```norun
157+
import "tests/inputs/cube.step" as cube // 1) Read
158+
159+
myCube = cube // 2) Background render starts
160+
161+
162+
// --- perform other operations and calculations or setup here ---
163+
164+
165+
myCube
166+
|> translate(z=10) // 3) Blocks only here
167+
```
168+
169+
##### 2. Encapsulate Imports in Modules
170+
Keep `main.kcl` free of reads and initialization; wrap them:
171+
172+
```norun
173+
// imports.kcl
174+
import "tests/inputs/cube.step" as cube // Read only
175+
176+
177+
export myCube = cube // Kick off rendering
178+
```
179+
180+
```norun
181+
// main.kcl
182+
import myCube from "imports.kcl" // Import the initialized object
183+
184+
185+
// ... computations ...
186+
187+
188+
myCube
189+
|> translate(z=10) // Blocking call at the end
190+
```
191+
192+
##### 3. Avoid Immediate Method Calls
193+
194+
```norun
195+
import "tests/inputs/cube.step" as cube
196+
197+
cube
198+
|> translate(z=10) // Blocks immediately, negating parallelism
199+
```
200+
201+
Both calling methods right on `cube` immediately or leaving an implicit import without assignment introduce blocking.
202+
203+
#### Future Improvements
204+
205+
Upcoming releases will auto‑analyze dependencies and only block when truly necessary. Until then, explicit deferral and modular wrapping give you the best performance.
206+

Diff for: docs/kcl/rotate.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ rotate(
5353

5454
### Returns
5555

56-
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry.
56+
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
5757

5858

5959
### Examples

Diff for: docs/kcl/scale.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ scale(
3737

3838
### Returns
3939

40-
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry.
40+
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
4141

4242

4343
### Examples

Diff for: docs/kcl/std.json

+116-19
Original file line numberDiff line numberDiff line change
@@ -28101,14 +28101,62 @@
2810128101
"args": [
2810228102
{
2810328103
"name": "solids",
28104-
"type": "[Solid]",
28104+
"type": "SolidOrImportedGeometry",
2810528105
"schema": {
2810628106
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
28107-
"title": "Array_of_Solid",
28108-
"type": "array",
28109-
"items": {
28110-
"$ref": "#/components/schemas/Solid"
28111-
},
28107+
"title": "SolidOrImportedGeometry",
28108+
"description": "Data for a solid or an imported geometry.",
28109+
"oneOf": [
28110+
{
28111+
"description": "Data for an imported geometry.",
28112+
"type": "object",
28113+
"required": [
28114+
"id",
28115+
"type",
28116+
"value"
28117+
],
28118+
"properties": {
28119+
"type": {
28120+
"type": "string",
28121+
"enum": [
28122+
"importedGeometry"
28123+
]
28124+
},
28125+
"id": {
28126+
"description": "The ID of the imported geometry.",
28127+
"type": "string",
28128+
"format": "uuid"
28129+
},
28130+
"value": {
28131+
"description": "The original file paths.",
28132+
"type": "array",
28133+
"items": {
28134+
"type": "string"
28135+
}
28136+
}
28137+
}
28138+
},
28139+
{
28140+
"type": [
28141+
"object",
28142+
"array"
28143+
],
28144+
"items": {
28145+
"$ref": "#/components/schemas/Solid"
28146+
},
28147+
"required": [
28148+
"type"
28149+
],
28150+
"properties": {
28151+
"type": {
28152+
"type": "string",
28153+
"enum": [
28154+
"solidSet"
28155+
]
28156+
}
28157+
}
28158+
}
28159+
],
2811228160
"definitions": {
2811328161
"Solid": {
2811428162
"type": "object",
@@ -34571,14 +34619,62 @@
3457134619
],
3457234620
"returnValue": {
3457334621
"name": "",
34574-
"type": "[Solid]",
34622+
"type": "SolidOrImportedGeometry",
3457534623
"schema": {
3457634624
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
34577-
"title": "Array_of_Solid",
34578-
"type": "array",
34579-
"items": {
34580-
"$ref": "#/components/schemas/Solid"
34581-
},
34625+
"title": "SolidOrImportedGeometry",
34626+
"description": "Data for a solid or an imported geometry.",
34627+
"oneOf": [
34628+
{
34629+
"description": "Data for an imported geometry.",
34630+
"type": "object",
34631+
"required": [
34632+
"id",
34633+
"type",
34634+
"value"
34635+
],
34636+
"properties": {
34637+
"type": {
34638+
"type": "string",
34639+
"enum": [
34640+
"importedGeometry"
34641+
]
34642+
},
34643+
"id": {
34644+
"description": "The ID of the imported geometry.",
34645+
"type": "string",
34646+
"format": "uuid"
34647+
},
34648+
"value": {
34649+
"description": "The original file paths.",
34650+
"type": "array",
34651+
"items": {
34652+
"type": "string"
34653+
}
34654+
}
34655+
}
34656+
},
34657+
{
34658+
"type": [
34659+
"object",
34660+
"array"
34661+
],
34662+
"items": {
34663+
"$ref": "#/components/schemas/Solid"
34664+
},
34665+
"required": [
34666+
"type"
34667+
],
34668+
"properties": {
34669+
"type": {
34670+
"type": "string",
34671+
"enum": [
34672+
"solidSet"
34673+
]
34674+
}
34675+
}
34676+
}
34677+
],
3458234678
"definitions": {
3458334679
"Solid": {
3458434680
"type": "object",
@@ -36198,7 +36294,8 @@
3619836294
"// Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.\n// This example shows _before_ the pattern.\nexampleSketch = startSketchOn(XZ)\n |> startProfileAt([0, 0], %)\n |> line(end = [0, 2])\n |> line(end = [3, 1])\n |> line(end = [0, -4])\n |> close()\n\nexample = extrude(exampleSketch, length = 1)\n |> appearance(color = '#ff0000', metalness = 90, roughness = 90)\n |> patternLinear3d(axis = [1, 0, 1], instances = 7, distance = 6)",
3619936295
"// Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.\n// This example shows _after_ the pattern.\nexampleSketch = startSketchOn(XZ)\n |> startProfileAt([0, 0], %)\n |> line(end = [0, 2])\n |> line(end = [3, 1])\n |> line(end = [0, -4])\n |> close()\n\nexample = extrude(exampleSketch, length = 1)\n |> patternLinear3d(axis = [1, 0, 1], instances = 7, distance = 6)\n |> appearance(color = '#ff0000', metalness = 90, roughness = 90)",
3620036296
"// Color the result of a 2D pattern that was extruded.\nexampleSketch = startSketchOn(XZ)\n |> startProfileAt([.5, 25], %)\n |> line(end = [0, 5])\n |> line(end = [-1, 0])\n |> line(end = [0, -5])\n |> close()\n |> patternCircular2d(\n center = [0, 0],\n instances = 13,\n arcDegrees = 360,\n rotateDuplicates = true,\n )\n\nexample = extrude(exampleSketch, length = 1)\n |> appearance(color = '#ff0000', metalness = 90, roughness = 90)",
36201-
"// Color the result of a sweep.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc(angle = 90, radius = 5)\n |> line(end = [-3, 0])\n |> tangentialArc(angle = -90, radius = 5)\n |> line(end = [0, 7])\n\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> appearance(color = \"#ff0000\", metalness = 50, roughness = 50)"
36297+
"// Color the result of a sweep.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc(angle = 90, radius = 5)\n |> line(end = [-3, 0])\n |> tangentialArc(angle = -90, radius = 5)\n |> line(end = [0, 7])\n\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> appearance(color = \"#ff0000\", metalness = 50, roughness = 50)",
36298+
"// Change the appearance of an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n// |> appearance(\n// color = \"#ff0000\",\n// metalness = 50,\n// roughness = 50\n// )"
3620236299
]
3620336300
},
3620436301
{
@@ -249578,7 +249675,7 @@
249578249675
"schema": {
249579249676
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
249580249677
"title": "SolidOrSketchOrImportedGeometry",
249581-
"description": "Data for a solid or an imported geometry.",
249678+
"description": "Data for a solid, sketch, or an imported geometry.",
249582249679
"oneOf": [
249583249680
{
249584249681
"description": "Data for an imported geometry.",
@@ -260975,7 +261072,7 @@
260975261072
"schema": {
260976261073
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
260977261074
"title": "SolidOrSketchOrImportedGeometry",
260978-
"description": "Data for a solid or an imported geometry.",
261075+
"description": "Data for a solid, sketch, or an imported geometry.",
260979261076
"oneOf": [
260980261077
{
260981261078
"description": "Data for an imported geometry.",
@@ -262721,7 +262818,7 @@
262721262818
"schema": {
262722262819
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
262723262820
"title": "SolidOrSketchOrImportedGeometry",
262724-
"description": "Data for a solid or an imported geometry.",
262821+
"description": "Data for a solid, sketch, or an imported geometry.",
262725262822
"oneOf": [
262726262823
{
262727262824
"description": "Data for an imported geometry.",
@@ -270879,7 +270976,7 @@
270879270976
"schema": {
270880270977
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
270881270978
"title": "SolidOrSketchOrImportedGeometry",
270882-
"description": "Data for a solid or an imported geometry.",
270979+
"description": "Data for a solid, sketch, or an imported geometry.",
270883270980
"oneOf": [
270884270981
{
270885270982
"description": "Data for an imported geometry.",
@@ -319774,7 +319871,7 @@
319774319871
"schema": {
319775319872
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
319776319873
"title": "SolidOrSketchOrImportedGeometry",
319777-
"description": "Data for a solid or an imported geometry.",
319874+
"description": "Data for a solid, sketch, or an imported geometry.",
319778319875
"oneOf": [
319779319876
{
319780319877
"description": "Data for an imported geometry.",
@@ -327932,7 +328029,7 @@
327932328029
"schema": {
327933328030
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
327934328031
"title": "SolidOrSketchOrImportedGeometry",
327935-
"description": "Data for a solid or an imported geometry.",
328032+
"description": "Data for a solid, sketch, or an imported geometry.",
327936328033
"oneOf": [
327937328034
{
327938328035
"description": "Data for an imported geometry.",

Diff for: docs/kcl/translate.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ translate(
3333

3434
### Returns
3535

36-
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry.
36+
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
3737

3838

3939
### Examples

Diff for: docs/kcl/types/SolidOrSketchOrImportedGeometry.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
22
title: "SolidOrSketchOrImportedGeometry"
3-
excerpt: "Data for a solid or an imported geometry."
3+
excerpt: "Data for a solid, sketch, or an imported geometry."
44
layout: manual
55
---
66

7-
Data for a solid or an imported geometry.
7+
Data for a solid, sketch, or an imported geometry.
88

99

1010

Diff for: e2e/playwright/point-click-assemblies.spec.ts

-8
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,6 @@ test.describe('Point-and-click assemblies tests', () => {
405405
)
406406
await scene.settled(cmdBar)
407407

408-
// TODO: remove this once #5780 is fixed
409-
await page.reload()
410-
411-
await scene.settled(cmdBar)
412408
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
413409
await toolbar.closePane('code')
414410
await scene.expectPixelColor(partColor, partPoint, tolerance)
@@ -453,10 +449,6 @@ test.describe('Point-and-click assemblies tests', () => {
453449
)
454450
await scene.settled(cmdBar)
455451

456-
// TODO: remove this once #5780 is fixed
457-
await page.reload()
458-
await scene.settled(cmdBar)
459-
460452
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
461453
await toolbar.closePane('code')
462454
await scene.expectPixelColor(partColor, partPoint, tolerance)

Diff for: flake.nix

+2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
packages =
4545
(with pkgs; [
4646
rustToolchain
47+
cargo-criterion
4748
cargo-nextest
49+
cargo-sort
4850
just
4951
postgresql.lib
5052
openssl

0 commit comments

Comments
 (0)