Compare commits
64 Commits
v1.0.5
...
jtran/anim
Author | SHA1 | Date | |
---|---|---|---|
bfefa0f51a | |||
0ad619e1d2 | |||
8d876a806e | |||
c7f0a6c2a0 | |||
e4941cb524 | |||
1b687a82a6 | |||
1bb882acf8 | |||
478bf34f2b | |||
dbc87292e4 | |||
bb3a74076f | |||
0cd6031aae | |||
1e1bdbd6e7 | |||
631b63b1b6 | |||
eabcf86436 | |||
7ce0ef770a | |||
599ab33e40 | |||
c584d942d4 | |||
35b8872678 | |||
2f245fe445 | |||
4b95980e9e | |||
53d6613d0d | |||
416d0b37a2 | |||
5f2a10ec7e | |||
24edb66b3c | |||
903ba33c46 | |||
c5bf6ad42d | |||
eeaa71142a | |||
0d1fc1b513 | |||
d510e58ebc | |||
23a01e86e6 | |||
9dd6e3e852 | |||
9eaacc2a51 | |||
de6e0f6b18 | |||
d02a9f59ae | |||
92f930dfc0 | |||
e651e0c2cf | |||
6358eed7e4 | |||
fe581ff1d2 | |||
b301fbba22 | |||
0c702e4bab | |||
25b9a34640 | |||
b2152a5684 | |||
832bf77c92 | |||
acb43fc82c | |||
7486d25cf1 | |||
1a4a030671 | |||
3049d939e1 | |||
ad9822e8ac | |||
aae34cf1e5 | |||
d6278cf075 | |||
4159cc0047 | |||
3936017f10 | |||
2b0ced179a | |||
c2f6ce065d | |||
b3bdc35da2 | |||
8fe4f67a29 | |||
c6b1d11700 | |||
2ef84382a6 | |||
939c2c77b0 | |||
31ec0184a1 | |||
62c4546658 | |||
383b38c2d2 | |||
e0025f7fad | |||
2a13888c54 |
@ -9,6 +9,7 @@ VITE_KC_SITE_BASE_URL=https://dev.zoo.dev
|
|||||||
VITE_KC_SITE_APP_URL=https://app.dev.zoo.dev
|
VITE_KC_SITE_APP_URL=https://app.dev.zoo.dev
|
||||||
VITE_KC_SKIP_AUTH=false
|
VITE_KC_SKIP_AUTH=false
|
||||||
VITE_KC_CONNECTION_TIMEOUT_MS=5000
|
VITE_KC_CONNECTION_TIMEOUT_MS=5000
|
||||||
|
#VITE_WASM_URL="optional way of overriding the wasm url, particular for unit tests which need this if you running not on the default 3000 port"
|
||||||
#VITE_KC_DEV_TOKEN="optional token to skip auth in the app"
|
#VITE_KC_DEV_TOKEN="optional token to skip auth in the app"
|
||||||
#token="required token for playwright. TODO: clean up env vars in #3973"
|
#token="required token for playwright. TODO: clean up env vars in #3973"
|
||||||
|
|
||||||
|
3
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
* @KittyCAD/frontend
|
||||||
|
/src/ @KittyCAD/frontend
|
||||||
|
/rust/ @KittyCAD/kcl
|
41
.github/ISSUE_TEMPLATE/release.md
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
name: Release
|
||||||
|
about: Create a new release for the Zoo Design Studio
|
||||||
|
title: "Cut release v1.?.?"
|
||||||
|
labels: [meta/release]
|
||||||
|
---
|
||||||
|
|
||||||
|
> Instructions: https://github.com/KittyCAD/modeling-app/blob/main/CONTRIBUTING.md#shipping-releases
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Manual Checklist
|
||||||
|
|
||||||
|
Release builds URL: ???
|
||||||
|
|
||||||
|
## Windows via ???
|
||||||
|
|
||||||
|
* [ ] Download the release build for this platform
|
||||||
|
* [ ] Confirm the application opens (dismiss the updater)
|
||||||
|
* [ ] Create a project with a basic Text-to-CAD prompt
|
||||||
|
* [ ] Confirm the result is viewable in an engine stream
|
||||||
|
* [ ] Use 'Check for updates' to bring back the updater toast
|
||||||
|
* [ ] Confirm the app can update to the previous release
|
||||||
|
|
||||||
|
## macOS via ???
|
||||||
|
|
||||||
|
* [ ] Download the release build for this platform
|
||||||
|
* [ ] Confirm the application opens (dismiss the updater)
|
||||||
|
* [ ] Create a project with a basic Text-to-CAD prompt
|
||||||
|
* [ ] Confirm the result is viewable in an engine stream
|
||||||
|
* [ ] Use 'Check for updates' to bring back the updater toast
|
||||||
|
* [ ] Confirm the app can update to the previous release
|
||||||
|
|
||||||
|
## Linux via ???
|
||||||
|
|
||||||
|
* [ ] Download the release build for this platform
|
||||||
|
* [ ] Confirm the application opens (dismiss the updater)
|
||||||
|
* [ ] Create a project with a basic Text-to-CAD prompt
|
||||||
|
* [ ] Confirm the result is viewable in an engine stream
|
||||||
|
* [ ] Use 'Check for updates' to bring back the updater toast
|
||||||
|
* [ ] Confirm the app can update to the previous release
|
6
.github/workflows/cargo-fmt.yml
vendored
@ -31,15 +31,15 @@ jobs:
|
|||||||
- name: Use correct Rust toolchain
|
- name: Use correct Rust toolchain
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
cp .github/workflows/nightly-rust-toolchain.toml rust-toolchain.toml
|
||||||
- name: Install rust
|
- name: Install rust
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
cache-workspaces: rust
|
cache-workspaces: rust
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
|
|
||||||
- name: Run cargo fmt
|
- name: Run nightly cargo fmt
|
||||||
run: |
|
run: |
|
||||||
cd rust
|
cd rust
|
||||||
cargo fmt -- --check
|
cargo +nightly fmt -- --check
|
||||||
shell: bash
|
shell: bash
|
||||||
|
15
.github/workflows/e2e-tests.yml
vendored
@ -95,7 +95,8 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: npm run build:wasm
|
run: npm run build:wasm
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Upload compiled wasm artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: prepared-wasm
|
name: prepared-wasm
|
||||||
path: |
|
path: |
|
||||||
@ -176,7 +177,8 @@ jobs:
|
|||||||
CI_SUITE: e2e:snapshots
|
CI_SUITE: e2e:snapshots
|
||||||
TARGET: web
|
TARGET: web
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Upload playwright report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
with:
|
with:
|
||||||
name: playwright-report-snapshot-${{ github.sha }}
|
name: playwright-report-snapshot-${{ github.sha }}
|
||||||
@ -290,7 +292,8 @@ jobs:
|
|||||||
CI_SUITE: e2e:web
|
CI_SUITE: e2e:web
|
||||||
TARGET: web
|
TARGET: web
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Upload playwright report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ !cancelled() && (success() || failure()) }}
|
if: ${{ !cancelled() && (success() || failure()) }}
|
||||||
with:
|
with:
|
||||||
name: playwright-report-web-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
name: playwright-report-web-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||||
@ -415,7 +418,8 @@ jobs:
|
|||||||
CI_SUITE: e2e:desktop
|
CI_SUITE: e2e:desktop
|
||||||
TARGET: desktop
|
TARGET: desktop
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Upload test report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: test-results-desktop-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
name: test-results-desktop-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||||
@ -424,7 +428,8 @@ jobs:
|
|||||||
retention-days: 30
|
retention-days: 30
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Upload playwright report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: playwright-report-desktop-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
name: playwright-report-desktop-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||||
|
3
.github/workflows/nightly-rust-toolchain.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
|
components = ["rustfmt"]
|
@ -251,7 +251,8 @@ Before you submit a contribution PR to this repo, please ensure that:
|
|||||||
|
|
||||||
#### 1. Create a 'Cut release $VERSION' issue
|
#### 1. Create a 'Cut release $VERSION' issue
|
||||||
|
|
||||||
It will be used to document changelog discussions and release testing.
|
Use the **Release** issue template.
|
||||||
|
This will be used to facilitate changelog discussions and release testing.
|
||||||
|
|
||||||
https://github.com/KittyCAD/modeling-app/issues/new
|
https://github.com/KittyCAD/modeling-app/issues/new
|
||||||
|
|
||||||
@ -270,33 +271,18 @@ The workflow should be listed right away [in this list](https://github.com/Kitty
|
|||||||
|
|
||||||
#### 3. Manually test artifacts
|
#### 3. Manually test artifacts
|
||||||
|
|
||||||
##### Release builds
|
|
||||||
|
|
||||||
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in step 2).
|
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in step 2).
|
||||||
|
|
||||||
Manually test against [this list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
Assign someone to each section of the manual checklist generated by the issue template.
|
||||||
|
|
||||||
A prompt should show up asking for a downgrade to the last release version. Running through that at the end of testing
|
|
||||||
and making sure the current release candidate has the ability to be updated to what electron-updater points to is critical,
|
|
||||||
but what is actually being downloaded and installed isn't.
|
|
||||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing.
|
|
||||||
|
|
||||||
```
|
|
||||||
# Windows (PowerShell)
|
|
||||||
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe'
|
|
||||||
|
|
||||||
# macOS
|
|
||||||
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
|
|
||||||
|
|
||||||
# Linux
|
|
||||||
./Zoo Design Studio-{version}-{arch}-linux.AppImage
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. Bump the KCL version
|
#### 4. Bump the KCL version
|
||||||
|
|
||||||
Follow the instructions [here](./rust/README.md) to publish new crates.
|
Follow the instructions [here](./rust/README.md) to publish new crates.
|
||||||
This ensures that the KCL accepted by the app is also accepted by the CLI.
|
This ensures that the KCL accepted by the app is also accepted by the CLI.
|
||||||
|
|
||||||
|
If there are documentation changes, merge the corresponding Dependabot PRs [here](https://github.com/KittyCAD/website/pulls/app%2Fdependabot) for the website.
|
||||||
|
You can trigger Dependabot to check for updates [here](https://github.com/KittyCAD/website/network/updates/17261214/jobs).
|
||||||
|
|
||||||
#### 5. Publish the release
|
#### 5. Publish the release
|
||||||
|
|
||||||
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
|
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
|
||||||
|
@ -4,8 +4,6 @@ excerpt: "Project specific settings for the app. These live in `project.toml` in
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project Settings
|
|
||||||
|
|
||||||
Project specific settings for the app. These live in `project.toml` in the base of the project directory. Updating the settings for the project in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file.
|
Project specific settings for the app. These live in `project.toml` in the base of the project directory. Updating the settings for the project in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file.
|
||||||
|
|
||||||
## Project Configuration Structure
|
## Project Configuration Structure
|
||||||
@ -184,4 +182,4 @@ color = 240.0
|
|||||||
# Use inches as the default measurement unit
|
# Use inches as the default measurement unit
|
||||||
base_unit = "in"
|
base_unit = "in"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -4,8 +4,6 @@ excerpt: "User specific settings for the app. These live in `user.toml` in the a
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
# User Settings
|
|
||||||
|
|
||||||
User specific settings for the app. These live in `user.toml` in the app's configuration directory. Updating the settings in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file.
|
User specific settings for the app. These live in `user.toml` in the app's configuration directory. Updating the settings in the app will update this file automatically. Do not edit this file manually, as it may be overwritten by the app. Manual edits can cause corruption of the settings file.
|
||||||
|
|
||||||
## User Configuration Structure
|
## User Configuration Structure
|
||||||
@ -85,6 +83,13 @@ Allow orbiting in sketch mode.
|
|||||||
Whether to show the debug panel, which lets you see various states of the app to aid in development.
|
Whether to show the debug panel, which lets you see various states of the app to aid in development.
|
||||||
|
|
||||||
|
|
||||||
|
**Default:** None
|
||||||
|
|
||||||
|
##### fixed_size_grid
|
||||||
|
|
||||||
|
If true, the grid cells will be fixed-size, where the width is your default length unit. If false, the grid will get larger as you zoom out, and smaller as you zoom in.
|
||||||
|
|
||||||
|
|
||||||
**Default:** None
|
**Default:** None
|
||||||
|
|
||||||
|
|
||||||
@ -234,4 +239,4 @@ base_unit = "mm"
|
|||||||
# Disable text wrapping in the editor
|
# Disable text wrapping in the editor
|
||||||
text_wrapping = false
|
text_wrapping = false
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -44,7 +44,7 @@ detail on importing geometry.
|
|||||||
|
|
||||||
Tags are used to give a name (tag) to a specific path.
|
Tags are used to give a name (tag) to a specific path.
|
||||||
|
|
||||||
### `TagDeclarator`
|
### Tag declarations - `TagDecl`
|
||||||
|
|
||||||
The syntax for declaring a tag is `$myTag` you would use it in the following
|
The syntax for declaring a tag is `$myTag` you would use it in the following
|
||||||
way:
|
way:
|
||||||
@ -67,24 +67,28 @@ startSketchOn(XZ)
|
|||||||
|> close()
|
|> close()
|
||||||
```
|
```
|
||||||
|
|
||||||
### `TagIdentifier`
|
When a function requires declaring a new tag (using the `$` syntax), the argument has type [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl).
|
||||||
|
|
||||||
As per the example above you can use the tag identifier to get a reference to the
|
### Tag identifiers
|
||||||
tagged object. The syntax for this is `myTag`.
|
|
||||||
|
|
||||||
In the example above we use the tag identifier to get the angle of the segment
|
A tag created using a tag declarator can be used by writing its name without the `$`, e.g., `myTag`.
|
||||||
`segAng(rectangleSegmentA001)`.
|
Where necessary to disambiguate from tag declarations, we call these tag identifiers.
|
||||||
|
|
||||||
### `Start`
|
In the example above we use the tag identifier `rectangleSegmentA001` to get the angle of the segment
|
||||||
|
using `segAng(rectangleSegmentA001)`.
|
||||||
|
|
||||||
There is a special tag, `START` (with type `Start`, although under the cover, it's a string)
|
Tags can identify either an edge or face of a solid, or a line or other edge of a sketch. Functions
|
||||||
for identifying the face of a solid which was the start of an extrusion (i.e., the surface which
|
which take a tag identifier as an argument will use either [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) (for the edge of a
|
||||||
is extruded).
|
solid or sketch) or [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace).
|
||||||
|
|
||||||
### `End`
|
If a line in a sketch is tagged and then the sketch is extruded, the tag is a `TaggedEdge` before
|
||||||
|
extrusion and a `TaggedFace` after extrusion.
|
||||||
|
|
||||||
|
#### `START` and `END`
|
||||||
|
|
||||||
|
[`START`](/docs/kcl-std/consts/std-START) and [`END`](/docs/kcl-std/consts/std-END) are special tags
|
||||||
|
for identifying the starting and ending faces of an extruded solid.
|
||||||
|
|
||||||
There is a special tag, `END` (with type `End`, although under the cover, it's a string)
|
|
||||||
for identifying the face of a solid which was finishes an extrusion.
|
|
||||||
|
|
||||||
### Tag Scope
|
### Tag Scope
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
Identifies the ending face of an extrusion. I.e., the new face created by an extrusion.
|
Identifies the ending face of an extrusion. I.e., the new face created by an extrusion.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
END: string = 'end'
|
END: TaggedFace
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) - A tag which references a face of a solid, including the distinguished tags `START` and `END`.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
Identifies the starting face of an extrusion. I.e., the face which is extruded.
|
Identifies the starting face of an extrusion. I.e., the face which is extruded.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
START: string = 'start'
|
START: TaggedFace
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) - A tag which references a face of a solid, including the distinguished tags `START` and `END`.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
The X-axis (can be used in both 2d and 3d contexts).
|
The X-axis (can be used in both 2d and 3d contexts).
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
X
|
X: Axis3d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`Axis3d`](/docs/kcl-std/types/std-types-Axis3d) - An abstract and infinite line in 3d space.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis.
|
An abstract 3d plane aligned with the X and Y axes. Its normal is the positive Z axis.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
XY
|
XY: Plane
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`Plane`](/docs/kcl-std/types/std-types-Plane) - An abstract plane.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
An abstract 3d plane aligned with the X and Z axes. Its normal is the negative Y axis.
|
An abstract 3d plane aligned with the X and Z axes. Its normal is the negative Y axis.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
XZ
|
XZ: Plane
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`Plane`](/docs/kcl-std/types/std-types-Plane) - An abstract plane.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
The Y-axis (can be used in both 2d and 3d contexts).
|
The Y-axis (can be used in both 2d and 3d contexts).
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
Y
|
Y: Axis3d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`Axis3d`](/docs/kcl-std/types/std-types-Axis3d) - An abstract and infinite line in 3d space.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
An abstract 3d plane aligned with the Y and Z axes. Its normal is the positive X axis.
|
An abstract 3d plane aligned with the Y and Z axes. Its normal is the positive X axis.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
YZ
|
YZ: Plane
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`Plane`](/docs/kcl-std/types/std-types-Plane) - An abstract plane.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
The 3D Z-axis.
|
The 3D Z-axis.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
Z
|
Z: Axis3d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`Axis3d`](/docs/kcl-std/types/std-types-Axis3d) - An abstract and infinite line in 3d space.
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +13,10 @@ E: number = 2.71828182845904523536028747135266250_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
|
@ -11,7 +11,7 @@ The value of `pi`, Archimedes’ constant (π).
|
|||||||
PI: number(_?) = 3.14159265358979323846264338327950288_?
|
PI: number(_?) = 3.14159265358979323846264338327950288_?
|
||||||
```
|
```
|
||||||
|
|
||||||
`PI` is a number and is technically a ratio, so you might expect it to have type `number(_)`.
|
`PI` is a number and is technically a ratio, so you might expect it to have type [`number(_)`](/docs/kcl-std/types/std-types-number).
|
||||||
However, `PI` is nearly always used for converting between different units - usually degrees to or
|
However, `PI` is nearly always used for converting between different units - usually degrees to or
|
||||||
from radians. Therefore, `PI` is treated a bit specially by KCL and always has unknown units. This
|
from radians. Therefore, `PI` is treated a bit specially by KCL and always has unknown units. This
|
||||||
means that if you use `PI`, you will need to give KCL some extra information about the units of numbers.
|
means that if you use `PI`, you will need to give KCL some extra information about the units of numbers.
|
||||||
@ -19,6 +19,10 @@ Usually you should use type ascription on the result of calculations, e.g., `(2
|
|||||||
It is better to use `units::toRadians` or `units::toDegrees` to convert between angles with
|
It is better to use `units::toRadians` or `units::toDegrees` to convert between angles with
|
||||||
different units where possible.
|
different units where possible.
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number(_?)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
|
@ -13,6 +13,10 @@ TAU: number = 6.28318530717958647692528676655900577_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
|
@ -13,4 +13,8 @@ sweep::SKETCH_PLANE: string = 'sketchPlane'
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`string`](/docs/kcl-std/types/std-types-string) - A sequence of characters
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,4 +13,8 @@ sweep::TRAJECTORY: string = 'trajectoryCurve'
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`string`](/docs/kcl-std/types/std-types-string) - A sequence of characters
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,4 +13,8 @@ turns::HALF_TURN: number(deg) = 180deg
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,4 +13,8 @@ turns::QUARTER_TURN: number(deg) = 90deg
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,4 +13,8 @@ turns::THREE_QUARTER_TURN: number(deg) = 270deg
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,13 @@ layout: manual
|
|||||||
No turn, zero degrees/radians.
|
No turn, zero degrees/radians.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
turns::ZERO
|
turns::ZERO: number(Angle)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Type
|
||||||
|
|
||||||
|
[`number(Angle)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ angledLine(
|
|||||||
lengthY?: number(Length),
|
lengthY?: number(Length),
|
||||||
endAbsoluteX?: number(Length),
|
endAbsoluteX?: number(Length),
|
||||||
endAbsoluteY?: number(Length),
|
endAbsoluteY?: number(Length),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ angledLine(
|
|||||||
| `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 |
|
| `lengthY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||||
| `endAbsoluteX` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
| `endAbsoluteX` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||||
| `endAbsoluteY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
| `endAbsoluteY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
|
||||||
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ Draw an angled line from the current origin, constructing a line segment such th
|
|||||||
angledLineThatIntersects(
|
angledLineThatIntersects(
|
||||||
@sketch: Sketch,
|
@sketch: Sketch,
|
||||||
angle: number(Angle),
|
angle: number(Angle),
|
||||||
intersectTag: tag,
|
intersectTag: TaggedEdge,
|
||||||
offset?: number(Length),
|
offset?: number(Length),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,9 +25,9 @@ angledLineThatIntersects(
|
|||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `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(Angle)`](/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` | [`tag`](/docs/kcl-std/types/std-types-tag) | The tag of the line to intersect with. | Yes |
|
| `intersectTag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The tag of the line to intersect with. | Yes |
|
||||||
| `offset` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The offset from the intersecting line. | No |
|
| `offset` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The offset from the intersecting line. | No |
|
||||||
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ arc(
|
|||||||
diameter?: number(Length),
|
diameter?: number(Length),
|
||||||
interiorAbsolute?: Point2d,
|
interiorAbsolute?: Point2d,
|
||||||
endAbsolute?: Point2d,
|
endAbsolute?: Point2d,
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ for to construct your shape, you're likely looking for tangentialArc.
|
|||||||
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How large should the circle be? Incompatible with `radius`. | No |
|
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How large should the circle be? Incompatible with `radius`. | No |
|
||||||
| `interiorAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
|
| `interiorAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
|
||||||
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Where should this arc end? Requires `interiorAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
|
| `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 |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this arc. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ circle(
|
|||||||
center: Point2d,
|
center: Point2d,
|
||||||
radius?: number(Length),
|
radius?: number(Length),
|
||||||
diameter?: number(Length),
|
diameter?: number(Length),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ circle(
|
|||||||
| `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 |
|
||||||
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this circle. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this circle. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ circleThreePoint(
|
|||||||
p1: Point2d,
|
p1: Point2d,
|
||||||
p2: Point2d,
|
p2: Point2d,
|
||||||
p3: Point2d,
|
p3: Point2d,
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ circleThreePoint(
|
|||||||
| `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) | [`tag`](/docs/kcl-std/types/std-types-tag) | Identifier for the circle to reference elsewhere. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Identifier for the circle to reference elsewhere. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Construct a line segment from the current origin back to the profile's origin, e
|
|||||||
```kcl
|
```kcl
|
||||||
close(
|
close(
|
||||||
@sketch: Sketch,
|
@sketch: Sketch,
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ starting point.
|
|||||||
| 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) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Get the shared edge between two faces.
|
Get the shared edge between two faces.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
getCommonEdge(faces: [tag; 2]): Edge
|
getCommonEdge(faces: [TaggedFace; 2]): Edge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ getCommonEdge(faces: [tag; 2]): Edge
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `faces` | `[tag; 2]` | The tags of the faces you want to find the common edge between. | Yes |
|
| `faces` | `[TaggedFace; 2]` | The tags of the faces you want to find the common edge between. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Get the next adjacent edge to the edge given.
|
Get the next adjacent edge to the edge given.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
getNextAdjacentEdge(@edge: tag): Edge
|
getNextAdjacentEdge(@edge: TaggedEdge): Edge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ getNextAdjacentEdge(@edge: tag): Edge
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `edge` | [`tag`](/docs/kcl-std/types/std-types-tag) | The tag of the edge you want to find the next adjacent edge of. | Yes |
|
| `edge` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The tag of the edge you want to find the next adjacent edge of. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Get the opposite edge to the edge given.
|
Get the opposite edge to the edge given.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
getOppositeEdge(@edge: tag): Edge
|
getOppositeEdge(@edge: TaggedEdge): Edge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ getOppositeEdge(@edge: tag): Edge
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `edge` | [`tag`](/docs/kcl-std/types/std-types-tag) | The tag of the edge you want to find the opposite edge of. | Yes |
|
| `edge` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The tag of the edge you want to find the opposite edge of. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Get the previous adjacent edge to the edge given.
|
Get the previous adjacent edge to the edge given.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
getPreviousAdjacentEdge(@edge: tag): Edge
|
getPreviousAdjacentEdge(@edge: TaggedEdge): Edge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ getPreviousAdjacentEdge(@edge: tag): Edge
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `edge` | [`tag`](/docs/kcl-std/types/std-types-tag) | The tag of the edge you want to find the previous adjacent edge of. | Yes |
|
| `edge` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The tag of the edge you want to find the previous adjacent edge of. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -10,11 +10,13 @@ Extend the current sketch with a new involute circular curve.
|
|||||||
```kcl
|
```kcl
|
||||||
involuteCircular(
|
involuteCircular(
|
||||||
@sketch: Sketch,
|
@sketch: Sketch,
|
||||||
startRadius: number(Length),
|
|
||||||
endRadius: number(Length),
|
|
||||||
angle: number(Angle),
|
angle: number(Angle),
|
||||||
|
startRadius?: number(Length),
|
||||||
|
endRadius?: number(Length),
|
||||||
|
startDiameter?: number(Length),
|
||||||
|
endDiameter?: number(Length),
|
||||||
reverse?: bool,
|
reverse?: bool,
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,11 +27,13 @@ involuteCircular(
|
|||||||
| 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 |
|
||||||
| `startRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The involute is described between two circles, start_radius is the radius of the inner circle. | Yes |
|
|
||||||
| `endRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The involute is described between two circles, end_radius is the radius of the outer circle. | Yes |
|
|
||||||
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | The angle to rotate the involute by. A value of zero will produce a curve with a tangent along the x-axis at the start point of the curve. | Yes |
|
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | The angle to rotate the involute by. A value of zero will produce a curve with a tangent along the x-axis at the start point of the curve. | Yes |
|
||||||
|
| `startRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The involute is described between two circles, startRadius is the radius of the inner circle. Either `startRadius` or `startDiameter` must be given (but not both). | No |
|
||||||
|
| `endRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The involute is described between two circles, endRadius is the radius of the outer circle. Either `endRadius` or `endDiameter` must be given (but not both). | No |
|
||||||
|
| `startDiameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The involute is described between two circles, startDiameter describes the inner circle. Either `startRadius` or `startDiameter` must be given (but not both). | No |
|
||||||
|
| `endDiameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The involute is described between two circles, endDiameter describes the outer circle. Either `endRadius` or `endDiameter` must be given (but not both). | No |
|
||||||
| `reverse` | [`bool`](/docs/kcl-std/types/std-types-bool) | If reverse is true, the segment will start from the end of the involute, otherwise it will start from that start. | No |
|
| `reverse` | [`bool`](/docs/kcl-std/types/std-types-bool) | If reverse is true, the segment will start from the end of the involute, otherwise it will start from that start. | 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 |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ line(
|
|||||||
@sketch: Sketch,
|
@sketch: Sketch,
|
||||||
endAbsolute?: Point2d,
|
endAbsolute?: Point2d,
|
||||||
end?: Point2d,
|
end?: Point2d,
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): 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) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ revolve(
|
|||||||
tolerance?: number(Length),
|
tolerance?: number(Length),
|
||||||
symmetric?: bool,
|
symmetric?: bool,
|
||||||
bidirectionalAngle?: number(Angle),
|
bidirectionalAngle?: number(Angle),
|
||||||
tagStart?: tag,
|
tagStart?: TagDecl,
|
||||||
tagEnd?: tag,
|
tagEnd?: TagDecl,
|
||||||
): [Solid; 1+]
|
): [Solid; 1+]
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -38,11 +38,11 @@ revolved around the same axis.
|
|||||||
| `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | The sketch or set of sketches that should be revolved | Yes |
|
| `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | The sketch or set of sketches that should be revolved | Yes |
|
||||||
| `axis` | [`Axis2d`](/docs/kcl-std/types/std-types-Axis2d) or [`Edge`](/docs/kcl-std/types/std-types-Edge) | Axis of revolution. | Yes |
|
| `axis` | [`Axis2d`](/docs/kcl-std/types/std-types-Axis2d) or [`Edge`](/docs/kcl-std/types/std-types-Edge) | Axis of revolution. | Yes |
|
||||||
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Angle to revolve (in degrees). Default is 360. | No |
|
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Angle to revolve (in degrees). Default is 360. | No |
|
||||||
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Tolerance for the revolve operation. | No |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. | 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 |
|
| `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 |
|
||||||
| `bidirectionalAngle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | If specified, will also revolve in the opposite direction to 'angle' to the specified angle. If 'symmetric' is true, this value is ignored. | No |
|
| `bidirectionalAngle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | If specified, will also revolve in the opposite direction to 'angle' to the specified angle. If 'symmetric' is true, this value is ignored. | No |
|
||||||
| `tagStart` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the start of the revolve, i.e. the original sketch. | No |
|
| `tagStart` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | A named tag for the face at the start of the revolve, i.e. the original sketch. | No |
|
||||||
| `tagEnd` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the end of the revolve. | No |
|
| `tagEnd` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | A named tag for the face at the end of the revolve. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Angle)
|
segAng(@tag: TaggedEdge): number(Angle)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segAng(@tag: tag): number(Angle)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): Point2d
|
segEnd(@tag: TaggedEdge): Point2d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segEnd(@tag: tag): Point2d
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Length)
|
segEndX(@tag: TaggedEdge): number(Length)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segEndX(@tag: tag): number(Length)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Length)
|
segEndY(@tag: TaggedEdge): number(Length)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segEndY(@tag: tag): number(Length)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Length)
|
segLen(@tag: TaggedEdge): number(Length)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segLen(@tag: tag): number(Length)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): Point2d
|
segStart(@tag: TaggedEdge): Point2d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segStart(@tag: tag): Point2d
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Length)
|
segStartX(@tag: TaggedEdge): number(Length)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segStartX(@tag: tag): number(Length)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Length)
|
segStartY(@tag: TaggedEdge): number(Length)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ segStartY(@tag: tag): number(Length)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Start a new profile at a given point.
|
|||||||
startProfile(
|
startProfile(
|
||||||
@startProfileOn: Plane | Face,
|
@startProfileOn: Plane | Face,
|
||||||
at: Point2d,
|
at: Point2d,
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ startProfile(
|
|||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `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 |
|
| `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) | [`tag`](/docs/kcl-std/types/std-types-tag) | Tag this first starting point. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Tag this first starting point. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Start a new 2-dimensional sketch on a specific plane or face.
|
|||||||
```kcl
|
```kcl
|
||||||
startSketchOn(
|
startSketchOn(
|
||||||
@planeOrSolid: Solid | Plane,
|
@planeOrSolid: Solid | Plane,
|
||||||
face?: tag,
|
face?: TaggedFace,
|
||||||
): Plane | Face
|
): Plane | Face
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ face, since it will include all the parent faces and Solids.
|
|||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `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 |
|
| `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` | [`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 |
|
| `face` | [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) | Identify a face of a solid if a solid is specified as the input argument (`planeOrSolid`). | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -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: tag): number(Angle)
|
tangentToEnd(@tag: TaggedEdge): number(Angle)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ tangentToEnd(@tag: tag): number(Angle)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| [`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 |
|
| `tag` | [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) | The line segment being queried by its tag. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ tangentialArc(
|
|||||||
radius?: number(Length),
|
radius?: number(Length),
|
||||||
diameter?: number(Length),
|
diameter?: number(Length),
|
||||||
angle?: number(Angle),
|
angle?: number(Angle),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ for 'angle' degrees along the imaginary circle.
|
|||||||
| `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 |
|
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Radius of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `diameter`. | No |
|
||||||
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Diameter of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `radius`. | No |
|
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Diameter of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `radius`. | No |
|
||||||
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Offset of the arc. `radius` must be given. Incompatible with `end` and `endAbsolute`. | No |
|
| `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 |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this arc. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ xLine(
|
|||||||
@sketch: Sketch,
|
@sketch: Sketch,
|
||||||
length?: number(Length),
|
length?: number(Length),
|
||||||
endAbsolute?: number(Length),
|
endAbsolute?: number(Length),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ xLine(
|
|||||||
| `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(Length)`](/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(Length)`](/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) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ yLine(
|
|||||||
@sketch: Sketch,
|
@sketch: Sketch,
|
||||||
length?: number(Length),
|
length?: number(Length),
|
||||||
endAbsolute?: number(Length),
|
endAbsolute?: number(Length),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ yLine(
|
|||||||
| `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(Length)`](/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(Length)`](/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) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this line. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ fillet(
|
|||||||
radius: number(Length),
|
radius: number(Length),
|
||||||
tags: [Edge; 1+],
|
tags: [Edge; 1+],
|
||||||
tolerance?: number(Length),
|
tolerance?: number(Length),
|
||||||
tag?: tag,
|
tag?: TagDecl,
|
||||||
): Solid
|
): Solid
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -28,8 +28,8 @@ will smoothly blend the transition.
|
|||||||
| `solid` | [`Solid`](/docs/kcl-std/types/std-types-Solid) | The solid whose edges should be filletted | Yes |
|
| `solid` | [`Solid`](/docs/kcl-std/types/std-types-Solid) | The solid whose edges should be filletted | Yes |
|
||||||
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the fillet | Yes |
|
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the fillet | Yes |
|
||||||
| `tags` | [`[Edge; 1+]`](/docs/kcl-std/types/std-types-Edge) | The paths you want to fillet | Yes |
|
| `tags` | [`[Edge; 1+]`](/docs/kcl-std/types/std-types-Edge) | The paths you want to fillet | Yes |
|
||||||
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance for this fillet | No |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. | 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 fillet | No |
|
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | Create a new tag which refers to this fillet | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ verifying fit, and analyzing overlapping geometries in assemblies.
|
|||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `solids` | `[Solid; 2+]` | The solids to intersect. | Yes |
|
| `solids` | `[Solid; 2+]` | The solids to intersect. | Yes |
|
||||||
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the intersection operation. | No |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ and complex multi-body part modeling.
|
|||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `solids` | [`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid) | The solids to use as the base to subtract from. | Yes |
|
| `solids` | [`[Solid; 1+]`](/docs/kcl-std/types/std-types-Solid) | The solids to use as the base to subtract from. | Yes |
|
||||||
| `tools` | [`[Solid]`](/docs/kcl-std/types/std-types-Solid) | The solids to subtract. | Yes |
|
| `tools` | [`[Solid]`](/docs/kcl-std/types/std-types-Solid) | The solids to subtract. | Yes |
|
||||||
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the subtraction operation. | No |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ union(
|
|||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `solids` | `[Solid; 2+]` | The solids to union. | Yes |
|
| `solids` | `[Solid; 2+]` | The solids to union. | Yes |
|
||||||
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the union operation. | No |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -145,12 +145,12 @@ See also the [types overview](/docs/kcl-lang/types)
|
|||||||
|
|
||||||
* [**Primitive types**](/docs/kcl-lang/types)
|
* [**Primitive types**](/docs/kcl-lang/types)
|
||||||
* [`ImportedGeometry`](/docs/kcl-std/types/std-types-ImportedGeometry)
|
* [`ImportedGeometry`](/docs/kcl-std/types/std-types-ImportedGeometry)
|
||||||
|
* [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl)
|
||||||
* [`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)
|
||||||
* [`number`](/docs/kcl-std/types/std-types-number)
|
* [`number`](/docs/kcl-std/types/std-types-number)
|
||||||
* [`string`](/docs/kcl-std/types/std-types-string)
|
* [`string`](/docs/kcl-std/types/std-types-string)
|
||||||
* [`tag`](/docs/kcl-std/types/std-types-tag)
|
|
||||||
* [**std::types**](/docs/kcl-std/modules/std-types)
|
* [**std::types**](/docs/kcl-std/modules/std-types)
|
||||||
* [`Axis2d`](/docs/kcl-std/types/std-types-Axis2d)
|
* [`Axis2d`](/docs/kcl-std/types/std-types-Axis2d)
|
||||||
* [`Axis3d`](/docs/kcl-std/types/std-types-Axis3d)
|
* [`Axis3d`](/docs/kcl-std/types/std-types-Axis3d)
|
||||||
@ -162,3 +162,5 @@ See also the [types overview](/docs/kcl-lang/types)
|
|||||||
* [`Point3d`](/docs/kcl-std/types/std-types-Point3d)
|
* [`Point3d`](/docs/kcl-std/types/std-types-Point3d)
|
||||||
* [`Sketch`](/docs/kcl-std/types/std-types-Sketch)
|
* [`Sketch`](/docs/kcl-std/types/std-types-Sketch)
|
||||||
* [`Solid`](/docs/kcl-std/types/std-types-Solid)
|
* [`Solid`](/docs/kcl-std/types/std-types-Solid)
|
||||||
|
* [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge)
|
||||||
|
* [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace)
|
||||||
|
@ -24,6 +24,9 @@ Types can (optionally) be used to describe a function's arguments and returned v
|
|||||||
* [`Point3d`](/docs/kcl-std/types/std-types-Point3d)
|
* [`Point3d`](/docs/kcl-std/types/std-types-Point3d)
|
||||||
* [`Sketch`](/docs/kcl-std/types/std-types-Sketch)
|
* [`Sketch`](/docs/kcl-std/types/std-types-Sketch)
|
||||||
* [`Solid`](/docs/kcl-std/types/std-types-Solid)
|
* [`Solid`](/docs/kcl-std/types/std-types-Solid)
|
||||||
|
* [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl)
|
||||||
|
* [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge)
|
||||||
|
* [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace)
|
||||||
* [`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)
|
||||||
|
102
docs/kcl-std/types/std-types-TagDecl.md
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
title: "TagDecl"
|
||||||
|
subtitle: "Type in std::types"
|
||||||
|
excerpt: "Tags are used to give a name (tag) to a specific path."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Tags are used to give a name (tag) to a specific path.
|
||||||
|
|
||||||
|
### Tag Declaration
|
||||||
|
|
||||||
|
The syntax for declaring a tag is `$myTag`. You would use it in the following
|
||||||
|
way:
|
||||||
|
|
||||||
|
```js
|
||||||
|
startSketchOn(XZ)
|
||||||
|
|> startProfile(at = origin)
|
||||||
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|
|> angledLine(
|
||||||
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
|
length = 196.99,
|
||||||
|
tag = $rectangleSegmentB001,
|
||||||
|
)
|
||||||
|
|> angledLine(
|
||||||
|
angle = segAng(rectangleSegmentA001),
|
||||||
|
length = -segLen(rectangleSegmentA001),
|
||||||
|
tag = $rectangleSegmentC001,
|
||||||
|
)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tag Scope
|
||||||
|
|
||||||
|
Tags are scoped globally if in the root context meaning in this example you can
|
||||||
|
use the tag `rectangleSegmentA001` in any function or expression in the file.
|
||||||
|
|
||||||
|
However if the code was written like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
fn rect(origin) {
|
||||||
|
return startSketchOn(XZ)
|
||||||
|
|> startProfile(at = origin)
|
||||||
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|
|> angledLine(
|
||||||
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
|
length = 196.99,
|
||||||
|
tag = $rectangleSegmentB001
|
||||||
|
)
|
||||||
|
|> angledLine(
|
||||||
|
angle = segAng(rectangleSegmentA001),
|
||||||
|
length = -segLen(rectangleSegmentA001),
|
||||||
|
tag = $rectangleSegmentC001
|
||||||
|
)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
}
|
||||||
|
|
||||||
|
rect(origin = [0, 0])
|
||||||
|
rect(origin = [20, 0])
|
||||||
|
```
|
||||||
|
|
||||||
|
Those tags would only be available in the `rect` function and not globally.
|
||||||
|
|
||||||
|
However you likely want to use those tags somewhere outside the `rect` function.
|
||||||
|
|
||||||
|
Tags are accessible through the sketch group they are declared in.
|
||||||
|
For example the following code works.
|
||||||
|
|
||||||
|
```js
|
||||||
|
fn rect(origin) {
|
||||||
|
return startSketchOn(XZ)
|
||||||
|
|> startProfile(at = origin)
|
||||||
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|
|> angledLine(
|
||||||
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
|
length = 196.99,
|
||||||
|
tag = $rectangleSegmentB001,
|
||||||
|
)
|
||||||
|
|> angledLine(
|
||||||
|
angle = segAng(rectangleSegmentA001),
|
||||||
|
length = -segLen(rectangleSegmentA001),
|
||||||
|
tag = $rectangleSegmentC001,
|
||||||
|
)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
}
|
||||||
|
|
||||||
|
rect(origin = [0, 0])
|
||||||
|
myRect = rect(origin = [20, 0])
|
||||||
|
|
||||||
|
myRect
|
||||||
|
|> extrude(length = 10)
|
||||||
|
|> fillet(radius = 0.5, tags = [myRect.tags.rectangleSegmentA001])
|
||||||
|
```
|
||||||
|
|
||||||
|
See how we use the tag `rectangleSegmentA001` in the `fillet` function outside
|
||||||
|
the `rect` function. This is because the `rect` function is returning the
|
||||||
|
sketch group that contains the tags.
|
||||||
|
|
||||||
|
|
||||||
|
|
17
docs/kcl-std/types/std-types-TaggedEdge.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
title: "TaggedEdge"
|
||||||
|
subtitle: "Type in std::types"
|
||||||
|
excerpt: "A tag which references a line, arc, or other edge in a sketch or an edge of a solid."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
A tag which references a line, arc, or other edge in a sketch or an edge of a solid.
|
||||||
|
|
||||||
|
Created by using a tag declarator (see the docs for [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl)). Can be used where an [`Edge`](/docs/kcl-std/types/std-types-Edge) is
|
||||||
|
required.
|
||||||
|
|
||||||
|
If a line in a sketch is tagged and then the sketch is extruded, the tag is a [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) before
|
||||||
|
extrusion and a [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) after extrusion.
|
||||||
|
|
||||||
|
|
||||||
|
|
16
docs/kcl-std/types/std-types-TaggedFace.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
title: "TaggedFace"
|
||||||
|
subtitle: "Type in std::types"
|
||||||
|
excerpt: "A tag which references a face of a solid, including the distinguished tags `START` and `END`."
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
A tag which references a face of a solid, including the distinguished tags `START` and `END`.
|
||||||
|
|
||||||
|
Created by using a tag declarator (see the docs for [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl)).
|
||||||
|
|
||||||
|
If a line in a sketch is tagged and then the sketch is extruded, the tag is a [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) before
|
||||||
|
extrusion and a [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace) after extrusion.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,109 +1,19 @@
|
|||||||
---
|
---
|
||||||
title: "tag"
|
title: "tag"
|
||||||
subtitle: "Type in std::types"
|
subtitle: "Type in std::types"
|
||||||
excerpt: "Tags are used to give a name (tag) to a specific path."
|
excerpt: "Reference a previously created tag. Used much like a variable."
|
||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
Tags are used to give a name (tag) to a specific path.
|
**WARNING:** This type is deprecated.
|
||||||
|
|
||||||
### Tag Declaration
|
Reference a previously created tag. Used much like a variable.
|
||||||
|
|
||||||
The syntax for declaring a tag is `$myTag` you would use it in the following
|
```kcl
|
||||||
way:
|
type tag = TaggedEdge
|
||||||
|
|
||||||
```js
|
|
||||||
startSketchOn(XZ)
|
|
||||||
|> startProfile(at = origin)
|
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|
||||||
|> angledLine(
|
|
||||||
angle = segAng(rectangleSegmentA001) - 90deg,
|
|
||||||
length = 196.99,
|
|
||||||
tag = $rectangleSegmentB001,
|
|
||||||
)
|
|
||||||
|> angledLine(
|
|
||||||
angle = segAng(rectangleSegmentA001),
|
|
||||||
length = -segLen(rectangleSegmentA001),
|
|
||||||
tag = $rectangleSegmentC001,
|
|
||||||
)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tag Identifier
|
Prefer to use [`TaggedEdge`](/docs/kcl-std/types/std-types-TaggedEdge) or [`TaggedFace`](/docs/kcl-std/types/std-types-TaggedFace). For more details on tags, see the docs for [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl).
|
||||||
|
|
||||||
As per the example above you can use the tag identifier to get a reference to the
|
|
||||||
tagged object. The syntax for this is `myTag`.
|
|
||||||
|
|
||||||
In the example above we use the tag identifier to get the angle of the segment
|
|
||||||
`segAng(rectangleSegmentA001)`.
|
|
||||||
|
|
||||||
### Tag Scope
|
|
||||||
|
|
||||||
Tags are scoped globally if in the root context meaning in this example you can
|
|
||||||
use the tag `rectangleSegmentA001` in any function or expression in the file.
|
|
||||||
|
|
||||||
However if the code was written like this:
|
|
||||||
|
|
||||||
```js
|
|
||||||
fn rect(origin) {
|
|
||||||
return startSketchOn(XZ)
|
|
||||||
|> startProfile(at = origin)
|
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|
||||||
|> angledLine(
|
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
|
||||||
length = 196.99,
|
|
||||||
tag = $rectangleSegmentB001)
|
|
||||||
|> angledLine(
|
|
||||||
angle = segAng(rectangleSegmentA001),
|
|
||||||
length = -segLen(rectangleSegmentA001),
|
|
||||||
tag = $rectangleSegmentC001
|
|
||||||
)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
}
|
|
||||||
|
|
||||||
rect(origin = [0, 0])
|
|
||||||
rect(origin = [20, 0])
|
|
||||||
```
|
|
||||||
|
|
||||||
Those tags would only be available in the `rect` function and not globally.
|
|
||||||
|
|
||||||
However you likely want to use those tags somewhere outside the `rect` function.
|
|
||||||
|
|
||||||
Tags are accessible through the sketch group they are declared in.
|
|
||||||
For example the following code works.
|
|
||||||
|
|
||||||
```js
|
|
||||||
fn rect(origin) {
|
|
||||||
return startSketchOn(XZ)
|
|
||||||
|> startProfile(at = origin)
|
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|
||||||
|> angledLine(
|
|
||||||
angle = segAng(rectangleSegmentA001) - 90deg,
|
|
||||||
length = 196.99
|
|
||||||
tag = $rectangleSegmentB001,
|
|
||||||
)
|
|
||||||
|> angledLine(
|
|
||||||
angle = segAng(rectangleSegmentA001),
|
|
||||||
length = -segLen(rectangleSegmentA001)
|
|
||||||
tag = $rectangleSegmentC001,
|
|
||||||
)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
}
|
|
||||||
|
|
||||||
rect(origin = [0, 0])
|
|
||||||
myRect = rect(origin = [20, 0])
|
|
||||||
|
|
||||||
myRect
|
|
||||||
|> extrude(length = 10)
|
|
||||||
|> fillet(radius = 0.5, tags = [myRect.tags.rectangleSegmentA001])
|
|
||||||
```
|
|
||||||
|
|
||||||
See how we use the tag `rectangleSegmentA001` in the `fillet` function outside
|
|
||||||
the `rect` function. This is because the `rect` function is returning the
|
|
||||||
sketch group that contains the tags.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,6 +265,8 @@ 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
|
||||||
|
|
||||||
|
Backtrace:
|
||||||
assert()
|
assert()
|
||||||
check()
|
check()
|
||||||
middle()`)
|
middle()`)
|
||||||
|
@ -4,7 +4,6 @@ import * as fsp from 'fs/promises'
|
|||||||
|
|
||||||
import { executorInputPath, getUtils } from '@e2e/playwright/test-utils'
|
import { executorInputPath, getUtils } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
import { expectPixelColor } from '@e2e/playwright/fixtures/sceneFixture'
|
|
||||||
|
|
||||||
test.describe('Command bar tests', () => {
|
test.describe('Command bar tests', () => {
|
||||||
test('Extrude from command bar selects extrude line after', async ({
|
test('Extrude from command bar selects extrude line after', async ({
|
||||||
@ -302,13 +301,13 @@ test.describe('Command bar tests', () => {
|
|||||||
|
|
||||||
// Assert that the an alternative variable name is chosen,
|
// Assert that the an alternative variable name is chosen,
|
||||||
// since the default variable name is already in use (distance)
|
// since the default variable name is already in use (distance)
|
||||||
await page.getByRole('button', { name: 'Create new variable' }).click()
|
await cmdBar.variableCheckbox.click()
|
||||||
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
|
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
|
||||||
'length001'
|
'length001'
|
||||||
)
|
)
|
||||||
|
|
||||||
const continueButton = page.getByRole('button', { name: 'Continue' })
|
const continueButton = page.getByRole('button', { name: 'Continue' })
|
||||||
const submitButton = page.getByRole('button', { name: 'Submit command' })
|
const submitButton = page.getByTestId('command-bar-submit')
|
||||||
await continueButton.click()
|
await continueButton.click()
|
||||||
|
|
||||||
// Review step and argument hotkeys
|
// Review step and argument hotkeys
|
||||||
@ -515,47 +514,6 @@ test.describe('Command bar tests', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
|
||||||
`Zoom to fit to shared model on web`,
|
|
||||||
{ tag: ['@web'] },
|
|
||||||
async ({ page, scene }) => {
|
|
||||||
if (process.env.TARGET !== 'web') {
|
|
||||||
// This test is web-only
|
|
||||||
// TODO: re-enable on CI as part of a new @web test suite
|
|
||||||
return
|
|
||||||
}
|
|
||||||
await test.step(`Prepare and navigate to home page with query params`, async () => {
|
|
||||||
// a quad in the top left corner of the XZ plane (which is out of the current view)
|
|
||||||
const code = `sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = startProfile(sketch001, at = [-484.34, 484.95])
|
|
||||||
|> yLine(length = -69.1)
|
|
||||||
|> xLine(length = 66.84)
|
|
||||||
|> yLine(length = 71.37)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
`
|
|
||||||
const targetURL = `?create-file=true&name=test&units=mm&code=${encodeURIComponent(btoa(code))}&ask-open-desktop=true`
|
|
||||||
await page.goto(page.url() + targetURL)
|
|
||||||
expect(page.url()).toContain(targetURL)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step(`Submit the command`, async () => {
|
|
||||||
await page.getByTestId('continue-to-web-app-button').click()
|
|
||||||
|
|
||||||
await scene.connectionEstablished()
|
|
||||||
|
|
||||||
// This makes SystemIOMachineActors.createKCLFile run after EngineStream/firstPlay
|
|
||||||
await page.waitForTimeout(3000)
|
|
||||||
|
|
||||||
await page.getByTestId('command-bar-submit').click()
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step(`Ensure we created the project and are in the modeling scene`, async () => {
|
|
||||||
await expectPixelColor(page, [252, 252, 252], { x: 600, y: 260 }, 8)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
test(`Can add and edit a named parameter or constant`, async ({
|
test(`Can add and edit a named parameter or constant`, async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
@ -54,9 +54,7 @@ test(
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
const submitButton = page.getByText('Confirm Export')
|
await cmdBar.submit()
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Expect it to succeed
|
// Expect it to succeed
|
||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||||
@ -119,9 +117,7 @@ test(
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
const submitButton = page.getByText('Confirm Export')
|
await cmdBar.submit()
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
const exportingToastMessage = page.getByText(`Exporting...`)
|
||||||
|
@ -1617,4 +1617,33 @@ sketch001 = startSketchOn(XZ)
|
|||||||
// Verify error is still visible
|
// Verify error is still visible
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(1)
|
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Core dump hotkey', async ({ page, scene, cmdBar, homePage }) => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = circle(sketch001, center = [-100.0, -100.0], radius = 50.0)
|
||||||
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const viewportSize = { width: 1200, height: 800 }
|
||||||
|
await page.setBodyDimensions(viewportSize)
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
const modifier = process.platform === 'darwin' ? 'Meta' : 'Control'
|
||||||
|
|
||||||
|
await page.keyboard.press(`${modifier}+Shift+.`)
|
||||||
|
|
||||||
|
const toast1 = page.getByText('Starting core dump...')
|
||||||
|
await expect(toast1).toBeVisible()
|
||||||
|
|
||||||
|
const toast2 = page.getByText('Core dump completed')
|
||||||
|
await expect(toast2).toBeVisible()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -229,11 +229,12 @@ test.describe('Feature Tree pane', () => {
|
|||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|> circle(center = [0, 0], radius = 5)
|
|> circle(center = [0, 0], radius = 5)
|
||||||
renamedExtrude = extrude(sketch001, length = ${initialInput})`
|
renamedExtrude = extrude(sketch001, length = ${initialInput})`
|
||||||
const newConstantName = 'length001'
|
const newParameterName = 'length001'
|
||||||
const expectedCode = `${newConstantName} = 23
|
const expectedCode = `${newParameterName} = 23
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> circle(center = [0, 0], radius = 5)
|
|> circle(center = [0, 0], radius = 5)
|
||||||
renamedExtrude = extrude(sketch001, length = ${newConstantName})`
|
renamedExtrude = extrude(sketch001, length = ${newParameterName})`
|
||||||
|
const editedParameterValue = '23 * 2'
|
||||||
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const testDir = join(dir, 'test-sample')
|
const testDir = join(dir, 'test-sample')
|
||||||
@ -279,12 +280,9 @@ test.describe('Feature Tree pane', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Add a named constant for distance argument and submit', async () => {
|
await test.step('Add a parameter for distance argument and submit', async () => {
|
||||||
await expect(cmdBar.currentArgumentInput).toBeVisible()
|
await expect(cmdBar.currentArgumentInput).toBeVisible()
|
||||||
const addVariableButton = page.getByRole('button', {
|
await cmdBar.variableCheckbox.click()
|
||||||
name: 'Create new variable',
|
|
||||||
})
|
|
||||||
await addVariableButton.click()
|
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
@ -299,13 +297,43 @@ test.describe('Feature Tree pane', () => {
|
|||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
activeLines: [
|
activeLines: [
|
||||||
`renamedExtrude = extrude(sketch001, length = ${newConstantName})`,
|
`renamedExtrude = extrude(sketch001, length = ${newParameterName})`,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
await editor.expectEditor.toContain(expectedCode, {
|
await editor.expectEditor.toContain(expectedCode, {
|
||||||
shouldNormalise: true,
|
shouldNormalise: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await test.step('Edit the parameter via the feature tree', async () => {
|
||||||
|
const parameter = await toolbar.getFeatureTreeOperation('Parameter', 0)
|
||||||
|
await parameter.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Edit parameter',
|
||||||
|
currentArgKey: 'value',
|
||||||
|
currentArgValue: '23',
|
||||||
|
headerArguments: {
|
||||||
|
Name: newParameterName,
|
||||||
|
Value: '23',
|
||||||
|
},
|
||||||
|
stage: 'arguments',
|
||||||
|
highlightedHeaderArg: 'value',
|
||||||
|
})
|
||||||
|
await cmdBar.argumentInput
|
||||||
|
.locator('[contenteditable]')
|
||||||
|
.fill(editedParameterValue)
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
commandName: 'Edit parameter',
|
||||||
|
headerArguments: {
|
||||||
|
Name: newParameterName,
|
||||||
|
Value: '46', // Shows calculated result
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await editor.expectEditor.toContain(editedParameterValue)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
test(`User can edit an offset plane operation from the feature tree`, async ({
|
test(`User can edit an offset plane operation from the feature tree`, async ({
|
||||||
context,
|
context,
|
||||||
|
@ -118,15 +118,11 @@ export class CmdBarFixture {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrowButton = this.page.getByRole('button', {
|
const arrowButton = this.page.getByTestId('command-bar-continue')
|
||||||
name: 'arrow right Continue',
|
|
||||||
})
|
|
||||||
if (await arrowButton.isVisible()) {
|
if (await arrowButton.isVisible()) {
|
||||||
await arrowButton.click()
|
await this.continue()
|
||||||
} else {
|
} else {
|
||||||
await this.page
|
await this.submit()
|
||||||
.getByRole('button', { name: 'checkmark Submit command' })
|
|
||||||
.click()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +168,10 @@ export class CmdBarFixture {
|
|||||||
return this.page.getByTestId('cmd-bar-arg-value')
|
return this.page.getByTestId('cmd-bar-arg-value')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get variableCheckbox() {
|
||||||
|
return this.page.getByTestId('cmd-bar-variable-checkbox')
|
||||||
|
}
|
||||||
|
|
||||||
get cmdOptions() {
|
get cmdOptions() {
|
||||||
return this.page.getByTestId('cmd-bar-option')
|
return this.page.getByTestId('cmd-bar-option')
|
||||||
}
|
}
|
||||||
@ -187,11 +187,18 @@ export class CmdBarFixture {
|
|||||||
return this.page.getByRole('option', options)
|
return this.page.getByRole('option', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select an optional argument from the command bar during review
|
||||||
|
*/
|
||||||
|
clickOptionalArgument = async (argName: string) => {
|
||||||
|
await this.page.getByTestId(`cmd-bar-add-optional-arg-${argName}`).click()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clicks the Create new variable button for kcl input
|
* Clicks the Create new variable button for kcl input
|
||||||
*/
|
*/
|
||||||
createNewVariable = async () => {
|
createNewVariable = async () => {
|
||||||
await this.page.getByRole('button', { name: 'Create new variable' }).click()
|
await this.variableCheckbox.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,14 +183,15 @@ export class EditorFixture {
|
|||||||
scrollToText(text: string, placeCursor?: boolean) {
|
scrollToText(text: string, placeCursor?: boolean) {
|
||||||
return this.page.evaluate(
|
return this.page.evaluate(
|
||||||
(args: { text: string; placeCursor?: boolean }) => {
|
(args: { text: string; placeCursor?: boolean }) => {
|
||||||
|
const editorView = window.editorManager.getEditorView()
|
||||||
// error TS2339: Property 'docView' does not exist on type 'EditorView'.
|
// error TS2339: Property 'docView' does not exist on type 'EditorView'.
|
||||||
// Except it does so :shrug:
|
// Except it does so :shrug:
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
let index = window.editorManager._editorView?.docView.view.state.doc
|
const index = editorView?.docView.view.state.doc
|
||||||
.toString()
|
.toString()
|
||||||
.indexOf(args.text)
|
.indexOf(args.text)
|
||||||
window.editorManager._editorView?.focus()
|
editorView?.focus()
|
||||||
window.editorManager._editorView?.dispatch({
|
editorView?.dispatch({
|
||||||
selection: window.EditorSelection.create([
|
selection: window.EditorSelection.create([
|
||||||
window.EditorSelection.cursor(index),
|
window.EditorSelection.cursor(index),
|
||||||
]),
|
]),
|
||||||
|
@ -5,7 +5,7 @@ import type {
|
|||||||
FullResult,
|
FullResult,
|
||||||
} from '@playwright/test/reporter'
|
} from '@playwright/test/reporter'
|
||||||
|
|
||||||
class MyAPIReporter implements Reporter {
|
class APIReporter implements Reporter {
|
||||||
private pendingRequests: Promise<void>[] = []
|
private pendingRequests: Promise<void>[] = []
|
||||||
private allResults: Record<string, any>[] = []
|
private allResults: Record<string, any>[] = []
|
||||||
private blockingResults: Record<string, any>[] = []
|
private blockingResults: Record<string, any>[] = []
|
||||||
@ -32,7 +32,7 @@ class MyAPIReporter implements Reporter {
|
|||||||
'X-API-Key': process.env.TAB_API_KEY || '',
|
'X-API-Key': process.env.TAB_API_KEY || '',
|
||||||
}),
|
}),
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
project: 'https://github.com/KittyCAD/modeling-app',
|
project: `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`,
|
||||||
branch:
|
branch:
|
||||||
process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
||||||
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
||||||
@ -60,7 +60,7 @@ class MyAPIReporter implements Reporter {
|
|||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
// Required information
|
// Required information
|
||||||
project: 'https://github.com/KittyCAD/modeling-app',
|
project: `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`,
|
||||||
suite: process.env.CI_SUITE || 'e2e',
|
suite: process.env.CI_SUITE || 'e2e',
|
||||||
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
||||||
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
||||||
@ -124,4 +124,4 @@ class MyAPIReporter implements Reporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MyAPIReporter
|
export default APIReporter
|
||||||
|
@ -1083,14 +1083,13 @@ openSketch = startSketchOn(XY)
|
|||||||
cmdBar,
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 700, y: 150 }
|
const testPoint = { x: 700, y: 200 }
|
||||||
|
// TODO: replace the testPoint selection with a feature tree click once that's supported #7544
|
||||||
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||||
const expectedOutput = `plane001 = offsetPlane(XZ, offset = 5)`
|
const expectedOutput = `plane001 = offsetPlane(XZ, offset = 5)`
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
// FIXME: Since there is no KCL code loaded. We need to wait for the scene to load before we continue.
|
await scene.settled(cmdBar)
|
||||||
// The engine may not be connected
|
|
||||||
await page.waitForTimeout(15000)
|
|
||||||
|
|
||||||
await test.step(`Look for the blue of the XZ plane`, async () => {
|
await test.step(`Look for the blue of the XZ plane`, async () => {
|
||||||
//await scene.expectPixelColor([50, 51, 96], testPoint, 15) // FIXME
|
//await scene.expectPixelColor([50, 51, 96], testPoint, 15) // FIXME
|
||||||
@ -1611,6 +1610,8 @@ sketch002 = startSketchOn(plane001)
|
|||||||
testPoint.y + 80
|
testPoint.y + 80
|
||||||
)
|
)
|
||||||
const loftDeclaration = 'loft001 = loft([sketch001, sketch002])'
|
const loftDeclaration = 'loft001 = loft([sketch001, sketch002])'
|
||||||
|
const editedLoftDeclaration =
|
||||||
|
'loft001 = loft([sketch001, sketch002], vDegree = 3)'
|
||||||
|
|
||||||
await test.step(`Look for the white of the sketch001 shape`, async () => {
|
await test.step(`Look for the white of the sketch001 shape`, async () => {
|
||||||
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
||||||
@ -1682,6 +1683,39 @@ sketch002 = startSketchOn(plane001)
|
|||||||
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await test.step('Go through the edit flow via feature tree', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const op = await toolbar.getFeatureTreeOperation('Loft', 0)
|
||||||
|
await op.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {},
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('vDegree')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'vDegree',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
VDegree: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'vDegree',
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('3')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
VDegree: '3',
|
||||||
|
},
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
await editor.expectEditor.toContain(editedLoftDeclaration)
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('Delete loft via feature tree selection', async () => {
|
await test.step('Delete loft via feature tree selection', async () => {
|
||||||
await editor.closePane()
|
await editor.closePane()
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation('Loft', 0)
|
const operationButton = await toolbar.getFeatureTreeOperation('Loft', 0)
|
||||||
@ -1692,72 +1726,6 @@ sketch002 = startSketchOn(plane001)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: merge with above test. Right now we're not able to delete a loft
|
|
||||||
// right after creation via selection for some reason, so we go with a new instance
|
|
||||||
test('Loft and offset plane deletion via selection', async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
|
||||||
|> circle(center = [0, 0], radius = 30)
|
|
||||||
plane001 = offsetPlane(XZ, offset = 50)
|
|
||||||
sketch002 = startSketchOn(plane001)
|
|
||||||
|> circle(center = [0, 0], radius = 20)
|
|
||||||
loft001 = loft([sketch001, sketch002])
|
|
||||||
`
|
|
||||||
await context.addInitScript((initialCode) => {
|
|
||||||
localStorage.setItem('persistCode', initialCode)
|
|
||||||
}, initialCode)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
|
||||||
const testPoint = { x: 575, y: 200 }
|
|
||||||
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
|
||||||
const [clickOnSketch2] = scene.makeMouseHelpers(
|
|
||||||
testPoint.x,
|
|
||||||
testPoint.y + 80
|
|
||||||
)
|
|
||||||
|
|
||||||
await test.step(`Delete loft`, async () => {
|
|
||||||
// Check for loft
|
|
||||||
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
|
||||||
await clickOnSketch1()
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
|
||||||
|> circle(center = [0, 0], radius = 30)
|
|
||||||
`)
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
// Check for sketch 1
|
|
||||||
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Delete sketch002', async () => {
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await clickOnSketch2()
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
|
||||||
|> circle(center = [0, 0], radius = 20)
|
|
||||||
`)
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
// Check for plane001
|
|
||||||
await scene.expectPixelColor([228, 228, 228], testPoint, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Delete plane001', async () => {
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await clickOnSketch2()
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
|
||||||
plane001 = offsetPlane(XZ, offset = 50)
|
|
||||||
`)
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
// Check for sketch 1
|
|
||||||
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const sweepCases = [
|
const sweepCases = [
|
||||||
{
|
{
|
||||||
targetType: 'circle',
|
targetType: 'circle',
|
||||||
@ -1829,7 +1797,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
currentArgKey: 'sketches',
|
currentArgKey: 'sketches',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
|
||||||
Profiles: '',
|
Profiles: '',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
@ -1843,7 +1810,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
currentArgKey: 'path',
|
currentArgKey: 'path',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
|
||||||
Profiles: '1 profile',
|
Profiles: '1 profile',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
@ -1856,7 +1822,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
currentArgKey: 'path',
|
currentArgKey: 'path',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
|
||||||
Profiles: '1 profile',
|
Profiles: '1 profile',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
@ -1869,7 +1834,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Profiles: '1 profile',
|
||||||
Path: '1 segment',
|
Path: '1 segment',
|
||||||
Sectional: '',
|
|
||||||
},
|
},
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
})
|
})
|
||||||
@ -1894,6 +1858,9 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
await operationButton.dblclick({ button: 'left' })
|
await operationButton.dblclick({ button: 'left' })
|
||||||
|
await page
|
||||||
|
.getByRole('button', { name: 'sectional', exact: false })
|
||||||
|
.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
currentArgKey: 'sectional',
|
currentArgKey: 'sectional',
|
||||||
@ -1956,6 +1923,7 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = ${circleCode}`
|
profile001 = ${circleCode}`
|
||||||
const sweepDeclaration = 'sweep001 = sweep(profile001, path = helix001)'
|
const sweepDeclaration = 'sweep001 = sweep(profile001, path = helix001)'
|
||||||
|
const editedSweepDeclaration = `sweep001 = sweep(profile001, path = helix001, relativeTo = 'sketchPlane')`
|
||||||
|
|
||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
localStorage.setItem('persistCode', initialCode)
|
localStorage.setItem('persistCode', initialCode)
|
||||||
@ -1971,7 +1939,6 @@ profile001 = ${circleCode}`
|
|||||||
currentArgKey: 'sketches',
|
currentArgKey: 'sketches',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
|
||||||
Profiles: '',
|
Profiles: '',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
@ -1986,7 +1953,6 @@ profile001 = ${circleCode}`
|
|||||||
currentArgKey: 'path',
|
currentArgKey: 'path',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
|
||||||
Profiles: '1 profile',
|
Profiles: '1 profile',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
@ -2000,7 +1966,6 @@ profile001 = ${circleCode}`
|
|||||||
currentArgKey: 'path',
|
currentArgKey: 'path',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
|
||||||
Profiles: '1 profile',
|
Profiles: '1 profile',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
@ -2013,7 +1978,6 @@ profile001 = ${circleCode}`
|
|||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Profiles: '1 profile',
|
||||||
Path: '1 helix',
|
Path: '1 helix',
|
||||||
Sectional: '',
|
|
||||||
},
|
},
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
})
|
})
|
||||||
@ -2021,11 +1985,43 @@ profile001 = ${circleCode}`
|
|||||||
await editor.expectEditor.toContain(sweepDeclaration)
|
await editor.expectEditor.toContain(sweepDeclaration)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await test.step('Go through the edit flow via feature tree', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const op = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
||||||
|
await op.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {},
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('relativeTo')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'relativeTo',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
RelativeTo: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'relativeTo',
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.selectOption({ name: 'sketchPlane' }).click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
RelativeTo: 'sketchPlane',
|
||||||
|
},
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
await editor.expectEditor.toContain(editedSweepDeclaration)
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('Delete sweep via feature tree selection', async () => {
|
await test.step('Delete sweep via feature tree selection', async () => {
|
||||||
const sweep = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
const sweep = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
||||||
await sweep.click()
|
await sweep.click()
|
||||||
await page.keyboard.press('Delete')
|
await page.keyboard.press('Delete')
|
||||||
await editor.expectEditor.not.toContain(sweepDeclaration)
|
await editor.expectEditor.not.toContain(editedSweepDeclaration)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3807,7 +3803,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
await page.keyboard.insertText(newAngle)
|
await page.keyboard.insertText(newAngle)
|
||||||
await page.getByRole('button', { name: 'Create new variable' }).click()
|
await cmdBar.variableCheckbox.click()
|
||||||
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
|
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
|
||||||
'angle001'
|
'angle001'
|
||||||
)
|
)
|
||||||
@ -3885,6 +3881,8 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
const newAngle = '270'
|
const newAngle = '270'
|
||||||
|
const newAngle2 = '5'
|
||||||
|
const editedCodeToFind = `revolve001 = revolve(sketch003, angle = ${newAngle}, axis = seg01, bidirectionalAngle = ${newAngle2}, )`
|
||||||
await toolbar.openPane('feature-tree')
|
await toolbar.openPane('feature-tree')
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
const operationButton = await toolbar.getFeatureTreeOperation(
|
||||||
'Revolve',
|
'Revolve',
|
||||||
@ -3910,11 +3908,33 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
},
|
},
|
||||||
commandName: 'Revolve',
|
commandName: 'Revolve',
|
||||||
})
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('bidirectionalAngle')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Revolve',
|
||||||
|
currentArgKey: 'bidirectionalAngle',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Angle: newAngle,
|
||||||
|
BidirectionalAngle: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'bidirectionalAngle',
|
||||||
|
stage: 'arguments',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText(newAngle2)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Angle: newAngle,
|
||||||
|
BidirectionalAngle: newAngle2,
|
||||||
|
},
|
||||||
|
commandName: 'Revolve',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(editedCodeToFind, {
|
||||||
newCodeToFind.replace('angle = 360', 'angle = ' + newAngle)
|
shouldNormalise: true,
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -4734,7 +4754,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '',
|
Profiles: '',
|
||||||
Path: '',
|
Path: '',
|
||||||
Sectional: '',
|
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'Profiles',
|
highlightedHeaderArg: 'Profiles',
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
@ -4747,7 +4766,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Profiles: '2 profiles',
|
||||||
Path: '',
|
Path: '',
|
||||||
Sectional: '',
|
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'path',
|
highlightedHeaderArg: 'path',
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
@ -4760,7 +4778,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Profiles: '2 profiles',
|
||||||
Path: '1 segment',
|
Path: '1 segment',
|
||||||
Sectional: '',
|
|
||||||
},
|
},
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
})
|
})
|
||||||
@ -4932,4 +4949,154 @@ extrude001 = extrude(profile001 length = 1)`
|
|||||||
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Point-and-click extrude with optional args', async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const squareProfileCode = `length001 = 100
|
||||||
|
sketch001 = startSketchOn(XY)
|
||||||
|
profile001 = startProfile(sketch001, at = [0, 0])
|
||||||
|
|> yLine(length = length001)
|
||||||
|
|> xLine(length = length001)
|
||||||
|
|> yLine(length = -length001)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
`
|
||||||
|
await context.addInitScript((initialCode) => {
|
||||||
|
localStorage.setItem('persistCode', initialCode)
|
||||||
|
}, squareProfileCode)
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await test.step('Select through code', async () => {
|
||||||
|
await editor.selectText('startProfile(sketch001, at = [0, 0])')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Go through command bar flow', async () => {
|
||||||
|
await toolbar.extrudeButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '',
|
||||||
|
Length: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'Profiles',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'length',
|
||||||
|
currentArgValue: '5',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'length',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '5',
|
||||||
|
},
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('bidirectionalLength')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'bidirectionalLength',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '5',
|
||||||
|
BidirectionalLength: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'bidirectionalLength',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('10')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '5',
|
||||||
|
BidirectionalLength: '10',
|
||||||
|
},
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Check that the code has changed', async () => {
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`extrude001 = extrude(profile001, length = 5, bidirectionalLength = 10)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Go through the edit flow via feature tree', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const op = await toolbar.getFeatureTreeOperation('Extrude', 0)
|
||||||
|
await op.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'length',
|
||||||
|
currentArgValue: '5',
|
||||||
|
headerArguments: {
|
||||||
|
Length: '5',
|
||||||
|
BidirectionalLength: '10',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'length',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('10')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.getByRole('button', { name: 'BidirectionalLength' }).click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'bidirectionalLength',
|
||||||
|
currentArgValue: '10',
|
||||||
|
headerArguments: {
|
||||||
|
Length: '10',
|
||||||
|
BidirectionalLength: '10',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'bidirectionalLength',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('20')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Length: '10',
|
||||||
|
BidirectionalLength: '20',
|
||||||
|
},
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Check that the code has changed again', async () => {
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await toolbar.closePane('feature-tree')
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`extrude001 = extrude(profile001, length = 10, bidirectionalLength = 20)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -170,7 +170,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 =
|
const crypticErrorText =
|
||||||
'tag requires a value with type `tag`, but found a value with type `string`.'
|
'tag requires a value with type `TagDecl`, but found a value with type `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.
|
||||||
@ -369,7 +369,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 =
|
const crypticErrorText =
|
||||||
'tag requires a value with type `tag`, but found a value with type `string`.'
|
'tag requires a value with type `TagDecl`, but found a value with type `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.
|
||||||
@ -408,7 +408,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 =
|
const crypticErrorText =
|
||||||
'tag requires a value with type `tag`, but found a value with type `string`.'
|
'tag requires a value with type `TagDecl`, but found a value with type `string`.'
|
||||||
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
|
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -475,6 +475,7 @@ test.describe('Can export from electron app', () => {
|
|||||||
},
|
},
|
||||||
tronApp.projectDirName,
|
tronApp.projectDirName,
|
||||||
page,
|
page,
|
||||||
|
cmdBar,
|
||||||
method
|
method
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -779,9 +780,6 @@ test.describe(`Project management commands`, () => {
|
|||||||
const commandContinueButton = page.getByRole('button', {
|
const commandContinueButton = page.getByRole('button', {
|
||||||
name: 'Continue',
|
name: 'Continue',
|
||||||
})
|
})
|
||||||
const commandSubmitButton = page.getByRole('button', {
|
|
||||||
name: 'Submit command',
|
|
||||||
})
|
|
||||||
const toastMessage = page.getByText(`Successfully renamed`)
|
const toastMessage = page.getByText(`Successfully renamed`)
|
||||||
|
|
||||||
await test.step(`Setup`, async () => {
|
await test.step(`Setup`, async () => {
|
||||||
@ -800,8 +798,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
await expect(commandContinueButton).toBeVisible()
|
await expect(commandContinueButton).toBeVisible()
|
||||||
await commandContinueButton.click()
|
await commandContinueButton.click()
|
||||||
|
|
||||||
await expect(commandSubmitButton).toBeVisible()
|
await cmdBar.submit()
|
||||||
await commandSubmitButton.click()
|
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
@ -837,9 +834,6 @@ test.describe(`Project management commands`, () => {
|
|||||||
})
|
})
|
||||||
const projectNameOption = page.getByRole('option', { name: projectName })
|
const projectNameOption = page.getByRole('option', { name: projectName })
|
||||||
const commandWarning = page.getByText('Are you sure you want to delete?')
|
const commandWarning = page.getByText('Are you sure you want to delete?')
|
||||||
const commandSubmitButton = page.getByRole('button', {
|
|
||||||
name: 'Submit command',
|
|
||||||
})
|
|
||||||
const toastMessage = page.getByText(`Successfully deleted`)
|
const toastMessage = page.getByText(`Successfully deleted`)
|
||||||
const noProjectsMessage = page.getByText('No projects found')
|
const noProjectsMessage = page.getByText('No projects found')
|
||||||
|
|
||||||
@ -859,8 +853,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
await projectNameOption.click()
|
await projectNameOption.click()
|
||||||
|
|
||||||
await expect(commandWarning).toBeVisible()
|
await expect(commandWarning).toBeVisible()
|
||||||
await expect(commandSubmitButton).toBeVisible()
|
await cmdBar.submit()
|
||||||
await commandSubmitButton.click()
|
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
@ -894,9 +887,6 @@ test.describe(`Project management commands`, () => {
|
|||||||
const commandContinueButton = page.getByRole('button', {
|
const commandContinueButton = page.getByRole('button', {
|
||||||
name: 'Continue',
|
name: 'Continue',
|
||||||
})
|
})
|
||||||
const commandSubmitButton = page.getByRole('button', {
|
|
||||||
name: 'Submit command',
|
|
||||||
})
|
|
||||||
const toastMessage = page.getByText(`Successfully renamed`)
|
const toastMessage = page.getByText(`Successfully renamed`)
|
||||||
|
|
||||||
await test.step(`Setup`, async () => {
|
await test.step(`Setup`, async () => {
|
||||||
@ -914,8 +904,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
await expect(commandContinueButton).toBeVisible()
|
await expect(commandContinueButton).toBeVisible()
|
||||||
await commandContinueButton.click()
|
await commandContinueButton.click()
|
||||||
|
|
||||||
await expect(commandSubmitButton).toBeVisible()
|
await cmdBar.submit()
|
||||||
await commandSubmitButton.click()
|
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
@ -949,9 +938,6 @@ test.describe(`Project management commands`, () => {
|
|||||||
})
|
})
|
||||||
const projectNameOption = page.getByRole('option', { name: projectName })
|
const projectNameOption = page.getByRole('option', { name: projectName })
|
||||||
const commandWarning = page.getByText('Are you sure you want to delete?')
|
const commandWarning = page.getByText('Are you sure you want to delete?')
|
||||||
const commandSubmitButton = page.getByRole('button', {
|
|
||||||
name: 'Submit command',
|
|
||||||
})
|
|
||||||
const toastMessage = page.getByText(`Successfully deleted`)
|
const toastMessage = page.getByText(`Successfully deleted`)
|
||||||
const noProjectsMessage = page.getByText('No projects found')
|
const noProjectsMessage = page.getByText('No projects found')
|
||||||
|
|
||||||
@ -967,8 +953,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
await projectNameOption.click()
|
await projectNameOption.click()
|
||||||
|
|
||||||
await expect(commandWarning).toBeVisible()
|
await expect(commandWarning).toBeVisible()
|
||||||
await expect(commandSubmitButton).toBeVisible()
|
await cmdBar.submit()
|
||||||
await commandSubmitButton.click()
|
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { bracket } from '@e2e/playwright/fixtures/bracket'
|
import { bracket } from '@e2e/playwright/fixtures/bracket'
|
||||||
import type { Page } from '@playwright/test'
|
import type { Page } from '@playwright/test'
|
||||||
|
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
import * as fsp from 'fs/promises'
|
import * as fsp from 'fs/promises'
|
||||||
|
|
||||||
@ -421,10 +422,7 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
const submitButton = page.getByText('Confirm Export')
|
await cmdBar.submit()
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
@ -461,8 +459,7 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
await expect(submitButton).toBeVisible()
|
await cmdBar.submit()
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
@ -482,6 +479,7 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
test('ensure you CAN export while an export is already going', async ({
|
test('ensure you CAN export while an export is already going', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await test.step('Set up the code and durations', async () => {
|
await test.step('Set up the code and durations', async () => {
|
||||||
@ -516,11 +514,11 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
const successToastMessage = page.getByText(`Exported successfully`)
|
||||||
|
|
||||||
await test.step('second export', async () => {
|
await test.step('second export', async () => {
|
||||||
await clickExportButton(page)
|
await clickExportButton(page, cmdBar)
|
||||||
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
await expect(exportingToastMessage).toBeVisible()
|
||||||
|
|
||||||
await clickExportButton(page)
|
await clickExportButton(page, cmdBar)
|
||||||
|
|
||||||
await test.step('The first export still succeeds', async () => {
|
await test.step('The first export still succeeds', async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -537,7 +535,7 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
|
|
||||||
await test.step('Successful, unblocked export', async () => {
|
await test.step('Successful, unblocked export', async () => {
|
||||||
// Try exporting again.
|
// Try exporting again.
|
||||||
await clickExportButton(page)
|
await clickExportButton(page, cmdBar)
|
||||||
|
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
@ -575,7 +573,7 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
name: 'Projects',
|
name: 'Projects',
|
||||||
})
|
})
|
||||||
const projectLink = page.getByRole('link', { name: 'bracket' })
|
const projectLink = page.getByRole('link', { name: 'bracket' })
|
||||||
const networkHealthIndicator = page.getByTestId('network-toggle')
|
const networkHealthIndicator = page.getByTestId(/network-toggle/)
|
||||||
|
|
||||||
await test.step('Check the home page', async () => {
|
await test.step('Check the home page', async () => {
|
||||||
await expect(projectsHeading).toBeVisible()
|
await expect(projectsHeading).toBeVisible()
|
||||||
@ -880,7 +878,7 @@ s2 = startSketchOn(XY)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
async function clickExportButton(page: Page) {
|
async function clickExportButton(page: Page, cmdBar: CmdBarFixture) {
|
||||||
await test.step('Running export flow', async () => {
|
await test.step('Running export flow', async () => {
|
||||||
// export the model
|
// export the model
|
||||||
const exportButton = page.getByTestId('export-pane-button')
|
const exportButton = page.getByTestId('export-pane-button')
|
||||||
@ -896,9 +894,6 @@ async function clickExportButton(page: Page) {
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
const submitButton = page.getByText('Confirm Export')
|
await cmdBar.submit()
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1445,6 +1445,103 @@ solid001 = subtract([extrude001], tools = [extrude002])
|
|||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Can edit a tangentialArc defined by angle and radius', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const viewportSize = { width: 1500, height: 750 }
|
||||||
|
await page.setBodyDimensions(viewportSize)
|
||||||
|
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`@settings(defaultLengthUnit=in)
|
||||||
|
sketch001 = startSketchOn(XZ)
|
||||||
|
|> startProfile(at = [-10, -10])
|
||||||
|
|> line(end = [20.0, 10.0])
|
||||||
|
|> tangentialArc(angle = 60deg, radius=10.0)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await toolbar.waitForFeatureTreeToBeBuilt()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await (await toolbar.getFeatureTreeOperation('Sketch', 0)).dblclick()
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
|
await page.mouse.move(1200, 139)
|
||||||
|
await page.mouse.down()
|
||||||
|
await page.mouse.move(870, 250)
|
||||||
|
await page.mouse.up()
|
||||||
|
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`tangentialArc(angle = 234.01deg, radius = 4.08)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Can undo with closed code pane', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
const viewportSize = { width: 1500, height: 750 }
|
||||||
|
await page.setBodyDimensions(viewportSize)
|
||||||
|
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`@settings(defaultLengthUnit=in)
|
||||||
|
sketch001 = startSketchOn(XZ)
|
||||||
|
|> startProfile(at = [-10, -10])
|
||||||
|
|> line(end = [20.0, 10.0])
|
||||||
|
|> tangentialArc(end = [5.49, 8.37])`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await toolbar.waitForFeatureTreeToBeBuilt()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await (await toolbar.getFeatureTreeOperation('Sketch', 0)).dblclick()
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
|
await page.mouse.move(1200, 139)
|
||||||
|
await page.mouse.down()
|
||||||
|
await page.mouse.move(870, 250)
|
||||||
|
await page.mouse.up()
|
||||||
|
|
||||||
|
await editor.expectEditor.toContain(`tangentialArc(end=[-5.85,4.32])`, {
|
||||||
|
shouldNormalise: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
await u.closeKclCodePanel()
|
||||||
|
|
||||||
|
// Undo the last change
|
||||||
|
await page.keyboard.down('Control')
|
||||||
|
await page.keyboard.press('KeyZ')
|
||||||
|
await page.keyboard.up('Control')
|
||||||
|
|
||||||
|
await u.openKclCodePanel()
|
||||||
|
await editor.expectEditor.toContain(`tangentialArc(end = [5.49, 8.37])`, {
|
||||||
|
shouldNormalise: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('Can delete a single segment line with keyboard', async ({
|
test('Can delete a single segment line with keyboard', async ({
|
||||||
page,
|
page,
|
||||||
scene,
|
scene,
|
||||||
|
@ -798,7 +798,7 @@ test('theme persists', async ({ page, context, homePage }) => {
|
|||||||
|
|
||||||
await page.getByTestId('settings-close-button').click()
|
await page.getByTestId('settings-close-button').click()
|
||||||
|
|
||||||
const networkToggle = page.getByTestId('network-toggle')
|
const networkToggle = page.getByTestId(/network-toggle/)
|
||||||
|
|
||||||
// simulate network down
|
// simulate network down
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |