merge main

This commit is contained in:
benjamaan476
2025-06-05 12:31:11 +01:00
429 changed files with 37330 additions and 270988 deletions

View File

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

853
.github/dependabot.yml vendored

File diff suppressed because it is too large Load Diff

View File

@ -20,9 +20,11 @@ permissions:
jobs: jobs:
prepare-wasm: prepare-wasm:
# separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner # separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64 runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- id: filter - id: filter
@ -103,9 +105,10 @@ jobs:
needs: [prepare-wasm] needs: [prepare-wasm]
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64 runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
name: playwright:snapshots:ubuntu name: e2e:snapshots
steps: steps:
- uses: actions/create-github-app-token@v1 - uses: actions/create-github-app-token@v1
id: app-token id: app-token
with: with:
@ -135,7 +138,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm install run: npm install
- name: Cache browsers - name: Download browser cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
@ -145,7 +148,7 @@ jobs:
- name: Install browsers - name: Install browsers
run: npm run playwright install --with-deps run: npm run playwright install --with-deps
- name: Test snapshots - name: npm run test:snapshots
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
with: with:
shell: bash shell: bash
@ -214,8 +217,12 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, windows-latest, macos-latest] include:
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- os: namespace-profile-macos-8-cores
- os: windows-latest-8-cores
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
name: e2e:web (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }})
env: env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
@ -250,7 +257,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm install run: npm install
- name: Cache browsers - name: Download browser cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
@ -267,7 +274,7 @@ jobs:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }} GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }} OS_NAME: ${{ env.OS_NAME }}
- name: Test web - name: npm run test:e2e:web
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
with: with:
shell: bash shell: bash
@ -336,7 +343,7 @@ jobs:
shardIndex: 2 shardIndex: 2
shardTotal: 2 shardTotal: 2
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} (shard ${{ matrix.shardIndex }}) name: e2e:desktop (${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}, shard ${{ matrix.shardIndex }})
env: env:
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }} OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
@ -346,7 +353,7 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
name: prepared-wasm name: prepared-wasm
- name: Copy prepared wasm - name: Copy prepared Wasm
run: | run: |
ls -R prepared-wasm ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public cp prepared-wasm/kcl_wasm_lib_bg.wasm public
@ -362,7 +369,7 @@ jobs:
id: deps-install id: deps-install
run: npm install run: npm install
- name: Cache browsers - name: Download browser cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
@ -372,9 +379,6 @@ jobs:
- name: Install browsers - name: Install browsers
run: npm run playwright install --with-deps run: npm run playwright install --with-deps
- name: Build web
run: npm run tronb:vite:dev
- name: Start Vector - name: Start Vector
if: ${{ !contains(matrix.os, 'windows') }} if: ${{ !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
@ -382,6 +386,9 @@ jobs:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }} GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }} OS_NAME: ${{ env.OS_NAME }}
- name: Build app
run: npm run tronb:vite:dev
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }} if: ${{ !cancelled() && (success() || failure()) }}
continue-on-error: true continue-on-error: true
@ -389,7 +396,7 @@ jobs:
name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
- name: Run playwright/electron flow (with retries) - name: npm run test:e2e:desktop
id: retry id: retry
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }} if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2

View File

@ -213,14 +213,21 @@ npm run test:snapshots
``` ```
You may use `-- --update-snapshots` as needed. You may use `-- --update-snapshots` as needed.
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows) #### Desktop tests (Electron on all platforms)
``` ```
npm run playwright -- install chromium npm run playwright -- install chromium
npm run test:playwright:electron:local npm run test:e2e:desktop:local
``` ```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file. You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Web tests (Google Chrome on all platforms)
```
npm run test:e2e:web
```
#### Debugger #### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying. However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.

View File

@ -129,9 +129,9 @@ endif
.PHONY: test-e2e-desktop .PHONY: test-e2e-desktop
test-e2e-desktop: install build ## Run the desktop e2e tests test-e2e-desktop: install build ## Run the desktop e2e tests
ifdef E2E_GREP ifdef E2E_GREP
npm run test:playwright:electron -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES) npm run test:e2e:desktop -- --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else else
npm run test:playwright:electron -- --workers='100%' npm run test:e2e:desktop -- --workers='100%'
endif endif
############################################################################### ###############################################################################

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,24 +1,23 @@
--- ---
title: "appearance::hexString" title: "appearance::hexString"
subtitle: "Function in std::appearance" subtitle: "Function in std::appearance"
excerpt: "" excerpt: "Build a color from its red, green and blue components. These must be between 0 and 255."
layout: manual layout: manual
--- ---
Build a color from its red, green and blue components. These must be between 0 and 255.
```kcl ```kcl
appearance::hexString(@rgb: [number(_); 3]): string appearance::hexString(@rgb: [number(_); 3]): string
``` ```
Build a color from its red, green and blue components.
These must be between 0 and 255.
### Arguments ### Arguments
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `rgb` | [`[number(_); 3]`](/docs/kcl-std/types/std-types-number) | | Yes | | `rgb` | [`[number(_); 3]`](/docs/kcl-std/types/std-types-number) | The red, blue and green components of the color. Must be between 0 and 255. | Yes |
### Returns ### Returns

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

