Compare commits
2 Commits
jtran/json
...
kurt-fix-m
Author | SHA1 | Date | |
---|---|---|---|
1caa4f0d5f | |||
fb4ad593b4 |
@ -1,3 +1,3 @@
|
|||||||
[codespell]
|
[codespell]
|
||||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM
|
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM
|
||||||
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,./e2e/playwright/lib/console-error-whitelist.ts,.package-lock.json,**/package-lock.json,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo,./src/lib/machine-api.d.ts
|
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,.package-lock.json,**/package-lock.json,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo,./src/lib/machine-api.d.ts
|
||||||
|
3
.github/workflows/cargo-bench.yml
vendored
3
.github/workflows/cargo-bench.yml
vendored
@ -50,12 +50,13 @@ jobs:
|
|||||||
- name: Build the benchmark target(s)
|
- name: Build the benchmark target(s)
|
||||||
run: |
|
run: |
|
||||||
cd rust
|
cd rust
|
||||||
cargo codspeed build
|
cargo codspeed build --measurement-mode walltime
|
||||||
- name: Run the benchmarks
|
- name: Run the benchmarks
|
||||||
uses: CodSpeedHQ/action@v3
|
uses: CodSpeedHQ/action@v3
|
||||||
with:
|
with:
|
||||||
working-directory: rust
|
working-directory: rust
|
||||||
run: cargo codspeed run
|
run: cargo codspeed run
|
||||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||||
|
mode: walltime
|
||||||
env:
|
env:
|
||||||
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN }}
|
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN }}
|
||||||
|
4
.github/workflows/e2e-tests.yml
vendored
4
.github/workflows/e2e-tests.yml
vendored
@ -226,8 +226,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
shell: bash
|
shell: bash
|
||||||
command: npm run test:snapshots
|
command: npm run test:snapshots
|
||||||
timeout_minutes: 5
|
timeout_minutes: 30
|
||||||
max_attempts: 5
|
max_attempts: 3
|
||||||
env:
|
env:
|
||||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
|
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
|
||||||
|
4
Makefile
4
Makefile
@ -15,8 +15,8 @@ ifdef WINDOWS
|
|||||||
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
|
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
|
||||||
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
|
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
|
||||||
else
|
else
|
||||||
CARGO ?= $(shell which cargo || echo ~/.cargo/bin/cargo)
|
CARGO ?= ~/.cargo/bin/cargo
|
||||||
WASM_PACK ?= $(shell which wasm-pack || echo ~/.cargo/bin/wasm-pack)
|
WASM_PACK ?= ~/.cargo/bin/wasm-pack
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
|
File diff suppressed because one or more lines are too long
@ -109,98 +109,3 @@ Coordinate systems:
|
|||||||
- `zoo` (the default), forward: -Y, up: +Z, handedness: right
|
- `zoo` (the default), forward: -Y, up: +Z, handedness: right
|
||||||
- `opengl`, forward: +Z, up: +Y, handedness: right
|
- `opengl`, forward: +Z, up: +Y, handedness: right
|
||||||
- `vulkan`, forward: +Z, up: -Y, handedness: left
|
- `vulkan`, forward: +Z, up: -Y, handedness: left
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
Parallelized foreign-file imports now let you overlap file reads, initialization,
|
|
||||||
and rendering. To maximize throughput, you need to understand the three distinct
|
|
||||||
stages—reading, initializing (background render start), and invocation (blocking)
|
|
||||||
—and structure your code to defer blocking operations until the end.
|
|
||||||
|
|
||||||
#### Foreign Import Execution Stages
|
|
||||||
|
|
||||||
1. **Import (Read) Stage**
|
|
||||||
```norun
|
|
||||||
import "tests/inputs/cube.step" as cube
|
|
||||||
```
|
|
||||||
- Reads the file from disk and makes its API available.
|
|
||||||
- **Does _not_** start Engine rendering or block your script.
|
|
||||||
|
|
||||||
2. **Initialization (Background Render) Stage**
|
|
||||||
```norun
|
|
||||||
import "tests/inputs/cube.step" as cube
|
|
||||||
|
|
||||||
myCube = cube // <- This line starts background rendering
|
|
||||||
```
|
|
||||||
- Invoking the imported symbol (assignment or plain call) triggers Engine rendering _in the background_.
|
|
||||||
- This kick‑starts the render pipeline but doesn’t block—you can continue other work while the Engine processes the model.
|
|
||||||
|
|
||||||
3. **Invocation (Blocking) Stage**
|
|
||||||
```norun
|
|
||||||
import "tests/inputs/cube.step" as cube
|
|
||||||
|
|
||||||
myCube = cube
|
|
||||||
|
|
||||||
myCube
|
|
||||||
|> translate(z=10) // <- This line blocks
|
|
||||||
```
|
|
||||||
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
|
|
||||||
- This is the only point where your script will block.
|
|
||||||
|
|
||||||
> **Nuance:** Foreign imports differ from pure KCL modules—calling the same import symbol multiple times (e.g., `screw` twice) starts background rendering twice.
|
|
||||||
|
|
||||||
#### Best Practices
|
|
||||||
|
|
||||||
##### 1. Defer Blocking Calls
|
|
||||||
Initialize early but delay all transformations until after your heavy computation:
|
|
||||||
```norun
|
|
||||||
import "tests/inputs/cube.step" as cube // 1) Read
|
|
||||||
|
|
||||||
myCube = cube // 2) Background render starts
|
|
||||||
|
|
||||||
|
|
||||||
// --- perform other operations and calculations or setup here ---
|
|
||||||
|
|
||||||
|
|
||||||
myCube
|
|
||||||
|> translate(z=10) // 3) Blocks only here
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 2. Encapsulate Imports in Modules
|
|
||||||
Keep `main.kcl` free of reads and initialization; wrap them:
|
|
||||||
|
|
||||||
```norun
|
|
||||||
// imports.kcl
|
|
||||||
import "tests/inputs/cube.step" as cube // Read only
|
|
||||||
|
|
||||||
|
|
||||||
export myCube = cube // Kick off rendering
|
|
||||||
```
|
|
||||||
|
|
||||||
```norun
|
|
||||||
// main.kcl
|
|
||||||
import myCube from "imports.kcl" // Import the initialized object
|
|
||||||
|
|
||||||
|
|
||||||
// ... computations ...
|
|
||||||
|
|
||||||
|
|
||||||
myCube
|
|
||||||
|> translate(z=10) // Blocking call at the end
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 3. Avoid Immediate Method Calls
|
|
||||||
|
|
||||||
```norun
|
|
||||||
import "tests/inputs/cube.step" as cube
|
|
||||||
|
|
||||||
cube
|
|
||||||
|> translate(z=10) // Blocks immediately, negating parallelism
|
|
||||||
```
|
|
||||||
|
|
||||||
Both calling methods right on `cube` immediately or leaving an implicit import without assignment introduce blocking.
|
|
||||||
|
|
||||||
#### Future Improvements
|
|
||||||
|
|
||||||
Upcoming releases will auto‑analyze dependencies and only block when truly necessary. Until then, explicit deferral and modular wrapping give you the best performance.
|
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ rotate(
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
|
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
@ -37,7 +37,7 @@ scale(
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
|
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
@ -28101,62 +28101,14 @@
|
|||||||
"args": [
|
"args": [
|
||||||
{
|
{
|
||||||
"name": "solids",
|
"name": "solids",
|
||||||
"type": "SolidOrImportedGeometry",
|
"type": "[Solid]",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrImportedGeometry",
|
"title": "Array_of_Solid",
|
||||||
"description": "Data for a solid or an imported geometry.",
|
"type": "array",
|
||||||
"oneOf": [
|
"items": {
|
||||||
{
|
"$ref": "#/components/schemas/Solid"
|
||||||
"description": "Data for an imported geometry.",
|
},
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"type",
|
|
||||||
"value"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"importedGeometry"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"description": "The ID of the imported geometry.",
|
|
||||||
"type": "string",
|
|
||||||
"format": "uuid"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"description": "The original file paths.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": [
|
|
||||||
"object",
|
|
||||||
"array"
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/Solid"
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"solidSet"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"Solid": {
|
"Solid": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -34619,62 +34571,14 @@
|
|||||||
],
|
],
|
||||||
"returnValue": {
|
"returnValue": {
|
||||||
"name": "",
|
"name": "",
|
||||||
"type": "SolidOrImportedGeometry",
|
"type": "[Solid]",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrImportedGeometry",
|
"title": "Array_of_Solid",
|
||||||
"description": "Data for a solid or an imported geometry.",
|
"type": "array",
|
||||||
"oneOf": [
|
"items": {
|
||||||
{
|
"$ref": "#/components/schemas/Solid"
|
||||||
"description": "Data for an imported geometry.",
|
},
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"type",
|
|
||||||
"value"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"importedGeometry"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"description": "The ID of the imported geometry.",
|
|
||||||
"type": "string",
|
|
||||||
"format": "uuid"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"description": "The original file paths.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": [
|
|
||||||
"object",
|
|
||||||
"array"
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/Solid"
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"solidSet"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"Solid": {
|
"Solid": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -36294,8 +36198,7 @@
|
|||||||
"// 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)",
|
"// 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)",
|
||||||
"// 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)",
|
"// 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)",
|
||||||
"// 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)",
|
"// 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)",
|
||||||
"// 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)",
|
"// 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)"
|
||||||
"// 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// )"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -249675,7 +249578,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrSketchOrImportedGeometry",
|
"title": "SolidOrSketchOrImportedGeometry",
|
||||||
"description": "Data for a solid, sketch, or an imported geometry.",
|
"description": "Data for a solid or an imported geometry.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"description": "Data for an imported geometry.",
|
"description": "Data for an imported geometry.",
|
||||||
@ -261072,7 +260975,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrSketchOrImportedGeometry",
|
"title": "SolidOrSketchOrImportedGeometry",
|
||||||
"description": "Data for a solid, sketch, or an imported geometry.",
|
"description": "Data for a solid or an imported geometry.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"description": "Data for an imported geometry.",
|
"description": "Data for an imported geometry.",
|
||||||
@ -262818,7 +262721,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrSketchOrImportedGeometry",
|
"title": "SolidOrSketchOrImportedGeometry",
|
||||||
"description": "Data for a solid, sketch, or an imported geometry.",
|
"description": "Data for a solid or an imported geometry.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"description": "Data for an imported geometry.",
|
"description": "Data for an imported geometry.",
|
||||||
@ -270976,7 +270879,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrSketchOrImportedGeometry",
|
"title": "SolidOrSketchOrImportedGeometry",
|
||||||
"description": "Data for a solid, sketch, or an imported geometry.",
|
"description": "Data for a solid or an imported geometry.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"description": "Data for an imported geometry.",
|
"description": "Data for an imported geometry.",
|
||||||
@ -319871,7 +319774,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrSketchOrImportedGeometry",
|
"title": "SolidOrSketchOrImportedGeometry",
|
||||||
"description": "Data for a solid, sketch, or an imported geometry.",
|
"description": "Data for a solid or an imported geometry.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"description": "Data for an imported geometry.",
|
"description": "Data for an imported geometry.",
|
||||||
@ -328029,7 +327932,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "SolidOrSketchOrImportedGeometry",
|
"title": "SolidOrSketchOrImportedGeometry",
|
||||||
"description": "Data for a solid, sketch, or an imported geometry.",
|
"description": "Data for a solid or an imported geometry.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"description": "Data for an imported geometry.",
|
"description": "Data for an imported geometry.",
|
||||||
|
@ -33,7 +33,7 @@ translate(
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid, sketch, or an imported geometry.
|
[`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) - Data for a solid or an imported geometry.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: "SolidOrSketchOrImportedGeometry"
|
title: "SolidOrSketchOrImportedGeometry"
|
||||||
excerpt: "Data for a solid, sketch, or an imported geometry."
|
excerpt: "Data for a solid or an imported geometry."
|
||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
Data for a solid, sketch, or an imported geometry.
|
Data for a solid or an imported geometry.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,13 +178,6 @@ export class CmdBarFixture {
|
|||||||
return this.page.getByRole('option', options)
|
return this.page.getByRole('option', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clicks the Create new variable button for kcl input
|
|
||||||
*/
|
|
||||||
createNewVariable = async () => {
|
|
||||||
await this.page.getByRole('button', { name: 'Create new variable' }).click()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Captures a snapshot of the request sent to the text-to-cad API endpoint
|
* Captures a snapshot of the request sent to the text-to-cad API endpoint
|
||||||
* and saves it to a file named after the current test.
|
* and saves it to a file named after the current test.
|
||||||
|
@ -257,14 +257,6 @@ export class SceneFixture {
|
|||||||
await expectPixelColor(this.page, colour, coords, diff)
|
await expectPixelColor(this.page, colour, coords, diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
expectPixelColorNotToBe = async (
|
|
||||||
colour: [number, number, number] | [number, number, number][],
|
|
||||||
coords: { x: number; y: number },
|
|
||||||
diff: number
|
|
||||||
) => {
|
|
||||||
await expectPixelColorNotToBe(this.page, colour, coords, diff)
|
|
||||||
}
|
|
||||||
|
|
||||||
get gizmo() {
|
get gizmo() {
|
||||||
return this.page.locator('[aria-label*=gizmo]')
|
return this.page.locator('[aria-label*=gizmo]')
|
||||||
}
|
}
|
||||||
@ -286,69 +278,37 @@ function isColourArray(
|
|||||||
return isArray(colour[0])
|
return isArray(colour[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
type PixelColorMatchMode = 'matches' | 'differs'
|
|
||||||
|
|
||||||
export async function checkPixelColor(
|
|
||||||
page: Page,
|
|
||||||
colour: [number, number, number] | [number, number, number][],
|
|
||||||
coords: { x: number; y: number },
|
|
||||||
diff: number,
|
|
||||||
mode: PixelColorMatchMode
|
|
||||||
) {
|
|
||||||
let finalValue = colour
|
|
||||||
const isMatchMode = mode === 'matches'
|
|
||||||
const actionText = isMatchMode ? 'expecting' : 'not expecting'
|
|
||||||
const functionName = isMatchMode
|
|
||||||
? 'ExpectPixelColor'
|
|
||||||
: 'ExpectPixelColourNotToBe'
|
|
||||||
|
|
||||||
await expect
|
|
||||||
.poll(
|
|
||||||
async () => {
|
|
||||||
const pixel = (await getPixelRGBs(page)(coords, 1))[0]
|
|
||||||
if (!pixel) return null
|
|
||||||
finalValue = pixel
|
|
||||||
|
|
||||||
let matches
|
|
||||||
if (!isColourArray(colour)) {
|
|
||||||
matches = pixel.every(
|
|
||||||
(channel, index) => Math.abs(channel - colour[index]) < diff
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
matches = colour.some((c) =>
|
|
||||||
c.every((channel, index) => Math.abs(pixel[index] - channel) < diff)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return isMatchMode ? matches : !matches
|
|
||||||
},
|
|
||||||
{ timeout: 10_000 }
|
|
||||||
)
|
|
||||||
.toBeTruthy()
|
|
||||||
.catch((cause) => {
|
|
||||||
throw new Error(
|
|
||||||
`${functionName}: point ${JSON.stringify(
|
|
||||||
coords
|
|
||||||
)} was ${actionText} ${colour} but got ${finalValue}`,
|
|
||||||
{ cause }
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function expectPixelColor(
|
export async function expectPixelColor(
|
||||||
page: Page,
|
page: Page,
|
||||||
colour: [number, number, number] | [number, number, number][],
|
colour: [number, number, number] | [number, number, number][],
|
||||||
coords: { x: number; y: number },
|
coords: { x: number; y: number },
|
||||||
diff: number
|
diff: number
|
||||||
) {
|
) {
|
||||||
await checkPixelColor(page, colour, coords, diff, 'matches')
|
let finalValue = colour
|
||||||
}
|
await expect
|
||||||
|
.poll(
|
||||||
export async function expectPixelColorNotToBe(
|
async () => {
|
||||||
page: Page,
|
const pixel = (await getPixelRGBs(page)(coords, 1))[0]
|
||||||
colour: [number, number, number] | [number, number, number][],
|
if (!pixel) return null
|
||||||
coords: { x: number; y: number },
|
finalValue = pixel
|
||||||
diff: number
|
if (!isColourArray(colour)) {
|
||||||
) {
|
return pixel.every(
|
||||||
await checkPixelColor(page, colour, coords, diff, 'differs')
|
(channel, index) => Math.abs(channel - colour[index]) < diff
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return colour.some((c) =>
|
||||||
|
c.every((channel, index) => Math.abs(pixel[index] - channel) < diff)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{ timeout: 10_000 }
|
||||||
|
)
|
||||||
|
.toBeTruthy()
|
||||||
|
.catch((cause) => {
|
||||||
|
throw new Error(
|
||||||
|
`ExpectPixelColor: point ${JSON.stringify(
|
||||||
|
coords
|
||||||
|
)} was expecting ${colour} but got ${finalValue}`,
|
||||||
|
{ cause }
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -169,180 +169,6 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test(
|
|
||||||
`Insert the bracket part into an assembly and transform it`,
|
|
||||||
{ tag: ['@electron'] },
|
|
||||||
async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
tronApp,
|
|
||||||
}) => {
|
|
||||||
if (!tronApp) {
|
|
||||||
fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
const midPoint = { x: 500, y: 250 }
|
|
||||||
const moreToTheRightPoint = { x: 900, y: 250 }
|
|
||||||
const bgColor: [number, number, number] = [30, 30, 30]
|
|
||||||
const partColor: [number, number, number] = [100, 100, 100]
|
|
||||||
const tolerance = 30
|
|
||||||
const u = await getUtils(page)
|
|
||||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
|
||||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
|
||||||
|
|
||||||
await test.step('Setup parts and expect empty assembly scene', async () => {
|
|
||||||
const projectName = 'assembly'
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
|
||||||
const bracketDir = path.join(dir, projectName)
|
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
|
||||||
await Promise.all([
|
|
||||||
fsp.copyFile(
|
|
||||||
path.join('public', 'kcl-samples', 'bracket', 'main.kcl'),
|
|
||||||
path.join(bracketDir, 'bracket.kcl')
|
|
||||||
),
|
|
||||||
fsp.writeFile(path.join(bracketDir, 'main.kcl'), ''),
|
|
||||||
])
|
|
||||||
})
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.openProject(projectName)
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Insert kcl as module', async () => {
|
|
||||||
await insertPartIntoAssembly(
|
|
||||||
'bracket.kcl',
|
|
||||||
'bracket',
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
page
|
|
||||||
)
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
import "bracket.kcl" as bracket
|
|
||||||
bracket
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
// Check scene for changes
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
await u.doAndWaitForCmd(async () => {
|
|
||||||
await gizmo.click({ button: 'right' })
|
|
||||||
await resetCameraButton.click()
|
|
||||||
}, 'zoom_to_fit')
|
|
||||||
await toolbar.closePane('debug')
|
|
||||||
await scene.expectPixelColor(partColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(bgColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Set translate on module', async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
|
|
||||||
const op = await toolbar.getFeatureTreeOperation('bracket', 0)
|
|
||||||
await op.click({ button: 'right' })
|
|
||||||
await page.getByTestId('context-menu-set-translate').click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'x',
|
|
||||||
currentArgValue: '0',
|
|
||||||
headerArguments: {
|
|
||||||
X: '',
|
|
||||||
Y: '',
|
|
||||||
Z: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'x',
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('5')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.1')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.2')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
X: '5',
|
|
||||||
Y: '0.1',
|
|
||||||
Z: '0.2',
|
|
||||||
},
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
bracket
|
|
||||||
|> translate(x = 5, y = 0.1, z = 0.2)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
// Expect translated part in the scene
|
|
||||||
await scene.expectPixelColor(bgColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(partColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Set rotate on module', async () => {
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
|
|
||||||
const op = await toolbar.getFeatureTreeOperation('bracket', 0)
|
|
||||||
await op.click({ button: 'right' })
|
|
||||||
await page.getByTestId('context-menu-set-rotate').click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'roll',
|
|
||||||
currentArgValue: '0',
|
|
||||||
headerArguments: {
|
|
||||||
Roll: '',
|
|
||||||
Pitch: '',
|
|
||||||
Yaw: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'roll',
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('0.1')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.2')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.3')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
Roll: '0.1',
|
|
||||||
Pitch: '0.2',
|
|
||||||
Yaw: '0.3',
|
|
||||||
},
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
bracket
|
|
||||||
|> translate(x = 5, y = 0.1, z = 0.2)
|
|
||||||
|> rotate(roll = 0.1, pitch = 0.2, yaw = 0.3)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
// Expect no change in the scene as the rotations are tiny
|
|
||||||
await scene.expectPixelColor(bgColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(partColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
test(
|
test(
|
||||||
`Insert foreign parts into assembly as whole module import`,
|
`Insert foreign parts into assembly as whole module import`,
|
||||||
{ tag: ['@electron'] },
|
{ tag: ['@electron'] },
|
||||||
@ -405,6 +231,10 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
)
|
)
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
// TODO: remove this once #5780 is fixed
|
||||||
|
await page.reload()
|
||||||
|
|
||||||
|
await scene.settled(cmdBar)
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
||||||
@ -449,6 +279,10 @@ test.describe('Point-and-click assemblies tests', () => {
|
|||||||
)
|
)
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
// TODO: remove this once #5780 is fixed
|
||||||
|
await page.reload()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
||||||
|
@ -5,10 +5,7 @@ import type { Locator, Page } from '@playwright/test'
|
|||||||
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
||||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
import {
|
import { orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
||||||
orRunWhenFullSuiteEnabled,
|
|
||||||
runningOnWindows,
|
|
||||||
} from '@e2e/playwright/test-utils'
|
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
// test file is for testing point an click code gen functionality that's not sketch mode related
|
// test file is for testing point an click code gen functionality that's not sketch mode related
|
||||||
@ -3547,9 +3544,6 @@ tag=$rectangleSegmentC002,
|
|||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
if (runningOnWindows()) {
|
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
}
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([-102.57, 101.72], %)
|
|> startProfileAt([-102.57, 101.72], %)
|
||||||
|> angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)
|
||||||
@ -3841,469 +3835,4 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const translateExtrudeCases: { variables: boolean }[] = [
|
|
||||||
{
|
|
||||||
variables: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
variables: true,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
translateExtrudeCases.map(({ variables }) => {
|
|
||||||
test(`Set translate on extrude through right-click menu (variables: ${variables})`, async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
`
|
|
||||||
await context.addInitScript((initialCode) => {
|
|
||||||
localStorage.setItem('persistCode', initialCode)
|
|
||||||
}, initialCode)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
|
||||||
const midPoint = { x: 500, y: 250 }
|
|
||||||
const moreToTheRightPoint = { x: 800, y: 250 }
|
|
||||||
const bgColor: [number, number, number] = [50, 50, 50]
|
|
||||||
const partColor: [number, number, number] = [150, 150, 150]
|
|
||||||
const tolerance = 50
|
|
||||||
|
|
||||||
await test.step('Confirm extrude exists with default appearance', async () => {
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
await scene.expectPixelColor(partColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(bgColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Set translate through command bar flow', async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
const op = await toolbar.getFeatureTreeOperation('Extrude', 0)
|
|
||||||
await op.click({ button: 'right' })
|
|
||||||
await page.getByTestId('context-menu-set-translate').click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'x',
|
|
||||||
currentArgValue: '0',
|
|
||||||
headerArguments: {
|
|
||||||
X: '',
|
|
||||||
Y: '',
|
|
||||||
Z: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'x',
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('3')
|
|
||||||
if (variables) {
|
|
||||||
await cmdBar.createNewVariable()
|
|
||||||
}
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.1')
|
|
||||||
if (variables) {
|
|
||||||
await cmdBar.createNewVariable()
|
|
||||||
}
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.2')
|
|
||||||
if (variables) {
|
|
||||||
await cmdBar.createNewVariable()
|
|
||||||
}
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
X: '3',
|
|
||||||
Y: '0.1',
|
|
||||||
Z: '0.2',
|
|
||||||
},
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Confirm code and scene have changed', async () => {
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
if (variables) {
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
z001 = 0.2
|
|
||||||
y001 = 0.1
|
|
||||||
x001 = 3
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
|> translate(x = x001, y = y001, z = z001)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
|> translate(x = 3, y = 0.1, z = 0.2)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
await scene.expectPixelColor(bgColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(partColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Edit translate', async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
const op = await toolbar.getFeatureTreeOperation('Extrude', 0)
|
|
||||||
await op.click({ button: 'right' })
|
|
||||||
await page.getByTestId('context-menu-set-translate').click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'z',
|
|
||||||
currentArgValue: variables ? 'z001' : '0.2',
|
|
||||||
headerArguments: {
|
|
||||||
X: '3',
|
|
||||||
Y: '0.1',
|
|
||||||
Z: '0.2',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'z',
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('0.3')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
X: '3',
|
|
||||||
Y: '0.1',
|
|
||||||
Z: '0.3',
|
|
||||||
},
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(`z = 0.3`)
|
|
||||||
// Expect almost no change in scene
|
|
||||||
await scene.expectPixelColor(bgColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(partColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const rotateExtrudeCases: { variables: boolean }[] = [
|
|
||||||
{
|
|
||||||
variables: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
variables: true,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
rotateExtrudeCases.map(({ variables }) => {
|
|
||||||
test(`Set rotate on extrude through right-click menu (variables: ${variables})`, async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
`
|
|
||||||
await context.addInitScript((initialCode) => {
|
|
||||||
localStorage.setItem('persistCode', initialCode)
|
|
||||||
}, initialCode)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await test.step('Set rotate through command bar flow', async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
const op = await toolbar.getFeatureTreeOperation('Extrude', 0)
|
|
||||||
await op.click({ button: 'right' })
|
|
||||||
await page.getByTestId('context-menu-set-rotate').click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'roll',
|
|
||||||
currentArgValue: '0',
|
|
||||||
headerArguments: {
|
|
||||||
Roll: '',
|
|
||||||
Pitch: '',
|
|
||||||
Yaw: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'roll',
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('1.1')
|
|
||||||
if (variables) {
|
|
||||||
await cmdBar.createNewVariable()
|
|
||||||
}
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('1.2')
|
|
||||||
if (variables) {
|
|
||||||
await cmdBar.createNewVariable()
|
|
||||||
}
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('1.3')
|
|
||||||
if (variables) {
|
|
||||||
await cmdBar.createNewVariable()
|
|
||||||
}
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
Roll: '1.1',
|
|
||||||
Pitch: '1.2',
|
|
||||||
Yaw: '1.3',
|
|
||||||
},
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Confirm code and scene have changed', async () => {
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
if (variables) {
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
yaw001 = 1.3
|
|
||||||
pitch001 = 1.2
|
|
||||||
roll001 = 1.1
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
|> rotate(roll = roll001, pitch = pitch001, yaw = yaw001)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
|> rotate(roll = 1.1, pitch = 1.2, yaw = 1.3)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Edit rotate', async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
const op = await toolbar.getFeatureTreeOperation('Extrude', 0)
|
|
||||||
await op.click({ button: 'right' })
|
|
||||||
await page.getByTestId('context-menu-set-rotate').click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'yaw',
|
|
||||||
currentArgValue: variables ? 'yaw001' : '1.3',
|
|
||||||
headerArguments: {
|
|
||||||
Roll: '1.1',
|
|
||||||
Pitch: '1.2',
|
|
||||||
Yaw: '1.3',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'yaw',
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('13')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
Roll: '1.1',
|
|
||||||
Pitch: '1.2',
|
|
||||||
Yaw: '13',
|
|
||||||
},
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(`yaw = 13`)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test(`Set translate and rotate on extrude through selection`, async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
`
|
|
||||||
await context.addInitScript((initialCode) => {
|
|
||||||
localStorage.setItem('persistCode', initialCode)
|
|
||||||
}, initialCode)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
|
||||||
const midPoint = { x: 500, y: 250 }
|
|
||||||
const moreToTheRightPoint = { x: 800, y: 250 }
|
|
||||||
const bgColor: [number, number, number] = [50, 50, 50]
|
|
||||||
const partColor: [number, number, number] = [150, 150, 150]
|
|
||||||
const tolerance = 50
|
|
||||||
const [clickMidPoint] = scene.makeMouseHelpers(midPoint.x, midPoint.y)
|
|
||||||
const [clickMoreToTheRightPoint] = scene.makeMouseHelpers(
|
|
||||||
moreToTheRightPoint.x,
|
|
||||||
moreToTheRightPoint.y
|
|
||||||
)
|
|
||||||
|
|
||||||
await test.step('Confirm extrude exists with default appearance', async () => {
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
await scene.expectPixelColor(partColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(bgColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Set translate through command bar flow', async () => {
|
|
||||||
await cmdBar.openCmdBar()
|
|
||||||
await cmdBar.chooseCommand('Translate')
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'selection',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '',
|
|
||||||
X: '',
|
|
||||||
Y: '',
|
|
||||||
Z: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'selection',
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await clickMidPoint()
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'x',
|
|
||||||
currentArgValue: '0',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '1 path',
|
|
||||||
X: '',
|
|
||||||
Y: '',
|
|
||||||
Z: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'x',
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('2')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '1 path',
|
|
||||||
X: '2',
|
|
||||||
Y: '0',
|
|
||||||
Z: '0',
|
|
||||||
},
|
|
||||||
commandName: 'Translate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Confirm code and scene have changed', async () => {
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
|> translate(x = 2, y = 0, z = 0)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
await scene.expectPixelColor(bgColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(partColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Set rotate through command bar flow', async () => {
|
|
||||||
// clear selection
|
|
||||||
await clickMidPoint()
|
|
||||||
await cmdBar.openCmdBar()
|
|
||||||
await cmdBar.chooseCommand('Rotate')
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'selection',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '',
|
|
||||||
Roll: '',
|
|
||||||
Pitch: '',
|
|
||||||
Yaw: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'selection',
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await clickMoreToTheRightPoint()
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'roll',
|
|
||||||
currentArgValue: '0',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '1 path',
|
|
||||||
Roll: '',
|
|
||||||
Pitch: '',
|
|
||||||
Yaw: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'roll',
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await page.keyboard.insertText('0.1')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.2')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0.3')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '1 path',
|
|
||||||
Roll: '0.1',
|
|
||||||
Pitch: '0.2',
|
|
||||||
Yaw: '0.3',
|
|
||||||
},
|
|
||||||
commandName: 'Rotate',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Confirm code has changed', async () => {
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
`
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
|
||||||
extrude001 = extrude(profile001, length = 1)
|
|
||||||
|> translate(x = 2, y = 0, z = 0)
|
|
||||||
|> rotate(roll = 0.1, pitch = 0.2, yaw = 0.3)
|
|
||||||
`,
|
|
||||||
{ shouldNormalise: true }
|
|
||||||
)
|
|
||||||
// No change here since the angles are super small
|
|
||||||
await scene.expectPixelColor(bgColor, midPoint, tolerance)
|
|
||||||
await scene.expectPixelColor(partColor, moreToTheRightPoint, tolerance)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
import { orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
|
||||||
|
|
||||||
/* eslint-disable jest/no-conditional-expect */
|
/* eslint-disable jest/no-conditional-expect */
|
||||||
|
|
||||||
@ -58,7 +57,6 @@ test.describe('edit with AI example snapshots', () => {
|
|||||||
`change colour`,
|
`change colour`,
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ context, homePage, cmdBar, editor, page, scene }) => {
|
async ({ context, homePage, cmdBar, editor, page, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
await context.addInitScript((file) => {
|
await context.addInitScript((file) => {
|
||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
|
@ -3087,43 +3087,47 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
const expectSketchOriginToBeDrawn = async () => {
|
||||||
|
await scene.expectPixelColor(TEST_COLORS.WHITE, { x: 672, y: 193 }, 15)
|
||||||
|
}
|
||||||
|
|
||||||
await test.step('Open feature tree and edit second sketch', async () => {
|
await test.step('Open feature tree and edit second sketch', async () => {
|
||||||
await toolbar.openFeatureTreePane()
|
await toolbar.openFeatureTreePane()
|
||||||
const sketchButton = await toolbar.getFeatureTreeOperation('Sketch', 1)
|
const sketchButton = await toolbar.getFeatureTreeOperation('Sketch', 1)
|
||||||
await sketchButton.dblclick()
|
await sketchButton.dblclick()
|
||||||
await page.waitForTimeout(700) // Wait for engine animation
|
await page.waitForTimeout(700) // Wait for engine animation
|
||||||
|
await expectSketchOriginToBeDrawn()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Add new variable and wait for re-execution', async () => {
|
await test.step('Add new variable and wait for re-execution', async () => {
|
||||||
await page.waitForTimeout(500) // wait for deferred execution
|
await page.waitForTimeout(500) // wait for deferred execution
|
||||||
await editor.replaceCode('myVar2 = 6', 'myVar2 = 6\nmyVar3 = 7')
|
await editor.replaceCode('myVar2 = 6', 'myVar2 = 6\nmyVar3 = 7')
|
||||||
await page.waitForTimeout(2000) // wait for deferred execution
|
await page.waitForTimeout(2000) // wait for deferred execution
|
||||||
|
await expectSketchOriginToBeDrawn()
|
||||||
})
|
})
|
||||||
|
|
||||||
const handle1Location = { x: 843, y: 235 }
|
const handle1Location = { x: 843, y: 235 }
|
||||||
|
|
||||||
await test.step('Edit sketch by dragging handle', async () => {
|
await test.step('Edit sketch by dragging handle', async () => {
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(async () => {
|
||||||
async () => {
|
await editor.expectEditor.toContain('length = 156.54, angle = -28')
|
||||||
await editor.expectEditor.toContain('length = 156.54, angle = -28')
|
await page.mouse.move(handle1Location.x, handle1Location.y)
|
||||||
await page.mouse.move(handle1Location.x, handle1Location.y)
|
await page.mouse.down()
|
||||||
await page.mouse.down()
|
await page.mouse.move(
|
||||||
await page.mouse.move(
|
handle1Location.x + 50,
|
||||||
handle1Location.x + 50,
|
handle1Location.y + 50,
|
||||||
handle1Location.y + 50,
|
{
|
||||||
{
|
steps: 5,
|
||||||
steps: 5,
|
}
|
||||||
}
|
)
|
||||||
)
|
await page.mouse.up()
|
||||||
await page.mouse.up()
|
await editor.expectEditor.toContain('length = 231.59, angle = -34')
|
||||||
await editor.expectEditor.toContain('length = 231.59, angle = -34')
|
return true
|
||||||
return true
|
})
|
||||||
},
|
|
||||||
{ timeout: 10_000 }
|
|
||||||
)
|
|
||||||
.toBeTruthy()
|
.toBeTruthy()
|
||||||
|
// await page.waitForTimeout(1000) // Wait for update
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Delete variables and wait for re-execution', async () => {
|
await test.step('Delete variables and wait for re-execution', async () => {
|
||||||
@ -3132,6 +3136,7 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
await page.waitForTimeout(50)
|
await page.waitForTimeout(50)
|
||||||
await editor.replaceCode('myVar2 = 6', '')
|
await editor.replaceCode('myVar2 = 6', '')
|
||||||
await page.waitForTimeout(2000) // Wait for deferred execution
|
await page.waitForTimeout(2000) // Wait for deferred execution
|
||||||
|
await expectSketchOriginToBeDrawn()
|
||||||
})
|
})
|
||||||
|
|
||||||
const handle2Location = { x: 872, y: 273 }
|
const handle2Location = { x: 872, y: 273 }
|
||||||
@ -3139,19 +3144,16 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
await editor.expectEditor.toContain('length = 231.59, angle = -34')
|
await editor.expectEditor.toContain('length = 231.59, angle = -34')
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(async () => {
|
||||||
async () => {
|
await page.mouse.move(handle2Location.x, handle2Location.y)
|
||||||
await page.mouse.move(handle2Location.x, handle2Location.y)
|
await page.mouse.down()
|
||||||
await page.mouse.down()
|
await page.mouse.move(handle2Location.x, handle2Location.y - 50, {
|
||||||
await page.mouse.move(handle2Location.x, handle2Location.y - 50, {
|
steps: 5,
|
||||||
steps: 5,
|
})
|
||||||
})
|
await page.mouse.up()
|
||||||
await page.mouse.up()
|
await editor.expectEditor.toContain('length = 167.36, angle = -14')
|
||||||
await editor.expectEditor.toContain('length = 167.36, angle = -14')
|
return true
|
||||||
return true
|
})
|
||||||
},
|
|
||||||
{ timeout: 10_000 }
|
|
||||||
)
|
|
||||||
.toBeTruthy()
|
.toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3164,26 +3166,24 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
profile004 = circle(sketch003, center = [143.91, 136.89], radius = 71.63)`
|
profile004 = circle(sketch003, center = [143.91, 136.89], radius = 71.63)`
|
||||||
)
|
)
|
||||||
await page.waitForTimeout(2000) // Wait for deferred execution
|
await page.waitForTimeout(2000) // Wait for deferred execution
|
||||||
|
await expectSketchOriginToBeDrawn()
|
||||||
})
|
})
|
||||||
|
|
||||||
const handle3Location = { x: 844, y: 212 }
|
const handle3Location = { x: 844, y: 212 }
|
||||||
await test.step('edit sketch again', async () => {
|
await test.step('edit sketch again', async () => {
|
||||||
await page.waitForTimeout(500) // Wait for deferred execution
|
await page.waitForTimeout(500) // Wait for deferred execution
|
||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(async () => {
|
||||||
async () => {
|
await editor.expectEditor.toContain('length = 167.36, angle = -14')
|
||||||
await editor.expectEditor.toContain('length = 167.36, angle = -14')
|
await page.mouse.move(handle3Location.x, handle3Location.y)
|
||||||
await page.mouse.move(handle3Location.x, handle3Location.y)
|
await page.mouse.down()
|
||||||
await page.mouse.down()
|
await page.mouse.move(handle3Location.x, handle3Location.y + 110, {
|
||||||
await page.mouse.move(handle3Location.x, handle3Location.y + 110, {
|
steps: 5,
|
||||||
steps: 5,
|
})
|
||||||
})
|
await page.mouse.up()
|
||||||
await page.mouse.up()
|
await editor.expectEditor.toContain('length = 219.2, angle = -56')
|
||||||
await editor.expectEditor.toContain('length = 219.2, angle = -56')
|
return true
|
||||||
return true
|
})
|
||||||
},
|
|
||||||
{ timeout: 10_000 }
|
|
||||||
)
|
|
||||||
.toBeTruthy()
|
.toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3361,21 +3361,7 @@ profile003 = startProfileAt([-201.08, 254.17], sketch002)
|
|||||||
// this checks sketch segments have been drawn
|
// this checks sketch segments have been drawn
|
||||||
await verifyArrowHeadColor(arrowHeadWhite)
|
await verifyArrowHeadColor(arrowHeadWhite)
|
||||||
})
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
await test.step('make a change to the code and expect pixel color to change', async () => {
|
|
||||||
// defends against a regression where sketch would duplicate in the scene
|
|
||||||
// https://github.com/KittyCAD/modeling-app/issues/6345
|
|
||||||
await editor.replaceCode(
|
|
||||||
'startProfileAt([75.8, 317.2',
|
|
||||||
'startProfileAt([75.8, 217.2'
|
|
||||||
)
|
|
||||||
// expect not white anymore
|
|
||||||
await scene.expectPixelColorNotToBe(
|
|
||||||
TEST_COLORS.WHITE,
|
|
||||||
arrowHeadLocation,
|
|
||||||
15
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -377,7 +377,8 @@ test.describe(
|
|||||||
'extrude on default planes should be stable',
|
'extrude on default planes should be stable',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
() => {
|
() => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
// FIXME: Skip on macos its being weird.
|
||||||
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
test('XY', async ({ page, context, cmdBar, scene }) => {
|
test('XY', async ({ page, context, cmdBar, scene }) => {
|
||||||
await extrudeDefaultPlane(context, page, cmdBar, scene, 'XY')
|
await extrudeDefaultPlane(context, page, cmdBar, scene, 'XY')
|
||||||
@ -409,7 +410,6 @@ test(
|
|||||||
'Draft segments should look right',
|
'Draft segments should look right',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, scene, toolbar }) => {
|
async ({ page, scene, toolbar }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -534,7 +534,8 @@ test(
|
|||||||
'Draft rectangles should look right',
|
'Draft rectangles should look right',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, context, cmdBar, scene }) => {
|
async ({ page, context, cmdBar, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
// FIXME: Skip on macos its being weird.
|
||||||
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
@ -628,7 +629,8 @@ test.describe(
|
|||||||
'Client side scene scale should match engine scale',
|
'Client side scene scale should match engine scale',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
() => {
|
() => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
// FIXME: Skip on macos its being weird.
|
||||||
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
test('Inch scale', async ({ page, cmdBar, scene }) => {
|
test('Inch scale', async ({ page, cmdBar, scene }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
@ -805,7 +807,8 @@ test(
|
|||||||
'Sketch on face with none z-up',
|
'Sketch on face with none z-up',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, context, cmdBar, scene }) => {
|
async ({ page, context, cmdBar, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
// FIXME: Skip on macos its being weird.
|
||||||
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
||||||
@ -865,7 +868,8 @@ test(
|
|||||||
'Zoom to fit on load - solid 2d',
|
'Zoom to fit on load - solid 2d',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, context, cmdBar, scene }) => {
|
async ({ page, context, cmdBar, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
// FIXME: Skip on macos its being weird.
|
||||||
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
@ -903,7 +907,8 @@ test(
|
|||||||
'Zoom to fit on load - solid 3d',
|
'Zoom to fit on load - solid 3d',
|
||||||
{ tag: '@snapshot' },
|
{ tag: '@snapshot' },
|
||||||
async ({ page, context, cmdBar, scene }) => {
|
async ({ page, context, cmdBar, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
// FIXME: Skip on macos its being weird.
|
||||||
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
@ -944,7 +949,6 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
|||||||
cmdBar,
|
cmdBar,
|
||||||
scene,
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
const stream = page.getByTestId('stream')
|
const stream = page.getByTestId('stream')
|
||||||
|
|
||||||
@ -1004,7 +1008,6 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('Grid turned off', async ({ page, cmdBar, scene }) => {
|
test('Grid turned off', async ({ page, cmdBar, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
const stream = page.getByTestId('stream')
|
const stream = page.getByTestId('stream')
|
||||||
|
|
||||||
@ -1026,7 +1029,6 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('Grid turned on', async ({ page, context, cmdBar, scene }) => {
|
test('Grid turned on', async ({ page, context, cmdBar, scene }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
await context.addInitScript(
|
await context.addInitScript(
|
||||||
async ({ settingsKey, settings }) => {
|
async ({ settingsKey, settings }) => {
|
||||||
localStorage.setItem(settingsKey, settings)
|
localStorage.setItem(settingsKey, settings)
|
||||||
@ -1136,7 +1138,6 @@ test('theme persists', async ({ page, context }) => {
|
|||||||
|
|
||||||
test.describe('code color goober', { tag: '@snapshot' }, () => {
|
test.describe('code color goober', { tag: '@snapshot' }, () => {
|
||||||
test('code color goober', async ({ page, context, scene, cmdBar }) => {
|
test('code color goober', async ({ page, context, scene, cmdBar }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
|
@ -44,9 +44,7 @@
|
|||||||
packages =
|
packages =
|
||||||
(with pkgs; [
|
(with pkgs; [
|
||||||
rustToolchain
|
rustToolchain
|
||||||
cargo-criterion
|
|
||||||
cargo-nextest
|
cargo-nextest
|
||||||
cargo-sort
|
|
||||||
just
|
just
|
||||||
postgresql.lib
|
postgresql.lib
|
||||||
openssl
|
openssl
|
||||||
|
@ -25,14 +25,10 @@ When you submit a PR to add or modify KCL samples, images and STEP files will be
|
|||||||
---
|
---
|
||||||
#### [80-20-rail](80-20-rail/main.kcl) ([screenshot](screenshots/80-20-rail.png))
|
#### [80-20-rail](80-20-rail/main.kcl) ([screenshot](screenshots/80-20-rail.png))
|
||||||
[](80-20-rail/main.kcl)
|
[](80-20-rail/main.kcl)
|
||||||
#### [axial-fan](axial-fan/main.kcl) ([screenshot](screenshots/axial-fan.png))
|
|
||||||
[](axial-fan/main.kcl)
|
|
||||||
#### [ball-bearing](ball-bearing/main.kcl) ([screenshot](screenshots/ball-bearing.png))
|
#### [ball-bearing](ball-bearing/main.kcl) ([screenshot](screenshots/ball-bearing.png))
|
||||||
[](ball-bearing/main.kcl)
|
[](ball-bearing/main.kcl)
|
||||||
#### [bench](bench/main.kcl) ([screenshot](screenshots/bench.png))
|
#### [bench](bench/main.kcl) ([screenshot](screenshots/bench.png))
|
||||||
[](bench/main.kcl)
|
[](bench/main.kcl)
|
||||||
#### [bottle](bottle/main.kcl) ([screenshot](screenshots/bottle.png))
|
|
||||||
[](bottle/main.kcl)
|
|
||||||
#### [bracket](bracket/main.kcl) ([screenshot](screenshots/bracket.png))
|
#### [bracket](bracket/main.kcl) ([screenshot](screenshots/bracket.png))
|
||||||
[](bracket/main.kcl)
|
[](bracket/main.kcl)
|
||||||
#### [car-wheel-assembly](car-wheel-assembly/main.kcl) ([screenshot](screenshots/car-wheel-assembly.png))
|
#### [car-wheel-assembly](car-wheel-assembly/main.kcl) ([screenshot](screenshots/car-wheel-assembly.png))
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
// Fan Housing
|
|
||||||
// The plastic housing that contains the fan and the motor
|
|
||||||
|
|
||||||
// Set units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
// Import parameters
|
|
||||||
import * from "parameters.kcl"
|
|
||||||
|
|
||||||
// Model the housing which holds the motor, the fan, and the mounting provisions
|
|
||||||
// Bottom mounting face
|
|
||||||
bottomFaceSketch = startSketchOn(XY)
|
|
||||||
|> startProfileAt([-fanSize / 2, -fanSize / 2], %)
|
|
||||||
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = fanSize, tag = $rectangleSegmentB001)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
|
||||||
|> close()
|
|
||||||
|> hole(circle(center = [0, 0], radius = 4), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
mountingHoleSpacing / 2,
|
|
||||||
mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
-mountingHoleSpacing / 2,
|
|
||||||
mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
mountingHoleSpacing / 2,
|
|
||||||
-mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
-mountingHoleSpacing / 2,
|
|
||||||
-mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> extrude(length = 4)
|
|
||||||
|
|
||||||
// Add large openings to the bottom face to allow airflow through the fan
|
|
||||||
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|
|
||||||
|> startProfileAt([fanSize * 7 / 25, -fanSize * 9 / 25], %)
|
|
||||||
|> angledLine(angle = 140, length = fanSize * 12 / 25, tag = $seg01)
|
|
||||||
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|
|
||||||
|> angledLine(angle = -130, length = fanSize * 8 / 25)
|
|
||||||
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|
|
||||||
|> angledLine(angle = segAng(seg01) + 180, length = fanSize * 2 / 25)
|
|
||||||
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40)
|
|
||||||
|> xLine(length = fanSize * 3 / 25)
|
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
|> patternCircular2d(
|
|
||||||
instances = 4,
|
|
||||||
center = [0, 0],
|
|
||||||
arcDegrees = 360,
|
|
||||||
rotateDuplicates = true,
|
|
||||||
)
|
|
||||||
|> extrude(length = -4)
|
|
||||||
|
|
||||||
// Create the middle segment of the fan housing body
|
|
||||||
housingMiddleLength = fanSize / 3
|
|
||||||
housingMiddleRadius = fanSize / 3 - 1
|
|
||||||
bodyMiddle = startSketchOn(bottomFaceSketch, face = END)
|
|
||||||
|> startProfileAt([
|
|
||||||
housingMiddleLength / 2,
|
|
||||||
-housingMiddleLength / 2 - housingMiddleRadius
|
|
||||||
], %)
|
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|
||||||
|> yLine(length = housingMiddleLength)
|
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|
||||||
|> xLine(length = -housingMiddleLength)
|
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|
||||||
|> yLine(length = -housingMiddleLength)
|
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> extrude(length = fanHeight - 4 - 4)
|
|
||||||
|
|
||||||
// Cut a hole in the body to accommodate the fan
|
|
||||||
bodyFanHole = startSketchOn(bodyMiddle, face = END)
|
|
||||||
|> circle(center = [0, 0], radius = fanSize * 23 / 50)
|
|
||||||
|> extrude(length = -(fanHeight - 4 - 4))
|
|
||||||
|
|
||||||
// Top mounting face. Cut a hole in the face to accommodate the fan
|
|
||||||
topFaceSketch = startSketchOn(bodyMiddle, face = END)
|
|
||||||
topHoles = startProfileAt([-fanSize / 2, -fanSize / 2], topFaceSketch)
|
|
||||||
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA002)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = fanSize, tag = $rectangleSegmentB002)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|
|
||||||
|> close()
|
|
||||||
|> hole(circle(center = [0, 0], radius = fanSize * 23 / 50), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
mountingHoleSpacing / 2,
|
|
||||||
mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
-mountingHoleSpacing / 2,
|
|
||||||
mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
mountingHoleSpacing / 2,
|
|
||||||
-mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> hole(circle(
|
|
||||||
center = [
|
|
||||||
-mountingHoleSpacing / 2,
|
|
||||||
-mountingHoleSpacing / 2
|
|
||||||
],
|
|
||||||
radius = mountingHoleSize / 2,
|
|
||||||
), %)
|
|
||||||
|> extrude(length = 4)
|
|
||||||
|
|
||||||
// Create a housing for the electric motor to sit
|
|
||||||
motorHousing = startSketchOn(bottomFaceSketch, face = END)
|
|
||||||
|> circle(center = [0, 0], radius = 11.2)
|
|
||||||
|> extrude(length = 16)
|
|
||||||
|
|
||||||
startSketchOn(motorHousing, face = END)
|
|
||||||
|> circle(center = [0, 0], radius = 10)
|
|
||||||
|> extrude(length = -16)
|
|
||||||
|> appearance(color = "#a55e2c")
|
|
||||||
|> fillet(
|
|
||||||
radius = abs(fanSize - mountingHoleSpacing) / 2,
|
|
||||||
tags = [
|
|
||||||
getNextAdjacentEdge(rectangleSegmentA001),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentB001),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentC001),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentD001),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentA002),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentB002),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentC002),
|
|
||||||
getNextAdjacentEdge(rectangleSegmentD002)
|
|
||||||
],
|
|
||||||
)
|
|
@ -1,92 +0,0 @@
|
|||||||
// Fan
|
|
||||||
// Spinning axial fan that moves airflow
|
|
||||||
|
|
||||||
// Set units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
// Import parameters
|
|
||||||
import * from "parameters.kcl"
|
|
||||||
|
|
||||||
// Model the center of the fan
|
|
||||||
fanCenter = startSketchOn(XZ)
|
|
||||||
|> startProfileAt([-0.0001, fanHeight], %)
|
|
||||||
|> xLine(endAbsolute = -15 + 1.5)
|
|
||||||
|> tangentialArc(radius = 1.5, angle = 90)
|
|
||||||
|> yLine(endAbsolute = 4.5)
|
|
||||||
|> xLine(endAbsolute = -13)
|
|
||||||
|> yLine(endAbsolute = profileStartY(%) - 5)
|
|
||||||
|> tangentialArc(radius = 1, angle = -90)
|
|
||||||
|> xLine(endAbsolute = -1)
|
|
||||||
|> yLine(length = 2)
|
|
||||||
|> xLine(length = -0.15)
|
|
||||||
|> line(endAbsolute = [
|
|
||||||
profileStartX(%) - 1,
|
|
||||||
profileStartY(%) - 1.4
|
|
||||||
])
|
|
||||||
|> xLine(endAbsolute = profileStartX(%))
|
|
||||||
|> yLine(endAbsolute = profileStartY(%))
|
|
||||||
|> close()
|
|
||||||
|> revolve(axis = {
|
|
||||||
direction = [0.0, 1.0],
|
|
||||||
origin = [0.0, 0.0]
|
|
||||||
})
|
|
||||||
|> appearance(color = "#f3e2d8")
|
|
||||||
|
|
||||||
// Create a function for a lofted fan blade cross section that rotates about the center hub of the fan
|
|
||||||
fn fanBlade(offsetHeight, startAngle) {
|
|
||||||
fanBlade = startSketchOn(offsetPlane(XY, offset = offsetHeight))
|
|
||||||
|> startProfileAt([
|
|
||||||
15 * cos(toRadians(startAngle)),
|
|
||||||
15 * sin(toRadians(startAngle))
|
|
||||||
], %)
|
|
||||||
|> arc({
|
|
||||||
angleStart = startAngle,
|
|
||||||
angleEnd = startAngle + 14,
|
|
||||||
radius = 15
|
|
||||||
}, %)
|
|
||||||
|> arcTo({
|
|
||||||
end = [
|
|
||||||
fanSize * 22 / 50 * cos(toRadians(startAngle - 20)),
|
|
||||||
fanSize * 22 / 50 * sin(toRadians(startAngle - 20))
|
|
||||||
],
|
|
||||||
interior = [
|
|
||||||
fanSize * 11 / 50 * cos(toRadians(startAngle + 3)),
|
|
||||||
fanSize * 11 / 50 * sin(toRadians(startAngle + 3))
|
|
||||||
]
|
|
||||||
}, %)
|
|
||||||
|> arcTo({
|
|
||||||
end = [
|
|
||||||
fanSize * 22 / 50 * cos(toRadians(startAngle - 24)),
|
|
||||||
fanSize * 22 / 50 * sin(toRadians(startAngle - 24))
|
|
||||||
],
|
|
||||||
interior = [
|
|
||||||
fanSize * 22 / 50 * cos(toRadians(startAngle - 22)),
|
|
||||||
fanSize * 22 / 50 * sin(toRadians(startAngle - 22))
|
|
||||||
]
|
|
||||||
}, %)
|
|
||||||
|> arcTo({
|
|
||||||
end = [profileStartX(%), profileStartY(%)],
|
|
||||||
interior = [
|
|
||||||
fanSize * 11 / 50 * cos(toRadians(startAngle - 5)),
|
|
||||||
fanSize * 11 / 50 * sin(toRadians(startAngle - 5))
|
|
||||||
]
|
|
||||||
}, %)
|
|
||||||
|> close()
|
|
||||||
return fanBlade
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loft the fan blade cross sections into a single blade, then pattern them about the fan center
|
|
||||||
loft([
|
|
||||||
fanBlade(4.5, 50),
|
|
||||||
fanBlade((fanHeight - 2 - 4) / 2, 30),
|
|
||||||
fanBlade(fanHeight - 2, 0)
|
|
||||||
])
|
|
||||||
|> appearance(color = "#f3e2d8")
|
|
||||||
|> patternCircular3d(
|
|
||||||
%,
|
|
||||||
instances = 9,
|
|
||||||
axis = [0, 0, 1],
|
|
||||||
center = [0, 0, 0],
|
|
||||||
arcDegrees = 360,
|
|
||||||
rotateDuplicates = true,
|
|
||||||
)
|
|
@ -1,15 +0,0 @@
|
|||||||
// PC Fan
|
|
||||||
// A small axial fan, used to push or draw airflow over components to remove excess heat
|
|
||||||
|
|
||||||
// Set units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
// Import all parts into assembly file
|
|
||||||
import "fan-housing.kcl" as fanHousing
|
|
||||||
import "motor.kcl" as motor
|
|
||||||
import "fan.kcl" as fan
|
|
||||||
|
|
||||||
// Produce the model for each imported part
|
|
||||||
fanHousing
|
|
||||||
motor
|
|
||||||
fan
|
|
@ -1,22 +0,0 @@
|
|||||||
// Motor
|
|
||||||
// A small electric motor to power the fan
|
|
||||||
|
|
||||||
// Set Units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
// Import Parameters
|
|
||||||
import * from "parameters.kcl"
|
|
||||||
|
|
||||||
// Model the motor body and stem
|
|
||||||
|
|
||||||
|
|
||||||
topFacePlane = offsetPlane(XY, offset = 4)
|
|
||||||
motorBody = startSketchOn(topFacePlane)
|
|
||||||
|> circle(center = [0, 0], radius = 10, tag = $seg04)
|
|
||||||
|> extrude(length = 17)
|
|
||||||
|> appearance(color = "#021b55")
|
|
||||||
|> fillet(radius = 2, tags = [getOppositeEdge(seg04), seg04])
|
|
||||||
startSketchOn(offsetPlane(XY, offset = 21))
|
|
||||||
|> circle(center = [0, 0], radius = 1)
|
|
||||||
|> extrude(length = 3.8)
|
|
||||||
|> appearance(color = "#dbc89e")
|
|
@ -1,10 +0,0 @@
|
|||||||
// Global parameters for the axial fan
|
|
||||||
|
|
||||||
// Set units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
// Define Parameters
|
|
||||||
export fanSize = 120
|
|
||||||
export fanHeight = 25
|
|
||||||
export mountingHoleSpacing = 105
|
|
||||||
export mountingHoleSize = 4.5
|
|
@ -1,35 +0,0 @@
|
|||||||
// Bottle
|
|
||||||
// A simple bottle with a hollow, watertight interior
|
|
||||||
|
|
||||||
// Set Units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
// Input dimensions to define the bottle
|
|
||||||
bottleWidth = 80
|
|
||||||
bottleLength = 125
|
|
||||||
bottleHeight = 220
|
|
||||||
neckDepth = 18
|
|
||||||
neckDiameter = 45
|
|
||||||
wallThickness = 4
|
|
||||||
|
|
||||||
// Create a rounded body for the bottle
|
|
||||||
bottleBody = startSketchOn(XY)
|
|
||||||
|> startProfileAt([-bottleLength / 2, 0], %)
|
|
||||||
|> yLine(length = bottleWidth / 3)
|
|
||||||
|> arcTo({
|
|
||||||
end = [bottleLength / 2, bottleWidth / 3],
|
|
||||||
interior = [0, bottleWidth / 2]
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|
||||||
|> mirror2d(axis = X)
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = bottleHeight - neckDepth)
|
|
||||||
|
|
||||||
// Create a neck centered at the top of the bottle
|
|
||||||
bottleNeck = startSketchOn(bottleBody, face = END)
|
|
||||||
|> circle(center = [0, 0], radius = neckDiameter / 2)
|
|
||||||
|> extrude(length = neckDepth)
|
|
||||||
|
|
||||||
// Define a shell operation so that the entire body and neck are hollow, with only the top face opened
|
|
||||||
bottleShell = shell(bottleNeck, faces = [END], thickness = wallThickness)
|
|
||||||
|> appearance(%, color = "#0078c2")
|
|
@ -6,13 +6,6 @@
|
|||||||
"title": "80/20 Rail",
|
"title": "80/20 Rail",
|
||||||
"description": "An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position"
|
"description": "An 80/20 extruded aluminum linear rail. T-slot profile adjustable by profile height, rail length, and origin position"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"file": "main.kcl",
|
|
||||||
"pathFromProjectDirectoryToFirstFile": "axial-fan/main.kcl",
|
|
||||||
"multipleFiles": true,
|
|
||||||
"title": "PC Fan",
|
|
||||||
"description": "A small axial fan, used to push or draw airflow over components to remove excess heat"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"file": "main.kcl",
|
"file": "main.kcl",
|
||||||
"pathFromProjectDirectoryToFirstFile": "ball-bearing/main.kcl",
|
"pathFromProjectDirectoryToFirstFile": "ball-bearing/main.kcl",
|
||||||
@ -27,13 +20,6 @@
|
|||||||
"title": "Bench",
|
"title": "Bench",
|
||||||
"description": "This is a slight remix of Depep1's original 3D Boaty (https://www.printables.com/model/1141963-3d-boaty). This is a tool used for benchmarking 3D FDM printers for bed adhesion, overhangs, bridging and top surface quality. The name of this file is a bit of misnomer, the shape of the object is a typical park bench."
|
"description": "This is a slight remix of Depep1's original 3D Boaty (https://www.printables.com/model/1141963-3d-boaty). This is a tool used for benchmarking 3D FDM printers for bed adhesion, overhangs, bridging and top surface quality. The name of this file is a bit of misnomer, the shape of the object is a typical park bench."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"file": "main.kcl",
|
|
||||||
"pathFromProjectDirectoryToFirstFile": "bottle/main.kcl",
|
|
||||||
"multipleFiles": false,
|
|
||||||
"title": "Bottle",
|
|
||||||
"description": "A simple bottle with a hollow, watertight interior"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"file": "main.kcl",
|
"file": "main.kcl",
|
||||||
"pathFromProjectDirectoryToFirstFile": "bracket/main.kcl",
|
"pathFromProjectDirectoryToFirstFile": "bracket/main.kcl",
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 105 KiB |
Binary file not shown.
Before Width: | Height: | Size: 70 KiB |
93
rust/Cargo.lock
generated
93
rust/Cargo.lock
generated
@ -535,7 +535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -665,9 +665,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.15"
|
version = "0.5.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
@ -758,7 +758,7 @@ dependencies = [
|
|||||||
"hashbrown 0.14.5",
|
"hashbrown 0.14.5",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot_core 0.9.10",
|
"parking_lot_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -772,7 +772,7 @@ dependencies = [
|
|||||||
"hashbrown 0.14.5",
|
"hashbrown 0.14.5",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot_core 0.9.10",
|
"parking_lot_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -847,7 +847,7 @@ dependencies = [
|
|||||||
"backtrace",
|
"backtrace",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"mintex",
|
"mintex",
|
||||||
"parking_lot 0.12.3",
|
"parking_lot",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -954,7 +954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1697,18 +1697,6 @@ dependencies = [
|
|||||||
"similar",
|
"similar",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "instant"
|
|
||||||
version = "0.1.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
version = "2.11.0"
|
version = "2.11.0"
|
||||||
@ -1723,7 +1711,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1897,7 +1885,6 @@ dependencies = [
|
|||||||
"image",
|
"image",
|
||||||
"indexmap 2.8.0",
|
"indexmap 2.8.0",
|
||||||
"insta",
|
"insta",
|
||||||
"instant",
|
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"kcl-derive-docs",
|
"kcl-derive-docs",
|
||||||
@ -1934,7 +1921,6 @@ dependencies = [
|
|||||||
"validator",
|
"validator",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"wasm-timer",
|
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"web-time",
|
"web-time",
|
||||||
"winnow 0.6.24",
|
"winnow 0.6.24",
|
||||||
@ -2474,17 +2460,6 @@ dependencies = [
|
|||||||
"unicode-width 0.2.0",
|
"unicode-width 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
|
||||||
dependencies = [
|
|
||||||
"instant",
|
|
||||||
"lock_api",
|
|
||||||
"parking_lot_core 0.8.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -2492,21 +2467,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core 0.9.10",
|
"parking_lot_core",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot_core"
|
|
||||||
version = "0.8.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"instant",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall 0.2.16",
|
|
||||||
"smallvec",
|
|
||||||
"winapi",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2517,7 +2478,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall 0.5.10",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
@ -2922,7 +2883,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3057,15 +3018,6 @@ dependencies = [
|
|||||||
"rand_core 0.3.1",
|
"rand_core 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.2.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.10"
|
version = "0.5.10"
|
||||||
@ -3259,7 +3211,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3857,7 +3809,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4032,7 +3984,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"parking_lot 0.12.3",
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
@ -4629,21 +4581,6 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-timer"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
|
|
||||||
dependencies = [
|
|
||||||
"futures",
|
|
||||||
"js-sys",
|
|
||||||
"parking_lot 0.11.2",
|
|
||||||
"pin-utils",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.77"
|
version = "0.3.77"
|
||||||
@ -4695,7 +4632,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -33,16 +33,10 @@ new-sim-test test_name render_to_png="true":
|
|||||||
|
|
||||||
# Run a KCL deterministic simulation test case and accept output.
|
# Run a KCL deterministic simulation test case and accept output.
|
||||||
overwrite-sim-test-sample test_name:
|
overwrite-sim-test-sample test_name:
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::kcl_samples::parse_{{test_name}}
|
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::kcl_samples::unparse_{{test_name}}
|
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::kcl_samples::kcl_test_execute_{{test_name}}
|
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::kcl_samples::kcl_test_execute_{{test_name}}
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::kcl_samples::test_after_engine_generate_manifest
|
|
||||||
|
|
||||||
overwrite-sim-test test_name:
|
overwrite-sim-test test_name:
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::{{test_name}}::parse
|
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::{{test_name}}::unparse
|
|
||||||
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::{{test_name}}::kcl_test_execute
|
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::{{test_name}}::kcl_test_execute
|
||||||
[ {{test_name}} != "kcl_samples" ] || EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::{{test_name}}::test_after_engine_generate_manifest
|
|
||||||
|
|
||||||
# Regenerate all the simulation test output.
|
# Regenerate all the simulation test output.
|
||||||
redo-sim-tests:
|
redo-sim-tests:
|
||||||
|
@ -89,17 +89,14 @@ winnow = "=0.6.24"
|
|||||||
zip = { workspace = true }
|
zip = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
instant = { version = "0.1.13", features = ["wasm-bindgen", "inaccurate"] }
|
|
||||||
js-sys = { version = "0.3.72" }
|
js-sys = { version = "0.3.72" }
|
||||||
tokio = { workspace = true, features = ["sync", "time"] }
|
tokio = { workspace = true, features = ["sync", "time"] }
|
||||||
tower-lsp = { workspace = true, features = ["runtime-agnostic"] }
|
tower-lsp = { workspace = true, features = ["runtime-agnostic"] }
|
||||||
wasm-bindgen = "0.2.99"
|
wasm-bindgen = "0.2.99"
|
||||||
wasm-bindgen-futures = "0.4.49"
|
wasm-bindgen-futures = "0.4.49"
|
||||||
wasm-timer = "0.2.5"
|
|
||||||
web-sys = { version = "0.3.76", features = ["console"] }
|
web-sys = { version = "0.3.76", features = ["console"] }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
instant = "0.1.13"
|
|
||||||
tokio = { workspace = true, features = ["full"] }
|
tokio = { workspace = true, features = ["full"] }
|
||||||
tokio-tungstenite = { version = "0.24.0", features = [
|
tokio-tungstenite = { version = "0.24.0", features = [
|
||||||
"rustls-tls-native-roots",
|
"rustls-tls-native-roots",
|
||||||
@ -108,7 +105,6 @@ tower-lsp = { workspace = true, features = ["proposed", "default"] }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["cli", "engine"]
|
default = ["cli", "engine"]
|
||||||
benchmark-execution = []
|
|
||||||
cli = ["dep:clap", "kittycad/clap"]
|
cli = ["dep:clap", "kittycad/clap"]
|
||||||
dhat-heap = ["dep:dhat"]
|
dhat-heap = ["dep:dhat"]
|
||||||
# For the lsp server, when run with stdout for rpc we want to disable println.
|
# For the lsp server, when run with stdout for rpc we want to disable println.
|
||||||
|
@ -45,7 +45,6 @@ fn run_benchmarks(c: &mut Criterion) {
|
|||||||
|
|
||||||
let benchmark_dirs = discover_benchmark_dirs(&base_dir);
|
let benchmark_dirs = discover_benchmark_dirs(&base_dir);
|
||||||
|
|
||||||
#[cfg(feature = "benchmark-execution")]
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
|
||||||
for dir in benchmark_dirs {
|
for dir in benchmark_dirs {
|
||||||
@ -68,14 +67,12 @@ fn run_benchmarks(c: &mut Criterion) {
|
|||||||
.sample_size(10)
|
.sample_size(10)
|
||||||
.measurement_time(std::time::Duration::from_secs(1)); // Short measurement time to keep it from running in parallel
|
.measurement_time(std::time::Duration::from_secs(1)); // Short measurement time to keep it from running in parallel
|
||||||
|
|
||||||
#[cfg(feature = "benchmark-execution")]
|
|
||||||
let program = kcl_lib::Program::parse_no_errs(&input_content).unwrap();
|
let program = kcl_lib::Program::parse_no_errs(&input_content).unwrap();
|
||||||
|
|
||||||
group.bench_function(format!("parse_{}", dir_name), |b| {
|
group.bench_function(format!("parse_{}", dir_name), |b| {
|
||||||
b.iter(|| kcl_lib::Program::parse_no_errs(black_box(&input_content)).unwrap())
|
b.iter(|| kcl_lib::Program::parse_no_errs(black_box(&input_content)).unwrap())
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(feature = "benchmark-execution")]
|
|
||||||
group.bench_function(format!("execute_{}", dir_name), |b| {
|
group.bench_function(format!("execute_{}", dir_name), |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
if let Err(err) = rt.block_on(async {
|
if let Err(err) = rt.block_on(async {
|
||||||
|
@ -2109,7 +2109,7 @@ async fn kcl_test_better_type_names() {
|
|||||||
},
|
},
|
||||||
None => todo!(),
|
None => todo!(),
|
||||||
};
|
};
|
||||||
assert_eq!(err, "This function expected the input argument to be one or more Solids or imported geometry but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`");
|
assert_eq!(err, "This function expected the input argument to be one or more Solids but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
@ -133,7 +133,6 @@ impl StdLibFnArg {
|
|||||||
|| self.type_ == "[Solid]"
|
|| self.type_ == "[Solid]"
|
||||||
|| self.type_ == "SketchSurface"
|
|| self.type_ == "SketchSurface"
|
||||||
|| self.type_ == "SketchOrSurface"
|
|| self.type_ == "SketchOrSurface"
|
||||||
|| self.type_ == "SolidOrImportedGeometry"
|
|
||||||
|| self.type_ == "SolidOrSketchOrImportedGeometry")
|
|| self.type_ == "SolidOrSketchOrImportedGeometry")
|
||||||
&& (self.required || self.include_in_snippet)
|
&& (self.required || self.include_in_snippet)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,6 @@ pub struct EngineConnection {
|
|||||||
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
|
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
|
||||||
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
|
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
|
||||||
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
|
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
|
||||||
ids_of_async_commands: Arc<RwLock<IndexMap<Uuid, SourceRange>>>,
|
|
||||||
|
|
||||||
/// The default planes for the scene.
|
/// The default planes for the scene.
|
||||||
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
||||||
@ -116,17 +115,6 @@ impl Drop for TcpReadHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResponsesInformation {
|
|
||||||
/// The responses from the engine.
|
|
||||||
responses: Arc<RwLock<IndexMap<uuid::Uuid, WebSocketResponse>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResponsesInformation {
|
|
||||||
pub async fn add(&self, id: Uuid, response: WebSocketResponse) {
|
|
||||||
self.responses.write().await.insert(id, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Requests to send to the engine, and a way to await a response.
|
/// Requests to send to the engine, and a way to await a response.
|
||||||
struct ToEngineReq {
|
struct ToEngineReq {
|
||||||
/// The request to send
|
/// The request to send
|
||||||
@ -239,13 +227,10 @@ impl EngineConnection {
|
|||||||
let session_data: Arc<RwLock<Option<ModelingSessionData>>> = Arc::new(RwLock::new(None));
|
let session_data: Arc<RwLock<Option<ModelingSessionData>>> = Arc::new(RwLock::new(None));
|
||||||
let session_data2 = session_data.clone();
|
let session_data2 = session_data.clone();
|
||||||
let responses: Arc<RwLock<IndexMap<uuid::Uuid, WebSocketResponse>>> = Arc::new(RwLock::new(IndexMap::new()));
|
let responses: Arc<RwLock<IndexMap<uuid::Uuid, WebSocketResponse>>> = Arc::new(RwLock::new(IndexMap::new()));
|
||||||
let ids_of_async_commands: Arc<RwLock<IndexMap<Uuid, SourceRange>>> = Arc::new(RwLock::new(IndexMap::new()));
|
let responses_clone = responses.clone();
|
||||||
let socket_health = Arc::new(RwLock::new(SocketHealth::Active));
|
let socket_health = Arc::new(RwLock::new(SocketHealth::Active));
|
||||||
let pending_errors = Arc::new(RwLock::new(Vec::new()));
|
let pending_errors = Arc::new(RwLock::new(Vec::new()));
|
||||||
let pending_errors_clone = pending_errors.clone();
|
let pending_errors_clone = pending_errors.clone();
|
||||||
let responses_information = ResponsesInformation {
|
|
||||||
responses: responses.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let socket_health_tcp_read = socket_health.clone();
|
let socket_health_tcp_read = socket_health.clone();
|
||||||
let tcp_read_handle = tokio::spawn(async move {
|
let tcp_read_handle = tokio::spawn(async move {
|
||||||
@ -259,7 +244,8 @@ impl EngineConnection {
|
|||||||
WebSocketResponse::Success(SuccessWebSocketResponse {
|
WebSocketResponse::Success(SuccessWebSocketResponse {
|
||||||
resp: OkWebSocketResponseData::ModelingBatch { responses },
|
resp: OkWebSocketResponseData::ModelingBatch { responses },
|
||||||
..
|
..
|
||||||
}) => {
|
}) =>
|
||||||
|
{
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::iter_over_hash_type,
|
clippy::iter_over_hash_type,
|
||||||
reason = "modeling command uses a HashMap and keys are random, so we don't really have a choice"
|
reason = "modeling command uses a HashMap and keys are random, so we don't really have a choice"
|
||||||
@ -268,32 +254,26 @@ impl EngineConnection {
|
|||||||
let id: uuid::Uuid = (*resp_id).into();
|
let id: uuid::Uuid = (*resp_id).into();
|
||||||
match batch_response {
|
match batch_response {
|
||||||
BatchResponse::Success { response } => {
|
BatchResponse::Success { response } => {
|
||||||
// If the id is in our ids of async commands, remove
|
responses_clone.write().await.insert(
|
||||||
// it.
|
id,
|
||||||
responses_information
|
WebSocketResponse::Success(SuccessWebSocketResponse {
|
||||||
.add(
|
success: true,
|
||||||
id,
|
request_id: Some(id),
|
||||||
WebSocketResponse::Success(SuccessWebSocketResponse {
|
resp: OkWebSocketResponseData::Modeling {
|
||||||
success: true,
|
modeling_response: response.clone(),
|
||||||
request_id: Some(id),
|
},
|
||||||
resp: OkWebSocketResponseData::Modeling {
|
}),
|
||||||
modeling_response: response.clone(),
|
);
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
BatchResponse::Failure { errors } => {
|
BatchResponse::Failure { errors } => {
|
||||||
responses_information
|
responses_clone.write().await.insert(
|
||||||
.add(
|
id,
|
||||||
id,
|
WebSocketResponse::Failure(FailureWebSocketResponse {
|
||||||
WebSocketResponse::Failure(FailureWebSocketResponse {
|
success: false,
|
||||||
success: false,
|
request_id: Some(id),
|
||||||
request_id: Some(id),
|
errors: errors.clone(),
|
||||||
errors: errors.clone(),
|
}),
|
||||||
}),
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,16 +291,14 @@ impl EngineConnection {
|
|||||||
errors,
|
errors,
|
||||||
}) => {
|
}) => {
|
||||||
if let Some(id) = request_id {
|
if let Some(id) = request_id {
|
||||||
responses_information
|
responses_clone.write().await.insert(
|
||||||
.add(
|
*id,
|
||||||
*id,
|
WebSocketResponse::Failure(FailureWebSocketResponse {
|
||||||
WebSocketResponse::Failure(FailureWebSocketResponse {
|
success: false,
|
||||||
success: false,
|
request_id: *request_id,
|
||||||
request_id: *request_id,
|
errors: errors.clone(),
|
||||||
errors: errors.clone(),
|
}),
|
||||||
}),
|
);
|
||||||
)
|
|
||||||
.await;
|
|
||||||
} else {
|
} else {
|
||||||
// Add it to our pending errors.
|
// Add it to our pending errors.
|
||||||
let mut pe = pending_errors_clone.write().await;
|
let mut pe = pending_errors_clone.write().await;
|
||||||
@ -336,7 +314,7 @@ impl EngineConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
responses_information.add(id, ws_resp.clone()).await;
|
responses_clone.write().await.insert(id, ws_resp.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -363,7 +341,6 @@ impl EngineConnection {
|
|||||||
batch: Arc::new(RwLock::new(Vec::new())),
|
batch: Arc::new(RwLock::new(Vec::new())),
|
||||||
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
||||||
artifact_commands: Arc::new(RwLock::new(Vec::new())),
|
artifact_commands: Arc::new(RwLock::new(Vec::new())),
|
||||||
ids_of_async_commands,
|
|
||||||
default_planes: Default::default(),
|
default_planes: Default::default(),
|
||||||
session_data,
|
session_data,
|
||||||
stats: Default::default(),
|
stats: Default::default(),
|
||||||
@ -389,10 +366,6 @@ impl EngineManager for EngineConnection {
|
|||||||
self.artifact_commands.clone()
|
self.artifact_commands.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ids_of_async_commands(&self) -> Arc<RwLock<IndexMap<Uuid, SourceRange>>> {
|
|
||||||
self.ids_of_async_commands.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stats(&self) -> &EngineStats {
|
fn stats(&self) -> &EngineStats {
|
||||||
&self.stats
|
&self.stats
|
||||||
}
|
}
|
||||||
@ -413,13 +386,13 @@ impl EngineManager for EngineConnection {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn inner_fire_modeling_cmd(
|
async fn inner_send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
_id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
source_range: SourceRange,
|
source_range: SourceRange,
|
||||||
cmd: WebSocketRequest,
|
cmd: WebSocketRequest,
|
||||||
_id_to_source_range: HashMap<Uuid, SourceRange>,
|
_id_to_source_range: HashMap<Uuid, SourceRange>,
|
||||||
) -> Result<(), KclError> {
|
) -> Result<WebSocketResponse, KclError> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|
||||||
// Send the request to the engine, via the actor.
|
// Send the request to the engine, via the actor.
|
||||||
@ -451,19 +424,6 @@ impl EngineManager for EngineConnection {
|
|||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn inner_send_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: SourceRange,
|
|
||||||
cmd: WebSocketRequest,
|
|
||||||
id_to_source_range: HashMap<Uuid, SourceRange>,
|
|
||||||
) -> Result<WebSocketResponse, KclError> {
|
|
||||||
self.inner_fire_modeling_cmd(id, source_range, cmd, id_to_source_range)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Wait for the response.
|
// Wait for the response.
|
||||||
let current_time = std::time::Instant::now();
|
let current_time = std::time::Instant::now();
|
||||||
while current_time.elapsed().as_secs() < 60 {
|
while current_time.elapsed().as_secs() < 60 {
|
||||||
|
@ -12,7 +12,7 @@ use kcmc::{
|
|||||||
WebSocketResponse,
|
WebSocketResponse,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use kittycad_modeling_cmds::{self as kcmc, websocket::ModelingCmdReq, ImportFiles, ModelingCmd};
|
use kittycad_modeling_cmds::{self as kcmc};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -29,8 +29,6 @@ pub struct EngineConnection {
|
|||||||
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
|
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
|
||||||
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
|
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
|
||||||
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
|
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
|
||||||
ids_of_async_commands: Arc<RwLock<IndexMap<Uuid, SourceRange>>>,
|
|
||||||
responses: Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>>,
|
|
||||||
/// The default planes for the scene.
|
/// The default planes for the scene.
|
||||||
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
||||||
stats: EngineStats,
|
stats: EngineStats,
|
||||||
@ -42,8 +40,6 @@ impl EngineConnection {
|
|||||||
batch: Arc::new(RwLock::new(Vec::new())),
|
batch: Arc::new(RwLock::new(Vec::new())),
|
||||||
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
||||||
artifact_commands: Arc::new(RwLock::new(Vec::new())),
|
artifact_commands: Arc::new(RwLock::new(Vec::new())),
|
||||||
ids_of_async_commands: Arc::new(RwLock::new(IndexMap::new())),
|
|
||||||
responses: Arc::new(RwLock::new(IndexMap::new())),
|
|
||||||
default_planes: Default::default(),
|
default_planes: Default::default(),
|
||||||
stats: Default::default(),
|
stats: Default::default(),
|
||||||
})
|
})
|
||||||
@ -61,7 +57,7 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn responses(&self) -> Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>> {
|
fn responses(&self) -> Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>> {
|
||||||
self.responses.clone()
|
Arc::new(RwLock::new(IndexMap::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stats(&self) -> &EngineStats {
|
fn stats(&self) -> &EngineStats {
|
||||||
@ -72,10 +68,6 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
self.artifact_commands.clone()
|
self.artifact_commands.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ids_of_async_commands(&self) -> Arc<RwLock<IndexMap<Uuid, SourceRange>>> {
|
|
||||||
self.ids_of_async_commands.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
|
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
|
||||||
self.default_planes.clone()
|
self.default_planes.clone()
|
||||||
}
|
}
|
||||||
@ -88,25 +80,6 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn inner_fire_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: SourceRange,
|
|
||||||
cmd: WebSocketRequest,
|
|
||||||
id_to_source_range: HashMap<Uuid, SourceRange>,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
// Pop off the id we care about.
|
|
||||||
self.ids_of_async_commands.write().await.swap_remove(&id);
|
|
||||||
|
|
||||||
// Add the response to our responses.
|
|
||||||
let response = self
|
|
||||||
.inner_send_modeling_cmd(id, source_range, cmd, id_to_source_range)
|
|
||||||
.await?;
|
|
||||||
self.responses().write().await.insert(id, response);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn inner_send_modeling_cmd(
|
async fn inner_send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
@ -136,20 +109,6 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
success: true,
|
success: true,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
WebSocketRequest::ModelingCmdReq(ModelingCmdReq {
|
|
||||||
cmd: ModelingCmd::ImportFiles(ImportFiles { .. }),
|
|
||||||
cmd_id,
|
|
||||||
}) => Ok(WebSocketResponse::Success(SuccessWebSocketResponse {
|
|
||||||
request_id: Some(id),
|
|
||||||
resp: OkWebSocketResponseData::Modeling {
|
|
||||||
modeling_response: OkModelingCmdResponse::ImportFiles(
|
|
||||||
kittycad_modeling_cmds::output::ImportFiles {
|
|
||||||
object_id: cmd_id.into(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
success: true,
|
|
||||||
})),
|
|
||||||
WebSocketRequest::ModelingCmdReq(_) => Ok(WebSocketResponse::Success(SuccessWebSocketResponse {
|
WebSocketRequest::ModelingCmdReq(_) => Ok(WebSocketResponse::Success(SuccessWebSocketResponse {
|
||||||
request_id: Some(id),
|
request_id: Some(id),
|
||||||
resp: OkWebSocketResponseData::Modeling {
|
resp: OkWebSocketResponseData::Modeling {
|
||||||
|
@ -22,15 +22,6 @@ extern "C" {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub type EngineCommandManager;
|
pub type EngineCommandManager;
|
||||||
|
|
||||||
#[wasm_bindgen(method, js_name = fireModelingCommandFromWasm, catch)]
|
|
||||||
fn fire_modeling_cmd_from_wasm(
|
|
||||||
this: &EngineCommandManager,
|
|
||||||
id: String,
|
|
||||||
rangeStr: String,
|
|
||||||
cmdStr: String,
|
|
||||||
idToRangeStr: String,
|
|
||||||
) -> Result<(), js_sys::Error>;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, js_name = sendModelingCommandFromWasm, catch)]
|
#[wasm_bindgen(method, js_name = sendModelingCommandFromWasm, catch)]
|
||||||
fn send_modeling_cmd_from_wasm(
|
fn send_modeling_cmd_from_wasm(
|
||||||
this: &EngineCommandManager,
|
this: &EngineCommandManager,
|
||||||
@ -47,128 +38,33 @@ extern "C" {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EngineConnection {
|
pub struct EngineConnection {
|
||||||
manager: Arc<EngineCommandManager>,
|
manager: Arc<EngineCommandManager>,
|
||||||
response_context: Arc<ResponseContext>,
|
|
||||||
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
|
batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
|
||||||
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
|
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
|
||||||
|
responses: Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>>,
|
||||||
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
|
artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
|
||||||
ids_of_async_commands: Arc<RwLock<IndexMap<Uuid, SourceRange>>>,
|
|
||||||
/// The default planes for the scene.
|
/// The default planes for the scene.
|
||||||
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
||||||
stats: EngineStats,
|
stats: EngineStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct ResponseContext {
|
|
||||||
responses: Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
impl ResponseContext {
|
|
||||||
#[wasm_bindgen(constructor)]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
responses: Arc::new(RwLock::new(IndexMap::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a response to the context.
|
|
||||||
pub async fn send_response(&self, data: js_sys::Uint8Array) -> Result<(), JsValue> {
|
|
||||||
let ws_result: WebSocketResponse = match bson::from_slice(&data.to_vec()) {
|
|
||||||
Ok(res) => res,
|
|
||||||
Err(_) => {
|
|
||||||
// We don't care about the error if we can't parse it.
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let id = match &ws_result {
|
|
||||||
WebSocketResponse::Success(res) => res.request_id,
|
|
||||||
WebSocketResponse::Failure(res) => res.request_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(id) = id else {
|
|
||||||
// We only care if we have an id.
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add this response to our responses.
|
|
||||||
self.add(id, ws_result.clone()).await;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResponseContext {
|
|
||||||
pub async fn add(&self, id: Uuid, response: WebSocketResponse) {
|
|
||||||
self.responses.write().await.insert(id, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn responses(&self) -> Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>> {
|
|
||||||
self.responses.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Safety: WebAssembly will only ever run in a single-threaded context.
|
// Safety: WebAssembly will only ever run in a single-threaded context.
|
||||||
unsafe impl Send for EngineConnection {}
|
unsafe impl Send for EngineConnection {}
|
||||||
unsafe impl Sync for EngineConnection {}
|
unsafe impl Sync for EngineConnection {}
|
||||||
|
|
||||||
impl EngineConnection {
|
impl EngineConnection {
|
||||||
pub async fn new(
|
pub async fn new(manager: EngineCommandManager) -> Result<EngineConnection, JsValue> {
|
||||||
manager: EngineCommandManager,
|
|
||||||
response_context: Arc<ResponseContext>,
|
|
||||||
) -> Result<EngineConnection, JsValue> {
|
|
||||||
#[allow(clippy::arc_with_non_send_sync)]
|
#[allow(clippy::arc_with_non_send_sync)]
|
||||||
Ok(EngineConnection {
|
Ok(EngineConnection {
|
||||||
manager: Arc::new(manager),
|
manager: Arc::new(manager),
|
||||||
batch: Arc::new(RwLock::new(Vec::new())),
|
batch: Arc::new(RwLock::new(Vec::new())),
|
||||||
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
||||||
response_context,
|
responses: Arc::new(RwLock::new(IndexMap::new())),
|
||||||
artifact_commands: Arc::new(RwLock::new(Vec::new())),
|
artifact_commands: Arc::new(RwLock::new(Vec::new())),
|
||||||
ids_of_async_commands: Arc::new(RwLock::new(IndexMap::new())),
|
|
||||||
default_planes: Default::default(),
|
default_planes: Default::default(),
|
||||||
stats: Default::default(),
|
stats: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn do_fire_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: SourceRange,
|
|
||||||
cmd: WebSocketRequest,
|
|
||||||
id_to_source_range: HashMap<uuid::Uuid, SourceRange>,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
let source_range_str = serde_json::to_string(&source_range).map_err(|e| {
|
|
||||||
KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Failed to serialize source range: {:?}", e),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let cmd_str = serde_json::to_string(&cmd).map_err(|e| {
|
|
||||||
KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Failed to serialize modeling command: {:?}", e),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let id_to_source_range_str = serde_json::to_string(&id_to_source_range).map_err(|e| {
|
|
||||||
KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Failed to serialize id to source range: {:?}", e),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
|
|
||||||
self.manager
|
|
||||||
.fire_modeling_cmd_from_wasm(id.to_string(), source_range_str, cmd_str, id_to_source_range_str)
|
|
||||||
.map_err(|e| {
|
|
||||||
KclError::Engine(KclErrorDetails {
|
|
||||||
message: e.to_string().into(),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn do_send_modeling_cmd(
|
async fn do_send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
@ -255,7 +151,7 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn responses(&self) -> Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>> {
|
fn responses(&self) -> Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>> {
|
||||||
self.response_context.responses.clone()
|
self.responses.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stats(&self) -> &EngineStats {
|
fn stats(&self) -> &EngineStats {
|
||||||
@ -266,10 +162,6 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
self.artifact_commands.clone()
|
self.artifact_commands.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ids_of_async_commands(&self) -> Arc<RwLock<IndexMap<Uuid, SourceRange>>> {
|
|
||||||
self.ids_of_async_commands.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
|
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
|
||||||
self.default_planes.clone()
|
self.default_planes.clone()
|
||||||
}
|
}
|
||||||
@ -301,19 +193,6 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn inner_fire_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: SourceRange,
|
|
||||||
cmd: WebSocketRequest,
|
|
||||||
id_to_source_range: HashMap<Uuid, SourceRange>,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
self.do_fire_modeling_cmd(id, source_range, cmd, id_to_source_range)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn inner_send_modeling_cmd(
|
async fn inner_send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
@ -325,7 +204,9 @@ impl crate::engine::EngineManager for EngineConnection {
|
|||||||
.do_send_modeling_cmd(id, source_range, cmd, id_to_source_range)
|
.do_send_modeling_cmd(id, source_range, cmd, id_to_source_range)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.response_context.add(id, ws_result.clone()).await;
|
let mut responses = self.responses.write().await;
|
||||||
|
responses.insert(id, ws_result.clone());
|
||||||
|
drop(responses);
|
||||||
|
|
||||||
Ok(ws_result)
|
Ok(ws_result)
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
/// Get the artifact commands that have accumulated so far.
|
/// Get the artifact commands that have accumulated so far.
|
||||||
fn artifact_commands(&self) -> Arc<RwLock<Vec<ArtifactCommand>>>;
|
fn artifact_commands(&self) -> Arc<RwLock<Vec<ArtifactCommand>>>;
|
||||||
|
|
||||||
/// Get the ids of the async commands we are waiting for.
|
|
||||||
fn ids_of_async_commands(&self) -> Arc<RwLock<IndexMap<Uuid, SourceRange>>>;
|
|
||||||
|
|
||||||
/// Take the batch of commands that have accumulated so far and clear them.
|
/// Take the batch of commands that have accumulated so far and clear them.
|
||||||
async fn take_batch(&self) -> Vec<(WebSocketRequest, SourceRange)> {
|
async fn take_batch(&self) -> Vec<(WebSocketRequest, SourceRange)> {
|
||||||
std::mem::take(&mut *self.batch().write().await)
|
std::mem::take(&mut *self.batch().write().await)
|
||||||
@ -99,11 +96,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
std::mem::take(&mut *self.artifact_commands().write().await)
|
std::mem::take(&mut *self.artifact_commands().write().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take the ids of async commands that have accumulated so far and clear them.
|
|
||||||
async fn take_ids_of_async_commands(&self) -> IndexMap<Uuid, SourceRange> {
|
|
||||||
std::mem::take(&mut *self.ids_of_async_commands().write().await)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Take the responses that have accumulated so far and clear them.
|
/// Take the responses that have accumulated so far and clear them.
|
||||||
async fn take_responses(&self) -> IndexMap<Uuid, WebSocketResponse> {
|
async fn take_responses(&self) -> IndexMap<Uuid, WebSocketResponse> {
|
||||||
std::mem::take(&mut *self.responses().write().await)
|
std::mem::take(&mut *self.responses().write().await)
|
||||||
@ -144,18 +136,8 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
async fn clear_queues(&self) {
|
async fn clear_queues(&self) {
|
||||||
self.batch().write().await.clear();
|
self.batch().write().await.clear();
|
||||||
self.batch_end().write().await.clear();
|
self.batch_end().write().await.clear();
|
||||||
self.ids_of_async_commands().write().await.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a modeling command and do not wait for the response message.
|
|
||||||
async fn inner_fire_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: SourceRange,
|
|
||||||
cmd: WebSocketRequest,
|
|
||||||
id_to_source_range: HashMap<Uuid, SourceRange>,
|
|
||||||
) -> Result<(), crate::errors::KclError>;
|
|
||||||
|
|
||||||
/// Send a modeling command and wait for the response message.
|
/// Send a modeling command and wait for the response message.
|
||||||
async fn inner_send_modeling_cmd(
|
async fn inner_send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
@ -198,68 +180,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure a specific async command has been completed.
|
|
||||||
async fn ensure_async_command_completed(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: Option<SourceRange>,
|
|
||||||
) -> Result<OkWebSocketResponseData, KclError> {
|
|
||||||
let source_range = if let Some(source_range) = source_range {
|
|
||||||
source_range
|
|
||||||
} else {
|
|
||||||
// Look it up if we don't have it.
|
|
||||||
self.ids_of_async_commands()
|
|
||||||
.read()
|
|
||||||
.await
|
|
||||||
.get(&id)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let current_time = instant::Instant::now();
|
|
||||||
while current_time.elapsed().as_secs() < 60 {
|
|
||||||
let responses = self.responses().read().await.clone();
|
|
||||||
let Some(resp) = responses.get(&id) else {
|
|
||||||
// Sleep for a little so we don't hog the CPU.
|
|
||||||
// No seriously WE DO NOT WANT TO PAUSE THE WHOLE APP ON THE JS SIDE.
|
|
||||||
let duration = instant::Duration::from_millis(100);
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
wasm_timer::Delay::new(duration).await.map_err(|err| {
|
|
||||||
KclError::Internal(KclErrorDetails {
|
|
||||||
message: format!("Failed to sleep: {:?}", err),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
tokio::time::sleep(duration).await;
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the response is an error, return it.
|
|
||||||
// Parsing will do that and we can ignore the result, we don't care.
|
|
||||||
let response = self.parse_websocket_response(resp.clone(), source_range)?;
|
|
||||||
return Ok(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(KclError::Engine(KclErrorDetails {
|
|
||||||
message: "async command timed out".to_string(),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ensure ALL async commands have been completed.
|
|
||||||
async fn ensure_async_commands_completed(&self) -> Result<(), KclError> {
|
|
||||||
// Check if all async commands have been completed.
|
|
||||||
let ids = self.take_ids_of_async_commands().await;
|
|
||||||
|
|
||||||
// Try to get them from the responses.
|
|
||||||
for (id, source_range) in ids {
|
|
||||||
self.ensure_async_command_completed(id, Some(source_range)).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the visibility of edges.
|
/// Set the visibility of edges.
|
||||||
async fn set_edge_visibility(
|
async fn set_edge_visibility(
|
||||||
&self,
|
&self,
|
||||||
@ -422,36 +342,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
self.run_batch(requests, source_range).await
|
self.run_batch(requests, source_range).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the modeling cmd async and don't wait for the response.
|
|
||||||
/// Add it to our list of async commands.
|
|
||||||
async fn async_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: SourceRange,
|
|
||||||
cmd: &ModelingCmd,
|
|
||||||
) -> Result<(), crate::errors::KclError> {
|
|
||||||
// Add the command ID to the list of async commands.
|
|
||||||
self.ids_of_async_commands().write().await.insert(id, source_range);
|
|
||||||
|
|
||||||
// Add to artifact commands.
|
|
||||||
self.handle_artifact_command(cmd, id.into(), &HashMap::from([(id, source_range)]))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Fire off the command now, but don't wait for the response, we don't care about it.
|
|
||||||
self.inner_fire_modeling_cmd(
|
|
||||||
id,
|
|
||||||
source_range,
|
|
||||||
WebSocketRequest::ModelingCmdReq(ModelingCmdReq {
|
|
||||||
cmd: cmd.clone(),
|
|
||||||
cmd_id: id.into(),
|
|
||||||
}),
|
|
||||||
HashMap::from([(id, source_range)]),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run the batch for the specific commands.
|
/// Run the batch for the specific commands.
|
||||||
async fn run_batch(
|
async fn run_batch(
|
||||||
&self,
|
&self,
|
||||||
|
@ -15,8 +15,6 @@ use crate::{
|
|||||||
std::{args::TyF64, sketch::PlaneData},
|
std::{args::TyF64, sketch::PlaneData},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ExecutorContext;
|
|
||||||
|
|
||||||
type Point2D = kcmc::shared::Point2d<f64>;
|
type Point2D = kcmc::shared::Point2d<f64>;
|
||||||
type Point3D = kcmc::shared::Point3d<f64>;
|
type Point3D = kcmc::shared::Point3d<f64>;
|
||||||
|
|
||||||
@ -78,45 +76,9 @@ pub struct ImportedGeometry {
|
|||||||
pub value: Vec<String>,
|
pub value: Vec<String>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub meta: Vec<Metadata>,
|
pub meta: Vec<Metadata>,
|
||||||
/// If the imported geometry has completed.
|
|
||||||
#[serde(skip)]
|
|
||||||
completed: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportedGeometry {
|
/// Data for a solid or an imported geometry.
|
||||||
pub fn new(id: uuid::Uuid, value: Vec<String>, meta: Vec<Metadata>) -> Self {
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
value,
|
|
||||||
meta,
|
|
||||||
completed: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_finish(&mut self, ctx: &ExecutorContext) -> Result<(), KclError> {
|
|
||||||
if self.completed {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.engine
|
|
||||||
.ensure_async_command_completed(self.id, self.meta.first().map(|m| m.source_range))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
self.completed = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn id(&mut self, ctx: &ExecutorContext) -> Result<uuid::Uuid, KclError> {
|
|
||||||
if !self.completed {
|
|
||||||
self.wait_for_finish(ctx).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Data for a solid, sketch, or an imported geometry.
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(tag = "type", rename_all = "camelCase")]
|
#[serde(tag = "type", rename_all = "camelCase")]
|
||||||
@ -166,61 +128,11 @@ impl From<SolidOrSketchOrImportedGeometry> for crate::execution::KclValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SolidOrSketchOrImportedGeometry {
|
impl SolidOrSketchOrImportedGeometry {
|
||||||
pub(crate) async fn ids(&mut self, ctx: &ExecutorContext) -> Result<Vec<uuid::Uuid>, KclError> {
|
pub(crate) fn ids(&self) -> Vec<uuid::Uuid> {
|
||||||
match self {
|
match self {
|
||||||
SolidOrSketchOrImportedGeometry::ImportedGeometry(s) => {
|
SolidOrSketchOrImportedGeometry::ImportedGeometry(s) => vec![s.id],
|
||||||
let id = s.id(ctx).await?;
|
SolidOrSketchOrImportedGeometry::SolidSet(s) => s.iter().map(|s| s.id).collect(),
|
||||||
|
SolidOrSketchOrImportedGeometry::SketchSet(s) => s.iter().map(|s| s.id).collect(),
|
||||||
Ok(vec![id])
|
|
||||||
}
|
|
||||||
SolidOrSketchOrImportedGeometry::SolidSet(s) => Ok(s.iter().map(|s| s.id).collect()),
|
|
||||||
SolidOrSketchOrImportedGeometry::SketchSet(s) => Ok(s.iter().map(|s| s.id).collect()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Data for a solid or an imported geometry.
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
||||||
#[ts(export)]
|
|
||||||
#[serde(tag = "type", rename_all = "camelCase")]
|
|
||||||
#[allow(clippy::vec_box)]
|
|
||||||
pub enum SolidOrImportedGeometry {
|
|
||||||
ImportedGeometry(Box<ImportedGeometry>),
|
|
||||||
SolidSet(Vec<Solid>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SolidOrImportedGeometry> for crate::execution::KclValue {
|
|
||||||
fn from(value: SolidOrImportedGeometry) -> Self {
|
|
||||||
match value {
|
|
||||||
SolidOrImportedGeometry::ImportedGeometry(s) => crate::execution::KclValue::ImportedGeometry(*s),
|
|
||||||
SolidOrImportedGeometry::SolidSet(mut s) => {
|
|
||||||
if s.len() == 1 {
|
|
||||||
crate::execution::KclValue::Solid {
|
|
||||||
value: Box::new(s.pop().unwrap()),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
crate::execution::KclValue::HomArray {
|
|
||||||
value: s
|
|
||||||
.into_iter()
|
|
||||||
.map(|s| crate::execution::KclValue::Solid { value: Box::new(s) })
|
|
||||||
.collect(),
|
|
||||||
ty: crate::execution::types::RuntimeType::solid(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SolidOrImportedGeometry {
|
|
||||||
pub(crate) async fn ids(&mut self, ctx: &ExecutorContext) -> Result<Vec<uuid::Uuid>, KclError> {
|
|
||||||
match self {
|
|
||||||
SolidOrImportedGeometry::ImportedGeometry(s) => {
|
|
||||||
let id = s.id(ctx).await?;
|
|
||||||
|
|
||||||
Ok(vec![id])
|
|
||||||
}
|
|
||||||
SolidOrImportedGeometry::SolidSet(s) => Ok(s.iter().map(|s| s.id).collect()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,10 @@ use kcmc::{
|
|||||||
coord::{System, KITTYCAD},
|
coord::{System, KITTYCAD},
|
||||||
each_cmd as mcmd,
|
each_cmd as mcmd,
|
||||||
format::InputFormat3d,
|
format::InputFormat3d,
|
||||||
|
ok_response::OkModelingCmdResponse,
|
||||||
shared::FileImportFormat,
|
shared::FileImportFormat,
|
||||||
units::UnitLength,
|
units::UnitLength,
|
||||||
|
websocket::OkWebSocketResponseData,
|
||||||
ImportFile, ModelingCmd,
|
ImportFile, ModelingCmd,
|
||||||
};
|
};
|
||||||
use kittycad_modeling_cmds as kcmc;
|
use kittycad_modeling_cmds as kcmc;
|
||||||
@ -287,17 +289,34 @@ pub struct PreImportedGeometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_to_engine(pre: PreImportedGeometry, ctxt: &ExecutorContext) -> Result<ImportedGeometry, KclError> {
|
pub async fn send_to_engine(pre: PreImportedGeometry, ctxt: &ExecutorContext) -> Result<ImportedGeometry, KclError> {
|
||||||
let imported_geometry = ImportedGeometry::new(
|
if ctxt.no_engine_commands().await {
|
||||||
pre.id,
|
return Ok(ImportedGeometry {
|
||||||
pre.command.files.iter().map(|f| f.path.to_string()).collect(),
|
id: pre.id,
|
||||||
vec![pre.source_range.into()],
|
value: pre.command.files.iter().map(|f| f.path.to_string()).collect(),
|
||||||
);
|
meta: vec![pre.source_range.into()],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ctxt.engine
|
let resp = ctxt
|
||||||
.async_modeling_cmd(pre.id, pre.source_range, &ModelingCmd::from(pre.command.clone()))
|
.engine
|
||||||
|
.send_modeling_cmd(pre.id, pre.source_range, &ModelingCmd::from(pre.command.clone()))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(imported_geometry)
|
let OkWebSocketResponseData::Modeling {
|
||||||
|
modeling_response: OkModelingCmdResponse::ImportFiles(imported_files),
|
||||||
|
} = &resp
|
||||||
|
else {
|
||||||
|
return Err(KclError::Engine(KclErrorDetails {
|
||||||
|
message: format!("ImportFiles response was not as expected: {:?}", resp),
|
||||||
|
source_ranges: vec![pre.source_range],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ImportedGeometry {
|
||||||
|
id: imported_files.object_id,
|
||||||
|
value: pre.command.files.iter().map(|f| f.path.to_string()).collect(),
|
||||||
|
meta: vec![pre.source_range.into()],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the source format from the extension.
|
/// Get the source format from the extension.
|
||||||
|
@ -947,7 +947,7 @@ impl ExecutorContext {
|
|||||||
exec_state.global.artifact_graph.clone(),
|
exec_state.global.artifact_graph.clone(),
|
||||||
module_id_to_module_path,
|
module_id_to_module_path,
|
||||||
exec_state.global.id_to_source.clone(),
|
exec_state.global.id_to_source.clone(),
|
||||||
default_planes.clone(),
|
default_planes,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -957,7 +957,6 @@ impl ExecutorContext {
|
|||||||
cache::write_old_memory((mem, exec_state.global.module_infos.clone())).await;
|
cache::write_old_memory((mem, exec_state.global.module_infos.clone())).await;
|
||||||
}
|
}
|
||||||
let session_data = self.engine.get_session_data().await;
|
let session_data = self.engine.get_session_data().await;
|
||||||
|
|
||||||
Ok((env_ref, session_data))
|
Ok((env_ref, session_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,9 +984,6 @@ impl ExecutorContext {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// Ensure all the async commands completed.
|
|
||||||
self.engine.ensure_async_commands_completed().await?;
|
|
||||||
|
|
||||||
// If we errored out and early-returned, there might be commands which haven't been executed
|
// If we errored out and early-returned, there might be commands which haven't been executed
|
||||||
// and should be dropped.
|
// and should be dropped.
|
||||||
self.engine.clear_queues().await;
|
self.engine.clear_queues().await;
|
||||||
|
@ -1338,11 +1338,11 @@ mod test {
|
|||||||
value: Box::new(Plane::from_plane_data(crate::std::sketch::PlaneData::XY, exec_state)),
|
value: Box::new(Plane::from_plane_data(crate::std::sketch::PlaneData::XY, exec_state)),
|
||||||
},
|
},
|
||||||
// No easy way to make a Face, Sketch, Solid, or Helix
|
// No easy way to make a Face, Sketch, Solid, or Helix
|
||||||
KclValue::ImportedGeometry(crate::execution::ImportedGeometry::new(
|
KclValue::ImportedGeometry(crate::execution::ImportedGeometry {
|
||||||
uuid::Uuid::nil(),
|
id: uuid::Uuid::nil(),
|
||||||
Vec::new(),
|
value: Vec::new(),
|
||||||
Vec::new(),
|
meta: Vec::new(),
|
||||||
)),
|
}),
|
||||||
// Other values don't have types
|
// Other values don't have types
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ pub mod exec {
|
|||||||
pub mod wasm_engine {
|
pub mod wasm_engine {
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
coredump::wasm::{CoreDumpManager, CoreDumper},
|
coredump::wasm::{CoreDumpManager, CoreDumper},
|
||||||
engine::conn_wasm::{EngineCommandManager, EngineConnection, ResponseContext},
|
engine::conn_wasm::{EngineCommandManager, EngineConnection},
|
||||||
fs::wasm::{FileManager, FileSystemManager},
|
fs::wasm::{FileManager, FileSystemManager},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2579,24 +2579,3 @@ mod tangent_to_3_point_arc {
|
|||||||
super::execute(TEST_NAME, true).await
|
super::execute(TEST_NAME, true).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod import_async {
|
|
||||||
const TEST_NAME: &str = "import_async";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn unparse() {
|
|
||||||
super::unparse(TEST_NAME).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, true).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
types::{NumericType, PrimitiveType, RuntimeType},
|
types::{NumericType, PrimitiveType, RuntimeType},
|
||||||
ExecState, KclValue, SolidOrImportedGeometry,
|
ExecState, KclValue, Solid,
|
||||||
},
|
},
|
||||||
std::Args,
|
std::Args,
|
||||||
};
|
};
|
||||||
@ -43,11 +43,7 @@ struct AppearanceData {
|
|||||||
|
|
||||||
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
|
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
|
||||||
pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let solids = args.get_unlabeled_kw_arg_typed(
|
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
|
||||||
"solids",
|
|
||||||
&RuntimeType::Union(vec![RuntimeType::solids(), RuntimeType::imported()]),
|
|
||||||
exec_state,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let color: String = args.get_kw_arg("color")?;
|
let color: String = args.get_kw_arg("color")?;
|
||||||
let count_ty = RuntimeType::Primitive(PrimitiveType::Number(NumericType::count()));
|
let count_ty = RuntimeType::Primitive(PrimitiveType::Number(NumericType::count()));
|
||||||
@ -274,19 +270,6 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
|
|||||||
/// roughness = 50
|
/// roughness = 50
|
||||||
/// )
|
/// )
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// // Change the appearance of an imported model.
|
|
||||||
///
|
|
||||||
/// import "tests/inputs/cube.sldprt" as cube
|
|
||||||
///
|
|
||||||
/// cube
|
|
||||||
/// // |> appearance(
|
|
||||||
/// // color = "#ff0000",
|
|
||||||
/// // metalness = 50,
|
|
||||||
/// // roughness = 50
|
|
||||||
/// // )
|
|
||||||
/// ```
|
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "appearance",
|
name = "appearance",
|
||||||
keywords = true,
|
keywords = true,
|
||||||
@ -299,16 +282,14 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
async fn inner_appearance(
|
async fn inner_appearance(
|
||||||
solids: SolidOrImportedGeometry,
|
solids: Vec<Solid>,
|
||||||
color: String,
|
color: String,
|
||||||
metalness: Option<f64>,
|
metalness: Option<f64>,
|
||||||
roughness: Option<f64>,
|
roughness: Option<f64>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<SolidOrImportedGeometry, KclError> {
|
) -> Result<Vec<Solid>, KclError> {
|
||||||
let mut solids = solids.clone();
|
for solid in &solids {
|
||||||
|
|
||||||
for solid_id in solids.ids(&args.ctx).await? {
|
|
||||||
// Set the material properties.
|
// Set the material properties.
|
||||||
let rgb = rgba_simple::RGB::<f32>::from_hex(&color).map_err(|err| {
|
let rgb = rgba_simple::RGB::<f32>::from_hex(&color).map_err(|err| {
|
||||||
KclError::Semantic(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
@ -327,7 +308,7 @@ async fn inner_appearance(
|
|||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
exec_state.next_uuid(),
|
exec_state.next_uuid(),
|
||||||
ModelingCmd::from(mcmd::ObjectSetMaterialParamsPbr {
|
ModelingCmd::from(mcmd::ObjectSetMaterialParamsPbr {
|
||||||
object_id: solid_id,
|
object_id: solid.id,
|
||||||
color,
|
color,
|
||||||
metalness: metalness.unwrap_or_default() as f32 / 100.0,
|
metalness: metalness.unwrap_or_default() as f32 / 100.0,
|
||||||
roughness: roughness.unwrap_or_default() as f32 / 100.0,
|
roughness: roughness.unwrap_or_default() as f32 / 100.0,
|
||||||
|
@ -28,9 +28,6 @@ use crate::{
|
|||||||
ModuleId,
|
ModuleId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ERROR_STRING_SKETCH_TO_SOLID_HELPER: &str =
|
|
||||||
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`";
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Arg {
|
pub struct Arg {
|
||||||
/// The evaluated argument.
|
/// The evaluated argument.
|
||||||
@ -223,19 +220,18 @@ impl Args {
|
|||||||
ty.human_friendly_type(),
|
ty.human_friendly_type(),
|
||||||
);
|
);
|
||||||
let suggestion = match (ty, actual_type_name) {
|
let suggestion = match (ty, actual_type_name) {
|
||||||
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some(ERROR_STRING_SKETCH_TO_SOLID_HELPER),
|
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some(
|
||||||
(RuntimeType::Array(t, _), "Sketch") if **t == RuntimeType::Primitive(PrimitiveType::Solid) => {
|
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
|
||||||
Some(ERROR_STRING_SKETCH_TO_SOLID_HELPER)
|
),
|
||||||
}
|
(RuntimeType::Array(t, _), "Sketch") if **t == RuntimeType::Primitive(PrimitiveType::Solid) => Some(
|
||||||
|
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
|
||||||
|
),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let mut message = match suggestion {
|
let message = match suggestion {
|
||||||
None => msg_base,
|
None => msg_base,
|
||||||
Some(sugg) => format!("{msg_base}. {sugg}"),
|
Some(sugg) => format!("{msg_base}. {sugg}"),
|
||||||
};
|
};
|
||||||
if message.contains("one or more Solids or imported geometry but it's actually of type Sketch") {
|
|
||||||
message = format!("{message}. {ERROR_STRING_SKETCH_TO_SOLID_HELPER}");
|
|
||||||
}
|
|
||||||
KclError::Semantic(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: arg.source_ranges(),
|
source_ranges: arg.source_ranges(),
|
||||||
message,
|
message,
|
||||||
@ -347,20 +343,18 @@ impl Args {
|
|||||||
ty.human_friendly_type(),
|
ty.human_friendly_type(),
|
||||||
);
|
);
|
||||||
let suggestion = match (ty, actual_type_name) {
|
let suggestion = match (ty, actual_type_name) {
|
||||||
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some(ERROR_STRING_SKETCH_TO_SOLID_HELPER),
|
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some(
|
||||||
(RuntimeType::Array(ty, _), "Sketch") if **ty == RuntimeType::Primitive(PrimitiveType::Solid) => {
|
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
|
||||||
Some(ERROR_STRING_SKETCH_TO_SOLID_HELPER)
|
),
|
||||||
}
|
(RuntimeType::Array(ty, _), "Sketch") if **ty == RuntimeType::Primitive(PrimitiveType::Solid) => Some(
|
||||||
|
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
|
||||||
|
),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let mut message = match suggestion {
|
let message = match suggestion {
|
||||||
None => msg_base,
|
None => msg_base,
|
||||||
Some(sugg) => format!("{msg_base}. {sugg}"),
|
Some(sugg) => format!("{msg_base}. {sugg}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if message.contains("one or more Solids or imported geometry but it's actually of type Sketch") {
|
|
||||||
message = format!("{message}. {ERROR_STRING_SKETCH_TO_SOLID_HELPER}");
|
|
||||||
}
|
|
||||||
KclError::Semantic(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: arg.source_ranges(),
|
source_ranges: arg.source_ranges(),
|
||||||
message,
|
message,
|
||||||
@ -1402,26 +1396,6 @@ impl<'a> FromKclValue<'a> for crate::execution::SolidOrSketchOrImportedGeometry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for crate::execution::SolidOrImportedGeometry {
|
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
|
||||||
match arg {
|
|
||||||
KclValue::Solid { value } => Some(Self::SolidSet(vec![(**value).clone()])),
|
|
||||||
KclValue::HomArray { value, .. } => {
|
|
||||||
let mut solids = vec![];
|
|
||||||
for item in value {
|
|
||||||
match item {
|
|
||||||
KclValue::Solid { value } => solids.push((**value).clone()),
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(Self::SolidSet(solids))
|
|
||||||
}
|
|
||||||
KclValue::ImportedGeometry(value) => Some(Self::ImportedGeometry(Box::new(value.clone()))),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for super::sketch::SketchData {
|
impl<'a> FromKclValue<'a> for super::sketch::SketchData {
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||||
// Order is critical since PlaneData is a subset of Plane.
|
// Order is critical since PlaneData is a subset of Plane.
|
||||||
|
@ -171,8 +171,7 @@ async fn inner_scale(
|
|||||||
args.flush_batch_for_solids(exec_state, solids).await?;
|
args.flush_batch_for_solids(exec_state, solids).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut objects = objects.clone();
|
for object_id in objects.ids() {
|
||||||
for object_id in objects.ids(&args.ctx).await? {
|
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
@ -410,8 +409,7 @@ async fn inner_translate(
|
|||||||
args.flush_batch_for_solids(exec_state, solids).await?;
|
args.flush_batch_for_solids(exec_state, solids).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut objects = objects.clone();
|
for object_id in objects.ids() {
|
||||||
for object_id in objects.ids(&args.ctx).await? {
|
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
@ -776,8 +774,7 @@ async fn inner_rotate(
|
|||||||
args.flush_batch_for_solids(exec_state, solids).await?;
|
args.flush_batch_for_solids(exec_state, solids).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut objects = objects.clone();
|
for object_id in objects.ids() {
|
||||||
for object_id in objects.ids(&args.ctx).await? {
|
|
||||||
let id = exec_state.next_uuid();
|
let id = exec_state.next_uuid();
|
||||||
|
|
||||||
if let (Some(axis), Some(angle)) = (axis, angle) {
|
if let (Some(axis), Some(angle)) = (axis, angle) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart import_async.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
@ -1,503 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
subgraph path3 [Path]
|
|
||||||
3["Path<br>[1035, 1085, 0]"]
|
|
||||||
4["Segment<br>[1035, 1085, 0]"]
|
|
||||||
5[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path13 [Path]
|
|
||||||
13["Path<br>[1562, 1599, 0]"]
|
|
||||||
14["Segment<br>[1250, 1288, 0]"]
|
|
||||||
15["Segment<br>[1250, 1288, 0]"]
|
|
||||||
16["Segment<br>[1250, 1288, 0]"]
|
|
||||||
17["Segment<br>[1250, 1288, 0]"]
|
|
||||||
18["Segment<br>[1250, 1288, 0]"]
|
|
||||||
19["Segment<br>[1250, 1288, 0]"]
|
|
||||||
20["Segment<br>[1250, 1288, 0]"]
|
|
||||||
21["Segment<br>[1250, 1288, 0]"]
|
|
||||||
22["Segment<br>[1250, 1288, 0]"]
|
|
||||||
23["Segment<br>[1250, 1288, 0]"]
|
|
||||||
24["Segment<br>[1250, 1288, 0]"]
|
|
||||||
25["Segment<br>[1250, 1288, 0]"]
|
|
||||||
26["Segment<br>[1250, 1288, 0]"]
|
|
||||||
27["Segment<br>[1250, 1288, 0]"]
|
|
||||||
28["Segment<br>[1250, 1288, 0]"]
|
|
||||||
29["Segment<br>[1250, 1288, 0]"]
|
|
||||||
30["Segment<br>[1250, 1288, 0]"]
|
|
||||||
31["Segment<br>[1250, 1288, 0]"]
|
|
||||||
32["Segment<br>[1250, 1288, 0]"]
|
|
||||||
33["Segment<br>[1250, 1288, 0]"]
|
|
||||||
34["Segment<br>[1250, 1288, 0]"]
|
|
||||||
35["Segment<br>[1250, 1288, 0]"]
|
|
||||||
36["Segment<br>[1250, 1288, 0]"]
|
|
||||||
37["Segment<br>[1250, 1288, 0]"]
|
|
||||||
38["Segment<br>[1250, 1288, 0]"]
|
|
||||||
39["Segment<br>[1250, 1288, 0]"]
|
|
||||||
40["Segment<br>[1250, 1288, 0]"]
|
|
||||||
41["Segment<br>[1250, 1288, 0]"]
|
|
||||||
42["Segment<br>[1250, 1288, 0]"]
|
|
||||||
43["Segment<br>[1250, 1288, 0]"]
|
|
||||||
44["Segment<br>[1250, 1288, 0]"]
|
|
||||||
45["Segment<br>[1250, 1288, 0]"]
|
|
||||||
46["Segment<br>[1250, 1288, 0]"]
|
|
||||||
47["Segment<br>[1250, 1288, 0]"]
|
|
||||||
48["Segment<br>[1250, 1288, 0]"]
|
|
||||||
49["Segment<br>[1250, 1288, 0]"]
|
|
||||||
50["Segment<br>[1250, 1288, 0]"]
|
|
||||||
51["Segment<br>[1250, 1288, 0]"]
|
|
||||||
52["Segment<br>[1250, 1288, 0]"]
|
|
||||||
53["Segment<br>[1250, 1288, 0]"]
|
|
||||||
54["Segment<br>[1250, 1288, 0]"]
|
|
||||||
55["Segment<br>[1250, 1288, 0]"]
|
|
||||||
56["Segment<br>[1250, 1288, 0]"]
|
|
||||||
57["Segment<br>[1250, 1288, 0]"]
|
|
||||||
58["Segment<br>[1250, 1288, 0]"]
|
|
||||||
59["Segment<br>[1250, 1288, 0]"]
|
|
||||||
60["Segment<br>[1250, 1288, 0]"]
|
|
||||||
61["Segment<br>[1250, 1288, 0]"]
|
|
||||||
62["Segment<br>[1250, 1288, 0]"]
|
|
||||||
63["Segment<br>[1250, 1288, 0]"]
|
|
||||||
64["Segment<br>[1250, 1288, 0]"]
|
|
||||||
65["Segment<br>[1250, 1288, 0]"]
|
|
||||||
66["Segment<br>[1250, 1288, 0]"]
|
|
||||||
67["Segment<br>[1250, 1288, 0]"]
|
|
||||||
68["Segment<br>[1250, 1288, 0]"]
|
|
||||||
69["Segment<br>[1250, 1288, 0]"]
|
|
||||||
70["Segment<br>[1250, 1288, 0]"]
|
|
||||||
71["Segment<br>[1250, 1288, 0]"]
|
|
||||||
72["Segment<br>[1250, 1288, 0]"]
|
|
||||||
73["Segment<br>[1250, 1288, 0]"]
|
|
||||||
74["Segment<br>[1250, 1288, 0]"]
|
|
||||||
75["Segment<br>[1250, 1288, 0]"]
|
|
||||||
76["Segment<br>[1250, 1288, 0]"]
|
|
||||||
77["Segment<br>[1250, 1288, 0]"]
|
|
||||||
78["Segment<br>[1250, 1288, 0]"]
|
|
||||||
79["Segment<br>[1250, 1288, 0]"]
|
|
||||||
80["Segment<br>[1250, 1288, 0]"]
|
|
||||||
81["Segment<br>[1250, 1288, 0]"]
|
|
||||||
82["Segment<br>[1250, 1288, 0]"]
|
|
||||||
83["Segment<br>[1250, 1288, 0]"]
|
|
||||||
84["Segment<br>[1250, 1288, 0]"]
|
|
||||||
85["Segment<br>[1250, 1288, 0]"]
|
|
||||||
86["Segment<br>[1250, 1288, 0]"]
|
|
||||||
87["Segment<br>[1250, 1288, 0]"]
|
|
||||||
88["Segment<br>[1250, 1288, 0]"]
|
|
||||||
89["Segment<br>[1250, 1288, 0]"]
|
|
||||||
90["Segment<br>[1250, 1288, 0]"]
|
|
||||||
91["Segment<br>[1250, 1288, 0]"]
|
|
||||||
92["Segment<br>[1250, 1288, 0]"]
|
|
||||||
93["Segment<br>[1250, 1288, 0]"]
|
|
||||||
94["Segment<br>[1250, 1288, 0]"]
|
|
||||||
95["Segment<br>[1250, 1288, 0]"]
|
|
||||||
96["Segment<br>[1250, 1288, 0]"]
|
|
||||||
97["Segment<br>[1250, 1288, 0]"]
|
|
||||||
98["Segment<br>[1250, 1288, 0]"]
|
|
||||||
99["Segment<br>[1250, 1288, 0]"]
|
|
||||||
100["Segment<br>[1250, 1288, 0]"]
|
|
||||||
101["Segment<br>[1250, 1288, 0]"]
|
|
||||||
102["Segment<br>[1250, 1288, 0]"]
|
|
||||||
103["Segment<br>[1250, 1288, 0]"]
|
|
||||||
104["Segment<br>[1250, 1288, 0]"]
|
|
||||||
105["Segment<br>[1250, 1288, 0]"]
|
|
||||||
106["Segment<br>[1250, 1288, 0]"]
|
|
||||||
107["Segment<br>[1250, 1288, 0]"]
|
|
||||||
108["Segment<br>[1250, 1288, 0]"]
|
|
||||||
109["Segment<br>[1250, 1288, 0]"]
|
|
||||||
110["Segment<br>[1250, 1288, 0]"]
|
|
||||||
111["Segment<br>[1250, 1288, 0]"]
|
|
||||||
112["Segment<br>[1250, 1288, 0]"]
|
|
||||||
113["Segment<br>[1250, 1288, 0]"]
|
|
||||||
114["Segment<br>[1250, 1288, 0]"]
|
|
||||||
115["Segment<br>[1651, 1753, 0]"]
|
|
||||||
116["Segment<br>[1478, 1508, 0]"]
|
|
||||||
117["Segment<br>[1478, 1508, 0]"]
|
|
||||||
118["Segment<br>[1478, 1508, 0]"]
|
|
||||||
119["Segment<br>[1478, 1508, 0]"]
|
|
||||||
120["Segment<br>[1478, 1508, 0]"]
|
|
||||||
121["Segment<br>[1478, 1508, 0]"]
|
|
||||||
122["Segment<br>[1478, 1508, 0]"]
|
|
||||||
123["Segment<br>[1478, 1508, 0]"]
|
|
||||||
124["Segment<br>[1478, 1508, 0]"]
|
|
||||||
125["Segment<br>[1478, 1508, 0]"]
|
|
||||||
126["Segment<br>[1478, 1508, 0]"]
|
|
||||||
127["Segment<br>[1478, 1508, 0]"]
|
|
||||||
128["Segment<br>[1478, 1508, 0]"]
|
|
||||||
129["Segment<br>[1478, 1508, 0]"]
|
|
||||||
130["Segment<br>[1478, 1508, 0]"]
|
|
||||||
131["Segment<br>[1478, 1508, 0]"]
|
|
||||||
132["Segment<br>[1478, 1508, 0]"]
|
|
||||||
133["Segment<br>[1478, 1508, 0]"]
|
|
||||||
134["Segment<br>[1478, 1508, 0]"]
|
|
||||||
135["Segment<br>[1478, 1508, 0]"]
|
|
||||||
136["Segment<br>[1478, 1508, 0]"]
|
|
||||||
137["Segment<br>[1478, 1508, 0]"]
|
|
||||||
138["Segment<br>[1478, 1508, 0]"]
|
|
||||||
139["Segment<br>[1478, 1508, 0]"]
|
|
||||||
140["Segment<br>[1478, 1508, 0]"]
|
|
||||||
141["Segment<br>[1478, 1508, 0]"]
|
|
||||||
142["Segment<br>[1478, 1508, 0]"]
|
|
||||||
143["Segment<br>[1478, 1508, 0]"]
|
|
||||||
144["Segment<br>[1478, 1508, 0]"]
|
|
||||||
145["Segment<br>[1478, 1508, 0]"]
|
|
||||||
146["Segment<br>[1478, 1508, 0]"]
|
|
||||||
147["Segment<br>[1478, 1508, 0]"]
|
|
||||||
148["Segment<br>[1478, 1508, 0]"]
|
|
||||||
149["Segment<br>[1478, 1508, 0]"]
|
|
||||||
150["Segment<br>[1478, 1508, 0]"]
|
|
||||||
151["Segment<br>[1478, 1508, 0]"]
|
|
||||||
152["Segment<br>[1478, 1508, 0]"]
|
|
||||||
153["Segment<br>[1478, 1508, 0]"]
|
|
||||||
154["Segment<br>[1478, 1508, 0]"]
|
|
||||||
155["Segment<br>[1478, 1508, 0]"]
|
|
||||||
156["Segment<br>[1478, 1508, 0]"]
|
|
||||||
157["Segment<br>[1478, 1508, 0]"]
|
|
||||||
158["Segment<br>[1478, 1508, 0]"]
|
|
||||||
159["Segment<br>[1478, 1508, 0]"]
|
|
||||||
160["Segment<br>[1478, 1508, 0]"]
|
|
||||||
161["Segment<br>[1478, 1508, 0]"]
|
|
||||||
162["Segment<br>[1478, 1508, 0]"]
|
|
||||||
163["Segment<br>[1478, 1508, 0]"]
|
|
||||||
164["Segment<br>[1478, 1508, 0]"]
|
|
||||||
165["Segment<br>[1478, 1508, 0]"]
|
|
||||||
166["Segment<br>[1478, 1508, 0]"]
|
|
||||||
167["Segment<br>[1478, 1508, 0]"]
|
|
||||||
168["Segment<br>[1478, 1508, 0]"]
|
|
||||||
169["Segment<br>[1478, 1508, 0]"]
|
|
||||||
170["Segment<br>[1478, 1508, 0]"]
|
|
||||||
171["Segment<br>[1478, 1508, 0]"]
|
|
||||||
172["Segment<br>[1478, 1508, 0]"]
|
|
||||||
173["Segment<br>[1478, 1508, 0]"]
|
|
||||||
174["Segment<br>[1478, 1508, 0]"]
|
|
||||||
175["Segment<br>[1478, 1508, 0]"]
|
|
||||||
176["Segment<br>[1478, 1508, 0]"]
|
|
||||||
177["Segment<br>[1478, 1508, 0]"]
|
|
||||||
178["Segment<br>[1478, 1508, 0]"]
|
|
||||||
179["Segment<br>[1478, 1508, 0]"]
|
|
||||||
180["Segment<br>[1478, 1508, 0]"]
|
|
||||||
181["Segment<br>[1478, 1508, 0]"]
|
|
||||||
182["Segment<br>[1478, 1508, 0]"]
|
|
||||||
183["Segment<br>[1478, 1508, 0]"]
|
|
||||||
184["Segment<br>[1478, 1508, 0]"]
|
|
||||||
185["Segment<br>[1478, 1508, 0]"]
|
|
||||||
186["Segment<br>[1478, 1508, 0]"]
|
|
||||||
187["Segment<br>[1478, 1508, 0]"]
|
|
||||||
188["Segment<br>[1478, 1508, 0]"]
|
|
||||||
189["Segment<br>[1478, 1508, 0]"]
|
|
||||||
190["Segment<br>[1478, 1508, 0]"]
|
|
||||||
191["Segment<br>[1478, 1508, 0]"]
|
|
||||||
192["Segment<br>[1478, 1508, 0]"]
|
|
||||||
193["Segment<br>[1478, 1508, 0]"]
|
|
||||||
194["Segment<br>[1478, 1508, 0]"]
|
|
||||||
195["Segment<br>[1478, 1508, 0]"]
|
|
||||||
196["Segment<br>[1478, 1508, 0]"]
|
|
||||||
197["Segment<br>[1478, 1508, 0]"]
|
|
||||||
198["Segment<br>[1478, 1508, 0]"]
|
|
||||||
199["Segment<br>[1478, 1508, 0]"]
|
|
||||||
200["Segment<br>[1478, 1508, 0]"]
|
|
||||||
201["Segment<br>[1478, 1508, 0]"]
|
|
||||||
202["Segment<br>[1478, 1508, 0]"]
|
|
||||||
203["Segment<br>[1478, 1508, 0]"]
|
|
||||||
204["Segment<br>[1478, 1508, 0]"]
|
|
||||||
205["Segment<br>[1478, 1508, 0]"]
|
|
||||||
206["Segment<br>[1478, 1508, 0]"]
|
|
||||||
207["Segment<br>[1478, 1508, 0]"]
|
|
||||||
208["Segment<br>[1478, 1508, 0]"]
|
|
||||||
209["Segment<br>[1478, 1508, 0]"]
|
|
||||||
210["Segment<br>[1478, 1508, 0]"]
|
|
||||||
211["Segment<br>[1478, 1508, 0]"]
|
|
||||||
212["Segment<br>[1478, 1508, 0]"]
|
|
||||||
213["Segment<br>[1478, 1508, 0]"]
|
|
||||||
214["Segment<br>[1478, 1508, 0]"]
|
|
||||||
215["Segment<br>[1478, 1508, 0]"]
|
|
||||||
216["Segment<br>[1478, 1508, 0]"]
|
|
||||||
217["Segment<br>[1799, 1806, 0]"]
|
|
||||||
218[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path220 [Path]
|
|
||||||
220["Path<br>[2287, 2387, 0]"]
|
|
||||||
221["Segment<br>[2393, 2420, 0]"]
|
|
||||||
222["Segment<br>[2426, 2454, 0]"]
|
|
||||||
223["Segment<br>[2460, 2488, 0]"]
|
|
||||||
224["Segment<br>[2494, 2614, 0]"]
|
|
||||||
225["Segment<br>[2620, 2729, 0]"]
|
|
||||||
226["Segment<br>[2735, 2742, 0]"]
|
|
||||||
227[Solid2d]
|
|
||||||
end
|
|
||||||
1["Plane<br>[168, 185, 0]"]
|
|
||||||
2["Plane<br>[1012, 1029, 0]"]
|
|
||||||
6["Sweep Extrusion<br>[1091, 1119, 0]"]
|
|
||||||
7[Wall]
|
|
||||||
8["Cap Start"]
|
|
||||||
9["Cap End"]
|
|
||||||
10["SweepEdge Opposite"]
|
|
||||||
11["SweepEdge Adjacent"]
|
|
||||||
12["Plane<br>[1539, 1556, 0]"]
|
|
||||||
219["Sweep Extrusion<br>[1812, 1840, 0]"]
|
|
||||||
228["Sweep Extrusion<br>[2748, 2777, 0]"]
|
|
||||||
229[Wall]
|
|
||||||
230[Wall]
|
|
||||||
231[Wall]
|
|
||||||
232[Wall]
|
|
||||||
233["SweepEdge Opposite"]
|
|
||||||
234["SweepEdge Adjacent"]
|
|
||||||
235["SweepEdge Opposite"]
|
|
||||||
236["SweepEdge Adjacent"]
|
|
||||||
237["SweepEdge Opposite"]
|
|
||||||
238["SweepEdge Adjacent"]
|
|
||||||
239["SweepEdge Opposite"]
|
|
||||||
240["SweepEdge Adjacent"]
|
|
||||||
241["StartSketchOnFace<br>[2250, 2281, 0]"]
|
|
||||||
2 --- 3
|
|
||||||
3 --- 4
|
|
||||||
3 ---- 6
|
|
||||||
3 --- 5
|
|
||||||
4 --- 7
|
|
||||||
4 --- 10
|
|
||||||
4 --- 11
|
|
||||||
6 --- 7
|
|
||||||
6 --- 8
|
|
||||||
6 --- 9
|
|
||||||
6 --- 10
|
|
||||||
6 --- 11
|
|
||||||
9 --- 220
|
|
||||||
12 --- 13
|
|
||||||
13 --- 14
|
|
||||||
13 --- 15
|
|
||||||
13 --- 16
|
|
||||||
13 --- 17
|
|
||||||
13 --- 18
|
|
||||||
13 --- 19
|
|
||||||
13 --- 20
|
|
||||||
13 --- 21
|
|
||||||
13 --- 22
|
|
||||||
13 --- 23
|
|
||||||
13 --- 24
|
|
||||||
13 --- 25
|
|
||||||
13 --- 26
|
|
||||||
13 --- 27
|
|
||||||
13 --- 28
|
|
||||||
13 --- 29
|
|
||||||
13 --- 30
|
|
||||||
13 --- 31
|
|
||||||
13 --- 32
|
|
||||||
13 --- 33
|
|
||||||
13 --- 34
|
|
||||||
13 --- 35
|
|
||||||
13 --- 36
|
|
||||||
13 --- 37
|
|
||||||
13 --- 38
|
|
||||||
13 --- 39
|
|
||||||
13 --- 40
|
|
||||||
13 --- 41
|
|
||||||
13 --- 42
|
|
||||||
13 --- 43
|
|
||||||
13 --- 44
|
|
||||||
13 --- 45
|
|
||||||
13 --- 46
|
|
||||||
13 --- 47
|
|
||||||
13 --- 48
|
|
||||||
13 --- 49
|
|
||||||
13 --- 50
|
|
||||||
13 --- 51
|
|
||||||
13 --- 52
|
|
||||||
13 --- 53
|
|
||||||
13 --- 54
|
|
||||||
13 --- 55
|
|
||||||
13 --- 56
|
|
||||||
13 --- 57
|
|
||||||
13 --- 58
|
|
||||||
13 --- 59
|
|
||||||
13 --- 60
|
|
||||||
13 --- 61
|
|
||||||
13 --- 62
|
|
||||||
13 --- 63
|
|
||||||
13 --- 64
|
|
||||||
13 --- 65
|
|
||||||
13 --- 66
|
|
||||||
13 --- 67
|
|
||||||
13 --- 68
|
|
||||||
13 --- 69
|
|
||||||
13 --- 70
|
|
||||||
13 --- 71
|
|
||||||
13 --- 72
|
|
||||||
13 --- 73
|
|
||||||
13 --- 74
|
|
||||||
13 --- 75
|
|
||||||
13 --- 76
|
|
||||||
13 --- 77
|
|
||||||
13 --- 78
|
|
||||||
13 --- 79
|
|
||||||
13 --- 80
|
|
||||||
13 --- 81
|
|
||||||
13 --- 82
|
|
||||||
13 --- 83
|
|
||||||
13 --- 84
|
|
||||||
13 --- 85
|
|
||||||
13 --- 86
|
|
||||||
13 --- 87
|
|
||||||
13 --- 88
|
|
||||||
13 --- 89
|
|
||||||
13 --- 90
|
|
||||||
13 --- 91
|
|
||||||
13 --- 92
|
|
||||||
13 --- 93
|
|
||||||
13 --- 94
|
|
||||||
13 --- 95
|
|
||||||
13 --- 96
|
|
||||||
13 --- 97
|
|
||||||
13 --- 98
|
|
||||||
13 --- 99
|
|
||||||
13 --- 100
|
|
||||||
13 --- 101
|
|
||||||
13 --- 102
|
|
||||||
13 --- 103
|
|
||||||
13 --- 104
|
|
||||||
13 --- 105
|
|
||||||
13 --- 106
|
|
||||||
13 --- 107
|
|
||||||
13 --- 108
|
|
||||||
13 --- 109
|
|
||||||
13 --- 110
|
|
||||||
13 --- 111
|
|
||||||
13 --- 112
|
|
||||||
13 --- 113
|
|
||||||
13 --- 114
|
|
||||||
13 --- 115
|
|
||||||
13 --- 116
|
|
||||||
13 --- 117
|
|
||||||
13 --- 118
|
|
||||||
13 --- 119
|
|
||||||
13 --- 120
|
|
||||||
13 --- 121
|
|
||||||
13 --- 122
|
|
||||||
13 --- 123
|
|
||||||
13 --- 124
|
|
||||||
13 --- 125
|
|
||||||
13 --- 126
|
|
||||||
13 --- 127
|
|
||||||
13 --- 128
|
|
||||||
13 --- 129
|
|
||||||
13 --- 130
|
|
||||||
13 --- 131
|
|
||||||
13 --- 132
|
|
||||||
13 --- 133
|
|
||||||
13 --- 134
|
|
||||||
13 --- 135
|
|
||||||
13 --- 136
|
|
||||||
13 --- 137
|
|
||||||
13 --- 138
|
|
||||||
13 --- 139
|
|
||||||
13 --- 140
|
|
||||||
13 --- 141
|
|
||||||
13 --- 142
|
|
||||||
13 --- 143
|
|
||||||
13 --- 144
|
|
||||||
13 --- 145
|
|
||||||
13 --- 146
|
|
||||||
13 --- 147
|
|
||||||
13 --- 148
|
|
||||||
13 --- 149
|
|
||||||
13 --- 150
|
|
||||||
13 --- 151
|
|
||||||
13 --- 152
|
|
||||||
13 --- 153
|
|
||||||
13 --- 154
|
|
||||||
13 --- 155
|
|
||||||
13 --- 156
|
|
||||||
13 --- 157
|
|
||||||
13 --- 158
|
|
||||||
13 --- 159
|
|
||||||
13 --- 160
|
|
||||||
13 --- 161
|
|
||||||
13 --- 162
|
|
||||||
13 --- 163
|
|
||||||
13 --- 164
|
|
||||||
13 --- 165
|
|
||||||
13 --- 166
|
|
||||||
13 --- 167
|
|
||||||
13 --- 168
|
|
||||||
13 --- 169
|
|
||||||
13 --- 170
|
|
||||||
13 --- 171
|
|
||||||
13 --- 172
|
|
||||||
13 --- 173
|
|
||||||
13 --- 174
|
|
||||||
13 --- 175
|
|
||||||
13 --- 176
|
|
||||||
13 --- 177
|
|
||||||
13 --- 178
|
|
||||||
13 --- 179
|
|
||||||
13 --- 180
|
|
||||||
13 --- 181
|
|
||||||
13 --- 182
|
|
||||||
13 --- 183
|
|
||||||
13 --- 184
|
|
||||||
13 --- 185
|
|
||||||
13 --- 186
|
|
||||||
13 --- 187
|
|
||||||
13 --- 188
|
|
||||||
13 --- 189
|
|
||||||
13 --- 190
|
|
||||||
13 --- 191
|
|
||||||
13 --- 192
|
|
||||||
13 --- 193
|
|
||||||
13 --- 194
|
|
||||||
13 --- 195
|
|
||||||
13 --- 196
|
|
||||||
13 --- 197
|
|
||||||
13 --- 198
|
|
||||||
13 --- 199
|
|
||||||
13 --- 200
|
|
||||||
13 --- 201
|
|
||||||
13 --- 202
|
|
||||||
13 --- 203
|
|
||||||
13 --- 204
|
|
||||||
13 --- 205
|
|
||||||
13 --- 206
|
|
||||||
13 --- 207
|
|
||||||
13 --- 208
|
|
||||||
13 --- 209
|
|
||||||
13 --- 210
|
|
||||||
13 --- 211
|
|
||||||
13 --- 212
|
|
||||||
13 --- 213
|
|
||||||
13 --- 214
|
|
||||||
13 --- 215
|
|
||||||
13 --- 216
|
|
||||||
13 --- 217
|
|
||||||
13 ---- 219
|
|
||||||
13 --- 218
|
|
||||||
220 --- 221
|
|
||||||
220 --- 222
|
|
||||||
220 --- 223
|
|
||||||
220 --- 224
|
|
||||||
220 --- 225
|
|
||||||
220 --- 226
|
|
||||||
220 ---- 228
|
|
||||||
220 --- 227
|
|
||||||
221 --- 232
|
|
||||||
221 --- 239
|
|
||||||
221 --- 240
|
|
||||||
222 --- 231
|
|
||||||
222 --- 237
|
|
||||||
222 --- 238
|
|
||||||
223 --- 230
|
|
||||||
223 --- 235
|
|
||||||
223 --- 236
|
|
||||||
225 --- 229
|
|
||||||
225 --- 233
|
|
||||||
225 --- 234
|
|
||||||
228 --- 229
|
|
||||||
228 --- 230
|
|
||||||
228 --- 231
|
|
||||||
228 --- 232
|
|
||||||
228 --- 233
|
|
||||||
228 --- 234
|
|
||||||
228 --- 235
|
|
||||||
228 --- 236
|
|
||||||
228 --- 237
|
|
||||||
228 --- 238
|
|
||||||
228 --- 239
|
|
||||||
228 --- 240
|
|
||||||
9 <--x 241
|
|
||||||
```
|
|
File diff suppressed because it is too large
Load Diff
@ -1,117 +0,0 @@
|
|||||||
@(lengthUnit = m)
|
|
||||||
import "../../e2e/executor/inputs/2-5-long-m8-chc-screw.stl" as screw
|
|
||||||
|
|
||||||
// Set units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
myScrew = screw
|
|
||||||
|
|
||||||
|
|
||||||
surface001 = startSketchOn(XY)
|
|
||||||
|
|
||||||
// Define parameters
|
|
||||||
nTeeth = 21
|
|
||||||
module = 0.5
|
|
||||||
pitchDiameter = module * nTeeth
|
|
||||||
pressureAngle = 20
|
|
||||||
addendum = module
|
|
||||||
deddendum = 1.25 * module
|
|
||||||
baseDiameter = pitchDiameter * cos(toRadians(pressureAngle))
|
|
||||||
tipDiameter = pitchDiameter + 2 * module
|
|
||||||
gearHeight = 3
|
|
||||||
|
|
||||||
// Interpolate points along the involute curve
|
|
||||||
cmo = 101
|
|
||||||
rs = map([0..cmo], fn(i) {
|
|
||||||
return baseDiameter / 2 + i / cmo * (tipDiameter - baseDiameter) / 2
|
|
||||||
})
|
|
||||||
|
|
||||||
// Calculate operating pressure angle
|
|
||||||
angles = map(rs, fn(r) {
|
|
||||||
return toDegrees( acos(baseDiameter / 2 / r))
|
|
||||||
})
|
|
||||||
|
|
||||||
// Calculate the involute function
|
|
||||||
invas = map(angles, fn(a) {
|
|
||||||
return tan(toRadians(a)) - toRadians(a)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Map the involute curve
|
|
||||||
xs = map([0..cmo], fn(i) {
|
|
||||||
return rs[i] * cos(invas[i])
|
|
||||||
})
|
|
||||||
|
|
||||||
ys = map([0..cmo], fn(i) {
|
|
||||||
return rs[i] * sin(invas[i])
|
|
||||||
})
|
|
||||||
|
|
||||||
// Extrude the gear body
|
|
||||||
body = startSketchOn(XY)
|
|
||||||
|> circle(center = [0, 0], radius = baseDiameter / 2)
|
|
||||||
|> extrude(length = gearHeight)
|
|
||||||
|
|
||||||
toothAngle = 360 / nTeeth / 1.5
|
|
||||||
|
|
||||||
// Plot the involute curve
|
|
||||||
fn leftInvolute(i, sg) {
|
|
||||||
j = 100 - i // iterate backwards
|
|
||||||
return line(sg, endAbsolute = [xs[j], ys[j]])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rightInvolute(i, sg) {
|
|
||||||
x = rs[i] * cos(toRadians(-toothAngle + toDegrees(atan(ys[i] / xs[i]))))
|
|
||||||
y = -rs[i] * sin(toRadians(-toothAngle + toDegrees(atan(ys[i] / xs[i]))))
|
|
||||||
return line(sg, endAbsolute = [x, y])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw gear teeth
|
|
||||||
start = startSketchOn(XY)
|
|
||||||
|> startProfileAt([xs[101], ys[101]], %)
|
|
||||||
teeth = reduce([0..100], start, leftInvolute)
|
|
||||||
|> arc({
|
|
||||||
angleStart = 0,
|
|
||||||
angleEnd = toothAngle,
|
|
||||||
radius = baseDiameter / 2
|
|
||||||
}, %)
|
|
||||||
|> reduce([1..101], %, rightInvolute)
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = gearHeight)
|
|
||||||
|> patternCircular3d(
|
|
||||||
axis = [0, 0, 1],
|
|
||||||
center = [0, 0, 0],
|
|
||||||
instances = nTeeth,
|
|
||||||
arcDegrees = 360,
|
|
||||||
rotateDuplicates = true,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Define the constants of the keyway and the bore hole
|
|
||||||
keywayWidth = 0.250
|
|
||||||
keywayDepth = keywayWidth / 2
|
|
||||||
holeDiam = 2
|
|
||||||
holeRadius = 1
|
|
||||||
startAngle = asin(keywayWidth / 2 / holeRadius)
|
|
||||||
|
|
||||||
// Sketch the keyway and center hole and extrude
|
|
||||||
keyWay = startSketchOn(body, face = END)
|
|
||||||
|> startProfileAt([
|
|
||||||
holeRadius * cos(startAngle),
|
|
||||||
holeRadius * sin(startAngle)
|
|
||||||
], %)
|
|
||||||
|> xLine(length = keywayDepth)
|
|
||||||
|> yLine(length = -keywayWidth)
|
|
||||||
|> xLine(length = -keywayDepth)
|
|
||||||
|> arc({
|
|
||||||
angleEnd = 180,
|
|
||||||
angleStart = -1 * toDegrees(startAngle) + 360,
|
|
||||||
radius = holeRadius
|
|
||||||
}, %)
|
|
||||||
|> arc({
|
|
||||||
angleEnd = toDegrees(startAngle),
|
|
||||||
angleStart = 180,
|
|
||||||
radius = holeRadius
|
|
||||||
}, %)
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = -gearHeight)
|
|
||||||
|
|
||||||
myScrew
|
|
||||||
|> translate(y=10)
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 55 KiB |
@ -1,120 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of unparsing import_async.kcl
|
|
||||||
---
|
|
||||||
// Set units
|
|
||||||
@settings(defaultLengthUnit = mm)
|
|
||||||
|
|
||||||
@(lengthUnit = m)
|
|
||||||
import "../../e2e/executor/inputs/2-5-long-m8-chc-screw.stl" as screw
|
|
||||||
|
|
||||||
myScrew = screw
|
|
||||||
|
|
||||||
surface001 = startSketchOn(XY)
|
|
||||||
|
|
||||||
// Define parameters
|
|
||||||
nTeeth = 21
|
|
||||||
module = 0.5
|
|
||||||
pitchDiameter = module * nTeeth
|
|
||||||
pressureAngle = 20
|
|
||||||
addendum = module
|
|
||||||
deddendum = 1.25 * module
|
|
||||||
baseDiameter = pitchDiameter * cos(toRadians(pressureAngle))
|
|
||||||
tipDiameter = pitchDiameter + 2 * module
|
|
||||||
gearHeight = 3
|
|
||||||
|
|
||||||
// Interpolate points along the involute curve
|
|
||||||
cmo = 101
|
|
||||||
rs = map([0..cmo], fn(i) {
|
|
||||||
return baseDiameter / 2 + i / cmo * (tipDiameter - baseDiameter) / 2
|
|
||||||
})
|
|
||||||
|
|
||||||
// Calculate operating pressure angle
|
|
||||||
angles = map(rs, fn(r) {
|
|
||||||
return toDegrees( acos(baseDiameter / 2 / r))
|
|
||||||
})
|
|
||||||
|
|
||||||
// Calculate the involute function
|
|
||||||
invas = map(angles, fn(a) {
|
|
||||||
return tan(toRadians(a)) - toRadians(a)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Map the involute curve
|
|
||||||
xs = map([0..cmo], fn(i) {
|
|
||||||
return rs[i] * cos(invas[i])
|
|
||||||
})
|
|
||||||
|
|
||||||
ys = map([0..cmo], fn(i) {
|
|
||||||
return rs[i] * sin(invas[i])
|
|
||||||
})
|
|
||||||
|
|
||||||
// Extrude the gear body
|
|
||||||
body = startSketchOn(XY)
|
|
||||||
|> circle(center = [0, 0], radius = baseDiameter / 2)
|
|
||||||
|> extrude(length = gearHeight)
|
|
||||||
|
|
||||||
toothAngle = 360 / nTeeth / 1.5
|
|
||||||
|
|
||||||
// Plot the involute curve
|
|
||||||
fn leftInvolute(i, sg) {
|
|
||||||
j = 100 - i // iterate backwards
|
|
||||||
return line(sg, endAbsolute = [xs[j], ys[j]])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rightInvolute(i, sg) {
|
|
||||||
x = rs[i] * cos(toRadians(-toothAngle + toDegrees(atan(ys[i] / xs[i]))))
|
|
||||||
y = -rs[i] * sin(toRadians(-toothAngle + toDegrees(atan(ys[i] / xs[i]))))
|
|
||||||
return line(sg, endAbsolute = [x, y])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw gear teeth
|
|
||||||
start = startSketchOn(XY)
|
|
||||||
|> startProfileAt([xs[101], ys[101]], %)
|
|
||||||
teeth = reduce([0..100], start, leftInvolute)
|
|
||||||
|> arc({
|
|
||||||
angleStart = 0,
|
|
||||||
angleEnd = toothAngle,
|
|
||||||
radius = baseDiameter / 2
|
|
||||||
}, %)
|
|
||||||
|> reduce([1..101], %, rightInvolute)
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = gearHeight)
|
|
||||||
|> patternCircular3d(
|
|
||||||
axis = [0, 0, 1],
|
|
||||||
center = [0, 0, 0],
|
|
||||||
instances = nTeeth,
|
|
||||||
arcDegrees = 360,
|
|
||||||
rotateDuplicates = true,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Define the constants of the keyway and the bore hole
|
|
||||||
keywayWidth = 0.250
|
|
||||||
keywayDepth = keywayWidth / 2
|
|
||||||
holeDiam = 2
|
|
||||||
holeRadius = 1
|
|
||||||
startAngle = asin(keywayWidth / 2 / holeRadius)
|
|
||||||
|
|
||||||
// Sketch the keyway and center hole and extrude
|
|
||||||
keyWay = startSketchOn(body, face = END)
|
|
||||||
|> startProfileAt([
|
|
||||||
holeRadius * cos(startAngle),
|
|
||||||
holeRadius * sin(startAngle)
|
|
||||||
], %)
|
|
||||||
|> xLine(length = keywayDepth)
|
|
||||||
|> yLine(length = -keywayWidth)
|
|
||||||
|> xLine(length = -keywayDepth)
|
|
||||||
|> arc({
|
|
||||||
angleEnd = 180,
|
|
||||||
angleStart = -1 * toDegrees(startAngle) + 360,
|
|
||||||
radius = holeRadius
|
|
||||||
}, %)
|
|
||||||
|> arc({
|
|
||||||
angleEnd = toDegrees(startAngle),
|
|
||||||
angleStart = 180,
|
|
||||||
radius = holeRadius
|
|
||||||
}, %)
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = -gearHeight)
|
|
||||||
|
|
||||||
myScrew
|
|
||||||
|> translate(y = 10)
|
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart axial-fan.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
@ -1,754 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
subgraph path2 [Path]
|
|
||||||
2["Path<br>[323, 370, 5]"]
|
|
||||||
3["Segment<br>[376, 444, 5]"]
|
|
||||||
4["Segment<br>[450, 550, 5]"]
|
|
||||||
5["Segment<br>[556, 673, 5]"]
|
|
||||||
6["Segment<br>[679, 764, 5]"]
|
|
||||||
7["Segment<br>[770, 777, 5]"]
|
|
||||||
8[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path9 [Path]
|
|
||||||
9["Path<br>[788, 823, 5]"]
|
|
||||||
10["Segment<br>[788, 823, 5]"]
|
|
||||||
11[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path12 [Path]
|
|
||||||
12["Path<br>[838, 985, 5]"]
|
|
||||||
13["Segment<br>[838, 985, 5]"]
|
|
||||||
14[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path15 [Path]
|
|
||||||
15["Path<br>[1000, 1148, 5]"]
|
|
||||||
16["Segment<br>[1000, 1148, 5]"]
|
|
||||||
17[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path18 [Path]
|
|
||||||
18["Path<br>[1163, 1311, 5]"]
|
|
||||||
19["Segment<br>[1163, 1311, 5]"]
|
|
||||||
20[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path21 [Path]
|
|
||||||
21["Path<br>[1326, 1475, 5]"]
|
|
||||||
22["Segment<br>[1326, 1475, 5]"]
|
|
||||||
23[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path39 [Path]
|
|
||||||
39["Path<br>[1646, 1702, 5]"]
|
|
||||||
40["Segment<br>[1708, 1773, 5]"]
|
|
||||||
41["Segment<br>[1779, 1831, 5]"]
|
|
||||||
42["Segment<br>[1837, 1888, 5]"]
|
|
||||||
43["Segment<br>[1894, 1946, 5]"]
|
|
||||||
44["Segment<br>[1952, 2018, 5]"]
|
|
||||||
45["Segment<br>[2024, 2076, 5]"]
|
|
||||||
46["Segment<br>[2082, 2114, 5]"]
|
|
||||||
47["Segment<br>[2120, 2185, 5]"]
|
|
||||||
48["Segment<br>[2191, 2198, 5]"]
|
|
||||||
49[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path78 [Path]
|
|
||||||
78["Path<br>[2547, 2660, 5]"]
|
|
||||||
79["Segment<br>[2666, 2721, 5]"]
|
|
||||||
80["Segment<br>[2727, 2762, 5]"]
|
|
||||||
81["Segment<br>[2768, 2823, 5]"]
|
|
||||||
82["Segment<br>[2829, 2865, 5]"]
|
|
||||||
83["Segment<br>[2871, 2926, 5]"]
|
|
||||||
84["Segment<br>[2932, 2968, 5]"]
|
|
||||||
85["Segment<br>[2974, 3029, 5]"]
|
|
||||||
86["Segment<br>[3035, 3091, 5]"]
|
|
||||||
end
|
|
||||||
subgraph path113 [Path]
|
|
||||||
113["Path<br>[3240, 3291, 5]"]
|
|
||||||
114["Segment<br>[3240, 3291, 5]"]
|
|
||||||
115[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path120 [Path]
|
|
||||||
120["Path<br>[3470, 3529, 5]"]
|
|
||||||
121["Segment<br>[3535, 3603, 5]"]
|
|
||||||
122["Segment<br>[3609, 3709, 5]"]
|
|
||||||
123["Segment<br>[3715, 3832, 5]"]
|
|
||||||
124["Segment<br>[3838, 3923, 5]"]
|
|
||||||
125["Segment<br>[3929, 3936, 5]"]
|
|
||||||
126[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path127 [Path]
|
|
||||||
127["Path<br>[3947, 3998, 5]"]
|
|
||||||
128["Segment<br>[3947, 3998, 5]"]
|
|
||||||
129[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path130 [Path]
|
|
||||||
130["Path<br>[4013, 4160, 5]"]
|
|
||||||
131["Segment<br>[4013, 4160, 5]"]
|
|
||||||
132[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path133 [Path]
|
|
||||||
133["Path<br>[4175, 4323, 5]"]
|
|
||||||
134["Segment<br>[4175, 4323, 5]"]
|
|
||||||
135[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path136 [Path]
|
|
||||||
136["Path<br>[4338, 4486, 5]"]
|
|
||||||
137["Segment<br>[4338, 4486, 5]"]
|
|
||||||
138[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path139 [Path]
|
|
||||||
139["Path<br>[4501, 4650, 5]"]
|
|
||||||
140["Segment<br>[4501, 4650, 5]"]
|
|
||||||
141[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path157 [Path]
|
|
||||||
157["Path<br>[4795, 4833, 5]"]
|
|
||||||
158["Segment<br>[4795, 4833, 5]"]
|
|
||||||
159[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path165 [Path]
|
|
||||||
165["Path<br>[4906, 4942, 5]"]
|
|
||||||
166["Segment<br>[4906, 4942, 5]"]
|
|
||||||
167[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path181 [Path]
|
|
||||||
181["Path<br>[277, 327, 6]"]
|
|
||||||
182["Segment<br>[277, 327, 6]"]
|
|
||||||
183[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path191 [Path]
|
|
||||||
191["Path<br>[502, 537, 6]"]
|
|
||||||
192["Segment<br>[502, 537, 6]"]
|
|
||||||
193[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path203 [Path]
|
|
||||||
203["Path<br>[216, 255, 7]"]
|
|
||||||
204["Segment<br>[261, 291, 7]"]
|
|
||||||
205["Segment<br>[297, 336, 7]"]
|
|
||||||
206["Segment<br>[342, 366, 7]"]
|
|
||||||
207["Segment<br>[372, 396, 7]"]
|
|
||||||
208["Segment<br>[402, 443, 7]"]
|
|
||||||
209["Segment<br>[449, 487, 7]"]
|
|
||||||
210["Segment<br>[493, 516, 7]"]
|
|
||||||
211["Segment<br>[522, 539, 7]"]
|
|
||||||
212["Segment<br>[545, 566, 7]"]
|
|
||||||
213["Segment<br>[572, 659, 7]"]
|
|
||||||
214["Segment<br>[665, 702, 7]"]
|
|
||||||
215["Segment<br>[708, 745, 7]"]
|
|
||||||
216["Segment<br>[751, 758, 7]"]
|
|
||||||
217[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path243 [Path]
|
|
||||||
243["Path<br>[1100, 1212, 7]"]
|
|
||||||
244["Segment<br>[1220, 1330, 7]"]
|
|
||||||
245["Segment<br>[1338, 1672, 7]"]
|
|
||||||
246["Segment<br>[1680, 2016, 7]"]
|
|
||||||
247["Segment<br>[2024, 2255, 7]"]
|
|
||||||
248["Segment<br>[2263, 2270, 7]"]
|
|
||||||
249[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path251 [Path]
|
|
||||||
251["Path<br>[1100, 1212, 7]"]
|
|
||||||
252["Segment<br>[1220, 1330, 7]"]
|
|
||||||
253["Segment<br>[1338, 1672, 7]"]
|
|
||||||
254["Segment<br>[1680, 2016, 7]"]
|
|
||||||
255["Segment<br>[2024, 2255, 7]"]
|
|
||||||
256["Segment<br>[2263, 2270, 7]"]
|
|
||||||
257[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path259 [Path]
|
|
||||||
259["Path<br>[1100, 1212, 7]"]
|
|
||||||
264["Segment<br>[2263, 2270, 7]"]
|
|
||||||
265[Solid2d]
|
|
||||||
end
|
|
||||||
1["Plane<br>[300, 317, 5]"]
|
|
||||||
24["Sweep Extrusion<br>[1485, 1504, 5]"]
|
|
||||||
25[Wall]
|
|
||||||
26[Wall]
|
|
||||||
27[Wall]
|
|
||||||
28[Wall]
|
|
||||||
29["Cap Start"]
|
|
||||||
30["Cap End"]
|
|
||||||
31["SweepEdge Opposite"]
|
|
||||||
32["SweepEdge Adjacent"]
|
|
||||||
33["SweepEdge Opposite"]
|
|
||||||
34["SweepEdge Adjacent"]
|
|
||||||
35["SweepEdge Opposite"]
|
|
||||||
36["SweepEdge Adjacent"]
|
|
||||||
37["SweepEdge Opposite"]
|
|
||||||
38["SweepEdge Adjacent"]
|
|
||||||
50["Sweep Extrusion<br>[2338, 2358, 5]"]
|
|
||||||
51[Wall]
|
|
||||||
52[Wall]
|
|
||||||
53[Wall]
|
|
||||||
54[Wall]
|
|
||||||
55[Wall]
|
|
||||||
56[Wall]
|
|
||||||
57[Wall]
|
|
||||||
58[Wall]
|
|
||||||
59["SweepEdge Opposite"]
|
|
||||||
60["SweepEdge Adjacent"]
|
|
||||||
61["SweepEdge Opposite"]
|
|
||||||
62["SweepEdge Adjacent"]
|
|
||||||
63["SweepEdge Opposite"]
|
|
||||||
64["SweepEdge Adjacent"]
|
|
||||||
65["SweepEdge Opposite"]
|
|
||||||
66["SweepEdge Adjacent"]
|
|
||||||
67["SweepEdge Opposite"]
|
|
||||||
68["SweepEdge Adjacent"]
|
|
||||||
69["SweepEdge Opposite"]
|
|
||||||
70["SweepEdge Adjacent"]
|
|
||||||
71["SweepEdge Opposite"]
|
|
||||||
72["SweepEdge Adjacent"]
|
|
||||||
73["SweepEdge Opposite"]
|
|
||||||
74["SweepEdge Adjacent"]
|
|
||||||
75["Sweep Extrusion<br>[2338, 2358, 5]"]
|
|
||||||
76["Sweep Extrusion<br>[2338, 2358, 5]"]
|
|
||||||
77["Sweep Extrusion<br>[2338, 2358, 5]"]
|
|
||||||
87["Sweep Extrusion<br>[3097, 3132, 5]"]
|
|
||||||
88[Wall]
|
|
||||||
89[Wall]
|
|
||||||
90[Wall]
|
|
||||||
91[Wall]
|
|
||||||
92[Wall]
|
|
||||||
93[Wall]
|
|
||||||
94[Wall]
|
|
||||||
95[Wall]
|
|
||||||
96["Cap End"]
|
|
||||||
97["SweepEdge Opposite"]
|
|
||||||
98["SweepEdge Adjacent"]
|
|
||||||
99["SweepEdge Opposite"]
|
|
||||||
100["SweepEdge Adjacent"]
|
|
||||||
101["SweepEdge Opposite"]
|
|
||||||
102["SweepEdge Adjacent"]
|
|
||||||
103["SweepEdge Opposite"]
|
|
||||||
104["SweepEdge Adjacent"]
|
|
||||||
105["SweepEdge Opposite"]
|
|
||||||
106["SweepEdge Adjacent"]
|
|
||||||
107["SweepEdge Opposite"]
|
|
||||||
108["SweepEdge Adjacent"]
|
|
||||||
109["SweepEdge Opposite"]
|
|
||||||
110["SweepEdge Adjacent"]
|
|
||||||
111["SweepEdge Opposite"]
|
|
||||||
112["SweepEdge Adjacent"]
|
|
||||||
116["Sweep Extrusion<br>[3297, 3335, 5]"]
|
|
||||||
117[Wall]
|
|
||||||
118["SweepEdge Opposite"]
|
|
||||||
119["SweepEdge Adjacent"]
|
|
||||||
142["Sweep Extrusion<br>[4660, 4679, 5]"]
|
|
||||||
143[Wall]
|
|
||||||
144[Wall]
|
|
||||||
145[Wall]
|
|
||||||
146[Wall]
|
|
||||||
147["Cap Start"]
|
|
||||||
148["Cap End"]
|
|
||||||
149["SweepEdge Opposite"]
|
|
||||||
150["SweepEdge Adjacent"]
|
|
||||||
151["SweepEdge Opposite"]
|
|
||||||
152["SweepEdge Adjacent"]
|
|
||||||
153["SweepEdge Opposite"]
|
|
||||||
154["SweepEdge Adjacent"]
|
|
||||||
155["SweepEdge Opposite"]
|
|
||||||
156["SweepEdge Adjacent"]
|
|
||||||
160["Sweep Extrusion<br>[4839, 4859, 5]"]
|
|
||||||
161[Wall]
|
|
||||||
162["Cap End"]
|
|
||||||
163["SweepEdge Opposite"]
|
|
||||||
164["SweepEdge Adjacent"]
|
|
||||||
168["Sweep Extrusion<br>[4948, 4969, 5]"]
|
|
||||||
169[Wall]
|
|
||||||
170["SweepEdge Opposite"]
|
|
||||||
171["SweepEdge Adjacent"]
|
|
||||||
172["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
173["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
174["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
175["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
176["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
177["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
178["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
179["EdgeCut Fillet<br>[5010, 5521, 5]"]
|
|
||||||
180["Plane<br>[204, 231, 6]"]
|
|
||||||
184["Sweep Extrusion<br>[333, 353, 6]"]
|
|
||||||
185[Wall]
|
|
||||||
186["Cap Start"]
|
|
||||||
187["Cap End"]
|
|
||||||
188["SweepEdge Opposite"]
|
|
||||||
189["SweepEdge Adjacent"]
|
|
||||||
190["Plane<br>[467, 495, 6]"]
|
|
||||||
194["Sweep Extrusion<br>[543, 564, 6]"]
|
|
||||||
195[Wall]
|
|
||||||
196["Cap Start"]
|
|
||||||
197["Cap End"]
|
|
||||||
198["SweepEdge Opposite"]
|
|
||||||
199["SweepEdge Adjacent"]
|
|
||||||
200["EdgeCut Fillet<br>[394, 452, 6]"]
|
|
||||||
201["EdgeCut Fillet<br>[394, 452, 6]"]
|
|
||||||
202["Plane<br>[193, 210, 7]"]
|
|
||||||
218["Sweep Revolve<br>[764, 846, 7]"]
|
|
||||||
219[Wall]
|
|
||||||
220[Wall]
|
|
||||||
221[Wall]
|
|
||||||
222[Wall]
|
|
||||||
223[Wall]
|
|
||||||
224[Wall]
|
|
||||||
225[Wall]
|
|
||||||
226[Wall]
|
|
||||||
227[Wall]
|
|
||||||
228[Wall]
|
|
||||||
229[Wall]
|
|
||||||
230[Wall]
|
|
||||||
231["SweepEdge Adjacent"]
|
|
||||||
232["SweepEdge Adjacent"]
|
|
||||||
233["SweepEdge Adjacent"]
|
|
||||||
234["SweepEdge Adjacent"]
|
|
||||||
235["SweepEdge Adjacent"]
|
|
||||||
236["SweepEdge Adjacent"]
|
|
||||||
237["SweepEdge Adjacent"]
|
|
||||||
238["SweepEdge Adjacent"]
|
|
||||||
239["SweepEdge Adjacent"]
|
|
||||||
240["SweepEdge Adjacent"]
|
|
||||||
241["SweepEdge Adjacent"]
|
|
||||||
242["Plane<br>[1053, 1091, 7]"]
|
|
||||||
250["Plane<br>[1053, 1091, 7]"]
|
|
||||||
258["Plane<br>[1053, 1091, 7]"]
|
|
||||||
260["SweepEdge Opposite"]
|
|
||||||
261["SweepEdge Opposite"]
|
|
||||||
262["SweepEdge Opposite"]
|
|
||||||
263["SweepEdge Opposite"]
|
|
||||||
266["Sweep Loft<br>[2389, 2509, 7]"]
|
|
||||||
267[Wall]
|
|
||||||
268[Wall]
|
|
||||||
269[Wall]
|
|
||||||
270[Wall]
|
|
||||||
271["Cap End"]
|
|
||||||
272["Cap End"]
|
|
||||||
273["SweepEdge Adjacent"]
|
|
||||||
274["SweepEdge Adjacent"]
|
|
||||||
275["SweepEdge Adjacent"]
|
|
||||||
276["SweepEdge Adjacent"]
|
|
||||||
277["StartSketchOnFace<br>[1597, 1640, 5]"]
|
|
||||||
278["StartSketchOnFace<br>[2498, 2541, 5]"]
|
|
||||||
279["StartSketchOnFace<br>[3197, 3234, 5]"]
|
|
||||||
280["StartSketchOnFace<br>[3421, 3458, 5]"]
|
|
||||||
281["StartSketchOnFace<br>[4746, 4789, 5]"]
|
|
||||||
282["StartSketchOnFace<br>[4861, 4900, 5]"]
|
|
||||||
283["StartSketchOnPlane<br>[244, 271, 6]"]
|
|
||||||
284["StartSketchOnPlane<br>[453, 496, 6]"]
|
|
||||||
285["StartSketchOnPlane<br>[1039, 1092, 7]"]
|
|
||||||
286["StartSketchOnPlane<br>[1039, 1092, 7]"]
|
|
||||||
287["StartSketchOnPlane<br>[1039, 1092, 7]"]
|
|
||||||
1 --- 2
|
|
||||||
1 --- 9
|
|
||||||
1 --- 12
|
|
||||||
1 --- 15
|
|
||||||
1 --- 18
|
|
||||||
1 --- 21
|
|
||||||
2 --- 3
|
|
||||||
2 --- 4
|
|
||||||
2 --- 5
|
|
||||||
2 --- 6
|
|
||||||
2 --- 7
|
|
||||||
2 ---- 24
|
|
||||||
2 --- 8
|
|
||||||
3 --- 25
|
|
||||||
3 --- 31
|
|
||||||
3 --- 32
|
|
||||||
4 --- 26
|
|
||||||
4 --- 33
|
|
||||||
4 --- 34
|
|
||||||
5 --- 27
|
|
||||||
5 --- 35
|
|
||||||
5 --- 36
|
|
||||||
6 --- 28
|
|
||||||
6 --- 37
|
|
||||||
6 --- 38
|
|
||||||
9 --- 10
|
|
||||||
9 --- 11
|
|
||||||
12 --- 13
|
|
||||||
12 --- 14
|
|
||||||
15 --- 16
|
|
||||||
15 --- 17
|
|
||||||
18 --- 19
|
|
||||||
18 --- 20
|
|
||||||
21 --- 22
|
|
||||||
21 --- 23
|
|
||||||
24 --- 25
|
|
||||||
24 --- 26
|
|
||||||
24 --- 27
|
|
||||||
24 --- 28
|
|
||||||
24 --- 29
|
|
||||||
24 --- 30
|
|
||||||
24 --- 31
|
|
||||||
24 --- 32
|
|
||||||
24 --- 33
|
|
||||||
24 --- 34
|
|
||||||
24 --- 35
|
|
||||||
24 --- 36
|
|
||||||
24 --- 37
|
|
||||||
24 --- 38
|
|
||||||
30 --- 39
|
|
||||||
30 --- 78
|
|
||||||
30 --- 157
|
|
||||||
39 --- 40
|
|
||||||
39 --- 41
|
|
||||||
39 --- 42
|
|
||||||
39 --- 43
|
|
||||||
39 --- 44
|
|
||||||
39 --- 45
|
|
||||||
39 --- 46
|
|
||||||
39 --- 47
|
|
||||||
39 --- 48
|
|
||||||
39 ---- 50
|
|
||||||
39 --- 49
|
|
||||||
40 --- 51
|
|
||||||
40 --- 59
|
|
||||||
40 --- 60
|
|
||||||
41 --- 52
|
|
||||||
41 --- 61
|
|
||||||
41 --- 62
|
|
||||||
42 --- 53
|
|
||||||
42 --- 63
|
|
||||||
42 --- 64
|
|
||||||
43 --- 54
|
|
||||||
43 --- 65
|
|
||||||
43 --- 66
|
|
||||||
44 --- 55
|
|
||||||
44 --- 67
|
|
||||||
44 --- 68
|
|
||||||
45 --- 56
|
|
||||||
45 --- 69
|
|
||||||
45 --- 70
|
|
||||||
46 --- 57
|
|
||||||
46 --- 71
|
|
||||||
46 --- 72
|
|
||||||
47 --- 58
|
|
||||||
47 --- 73
|
|
||||||
47 --- 74
|
|
||||||
50 --- 51
|
|
||||||
50 --- 52
|
|
||||||
50 --- 53
|
|
||||||
50 --- 54
|
|
||||||
50 --- 55
|
|
||||||
50 --- 56
|
|
||||||
50 --- 57
|
|
||||||
50 --- 58
|
|
||||||
50 --- 59
|
|
||||||
50 --- 60
|
|
||||||
50 --- 61
|
|
||||||
50 --- 62
|
|
||||||
50 --- 63
|
|
||||||
50 --- 64
|
|
||||||
50 --- 65
|
|
||||||
50 --- 66
|
|
||||||
50 --- 67
|
|
||||||
50 --- 68
|
|
||||||
50 --- 69
|
|
||||||
50 --- 70
|
|
||||||
50 --- 71
|
|
||||||
50 --- 72
|
|
||||||
50 --- 73
|
|
||||||
50 --- 74
|
|
||||||
78 --- 79
|
|
||||||
78 --- 80
|
|
||||||
78 --- 81
|
|
||||||
78 --- 82
|
|
||||||
78 --- 83
|
|
||||||
78 --- 84
|
|
||||||
78 --- 85
|
|
||||||
78 --- 86
|
|
||||||
78 ---- 87
|
|
||||||
79 --- 88
|
|
||||||
79 --- 97
|
|
||||||
79 --- 98
|
|
||||||
80 --- 89
|
|
||||||
80 --- 99
|
|
||||||
80 --- 100
|
|
||||||
81 --- 90
|
|
||||||
81 --- 101
|
|
||||||
81 --- 102
|
|
||||||
82 --- 91
|
|
||||||
82 --- 103
|
|
||||||
82 --- 104
|
|
||||||
83 --- 92
|
|
||||||
83 --- 105
|
|
||||||
83 --- 106
|
|
||||||
84 --- 93
|
|
||||||
84 --- 107
|
|
||||||
84 --- 108
|
|
||||||
85 --- 94
|
|
||||||
85 --- 109
|
|
||||||
85 --- 110
|
|
||||||
86 --- 95
|
|
||||||
86 --- 111
|
|
||||||
86 --- 112
|
|
||||||
87 --- 88
|
|
||||||
87 --- 89
|
|
||||||
87 --- 90
|
|
||||||
87 --- 91
|
|
||||||
87 --- 92
|
|
||||||
87 --- 93
|
|
||||||
87 --- 94
|
|
||||||
87 --- 95
|
|
||||||
87 --- 96
|
|
||||||
87 --- 97
|
|
||||||
87 --- 98
|
|
||||||
87 --- 99
|
|
||||||
87 --- 100
|
|
||||||
87 --- 101
|
|
||||||
87 --- 102
|
|
||||||
87 --- 103
|
|
||||||
87 --- 104
|
|
||||||
87 --- 105
|
|
||||||
87 --- 106
|
|
||||||
87 --- 107
|
|
||||||
87 --- 108
|
|
||||||
87 --- 109
|
|
||||||
87 --- 110
|
|
||||||
87 --- 111
|
|
||||||
87 --- 112
|
|
||||||
96 --- 113
|
|
||||||
96 --- 120
|
|
||||||
96 --- 127
|
|
||||||
96 --- 130
|
|
||||||
96 --- 133
|
|
||||||
96 --- 136
|
|
||||||
96 --- 139
|
|
||||||
113 --- 114
|
|
||||||
113 ---- 116
|
|
||||||
113 --- 115
|
|
||||||
114 --- 117
|
|
||||||
114 --- 118
|
|
||||||
114 --- 119
|
|
||||||
116 --- 117
|
|
||||||
116 --- 118
|
|
||||||
116 --- 119
|
|
||||||
120 --- 121
|
|
||||||
120 --- 122
|
|
||||||
120 --- 123
|
|
||||||
120 --- 124
|
|
||||||
120 --- 125
|
|
||||||
120 ---- 142
|
|
||||||
120 --- 126
|
|
||||||
121 --- 143
|
|
||||||
121 --- 149
|
|
||||||
121 --- 150
|
|
||||||
122 --- 144
|
|
||||||
122 --- 151
|
|
||||||
122 --- 152
|
|
||||||
123 --- 145
|
|
||||||
123 --- 153
|
|
||||||
123 --- 154
|
|
||||||
124 --- 146
|
|
||||||
124 --- 155
|
|
||||||
124 --- 156
|
|
||||||
127 --- 128
|
|
||||||
127 --- 129
|
|
||||||
130 --- 131
|
|
||||||
130 --- 132
|
|
||||||
133 --- 134
|
|
||||||
133 --- 135
|
|
||||||
136 --- 137
|
|
||||||
136 --- 138
|
|
||||||
139 --- 140
|
|
||||||
139 --- 141
|
|
||||||
142 --- 143
|
|
||||||
142 --- 144
|
|
||||||
142 --- 145
|
|
||||||
142 --- 146
|
|
||||||
142 --- 147
|
|
||||||
142 --- 148
|
|
||||||
142 --- 149
|
|
||||||
142 --- 150
|
|
||||||
142 --- 151
|
|
||||||
142 --- 152
|
|
||||||
142 --- 153
|
|
||||||
142 --- 154
|
|
||||||
142 --- 155
|
|
||||||
142 --- 156
|
|
||||||
157 --- 158
|
|
||||||
157 ---- 160
|
|
||||||
157 --- 159
|
|
||||||
158 --- 161
|
|
||||||
158 --- 163
|
|
||||||
158 --- 164
|
|
||||||
160 --- 161
|
|
||||||
160 --- 162
|
|
||||||
160 --- 163
|
|
||||||
160 --- 164
|
|
||||||
162 --- 165
|
|
||||||
165 --- 166
|
|
||||||
165 ---- 168
|
|
||||||
165 --- 167
|
|
||||||
166 --- 169
|
|
||||||
166 --- 170
|
|
||||||
166 --- 171
|
|
||||||
168 --- 169
|
|
||||||
168 --- 170
|
|
||||||
168 --- 171
|
|
||||||
32 <--x 172
|
|
||||||
34 <--x 173
|
|
||||||
36 <--x 174
|
|
||||||
38 <--x 175
|
|
||||||
150 <--x 176
|
|
||||||
152 <--x 177
|
|
||||||
154 <--x 178
|
|
||||||
156 <--x 179
|
|
||||||
180 --- 181
|
|
||||||
181 --- 182
|
|
||||||
181 ---- 184
|
|
||||||
181 --- 183
|
|
||||||
182 --- 185
|
|
||||||
182 --- 188
|
|
||||||
182 --- 189
|
|
||||||
182 --- 201
|
|
||||||
184 --- 185
|
|
||||||
184 --- 186
|
|
||||||
184 --- 187
|
|
||||||
184 --- 188
|
|
||||||
184 --- 189
|
|
||||||
190 --- 191
|
|
||||||
191 --- 192
|
|
||||||
191 ---- 194
|
|
||||||
191 --- 193
|
|
||||||
192 --- 195
|
|
||||||
192 --- 198
|
|
||||||
192 --- 199
|
|
||||||
194 --- 195
|
|
||||||
194 --- 196
|
|
||||||
194 --- 197
|
|
||||||
194 --- 198
|
|
||||||
194 --- 199
|
|
||||||
188 <--x 200
|
|
||||||
202 --- 203
|
|
||||||
203 --- 204
|
|
||||||
203 --- 205
|
|
||||||
203 --- 206
|
|
||||||
203 --- 207
|
|
||||||
203 --- 208
|
|
||||||
203 --- 209
|
|
||||||
203 --- 210
|
|
||||||
203 --- 211
|
|
||||||
203 --- 212
|
|
||||||
203 --- 213
|
|
||||||
203 --- 214
|
|
||||||
203 --- 215
|
|
||||||
203 --- 216
|
|
||||||
203 ---- 218
|
|
||||||
203 --- 217
|
|
||||||
204 --- 219
|
|
||||||
204 x--> 231
|
|
||||||
205 --- 220
|
|
||||||
205 --- 231
|
|
||||||
206 --- 221
|
|
||||||
206 --- 232
|
|
||||||
207 --- 222
|
|
||||||
207 --- 233
|
|
||||||
208 --- 223
|
|
||||||
208 --- 234
|
|
||||||
209 --- 224
|
|
||||||
209 --- 235
|
|
||||||
210 --- 225
|
|
||||||
210 --- 236
|
|
||||||
211 --- 226
|
|
||||||
211 --- 237
|
|
||||||
212 --- 227
|
|
||||||
212 --- 238
|
|
||||||
213 --- 228
|
|
||||||
213 --- 239
|
|
||||||
214 --- 229
|
|
||||||
214 --- 240
|
|
||||||
215 --- 230
|
|
||||||
215 --- 241
|
|
||||||
218 --- 219
|
|
||||||
218 --- 220
|
|
||||||
218 --- 221
|
|
||||||
218 --- 222
|
|
||||||
218 --- 223
|
|
||||||
218 --- 224
|
|
||||||
218 --- 225
|
|
||||||
218 --- 226
|
|
||||||
218 --- 227
|
|
||||||
218 --- 228
|
|
||||||
218 --- 229
|
|
||||||
218 --- 230
|
|
||||||
218 <--x 204
|
|
||||||
218 --- 231
|
|
||||||
218 <--x 205
|
|
||||||
218 <--x 206
|
|
||||||
218 --- 232
|
|
||||||
218 <--x 207
|
|
||||||
218 --- 233
|
|
||||||
218 <--x 208
|
|
||||||
218 --- 234
|
|
||||||
218 <--x 209
|
|
||||||
218 --- 235
|
|
||||||
218 <--x 210
|
|
||||||
218 --- 236
|
|
||||||
218 <--x 211
|
|
||||||
218 --- 237
|
|
||||||
218 <--x 212
|
|
||||||
218 --- 238
|
|
||||||
218 <--x 213
|
|
||||||
218 --- 239
|
|
||||||
218 <--x 214
|
|
||||||
218 --- 240
|
|
||||||
218 <--x 215
|
|
||||||
218 --- 241
|
|
||||||
242 --- 243
|
|
||||||
243 --- 244
|
|
||||||
243 --- 245
|
|
||||||
243 --- 246
|
|
||||||
243 --- 247
|
|
||||||
243 --- 248
|
|
||||||
243 ---- 266
|
|
||||||
243 --- 249
|
|
||||||
244 --- 267
|
|
||||||
244 --- 260
|
|
||||||
244 --- 273
|
|
||||||
245 --- 268
|
|
||||||
245 --- 261
|
|
||||||
245 --- 274
|
|
||||||
246 --- 269
|
|
||||||
246 --- 262
|
|
||||||
246 --- 275
|
|
||||||
247 --- 270
|
|
||||||
247 --- 263
|
|
||||||
247 --- 276
|
|
||||||
250 --- 251
|
|
||||||
251 --- 252
|
|
||||||
251 --- 253
|
|
||||||
251 --- 254
|
|
||||||
251 --- 255
|
|
||||||
251 --- 256
|
|
||||||
251 x---> 266
|
|
||||||
251 --- 257
|
|
||||||
258 --- 259
|
|
||||||
259 x--> 260
|
|
||||||
259 x--> 261
|
|
||||||
259 x--> 262
|
|
||||||
259 x--> 263
|
|
||||||
259 --- 264
|
|
||||||
259 x---> 266
|
|
||||||
259 --- 265
|
|
||||||
266 --- 260
|
|
||||||
266 --- 261
|
|
||||||
266 --- 262
|
|
||||||
266 --- 263
|
|
||||||
266 --- 267
|
|
||||||
266 --- 268
|
|
||||||
266 --- 269
|
|
||||||
266 --- 270
|
|
||||||
266 --- 271
|
|
||||||
266 --- 272
|
|
||||||
266 --- 273
|
|
||||||
266 --- 274
|
|
||||||
266 --- 275
|
|
||||||
266 --- 276
|
|
||||||
30 <--x 277
|
|
||||||
30 <--x 278
|
|
||||||
96 <--x 279
|
|
||||||
96 <--x 280
|
|
||||||
30 <--x 281
|
|
||||||
162 <--x 282
|
|
||||||
180 <--x 283
|
|
||||||
190 <--x 284
|
|
||||||
242 <--x 285
|
|
||||||
250 <--x 286
|
|
||||||
258 <--x 287
|
|
||||||
```
|
|
@ -1,220 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of parsing axial-fan.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"Ok": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"path": {
|
|
||||||
"type": "Kcl",
|
|
||||||
"filename": "fan-housing.kcl"
|
|
||||||
},
|
|
||||||
"preComments": [
|
|
||||||
"// Import all parts into assembly file"
|
|
||||||
],
|
|
||||||
"selector": {
|
|
||||||
"type": "None",
|
|
||||||
"alias": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "fanHousing",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ImportStatement",
|
|
||||||
"type": "ImportStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"path": {
|
|
||||||
"type": "Kcl",
|
|
||||||
"filename": "motor.kcl"
|
|
||||||
},
|
|
||||||
"selector": {
|
|
||||||
"type": "None",
|
|
||||||
"alias": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "motor",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ImportStatement",
|
|
||||||
"type": "ImportStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"path": {
|
|
||||||
"type": "Kcl",
|
|
||||||
"filename": "fan.kcl"
|
|
||||||
},
|
|
||||||
"selector": {
|
|
||||||
"type": "None",
|
|
||||||
"alias": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "fan",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ImportStatement",
|
|
||||||
"type": "ImportStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "fanHousing",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"preComments": [
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"// Produce the model for each imported part"
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "motor",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "fan",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"innerAttrs": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "settings",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"preComments": [
|
|
||||||
"// PC Fan",
|
|
||||||
"// A small axial fan, used to push or draw airflow over components to remove excess heat",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"// Set units"
|
|
||||||
],
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"key": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "defaultLengthUnit",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ObjectProperty",
|
|
||||||
"value": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "mm",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Annotation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nonCodeMeta": {
|
|
||||||
"nonCodeNodes": {},
|
|
||||||
"startNodes": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "NonCodeNode",
|
|
||||||
"value": {
|
|
||||||
"type": "newLine"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"start": 0
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Variables in memory after executing axial-fan.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"fan": {
|
|
||||||
"type": "Module",
|
|
||||||
"value": 7
|
|
||||||
},
|
|
||||||
"fanHousing": {
|
|
||||||
"type": "Module",
|
|
||||||
"value": 5
|
|
||||||
},
|
|
||||||
"motor": {
|
|
||||||
"type": "Module",
|
|
||||||
"value": 6
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 105 KiB |
@ -1,544 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact commands bottle.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "edge_lines_visible",
|
|
||||||
"hidden": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "make_plane",
|
|
||||||
"origin": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"x_axis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"y_axis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"size": 60.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "enable_sketch_mode",
|
|
||||||
"entity_id": "[uuid]",
|
|
||||||
"ortho": false,
|
|
||||||
"animated": false,
|
|
||||||
"adjust_camera": false,
|
|
||||||
"planar_normal": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "start_path"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "move_path_pen",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"to": {
|
|
||||||
"x": -62.5,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "sketch_mode_disable"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "extend_path",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"segment": {
|
|
||||||
"type": "line",
|
|
||||||
"end": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 26.6667,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"relative": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "extend_path",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"segment": {
|
|
||||||
"type": "arc_to",
|
|
||||||
"interior": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 40.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"x": 62.5,
|
|
||||||
"y": 26.6667,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"relative": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "extend_path",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"segment": {
|
|
||||||
"type": "line",
|
|
||||||
"end": {
|
|
||||||
"x": 62.5,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"relative": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "entity_mirror",
|
|
||||||
"ids": [
|
|
||||||
"[uuid]"
|
|
||||||
],
|
|
||||||
"axis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"point": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "entity_get_all_child_uuids",
|
|
||||||
"entity_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "close_path",
|
|
||||||
"path_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "enable_sketch_mode",
|
|
||||||
"entity_id": "[uuid]",
|
|
||||||
"ortho": false,
|
|
||||||
"animated": false,
|
|
||||||
"adjust_camera": false,
|
|
||||||
"planar_normal": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "extrude",
|
|
||||||
"target": "[uuid]",
|
|
||||||
"distance": 202.0,
|
|
||||||
"faces": null,
|
|
||||||
"opposite": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "sketch_mode_disable"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_bring_to_front",
|
|
||||||
"object_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_extrusion_face_info",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "enable_sketch_mode",
|
|
||||||
"entity_id": "[uuid]",
|
|
||||||
"ortho": false,
|
|
||||||
"animated": false,
|
|
||||||
"adjust_camera": false,
|
|
||||||
"planar_normal": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "start_path"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "move_path_pen",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"to": {
|
|
||||||
"x": 22.5,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "sketch_mode_disable"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "extend_path",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"segment": {
|
|
||||||
"type": "arc",
|
|
||||||
"center": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0
|
|
||||||
},
|
|
||||||
"radius": 22.5,
|
|
||||||
"start": {
|
|
||||||
"unit": "degrees",
|
|
||||||
"value": 0.0
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"unit": "degrees",
|
|
||||||
"value": 360.0
|
|
||||||
},
|
|
||||||
"relative": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "close_path",
|
|
||||||
"path_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "enable_sketch_mode",
|
|
||||||
"entity_id": "[uuid]",
|
|
||||||
"ortho": false,
|
|
||||||
"animated": false,
|
|
||||||
"adjust_camera": false,
|
|
||||||
"planar_normal": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "extrude",
|
|
||||||
"target": "[uuid]",
|
|
||||||
"distance": 18.0,
|
|
||||||
"faces": null,
|
|
||||||
"opposite": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "sketch_mode_disable"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_bring_to_front",
|
|
||||||
"object_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_extrusion_face_info",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_shell_face",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"face_ids": [
|
|
||||||
"[uuid]"
|
|
||||||
],
|
|
||||||
"shell_thickness": 4.0,
|
|
||||||
"hollow": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_set_material_params_pbr",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.0,
|
|
||||||
"g": 0.47058824,
|
|
||||||
"b": 0.7607843,
|
|
||||||
"a": 100.0
|
|
||||||
},
|
|
||||||
"metalness": 0.0,
|
|
||||||
"roughness": 0.0,
|
|
||||||
"ambient_occlusion": 0.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart bottle.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
@ -1,44 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
subgraph path2 [Path]
|
|
||||||
2["Path<br>[337, 378, 0]"]
|
|
||||||
3["Segment<br>[384, 415, 0]"]
|
|
||||||
4["Segment<br>[421, 528, 0]"]
|
|
||||||
5["Segment<br>[534, 556, 0]"]
|
|
||||||
6["Segment<br>[586, 593, 0]"]
|
|
||||||
7[Solid2d]
|
|
||||||
end
|
|
||||||
subgraph path10 [Path]
|
|
||||||
10["Path<br>[750, 800, 0]"]
|
|
||||||
11["Segment<br>[750, 800, 0]"]
|
|
||||||
12[Solid2d]
|
|
||||||
end
|
|
||||||
1["Plane<br>[314, 331, 0]"]
|
|
||||||
8["Sweep Extrusion<br>[599, 641, 0]"]
|
|
||||||
9["Plane<br>[750, 800, 0]"]
|
|
||||||
13["Sweep Extrusion<br>[806, 833, 0]"]
|
|
||||||
14[Wall]
|
|
||||||
15["Cap End"]
|
|
||||||
16["SweepEdge Opposite"]
|
|
||||||
17["SweepEdge Adjacent"]
|
|
||||||
18["StartSketchOnFace<br>[707, 744, 0]"]
|
|
||||||
1 --- 2
|
|
||||||
2 --- 3
|
|
||||||
2 --- 4
|
|
||||||
2 --- 5
|
|
||||||
2 --- 6
|
|
||||||
2 ---- 8
|
|
||||||
2 --- 7
|
|
||||||
9 --- 10
|
|
||||||
10 --- 11
|
|
||||||
10 ---- 13
|
|
||||||
10 --- 12
|
|
||||||
11 --- 14
|
|
||||||
11 --- 16
|
|
||||||
11 --- 17
|
|
||||||
13 --- 14
|
|
||||||
13 --- 15
|
|
||||||
13 --- 16
|
|
||||||
13 --- 17
|
|
||||||
9 <--x 18
|
|
||||||
```
|
|
File diff suppressed because it is too large
Load Diff
@ -1,152 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Operations executed bottle.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"planeOrSolid": {
|
|
||||||
"value": {
|
|
||||||
"type": "Plane",
|
|
||||||
"artifact_id": "[uuid]"
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "startSketchOn",
|
|
||||||
"sourceRange": [],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"length": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 202.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "extrude",
|
|
||||||
"sourceRange": [],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"value": {
|
|
||||||
"artifactId": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"face": {
|
|
||||||
"value": {
|
|
||||||
"type": "String",
|
|
||||||
"value": "end"
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "startSketchOn",
|
|
||||||
"sourceRange": [],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Solid",
|
|
||||||
"value": {
|
|
||||||
"artifactId": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"length": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 18.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "extrude",
|
|
||||||
"sourceRange": [],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"value": {
|
|
||||||
"artifactId": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"faces": {
|
|
||||||
"value": {
|
|
||||||
"type": "Array",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"type": "String",
|
|
||||||
"value": "end"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"thickness": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 4.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "shell",
|
|
||||||
"sourceRange": [],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Solid",
|
|
||||||
"value": {
|
|
||||||
"artifactId": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,817 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Variables in memory after executing bottle.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"bottleBody": {
|
|
||||||
"type": "Solid",
|
|
||||||
"value": {
|
|
||||||
"type": "Solid",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": [],
|
|
||||||
"sketch": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"p1": [
|
|
||||||
-62.5,
|
|
||||||
26.666666666666668
|
|
||||||
],
|
|
||||||
"p2": [
|
|
||||||
0.0,
|
|
||||||
40.0
|
|
||||||
],
|
|
||||||
"p3": [
|
|
||||||
62.5,
|
|
||||||
26.666666666666668
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"type": "ArcThreePoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "plane",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "XY",
|
|
||||||
"origin": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height": 202.0,
|
|
||||||
"startCapId": "[uuid]",
|
|
||||||
"endCapId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bottleHeight": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 220.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bottleLength": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 125.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bottleNeck": {
|
|
||||||
"type": "Solid",
|
|
||||||
"value": {
|
|
||||||
"type": "Solid",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"faceId": "[uuid]",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [],
|
|
||||||
"tag": null,
|
|
||||||
"type": "extrudeArc"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sketch": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"ccw": true,
|
|
||||||
"center": [
|
|
||||||
0.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"from": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"radius": 22.5,
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "Circle",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "face",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "end",
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"solid": {
|
|
||||||
"type": "Solid",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": [],
|
|
||||||
"sketch": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"p1": [
|
|
||||||
-62.5,
|
|
||||||
26.666666666666668
|
|
||||||
],
|
|
||||||
"p2": [
|
|
||||||
0.0,
|
|
||||||
40.0
|
|
||||||
],
|
|
||||||
"p3": [
|
|
||||||
62.5,
|
|
||||||
26.666666666666668
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"type": "ArcThreePoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "plane",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "XY",
|
|
||||||
"origin": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height": 202.0,
|
|
||||||
"startCapId": "[uuid]",
|
|
||||||
"endCapId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height": 18.0,
|
|
||||||
"startCapId": null,
|
|
||||||
"endCapId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bottleShell": {
|
|
||||||
"type": "Solid",
|
|
||||||
"value": {
|
|
||||||
"type": "Solid",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"faceId": "[uuid]",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [],
|
|
||||||
"tag": null,
|
|
||||||
"type": "extrudeArc"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sketch": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"ccw": true,
|
|
||||||
"center": [
|
|
||||||
0.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"from": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"radius": 22.5,
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "Circle",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "face",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "end",
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"solid": {
|
|
||||||
"type": "Solid",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": [],
|
|
||||||
"sketch": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"p1": [
|
|
||||||
-62.5,
|
|
||||||
26.666666666666668
|
|
||||||
],
|
|
||||||
"p2": [
|
|
||||||
0.0,
|
|
||||||
40.0
|
|
||||||
],
|
|
||||||
"p3": [
|
|
||||||
62.5,
|
|
||||||
26.666666666666668
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"type": "ArcThreePoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
62.5,
|
|
||||||
26.6667
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "plane",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "XY",
|
|
||||||
"origin": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0,
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
-62.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height": 202.0,
|
|
||||||
"startCapId": "[uuid]",
|
|
||||||
"endCapId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
22.5,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"height": 18.0,
|
|
||||||
"startCapId": null,
|
|
||||||
"endCapId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bottleWidth": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 80.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"neckDepth": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 18.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"neckDiameter": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 45.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"wallThickness": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 4.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 70 KiB |
Binary file not shown.
Before Width: | Height: | Size: 74 KiB |
@ -23,7 +23,6 @@ pub struct EngineConnection {
|
|||||||
batch: Arc<RwLock<Vec<(WebSocketRequest, kcl_lib::SourceRange)>>>,
|
batch: Arc<RwLock<Vec<(WebSocketRequest, kcl_lib::SourceRange)>>>,
|
||||||
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, kcl_lib::SourceRange)>>>,
|
batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, kcl_lib::SourceRange)>>>,
|
||||||
core_test: Arc<RwLock<String>>,
|
core_test: Arc<RwLock<String>>,
|
||||||
ids_of_async_commands: Arc<RwLock<IndexMap<Uuid, kcl_lib::SourceRange>>>,
|
|
||||||
/// The default planes for the scene.
|
/// The default planes for the scene.
|
||||||
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
|
||||||
stats: EngineStats,
|
stats: EngineStats,
|
||||||
@ -38,7 +37,6 @@ impl EngineConnection {
|
|||||||
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
batch_end: Arc::new(RwLock::new(IndexMap::new())),
|
||||||
core_test: result,
|
core_test: result,
|
||||||
default_planes: Default::default(),
|
default_planes: Default::default(),
|
||||||
ids_of_async_commands: Arc::new(RwLock::new(IndexMap::new())),
|
|
||||||
stats: Default::default(),
|
stats: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -381,10 +379,6 @@ impl kcl_lib::EngineManager for EngineConnection {
|
|||||||
Arc::new(RwLock::new(Vec::new()))
|
Arc::new(RwLock::new(Vec::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ids_of_async_commands(&self) -> Arc<RwLock<IndexMap<Uuid, kcl_lib::SourceRange>>> {
|
|
||||||
self.ids_of_async_commands.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
|
fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
|
||||||
self.default_planes.clone()
|
self.default_planes.clone()
|
||||||
}
|
}
|
||||||
@ -397,25 +391,6 @@ impl kcl_lib::EngineManager for EngineConnection {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn inner_fire_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: kcl_lib::SourceRange,
|
|
||||||
cmd: WebSocketRequest,
|
|
||||||
id_to_source_range: HashMap<Uuid, kcl_lib::SourceRange>,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
// Pop off the id we care about.
|
|
||||||
self.ids_of_async_commands.write().await.swap_remove(&id);
|
|
||||||
|
|
||||||
// Add the response to our responses.
|
|
||||||
let response = self
|
|
||||||
.inner_send_modeling_cmd(id, source_range, cmd, id_to_source_range)
|
|
||||||
.await?;
|
|
||||||
self.responses().write().await.insert(id, response);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn inner_send_modeling_cmd(
|
async fn inner_send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
|
@ -9,7 +9,6 @@ use wasm_bindgen::prelude::*;
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
engine: Arc<Box<dyn EngineManager>>,
|
engine: Arc<Box<dyn EngineManager>>,
|
||||||
response_context: Arc<kcl_lib::wasm_engine::ResponseContext>,
|
|
||||||
fs: Arc<FileManager>,
|
fs: Arc<FileManager>,
|
||||||
mock_engine: Arc<Box<dyn EngineManager>>,
|
mock_engine: Arc<Box<dyn EngineManager>>,
|
||||||
}
|
}
|
||||||
@ -23,10 +22,9 @@ impl Context {
|
|||||||
) -> Result<Self, JsValue> {
|
) -> Result<Self, JsValue> {
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
let response_context = Arc::new(kcl_lib::wasm_engine::ResponseContext::new());
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
engine: Arc::new(Box::new(
|
engine: Arc::new(Box::new(
|
||||||
kcl_lib::wasm_engine::EngineConnection::new(engine_manager, response_context.clone())
|
kcl_lib::wasm_engine::EngineConnection::new(engine_manager)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?,
|
.map_err(|e| format!("{:?}", e))?,
|
||||||
)),
|
)),
|
||||||
@ -36,7 +34,6 @@ impl Context {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?,
|
.map_err(|e| format!("{:?}", e))?,
|
||||||
)),
|
)),
|
||||||
response_context,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,12 +100,6 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a response to kcl lib's engine.
|
|
||||||
#[wasm_bindgen(js_name = sendResponse)]
|
|
||||||
pub async fn send_response(&self, data: js_sys::Uint8Array) -> Result<(), JsValue> {
|
|
||||||
self.response_context.send_response(data).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a program in mock mode.
|
/// Execute a program in mock mode.
|
||||||
#[wasm_bindgen(js_name = executeMock)]
|
#[wasm_bindgen(js_name = executeMock)]
|
||||||
pub async fn execute_mock(
|
pub async fn execute_mock(
|
||||||
|
@ -669,10 +669,7 @@ export class SceneEntities {
|
|||||||
variableDeclarationName: string
|
variableDeclarationName: string
|
||||||
}> {
|
}> {
|
||||||
const prepared = this.prepareTruncatedAst(sketchNodePaths, maybeModdedAst)
|
const prepared = this.prepareTruncatedAst(sketchNodePaths, maybeModdedAst)
|
||||||
if (err(prepared)) {
|
if (err(prepared)) return Promise.reject(prepared)
|
||||||
this.tearDownSketch({ removeAxis: false })
|
|
||||||
return Promise.reject(prepared)
|
|
||||||
}
|
|
||||||
const { truncatedAst, variableDeclarationName } = prepared
|
const { truncatedAst, variableDeclarationName } = prepared
|
||||||
|
|
||||||
const { execState } = await executeAstMock({
|
const { execState } = await executeAstMock({
|
||||||
@ -698,8 +695,6 @@ export class SceneEntities {
|
|||||||
const scale = this.sceneInfra.getClientSceneScaleFactor(dummy)
|
const scale = this.sceneInfra.getClientSceneScaleFactor(dummy)
|
||||||
|
|
||||||
const callbacks: (() => SegmentOverlayPayload | null)[] = []
|
const callbacks: (() => SegmentOverlayPayload | null)[] = []
|
||||||
this.sceneInfra.pauseRendering()
|
|
||||||
this.tearDownSketch({ removeAxis: false })
|
|
||||||
|
|
||||||
for (const sketchInfo of sketchesInfo) {
|
for (const sketchInfo of sketchesInfo) {
|
||||||
const { sketch } = sketchInfo
|
const { sketch } = sketchInfo
|
||||||
@ -771,11 +766,7 @@ export class SceneEntities {
|
|||||||
segPathToNode,
|
segPathToNode,
|
||||||
['CallExpression', 'CallExpressionKw']
|
['CallExpression', 'CallExpressionKw']
|
||||||
)
|
)
|
||||||
if (err(_node1)) {
|
if (err(_node1)) return
|
||||||
this.tearDownSketch({ removeAxis: false })
|
|
||||||
this.sceneInfra.resumeRendering()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const callExpName = _node1.node?.callee?.name.name
|
const callExpName = _node1.node?.callee?.name.name
|
||||||
|
|
||||||
const initSegment =
|
const initSegment =
|
||||||
@ -871,9 +862,6 @@ export class SceneEntities {
|
|||||||
)
|
)
|
||||||
position && this.intersectionPlane.position.set(...position)
|
position && this.intersectionPlane.position.set(...position)
|
||||||
this.sceneInfra.scene.add(group)
|
this.sceneInfra.scene.add(group)
|
||||||
|
|
||||||
this.sceneInfra.resumeRendering()
|
|
||||||
|
|
||||||
this.sceneInfra.camControls.enableRotate = false
|
this.sceneInfra.camControls.enableRotate = false
|
||||||
this.sceneInfra.overlayCallbacks(callbacks)
|
this.sceneInfra.overlayCallbacks(callbacks)
|
||||||
|
|
||||||
@ -894,6 +882,7 @@ export class SceneEntities {
|
|||||||
) => {
|
) => {
|
||||||
if (trap(modifiedAst)) return Promise.reject(modifiedAst)
|
if (trap(modifiedAst)) return Promise.reject(modifiedAst)
|
||||||
const nextAst = await this.kclManager.updateAst(modifiedAst, false)
|
const nextAst = await this.kclManager.updateAst(modifiedAst, false)
|
||||||
|
this.tearDownSketch({ removeAxis: false })
|
||||||
this.sceneInfra.resetMouseListeners()
|
this.sceneInfra.resetMouseListeners()
|
||||||
await this.setupSketch({
|
await this.setupSketch({
|
||||||
sketchEntryNodePath,
|
sketchEntryNodePath,
|
||||||
@ -967,6 +956,7 @@ export class SceneEntities {
|
|||||||
|
|
||||||
const draftExpressionsIndices = { start: index, end: index }
|
const draftExpressionsIndices = { start: index, end: index }
|
||||||
|
|
||||||
|
if (shouldTearDown) this.tearDownSketch({ removeAxis: false })
|
||||||
this.sceneInfra.resetMouseListeners()
|
this.sceneInfra.resetMouseListeners()
|
||||||
|
|
||||||
const { truncatedAst } = await this.setupSketch({
|
const { truncatedAst } = await this.setupSketch({
|
||||||
@ -977,8 +967,6 @@ export class SceneEntities {
|
|||||||
position: origin,
|
position: origin,
|
||||||
maybeModdedAst: modifiedAst,
|
maybeModdedAst: modifiedAst,
|
||||||
draftExpressionsIndices,
|
draftExpressionsIndices,
|
||||||
}).catch(() => {
|
|
||||||
return { truncatedAst: modifiedAst }
|
|
||||||
})
|
})
|
||||||
this.sceneInfra.setCallbacks({
|
this.sceneInfra.setCallbacks({
|
||||||
onClick: async (args) => {
|
onClick: async (args) => {
|
||||||
@ -1836,6 +1824,7 @@ export class SceneEntities {
|
|||||||
const index = sg.paths.length // because we've added a new segment that's not in the memory yet
|
const index = sg.paths.length // because we've added a new segment that's not in the memory yet
|
||||||
const draftExpressionsIndices = { start: index, end: index }
|
const draftExpressionsIndices = { start: index, end: index }
|
||||||
|
|
||||||
|
this.tearDownSketch({ removeAxis: false })
|
||||||
this.sceneInfra.resetMouseListeners()
|
this.sceneInfra.resetMouseListeners()
|
||||||
|
|
||||||
const { truncatedAst } = await this.setupSketch({
|
const { truncatedAst } = await this.setupSketch({
|
||||||
@ -2066,6 +2055,7 @@ export class SceneEntities {
|
|||||||
// Get the insertion index from the modified path
|
// Get the insertion index from the modified path
|
||||||
const insertIndex = Number(mod.pathToNode[1][0])
|
const insertIndex = Number(mod.pathToNode[1][0])
|
||||||
|
|
||||||
|
this.tearDownSketch({ removeAxis: false })
|
||||||
this.sceneInfra.resetMouseListeners()
|
this.sceneInfra.resetMouseListeners()
|
||||||
|
|
||||||
const { truncatedAst } = await this.setupSketch({
|
const { truncatedAst } = await this.setupSketch({
|
||||||
@ -2487,6 +2477,7 @@ export class SceneEntities {
|
|||||||
this.sceneInfra.setCallbacks({
|
this.sceneInfra.setCallbacks({
|
||||||
onDragEnd: async () => {
|
onDragEnd: async () => {
|
||||||
if (addingNewSegmentStatus !== 'nothing') {
|
if (addingNewSegmentStatus !== 'nothing') {
|
||||||
|
this.tearDownSketch({ removeAxis: false })
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.setupSketch({
|
this.setupSketch({
|
||||||
sketchEntryNodePath,
|
sketchEntryNodePath,
|
||||||
@ -2561,6 +2552,7 @@ export class SceneEntities {
|
|||||||
mod.modifiedAst
|
mod.modifiedAst
|
||||||
)
|
)
|
||||||
if (err(didReParse)) return
|
if (err(didReParse)) return
|
||||||
|
this.tearDownSketch({ removeAxis: false })
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.setupSketch({
|
this.setupSketch({
|
||||||
sketchEntryNodePath: pathToNode,
|
sketchEntryNodePath: pathToNode,
|
||||||
@ -2672,8 +2664,8 @@ export class SceneEntities {
|
|||||||
if (prev && ARC_SEGMENT_TYPES.includes(prev.userData.type)) {
|
if (prev && ARC_SEGMENT_TYPES.includes(prev.userData.type)) {
|
||||||
const snapDirection = findTangentDirection(prev)
|
const snapDirection = findTangentDirection(prev)
|
||||||
if (snapDirection) {
|
if (snapDirection) {
|
||||||
const SNAP_TOLERANCE_PIXELS = 8 * window.devicePixelRatio
|
const SNAP_TOLERANCE_PIXELS = 12 * window.devicePixelRatio
|
||||||
const SNAP_MIN_DISTANCE_PIXELS = 10 * window.devicePixelRatio
|
const SNAP_MIN_DISTANCE_PIXELS = 5 * window.devicePixelRatio
|
||||||
const orthoFactor = orthoScale(this.sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(this.sceneInfra.camControls.camera)
|
||||||
|
|
||||||
// See if snapDirection intersects with any of the axes
|
// See if snapDirection intersects with any of the axes
|
||||||
|
@ -264,8 +264,6 @@ export class SceneInfra {
|
|||||||
hasBeenDragged: boolean
|
hasBeenDragged: boolean
|
||||||
} | null = null
|
} | null = null
|
||||||
mouseDownVector: null | Vector2 = null
|
mouseDownVector: null | Vector2 = null
|
||||||
private isRenderingPaused = false
|
|
||||||
private lastFrameTime = 0
|
|
||||||
|
|
||||||
constructor(engineCommandManager: EngineCommandManager) {
|
constructor(engineCommandManager: EngineCommandManager) {
|
||||||
// SCENE
|
// SCENE
|
||||||
@ -350,20 +348,8 @@ export class SceneInfra {
|
|||||||
TWEEN.update() // This will update all tweens during the animation loop
|
TWEEN.update() // This will update all tweens during the animation loop
|
||||||
if (!this.isFovAnimationInProgress) {
|
if (!this.isFovAnimationInProgress) {
|
||||||
this.camControls.update()
|
this.camControls.update()
|
||||||
|
this.renderer.render(this.scene, this.camControls.camera)
|
||||||
// If rendering is paused, only render if enough time has passed to maintain smooth animation
|
this.labelRenderer.render(this.scene, this.camControls.camera)
|
||||||
if (this.isRenderingPaused) {
|
|
||||||
const currentTime = performance.now()
|
|
||||||
if (currentTime - this.lastFrameTime > 1000 / 30) {
|
|
||||||
// Limit to 30fps while paused
|
|
||||||
this.renderer.render(this.scene, this.camControls.camera)
|
|
||||||
this.labelRenderer.render(this.scene, this.camControls.camera)
|
|
||||||
this.lastFrameTime = currentTime
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.renderer.render(this.scene, this.camControls.camera)
|
|
||||||
this.labelRenderer.render(this.scene, this.camControls.camera)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,15 +685,6 @@ export class SceneInfra {
|
|||||||
const scale = this.getClientSceneScaleFactor(dummy)
|
const scale = this.getClientSceneScaleFactor(dummy)
|
||||||
return getLength(a, b) / scale
|
return getLength(a, b) / scale
|
||||||
}
|
}
|
||||||
pauseRendering() {
|
|
||||||
this.isRenderingPaused = true
|
|
||||||
// Store the current time to prevent unnecessary updates
|
|
||||||
this.lastFrameTime = performance.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
resumeRendering() {
|
|
||||||
this.isRenderingPaused = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function baseUnitTomm(baseUnit: BaseUnit) {
|
function baseUnitTomm(baseUnit: BaseUnit) {
|
||||||
|
@ -221,7 +221,7 @@ class StraightSegment implements SegmentUtils {
|
|||||||
const snapLine = createLine({
|
const snapLine = createLine({
|
||||||
from: [0, 0],
|
from: [0, 0],
|
||||||
to: [0, 0],
|
to: [0, 0],
|
||||||
color: 0x555555,
|
color: 0xcccccc,
|
||||||
})
|
})
|
||||||
snapLine.name = STRAIGHT_SEGMENT_SNAP_LINE
|
snapLine.name = STRAIGHT_SEGMENT_SNAP_LINE
|
||||||
segmentGroup.add(snapLine)
|
segmentGroup.add(snapLine)
|
||||||
@ -294,8 +294,6 @@ class StraightSegment implements SegmentUtils {
|
|||||||
if (snapLine) {
|
if (snapLine) {
|
||||||
snapLine.visible = !!input.snap
|
snapLine.visible = !!input.snap
|
||||||
if (snapLine.visible) {
|
if (snapLine.visible) {
|
||||||
// Without this three.js incorrectly culls the line in some cases when zoomed in too much
|
|
||||||
snapLine.frustumCulled = false
|
|
||||||
const snapLineFrom = to
|
const snapLineFrom = to
|
||||||
const snapLineTo = new Vector3(to[0], to[1], 0).addScaledVector(
|
const snapLineTo = new Vector3(to[0], to[1], 0).addScaledVector(
|
||||||
dir,
|
dir,
|
||||||
|
@ -117,6 +117,7 @@ export default function CommandBarSelectionMixedInput({
|
|||||||
Continue without selection
|
Continue without selection
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<span data-testid="cmd-bar-arg-name" className="sr-only">
|
<span data-testid="cmd-bar-arg-name" className="sr-only">
|
||||||
{arg.name}
|
{arg.name}
|
||||||
</span>
|
</span>
|
||||||
|
@ -3,7 +3,6 @@ import { useEffect, useState } from 'react'
|
|||||||
import type { CommandLog } from '@src/lang/std/commandLog'
|
import type { CommandLog } from '@src/lang/std/commandLog'
|
||||||
import { engineCommandManager } from '@src/lib/singletons'
|
import { engineCommandManager } from '@src/lib/singletons'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
import { parseJson } from '@src/lib/utils'
|
|
||||||
|
|
||||||
export function useEngineCommands(): [CommandLog[], () => void] {
|
export function useEngineCommands(): [CommandLog[], () => void] {
|
||||||
const [engineCommands, setEngineCommands] = useState<CommandLog[]>(
|
const [engineCommands, setEngineCommands] = useState<CommandLog[]>(
|
||||||
@ -85,7 +84,7 @@ export const EngineCommands = () => {
|
|||||||
data-testid="custom-cmd-send-button"
|
data-testid="custom-cmd-send-button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
engineCommandManager
|
engineCommandManager
|
||||||
.sendSceneCommand(parseJson(customCmd))
|
.sendSceneCommand(JSON.parse(customCmd))
|
||||||
.catch(reportRejection)
|
.catch(reportRejection)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -5,7 +5,10 @@ import { useModelingContext } from '@src/hooks/useModelingContext'
|
|||||||
import { useNetworkContext } from '@src/hooks/useNetworkContext'
|
import { useNetworkContext } from '@src/hooks/useNetworkContext'
|
||||||
import { NetworkHealthState } from '@src/hooks/useNetworkStatus'
|
import { NetworkHealthState } from '@src/hooks/useNetworkStatus'
|
||||||
import { getArtifactOfTypes } from '@src/lang/std/artifactGraph'
|
import { getArtifactOfTypes } from '@src/lang/std/artifactGraph'
|
||||||
import { EngineCommandManagerEvents } from '@src/lang/std/engineConnection'
|
import {
|
||||||
|
EngineCommandManagerEvents,
|
||||||
|
EngineConnectionStateType,
|
||||||
|
} from '@src/lang/std/engineConnection'
|
||||||
import { btnName } from '@src/lib/cameraControls'
|
import { btnName } from '@src/lib/cameraControls'
|
||||||
import { PATHS } from '@src/lib/paths'
|
import { PATHS } from '@src/lib/paths'
|
||||||
import { sendSelectEventToEngine } from '@src/lib/selections'
|
import { sendSelectEventToEngine } from '@src/lib/selections'
|
||||||
@ -427,9 +430,8 @@ export const EngineStream = (props: {
|
|||||||
}
|
}
|
||||||
menuTargetElement={videoWrapperRef}
|
menuTargetElement={videoWrapperRef}
|
||||||
/>
|
/>
|
||||||
{![EngineStreamState.Playing, EngineStreamState.Paused].some(
|
{engineCommandManager.engineConnection?.state.type !==
|
||||||
(s) => s === engineStreamState.value
|
EngineConnectionStateType.ConnectionEstablished && (
|
||||||
) && (
|
|
||||||
<Loading dataTestId="loading-engine" className="fixed inset-0">
|
<Loading dataTestId="loading-engine" className="fixed inset-0">
|
||||||
Connecting to engine
|
Connecting to engine
|
||||||
</Loading>
|
</Loading>
|
||||||
|
@ -330,13 +330,6 @@ export const ModelingMachineProvider = ({
|
|||||||
}
|
}
|
||||||
if (setSelections.selectionType === 'singleCodeCursor') {
|
if (setSelections.selectionType === 'singleCodeCursor') {
|
||||||
if (!setSelections.selection && editorManager.isShiftDown) {
|
if (!setSelections.selection && editorManager.isShiftDown) {
|
||||||
// if the user is holding shift, but they didn't select anything
|
|
||||||
// don't nuke their other selections (frustrating to have one bad click ruin your
|
|
||||||
// whole selection)
|
|
||||||
selections = {
|
|
||||||
graphSelections: selectionRanges.graphSelections,
|
|
||||||
otherSelections: selectionRanges.otherSelections,
|
|
||||||
}
|
|
||||||
} else if (
|
} else if (
|
||||||
!setSelections.selection &&
|
!setSelections.selection &&
|
||||||
!editorManager.isShiftDown
|
!editorManager.isShiftDown
|
||||||
@ -1494,6 +1487,7 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, data } }) => {
|
async ({ input: { sketchDetails, data } }) => {
|
||||||
if (!sketchDetails || !data)
|
if (!sketchDetails || !data)
|
||||||
return reject('No sketch details or data')
|
return reject('No sketch details or data')
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
|
|
||||||
const result = await sceneEntitiesManager.setupDraftCircle(
|
const result = await sceneEntitiesManager.setupDraftCircle(
|
||||||
sketchDetails.sketchEntryNodePath,
|
sketchDetails.sketchEntryNodePath,
|
||||||
@ -1514,6 +1508,7 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, data } }) => {
|
async ({ input: { sketchDetails, data } }) => {
|
||||||
if (!sketchDetails || !data)
|
if (!sketchDetails || !data)
|
||||||
return reject('No sketch details or data')
|
return reject('No sketch details or data')
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
|
|
||||||
const result =
|
const result =
|
||||||
await sceneEntitiesManager.setupDraftCircleThreePoint(
|
await sceneEntitiesManager.setupDraftCircleThreePoint(
|
||||||
@ -1536,6 +1531,7 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, data } }) => {
|
async ({ input: { sketchDetails, data } }) => {
|
||||||
if (!sketchDetails || !data)
|
if (!sketchDetails || !data)
|
||||||
return reject('No sketch details or data')
|
return reject('No sketch details or data')
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
|
|
||||||
const result = await sceneEntitiesManager.setupDraftRectangle(
|
const result = await sceneEntitiesManager.setupDraftRectangle(
|
||||||
sketchDetails.sketchEntryNodePath,
|
sketchDetails.sketchEntryNodePath,
|
||||||
@ -1556,6 +1552,7 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, data } }) => {
|
async ({ input: { sketchDetails, data } }) => {
|
||||||
if (!sketchDetails || !data)
|
if (!sketchDetails || !data)
|
||||||
return reject('No sketch details or data')
|
return reject('No sketch details or data')
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
const result = await sceneEntitiesManager.setupDraftCenterRectangle(
|
const result = await sceneEntitiesManager.setupDraftCenterRectangle(
|
||||||
sketchDetails.sketchEntryNodePath,
|
sketchDetails.sketchEntryNodePath,
|
||||||
sketchDetails.sketchNodePaths,
|
sketchDetails.sketchNodePaths,
|
||||||
@ -1575,6 +1572,7 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, data } }) => {
|
async ({ input: { sketchDetails, data } }) => {
|
||||||
if (!sketchDetails || !data)
|
if (!sketchDetails || !data)
|
||||||
return reject('No sketch details or data')
|
return reject('No sketch details or data')
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
const result = await sceneEntitiesManager.setupDraftArcThreePoint(
|
const result = await sceneEntitiesManager.setupDraftArcThreePoint(
|
||||||
sketchDetails.sketchEntryNodePath,
|
sketchDetails.sketchEntryNodePath,
|
||||||
sketchDetails.sketchNodePaths,
|
sketchDetails.sketchNodePaths,
|
||||||
@ -1594,6 +1592,7 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, data } }) => {
|
async ({ input: { sketchDetails, data } }) => {
|
||||||
if (!sketchDetails || !data)
|
if (!sketchDetails || !data)
|
||||||
return reject('No sketch details or data')
|
return reject('No sketch details or data')
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
const result = await sceneEntitiesManager.setupDraftArc(
|
const result = await sceneEntitiesManager.setupDraftArc(
|
||||||
sketchDetails.sketchEntryNodePath,
|
sketchDetails.sketchEntryNodePath,
|
||||||
sketchDetails.sketchNodePaths,
|
sketchDetails.sketchNodePaths,
|
||||||
@ -1613,6 +1612,9 @@ export const ModelingMachineProvider = ({
|
|||||||
async ({ input: { sketchDetails, selectionRanges } }) => {
|
async ({ input: { sketchDetails, selectionRanges } }) => {
|
||||||
if (!sketchDetails) return
|
if (!sketchDetails) return
|
||||||
if (!sketchDetails.sketchEntryNodePath?.length) return
|
if (!sketchDetails.sketchEntryNodePath?.length) return
|
||||||
|
if (Object.keys(sceneEntitiesManager.activeSegments).length > 0) {
|
||||||
|
sceneEntitiesManager.tearDownSketch({ removeAxis: false })
|
||||||
|
}
|
||||||
sceneInfra.resetMouseListeners()
|
sceneInfra.resetMouseListeners()
|
||||||
await sceneEntitiesManager.setupSketch({
|
await sceneEntitiesManager.setupSketch({
|
||||||
sketchEntryNodePath: sketchDetails?.sketchEntryNodePath || [],
|
sketchEntryNodePath: sketchDetails?.sketchEntryNodePath || [],
|
||||||
|
@ -355,38 +355,6 @@ const OperationItem = (props: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function enterTranslateFlow() {
|
|
||||||
if (
|
|
||||||
props.item.type === 'StdLibCall' ||
|
|
||||||
props.item.type === 'KclStdLibCall' ||
|
|
||||||
props.item.type === 'GroupBegin'
|
|
||||||
) {
|
|
||||||
props.send({
|
|
||||||
type: 'enterTranslateFlow',
|
|
||||||
data: {
|
|
||||||
targetSourceRange: sourceRangeFromRust(props.item.sourceRange),
|
|
||||||
currentOperation: props.item,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function enterRotateFlow() {
|
|
||||||
if (
|
|
||||||
props.item.type === 'StdLibCall' ||
|
|
||||||
props.item.type === 'KclStdLibCall' ||
|
|
||||||
props.item.type === 'GroupBegin'
|
|
||||||
) {
|
|
||||||
props.send({
|
|
||||||
type: 'enterRotateFlow',
|
|
||||||
data: {
|
|
||||||
targetSourceRange: sourceRangeFromRust(props.item.sourceRange),
|
|
||||||
currentOperation: props.item,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteOperation() {
|
function deleteOperation() {
|
||||||
if (
|
if (
|
||||||
props.item.type === 'StdLibCall' ||
|
props.item.type === 'StdLibCall' ||
|
||||||
@ -450,13 +418,6 @@ const OperationItem = (props: {
|
|||||||
...(props.item.type === 'StdLibCall' ||
|
...(props.item.type === 'StdLibCall' ||
|
||||||
props.item.type === 'KclStdLibCall'
|
props.item.type === 'KclStdLibCall'
|
||||||
? [
|
? [
|
||||||
<ContextMenuItem
|
|
||||||
disabled={!stdLibMap[props.item.name]?.prepareToEdit}
|
|
||||||
onClick={enterEditFlow}
|
|
||||||
hotkey="Double click"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</ContextMenuItem>,
|
|
||||||
<ContextMenuItem
|
<ContextMenuItem
|
||||||
disabled={!stdLibMap[props.item.name]?.supportsAppearance}
|
disabled={!stdLibMap[props.item.name]?.supportsAppearance}
|
||||||
onClick={enterAppearanceFlow}
|
onClick={enterAppearanceFlow}
|
||||||
@ -464,41 +425,22 @@ const OperationItem = (props: {
|
|||||||
>
|
>
|
||||||
Set appearance
|
Set appearance
|
||||||
</ContextMenuItem>,
|
</ContextMenuItem>,
|
||||||
]
|
|
||||||
: []),
|
|
||||||
...(props.item.type === 'StdLibCall' ||
|
|
||||||
props.item.type === 'KclStdLibCall' ||
|
|
||||||
props.item.type === 'GroupBegin'
|
|
||||||
? [
|
|
||||||
<ContextMenuItem
|
<ContextMenuItem
|
||||||
onClick={enterTranslateFlow}
|
disabled={!stdLibMap[props.item.name]?.prepareToEdit}
|
||||||
data-testid="context-menu-set-translate"
|
onClick={enterEditFlow}
|
||||||
disabled={
|
hotkey="Double click"
|
||||||
props.item.type !== 'GroupBegin' &&
|
|
||||||
!stdLibMap[props.item.name]?.supportsTransform
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Set translate
|
Edit
|
||||||
</ContextMenuItem>,
|
|
||||||
<ContextMenuItem
|
|
||||||
onClick={enterRotateFlow}
|
|
||||||
data-testid="context-menu-set-rotate"
|
|
||||||
disabled={
|
|
||||||
props.item.type !== 'GroupBegin' &&
|
|
||||||
!stdLibMap[props.item.name]?.supportsTransform
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Set rotate
|
|
||||||
</ContextMenuItem>,
|
|
||||||
<ContextMenuItem
|
|
||||||
onClick={deleteOperation}
|
|
||||||
hotkey="Delete"
|
|
||||||
data-testid="context-menu-delete"
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</ContextMenuItem>,
|
</ContextMenuItem>,
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
<ContextMenuItem
|
||||||
|
onClick={deleteOperation}
|
||||||
|
hotkey="Delete"
|
||||||
|
data-testid="context-menu-delete"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</ContextMenuItem>,
|
||||||
],
|
],
|
||||||
[props.item, props.send]
|
[props.item, props.send]
|
||||||
)
|
)
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import toast from 'react-hot-toast'
|
|
||||||
|
|
||||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
|
||||||
|
|
||||||
export function ToastUnsupportedSelection({
|
|
||||||
toastId,
|
|
||||||
}: {
|
|
||||||
toastId: string
|
|
||||||
}) {
|
|
||||||
const githubIssueUrl = 'https://github.com/KittyCAD/modeling-app/issues/6368'
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="inset-0 z-50 grid place-content-center rounded bg-chalkboard-10 dark:bg-chalkboard-90 shadow-md p-3">
|
|
||||||
<section>
|
|
||||||
<p className="text-sm text-chalkboard-70 dark:text-chalkboard-30">
|
|
||||||
Some faces and edges are not currently selectable.{' '}
|
|
||||||
<a
|
|
||||||
href={githubIssueUrl}
|
|
||||||
onClick={openExternalBrowserIfDesktop(githubIssueUrl)}
|
|
||||||
className="underline"
|
|
||||||
>
|
|
||||||
The team is working on it
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a toast notification for when users try to select unsupported faces/edges
|
|
||||||
* @example
|
|
||||||
* // In your component or handler:
|
|
||||||
* import { showUnsupportedSelectionToast } from '@src/components/ToastUnsupportedSelection'
|
|
||||||
*
|
|
||||||
* // When user tries to select an unsupported face/edge
|
|
||||||
* showUnsupportedSelectionToast()
|
|
||||||
*/
|
|
||||||
export function showUnsupportedSelectionToast() {
|
|
||||||
const toastId = toast.custom(
|
|
||||||
(t) => <ToastUnsupportedSelection toastId={t.id} />,
|
|
||||||
{
|
|
||||||
duration: 4_000,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return toastId
|
|
||||||
}
|
|
@ -37,7 +37,7 @@ export class KCLError extends Error {
|
|||||||
filenames: { [x: number]: ModulePath | undefined },
|
filenames: { [x: number]: ModulePath | undefined },
|
||||||
defaultPlanes: DefaultPlanes | null
|
defaultPlanes: DefaultPlanes | null
|
||||||
) {
|
) {
|
||||||
super(`${kind}: ${msg}`)
|
super()
|
||||||
this.kind = kind
|
this.kind = kind
|
||||||
this.msg = msg
|
this.msg = msg
|
||||||
this.sourceRange = sourceRange
|
this.sourceRange = sourceRange
|
||||||
|
@ -4,7 +4,6 @@ import path from 'node:path'
|
|||||||
import { assertParse } from '@src/lang/wasm'
|
import { assertParse } from '@src/lang/wasm'
|
||||||
import { initPromise } from '@src/lang/wasmUtils'
|
import { initPromise } from '@src/lang/wasmUtils'
|
||||||
import { enginelessExecutor } from '@src/lib/testHelpers'
|
import { enginelessExecutor } from '@src/lib/testHelpers'
|
||||||
import { parseJson } from '@src/lib/utils'
|
|
||||||
|
|
||||||
// The purpose of these tests is to act as a first line of defense
|
// The purpose of these tests is to act as a first line of defense
|
||||||
// if something gets real screwy with our KCL ecosystem.
|
// if something gets real screwy with our KCL ecosystem.
|
||||||
@ -28,7 +27,7 @@ const manifestJsonStr = await fs.readFile(
|
|||||||
path.resolve(DIR_KCL_SAMPLES, 'manifest.json'),
|
path.resolve(DIR_KCL_SAMPLES, 'manifest.json'),
|
||||||
'utf-8'
|
'utf-8'
|
||||||
)
|
)
|
||||||
const manifest: KclSampleFile[] = parseJson(manifestJsonStr)
|
const manifest = JSON.parse(manifestJsonStr)
|
||||||
|
|
||||||
process.chdir(DIR_KCL_SAMPLES)
|
process.chdir(DIR_KCL_SAMPLES)
|
||||||
|
|
||||||
|
@ -54,18 +54,23 @@ export async function updateModelingState(
|
|||||||
},
|
},
|
||||||
options?: {
|
options?: {
|
||||||
focusPath?: Array<PathToNode>
|
focusPath?: Array<PathToNode>
|
||||||
|
skipUpdateAst?: boolean
|
||||||
}
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
let updatedAst: {
|
let updatedAst: {
|
||||||
newAst: Node<Program>
|
newAst: Node<Program>
|
||||||
selections?: Selections
|
selections?: Selections
|
||||||
} = { newAst: ast }
|
} = { newAst: ast }
|
||||||
// Step 1: Update AST without executing (prepare selections)
|
// TODO: understand why this skip flag is needed for insertAstMod.
|
||||||
updatedAst = await dependencies.kclManager.updateAst(
|
// It's unclear why we double casts the AST
|
||||||
ast,
|
if (!options?.skipUpdateAst) {
|
||||||
false, // Execution handled separately for error resilience
|
// Step 1: Update AST without executing (prepare selections)
|
||||||
options
|
updatedAst = await dependencies.kclManager.updateAst(
|
||||||
)
|
ast,
|
||||||
|
false, // Execution handled separately for error resilience
|
||||||
|
options
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Step 2: Update the code editor and save file
|
// Step 2: Update the code editor and save file
|
||||||
await dependencies.codeManager.updateEditorWithAstAndWriteToFile(
|
await dependencies.codeManager.updateEditorWithAstAndWriteToFile(
|
||||||
|
@ -81,10 +81,7 @@ import type {
|
|||||||
VariableMap,
|
VariableMap,
|
||||||
} from '@src/lang/wasm'
|
} from '@src/lang/wasm'
|
||||||
import { isPathToNodeNumber, parse } from '@src/lang/wasm'
|
import { isPathToNodeNumber, parse } from '@src/lang/wasm'
|
||||||
import type {
|
import type { KclExpressionWithVariable } from '@src/lib/commandTypes'
|
||||||
KclCommandValue,
|
|
||||||
KclExpressionWithVariable,
|
|
||||||
} from '@src/lib/commandTypes'
|
|
||||||
import { KCL_DEFAULT_CONSTANT_PREFIXES } from '@src/lib/constants'
|
import { KCL_DEFAULT_CONSTANT_PREFIXES } from '@src/lib/constants'
|
||||||
import type { DefaultPlaneStr } from '@src/lib/planes'
|
import type { DefaultPlaneStr } from '@src/lib/planes'
|
||||||
import type { Selection } from '@src/lib/selections'
|
import type { Selection } from '@src/lib/selections'
|
||||||
@ -230,8 +227,6 @@ export function addSketchTo(
|
|||||||
Set the keyword argument to the given value.
|
Set the keyword argument to the given value.
|
||||||
Returns true if it overwrote an existing argument.
|
Returns true if it overwrote an existing argument.
|
||||||
Returns false if no argument with the label existed before.
|
Returns false if no argument with the label existed before.
|
||||||
Returns 'no-mutate' if the label was found, but the value is constrained and not
|
|
||||||
mutated.
|
|
||||||
Also do some checks to see if it's actually trying to set a constraint on
|
Also do some checks to see if it's actually trying to set a constraint on
|
||||||
a sketch line that's already fully constrained, and if so, duplicates the arg.
|
a sketch line that's already fully constrained, and if so, duplicates the arg.
|
||||||
WILL BE FIXED SOON.
|
WILL BE FIXED SOON.
|
||||||
@ -240,7 +235,7 @@ export function mutateKwArg(
|
|||||||
label: string,
|
label: string,
|
||||||
node: CallExpressionKw,
|
node: CallExpressionKw,
|
||||||
val: Expr
|
val: Expr
|
||||||
): boolean | 'no-mutate' {
|
): boolean {
|
||||||
for (let i = 0; i < node.arguments.length; i++) {
|
for (let i = 0; i < node.arguments.length; i++) {
|
||||||
const arg = node.arguments[i]
|
const arg = node.arguments[i]
|
||||||
if (arg.label.name === label) {
|
if (arg.label.name === label) {
|
||||||
@ -259,8 +254,6 @@ export function mutateKwArg(
|
|||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// The label was found, but the value is not a literal or static.
|
|
||||||
return 'no-mutate'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.arguments.push(createLabeledArg(label, val))
|
node.arguments.push(createLabeledArg(label, val))
|
||||||
@ -1831,20 +1824,3 @@ export function createNodeFromExprSnippet(
|
|||||||
if (!node) return new Error('No node found')
|
if (!node) return new Error('No node found')
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insertVariableAndOffsetPathToNode(
|
|
||||||
variable: KclCommandValue,
|
|
||||||
modifiedAst: Node<Program>,
|
|
||||||
pathToNode: PathToNode
|
|
||||||
) {
|
|
||||||
if ('variableName' in variable && variable.variableName) {
|
|
||||||
modifiedAst.body.splice(
|
|
||||||
variable.insertIndex,
|
|
||||||
0,
|
|
||||||
variable.variableDeclarationAst
|
|
||||||
)
|
|
||||||
if (typeof pathToNode[1][0] === 'number') {
|
|
||||||
pathToNode[1][0]++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
|
||||||
|
|
||||||
import {
|
|
||||||
createCallExpressionStdLibKw,
|
|
||||||
createLabeledArg,
|
|
||||||
createPipeExpression,
|
|
||||||
} from '@src/lang/create'
|
|
||||||
import { getNodeFromPath } from '@src/lang/queryAst'
|
|
||||||
import type {
|
|
||||||
CallExpressionKw,
|
|
||||||
Expr,
|
|
||||||
ExpressionStatement,
|
|
||||||
PathToNode,
|
|
||||||
PipeExpression,
|
|
||||||
Program,
|
|
||||||
VariableDeclarator,
|
|
||||||
} from '@src/lang/wasm'
|
|
||||||
import { err } from '@src/lib/trap'
|
|
||||||
|
|
||||||
export function setTranslate({
|
|
||||||
modifiedAst,
|
|
||||||
pathToNode,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
z,
|
|
||||||
}: {
|
|
||||||
modifiedAst: Node<Program>
|
|
||||||
pathToNode: PathToNode
|
|
||||||
x: Expr
|
|
||||||
y: Expr
|
|
||||||
z: Expr
|
|
||||||
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
|
||||||
const noPercentSign = null
|
|
||||||
const call = createCallExpressionStdLibKw('translate', noPercentSign, [
|
|
||||||
createLabeledArg('x', x),
|
|
||||||
createLabeledArg('y', y),
|
|
||||||
createLabeledArg('z', z),
|
|
||||||
])
|
|
||||||
|
|
||||||
const potentialPipe = getNodeFromPath<PipeExpression>(
|
|
||||||
modifiedAst,
|
|
||||||
pathToNode,
|
|
||||||
['PipeExpression']
|
|
||||||
)
|
|
||||||
if (!err(potentialPipe) && potentialPipe.node.type === 'PipeExpression') {
|
|
||||||
setTransformInPipe(potentialPipe.node, call)
|
|
||||||
} else {
|
|
||||||
const error = createPipeWithTransform(modifiedAst, pathToNode, call)
|
|
||||||
if (err(error)) {
|
|
||||||
return error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
modifiedAst,
|
|
||||||
pathToNode, // TODO: check if this should be updated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setRotate({
|
|
||||||
modifiedAst,
|
|
||||||
pathToNode,
|
|
||||||
roll,
|
|
||||||
pitch,
|
|
||||||
yaw,
|
|
||||||
}: {
|
|
||||||
modifiedAst: Node<Program>
|
|
||||||
pathToNode: PathToNode
|
|
||||||
roll: Expr
|
|
||||||
pitch: Expr
|
|
||||||
yaw: Expr
|
|
||||||
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
|
||||||
const noPercentSign = null
|
|
||||||
const call = createCallExpressionStdLibKw('rotate', noPercentSign, [
|
|
||||||
createLabeledArg('roll', roll),
|
|
||||||
createLabeledArg('pitch', pitch),
|
|
||||||
createLabeledArg('yaw', yaw),
|
|
||||||
])
|
|
||||||
|
|
||||||
const potentialPipe = getNodeFromPath<PipeExpression>(
|
|
||||||
modifiedAst,
|
|
||||||
pathToNode,
|
|
||||||
['PipeExpression']
|
|
||||||
)
|
|
||||||
if (!err(potentialPipe) && potentialPipe.node.type === 'PipeExpression') {
|
|
||||||
setTransformInPipe(potentialPipe.node, call)
|
|
||||||
} else {
|
|
||||||
const error = createPipeWithTransform(modifiedAst, pathToNode, call)
|
|
||||||
if (err(error)) {
|
|
||||||
return error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
modifiedAst,
|
|
||||||
pathToNode, // TODO: check if this should be updated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTransformInPipe(
|
|
||||||
expression: PipeExpression,
|
|
||||||
call: Node<CallExpressionKw>
|
|
||||||
) {
|
|
||||||
const existingIndex = expression.body.findIndex(
|
|
||||||
(v) =>
|
|
||||||
v.type === 'CallExpressionKw' &&
|
|
||||||
v.callee.type === 'Name' &&
|
|
||||||
v.callee.name.name === call.callee.name.name
|
|
||||||
)
|
|
||||||
if (existingIndex > -1) {
|
|
||||||
expression.body[existingIndex] = call
|
|
||||||
} else {
|
|
||||||
expression.body.push(call)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPipeWithTransform(
|
|
||||||
modifiedAst: Node<Program>,
|
|
||||||
pathToNode: PathToNode,
|
|
||||||
call: Node<CallExpressionKw>
|
|
||||||
) {
|
|
||||||
const existingCall = getNodeFromPath<
|
|
||||||
VariableDeclarator | ExpressionStatement
|
|
||||||
>(modifiedAst, pathToNode, ['VariableDeclarator', 'ExpressionStatement'])
|
|
||||||
if (err(existingCall)) {
|
|
||||||
return new Error('Unsupported operation type.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingCall.node.type === 'ExpressionStatement') {
|
|
||||||
existingCall.node.expression = createPipeExpression([
|
|
||||||
existingCall.node.expression,
|
|
||||||
call,
|
|
||||||
])
|
|
||||||
} else if (existingCall.node.type === 'VariableDeclarator') {
|
|
||||||
existingCall.node.init = createPipeExpression([
|
|
||||||
existingCall.node.init,
|
|
||||||
call,
|
|
||||||
])
|
|
||||||
} else {
|
|
||||||
return new Error('Unsupported operation type.')
|
|
||||||
}
|
|
||||||
}
|
|
@ -51,7 +51,6 @@ import { Reason, err } from '@src/lib/trap'
|
|||||||
import { getAngle, isArray } from '@src/lib/utils'
|
import { getAngle, isArray } from '@src/lib/utils'
|
||||||
|
|
||||||
import { ARG_INDEX_FIELD, LABELED_ARG_FIELD } from '@src/lang/queryAstConstants'
|
import { ARG_INDEX_FIELD, LABELED_ARG_FIELD } from '@src/lang/queryAstConstants'
|
||||||
import type { KclCommandValue } from '@src/lib/commandTypes'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a node from a given path within a Program node structure, optionally stopping at a specified node type.
|
* Retrieves a node from a given path within a Program node structure, optionally stopping at a specified node type.
|
||||||
@ -1053,9 +1052,3 @@ export function updatePathToNodesAfterEdit(
|
|||||||
newPath[1][0] = newIndex // Update the body index
|
newPath[1][0] = newIndex // Update the body index
|
||||||
return newPath
|
return newPath
|
||||||
}
|
}
|
||||||
|
|
||||||
export const valueOrVariable = (variable: KclCommandValue) => {
|
|
||||||
return 'variableName' in variable
|
|
||||||
? variable.variableIdentifierAst
|
|
||||||
: variable.valueAst
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
getThemeColorForEngine,
|
getThemeColorForEngine,
|
||||||
} from '@src/lib/theme'
|
} from '@src/lib/theme'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
import { binaryToUuid, parseJson, uuidv4 } from '@src/lib/utils'
|
import { binaryToUuid, uuidv4 } from '@src/lib/utils'
|
||||||
|
|
||||||
const pingIntervalMs = 1_000
|
const pingIntervalMs = 1_000
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ class EngineConnection extends EventTarget {
|
|||||||
this.websocket.addEventListener('open', this.onWebSocketOpen)
|
this.websocket.addEventListener('open', this.onWebSocketOpen)
|
||||||
|
|
||||||
this.websocket?.addEventListener('message', ((event: MessageEvent) => {
|
this.websocket?.addEventListener('message', ((event: MessageEvent) => {
|
||||||
const message: Models['WebSocketResponse_type'] = parseJson(event.data)
|
const message: Models['WebSocketResponse_type'] = JSON.parse(event.data)
|
||||||
const pending =
|
const pending =
|
||||||
this.engineCommandManager.pendingCommands[message.request_id || '']
|
this.engineCommandManager.pendingCommands[message.request_id || '']
|
||||||
if (!('resp' in message)) return
|
if (!('resp' in message)) return
|
||||||
@ -862,7 +862,7 @@ class EngineConnection extends EventTarget {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.onDataChannelMessage = (event) => {
|
this.onDataChannelMessage = (event) => {
|
||||||
const result: UnreliableResponses = parseJson(event.data)
|
const result: UnreliableResponses = JSON.parse(event.data)
|
||||||
Object.values(
|
Object.values(
|
||||||
this.engineCommandManager.unreliableSubscriptions[result.type] ||
|
this.engineCommandManager.unreliableSubscriptions[result.type] ||
|
||||||
{}
|
{}
|
||||||
@ -976,7 +976,7 @@ class EngineConnection extends EventTarget {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const message: Models['WebSocketResponse_type'] = parseJson(
|
const message: Models['WebSocketResponse_type'] = JSON.parse(
|
||||||
event.data
|
event.data
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1564,7 +1564,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
unreliableDataChannel.addEventListener(
|
unreliableDataChannel.addEventListener(
|
||||||
'message',
|
'message',
|
||||||
(event: MessageEvent) => {
|
(event: MessageEvent) => {
|
||||||
const result: UnreliableResponses = parseJson(event.data)
|
const result: UnreliableResponses = JSON.parse(event.data)
|
||||||
Object.values(
|
Object.values(
|
||||||
this.unreliableSubscriptions[result.type] || {}
|
this.unreliableSubscriptions[result.type] || {}
|
||||||
).forEach(
|
).forEach(
|
||||||
@ -1608,7 +1608,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
message.request_id = binaryToUuid(message.request_id)
|
message.request_id = binaryToUuid(message.request_id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message = parseJson(event.data)
|
message = JSON.parse(event.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message === null) {
|
if (message === null) {
|
||||||
@ -1617,12 +1617,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// In either case we want to send the response back over the wire to
|
|
||||||
// the rust side.
|
|
||||||
this.rustContext?.sendResponse(message).catch((err) => {
|
|
||||||
console.error('Error sending response to rust', err)
|
|
||||||
})
|
|
||||||
|
|
||||||
const pending = this.pendingCommands[message.request_id || '']
|
const pending = this.pendingCommands[message.request_id || '']
|
||||||
|
|
||||||
if (pending && !message.success) {
|
if (pending && !message.success) {
|
||||||
@ -1937,46 +1931,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
return e
|
return e
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* A wrapper around the sendCommand where all inputs are JSON strings
|
|
||||||
*
|
|
||||||
* This one does not wait for a response.
|
|
||||||
*/
|
|
||||||
fireModelingCommandFromWasm(
|
|
||||||
id: string,
|
|
||||||
rangeStr: string,
|
|
||||||
commandStr: string,
|
|
||||||
idToRangeStr: string
|
|
||||||
): void | Error {
|
|
||||||
if (this.engineConnection === undefined)
|
|
||||||
return new Error('engineConnection is undefined')
|
|
||||||
if (
|
|
||||||
!this.engineConnection?.isReady() &&
|
|
||||||
!this.engineConnection.isUsingConnectionLite
|
|
||||||
)
|
|
||||||
return new Error('engineConnection is not ready')
|
|
||||||
if (id === undefined) return new Error('id is undefined')
|
|
||||||
if (rangeStr === undefined) return new Error('rangeStr is undefined')
|
|
||||||
if (commandStr === undefined) return new Error('commandStr is undefined')
|
|
||||||
const range: SourceRange = JSON.parse(rangeStr)
|
|
||||||
const command: EngineCommand = JSON.parse(commandStr)
|
|
||||||
const idToRangeMap: { [key: string]: SourceRange } =
|
|
||||||
JSON.parse(idToRangeStr)
|
|
||||||
|
|
||||||
// Current executeAst is stale, going to interrupt, a new executeAst will trigger
|
|
||||||
// Used in conjunction with rejectAllModelingCommands
|
|
||||||
if (this?.kclManager?.executeIsStale) {
|
|
||||||
return new Error(EXECUTE_AST_INTERRUPT_ERROR_MESSAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We purposely don't wait for a response here
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
||||||
this.sendCommand(id, {
|
|
||||||
command,
|
|
||||||
range,
|
|
||||||
idToRangeMap,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around the sendCommand where all inputs are JSON strings
|
* A wrapper around the sendCommand where all inputs are JSON strings
|
||||||
*/
|
*/
|
||||||
|
@ -40,7 +40,7 @@ import type { CoreDumpManager } from '@src/lib/coredump'
|
|||||||
import openWindow from '@src/lib/openWindow'
|
import openWindow from '@src/lib/openWindow'
|
||||||
import { Reason, err } from '@src/lib/trap'
|
import { Reason, err } from '@src/lib/trap'
|
||||||
import type { DeepPartial } from '@src/lib/types'
|
import type { DeepPartial } from '@src/lib/types'
|
||||||
import { isArray, parseJson } from '@src/lib/utils'
|
import { isArray } from '@src/lib/utils'
|
||||||
import {
|
import {
|
||||||
base64_decode,
|
base64_decode,
|
||||||
change_kcl_settings,
|
change_kcl_settings,
|
||||||
@ -217,7 +217,9 @@ export const parse = (code: string | Error): ParseResult | Error => {
|
|||||||
let errs = splitErrors(parsed[1])
|
let errs = splitErrors(parsed[1])
|
||||||
return new ParseResult(parsed[0], errs.errors, errs.warnings)
|
return new ParseResult(parsed[0], errs.errors, errs.warnings)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
const parsed: RustKclError = parseJson(e.toString())
|
// throw e
|
||||||
|
console.error(e.toString())
|
||||||
|
const parsed: RustKclError = JSON.parse(e.toString())
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.kind,
|
parsed.kind,
|
||||||
parsed.msg,
|
parsed.msg,
|
||||||
@ -379,7 +381,7 @@ export function sketchFromKclValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const errFromErrWithOutputs = (e: any): KCLError => {
|
export const errFromErrWithOutputs = (e: any): KCLError => {
|
||||||
const parsed: KclErrorWithOutputs = parseJson(e.toString())
|
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.error.kind,
|
parsed.error.kind,
|
||||||
parsed.error.msg,
|
parsed.error.msg,
|
||||||
|
@ -22,11 +22,7 @@ import type {
|
|||||||
KclCommandValue,
|
KclCommandValue,
|
||||||
StateMachineCommandSetConfig,
|
StateMachineCommandSetConfig,
|
||||||
} from '@src/lib/commandTypes'
|
} from '@src/lib/commandTypes'
|
||||||
import {
|
import { KCL_DEFAULT_DEGREE, KCL_DEFAULT_LENGTH } from '@src/lib/constants'
|
||||||
KCL_DEFAULT_DEGREE,
|
|
||||||
KCL_DEFAULT_LENGTH,
|
|
||||||
KCL_DEFAULT_TRANSFORM,
|
|
||||||
} from '@src/lib/constants'
|
|
||||||
import type { components } from '@src/lib/machine-api'
|
import type { components } from '@src/lib/machine-api'
|
||||||
import type { Selections } from '@src/lib/selections'
|
import type { Selections } from '@src/lib/selections'
|
||||||
import { codeManager, kclManager } from '@src/lib/singletons'
|
import { codeManager, kclManager } from '@src/lib/singletons'
|
||||||
@ -167,20 +163,6 @@ export type ModelingCommandSchema = {
|
|||||||
nodeToEdit?: PathToNode
|
nodeToEdit?: PathToNode
|
||||||
color: string
|
color: string
|
||||||
}
|
}
|
||||||
Translate: {
|
|
||||||
nodeToEdit?: PathToNode
|
|
||||||
selection: Selections
|
|
||||||
x: KclCommandValue
|
|
||||||
y: KclCommandValue
|
|
||||||
z: KclCommandValue
|
|
||||||
}
|
|
||||||
Rotate: {
|
|
||||||
nodeToEdit?: PathToNode
|
|
||||||
selection: Selections
|
|
||||||
roll: KclCommandValue
|
|
||||||
pitch: KclCommandValue
|
|
||||||
yaw: KclCommandValue
|
|
||||||
}
|
|
||||||
'Boolean Subtract': {
|
'Boolean Subtract': {
|
||||||
target: Selections
|
target: Selections
|
||||||
tool: Selections
|
tool: Selections
|
||||||
@ -1042,88 +1024,6 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
|||||||
// Add more fields
|
// Add more fields
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Translate: {
|
|
||||||
description: 'Set translation on solid or sketch.',
|
|
||||||
icon: 'dimension', // TODO: likely not the best icon
|
|
||||||
needsReview: true,
|
|
||||||
hide: DEV || IS_NIGHTLY_OR_DEBUG ? undefined : 'both',
|
|
||||||
args: {
|
|
||||||
nodeToEdit: {
|
|
||||||
description:
|
|
||||||
'Path to the node in the AST to edit. Never shown to the user.',
|
|
||||||
skip: true,
|
|
||||||
inputType: 'text',
|
|
||||||
required: false,
|
|
||||||
hidden: true,
|
|
||||||
},
|
|
||||||
selection: {
|
|
||||||
// selectionMixed allows for feature tree selection of module imports
|
|
||||||
inputType: 'selectionMixed',
|
|
||||||
multiple: false,
|
|
||||||
required: true,
|
|
||||||
skip: true,
|
|
||||||
selectionTypes: ['path'],
|
|
||||||
selectionFilter: ['object'],
|
|
||||||
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
|
||||||
},
|
|
||||||
x: {
|
|
||||||
inputType: 'kcl',
|
|
||||||
defaultValue: KCL_DEFAULT_TRANSFORM,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
inputType: 'kcl',
|
|
||||||
defaultValue: KCL_DEFAULT_TRANSFORM,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
z: {
|
|
||||||
inputType: 'kcl',
|
|
||||||
defaultValue: KCL_DEFAULT_TRANSFORM,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Rotate: {
|
|
||||||
description: 'Set rotation on solid or sketch.',
|
|
||||||
icon: 'angle', // TODO: likely not the best icon
|
|
||||||
needsReview: true,
|
|
||||||
hide: DEV || IS_NIGHTLY_OR_DEBUG ? undefined : 'both',
|
|
||||||
args: {
|
|
||||||
nodeToEdit: {
|
|
||||||
description:
|
|
||||||
'Path to the node in the AST to edit. Never shown to the user.',
|
|
||||||
skip: true,
|
|
||||||
inputType: 'text',
|
|
||||||
required: false,
|
|
||||||
hidden: true,
|
|
||||||
},
|
|
||||||
selection: {
|
|
||||||
// selectionMixed allows for feature tree selection of module imports
|
|
||||||
inputType: 'selectionMixed',
|
|
||||||
multiple: false,
|
|
||||||
required: true,
|
|
||||||
skip: true,
|
|
||||||
selectionTypes: ['path'],
|
|
||||||
selectionFilter: ['object'],
|
|
||||||
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
|
||||||
},
|
|
||||||
roll: {
|
|
||||||
inputType: 'kcl',
|
|
||||||
defaultValue: KCL_DEFAULT_TRANSFORM,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
pitch: {
|
|
||||||
inputType: 'kcl',
|
|
||||||
defaultValue: KCL_DEFAULT_TRANSFORM,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
yaw: {
|
|
||||||
inputType: 'kcl',
|
|
||||||
defaultValue: KCL_DEFAULT_TRANSFORM,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modelingMachineCommandConfig
|
modelingMachineCommandConfig
|
||||||
|
@ -3,7 +3,7 @@ import type { ApiError_type } from '@kittycad/lib/dist/types/src/models'
|
|||||||
|
|
||||||
import type { Selections } from '@src/lib/selections'
|
import type { Selections } from '@src/lib/selections'
|
||||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
||||||
import { parseJson, uuidv4 } from '@src/lib/utils'
|
import { uuidv4 } from '@src/lib/utils'
|
||||||
import type { CommandBarContext } from '@src/machines/commandBarMachine'
|
import type { CommandBarContext } from '@src/machines/commandBarMachine'
|
||||||
|
|
||||||
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
||||||
@ -54,7 +54,7 @@ export function parseEngineErrorMessage(engineError: string) {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const errors = parseJson<ApiError_type[]>(parts[1])
|
const errors = JSON.parse(parts[1]) as ApiError_type[]
|
||||||
if (!errors[0]) {
|
if (!errors[0]) {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,6 @@ export const KCL_DEFAULT_CONSTANT_PREFIXES = {
|
|||||||
/** The default KCL length expression */
|
/** The default KCL length expression */
|
||||||
export const KCL_DEFAULT_LENGTH = `5`
|
export const KCL_DEFAULT_LENGTH = `5`
|
||||||
|
|
||||||
/** The default KCL transform arg value that means no transform */
|
|
||||||
export const KCL_DEFAULT_TRANSFORM = `0`
|
|
||||||
|
|
||||||
/** The default KCL degree expression */
|
/** The default KCL degree expression */
|
||||||
export const KCL_DEFAULT_DEGREE = `360`
|
export const KCL_DEFAULT_DEGREE = `360`
|
||||||
|
|
||||||
|
@ -153,6 +153,7 @@ export function kclCommands(commandProps: KclCommandConfig): Command[] {
|
|||||||
EXECUTION_TYPE_REAL,
|
EXECUTION_TYPE_REAL,
|
||||||
{ kclManager, editorManager, codeManager },
|
{ kclManager, editorManager, codeManager },
|
||||||
{
|
{
|
||||||
|
skipUpdateAst: true,
|
||||||
focusPath: [pathToImportNode, pathToInsertNode],
|
focusPath: [pathToImportNode, pathToInsertNode],
|
||||||
}
|
}
|
||||||
).catch(reportRejection)
|
).catch(reportRejection)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { executeAstMock } from '@src/lang/langHelpers'
|
import { executeAstMock } from '@src/lang/langHelpers'
|
||||||
import { type CallExpressionKw, parse, resultIsOk } from '@src/lang/wasm'
|
import { parse, resultIsOk } from '@src/lang/wasm'
|
||||||
import type { KclCommandValue, KclExpression } from '@src/lib/commandTypes'
|
import type { KclExpression } from '@src/lib/commandTypes'
|
||||||
import { rustContext } from '@src/lib/singletons'
|
import { rustContext } from '@src/lib/singletons'
|
||||||
import { err } from '@src/lib/trap'
|
import { err } from '@src/lib/trap'
|
||||||
|
|
||||||
@ -54,23 +54,3 @@ export async function stringToKclExpression(value: string) {
|
|||||||
valueText: value,
|
valueText: value,
|
||||||
} satisfies KclExpression
|
} satisfies KclExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function retrieveArgFromPipedCallExpression(
|
|
||||||
callExpression: CallExpressionKw,
|
|
||||||
name: string
|
|
||||||
): Promise<KclCommandValue | undefined> {
|
|
||||||
const arg = callExpression.arguments.find(
|
|
||||||
(a) => a.label.type === 'Identifier' && a.label.name === name
|
|
||||||
)
|
|
||||||
if (
|
|
||||||
arg?.type === 'LabeledArg' &&
|
|
||||||
(arg.arg.type === 'Name' || arg.arg.type === 'Literal')
|
|
||||||
) {
|
|
||||||
const value = arg.arg.type === 'Name' ? arg.arg.name.name : arg.arg.raw
|
|
||||||
const result = await stringToKclExpression(value)
|
|
||||||
if (!(err(result) || 'errors' in result)) {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import type { OpKclValue, Operation } from '@rust/kcl-lib/bindings/Operation'
|
import type { OpKclValue, Operation } from '@rust/kcl-lib/bindings/Operation'
|
||||||
|
|
||||||
import type { CustomIconName } from '@src/components/CustomIcon'
|
import type { CustomIconName } from '@src/components/CustomIcon'
|
||||||
import { getNodeFromPath } from '@src/lang/queryAst'
|
|
||||||
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
|
||||||
import type { Artifact } from '@src/lang/std/artifactGraph'
|
import type { Artifact } from '@src/lang/std/artifactGraph'
|
||||||
import {
|
import {
|
||||||
@ -11,16 +10,13 @@ import {
|
|||||||
getSweepEdgeCodeRef,
|
getSweepEdgeCodeRef,
|
||||||
getWallCodeRef,
|
getWallCodeRef,
|
||||||
} from '@src/lang/std/artifactGraph'
|
} from '@src/lang/std/artifactGraph'
|
||||||
import { type PipeExpression, sourceRangeFromRust } from '@src/lang/wasm'
|
import { sourceRangeFromRust } from '@src/lang/wasm'
|
||||||
import type {
|
import type {
|
||||||
HelixModes,
|
HelixModes,
|
||||||
ModelingCommandSchema,
|
ModelingCommandSchema,
|
||||||
} from '@src/lib/commandBarConfigs/modelingCommandConfig'
|
} from '@src/lib/commandBarConfigs/modelingCommandConfig'
|
||||||
import type { KclExpression } from '@src/lib/commandTypes'
|
import type { KclExpression } from '@src/lib/commandTypes'
|
||||||
import {
|
import { stringToKclExpression } from '@src/lib/kclHelpers'
|
||||||
stringToKclExpression,
|
|
||||||
retrieveArgFromPipedCallExpression,
|
|
||||||
} from '@src/lib/kclHelpers'
|
|
||||||
import { isDefaultPlaneStr } from '@src/lib/planes'
|
import { isDefaultPlaneStr } from '@src/lib/planes'
|
||||||
import type { Selection, Selections } from '@src/lib/selections'
|
import type { Selection, Selections } from '@src/lib/selections'
|
||||||
import { codeManager, kclManager, rustContext } from '@src/lib/singletons'
|
import { codeManager, kclManager, rustContext } from '@src/lib/singletons'
|
||||||
@ -50,7 +46,6 @@ interface StdLibCallInfo {
|
|||||||
| PrepareToEditCallback
|
| PrepareToEditCallback
|
||||||
| PrepareToEditFailurePayload
|
| PrepareToEditFailurePayload
|
||||||
supportsAppearance?: boolean
|
supportsAppearance?: boolean
|
||||||
supportsTransform?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1013,7 +1008,6 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
|
|||||||
icon: 'extrude',
|
icon: 'extrude',
|
||||||
prepareToEdit: prepareToEditExtrude,
|
prepareToEdit: prepareToEditExtrude,
|
||||||
supportsAppearance: true,
|
supportsAppearance: true,
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
fillet: {
|
fillet: {
|
||||||
label: 'Fillet',
|
label: 'Fillet',
|
||||||
@ -1032,26 +1026,19 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
|
|||||||
hollow: {
|
hollow: {
|
||||||
label: 'Hollow',
|
label: 'Hollow',
|
||||||
icon: 'hollow',
|
icon: 'hollow',
|
||||||
supportsAppearance: true,
|
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
import: {
|
import: {
|
||||||
label: 'Import',
|
label: 'Import',
|
||||||
icon: 'import',
|
icon: 'import',
|
||||||
supportsAppearance: true,
|
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
intersect: {
|
intersect: {
|
||||||
label: 'Intersect',
|
label: 'Intersect',
|
||||||
icon: 'booleanIntersect',
|
icon: 'booleanIntersect',
|
||||||
supportsAppearance: true,
|
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
loft: {
|
loft: {
|
||||||
label: 'Loft',
|
label: 'Loft',
|
||||||
icon: 'loft',
|
icon: 'loft',
|
||||||
supportsAppearance: true,
|
supportsAppearance: true,
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
offsetPlane: {
|
offsetPlane: {
|
||||||
label: 'Offset Plane',
|
label: 'Offset Plane',
|
||||||
@ -1065,8 +1052,6 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
|
|||||||
patternCircular3d: {
|
patternCircular3d: {
|
||||||
label: 'Circular Pattern',
|
label: 'Circular Pattern',
|
||||||
icon: 'patternCircular3d',
|
icon: 'patternCircular3d',
|
||||||
supportsAppearance: true,
|
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
patternLinear2d: {
|
patternLinear2d: {
|
||||||
label: 'Linear Pattern',
|
label: 'Linear Pattern',
|
||||||
@ -1075,22 +1060,18 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
|
|||||||
patternLinear3d: {
|
patternLinear3d: {
|
||||||
label: 'Linear Pattern',
|
label: 'Linear Pattern',
|
||||||
icon: 'patternLinear3d',
|
icon: 'patternLinear3d',
|
||||||
supportsAppearance: true,
|
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
revolve: {
|
revolve: {
|
||||||
label: 'Revolve',
|
label: 'Revolve',
|
||||||
icon: 'revolve',
|
icon: 'revolve',
|
||||||
prepareToEdit: prepareToEditRevolve,
|
prepareToEdit: prepareToEditRevolve,
|
||||||
supportsAppearance: true,
|
supportsAppearance: true,
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
shell: {
|
shell: {
|
||||||
label: 'Shell',
|
label: 'Shell',
|
||||||
icon: 'shell',
|
icon: 'shell',
|
||||||
prepareToEdit: prepareToEditShell,
|
prepareToEdit: prepareToEditShell,
|
||||||
supportsAppearance: true,
|
supportsAppearance: true,
|
||||||
supportsTransform: true,
|
|
||||||
},
|
},
|
||||||
startSketchOn: {
|
startSketchOn: {
|
||||||
label: 'Sketch',
|
label: 'Sketch',
|
||||||
@ -1303,6 +1284,7 @@ export async function enterEditFlow({
|
|||||||
|
|
||||||
export async function enterAppearanceFlow({
|
export async function enterAppearanceFlow({
|
||||||
operation,
|
operation,
|
||||||
|
artifact,
|
||||||
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
|
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
|
||||||
if (operation.type !== 'StdLibCall' && operation.type !== 'KclStdLibCall') {
|
if (operation.type !== 'StdLibCall' && operation.type !== 'KclStdLibCall') {
|
||||||
return new Error(
|
return new Error(
|
||||||
@ -1318,6 +1300,7 @@ export async function enterAppearanceFlow({
|
|||||||
sourceRangeFromRust(operation.sourceRange)
|
sourceRangeFromRust(operation.sourceRange)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
console.log('argDefaultValues', argDefaultValues)
|
||||||
return {
|
return {
|
||||||
type: 'Find and select command',
|
type: 'Find and select command',
|
||||||
data: {
|
data: {
|
||||||
@ -1332,101 +1315,3 @@ export async function enterAppearanceFlow({
|
|||||||
'Appearance setting not yet supported for this operation. Please edit in the code editor.'
|
'Appearance setting not yet supported for this operation. Please edit in the code editor.'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function enterTranslateFlow({
|
|
||||||
operation,
|
|
||||||
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
|
|
||||||
const isModuleImport = operation.type === 'GroupBegin'
|
|
||||||
const isSupportedStdLibCall =
|
|
||||||
(operation.type === 'KclStdLibCall' || operation.type === 'StdLibCall') &&
|
|
||||||
stdLibMap[operation.name]?.supportsTransform
|
|
||||||
if (!isModuleImport && !isSupportedStdLibCall) {
|
|
||||||
return new Error(
|
|
||||||
'Unsupported operation type. Please edit in the code editor.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeToEdit = getNodePathFromSourceRange(
|
|
||||||
kclManager.ast,
|
|
||||||
sourceRangeFromRust(operation.sourceRange)
|
|
||||||
)
|
|
||||||
let x: KclExpression | undefined = undefined
|
|
||||||
let y: KclExpression | undefined = undefined
|
|
||||||
let z: KclExpression | undefined = undefined
|
|
||||||
const pipe = getNodeFromPath<PipeExpression>(
|
|
||||||
kclManager.ast,
|
|
||||||
nodeToEdit,
|
|
||||||
'PipeExpression'
|
|
||||||
)
|
|
||||||
if (!err(pipe) && pipe.node.body) {
|
|
||||||
const translate = pipe.node.body.find(
|
|
||||||
(n) => n.type === 'CallExpressionKw' && n.callee.name.name === 'translate'
|
|
||||||
)
|
|
||||||
if (translate?.type === 'CallExpressionKw') {
|
|
||||||
x = await retrieveArgFromPipedCallExpression(translate, 'x')
|
|
||||||
y = await retrieveArgFromPipedCallExpression(translate, 'y')
|
|
||||||
z = await retrieveArgFromPipedCallExpression(translate, 'z')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Won't be used since we provide nodeToEdit
|
|
||||||
const selection: Selections = { graphSelections: [], otherSelections: [] }
|
|
||||||
const argDefaultValues = { nodeToEdit, selection, x, y, z }
|
|
||||||
return {
|
|
||||||
type: 'Find and select command',
|
|
||||||
data: {
|
|
||||||
name: 'Translate',
|
|
||||||
groupId: 'modeling',
|
|
||||||
argDefaultValues,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function enterRotateFlow({
|
|
||||||
operation,
|
|
||||||
}: EnterEditFlowProps): Promise<Error | CommandBarMachineEvent> {
|
|
||||||
const isModuleImport = operation.type === 'GroupBegin'
|
|
||||||
const isSupportedStdLibCall =
|
|
||||||
(operation.type === 'KclStdLibCall' || operation.type === 'StdLibCall') &&
|
|
||||||
stdLibMap[operation.name]?.supportsTransform
|
|
||||||
if (!isModuleImport && !isSupportedStdLibCall) {
|
|
||||||
return new Error(
|
|
||||||
'Unsupported operation type. Please edit in the code editor.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeToEdit = getNodePathFromSourceRange(
|
|
||||||
kclManager.ast,
|
|
||||||
sourceRangeFromRust(operation.sourceRange)
|
|
||||||
)
|
|
||||||
let roll: KclExpression | undefined = undefined
|
|
||||||
let pitch: KclExpression | undefined = undefined
|
|
||||||
let yaw: KclExpression | undefined = undefined
|
|
||||||
const pipe = getNodeFromPath<PipeExpression>(
|
|
||||||
kclManager.ast,
|
|
||||||
nodeToEdit,
|
|
||||||
'PipeExpression'
|
|
||||||
)
|
|
||||||
if (!err(pipe) && pipe.node.body) {
|
|
||||||
const rotate = pipe.node.body.find(
|
|
||||||
(n) => n.type === 'CallExpressionKw' && n.callee.name.name === 'rotate'
|
|
||||||
)
|
|
||||||
if (rotate?.type === 'CallExpressionKw') {
|
|
||||||
roll = await retrieveArgFromPipedCallExpression(rotate, 'roll')
|
|
||||||
pitch = await retrieveArgFromPipedCallExpression(rotate, 'pitch')
|
|
||||||
yaw = await retrieveArgFromPipedCallExpression(rotate, 'yaw')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Won't be used since we provide nodeToEdit
|
|
||||||
const selection: Selections = { graphSelections: [], otherSelections: [] }
|
|
||||||
const argDefaultValues = { nodeToEdit, selection, roll, pitch, yaw }
|
|
||||||
return {
|
|
||||||
type: 'Find and select command',
|
|
||||||
data: {
|
|
||||||
name: 'Rotate',
|
|
||||||
groupId: 'modeling',
|
|
||||||
argDefaultValues,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
|
|
||||||
import { BSON } from 'bson'
|
|
||||||
import type { Configuration } from '@rust/kcl-lib/bindings/Configuration'
|
import type { Configuration } from '@rust/kcl-lib/bindings/Configuration'
|
||||||
import type { DefaultPlanes } from '@rust/kcl-lib/bindings/DefaultPlanes'
|
import type { DefaultPlanes } from '@rust/kcl-lib/bindings/DefaultPlanes'
|
||||||
import type { KclError as RustKclError } from '@rust/kcl-lib/bindings/KclError'
|
import type { KclError as RustKclError } from '@rust/kcl-lib/bindings/KclError'
|
||||||
@ -25,8 +24,6 @@ import { err, reportRejection } from '@src/lib/trap'
|
|||||||
import type { DeepPartial } from '@src/lib/types'
|
import type { DeepPartial } from '@src/lib/types'
|
||||||
import type { ModuleType } from '@src/lib/wasm_lib_wrapper'
|
import type { ModuleType } from '@src/lib/wasm_lib_wrapper'
|
||||||
import { getModule } from '@src/lib/wasm_lib_wrapper'
|
import { getModule } from '@src/lib/wasm_lib_wrapper'
|
||||||
import type { Models } from '@kittycad/lib/dist/types/src'
|
|
||||||
import { parseJson } from '@src/lib/utils'
|
|
||||||
|
|
||||||
export default class RustContext {
|
export default class RustContext {
|
||||||
private wasmInitFailed: boolean = true
|
private wasmInitFailed: boolean = true
|
||||||
@ -61,7 +58,6 @@ export default class RustContext {
|
|||||||
// Create a new context instance
|
// Create a new context instance
|
||||||
async create(): Promise<Context> {
|
async create(): Promise<Context> {
|
||||||
this.rustInstance = getModule()
|
this.rustInstance = getModule()
|
||||||
|
|
||||||
// We need this await here, DO NOT REMOVE it even if your editor says it's
|
// We need this await here, DO NOT REMOVE it even if your editor says it's
|
||||||
// unnecessary. The constructor of the module is async and it will not
|
// unnecessary. The constructor of the module is async and it will not
|
||||||
// resolve if you don't await it.
|
// resolve if you don't await it.
|
||||||
@ -141,7 +137,7 @@ export default class RustContext {
|
|||||||
JSON.stringify(settings)
|
JSON.stringify(settings)
|
||||||
)
|
)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
const parsed: RustKclError = parseJson(e.toString())
|
const parsed: RustKclError = JSON.parse(e.toString())
|
||||||
toast.error(parsed.msg, { id: toastId })
|
toast.error(parsed.msg, { id: toastId })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -207,21 +203,6 @@ export default class RustContext {
|
|||||||
return this.defaultPlanes[key]
|
return this.defaultPlanes[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a response back to the rust side, that we got back from the engine.
|
|
||||||
async sendResponse(
|
|
||||||
response: Models['WebSocketResponse_type']
|
|
||||||
): Promise<void> {
|
|
||||||
const instance = await this._checkInstance()
|
|
||||||
|
|
||||||
try {
|
|
||||||
const serialized = BSON.serialize(response)
|
|
||||||
await instance.sendResponse(serialized)
|
|
||||||
} catch (e: any) {
|
|
||||||
const err = errFromErrWithOutputs(e)
|
|
||||||
return Promise.reject(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to check if context instance exists
|
// Helper to check if context instance exists
|
||||||
private async _checkInstance(): Promise<Context> {
|
private async _checkInstance(): Promise<Context> {
|
||||||
if (!this.ctxInstance) {
|
if (!this.ctxInstance) {
|
||||||
|
@ -45,7 +45,6 @@ import {
|
|||||||
} from '@src/lib/utils'
|
} from '@src/lib/utils'
|
||||||
import { engineStreamActor } from '@src/machines/appMachine'
|
import { engineStreamActor } from '@src/machines/appMachine'
|
||||||
import type { ModelingMachineEvent } from '@src/machines/modelingMachine'
|
import type { ModelingMachineEvent } from '@src/machines/modelingMachine'
|
||||||
import { showUnsupportedSelectionToast } from '@src/components/ToastUnsupportedSelection'
|
|
||||||
|
|
||||||
export const X_AXIS_UUID = 'ad792545-7fd3-482a-a602-a93924e3055b'
|
export const X_AXIS_UUID = 'ad792545-7fd3-482a-a602-a93924e3055b'
|
||||||
export const Y_AXIS_UUID = '680fd157-266f-4b8a-984f-cdf46b8bdf01'
|
export const Y_AXIS_UUID = '680fd157-266f-4b8a-984f-cdf46b8bdf01'
|
||||||
@ -108,18 +107,6 @@ export async function getEventForSelectWithPoint({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _artifact = kclManager.artifactGraph.get(data.entity_id)
|
let _artifact = kclManager.artifactGraph.get(data.entity_id)
|
||||||
if (!_artifact) {
|
|
||||||
// if there's no artifact but there is a data.entity_id, it means we don't recognize the engine entity
|
|
||||||
// we should still return an empty singleCodeCursor to plug into the selection logic
|
|
||||||
// (i.e. if the user is holding shift they can keep selecting)
|
|
||||||
// but we should also put up a toast
|
|
||||||
// toast.error('some edges or faces are not currently selectable')
|
|
||||||
showUnsupportedSelectionToast()
|
|
||||||
return {
|
|
||||||
type: 'Set selection',
|
|
||||||
data: { selectionType: 'singleCodeCursor' },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const codeRefs = getCodeRefsByArtifactId(
|
const codeRefs = getCodeRefsByArtifactId(
|
||||||
data.entity_id,
|
data.entity_id,
|
||||||
kclManager.artifactGraph
|
kclManager.artifactGraph
|
||||||
|
@ -362,33 +362,17 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'translate',
|
id: 'transform',
|
||||||
onClick: () =>
|
icon: 'angle',
|
||||||
commandBarActor.send({
|
status: 'kcl-only',
|
||||||
type: 'Find and select command',
|
title: 'Transform',
|
||||||
data: { name: 'Translate', groupId: 'modeling' },
|
description: 'Apply a translation and/or rotation to a module',
|
||||||
}),
|
onClick: () => undefined,
|
||||||
status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'kcl-only',
|
|
||||||
title: 'Translate',
|
|
||||||
description: 'Apply a translation to a solid or sketch.',
|
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
label: 'API docs',
|
||||||
url: 'https://zoo.dev/docs/kcl/translate',
|
url: 'https://zoo.dev/docs/kcl/translate',
|
||||||
},
|
},
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'rotate',
|
|
||||||
onClick: () =>
|
|
||||||
commandBarActor.send({
|
|
||||||
type: 'Find and select command',
|
|
||||||
data: { name: 'Rotate', groupId: 'modeling' },
|
|
||||||
}),
|
|
||||||
status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'kcl-only',
|
|
||||||
title: 'Rotate',
|
|
||||||
description: 'Apply a rotation to a solid or sketch.',
|
|
||||||
links: [
|
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
label: 'API docs',
|
||||||
url: 'https://zoo.dev/docs/kcl/rotate',
|
url: 'https://zoo.dev/docs/kcl/rotate',
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user