@ -10,18 +10,21 @@ Construct a line segment from the current origin back to the profile's origin, e
```kcl ```kcl
close( close(
@sketch: Sketch, @sketch: Sketch,
tag?: TagDeclarator, tag?: tag,
): Sketch ): Sketch
``` ```
If you want to perform some 3-dimensional operation on a sketch, like
extrude or sweep, you must `close` it first. `close` must be called even
if the end point of the last segment is coincident with the sketch
starting point.
### Arguments ### Arguments
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | The sketch you want to close | Yes | | `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | The sketch you want to close. | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No | | [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
### Returns ### Returns

View File

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

View File

@ -8,7 +8,7 @@ layout: manual
Get the shared edge between two faces. Get the shared edge between two faces.
```kcl ```kcl
getCommonEdge(faces: [TagIdentifier]): Uuid getCommonEdge(faces: [tag; 2]): Edge
``` ```
@ -17,11 +17,11 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `faces` | [`[TagIdentifier]`](/docs/kcl-lang/types#TagIdentifier) | The tags of the faces you want to find the common edge between | Yes | | `faces` | `[tag; 2]` | The tags of the faces you want to find the common edge between. | Yes |
### Returns ### Returns
`Uuid` [`Edge`](/docs/kcl-std/types/std-types-Edge) - An edge of a solid.
### Examples ### Examples
@ -29,7 +29,6 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
```kcl ```kcl
// Get an edge shared between two faces, created after a chamfer. // Get an edge shared between two faces, created after a chamfer.
scale = 20 scale = 20
part001 = startSketchOn(XY) part001 = startSketchOn(XY)
|> startProfile(at = [0, 0]) |> startProfile(at = [0, 0])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

@ -1,6 +1,6 @@
--- ---
title: "patternLinear2d" title: "patternLinear2d"
subtitle: "Function in std" subtitle: "Function in std::sketch"
excerpt: "Repeat a 2-dimensional sketch along some dimension, with a dynamic amount of distance between each repetition, some specified number of times." excerpt: "Repeat a 2-dimensional sketch along some dimension, with a dynamic amount of distance between each repetition, some specified number of times."
layout: manual layout: manual
--- ---
@ -9,12 +9,12 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount of dis
```kcl ```kcl
patternLinear2d( patternLinear2d(
@sketches: [Sketch], @sketches: [Sketch; 1+],
instances: number, instances: number(_),
distance: number, distance: number(Length),
axis: Point2d, axis: Axis2d | Point2d,
useOriginal?: bool, useOriginal?: bool,
): [Sketch] ): [Sketch; 1+]
``` ```
@ -23,15 +23,15 @@ patternLinear2d(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | The sketch(es) to duplicate | Yes | | `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | The sketch(es) to duplicate. | Yes |
| `instances` | [`number`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes | | `instances` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `distance` | [`number`](/docs/kcl-std/types/std-types-number) | Distance between each repetition. Also known as 'spacing'. | Yes | | `distance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Distance between each repetition. Also known as 'spacing'. | Yes |
| `axis` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The axis of the pattern. A 2D vector. | Yes | | `axis` | [`Axis2d`](/docs/kcl-std/types/std-types-Axis2d) or [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The axis of the pattern. A 2D vector. | Yes |
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No | | `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No |
### Returns ### Returns
[`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch)
### Examples ### Examples
@ -39,10 +39,13 @@ patternLinear2d(
```kcl ```kcl
/// Pattern using a named axis. /// Pattern using a named axis.
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 1) |> circle(center = [0, 0], radius = 1)
|> patternLinear2d(axis = X, instances = 7, distance = 4) |> patternLinear2d(
axis = X,
instances = 7,
distance = 4
)
example = extrude(exampleSketch, length = 1) example = extrude(exampleSketch, length = 1)
``` ```
@ -52,10 +55,13 @@ example = extrude(exampleSketch, length = 1)
```kcl ```kcl
/// Pattern using a raw axis. /// Pattern using a raw axis.
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 1) |> circle(center = [0, 0], radius = 1)
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4) |> patternLinear2d(
axis = [1, 0],
instances = 7,
distance = 4
)
example = extrude(exampleSketch, length = 1) example = extrude(exampleSketch, length = 1)
``` ```

View File

@ -9,9 +9,9 @@ Create a regular polygon with the specified number of sides that is either inscr
```kcl ```kcl
polygon( polygon(
@sketchSurfaceOrGroup: Sketch | Plane | Face, @sketchOrSurface: Sketch | Plane | Face,
radius: number, radius: number(Length),
numSides: u64, numSides: number(_),
center: Point2d, center: Point2d,
inscribed?: bool, inscribed?: bool,
): Sketch ): Sketch
@ -23,11 +23,11 @@ polygon(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on | Yes | | `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on. | Yes |
| `radius` | [`number`](/docs/kcl-std/types/std-types-number) | The radius of the polygon | Yes | | `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the polygon. | Yes |
| `numSides` | `u64` | The number of sides in the polygon | Yes | | `numSides` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of sides in the polygon. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center point of the polygon | Yes | | `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center point of the polygon. | Yes |
| `inscribed` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius | No | | `inscribed` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius. | No |
### Returns ### Returns

View File

@ -8,7 +8,7 @@ layout: manual
Extract the provided 2-dimensional sketch's profile's origin value. Extract the provided 2-dimensional sketch's profile's origin value.
```kcl ```kcl
profileStart(@profile: Sketch): [number] profileStart(@profile: Sketch): Point2d
``` ```
@ -17,11 +17,11 @@ profileStart(@profile: Sketch): [number]
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `profile` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Profile whose start is being used | Yes | | `profile` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Profile whose start is being used. | Yes |
### Returns ### Returns
[`[number]`](/docs/kcl-std/types/std-types-number) [`Point2d`](/docs/kcl-std/types/std-types-Point2d) - A point in two dimensional space.
### Examples ### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Extract the provided 2-dimensional sketch's profile's origin's 'x' value. Extract the provided 2-dimensional sketch's profile's origin's 'x' value.
```kcl ```kcl
profileStartX(@profile: Sketch): number profileStartX(@profile: Sketch): number(Length)
``` ```
@ -17,11 +17,11 @@ profileStartX(@profile: Sketch): number
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `profile` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Profile whose start is being used | Yes | | `profile` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Profile whose start is being used. | Yes |
### Returns ### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number. [`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples ### Examples

View File

@ -8,7 +8,7 @@ layout: manual
Extract the provided 2-dimensional sketch's profile's origin's 'y' value. Extract the provided 2-dimensional sketch's profile's origin's 'y' value.
```kcl ```kcl
profileStartY(@profile: Sketch): number profileStartY(@profile: Sketch): number(Length)
``` ```
@ -17,11 +17,11 @@ profileStartY(@profile: Sketch): number
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `profile` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Profile whose start is being used | Yes | | `profile` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Profile whose start is being used. | Yes |
### Returns ### Returns
[`number`](/docs/kcl-std/types/std-types-number) - A number. [`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
### Examples ### Examples

View File

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

View File

@ -8,7 +8,7 @@ layout: manual
Compute the ending point of the provided line segment. Compute the ending point of the provided line segment.
```kcl ```kcl
segEnd(@tag: TagIdentifier): Point2d segEnd(@tag: tag): Point2d
``` ```
@ -17,7 +17,7 @@ segEnd(@tag: TagIdentifier): Point2d
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes | | [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns ### Returns

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ layout: manual
Compute the starting point of the provided line segment. Compute the starting point of the provided line segment.
```kcl ```kcl
segStart(@tag: TagIdentifier): Point2d segStart(@tag: tag): Point2d
``` ```
@ -17,7 +17,7 @@ segStart(@tag: TagIdentifier): Point2d
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The line segment being queried by its tag | Yes | | [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | The line segment being queried by its tag. | Yes |
### Returns ### Returns

View File

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

View File

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

View File

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

View File

@ -9,8 +9,8 @@ Start a new 2-dimensional sketch on a specific plane or face.
```kcl ```kcl
startSketchOn( startSketchOn(
@planeOrSolid: Plane | Solid, @planeOrSolid: Solid | Plane,
face?: TagIdentifier | Start | End, face?: tag,
): Plane | Face ): Plane | Face
``` ```
@ -18,22 +18,29 @@ startSketchOn(
There are some important behaviors to understand when sketching on a face: There are some important behaviors to understand when sketching on a face:
The resulting sketch will _include_ the face and thus Solid that was sketched on. So say you were to export the resulting Sketch / Solid from a sketch on a face, you would get both the artifact of the sketch on the face and the parent face / Solid itself. The resulting sketch will _include_ the face and thus Solid
that was sketched on. So say you were to export the resulting Sketch / Solid
from a sketch on a face, you would get both the artifact of the sketch
on the face and the parent face / Solid itself.
This is important to understand because if you were to then sketch on the resulting Solid, it would again include the face and parent Solid that was sketched on. This could go on indefinitely. This is important to understand because if you were to then sketch on the
resulting Solid, it would again include the face and parent Solid that was
sketched on. This could go on indefinitely.
The point is if you want to export the result of a sketch on a face, you only need to export the final Solid that was created from the sketch on the face, since it will include all the parent faces and Solids. The point is if you want to export the result of a sketch on a face, you
only need to export the final Solid that was created from the sketch on the
face, since it will include all the parent faces and Solids.
### Arguments ### Arguments
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `planeOrSolid` | [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Solid`](/docs/kcl-std/types/std-types-Solid) | The plane or solid to sketch on | Yes | | `planeOrSolid` | [`Solid`](/docs/kcl-std/types/std-types-Solid) or [`Plane`](/docs/kcl-std/types/std-types-Plane) | Profile whose start is being used. | Yes |
| `face` | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) or [`Start`](/docs/kcl-lang/types#Start) or [`End`](/docs/kcl-lang/types#End) | Identify a face of a solid if a solid is specified as the input argument (`plane_or_solid`) | No | | `face` | [`tag`](/docs/kcl-std/types/std-types-tag) | Identify a face of a solid if a solid is specified as the input argument (`planeOrSolid`). | No |
### Returns ### Returns
[`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) - A sketch type. [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face)
### Examples ### Examples
@ -72,7 +79,6 @@ example003 = extrude(exampleSketch003, length = 5)
```kcl ```kcl
// Sketch on the end of an extruded face by tagging the end face. // Sketch on the end of an extruded face by tagging the end face.
exampleSketch = startSketchOn(XY) exampleSketch = startSketchOn(XY)
|> startProfile(at = [0, 0]) |> startProfile(at = [0, 0])
|> line(end = [10, 0]) |> line(end = [10, 0])
@ -163,7 +169,6 @@ example002 = extrude(exampleSketch002, length = 5)
```kcl ```kcl
// Sketch on the end of a revolved face by tagging the end face. // Sketch on the end of a revolved face by tagging the end face.
exampleSketch = startSketchOn(XY) exampleSketch = startSketchOn(XY)
|> startProfile(at = [4, 12]) |> startProfile(at = [4, 12])
|> line(end = [2, 0]) |> line(end = [2, 0])
@ -175,12 +180,7 @@ exampleSketch = startSketchOn(XY)
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
example = revolve( example = revolve(exampleSketch, axis = Y, angle = 180, tagEnd = $end01)
exampleSketch,
axis = Y,
angle = 180,
tagEnd = $end01,
)
exampleSketch002 = startSketchOn(example, face = end01) exampleSketch002 = startSketchOn(example, face = end01)
|> startProfile(at = [4.5, -5]) |> startProfile(at = [4.5, -5])

File diff suppressed because one or more lines are too long

View File

@ -9,35 +9,40 @@ Extrude a sketch along a path.
```kcl ```kcl
sweep( sweep(
@sketches: [Sketch], @sketches: [Sketch; 1+],
path: Sketch | Helix, path: Sketch | Helix,
sectional?: bool, sectional?: bool,
tolerance?: number, tolerance?: number(Length),
relativeTo?: string, relativeTo?: string,
tagStart?: TagDeclarator, tagStart?: tag,
tagEnd?: TagDeclarator, tagEnd?: tag,
): [Solid] ): [Solid; 1+]
``` ```
This, like extrude, is able to create a 3-dimensional solid from a 2-dimensional sketch. However, unlike extrude, this creates a solid by using the extent of the sketch as its path. This is useful for creating more complex shapes that can't be created with a simple extrusion. This, like extrude, is able to create a 3-dimensional solid from a
2-dimensional sketch. However, unlike extrude, this creates a solid
by using the extent of the sketch as its path. This is useful for
creating more complex shapes that can't be created with a simple
extrusion.
You can provide more than one sketch to sweep, and they will all be swept along the same path. You can provide more than one sketch to sweep, and they will all be
swept along the same path.
### Arguments ### Arguments
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | The sketch or set of sketches that should be swept in space | Yes | | `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | The sketch or set of sketches that should be swept in space. | Yes |
| `path` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Helix`](/docs/kcl-std/types/std-types-Helix) | The path to sweep the sketch along | Yes | | `path` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Helix`](/docs/kcl-std/types/std-types-Helix) | The path to sweep the sketch along. | Yes |
| `sectional` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. | No | | `sectional` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. | No |
| `tolerance` | [`number`](/docs/kcl-std/types/std-types-number) | Tolerance for this operation | No | | `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Tolerance for this operation. | No |
| `relativeTo` | [`string`](/docs/kcl-std/types/std-types-string) | What is the sweep relative to? Can be either 'sketchPlane' or 'trajectoryCurve'. Defaults to trajectoryCurve. | No | | `relativeTo` | [`string`](/docs/kcl-std/types/std-types-string) | What is the sweep relative to? Can be either 'sketchPlane' or 'trajectoryCurve'. | No |
| `tagStart` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the start of the sweep, i.e. the original sketch | No | | `tagStart` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the start of the sweep, i.e. the original sketch. | No |
| `tagEnd` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the end of the sweep | No | | `tagEnd` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the end of the sweep. | No |
### Returns ### Returns
[`[Solid]`](/docs/kcl-std/types/std-types-Solid) [`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid)
### Examples ### Examples
@ -56,10 +61,16 @@ sweepPath = startSketchOn(XZ)
// Create a hole for the pipe. // Create a hole for the pipe.
pipeHole = startSketchOn(XY) pipeHole = startSketchOn(XY)
|> circle(center = [0, 0], radius = 1.5) |> circle(
center = [0, 0],
radius = 1.5,
)
sweepSketch = startSketchOn(XY) sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2) |> circle(
center = [0, 0],
radius = 2,
)
|> subtract2d(tool = pipeHole) |> subtract2d(tool = pipeHole)
|> sweep(path = sweepPath) |> sweep(path = sweepPath)
``` ```
@ -79,6 +90,7 @@ helixPath = helix(
axis = Z, axis = Z,
) )
// Create a spring by sweeping around the helix path. // Create a spring by sweeping around the helix path.
springSketch = startSketchOn(XZ) springSketch = startSketchOn(XZ)
|> circle( center = [5, 0], radius = 1) |> circle( center = [5, 0], radius = 1)
@ -90,12 +102,17 @@ springSketch = startSketchOn(XZ)
```kcl ```kcl
// Sweep two sketches along the same path. // Sweep two sketches along the same path.
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
rectangleSketch = startProfile(sketch001, at = [-200, 23.86]) rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61) |> angledLine(
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001)) angle = segAng(rectangleSegmentA001) - 90,
length = 50.61,
)
|> angledLine(
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001),
)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
@ -115,7 +132,6 @@ sweep([rectangleSketch, circleSketch], path = sweepPath)
```kcl ```kcl
// Sectionally sweep one sketch along the path // Sectionally sweep one sketch along the path
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)

View File

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

View File

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

View File

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

View File

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

View File

@ -1,11 +1,11 @@
--- ---
title: "intersect" title: "intersect"
subtitle: "Function in std::solid" subtitle: "Function in std::solid"
excerpt: "" excerpt: "Intersect returns the shared volume between multiple solids, preserving only overlapping regions."
layout: manual layout: manual
--- ---
Intersect returns the shared volume between multiple solids, preserving only overlapping regions.
```kcl ```kcl
intersect( intersect(
@ -14,8 +14,6 @@ intersect(
): [Solid; 1+] ): [Solid; 1+]
``` ```
Intersect returns the shared volume between multiple solids, preserving only
overlapping regions.
Intersect computes the geometric intersection of multiple solid bodies, Intersect computes the geometric intersection of multiple solid bodies,
returning a new solid representing the volume that is common to all input returning a new solid representing the volume that is common to all input
solids. This operation is useful for determining shared material regions, solids. This operation is useful for determining shared material regions,

View File

@ -1,11 +1,11 @@
--- ---
title: "patternCircular3d" title: "patternCircular3d"
subtitle: "Function in std::solid" subtitle: "Function in std::solid"
excerpt: "" excerpt: "Repeat a 3-dimensional solid some number of times along a partial or complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orientation of the solid with respect to the center of the circle is maintained."
layout: manual layout: manual
--- ---
Repeat a 3-dimensional solid some number of times along a partial or complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orientation of the solid with respect to the center of the circle is maintained.
```kcl ```kcl
patternCircular3d( patternCircular3d(
@ -19,9 +19,7 @@ patternCircular3d(
): [Solid; 1+] ): [Solid; 1+]
``` ```
Repeat a 3-dimensional solid some number of times along a partial or
complete circle some specified number of times. Each object mayadditionally be rotated along the circle, ensuring orientation of the
solid with respect to the center of the circle is maintained.
### Arguments ### Arguments

View File

@ -1,11 +1,11 @@
--- ---
title: "patternLinear3d" title: "patternLinear3d"
subtitle: "Function in std::solid" subtitle: "Function in std::solid"
excerpt: "" excerpt: "Repeat a 3-dimensional solid along a linear path, with a dynamic amount of distance between each repetition, some specified number of times."
layout: manual layout: manual
--- ---
Repeat a 3-dimensional solid along a linear path, with a dynamic amount of distance between each repetition, some specified number of times.
```kcl ```kcl
patternLinear3d( patternLinear3d(
@ -17,8 +17,7 @@ patternLinear3d(
): [Solid; 1+] ): [Solid; 1+]
``` ```
Repeat a 3-dimensional solid along a linear path, with a dynamic amount
of distance between each repetition, some specified number of times.
### Arguments ### Arguments

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

@ -36,10 +36,9 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui
* [`Y`](/docs/kcl-std/consts/std-Y) * [`Y`](/docs/kcl-std/consts/std-Y)
* [`YZ`](/docs/kcl-std/consts/std-YZ) * [`YZ`](/docs/kcl-std/consts/std-YZ)
* [`Z`](/docs/kcl-std/consts/std-Z) * [`Z`](/docs/kcl-std/consts/std-Z)
* [`assert`](/docs/kcl-std/assert) * [`assert`](/docs/kcl-std/functions/std-assert)
* [`assertIs`](/docs/kcl-std/assertIs) * [`assertIs`](/docs/kcl-std/functions/std-assertIs)
* [`clone`](/docs/kcl-std/functions/std-clone) * [`clone`](/docs/kcl-std/functions/std-clone)
* [`helix`](/docs/kcl-std/functions/std-helix) * [`helix`](/docs/kcl-std/functions/std-helix)
* [`offsetPlane`](/docs/kcl-std/functions/std-offsetPlane) * [`offsetPlane`](/docs/kcl-std/functions/std-offsetPlane)
* [`patternLinear2d`](/docs/kcl-std/patternLinear2d)

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -534,7 +534,7 @@ profile001 = startProfile(sketch001, at = [-484.34, 484.95])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
` `
const targetURL = `?create-file&name=test&units=mm&code=${encodeURIComponent(btoa(code))}&ask-open-desktop` const targetURL = `?create-file=true&name=test&units=mm&code=${encodeURIComponent(btoa(code))}&ask-open-desktop=true`
await page.goto(page.url() + targetURL) await page.goto(page.url() + targetURL)
expect(page.url()).toContain(targetURL) expect(page.url()).toContain(targetURL)
}) })

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1733,7 +1733,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
await page.waitForTimeout(600) await page.waitForTimeout(600)
}) })
const codeFromTangentialArc = ` |> tangentialArc(endAbsolute = [39.49, 88.22])` const codeFromTangentialArc = ` |> tangentialArc(end = [-10.82, 144.95])`
await test.step('check that tangential tool does not snap to other profile starts', async () => { await test.step('check that tangential tool does not snap to other profile starts', async () => {
await toolbar.selectTangentialArc() await toolbar.selectTangentialArc()
await page.waitForTimeout(1000) await page.waitForTimeout(1000)
@ -1755,7 +1755,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
// check pixel is now gray at tanArcLocation to verify code has executed // check pixel is now gray at tanArcLocation to verify code has executed
await scene.expectPixelColor([26, 26, 26], tanArcLocation, 15) await scene.expectPixelColor([26, 26, 26], tanArcLocation, 15)
await editor.expectEditor.not.toContain( await editor.expectEditor.not.toContain(
`tangentialArc(endAbsolute = [39.49, 88.22])` `tangentialArc(end = [-10.82, 144.95])`
) )
}) })
@ -1955,7 +1955,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
await endArcStartLine() await endArcStartLine()
await editor.expectEditor.toContain( await editor.expectEditor.toContain(
`|> tangentialArc(endAbsolute = [16.61, 4.14])` `|> tangentialArc(end = [2.98, -7.52])`
) )
// Add a three-point arc segment // Add a three-point arc segment
@ -2362,7 +2362,7 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
await test.step('add new profile', async () => { await test.step('add new profile', async () => {
await toolbar.rectangleBtn.click() await toolbar.rectangleBtn.click()
await page.waitForTimeout(100) await page.waitForTimeout(200)
await rectStart() await rectStart()
await editor.expectEditor.toContain( await editor.expectEditor.toContain(
`profile005 = startProfile(sketch001, at = [15.68, -3.84])` `profile005 = startProfile(sketch001, at = [15.68, -3.84])`
@ -3181,7 +3181,7 @@ test.describe('Redirecting to home page and back to the original file should cle
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn(XZ)
profile001 = startProfile(sketch001, at = [0, 0]) profile001 = startProfile(sketch001, at = [0, 0])
|> line(end = [191.39, 191.39]) |> line(end = [191.39, 191.39])
|> tangentialArc(endAbsolute = [287.08, 95.69], tag = $seg01) |> tangentialArc(end = [95.69, -95.7], tag = $seg01)
|> angledLine(angle = tangentToEnd(seg01), length = 135.34) |> angledLine(angle = tangentToEnd(seg01), length = 135.34)
|> arc(interiorAbsolute = [191.39, -95.69], endAbsolute = [287.08, -95.69], tag = $seg02) |> arc(interiorAbsolute = [191.39, -95.69], endAbsolute = [287.08, -95.69], tag = $seg02)
|> angledLine(angle = tangentToEnd(seg02) + turns::HALF_TURN, length = 270.67) |> angledLine(angle = tangentToEnd(seg02) + turns::HALF_TURN, length = 270.67)

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -14,8 +14,10 @@ test.describe('Test network related behaviors', () => {
'simulate network down and network little widget', 'simulate network down and network little widget',
{ tag: '@skipLocalEngine' }, { tag: '@skipLocalEngine' },
async ({ page, homePage }) => { async ({ page, homePage }) => {
const networkToggleConnectedText = page.getByText('Connected') const networkToggleConnectedText = page.getByText(
const networkToggleWeakText = page.getByText('Network health (Weak)') 'Network health (Strong)'
)
const networkToggleWeakText = page.getByText('Network health (Ok)')
const u = await getUtils(page) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
@ -61,7 +63,7 @@ test.describe('Test network related behaviors', () => {
}) })
// Expect the network to be down // Expect the network to be down
await expect(networkToggle).toContainText('Problem') await expect(networkToggle).toContainText('Network health (Offline)')
// Click the network widget // Click the network widget
await networkWidget.click() await networkWidget.click()
@ -98,8 +100,10 @@ test.describe('Test network related behaviors', () => {
{ tag: '@skipLocalEngine' }, { tag: '@skipLocalEngine' },
async ({ page, homePage, toolbar, scene, cmdBar }) => { async ({ page, homePage, toolbar, scene, cmdBar }) => {
const networkToggle = page.getByTestId('network-toggle') const networkToggle = page.getByTestId('network-toggle')
const networkToggleConnectedText = page.getByText('Connected') const networkToggleConnectedText = page.getByText(
const networkToggleWeakText = page.getByText('Network health (Weak)') 'Network health (Strong)'
)
const networkToggleWeakText = page.getByText('Network health (Ok)')
const u = await getUtils(page) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
@ -156,7 +160,8 @@ test.describe('Test network related behaviors', () => {
// Expect the network to be down // Expect the network to be down
await networkToggle.hover() await networkToggle.hover()
await expect(networkToggle).toContainText('Problem')
await expect(networkToggle).toContainText('Network health (Offline)')
// Ensure we are not in sketch mode // Ensure we are not in sketch mode
await expect( await expect(
@ -279,11 +284,13 @@ profile001 = startProfile(sketch001, at = [12.34, -12.34])
test( test(
'Paused stream freezes view frame, unpause reconnect is seamless to user', 'Paused stream freezes view frame, unpause reconnect is seamless to user',
{ tag: ['@electron', '@skipLocalEngine'] }, { tag: ['@desktop', '@skipLocalEngine'] },
async ({ page, homePage, scene, cmdBar, toolbar, tronApp }) => { async ({ page, homePage, scene, cmdBar, toolbar, tronApp }) => {
const networkToggle = page.getByTestId('network-toggle') const networkToggle = page.getByTestId('network-toggle')
const networkToggleConnectedText = page.getByText('Connected') const networkToggleConnectedText = page.getByText(
const networkToggleWeakText = page.getByText('Network health (Weak)') 'Network health (Strong)'
)
const networkToggleWeakText = page.getByText('Network health (Ok)')
if (!tronApp) { if (!tronApp) {
fail() fail()

View File

@ -79,20 +79,6 @@ export function runningOnWindows() {
return process.platform === 'win32' return process.platform === 'win32'
} }
async function waitForPageLoadWithRetry(page: Page) {
await expect(async () => {
await page.goto('/')
const errorMessage = 'App failed to load - 🔃 Retrying ...'
await expect(
page.getByRole('button', { name: 'sketch Start Sketch' }),
errorMessage
).toBeEnabled({
timeout: 20_000,
})
}).toPass({ timeout: 70_000, intervals: [1_000] })
}
// lee: This needs to be replaced by scene.settled() eventually. // lee: This needs to be replaced by scene.settled() eventually.
async function waitForPageLoad(page: Page) { async function waitForPageLoad(page: Page) {
await expect(page.getByRole('button', { name: 'Start Sketch' })).toBeEnabled({ await expect(page.getByRole('button', { name: 'Start Sketch' })).toBeEnabled({
@ -354,13 +340,8 @@ async function waitForAuthAndLsp(page: Page) {
}, },
timeout: 45_000, timeout: 45_000,
}) })
if (process.env.CI) {
await waitForPageLoadWithRetry(page)
} else {
await page.goto('/') await page.goto('/')
await waitForPageLoad(page) await waitForPageLoad(page)
}
return waitForLspPromise return waitForLspPromise
} }
@ -383,15 +364,9 @@ export async function getUtils(page: Page, test_?: typeof test) {
) )
} }
// Chrome devtools protocol session only works in Chromium
const browserType = page.context().browser()?.browserType().name()
const cdpSession =
browserType !== 'chromium' ? null : await page.context().newCDPSession(page)
const util = { const util = {
waitForAuthSkipAppStart: () => waitForAuthAndLsp(page), waitForAuthSkipAppStart: () => waitForAuthAndLsp(page),
waitForPageLoad: () => waitForPageLoad(page), waitForPageLoad: () => waitForPageLoad(page),
waitForPageLoadWithRetry: () => waitForPageLoadWithRetry(page),
removeCurrentCode: () => removeCurrentCode(page), removeCurrentCode: () => removeCurrentCode(page),
sendCustomCmd: (cmd: EngineCommand) => sendCustomCmd(page, cmd), sendCustomCmd: (cmd: EngineCommand) => sendCustomCmd(page, cmd),
updateCamPosition: async (xyz: [number, number, number]) => { updateCamPosition: async (xyz: [number, number, number]) => {
@ -509,15 +484,9 @@ export async function getUtils(page: Page, test_?: typeof test) {
emulateNetworkConditions: async ( emulateNetworkConditions: async (
networkOptions: Protocol.Network.emulateNetworkConditionsParameters networkOptions: Protocol.Network.emulateNetworkConditionsParameters
) => { ) => {
if (cdpSession === null) { return networkOptions.offline
// Use a fail safe if we can't simulate disconnect (on Safari) ? page.evaluate('window.engineCommandManager.offline()')
return page.evaluate('window.engineCommandManager.tearDown()') : page.evaluate('window.engineCommandManager.online()')
}
return cdpSession?.send(
'Network.emulateNetworkConditions',
networkOptions
)
}, },
toNormalizedCode(text: string) { toNormalizedCode(text: string) {

View File

@ -3,102 +3,189 @@ import { uuidv4 } from '@src/lib/utils'
import { getUtils } from '@e2e/playwright/test-utils' import { getUtils } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test' import { expect, test } from '@e2e/playwright/zoo-test'
import type { Page } from '@playwright/test'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
test.describe('Testing Camera Movement', () => { test.describe('Testing Camera Movement', () => {
test('Can move camera reliably', async ({ /**
* hack that we're implemented our own retry instead of using retries built into playwright.
* however each of these camera drags can be flaky, because of udp
* and so putting them together means only one needs to fail to make this test extra flaky.
* this way we can retry within the test
* We could break them out into separate tests, but the longest past of the test is waiting
* for the stream to start, so it can be good to bundle related things together.
*/
const bakeInRetries = async ({
mouseActions,
afterPosition,
beforePosition,
retryCount = 0,
page, page,
context,
homePage,
scene, scene,
}: {
mouseActions: () => Promise<void>
beforePosition: [number, number, number]
afterPosition: [number, number, number]
retryCount?: number
page: Page
scene: SceneFixture
}) => { }) => {
const acceptableCamError = 5
const u = await getUtils(page) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await test.step('Set up initial camera position', async () =>
await scene.connectionEstablished() await scene.moveCameraTo({
x: beforePosition[0],
y: beforePosition[1],
z: beforePosition[2],
}))
await u.openAndClearDebugPanel() await test.step('Do actions and watch for changes', async () =>
await u.closeKclCodePanel() u.doAndWaitForImageDiff(async () => {
const camPos: [number, number, number] = [0, 85, 85]
const bakeInRetries = async (
mouseActions: any,
xyz: [number, number, number],
cnt = 0
) => {
// hack that we're implemented our own retry instead of using retries built into playwright.
// however each of these camera drags can be flaky, because of udp
// and so putting them together means only one needs to fail to make this test extra flaky.
// this way we can retry within the test
// We could break them out into separate tests, but the longest past of the test is waiting
// for the stream to start, so it can be good to bundle related things together.
const camCommand: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
center: { x: 0, y: 0, z: 0 },
vantage: { x: camPos[0], y: camPos[1], z: camPos[2] },
up: { x: 0, y: 0, z: 1 },
},
}
const updateCamCommand: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
}
await u.sendCustomCmd(camCommand)
await page.waitForTimeout(100)
await u.sendCustomCmd(updateCamCommand)
await page.waitForTimeout(100)
// rotate
await u.closeDebugPanel()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(100)
// const yo = page.getByTestId('cam-x-position').inputValue()
await u.doAndWaitForImageDiff(async () => {
await mouseActions() await mouseActions()
await u.openAndClearDebugPanel() await u.openAndClearDebugPanel()
await u.closeDebugPanel() await u.closeDebugPanel()
await page.waitForTimeout(100) await page.waitForTimeout(100)
}, 300) }, 300))
await u.openAndClearDebugPanel() await u.openAndClearDebugPanel()
await page.getByTestId('cam-x-position').isVisible() await expect(page.getByTestId('cam-x-position')).toBeAttached()
const vals = await Promise.all([ const vals = await Promise.all([
page.getByTestId('cam-x-position').inputValue(), page.getByTestId('cam-x-position').inputValue(),
page.getByTestId('cam-y-position').inputValue(), page.getByTestId('cam-y-position').inputValue(),
page.getByTestId('cam-z-position').inputValue(), page.getByTestId('cam-z-position').inputValue(),
]) ])
const xError = Math.abs(Number(vals[0]) + xyz[0]) const errors = vals.map((v, i) => Math.abs(Number(v) - afterPosition[i]))
const yError = Math.abs(Number(vals[1]) + xyz[1])
const zError = Math.abs(Number(vals[2]) + xyz[2])
let shouldRetry = false let shouldRetry = false
if (xError > 5 || yError > 5 || zError > 5) { if (errors.some((e) => e > acceptableCamError)) {
if (cnt > 2) { if (retryCount > 2) {
console.log('xVal', vals[0], 'xError', xError) console.log('xVal', vals[0], 'xError', errors[0])
console.log('yVal', vals[1], 'yError', yError) console.log('yVal', vals[1], 'yError', errors[1])
console.log('zVal', vals[2], 'zError', zError) console.log('zVal', vals[2], 'zError', errors[2])
throw new Error('Camera position not as expected') throw new Error('Camera position not as expected', {
cause: {
vals,
errors,
},
})
} }
shouldRetry = true shouldRetry = true
} }
await page.getByRole('button', { name: 'Exit Sketch' }).click() if (shouldRetry) {
await page.waitForTimeout(100) await bakeInRetries({
if (shouldRetry) await bakeInRetries(mouseActions, xyz, cnt + 1) mouseActions,
afterPosition: afterPosition,
beforePosition: beforePosition,
retryCount: retryCount + 1,
page,
scene,
})
} }
await bakeInRetries(async () => { }
test(
'Can pan and zoom camera reliably',
{
tag: '@web',
},
async ({ page, homePage, scene, cmdBar }) => {
const u = await getUtils(page)
const camInitialPosition: [number, number, number] = [0, 85, 85]
await homePage.goToModelingScene()
await scene.settled(cmdBar)
await u.openAndClearDebugPanel()
await u.closeKclCodePanel()
await test.step('Pan', async () => {
await bakeInRetries({
mouseActions: async () => {
await page.keyboard.down('Shift')
await page.mouse.move(600, 200)
await page.mouse.down({ button: 'right' })
// Gotcha: remove steps:2 from this 700,200 mouse move. This bricked the test on local host engine.
await page.mouse.move(700, 200)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Shift')
await page.waitForTimeout(200)
},
afterPosition: [19, 85, 85],
beforePosition: camInitialPosition,
page,
scene,
})
})
await test.step('Zoom with click and drag', async () => {
await bakeInRetries({
mouseActions: async () => {
await page.keyboard.down('Control')
await page.mouse.move(700, 400)
await page.mouse.down({ button: 'right' })
await page.mouse.move(700, 300)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Control')
},
afterPosition: [0, 118, 118],
beforePosition: camInitialPosition,
page,
scene,
})
})
await test.step('Zoom with scrollwheel', async () => {
const refreshCamValuesCmd: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
}
await bakeInRetries({
mouseActions: async () => {
await page.mouse.move(700, 400)
await page.mouse.wheel(0, -150)
// Scroll zooming doesn't update the debug pane's cam position values,
// so we have to force a refresh.
await u.openAndClearDebugPanel()
await u.sendCustomCmd(refreshCamValuesCmd)
await u.waitForCmdReceive('default_camera_get_settings')
await u.closeDebugPanel()
},
afterPosition: [0, 42.5, 42.5],
beforePosition: camInitialPosition,
page,
scene,
})
})
}
)
test(
'Can orbit camera reliably',
{
tag: '@web',
},
async ({ page, homePage, scene, cmdBar }) => {
const u = await getUtils(page)
const initialCamPosition: [number, number, number] = [0, 85, 85]
await homePage.goToModelingScene()
// this turns on the debug pane setting as well
await scene.settled(cmdBar)
await u.openAndClearDebugPanel()
await u.closeKclCodePanel()
await test.step('Test orbit with spherical mode', async () => {
await bakeInRetries({
mouseActions: async () => {
await page.mouse.move(700, 200) await page.mouse.move(700, 200)
await page.mouse.down({ button: 'right' }) await page.mouse.down({ button: 'right' })
await page.waitForTimeout(100) await page.waitForTimeout(100)
@ -114,76 +201,52 @@ test.describe('Testing Camera Movement', () => {
await page.mouse.move(600, 303) await page.mouse.move(600, 303)
await page.waitForTimeout(100) await page.waitForTimeout(100)
await page.mouse.up({ button: 'right' }) await page.mouse.up({ button: 'right' })
}, [4, -10.5, -120])
await bakeInRetries(async () => {
await page.keyboard.down('Shift')
await page.mouse.move(600, 200)
await page.mouse.down({ button: 'right' })
// Gotcha: remove steps:2 from this 700,200 mouse move. This bricked the test on local host engine.
await page.mouse.move(700, 200)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Shift')
}, [-19, -85, -85])
const camCommand: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
center: { x: 0, y: 0, z: 0 },
vantage: { x: camPos[0], y: camPos[1], z: camPos[2] },
up: { x: 0, y: 0, z: 1 },
}, },
} afterPosition: [-4, 10.5, 120],
const updateCamCommand: EngineCommand = { beforePosition: initialCamPosition,
type: 'modeling_cmd_req', page,
cmd_id: uuidv4(), scene,
cmd: {
type: 'default_camera_get_settings',
},
}
await u.sendCustomCmd(camCommand)
await page.waitForTimeout(100)
await u.sendCustomCmd(updateCamCommand)
await page.waitForTimeout(100)
await u.clearCommandLogs()
await u.closeDebugPanel()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(200)
// zoom
await u.doAndWaitForImageDiff(async () => {
await page.keyboard.down('Control')
await page.mouse.move(700, 400)
await page.mouse.down({ button: 'right' })
await page.mouse.move(700, 300)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Control')
await u.openDebugPanel()
await page.waitForTimeout(300)
await u.clearCommandLogs()
await u.closeDebugPanel()
}, 300)
// zoom with scroll
await u.openAndClearDebugPanel()
// TODO, it appears we don't get the cam setting back from the engine when the interaction is zoom into `backInRetries` once the information is sent back on zoom
// await expect(Math.abs(Number(await page.getByTestId('cam-x-position').inputValue()) + 12)).toBeLessThan(1.5)
// await expect(Math.abs(Number(await page.getByTestId('cam-y-position').inputValue()) - 85)).toBeLessThan(1.5)
// await expect(Math.abs(Number(await page.getByTestId('cam-z-position').inputValue()) - 85)).toBeLessThan(1.5)
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await bakeInRetries(async () => {
await page.mouse.move(700, 400)
await page.mouse.wheel(0, -100)
}, [0, -85, -85])
}) })
})
await test.step('Test orbit with trackball mode', async () => {
await test.step('Set orbitMode to trackball', async () => {
await cmdBar.openCmdBar()
await cmdBar.selectOption({ name: 'camera orbit' }).click()
await cmdBar.selectOption({ name: 'trackball' }).click()
await expect(
page.getByText(`camera orbit to "trackball"`)
).toBeVisible()
})
await bakeInRetries({
mouseActions: async () => {
await page.mouse.move(700, 200)
await page.mouse.down({ button: 'right' })
await page.waitForTimeout(100)
const appLogoBBox = await page.getByTestId('app-logo').boundingBox()
expect(appLogoBBox).not.toBeNull()
if (!appLogoBBox) {
throw new Error('app logo not found')
}
await page.mouse.move(
appLogoBBox.x + appLogoBBox.width / 2,
appLogoBBox.y + appLogoBBox.height / 2
)
await page.waitForTimeout(100)
await page.mouse.move(600, 303)
await page.waitForTimeout(100)
await page.mouse.up({ button: 'right' })
},
afterPosition: [18.06, -42.79, 110.87],
beforePosition: initialCamPosition,
page,
scene,
})
})
}
)
// TODO: fix after electron migration is merged // TODO: fix after electron migration is merged
test('Zoom should be consistent when exiting or entering sketches', async ({ test('Zoom should be consistent when exiting or entering sketches', async ({

View File

@ -1120,7 +1120,7 @@ part002 = startSketchOn(XZ)
test.describe('Electron constraint tests', () => { test.describe('Electron constraint tests', () => {
test( test(
'Able to double click label to set constraint', 'Able to double click label to set constraint',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ page, context, homePage, scene, editor, toolbar, cmdBar }) => { async ({ page, context, homePage, scene, editor, toolbar, cmdBar }) => {
await context.folderSetupFn(async (dir) => { await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'test-sample') const bracketDir = path.join(dir, 'test-sample')

View File

@ -84,7 +84,7 @@ test.describe('Testing loading external models', () => {
*/ */
test( test(
'Desktop: should create new file by default, creates a second file with automatic unique name', 'Desktop: should create new file by default, creates a second file with automatic unique name',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ editor, context, page, scene, cmdBar, toolbar }) => { async ({ editor, context, page, scene, cmdBar, toolbar }) => {
if (runningOnWindows()) { if (runningOnWindows()) {
} }
@ -196,7 +196,7 @@ test.describe('Testing loading external models', () => {
externalModelCases.map(({ modelName, deconflictedModelName, modelPath }) => { externalModelCases.map(({ modelName, deconflictedModelName, modelPath }) => {
test( test(
`Load external models from local drive - ${modelName}`, `Load external models from local drive - ${modelName}`,
{ tag: ['@electron'] }, { tag: ['@desktop'] },
async ({ page, homePage, scene, toolbar, cmdBar, tronApp }) => { async ({ page, homePage, scene, toolbar, cmdBar, tronApp }) => {
if (!tronApp) { if (!tronApp) {
fail() fail()

File diff suppressed because it is too large Load Diff

View File

@ -278,7 +278,7 @@ test.describe(
test( test(
`Project settings override user settings on desktop`, `Project settings override user settings on desktop`,
{ tag: ['@electron'] }, { tag: ['@desktop'] },
async ({ context, page }, testInfo) => { async ({ context, page }, testInfo) => {
const projectName = 'bracket' const projectName = 'bracket'
const { dir: projectDirName } = await context.folderSetupFn( const { dir: projectDirName } = await context.folderSetupFn(
@ -373,7 +373,7 @@ test.describe(
test( test(
`Load desktop app with no settings file`, `Load desktop app with no settings file`,
{ {
tag: '@electron', tag: '@desktop',
}, },
async ({ page }, testInfo) => { async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
@ -393,7 +393,7 @@ test.describe(
test( test(
`Load desktop app with a settings file, but no project directory setting`, `Load desktop app with a settings file, but no project directory setting`,
{ {
tag: '@electron', tag: '@desktop',
}, },
async ({ context, page, tronApp }, testInfo) => { async ({ context, page, tronApp }, testInfo) => {
if (!tronApp) { if (!tronApp) {
@ -425,7 +425,7 @@ test.describe(
test( test(
'user settings reload on external change, on project and modeling view', 'user settings reload on external change, on project and modeling view',
{ {
tag: '@electron', tag: '@desktop',
}, },
async ({ context, page, tronApp }, testInfo) => { async ({ context, page, tronApp }, testInfo) => {
if (!tronApp) { if (!tronApp) {
@ -486,7 +486,7 @@ test.describe(
test( test(
'project settings reload on external change', 'project settings reload on external change',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ context, page }, testInfo) => { async ({ context, page }, testInfo) => {
const { dir: projectDirName } = await context.folderSetupFn( const { dir: projectDirName } = await context.folderSetupFn(
async () => {} async () => {}
@ -536,7 +536,7 @@ test.describe(
test( test(
`Closing settings modal should go back to the original file being viewed`, `Closing settings modal should go back to the original file being viewed`,
{ tag: '@electron' }, { tag: '@desktop' },
async ({ context, page }, testInfo) => { async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => { await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'project-000') const bracketDir = join(dir, 'project-000')

View File

@ -640,7 +640,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> New Project -> Stay in home page -> Reject -> Project should be deleted', 'Home Page -> Text To CAD -> New Project -> Stay in home page -> Reject -> Project should be deleted',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ context, page }, testInfo) => { async ({ context, page }, testInfo) => {
const projectName = 'my-project-name' const projectName = 'my-project-name'
const prompt = '2x2x2 cube' const prompt = '2x2x2 cube'
@ -678,7 +678,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> New Project -> Stay in home page -> Accept -> should navigate to file', 'Home Page -> Text To CAD -> New Project -> Stay in home page -> Accept -> should navigate to file',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ context, page }, testInfo) => { async ({ context, page }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -724,7 +724,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> Existing Project -> Stay in home page -> Reject -> should delete single file', 'Home Page -> Text To CAD -> Existing Project -> Stay in home page -> Reject -> should delete single file',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const projectName = 'my-project-name' const projectName = 'my-project-name'
const prompt = '2x2x2 cube' const prompt = '2x2x2 cube'
@ -767,7 +767,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> Existing Project -> Stay in home page -> Accept -> should navigate to file', 'Home Page -> Text To CAD -> Existing Project -> Stay in home page -> Accept -> should navigate to file',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -818,7 +818,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> New Project -> Navigate to the project -> Reject -> should go to home page', 'Home Page -> Text To CAD -> New Project -> Navigate to the project -> Reject -> should go to home page',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const projectName = 'my-project-name' const projectName = 'my-project-name'
const prompt = '2x2x2 cube' const prompt = '2x2x2 cube'
@ -864,7 +864,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> New Project -> Navigate to the project -> Accept -> should stay in same file', 'Home Page -> Text To CAD -> New Project -> Navigate to the project -> Accept -> should stay in same file',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const projectName = 'my-project-name' const projectName = 'my-project-name'
const prompt = '2x2x2 cube' const prompt = '2x2x2 cube'
@ -907,7 +907,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to the project -> Reject -> should load main.kcl', 'Home Page -> Text To CAD -> Existing Project -> Navigate to the project -> Reject -> should load main.kcl',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -962,7 +962,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to the project -> Accept -> should load 2x2x2-cube.kcl', 'Home Page -> Text To CAD -> Existing Project -> Navigate to the project -> Accept -> should load 2x2x2-cube.kcl',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -1019,7 +1019,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> New Project -> Navigate to different project -> Reject -> should stay in project', 'Home Page -> Text To CAD -> New Project -> Navigate to different project -> Reject -> should stay in project',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ homePage, page }, testInfo) => { async ({ homePage, page }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -1096,7 +1096,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> New Project -> Navigate to different project -> Accept -> should go to new project', 'Home Page -> Text To CAD -> New Project -> Navigate to different project -> Accept -> should go to new project',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ page, homePage }, testInfo) => { async ({ page, homePage }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -1165,7 +1165,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to different project -> Reject -> should stay in same project', 'Home Page -> Text To CAD -> Existing Project -> Navigate to different project -> Reject -> should stay in same project',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ page, homePage }, testInfo) => { async ({ page, homePage }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'
@ -1240,7 +1240,7 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
test( test(
'Home Page -> Text To CAD -> Existing Project -> Navigate to different project -> Accept -> should navigate to new project', 'Home Page -> Text To CAD -> Existing Project -> Navigate to different project -> Accept -> should navigate to new project',
{ tag: '@electron' }, { tag: '@desktop' },
async ({ page, homePage }, testInfo) => { async ({ page, homePage }, testInfo) => {
const u = await getUtils(page) const u = await getUtils(page)
const projectName = 'my-project-name' const projectName = 'my-project-name'

View File

@ -133,9 +133,9 @@
"test:unit": "vitest run --mode development --exclude **/jest-component-unit-tests/*", "test:unit": "vitest run --mode development --exclude **/jest-component-unit-tests/*",
"test:unit:components": "jest -c jest-component-unit-tests/jest.config.ts --rootDir jest-component-unit-tests/", "test:unit:components": "jest -c jest-component-unit-tests/jest.config.ts --rootDir jest-component-unit-tests/",
"test:e2e:web": "cross-env TARGET=web NODE_ENV=development playwright test --config=playwright.config.ts --project=\"Google Chrome\" --grep=@web", "test:e2e:web": "cross-env TARGET=web NODE_ENV=development playwright test --config=playwright.config.ts --project=\"Google Chrome\" --grep=@web",
"test:playwright:electron": "playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot", "test:e2e:desktop": "cross-env TARGET=desktop playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
"test:playwright:electron:local": "npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"", "test:e2e:desktop:local": "cross-env TARGET=desktop npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
"test:playwright:electron:local-engine": "npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot|@skipLocalEngine' --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"", "test:e2e:desktop:local-engine": "cross-env TARGET=desktop npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot|@skipLocalEngine' --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
"test:unit:local": "npm run simpleserver:bg && npm run test:unit; kill-port 3000" "test:unit:local": "npm run simpleserver:bg && npm run test:unit; kill-port 3000"
}, },
"browserslist": { "browserslist": {

View File

@ -27,7 +27,7 @@ if len(modified_release_body) > max_length:
# Message to send to Discord # Message to send to Discord
data = { data = {
"content": textwrap.dedent(f''' "content": textwrap.dedent(f'''
**{release_version}** is now available! Check out the latest features and improvements here: <https://zoo.dev/design-studio> **{release_version}** is now available! Check out the latest features and improvements here: <https://zoo.dev/design-studio/download#added>
{modified_release_body} {modified_release_body}
'''), '''),

View File

@ -27,6 +27,8 @@ When you submit a PR to add or modify KCL samples, images will be generated and
[![axial-fan](screenshots/axial-fan.png)](axial-fan/main.kcl) [![axial-fan](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](screenshots/ball-bearing.png)](ball-bearing/main.kcl) [![ball-bearing](screenshots/ball-bearing.png)](ball-bearing/main.kcl)
#### [ball-joint-rod-end](ball-joint-rod-end/main.kcl) ([screenshot](screenshots/ball-joint-rod-end.png))
[![ball-joint-rod-end](screenshots/ball-joint-rod-end.png)](ball-joint-rod-end/main.kcl)
#### [bench](bench/main.kcl) ([screenshot](screenshots/bench.png)) #### [bench](bench/main.kcl) ([screenshot](screenshots/bench.png))
[![bench](screenshots/bench.png)](bench/main.kcl) [![bench](screenshots/bench.png)](bench/main.kcl)
#### [bone-plate](bone-plate/main.kcl) ([screenshot](screenshots/bone-plate.png)) #### [bone-plate](bone-plate/main.kcl) ([screenshot](screenshots/bone-plate.png))

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