Compare commits
7 Commits
nadro/adho
...
nrc-warn-a
Author | SHA1 | Date | |
---|---|---|---|
14e3311050 | |||
d4c5cef78a | |||
4b4960ac2c | |||
8c36105113 | |||
77e5d6e3a5 | |||
bfaec5c04e | |||
8395869b2e |
@ -9,7 +9,6 @@ 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"
|
||||||
|
|
||||||
|
11
.github/ISSUE_TEMPLATE/release.md
vendored
@ -2,7 +2,7 @@
|
|||||||
name: Release
|
name: Release
|
||||||
about: Create a new release for the Zoo Design Studio
|
about: Create a new release for the Zoo Design Studio
|
||||||
title: "Cut release v1.?.?"
|
title: "Cut release v1.?.?"
|
||||||
labels: [meta/release]
|
labels: [release]
|
||||||
---
|
---
|
||||||
|
|
||||||
> Instructions: https://github.com/KittyCAD/modeling-app/blob/main/CONTRIBUTING.md#shipping-releases
|
> Instructions: https://github.com/KittyCAD/modeling-app/blob/main/CONTRIBUTING.md#shipping-releases
|
||||||
@ -19,8 +19,7 @@ Release builds URL: ???
|
|||||||
* [ ] Confirm the application opens (dismiss the updater)
|
* [ ] Confirm the application opens (dismiss the updater)
|
||||||
* [ ] Create a project with a basic Text-to-CAD prompt
|
* [ ] Create a project with a basic Text-to-CAD prompt
|
||||||
* [ ] Confirm the result is viewable in an engine stream
|
* [ ] Confirm the result is viewable in an engine stream
|
||||||
* [ ] Use 'Check for updates' to bring back the updater toast
|
* [ ] Open the application again and confirm the updater can downgrade
|
||||||
* [ ] Confirm the app can update to the previous release
|
|
||||||
|
|
||||||
## macOS via ???
|
## macOS via ???
|
||||||
|
|
||||||
@ -28,8 +27,7 @@ Release builds URL: ???
|
|||||||
* [ ] Confirm the application opens (dismiss the updater)
|
* [ ] Confirm the application opens (dismiss the updater)
|
||||||
* [ ] Create a project with a basic Text-to-CAD prompt
|
* [ ] Create a project with a basic Text-to-CAD prompt
|
||||||
* [ ] Confirm the result is viewable in an engine stream
|
* [ ] Confirm the result is viewable in an engine stream
|
||||||
* [ ] Use 'Check for updates' to bring back the updater toast
|
* [ ] Open the application again and confirm the updater can downgrade
|
||||||
* [ ] Confirm the app can update to the previous release
|
|
||||||
|
|
||||||
## Linux via ???
|
## Linux via ???
|
||||||
|
|
||||||
@ -37,5 +35,4 @@ Release builds URL: ???
|
|||||||
* [ ] Confirm the application opens (dismiss the updater)
|
* [ ] Confirm the application opens (dismiss the updater)
|
||||||
* [ ] Create a project with a basic Text-to-CAD prompt
|
* [ ] Create a project with a basic Text-to-CAD prompt
|
||||||
* [ ] Confirm the result is viewable in an engine stream
|
* [ ] Confirm the result is viewable in an engine stream
|
||||||
* [ ] Use 'Check for updates' to bring back the updater toast
|
* [ ] Open the application again and confirm the updater can downgrade
|
||||||
* [ ] Confirm the app can update to the previous release
|
|
||||||
|
4
.github/workflows/build-apps.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
|||||||
- name: Download Wasm Cache
|
- name: Download Wasm Cache
|
||||||
id: download-wasm
|
id: download-wasm
|
||||||
if: ${{ github.event_name == 'pull_request' && steps.filter.outputs.rust == 'false' }}
|
if: ${{ github.event_name == 'pull_request' && steps.filter.outputs.rust == 'false' }}
|
||||||
uses: dawidd6/action-download-artifact@v11
|
uses: dawidd6/action-download-artifact@v7
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||||
@ -362,7 +362,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_STAGING == 'true' }}
|
||||||
uses: 'google-github-actions/auth@v2.1.10'
|
uses: 'google-github-actions/auth@v2.1.8'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
|
12
.github/workflows/cargo-test.yml
vendored
@ -25,8 +25,8 @@ jobs:
|
|||||||
- runner=8cpu-linux-x64
|
- runner=8cpu-linux-x64
|
||||||
- extras=s3-cache
|
- extras=s3-cache
|
||||||
steps:
|
steps:
|
||||||
- uses: runs-on/action@v2
|
- uses: runs-on/action@v1
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||||
@ -149,8 +149,8 @@ jobs:
|
|||||||
partitionIndex: [1, 2, 3, 4, 5, 6]
|
partitionIndex: [1, 2, 3, 4, 5, 6]
|
||||||
partitionTotal: [6]
|
partitionTotal: [6]
|
||||||
steps:
|
steps:
|
||||||
- uses: runs-on/action@v2
|
- uses: runs-on/action@v1
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||||
@ -207,8 +207,8 @@ jobs:
|
|||||||
- runner=32cpu-linux-x64
|
- runner=32cpu-linux-x64
|
||||||
- extras=s3-cache
|
- extras=s3-cache
|
||||||
steps:
|
steps:
|
||||||
- uses: runs-on/action@v2
|
- uses: runs-on/action@v1
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||||
|
6
.github/workflows/e2e-tests.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
|||||||
- name: Download Wasm cache
|
- name: Download Wasm cache
|
||||||
id: download-wasm
|
id: download-wasm
|
||||||
if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
|
if: ${{ github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
|
||||||
uses: dawidd6/action-download-artifact@v11
|
uses: dawidd6/action-download-artifact@v7
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||||
@ -110,7 +110,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||||
@ -230,7 +230,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||||
|
2
.github/workflows/generate-website-docs.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
# required
|
# required
|
||||||
|
2
.github/workflows/kcl-language-server.yml
vendored
@ -328,7 +328,7 @@ jobs:
|
|||||||
mkdir -p releases/language-server/${{ env.TAG }}
|
mkdir -p releases/language-server/${{ env.TAG }}
|
||||||
cp -r build/* releases/language-server/${{ env.TAG }}
|
cp -r build/* releases/language-server/${{ env.TAG }}
|
||||||
- name: "Authenticate to Google Cloud"
|
- name: "Authenticate to Google Cloud"
|
||||||
uses: "google-github-actions/auth@v2.1.10"
|
uses: "google-github-actions/auth@v2.1.8"
|
||||||
with:
|
with:
|
||||||
credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}"
|
credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}"
|
||||||
- name: Set up Cloud SDK
|
- name: Set up Cloud SDK
|
||||||
|
6
.github/workflows/kcl-python-bindings.yml
vendored
@ -113,7 +113,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v5
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
- uses: taiki-e/install-action@just
|
- uses: taiki-e/install-action@just
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
@ -130,7 +130,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install the latest version of uv
|
- name: Install the latest version of uv
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v5
|
||||||
- name: Install codespell
|
- name: Install codespell
|
||||||
run: |
|
run: |
|
||||||
uv venv .venv
|
uv venv .venv
|
||||||
@ -161,7 +161,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: rust/kcl-python-bindings
|
path: rust/kcl-python-bindings
|
||||||
- name: Install the latest version of uv
|
- name: Install the latest version of uv
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v5
|
||||||
- name: do uv things
|
- name: do uv things
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-python-bindings
|
cd rust/kcl-python-bindings
|
||||||
|
2
.github/workflows/publish-apps-release.yml
vendored
@ -108,7 +108,7 @@ jobs:
|
|||||||
run: npm run files:set-notes
|
run: npm run files:set-notes
|
||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
uses: 'google-github-actions/auth@v2.1.10'
|
uses: 'google-github-actions/auth@v2.1.8'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
|
@ -280,9 +280,6 @@ Assign someone to each section of the manual checklist generated by the issue te
|
|||||||
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.
|
||||||
|
3
Makefile
@ -62,10 +62,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
public/kcl-samples/manifest.json: $(KCL_SOURCES)
|
public/kcl-samples/manifest.json: $(KCL_SOURCES)
|
||||||
ifndef WINDOWS
|
|
||||||
cd rust/kcl-lib && EXPECTORATE=overwrite cargo test generate_manifest
|
cd rust/kcl-lib && EXPECTORATE=overwrite cargo test generate_manifest
|
||||||
@ touch $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
.vite/build/main.js: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
|
.vite/build/main.js: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
|
||||||
npm run tronb:vite:dev
|
npm run tronb:vite:dev
|
||||||
|
@ -83,13 +83,6 @@ 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
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,11 +10,9 @@ 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?: TagDecl,
|
tag?: TagDecl,
|
||||||
): Sketch
|
): Sketch
|
||||||
@ -27,11 +25,9 @@ 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` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | 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 |
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ 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) | 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 |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Tolerance for the revolve operation. | 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` | [`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 |
|
| `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 |
|
||||||
|
@ -28,7 +28,7 @@ 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) | 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 |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance for this fillet | No |
|
||||||
| `tag` | [`TagDecl`](/docs/kcl-std/types/std-types-TagDecl) | 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) | 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 |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the intersection operation. | 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) | 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 |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the subtraction operation. | 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) | 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 |
|
| `tolerance` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The tolerance to use for the union operation. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'subtract',
|
name: 'subtract',
|
||||||
code: 'subtract(extrude001, tools = extrude006)',
|
code: 'subtract([extrude001], tools = [extrude006])',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'intersect',
|
name: 'intersect',
|
||||||
@ -81,8 +81,6 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
if (operationName !== 'subtract') {
|
if (operationName !== 'subtract') {
|
||||||
// should down shift key to select multiple objects
|
// should down shift key to select multiple objects
|
||||||
await page.keyboard.down('Shift')
|
await page.keyboard.down('Shift')
|
||||||
} else {
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select second object
|
// Select second object
|
||||||
@ -105,8 +103,8 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Solids: '1 path',
|
Tool: '1 path',
|
||||||
Tools: '1 path',
|
Target: '1 path',
|
||||||
},
|
},
|
||||||
commandName,
|
commandName,
|
||||||
})
|
})
|
||||||
|
@ -5,7 +5,6 @@ import { uuidv4 } from '@src/lib/utils'
|
|||||||
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
||||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
|
||||||
import { getUtils } from '@e2e/playwright/test-utils'
|
import { getUtils } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
@ -15,18 +14,13 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
homePage: HomePageFixture,
|
homePage: HomePageFixture,
|
||||||
scene: SceneFixture,
|
scene: SceneFixture,
|
||||||
toolbar: ToolbarFixture,
|
toolbar: ToolbarFixture,
|
||||||
cmdBar: CmdBarFixture,
|
|
||||||
plane: string,
|
plane: string,
|
||||||
clickCoords: { x: number; y: number }
|
clickCoords: { x: number; y: number }
|
||||||
) => {
|
) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// await page.addInitScript(() => {
|
|
||||||
// localStorage.setItem('persistCode', '@settings(defaultLengthUnit = in)')
|
|
||||||
// })
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
// await scene.settled(cmdBar)
|
|
||||||
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
||||||
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
||||||
|
|
||||||
@ -125,166 +119,12 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
for (const config of planeConfigs) {
|
for (const config of planeConfigs) {
|
||||||
test(config.plane, async ({ page, homePage, scene, toolbar, cmdBar }) => {
|
test(config.plane, async ({ page, homePage, scene, toolbar }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(
|
await sketchOnPlaneAndBackSideTest(
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
|
||||||
config.plane,
|
|
||||||
config.coords
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
test.describe('Can create sketches on offset planes and their back sides', () => {
|
|
||||||
const sketchOnPlaneAndBackSideTest = async (
|
|
||||||
page: Page,
|
|
||||||
homePage: HomePageFixture,
|
|
||||||
scene: SceneFixture,
|
|
||||||
toolbar: ToolbarFixture,
|
|
||||||
cmdbar: CmdBarFixture,
|
|
||||||
plane: string,
|
|
||||||
clickCoords: { x: number; y: number }
|
|
||||||
) => {
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.addInitScript(() => {
|
|
||||||
localStorage.setItem(
|
|
||||||
'persistCode',
|
|
||||||
`@settings(defaultLengthUnit = in)
|
|
||||||
xyPlane = offsetPlane(XY, offset = 0.05)
|
|
||||||
xzPlane = offsetPlane(XZ, offset = 0.05)
|
|
||||||
yzPlane = offsetPlane(YZ, offset = 0.05)
|
|
||||||
`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
// await scene.settled(cmdbar)
|
|
||||||
const XYPlanRed: [number, number, number] = [74, 74, 74]
|
|
||||||
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
|
||||||
|
|
||||||
await u.openDebugPanel()
|
|
||||||
|
|
||||||
const coord =
|
|
||||||
plane === '-XY' || plane === '-YZ' || plane === 'XZ' ? -100 : 100
|
|
||||||
const camCommand: EngineCommand = {
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_look_at',
|
|
||||||
center: { x: 0, y: 0, z: 0 },
|
|
||||||
vantage: { x: coord, y: coord, z: coord },
|
|
||||||
up: { x: 0, y: 0, z: 1 },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const updateCamCommand: EngineCommand = {
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_get_settings',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const prefix = plane.length === 3 ? '-' : ''
|
|
||||||
const planeName = plane
|
|
||||||
.slice(plane.length === 3 ? 1 : 0)
|
|
||||||
.toLocaleLowerCase()
|
|
||||||
|
|
||||||
const codeLine1 = `sketch001 = startSketchOn(${prefix}${planeName}Plane)`
|
|
||||||
const codeLine2 = `profile001 = startProfile(sketch001, at = [${0.91 + (plane[0] === '-' ? 0.01 : 0)}, -${1.21 + (plane[0] === '-' ? 0.01 : 0)}])`
|
|
||||||
|
|
||||||
await u.openDebugPanel()
|
|
||||||
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
|
||||||
|
|
||||||
await u.sendCustomCmd(camCommand)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await u.sendCustomCmd(updateCamCommand)
|
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
await toolbar.openFeatureTreePane()
|
|
||||||
await toolbar.getDefaultPlaneVisibilityButton('XY').click()
|
|
||||||
await toolbar.getDefaultPlaneVisibilityButton('XZ').click()
|
|
||||||
await toolbar.getDefaultPlaneVisibilityButton('YZ').click()
|
|
||||||
await expect(
|
|
||||||
toolbar
|
|
||||||
.getDefaultPlaneVisibilityButton('YZ')
|
|
||||||
.locator('[aria-label="eye crossed out"]')
|
|
||||||
).toBeVisible()
|
|
||||||
|
|
||||||
await page.mouse.click(clickCoords.x, clickCoords.y)
|
|
||||||
await page.waitForTimeout(600) // wait for animation
|
|
||||||
|
|
||||||
await toolbar.waitUntilSketchingReady()
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'line Line', exact: true })
|
|
||||||
).toBeVisible()
|
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
await page.mouse.click(707, 393)
|
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toContainText(codeLine1)
|
|
||||||
await expect(page.locator('.cm-content')).toContainText(codeLine2)
|
|
||||||
|
|
||||||
await page
|
|
||||||
.getByRole('button', { name: 'line Line', exact: true })
|
|
||||||
.first()
|
|
||||||
.click()
|
|
||||||
await u.openAndClearDebugPanel()
|
|
||||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await u.removeCurrentCode()
|
|
||||||
}
|
|
||||||
|
|
||||||
const planeConfigs = [
|
|
||||||
{
|
|
||||||
plane: 'XY',
|
|
||||||
coords: { x: 600, y: 388 },
|
|
||||||
description: 'red plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: 'YZ',
|
|
||||||
coords: { x: 700, y: 250 },
|
|
||||||
description: 'green plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: 'XZ',
|
|
||||||
coords: { x: 684, y: 427 },
|
|
||||||
description: 'blue plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: '-XY',
|
|
||||||
coords: { x: 600, y: 118 },
|
|
||||||
description: 'back of red plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: '-YZ',
|
|
||||||
coords: { x: 700, y: 219 },
|
|
||||||
description: 'back of green plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: '-XZ',
|
|
||||||
coords: { x: 700, y: 80 },
|
|
||||||
description: 'back of blue plane',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
for (const config of planeConfigs) {
|
|
||||||
test(config.plane, async ({ page, homePage, scene, toolbar, cmdBar }) => {
|
|
||||||
await sketchOnPlaneAndBackSideTest(
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
config.plane,
|
config.plane,
|
||||||
config.coords
|
config.coords
|
||||||
)
|
)
|
||||||
|
@ -265,8 +265,6 @@ 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()`)
|
||||||
|
@ -307,7 +307,7 @@ test.describe('Command bar tests', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const continueButton = page.getByRole('button', { name: 'Continue' })
|
const continueButton = page.getByRole('button', { name: 'Continue' })
|
||||||
const submitButton = page.getByTestId('command-bar-submit')
|
const submitButton = page.getByRole('button', { name: 'Submit command' })
|
||||||
await continueButton.click()
|
await continueButton.click()
|
||||||
|
|
||||||
// Review step and argument hotkeys
|
// Review step and argument hotkeys
|
||||||
@ -525,9 +525,7 @@ test.describe('Command bar tests', () => {
|
|||||||
const projectName = 'test'
|
const projectName = 'test'
|
||||||
const beforeKclCode = `a = 5
|
const beforeKclCode = `a = 5
|
||||||
b = a * a
|
b = a * a
|
||||||
c = 3 + a
|
c = 3 + a`
|
||||||
theta = 45deg
|
|
||||||
`
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const testProject = join(dir, projectName)
|
const testProject = join(dir, projectName)
|
||||||
await fsp.mkdir(testProject, { recursive: true })
|
await fsp.mkdir(testProject, { recursive: true })
|
||||||
@ -617,45 +615,9 @@ theta = 45deg
|
|||||||
stage: 'commandBarClosed',
|
stage: 'commandBarClosed',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
await test.step(`Edit a parameter with explicit units via command bar`, async () => {
|
|
||||||
await cmdBar.cmdBarOpenBtn.click()
|
|
||||||
await cmdBar.chooseCommand('edit parameter')
|
|
||||||
await cmdBar
|
|
||||||
.selectOption({
|
|
||||||
name: 'theta',
|
|
||||||
})
|
|
||||||
.click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
commandName: 'Edit parameter',
|
|
||||||
currentArgKey: 'value',
|
|
||||||
currentArgValue: '45deg',
|
|
||||||
headerArguments: {
|
|
||||||
Name: 'theta',
|
|
||||||
Value: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'value',
|
|
||||||
})
|
|
||||||
await cmdBar.argumentInput
|
|
||||||
.locator('[contenteditable]')
|
|
||||||
.fill('45deg + 1deg')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
commandName: 'Edit parameter',
|
|
||||||
headerArguments: {
|
|
||||||
Name: 'theta',
|
|
||||||
Value: '46deg',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'commandBarClosed',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`a = 5b = a * amyParameter001 = ${newValue}c = 3 + atheta = 45deg + 1deg`
|
`a = 5b = a * amyParameter001 = ${newValue}c = 3 + a`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -54,7 +54,9 @@ test(
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
await cmdBar.submit()
|
const submitButton = page.getByText('Confirm Export')
|
||||||
|
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`)
|
||||||
@ -117,7 +119,9 @@ test(
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
await cmdBar.submit()
|
const submitButton = page.getByText('Confirm Export')
|
||||||
|
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...`)
|
||||||
|
@ -288,7 +288,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers should be lowerCamelCase').first()
|
page.getByText('Identifiers must be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
await page.locator('#code-pane button:first-child').click()
|
await page.locator('#code-pane button:first-child').click()
|
||||||
@ -314,7 +314,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers should be lowerCamelCase').first()
|
page.getByText('Identifiers must be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -511,7 +511,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers should be lowerCamelCase').first()
|
page.getByText('Identifiers must be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// focus the editor
|
// focus the editor
|
||||||
@ -539,7 +539,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers should be lowerCamelCase').first()
|
page.getByText('Identifiers must be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -681,7 +681,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers should be lowerCamelCase').first()
|
page.getByText('Identifiers must be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// select the line that's causing the error and delete it
|
// select the line that's causing the error and delete it
|
||||||
@ -912,7 +912,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
|> close()
|
|> close()
|
||||||
|> revolve(
|
|> revolve(
|
||||||
axis = revolveAxis,
|
axis = revolveAxis,
|
||||||
angle = 90
|
angle = 90deg
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -1617,33 +1617,4 @@ 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,12 +229,11 @@ 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 newParameterName = 'length001'
|
const newConstantName = 'length001'
|
||||||
const expectedCode = `${newParameterName} = 23
|
const expectedCode = `${newConstantName} = 23
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> circle(center = [0, 0], radius = 5)
|
|> circle(center = [0, 0], radius = 5)
|
||||||
renamedExtrude = extrude(sketch001, length = ${newParameterName})`
|
renamedExtrude = extrude(sketch001, length = ${newConstantName})`
|
||||||
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')
|
||||||
@ -280,7 +279,7 @@ test.describe('Feature Tree pane', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Add a parameter for distance argument and submit', async () => {
|
await test.step('Add a named constant for distance argument and submit', async () => {
|
||||||
await expect(cmdBar.currentArgumentInput).toBeVisible()
|
await expect(cmdBar.currentArgumentInput).toBeVisible()
|
||||||
await cmdBar.variableCheckbox.click()
|
await cmdBar.variableCheckbox.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -297,43 +296,13 @@ test.describe('Feature Tree pane', () => {
|
|||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
activeLines: [
|
activeLines: [
|
||||||
`renamedExtrude = extrude(sketch001, length = ${newParameterName})`,
|
`renamedExtrude = extrude(sketch001, length = ${newConstantName})`,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
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,11 +118,15 @@ export class CmdBarFixture {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrowButton = this.page.getByTestId('command-bar-continue')
|
const arrowButton = this.page.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
if (await arrowButton.isVisible()) {
|
if (await arrowButton.isVisible()) {
|
||||||
await this.continue()
|
await arrowButton.click()
|
||||||
} else {
|
} else {
|
||||||
await this.submit()
|
await this.page
|
||||||
|
.getByRole('button', { name: 'checkmark Submit command' })
|
||||||
|
.click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,13 +191,6 @@ 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
|
||||||
*/
|
*/
|
||||||
|
@ -183,15 +183,14 @@ 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
|
||||||
const index = editorView?.docView.view.state.doc
|
let index = window.editorManager._editorView?.docView.view.state.doc
|
||||||
.toString()
|
.toString()
|
||||||
.indexOf(args.text)
|
.indexOf(args.text)
|
||||||
editorView?.focus()
|
window.editorManager._editorView?.focus()
|
||||||
editorView?.dispatch({
|
window.editorManager._editorView?.dispatch({
|
||||||
selection: window.EditorSelection.create([
|
selection: window.EditorSelection.create([
|
||||||
window.EditorSelection.cursor(index),
|
window.EditorSelection.cursor(index),
|
||||||
]),
|
]),
|
||||||
|
@ -274,13 +274,6 @@ export class ToolbarFixture {
|
|||||||
.nth(operationIndex)
|
.nth(operationIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultPlaneVisibilityButton(plane: 'XY' | 'XZ' | 'YZ' = 'XY') {
|
|
||||||
const index = plane === 'XZ' ? 0 : plane === 'XY' ? 1 : 2
|
|
||||||
return this.featureTreePane
|
|
||||||
.getByTestId('feature-tree-visibility-toggle')
|
|
||||||
.nth(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View source on a specific operation in the Feature Tree pane.
|
* View source on a specific operation in the Feature Tree pane.
|
||||||
* @param operationName The name of the operation type
|
* @param operationName The name of the operation type
|
||||||
|
@ -5,7 +5,7 @@ import type {
|
|||||||
FullResult,
|
FullResult,
|
||||||
} from '@playwright/test/reporter'
|
} from '@playwright/test/reporter'
|
||||||
|
|
||||||
class APIReporter implements Reporter {
|
class MyAPIReporter 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 APIReporter 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: `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`,
|
project: 'https://github.com/KittyCAD/modeling-app',
|
||||||
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 APIReporter implements Reporter {
|
|||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
// Required information
|
// Required information
|
||||||
project: `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`,
|
project: 'https://github.com/KittyCAD/modeling-app',
|
||||||
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 APIReporter implements Reporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default APIReporter
|
export default MyAPIReporter
|
||||||
|
@ -475,7 +475,6 @@ test.describe('Can export from electron app', () => {
|
|||||||
},
|
},
|
||||||
tronApp.projectDirName,
|
tronApp.projectDirName,
|
||||||
page,
|
page,
|
||||||
cmdBar,
|
|
||||||
method
|
method
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -780,6 +779,9 @@ 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 () => {
|
||||||
@ -798,7 +800,8 @@ test.describe(`Project management commands`, () => {
|
|||||||
await expect(commandContinueButton).toBeVisible()
|
await expect(commandContinueButton).toBeVisible()
|
||||||
await commandContinueButton.click()
|
await commandContinueButton.click()
|
||||||
|
|
||||||
await cmdBar.submit()
|
await expect(commandSubmitButton).toBeVisible()
|
||||||
|
await commandSubmitButton.click()
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
@ -834,6 +837,9 @@ 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')
|
||||||
|
|
||||||
@ -853,7 +859,8 @@ test.describe(`Project management commands`, () => {
|
|||||||
await projectNameOption.click()
|
await projectNameOption.click()
|
||||||
|
|
||||||
await expect(commandWarning).toBeVisible()
|
await expect(commandWarning).toBeVisible()
|
||||||
await cmdBar.submit()
|
await expect(commandSubmitButton).toBeVisible()
|
||||||
|
await commandSubmitButton.click()
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
@ -887,6 +894,9 @@ 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 () => {
|
||||||
@ -904,7 +914,8 @@ test.describe(`Project management commands`, () => {
|
|||||||
await expect(commandContinueButton).toBeVisible()
|
await expect(commandContinueButton).toBeVisible()
|
||||||
await commandContinueButton.click()
|
await commandContinueButton.click()
|
||||||
|
|
||||||
await cmdBar.submit()
|
await expect(commandSubmitButton).toBeVisible()
|
||||||
|
await commandSubmitButton.click()
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
@ -938,6 +949,9 @@ 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')
|
||||||
|
|
||||||
@ -953,7 +967,8 @@ test.describe(`Project management commands`, () => {
|
|||||||
await projectNameOption.click()
|
await projectNameOption.click()
|
||||||
|
|
||||||
await expect(commandWarning).toBeVisible()
|
await expect(commandWarning).toBeVisible()
|
||||||
await cmdBar.submit()
|
await expect(commandSubmitButton).toBeVisible()
|
||||||
|
await commandSubmitButton.click()
|
||||||
|
|
||||||
await expect(toastMessage).toBeVisible()
|
await expect(toastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
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'
|
||||||
|
|
||||||
@ -422,7 +421,10 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
await cmdBar.submit()
|
const submitButton = page.getByText('Confirm Export')
|
||||||
|
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
|
||||||
@ -459,7 +461,8 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
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
|
||||||
@ -479,7 +482,6 @@ 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 () => {
|
||||||
@ -514,11 +516,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, cmdBar)
|
await clickExportButton(page)
|
||||||
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
await expect(exportingToastMessage).toBeVisible()
|
||||||
|
|
||||||
await clickExportButton(page, cmdBar)
|
await clickExportButton(page)
|
||||||
|
|
||||||
await test.step('The first export still succeeds', async () => {
|
await test.step('The first export still succeeds', async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -535,7 +537,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, cmdBar)
|
await clickExportButton(page)
|
||||||
|
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
@ -878,7 +880,7 @@ s2 = startSketchOn(XY)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
async function clickExportButton(page: Page, cmdBar: CmdBarFixture) {
|
async function clickExportButton(page: Page) {
|
||||||
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')
|
||||||
@ -894,6 +896,9 @@ async function clickExportButton(page: Page, cmdBar: CmdBarFixture) {
|
|||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
await cmdBar.submit()
|
const submitButton = page.getByText('Confirm Export')
|
||||||
|
await expect(submitButton).toBeVisible()
|
||||||
|
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1478,7 +1478,6 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.mouse.move(1200, 139)
|
await page.mouse.move(1200, 139)
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(870, 250)
|
await page.mouse.move(870, 250)
|
||||||
await page.mouse.up()
|
|
||||||
|
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
|
|
||||||
@ -1488,60 +1487,6 @@ sketch001 = startSketchOn(XZ)
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
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,
|
||||||
@ -2155,8 +2100,8 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
)
|
)
|
||||||
await crnRect1point2()
|
await crnRect1point2()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 2.37, tag = $rectangleSegmentA001)
|
`|> angledLine(angle = 0deg, length = 2.37, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 7.8)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 7.8)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()`.replaceAll('\n', '')
|
|> close()`.replaceAll('\n', '')
|
||||||
@ -2170,8 +2115,8 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
await crnRect2point2()
|
await crnRect2point2()
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 5.49, tag = $rectangleSegmentA002)
|
`|> angledLine(angle = 0deg, length = 5.49, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 4.14)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90deg, length = 4.14)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()`.replaceAll('\n', '')
|
|> close()`.replaceAll('\n', '')
|
||||||
@ -2189,8 +2134,8 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
await cntrRect1point2()
|
await cntrRect1point2()
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 7.06, tag = $rectangleSegmentA003)
|
`|> angledLine(angle = 0deg, length = 7.06, tag = $rectangleSegmentA003)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003) + 90, length = 4.34)
|
|> angledLine(angle = segAng(rectangleSegmentA003) + 90deg, length = 4.34)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()`.replaceAll('\n', '')
|
|> close()`.replaceAll('\n', '')
|
||||||
@ -2205,8 +2150,8 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
await cntrRect2point2()
|
await cntrRect2point2()
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 3.12, tag = $rectangleSegmentA004)
|
`|> angledLine(angle = 0deg, length = 3.12, tag = $rectangleSegmentA004)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004) + 90, length = 6.24)
|
|> angledLine(angle = segAng(rectangleSegmentA004) + 90deg, length = 6.24)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()`.replaceAll('\n', '')
|
|> close()`.replaceAll('\n', '')
|
||||||
@ -2355,8 +2300,8 @@ profile001 = startProfile(sketch001, at = [6.24, 4.54])
|
|||||||
|> line(end = [8.61, 0.74])
|
|> line(end = [8.61, 0.74])
|
||||||
|> line(end = [10.99, -5.22])
|
|> line(end = [10.99, -5.22])
|
||||||
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
||||||
|> angledLine(angle = 0, length = 10.78, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 10.78, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.14)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 4.14)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -2428,7 +2373,7 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
|
|||||||
await page.mouse.up()
|
await page.mouse.up()
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`angledLine(angle = -7, length = 10.27, tag = $rectangleSegmentA001)`
|
`angledLine(angle = -7deg, length = 10.27, tag = $rectangleSegmentA001)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -2470,8 +2415,8 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await rectEnd()
|
await rectEnd()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 180, length = 1.97, tag = $rectangleSegmentA002)
|
`|> angledLine(angle = 180deg, length = 1.97, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = 3.89)
|
|> angledLine(angle = segAng(rectangleSegmentA002) + 90deg, length = 3.89)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()`.replaceAll('\n', '')
|
|> close()`.replaceAll('\n', '')
|
||||||
@ -2496,8 +2441,8 @@ profile001 = startProfile(sketch001, at = [6.24, 4.54])
|
|||||||
|> line(end = [8.61, 0.74])
|
|> line(end = [8.61, 0.74])
|
||||||
|> line(end = [10.99, -5.22])
|
|> line(end = [10.99, -5.22])
|
||||||
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
||||||
|> angledLine(angle = 0, length = 10.78, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 10.78, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.14)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 4.14)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -2826,8 +2771,8 @@ profile002 = startProfile(sketch002, at = [0.75, 13.46])
|
|||||||
|> line(end = [4.52, 3.79])
|
|> line(end = [4.52, 3.79])
|
||||||
|> line(end = [5.98, -2.81])
|
|> line(end = [5.98, -2.81])
|
||||||
profile003 = startProfile(sketch002, at = [3.19, 13.3])
|
profile003 = startProfile(sketch002, at = [3.19, 13.3])
|
||||||
|> angledLine(angle = 0, length = 6.64, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 6.64, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.81)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 2.81)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -2844,7 +2789,7 @@ profile006 = startProfile(sketch002, at = [9.65, 3.82])
|
|||||||
|> close()
|
|> close()
|
||||||
revolve001 = revolve(
|
revolve001 = revolve(
|
||||||
profile004,
|
profile004,
|
||||||
angle = 45,
|
angle = 45deg,
|
||||||
axis = getNextAdjacentEdge(seg01)
|
axis = getNextAdjacentEdge(seg01)
|
||||||
)
|
)
|
||||||
extrude002 = extrude(profile006, length = 4)
|
extrude002 = extrude(profile006, length = 4)
|
||||||
@ -2868,8 +2813,8 @@ profile010 = circle(
|
|||||||
radius = 2.67
|
radius = 2.67
|
||||||
)
|
)
|
||||||
profile011 = startProfile(sketch003, at = [5.07, -6.39])
|
profile011 = startProfile(sketch003, at = [5.07, -6.39])
|
||||||
|> angledLine(angle = 0, length = 4.54, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = 4.54, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 4.17)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90deg, length = 4.17)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -3021,7 +2966,7 @@ loft([profile001, profile002])
|
|||||||
)
|
)
|
||||||
await rect1Crn2()
|
await rect1Crn2()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`angledLine(angle = 0, length = 113.01, tag = $rectangleSegmentA001)`
|
`angledLine(angle = 0deg, length = 113.01, tag = $rectangleSegmentA001)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
test('Can enter sketch loft edges offsetPlane and continue sketch', async ({
|
test('Can enter sketch loft edges offsetPlane and continue sketch', async ({
|
||||||
@ -3090,7 +3035,7 @@ loft([profile001, profile002])
|
|||||||
)
|
)
|
||||||
await rect1Crn2()
|
await rect1Crn2()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`angledLine(angle = 0, length = 106.42], tag = $rectangleSegmentA001)`
|
`angledLine(angle = 0deg, length = 106.42], tag = $rectangleSegmentA001)`
|
||||||
)
|
)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
})
|
})
|
||||||
@ -3312,8 +3257,8 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 156.54, angle = -28)
|
|> angledLine(length = 156.54, angle = -28deg)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151,
|
||||||
length = 116.27,
|
length = 116.27,
|
||||||
@ -3351,7 +3296,9 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(
|
||||||
async () => {
|
async () => {
|
||||||
await editor.expectEditor.toContain('length = 156.54, angle = -28')
|
await editor.expectEditor.toContain(
|
||||||
|
'length = 156.54, angle = -28deg'
|
||||||
|
)
|
||||||
await page.mouse.move(handle1Location.x, handle1Location.y)
|
await page.mouse.move(handle1Location.x, handle1Location.y)
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(
|
await page.mouse.move(
|
||||||
@ -3362,7 +3309,9 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
await page.mouse.up()
|
await page.mouse.up()
|
||||||
await editor.expectEditor.toContain('length = 231.59, angle = -34')
|
await editor.expectEditor.toContain(
|
||||||
|
'length = 231.59, angle = -34deg'
|
||||||
|
)
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
{ timeout: 10_000 }
|
{ timeout: 10_000 }
|
||||||
@ -3380,7 +3329,7 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
|
|
||||||
const handle2Location = { x: 872, y: 273 }
|
const handle2Location = { x: 872, y: 273 }
|
||||||
await test.step('Edit sketch again', async () => {
|
await test.step('Edit sketch again', async () => {
|
||||||
await editor.expectEditor.toContain('length = 231.59, angle = -34')
|
await editor.expectEditor.toContain('length = 231.59, angle = -34deg')
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(
|
||||||
@ -3391,7 +3340,9 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
steps: 5,
|
steps: 5,
|
||||||
})
|
})
|
||||||
await page.mouse.up()
|
await page.mouse.up()
|
||||||
await editor.expectEditor.toContain('length = 167.36, angle = -14')
|
await editor.expectEditor.toContain(
|
||||||
|
'length = 167.36, angle = -14deg'
|
||||||
|
)
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
{ timeout: 10_000 }
|
{ timeout: 10_000 }
|
||||||
@ -3416,14 +3367,18 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(
|
||||||
async () => {
|
async () => {
|
||||||
await editor.expectEditor.toContain('length = 167.36, angle = -14')
|
await editor.expectEditor.toContain(
|
||||||
|
'length = 167.36, angle = -14deg'
|
||||||
|
)
|
||||||
await page.mouse.move(handle3Location.x, handle3Location.y)
|
await page.mouse.move(handle3Location.x, handle3Location.y)
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(handle3Location.x, handle3Location.y + 110, {
|
await page.mouse.move(handle3Location.x, handle3Location.y + 110, {
|
||||||
steps: 5,
|
steps: 5,
|
||||||
})
|
})
|
||||||
await page.mouse.up()
|
await page.mouse.up()
|
||||||
await editor.expectEditor.toContain('length = 219.2, angle = -56')
|
await editor.expectEditor.toContain(
|
||||||
|
'length = 219.2, angle = -56deg'
|
||||||
|
)
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
{ timeout: 10_000 }
|
{ timeout: 10_000 }
|
||||||
@ -3448,9 +3403,9 @@ profile001 = startProfile(sketch001, at = [106.68, 89.77])
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 219.2, angle = -56)
|
|> angledLine(length = 219.2, angle = -56deg)
|
||||||
|> angledLine(angle = -151, length = 116.27)
|
|> angledLine(angle = -151deg, length = 116.27)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
profile003 = startProfile(sketch002, at = [-201.08, 254.17])
|
profile003 = startProfile(sketch002, at = [-201.08, 254.17])
|
||||||
@ -3487,10 +3442,10 @@ profile003 = startProfile(sketch002, at = [-201.08, 254.17])
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 156.54, angle = -28)
|
|> angledLine(length = 156.54, angle = -28deg)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151deg,
|
||||||
length = 116.27,
|
length = 116.27,
|
||||||
)
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -3551,10 +3506,10 @@ profile003 = startProfile(sketch002, at = [-201.08, 254.17])
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 156.54, angle = -28)
|
|> angledLine(length = 156.54, angle = -28deg)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151deg,
|
||||||
length = 116.27,
|
length = 116.27,
|
||||||
)
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
@ -845,14 +845,14 @@ test.describe('code color goober', { tag: '@snapshot' }, () => {
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90deg, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
sweepSketch = startSketchOn(XY)
|
sweepSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [2, 0])
|
|> startProfile(at = [2, 0])
|
||||||
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|
|> arc(angleStart = 0, angleEnd = 360deg, radius = 2)
|
||||||
|> sweep(path = sweepPath)
|
|> sweep(path = sweepPath)
|
||||||
|> appearance(
|
|> appearance(
|
||||||
color = "#bb00ff",
|
color = "#bb00ff",
|
||||||
@ -889,14 +889,14 @@ sweepSketch = startSketchOn(XY)
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90deg, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
sweepSketch = startSketchOn(XY)
|
sweepSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [2, 0])
|
|> startProfile(at = [2, 0])
|
||||||
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|
|> arc(angleStart = 0deg, angleEnd = 360deg, radius = 2)
|
||||||
|> sweep(path = sweepPath)
|
|> sweep(path = sweepPath)
|
||||||
|> appearance(
|
|> appearance(
|
||||||
color = '#bb00ff',
|
color = '#bb00ff',
|
||||||
@ -934,14 +934,14 @@ sweepSketch = startSketchOn(XY)
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90deg, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
sweepSketch = startSketchOn(XY)
|
sweepSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [2, 0])
|
|> startProfile(at = [2, 0])
|
||||||
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|
|> arc(angleStart = 0deg, angleEnd = 360deg, radius = 2)
|
||||||
|> sweep(path = sweepPath)
|
|> sweep(path = sweepPath)
|
||||||
|> appearance(
|
|> appearance(
|
||||||
color = "#bb00ff",
|
color = "#bb00ff",
|
||||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 64 KiB |
@ -12,7 +12,6 @@ export const TEST_SETTINGS: DeepPartial<Settings> = {
|
|||||||
},
|
},
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: 'dismissed',
|
||||||
show_debug_panel: true,
|
show_debug_panel: true,
|
||||||
fixed_size_grid: false,
|
|
||||||
},
|
},
|
||||||
modeling: {
|
modeling: {
|
||||||
enable_ssao: false,
|
enable_ssao: false,
|
||||||
|
@ -22,7 +22,6 @@ export const token = process.env.token || ''
|
|||||||
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
|
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
|
||||||
|
|
||||||
import type { ElectronZoo } from '@e2e/playwright/fixtures/fixtureSetup'
|
import type { ElectronZoo } from '@e2e/playwright/fixtures/fixtureSetup'
|
||||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
|
||||||
import { isErrorWhitelisted } from '@e2e/playwright/lib/console-error-whitelist'
|
import { isErrorWhitelisted } from '@e2e/playwright/lib/console-error-whitelist'
|
||||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
|
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
|
||||||
import { test } from '@e2e/playwright/zoo-test'
|
import { test } from '@e2e/playwright/zoo-test'
|
||||||
@ -159,10 +158,10 @@ async function openKclCodePanel(page: Page) {
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
// editorManager is available on the window object.
|
// editorManager is available on the window object.
|
||||||
//@ts-ignore this is in an entirely different context that tsc can't see.
|
//@ts-ignore this is in an entirely different context that tsc can't see.
|
||||||
editorManager.getEditorView().dispatch({
|
editorManager._editorView.dispatch({
|
||||||
selection: {
|
selection: {
|
||||||
//@ts-ignore this is in an entirely different context that tsc can't see.
|
//@ts-ignore this is in an entirely different context that tsc can't see.
|
||||||
anchor: editorManager.getEditorView().docView.length,
|
anchor: editorManager._editorView.docView.length,
|
||||||
},
|
},
|
||||||
scrollIntoView: true,
|
scrollIntoView: true,
|
||||||
})
|
})
|
||||||
@ -738,7 +737,6 @@ export const doExport = async (
|
|||||||
output: Models['OutputFormat3d_type'],
|
output: Models['OutputFormat3d_type'],
|
||||||
rootDir: string,
|
rootDir: string,
|
||||||
page: Page,
|
page: Page,
|
||||||
cmdBar: CmdBarFixture,
|
|
||||||
exportFrom: 'dropdown' | 'sidebarButton' | 'commandBar' = 'dropdown'
|
exportFrom: 'dropdown' | 'sidebarButton' | 'commandBar' = 'dropdown'
|
||||||
): Promise<Paths> => {
|
): Promise<Paths> => {
|
||||||
if (exportFrom === 'dropdown') {
|
if (exportFrom === 'dropdown') {
|
||||||
@ -782,7 +780,9 @@ export const doExport = async (
|
|||||||
.click()
|
.click()
|
||||||
await page.locator('#arg-form').waitFor({ state: 'detached' })
|
await page.locator('#arg-form').waitFor({ state: 'detached' })
|
||||||
}
|
}
|
||||||
await cmdBar.submit()
|
await expect(page.getByText('Confirm Export')).toBeVisible()
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Submit command' }).click()
|
||||||
|
|
||||||
await expect(page.getByText('Exported successfully')).toBeVisible()
|
await expect(page.getByText('Exported successfully')).toBeVisible()
|
||||||
|
|
||||||
@ -880,10 +880,6 @@ export async function setup(
|
|||||||
},
|
},
|
||||||
...TEST_SETTINGS.project,
|
...TEST_SETTINGS.project,
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: 'dismissed',
|
||||||
// Tests were written before this setting existed.
|
|
||||||
// It's true by default because it's a good user experience, but
|
|
||||||
// these tests require it to be false.
|
|
||||||
fixed_size_grid: false,
|
|
||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
...TEST_SETTINGS.project,
|
...TEST_SETTINGS.project,
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Testing constraints', () => {
|
test.describe('Testing constraints', () => {
|
||||||
test('Can constrain line length', async ({ page, homePage, cmdBar }) => {
|
test('Can constrain line length', async ({ page, homePage }) => {
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
@ -50,10 +50,14 @@ test.describe('Testing constraints', () => {
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.getByTestId('constraint-length').click()
|
await page.getByTestId('constraint-length').click()
|
||||||
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('20')
|
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('20')
|
||||||
await cmdBar.continue()
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
.click()
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`length001 = 20sketch001 = startSketchOn(XY) |> startProfile(at = [-10, -10]) |> line(end = [20, 0]) |> angledLine(angle = 90, length = length001) |> xLine(length = -20)`
|
`length001 = 20sketch001 = startSketchOn(XY) |> startProfile(at = [-10, -10]) |> line(end = [20, 0]) |> angledLine(angle = 90deg, length = length001) |> xLine(length = -20)`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Make sure we didn't pop out of sketch mode.
|
// Make sure we didn't pop out of sketch mode.
|
||||||
@ -204,7 +208,9 @@ test.describe('Testing constraints', () => {
|
|||||||
.click()
|
.click()
|
||||||
|
|
||||||
// Wait for the codemod to take effect
|
// Wait for the codemod to take effect
|
||||||
await expect(page.locator('.cm-content')).toContainText(`angle = -57,`)
|
await expect(page.locator('.cm-content')).toContainText(
|
||||||
|
`angle = -57deg,`
|
||||||
|
)
|
||||||
await expect(page.locator('.cm-content')).toContainText(
|
await expect(page.locator('.cm-content')).toContainText(
|
||||||
`offset = ${offset},`
|
`offset = ${offset},`
|
||||||
)
|
)
|
||||||
@ -215,7 +221,7 @@ test.describe('Testing constraints', () => {
|
|||||||
`|> line(end = [74.36, 130.4], tag = $seg01)`
|
`|> line(end = [74.36, 130.4], tag = $seg01)`
|
||||||
)
|
)
|
||||||
await expect(activeLinesContent[1]).toHaveText(
|
await expect(activeLinesContent[1]).toHaveText(
|
||||||
` |> angledLineThatIntersects(angle = -57, offset = ${offset}, intersectTag = seg01)`
|
` |> angledLineThatIntersects(angle = -57deg, offset = ${offset}, intersectTag = seg01)`
|
||||||
)
|
)
|
||||||
|
|
||||||
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
|
||||||
@ -466,7 +472,7 @@ test.describe('Testing constraints', () => {
|
|||||||
testName: 'No variable',
|
testName: 'No variable',
|
||||||
addVariable: false,
|
addVariable: false,
|
||||||
axisSelect: false,
|
axisSelect: false,
|
||||||
value: 'segAng(seg01) + 22.69',
|
value: 'segAng(seg01) + 22.69deg',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: 'Add variable, selecting axis',
|
testName: 'Add variable, selecting axis',
|
||||||
@ -478,7 +484,7 @@ test.describe('Testing constraints', () => {
|
|||||||
testName: 'No variable, selecting axis',
|
testName: 'No variable, selecting axis',
|
||||||
addVariable: false,
|
addVariable: false,
|
||||||
axisSelect: true,
|
axisSelect: true,
|
||||||
value: 'turns::QUARTER_TURN - 7',
|
value: 'turns::QUARTER_TURN - 7deg',
|
||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
for (const { testName, addVariable, value, axisSelect } of cases) {
|
for (const { testName, addVariable, value, axisSelect } of cases) {
|
||||||
@ -581,7 +587,7 @@ test.describe('Testing constraints', () => {
|
|||||||
testName: 'Angle - No variable',
|
testName: 'Angle - No variable',
|
||||||
addVariable: false,
|
addVariable: false,
|
||||||
constraint: 'angle',
|
constraint: 'angle',
|
||||||
value: '83, 78.33',
|
value: '83deg, 78.33',
|
||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
for (const { testName, addVariable, value, constraint } of cases) {
|
for (const { testName, addVariable, value, constraint } of cases) {
|
||||||
@ -653,13 +659,13 @@ test.describe('Testing constraints', () => {
|
|||||||
testName: 'Length - Add variable',
|
testName: 'Length - Add variable',
|
||||||
addVariable: true,
|
addVariable: true,
|
||||||
constraint: 'length',
|
constraint: 'length',
|
||||||
value: '83, length001',
|
value: '83deg, length001',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: 'Length - No variable',
|
testName: 'Length - No variable',
|
||||||
addVariable: false,
|
addVariable: false,
|
||||||
constraint: 'length',
|
constraint: 'length',
|
||||||
value: '83, 78.33',
|
value: '83deg, 78.33',
|
||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
for (const { testName, addVariable, value, constraint } of cases) {
|
for (const { testName, addVariable, value, constraint } of cases) {
|
||||||
@ -677,6 +683,9 @@ test.describe('Testing constraints', () => {
|
|||||||
.getByRole('textbox')
|
.getByRole('textbox')
|
||||||
const cmdBarKclVariableNameInput =
|
const cmdBarKclVariableNameInput =
|
||||||
page.getByPlaceholder('Variable name')
|
page.getByPlaceholder('Variable name')
|
||||||
|
const cmdBarSubmitButton = page.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@ -729,7 +738,7 @@ part002 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
const [ang, len] = value.split(', ')
|
const [ang, len] = value.split(', ')
|
||||||
const changedCode = `|> angledLine(angle = ${ang}, length = ${len})`
|
const changedCode = `|> angledLine(angle = ${ang}, length = ${len})`
|
||||||
await cmdBar.continue()
|
await cmdBarSubmitButton.click()
|
||||||
await expect(page.locator('.cm-content')).toContainText(changedCode)
|
await expect(page.locator('.cm-content')).toContainText(changedCode)
|
||||||
|
|
||||||
// checking active assures the cursor is where it should be
|
// checking active assures the cursor is where it should be
|
||||||
@ -845,7 +854,7 @@ part002 = startSketchOn(XZ)
|
|||||||
test.describe('Two segment - no modal constraints', () => {
|
test.describe('Two segment - no modal constraints', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
{
|
{
|
||||||
codeAfter: `|> angledLine(angle = 83, length = segLen(seg01))`,
|
codeAfter: `|> angledLine(angle = 83deg, length = segLen(seg01))`,
|
||||||
constraintName: 'Equal Length',
|
constraintName: 'Equal Length',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1094,7 +1103,11 @@ part002 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10')
|
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10')
|
||||||
await cmdBar.continue()
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
.click()
|
||||||
|
|
||||||
await pollEditorLinesSelectedLength(page, 1)
|
await pollEditorLinesSelectedLength(page, 1)
|
||||||
activeLinesContent = await page.locator('.cm-activeLine').all()
|
activeLinesContent = await page.locator('.cm-activeLine').all()
|
||||||
@ -1163,7 +1176,7 @@ test.describe('Electron constraint tests', () => {
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await editor.expectEditor.toContain('length001 = 15.3')
|
await editor.expectEditor.toContain('length001 = 15.3')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
'|> angledLine(angle = 9, length = length001)'
|
'|> angledLine(angle = 9deg, length = length001)'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ test.describe('Testing loading external models', () => {
|
|||||||
// We have no more web tests
|
// We have no more web tests
|
||||||
test.fail(
|
test.fail(
|
||||||
'Web: should overwrite current code, cannot create new file',
|
'Web: should overwrite current code, cannot create new file',
|
||||||
async ({ editor, context, page, homePage, cmdBar }) => {
|
async ({ editor, context, page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await test.step(`Test setup`, async () => {
|
await test.step(`Test setup`, async () => {
|
||||||
await context.addInitScript((code) => {
|
await context.addInitScript((code) => {
|
||||||
@ -52,6 +52,9 @@ test.describe('Testing loading external models', () => {
|
|||||||
name,
|
name,
|
||||||
})
|
})
|
||||||
const warningText = page.getByText('Overwrite current file with sample?')
|
const warningText = page.getByText('Overwrite current file with sample?')
|
||||||
|
const confirmButton = page.getByRole('button', {
|
||||||
|
name: 'Submit command',
|
||||||
|
})
|
||||||
|
|
||||||
await test.step(`Precondition: check the initial code`, async () => {
|
await test.step(`Precondition: check the initial code`, async () => {
|
||||||
await u.openKclCodePanel()
|
await u.openKclCodePanel()
|
||||||
@ -67,7 +70,7 @@ test.describe('Testing loading external models', () => {
|
|||||||
await expect(commandMethodOption('Create new file')).not.toBeVisible()
|
await expect(commandMethodOption('Create new file')).not.toBeVisible()
|
||||||
await commandMethodOption('Overwrite').click()
|
await commandMethodOption('Overwrite').click()
|
||||||
await expect(warningText).toBeVisible()
|
await expect(warningText).toBeVisible()
|
||||||
await cmdBar.submit()
|
await confirmButton.click()
|
||||||
|
|
||||||
await editor.expectEditor.toContain('// ' + newSample.title)
|
await editor.expectEditor.toContain('// ' + newSample.title)
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,6 @@ import type { LineInputsType } from '@src/lang/std/sketchcombos'
|
|||||||
import { uuidv4 } from '@src/lib/utils'
|
import { uuidv4 } from '@src/lib/utils'
|
||||||
|
|
||||||
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
||||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
|
||||||
import { deg, getUtils, wiggleMove } from '@e2e/playwright/test-utils'
|
import { deg, getUtils, wiggleMove } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
* @param {number} options.steps - The number of steps to perform
|
* @param {number} options.steps - The number of steps to perform
|
||||||
*/
|
*/
|
||||||
const _clickConstrained =
|
const _clickConstrained =
|
||||||
(page: Page, editor: EditorFixture, cmdBar: CmdBarFixture) =>
|
(page: Page, editor: EditorFixture) =>
|
||||||
async ({
|
async ({
|
||||||
hoverPos,
|
hoverPos,
|
||||||
constraintType,
|
constraintType,
|
||||||
@ -94,7 +93,11 @@ test.describe('Testing segment overlays', () => {
|
|||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.continue()
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
.click()
|
||||||
await editor.expectEditor.toContain(expectFinal, {
|
await editor.expectEditor.toContain(expectFinal, {
|
||||||
shouldNormalise: true,
|
shouldNormalise: true,
|
||||||
})
|
})
|
||||||
@ -110,7 +113,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
* @param {number} options.steps - The number of steps to perform
|
* @param {number} options.steps - The number of steps to perform
|
||||||
*/
|
*/
|
||||||
const _clickUnconstrained =
|
const _clickUnconstrained =
|
||||||
(page: Page, editor: EditorFixture, cmdBar: CmdBarFixture) =>
|
(page: Page, editor: EditorFixture) =>
|
||||||
async ({
|
async ({
|
||||||
hoverPos,
|
hoverPos,
|
||||||
constraintType,
|
constraintType,
|
||||||
@ -160,7 +163,11 @@ test.describe('Testing segment overlays', () => {
|
|||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.continue()
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
.click()
|
||||||
await editor.expectEditor.toContain(expectAfterUnconstrained, {
|
await editor.expectEditor.toContain(expectAfterUnconstrained, {
|
||||||
shouldNormalise: true,
|
shouldNormalise: true,
|
||||||
})
|
})
|
||||||
@ -232,8 +239,8 @@ test.describe('Testing segment overlays', () => {
|
|||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
|
||||||
|
|
||||||
const clickUnconstrained = _clickUnconstrained(page, editor, cmdBar)
|
const clickUnconstrained = _clickUnconstrained(page, editor)
|
||||||
const clickConstrained = _clickConstrained(page, editor, cmdBar)
|
const clickConstrained = _clickConstrained(page, editor)
|
||||||
|
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await u.sendCustomCmd({
|
await u.sendCustomCmd({
|
||||||
@ -657,7 +664,7 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify the X constraint was added
|
// Verify the X constraint was added
|
||||||
await editor.expectEditor.toContain('center = [xAbs001, 0]', {
|
await editor.expectEditor.toContain('center = [xAbs001, 0]', {
|
||||||
@ -675,7 +682,7 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify the Y constraint was added
|
// Verify the Y constraint was added
|
||||||
await editor.expectEditor.toContain('center = [xAbs001, yAbs001]', {
|
await editor.expectEditor.toContain('center = [xAbs001, yAbs001]', {
|
||||||
@ -693,7 +700,7 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify all constraints were added
|
// Verify all constraints were added
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
@ -880,7 +887,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify the constraint was added
|
// Verify the constraint was added
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
@ -903,7 +910,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify both constraints were added
|
// Verify both constraints were added
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
@ -928,7 +935,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify the constraint was added
|
// Verify the constraint was added
|
||||||
await editor.expectEditor.toContain('endAbsolute = [xAbs002, 84.07]', {
|
await editor.expectEditor.toContain('endAbsolute = [xAbs002, 84.07]', {
|
||||||
@ -948,7 +955,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||||
).toBeFocused()
|
).toBeFocused()
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
|
|
||||||
// Verify all constraints were added
|
// Verify all constraints were added
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
|
@ -32,7 +32,7 @@ test('Units menu', async ({ page, homePage }) => {
|
|||||||
test(
|
test(
|
||||||
'Successful export shows a success toast',
|
'Successful export shows a success toast',
|
||||||
{ tag: '@skipLocalEngine' },
|
{ tag: '@skipLocalEngine' },
|
||||||
async ({ page, homePage, cmdBar, tronApp }) => {
|
async ({ page, homePage, tronApp }) => {
|
||||||
// FYI this test doesn't work with only engine running locally
|
// FYI this test doesn't work with only engine running locally
|
||||||
// And you will need to have the KittyCAD CLI installed
|
// And you will need to have the KittyCAD CLI installed
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
@ -94,8 +94,7 @@ part001 = startSketchOn(-XZ)
|
|||||||
presentation: 'pretty',
|
presentation: 'pretty',
|
||||||
},
|
},
|
||||||
tronApp?.projectDirName,
|
tronApp?.projectDirName,
|
||||||
page,
|
page
|
||||||
cmdBar
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -255,7 +254,6 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
|||||||
test('Basic default modeling and sketch hotkeys work', async ({
|
test('Basic default modeling and sketch hotkeys work', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
cmdBar,
|
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await test.step(`Set up test`, async () => {
|
await test.step(`Set up test`, async () => {
|
||||||
@ -399,8 +397,11 @@ test('Basic default modeling and sketch hotkeys work', async ({
|
|||||||
await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({
|
await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({
|
||||||
timeout: 20_000,
|
timeout: 20_000,
|
||||||
})
|
})
|
||||||
await cmdBar.continue()
|
await page.getByRole('button', { name: 'Continue' }).click()
|
||||||
await cmdBar.submit()
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Submit command' })
|
||||||
|
).toBeVisible()
|
||||||
|
await page.getByRole('button', { name: 'Submit command' }).click()
|
||||||
await expect(page.locator('.cm-content')).toContainText('extrude(')
|
await expect(page.locator('.cm-content')).toContainText('extrude(')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -574,7 +575,8 @@ profile001 = startProfile(sketch002, at = [-12.34, 12.34])
|
|||||||
|
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.submit()
|
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const result2 = result.genNext`
|
const result2 = result.genNext`
|
||||||
const sketch002 = extrude(sketch002, length = ${[5, 5]} + 7)`
|
const sketch002 = extrude(sketch002, length = ${[5, 5]} + 7)`
|
||||||
|
18
flake.lock
generated
@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1750865895,
|
"lastModified": 1745998881,
|
||||||
"narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=",
|
"narHash": "sha256-vonyYAKJSlsX4n9GCsS0pHxR6yCrfqBIuGvANlkwG6U=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "61c0f513911459945e2cb8bf333dc849f1b976ff",
|
"rev": "423d2df5b04b4ee7688c3d71396e872afa236a89",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -36,11 +36,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1750865895,
|
"lastModified": 1745998881,
|
||||||
"narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=",
|
"narHash": "sha256-vonyYAKJSlsX4n9GCsS0pHxR6yCrfqBIuGvANlkwG6U=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "61c0f513911459945e2cb8bf333dc849f1b976ff",
|
"rev": "423d2df5b04b4ee7688c3d71396e872afa236a89",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -78,11 +78,11 @@
|
|||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1750964660,
|
"lastModified": 1745980514,
|
||||||
"narHash": "sha256-YQ6EyFetjH1uy5JhdhRdPe6cuNXlYpMAQePFfZj4W7M=",
|
"narHash": "sha256-CITAeiuXGjDvT5iZBXr6vKVWQwsUQLJUMFO91bfJFC4=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "04f0fcfb1a50c63529805a798b4b5c21610ff390",
|
"rev": "7fbdae44b0f40ea432e46fd152ad8be0f8f41ad6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -125,57 +125,18 @@ test('Shows a loading spinner when uninitialized credit count', async () => {
|
|||||||
await expect(queryByTestId('spinner')).toBeVisible()
|
await expect(queryByTestId('spinner')).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
const unKnownTierData = {
|
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 25,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
name: "unknown",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const freeTierData = {
|
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 0,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
name: "free",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const proTierData = {
|
|
||||||
// These are all ignored
|
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 0,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
// This should be ignored because it's Pro tier.
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
name: "pro",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const enterpriseTierData = {
|
|
||||||
// These are all ignored, user is part of an org.
|
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 0,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
// This should be ignored because it's Pro tier.
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
// This should be ignored because the user is part of an Org.
|
|
||||||
name: "free",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test('Shows the total credits for Unknown subscription', async () => {
|
test('Shows the total credits for Unknown subscription', async () => {
|
||||||
const data = unKnownTierData
|
const data = {
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 25,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
name: "unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
@ -205,7 +166,17 @@ test('Shows the total credits for Unknown subscription', async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('Progress bar reflects ratio left of Free subscription', async () => {
|
test('Progress bar reflects ratio left of Free subscription', async () => {
|
||||||
const data = freeTierData
|
const data = {
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 0,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
name: "free",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
@ -241,7 +212,19 @@ test('Progress bar reflects ratio left of Free subscription', async () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('Shows infinite credits for Pro subscription', async () => {
|
test('Shows infinite credits for Pro subscription', async () => {
|
||||||
const data = proTierData
|
const data = {
|
||||||
|
// These are all ignored
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 0,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
// This should be ignored because it's Pro tier.
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
name: "pro",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
@ -272,7 +255,19 @@ test('Shows infinite credits for Pro subscription', async () => {
|
|||||||
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
||||||
})
|
})
|
||||||
test('Shows infinite credits for Enterprise subscription', async () => {
|
test('Shows infinite credits for Enterprise subscription', async () => {
|
||||||
const data = enterpriseTierData
|
const data = {
|
||||||
|
// These are all ignored, user is part of an org.
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 0,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
// This should be ignored because it's Pro tier.
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
// This should be ignored because the user is part of an Org.
|
||||||
|
name: "free",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
@ -302,58 +297,3 @@ test('Shows infinite credits for Enterprise subscription', async () => {
|
|||||||
await expect(queryByTestId('infinity')).toBeVisible()
|
await expect(queryByTestId('infinity')).toBeVisible()
|
||||||
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Show upgrade button if credits are not infinite', async () => {
|
|
||||||
const data = freeTierData
|
|
||||||
server.use(
|
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
|
||||||
}),
|
|
||||||
http.get('*/user/payment/subscriptions', (req, res, ctx) => {
|
|
||||||
return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
|
|
||||||
}),
|
|
||||||
http.get('*/org', (req, res, ctx) => {
|
|
||||||
return new HttpResponse(403)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
|
|
||||||
|
|
||||||
const { queryByTestId } = render(<BillingDialog
|
|
||||||
billingActor={billingActor}
|
|
||||||
/>)
|
|
||||||
|
|
||||||
await act(() => {
|
|
||||||
billingActor.send({ type: BillingTransition.Update, apiToken: "it doesn't matter wtf this is :)" })
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(queryByTestId('billing-upgrade-button')).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Hide upgrade button if credits are infinite', async () => {
|
|
||||||
const data = enterpriseTierData
|
|
||||||
server.use(
|
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
|
||||||
}),
|
|
||||||
http.get('*/user/payment/subscriptions', (req, res, ctx) => {
|
|
||||||
return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
|
|
||||||
}),
|
|
||||||
// Ok finally the first use of an org lol
|
|
||||||
http.get('*/org', (req, res, ctx) => {
|
|
||||||
return HttpResponse.json(createOrgResponse())
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
|
|
||||||
|
|
||||||
const { queryByTestId } = render(<BillingDialog
|
|
||||||
billingActor={billingActor}
|
|
||||||
/>)
|
|
||||||
|
|
||||||
await act(() => {
|
|
||||||
billingActor.send({ type: BillingTransition.Update, apiToken: "it doesn't matter wtf this is :)" })
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(queryByTestId('billing-upgrade-button')).toBe(null)
|
|
||||||
})
|
|
||||||
|
1119
package-lock.json
generated
@ -111,8 +111,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* }
|
|||||||
|
|
||||||
PipeSubstitution { "%" }
|
PipeSubstitution { "%" }
|
||||||
|
|
||||||
// Includes non-whitespace unicode characters.
|
identifier { (@asciiLetter | "_") (@asciiLetter | @digit | "_")* }
|
||||||
identifier { $[a-zA-Z_\u{a1}-\u{167f}\u{1681}-\u{1fff}\u{200e}-\u{2027}\u{202a}-\u{202e}\u{2030}-\u{205e}\u{2061}-\u{2fff}\u{3001}-\u{fefe}\u{ff00}-\u{10ffff}] $[a-zA-Z0-9_\u{a1}-\u{167f}\u{1681}-\u{1fff}\u{200e}-\u{2027}\u{202a}-\u{202e}\u{2030}-\u{205e}\u{2061}-\u{2fff}\u{3001}-\u{fefe}\u{ff00}-\u{10ffff}]* }
|
|
||||||
AnnotationName { "@" identifier? }
|
AnnotationName { "@" identifier? }
|
||||||
PropertyName { identifier }
|
PropertyName { identifier }
|
||||||
TagDeclarator { "$" identifier }
|
TagDeclarator { "$" identifier }
|
||||||
|
@ -27,7 +27,7 @@ insideWall = extrude(insideWallSketch, length = overallThickness)
|
|||||||
// Create the sketch of one of the balls
|
// Create the sketch of one of the balls
|
||||||
ballsSketch = startSketchOn(XY)
|
ballsSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [shaftDia / 2 + wallThickness, 0.001])
|
|> startProfile(at = [shaftDia / 2 + wallThickness, 0.001])
|
||||||
|> arc(angleStart = 180, angleEnd = 0, radius = sphereDia / 2)
|
|> arc(angleStart = 180deg, angleEnd = 0, radius = sphereDia / 2)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
// Revolve the ball to make a sphere and pattern around the inside wall
|
// Revolve the ball to make a sphere and pattern around the inside wall
|
||||||
@ -44,9 +44,9 @@ balls = revolve(ballsSketch, axis = X)
|
|||||||
chainSketch = startSketchOn(XY)
|
chainSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [
|
|> startProfile(at = [
|
||||||
shaftDia / 2 + wallThickness + sphereDia / 2 - (chainWidth / 2),
|
shaftDia / 2 + wallThickness + sphereDia / 2 - (chainWidth / 2),
|
||||||
0.125 * sin(60)
|
0.125 * sin(60deg)
|
||||||
])
|
])
|
||||||
|> arc(angleStart = 120, angleEnd = 60, radius = sphereDia / 2)
|
|> arc(angleStart = 120deg, angleEnd = 60deg, radius = sphereDia / 2)
|
||||||
|> line(end = [0, chainThickness])
|
|> line(end = [0, chainThickness])
|
||||||
|> line(end = [-chainWidth, 0])
|
|> line(end = [-chainWidth, 0])
|
||||||
|> close()
|
|> close()
|
||||||
@ -54,7 +54,7 @@ chainSketch = startSketchOn(XY)
|
|||||||
// Revolve the chain sketch
|
// Revolve the chain sketch
|
||||||
chainHead = revolve(chainSketch, axis = X)
|
chainHead = revolve(chainSketch, axis = X)
|
||||||
|> patternCircular3d(
|
|> patternCircular3d(
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
instances = nBalls,
|
instances = nBalls,
|
||||||
@ -72,9 +72,9 @@ linkSketch = startSketchOn(XZ)
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Revolve the link sketch
|
// Revolve the link sketch
|
||||||
linkRevolve = revolve(linkSketch, axis = Y, angle = 360 / nBalls)
|
linkRevolve = revolve(linkSketch, axis = Y, angle = 360deg / nBalls)
|
||||||
|> patternCircular3d(
|
|> patternCircular3d(
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
instances = nBalls,
|
instances = nBalls,
|
||||||
|
@ -23,12 +23,12 @@ nVentBosses = 36
|
|||||||
|
|
||||||
// Drilling parameters.
|
// Drilling parameters.
|
||||||
dDrillDia = 6
|
dDrillDia = 6
|
||||||
aBase = 90
|
aBase = 90deg
|
||||||
aSweep = 30
|
aSweep = 30deg
|
||||||
nArcs = 12
|
nArcs = 12
|
||||||
|
|
||||||
// Bell parameters.
|
// Bell parameters.
|
||||||
aDraftBell = 5
|
aDraftBell = 5deg
|
||||||
tBell = 5 // Wall thickness.
|
tBell = 5 // Wall thickness.
|
||||||
hBellAboveDiscFace = 40
|
hBellAboveDiscFace = 40
|
||||||
hBellSubflush = 4
|
hBellSubflush = 4
|
||||||
@ -98,7 +98,7 @@ planeVent = offsetPlane(XY, offset = tDiscHalf)
|
|||||||
sketchVent = startSketchOn(planeVent)
|
sketchVent = startSketchOn(planeVent)
|
||||||
profileVent = startProfile(sketchVent, at = [-wVent, dDisc / 2])
|
profileVent = startProfile(sketchVent, at = [-wVent, dDisc / 2])
|
||||||
|> angledLine(angle = 0, length = wVent, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = wVent, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = hFrictionSurface, tag = $seg02)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = hFrictionSurface, tag = $seg02)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg03)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg03)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
||||||
|> close()
|
|> close()
|
||||||
@ -118,7 +118,7 @@ ventSet = patternCircular3d(
|
|||||||
instances = nVentBosses,
|
instances = nVentBosses,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, tDiscHalf],
|
center = [0, 0, tDiscHalf],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -134,8 +134,8 @@ discOutboard = createDiscHalf(
|
|||||||
// Now create bell.
|
// Now create bell.
|
||||||
rCenter = dDisc / 2 - hFrictionSurface - wUndercut
|
rCenter = dDisc / 2 - hFrictionSurface - wUndercut
|
||||||
rBore = dBore / 2
|
rBore = dBore / 2
|
||||||
lDraftExterior = hBellAboveDiscFace / tan(90 - aDraftBell)
|
lDraftExterior = hBellAboveDiscFace / tan(90deg - aDraftBell)
|
||||||
lDraftInterior = (hBellAboveDiscFace - tBell) / tan(90 - aDraftBell)
|
lDraftInterior = (hBellAboveDiscFace - tBell) / tan(90deg - aDraftBell)
|
||||||
|
|
||||||
// Inner and outer radius of outboard face of disc bell.
|
// Inner and outer radius of outboard face of disc bell.
|
||||||
rOuter = rCenter - lDraftExterior - rBore
|
rOuter = rCenter - lDraftExterior - rBore
|
||||||
@ -151,7 +151,7 @@ bodyDiscBell = startProfile(
|
|||||||
)
|
)
|
||||||
|> arc(
|
|> arc(
|
||||||
%,
|
%,
|
||||||
angleStart = -180,
|
angleStart = -180deg,
|
||||||
angleEnd = 0,
|
angleEnd = 0,
|
||||||
radius = wUndercut / 2,
|
radius = wUndercut / 2,
|
||||||
)
|
)
|
||||||
@ -172,7 +172,7 @@ profileStud = circle(sketchLugs, center = [0, dPitchCircle / 2], radius = dStudD
|
|||||||
%,
|
%,
|
||||||
instances = nStuds,
|
instances = nStuds,
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ hour = 9
|
|||||||
minute = 29
|
minute = 29
|
||||||
|
|
||||||
// Calculate hand angles
|
// Calculate hand angles
|
||||||
hourHandAngle = 90 - (hour * 30)
|
hourHandAngle = 90deg - (hour * 30deg)
|
||||||
minuteHandAngle = 90 - (minute * 6)
|
minuteHandAngle = 90deg - (minute * 6deg)
|
||||||
|
|
||||||
// Create the clock body
|
// Create the clock body
|
||||||
clockBodySketch = startSketchOn(XY)
|
clockBodySketch = startSketchOn(XY)
|
||||||
@ -72,18 +72,18 @@ numberObject = {
|
|||||||
// one = { i = [90, 160] },
|
// one = { i = [90, 160] },
|
||||||
one = {
|
one = {
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(60),
|
clockDiameter / 2 * 3 / 4 * cos(60deg),
|
||||||
clockDiameter / 2 * 3 / 4 * sin(60)
|
clockDiameter / 2 * 3 / 4 * sin(60deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
two = {
|
two = {
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(30) - 10,
|
clockDiameter / 2 * 3 / 4 * cos(30deg) - 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(30)
|
clockDiameter / 2 * 3 / 4 * sin(30deg)
|
||||||
],
|
],
|
||||||
i2 = [
|
i2 = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(30) + 5,
|
clockDiameter / 2 * 3 / 4 * cos(30deg) + 5,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(30)
|
clockDiameter / 2 * 3 / 4 * sin(30deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
three = {
|
three = {
|
||||||
@ -102,100 +102,100 @@ numberObject = {
|
|||||||
},
|
},
|
||||||
four = {
|
four = {
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-30) - 10,
|
clockDiameter / 2 * 3 / 4 * cos(-30deg) - 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-30)
|
clockDiameter / 2 * 3 / 4 * sin(-30deg)
|
||||||
],
|
],
|
||||||
v = [
|
v = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-30) + 13,
|
clockDiameter / 2 * 3 / 4 * cos(-30deg) + 13,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-30)
|
clockDiameter / 2 * 3 / 4 * sin(-30deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
five = {
|
five = {
|
||||||
v = [
|
v = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-60),
|
clockDiameter / 2 * 3 / 4 * cos(-60deg),
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-60)
|
clockDiameter / 2 * 3 / 4 * sin(-60deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
six = {
|
six = {
|
||||||
v = [
|
v = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-90) - 10,
|
clockDiameter / 2 * 3 / 4 * cos(-90deg) - 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-90)
|
clockDiameter / 2 * 3 / 4 * sin(-90deg)
|
||||||
],
|
],
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-90) + 12,
|
clockDiameter / 2 * 3 / 4 * cos(-90deg) + 12,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-90)
|
clockDiameter / 2 * 3 / 4 * sin(-90deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
seven = {
|
seven = {
|
||||||
v = [
|
v = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-120) - 15,
|
clockDiameter / 2 * 3 / 4 * cos(-120deg) - 15,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-120)
|
clockDiameter / 2 * 3 / 4 * sin(-120deg)
|
||||||
],
|
],
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-120) + 5,
|
clockDiameter / 2 * 3 / 4 * cos(-120deg) + 5,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-120)
|
clockDiameter / 2 * 3 / 4 * sin(-120deg)
|
||||||
],
|
],
|
||||||
i2 = [
|
i2 = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-120) + 20,
|
clockDiameter / 2 * 3 / 4 * cos(-120deg) + 20,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-120)
|
clockDiameter / 2 * 3 / 4 * sin(-120deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
eight = {
|
eight = {
|
||||||
v = [
|
v = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-150) - 10,
|
clockDiameter / 2 * 3 / 4 * cos(-150deg) - 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-150)
|
clockDiameter / 2 * 3 / 4 * sin(-150deg)
|
||||||
],
|
],
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-150) + 10,
|
clockDiameter / 2 * 3 / 4 * cos(-150deg) + 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-150)
|
clockDiameter / 2 * 3 / 4 * sin(-150deg)
|
||||||
],
|
],
|
||||||
i2 = [
|
i2 = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-150) + 25,
|
clockDiameter / 2 * 3 / 4 * cos(-150deg) + 25,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-150)
|
clockDiameter / 2 * 3 / 4 * sin(-150deg)
|
||||||
],
|
],
|
||||||
i3 = [
|
i3 = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(-150) + 40,
|
clockDiameter / 2 * 3 / 4 * cos(-150deg) + 40,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(-150)
|
clockDiameter / 2 * 3 / 4 * sin(-150deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
nine = {
|
nine = {
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(180) - 15,
|
clockDiameter / 2 * 3 / 4 * cos(180deg) - 15,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(180)
|
clockDiameter / 2 * 3 / 4 * sin(180deg)
|
||||||
],
|
],
|
||||||
x = [
|
x = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(180) + 15,
|
clockDiameter / 2 * 3 / 4 * cos(180deg) + 15,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(180)
|
clockDiameter / 2 * 3 / 4 * sin(180deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
ten = {
|
ten = {
|
||||||
x = [
|
x = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(150) + 5,
|
clockDiameter / 2 * 3 / 4 * cos(150deg) + 5,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(150)
|
clockDiameter / 2 * 3 / 4 * sin(150deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
eleven = {
|
eleven = {
|
||||||
x = [
|
x = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(120),
|
clockDiameter / 2 * 3 / 4 * cos(120deg),
|
||||||
clockDiameter / 2 * 3 / 4 * sin(120)
|
clockDiameter / 2 * 3 / 4 * sin(120deg)
|
||||||
],
|
],
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(120) + 10,
|
clockDiameter / 2 * 3 / 4 * cos(120deg) + 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(120)
|
clockDiameter / 2 * 3 / 4 * sin(120deg)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
twelve = {
|
twelve = {
|
||||||
x = [
|
x = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(90) - 10,
|
clockDiameter / 2 * 3 / 4 * cos(90deg) - 10,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(90)
|
clockDiameter / 2 * 3 / 4 * sin(90deg)
|
||||||
],
|
],
|
||||||
i = [
|
i = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(90) + 5,
|
clockDiameter / 2 * 3 / 4 * cos(90deg) + 5,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(90)
|
clockDiameter / 2 * 3 / 4 * sin(90deg)
|
||||||
],
|
],
|
||||||
i2 = [
|
i2 = [
|
||||||
clockDiameter / 2 * 3 / 4 * cos(90) + 20,
|
clockDiameter / 2 * 3 / 4 * cos(90deg) + 20,
|
||||||
clockDiameter / 2 * 3 / 4 * sin(90)
|
clockDiameter / 2 * 3 / 4 * sin(90deg)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,16 +234,16 @@ fn letterX(startX, startY) {
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> xLine(%, length = xWidth / 6)
|
|> xLine(%, length = xWidth / 6)
|
||||||
|> angledLine(%, angle = -70, lengthY = xLength * 1 / 3)
|
|> angledLine(%, angle = -70deg, lengthY = xLength * 1 / 3)
|
||||||
|> angledLine(%, angle = 70, lengthY = xLength * 1 / 3)
|
|> angledLine(%, angle = 70deg, lengthY = xLength * 1 / 3)
|
||||||
|> xLine(%, length = xWidth / 6)
|
|> xLine(%, length = xWidth / 6)
|
||||||
|> angledLine(%, angle = 70 + 180, lengthY = xLength * 1 / 2)
|
|> angledLine(%, angle = 70deg + 180deg, lengthY = xLength * 1 / 2)
|
||||||
|> angledLine(%, angle = -70, lengthY = xLength * 1 / 2)
|
|> angledLine(%, angle = -70deg, lengthY = xLength * 1 / 2)
|
||||||
|> xLine(%, length = -xWidth / 6)
|
|> xLine(%, length = -xWidth / 6)
|
||||||
|> angledLine(%, angle = -70 - 180, lengthY = xLength * 1 / 3)
|
|> angledLine(%, angle = -70deg - 180deg, lengthY = xLength * 1 / 3)
|
||||||
|> angledLine(%, angle = 70 + 180, lengthY = xLength * 1 / 3)
|
|> angledLine(%, angle = 70deg + 180deg, lengthY = xLength * 1 / 3)
|
||||||
|> xLine(%, length = -xWidth / 6)
|
|> xLine(%, length = -xWidth / 6)
|
||||||
|> angledLine(%, angle = 70, lengthY = xLength * 1 / 2)
|
|> angledLine(%, angle = 70deg, lengthY = xLength * 1 / 2)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(%, length = numberThickness)
|
|> extrude(%, length = numberThickness)
|
||||||
|> appearance(%, color = "#140f0f")
|
|> appearance(%, color = "#140f0f")
|
||||||
@ -333,25 +333,25 @@ sketch005 = startSketchOn(offsetPlane(XY, offset = 55))
|
|||||||
profile007 = startProfile(
|
profile007 = startProfile(
|
||||||
sketch005,
|
sketch005,
|
||||||
at = [
|
at = [
|
||||||
nubDiameter / 2 * 1.375 * cos(hourHandAngle + 20),
|
nubDiameter / 2 * 1.375 * cos(hourHandAngle + 20deg),
|
||||||
nubDiameter / 2 * 1.375 * sin(hourHandAngle + 20)
|
nubDiameter / 2 * 1.375 * sin(hourHandAngle + 20deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> arc(
|
|> arc(
|
||||||
%,
|
%,
|
||||||
interiorAbsolute = [
|
interiorAbsolute = [
|
||||||
nubDiameter / 2 * 1.375 * cos(hourHandAngle + 180),
|
nubDiameter / 2 * 1.375 * cos(hourHandAngle + 180deg),
|
||||||
nubDiameter / 2 * 1.375 * sin(hourHandAngle + 180)
|
nubDiameter / 2 * 1.375 * sin(hourHandAngle + 180deg)
|
||||||
],
|
],
|
||||||
endAbsolute = [
|
endAbsolute = [
|
||||||
nubDiameter / 2 * 1.375 * cos(hourHandAngle + 340),
|
nubDiameter / 2 * 1.375 * cos(hourHandAngle + 340deg),
|
||||||
nubDiameter / 2 * 1.375 * sin(hourHandAngle + 340)
|
nubDiameter / 2 * 1.375 * sin(hourHandAngle + 340deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> angledLine(%, angle = hourHandAngle, length = hourHandArmLength)
|
|> angledLine(%, angle = hourHandAngle, length = hourHandArmLength)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
%,
|
%,
|
||||||
angle = hourHandAngle - 90,
|
angle = hourHandAngle - 90deg,
|
||||||
length = hourHandWidth / 2,
|
length = hourHandWidth / 2,
|
||||||
tag = $seg004,
|
tag = $seg004,
|
||||||
)
|
)
|
||||||
@ -363,9 +363,9 @@ profile007 = startProfile(
|
|||||||
],
|
],
|
||||||
tag = $seg002,
|
tag = $seg002,
|
||||||
)
|
)
|
||||||
|> angledLine(%, angle = segAng(seg002) + 120, length = segLen(seg002))
|
|> angledLine(%, angle = segAng(seg002) + 120deg, length = segLen(seg002))
|
||||||
// |> angledLineThatIntersects(%, angle = segAng(seg002) + hourHandAngle - 90, intersectTag = seg004)
|
// |> angledLineThatIntersects(%, angle = segAng(seg002) + hourHandAngle - 90deg, intersectTag = seg004)
|
||||||
|> angledLine(%, angle = hourHandAngle - 90, length = segLen(seg004))
|
|> angledLine(%, angle = hourHandAngle - 90deg, length = segLen(seg004))
|
||||||
|> line(%, endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(%, endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close(%)
|
|> close(%)
|
||||||
profile008 = circle(sketch005, center = [0, 0], diameter = nubDiameter)
|
profile008 = circle(sketch005, center = [0, 0], diameter = nubDiameter)
|
||||||
@ -378,25 +378,25 @@ sketch006 = startSketchOn(offsetPlane(XY, offset = 50))
|
|||||||
profile009 = startProfile(
|
profile009 = startProfile(
|
||||||
sketch006,
|
sketch006,
|
||||||
at = [
|
at = [
|
||||||
nubDiameter / 2 * 1.375 * cos(minuteHandAngle + 20),
|
nubDiameter / 2 * 1.375 * cos(minuteHandAngle + 20deg),
|
||||||
nubDiameter / 2 * 1.375 * sin(minuteHandAngle + 20)
|
nubDiameter / 2 * 1.375 * sin(minuteHandAngle + 20deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> arc(
|
|> arc(
|
||||||
%,
|
%,
|
||||||
interiorAbsolute = [
|
interiorAbsolute = [
|
||||||
nubDiameter / 2 * 1.375 * cos(minuteHandAngle + 180),
|
nubDiameter / 2 * 1.375 * cos(minuteHandAngle + 180deg),
|
||||||
nubDiameter / 2 * 1.375 * sin(minuteHandAngle + 180)
|
nubDiameter / 2 * 1.375 * sin(minuteHandAngle + 180deg)
|
||||||
],
|
],
|
||||||
endAbsolute = [
|
endAbsolute = [
|
||||||
nubDiameter / 2 * 1.375 * cos(minuteHandAngle + 340),
|
nubDiameter / 2 * 1.375 * cos(minuteHandAngle + 340deg),
|
||||||
nubDiameter / 2 * 1.375 * sin(minuteHandAngle + 340)
|
nubDiameter / 2 * 1.375 * sin(minuteHandAngle + 340deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> angledLine(%, angle = minuteHandAngle, length = minuteHandArmLength)
|
|> angledLine(%, angle = minuteHandAngle, length = minuteHandArmLength)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
%,
|
%,
|
||||||
angle = minuteHandAngle - 90,
|
angle = minuteHandAngle - 90deg,
|
||||||
length = minuteHandWidth / 2,
|
length = minuteHandWidth / 2,
|
||||||
tag = $seg003,
|
tag = $seg003,
|
||||||
)
|
)
|
||||||
@ -408,8 +408,8 @@ profile009 = startProfile(
|
|||||||
],
|
],
|
||||||
tag = $seg005,
|
tag = $seg005,
|
||||||
)
|
)
|
||||||
|> angledLine(%, angle = segAng(seg005) + 120, length = segLen(seg005))
|
|> angledLine(%, angle = segAng(seg005) + 120deg, length = segLen(seg005))
|
||||||
|> angledLine(%, angle = minuteHandAngle - 90, length = segLen(seg003))
|
|> angledLine(%, angle = minuteHandAngle - 90deg, length = segLen(seg003))
|
||||||
|> line(%, endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(%, endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close(%)
|
|> close(%)
|
||||||
profile010 = circle(sketch006, center = [0, 0], diameter = 30)
|
profile010 = circle(sketch006, center = [0, 0], diameter = 30)
|
||||||
@ -430,8 +430,8 @@ profile004 = startProfile(sketch003, at = [-slotWidth / 2, 200])
|
|||||||
|> arc(
|
|> arc(
|
||||||
%,
|
%,
|
||||||
radius = screwHeadDiameter / 2 + screwTolerance,
|
radius = screwHeadDiameter / 2 + screwTolerance,
|
||||||
angleStart = 120,
|
angleStart = 120deg,
|
||||||
angleEnd = 420,
|
angleEnd = 420deg,
|
||||||
)
|
)
|
||||||
|> yLine(%, length = slotLength)
|
|> yLine(%, length = slotLength)
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
@ -14,15 +14,15 @@ coldPlate = startSketchOn(YZ)
|
|||||||
|> startProfile(at = [0, tubeDiameter * 2])
|
|> startProfile(at = [0, tubeDiameter * 2])
|
||||||
|> xLine(length = bendRadius - (tubeDiameter / 2))
|
|> xLine(length = bendRadius - (tubeDiameter / 2))
|
||||||
|> yLine(length = -tubeDiameter)
|
|> yLine(length = -tubeDiameter)
|
||||||
|> tangentialArc(angle = 180, radius = tubeDiameter / 2)
|
|> tangentialArc(angle = 180deg, radius = tubeDiameter / 2)
|
||||||
|> yLine(length = tubeDiameter)
|
|> yLine(length = tubeDiameter)
|
||||||
|> xLine(length = bendRadius * 2 - tubeDiameter, tag = $seg07)
|
|> xLine(length = bendRadius * 2 - tubeDiameter, tag = $seg07)
|
||||||
|> yLine(length = -tubeDiameter, tag = $seg09)
|
|> yLine(length = -tubeDiameter, tag = $seg09)
|
||||||
|> tangentialArc(angle = 180, radius = tubeDiameter / 2)
|
|> tangentialArc(angle = 180deg, radius = tubeDiameter / 2)
|
||||||
|> yLine(length = tubeDiameter, tag = $seg08)
|
|> yLine(length = tubeDiameter, tag = $seg08)
|
||||||
|> xLine(length = bendRadius - (tubeDiameter / 2))
|
|> xLine(length = bendRadius - (tubeDiameter / 2))
|
||||||
|> angledLine(angle = -77, length = tubeDiameter / 3)
|
|> angledLine(angle = -77deg, length = tubeDiameter / 3)
|
||||||
|> tangentialArc(angle = 77, radius = tubeDiameter, tag = $seg01)
|
|> tangentialArc(angle = 77deg, radius = tubeDiameter, tag = $seg01)
|
||||||
|> angledLine(angle = tangentToEnd(seg01), length = 1)
|
|> angledLine(angle = tangentToEnd(seg01), length = 1)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> xLine(endAbsolute = 0)
|
|> xLine(endAbsolute = 0)
|
||||||
@ -34,11 +34,11 @@ coldPlate = startSketchOn(YZ)
|
|||||||
copperTubePath = startSketchOn(offsetPlane(XY, offset = tubeDiameter))
|
copperTubePath = startSketchOn(offsetPlane(XY, offset = tubeDiameter))
|
||||||
|> startProfile(at = [-7.35, -bendRadius * 3])
|
|> startProfile(at = [-7.35, -bendRadius * 3])
|
||||||
|> xLine(length = 14.13, tag = $seg05)
|
|> xLine(length = 14.13, tag = $seg05)
|
||||||
|> tangentialArc(angle = 180, radius = bendRadius, tag = $seg02)
|
|> tangentialArc(angle = 180deg, radius = bendRadius, tag = $seg02)
|
||||||
|> angledLine(angle = tangentToEnd(seg02), length = 13.02, tag = $seg06)
|
|> angledLine(angle = tangentToEnd(seg02), length = 13.02, tag = $seg06)
|
||||||
|> tangentialArc(angle = -180, radius = bendRadius, tag = $seg03)
|
|> tangentialArc(angle = -180deg, radius = bendRadius, tag = $seg03)
|
||||||
|> angledLine(angle = tangentToEnd(seg03), length = segLen(seg06))
|
|> angledLine(angle = tangentToEnd(seg03), length = segLen(seg06))
|
||||||
|> tangentialArc(angle = 180, radius = bendRadius, tag = $seg04)
|
|> tangentialArc(angle = 180deg, radius = bendRadius, tag = $seg04)
|
||||||
|> angledLine(angle = tangentToEnd(seg04), length = segLen(seg05))
|
|> angledLine(angle = tangentToEnd(seg04), length = segLen(seg05))
|
||||||
|
|
||||||
// Create the profile for the inner and outer diameter of the hollow copper tube
|
// Create the profile for the inner and outer diameter of the hollow copper tube
|
||||||
|
@ -22,13 +22,13 @@ tangentLength = (r1 - r2) / tan(tangentAngle)
|
|||||||
|
|
||||||
plateBody = startSketchOn(XY)
|
plateBody = startSketchOn(XY)
|
||||||
// Use polar coordinates to start the sketch at the tangent point of the larger radius
|
// Use polar coordinates to start the sketch at the tangent point of the larger radius
|
||||||
|> startProfile(at = polar(angle = 90 - tangentAngle, length = r1))
|
|> startProfile(at = polar(angle = 90deg - tangentAngle, length = r1))
|
||||||
|> angledLine(angle = -tangentAngle, length = tangentLength)
|
|> angledLine(angle = -tangentAngle, length = tangentLength)
|
||||||
|> tangentialArc(radius = r2, angle = (tangentAngle - 90) * 2)
|
|> tangentialArc(radius = r2, angle = (tangentAngle - 90deg) * 2)
|
||||||
|> angledLine(angle = tangentAngle, length = -tangentLength)
|
|> angledLine(angle = tangentAngle, length = -tangentLength)
|
||||||
|> tangentialArc(radius = r1, angle = -tangentAngle * 2)
|
|> tangentialArc(radius = r1, angle = -tangentAngle * 2)
|
||||||
|> angledLine(angle = -tangentAngle, length = -tangentLength)
|
|> angledLine(angle = -tangentAngle, length = -tangentLength)
|
||||||
|> tangentialArc(radius = r2, angle = (tangentAngle - 90) * 2)
|
|> tangentialArc(radius = r2, angle = (tangentAngle - 90deg) * 2)
|
||||||
|> angledLine(angle = tangentAngle, length = tangentLength)
|
|> angledLine(angle = tangentAngle, length = tangentLength)
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -12,7 +12,7 @@ import * from "parameters.kcl"
|
|||||||
bottomFaceSketch = startSketchOn(YZ)
|
bottomFaceSketch = startSketchOn(YZ)
|
||||||
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|
||||||
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = fanSize, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = fanSize, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
||||||
|> close()
|
|> close()
|
||||||
@ -50,12 +50,12 @@ bottomFaceSketch = startSketchOn(YZ)
|
|||||||
// Add large openings to the bottom face to allow airflow through the fan
|
// Add large openings to the bottom face to allow airflow through the fan
|
||||||
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|
||||||
|> startProfile(at = [fanSize * 7 / 25, -fanSize * 9 / 25])
|
|> startProfile(at = [fanSize * 7 / 25, -fanSize * 9 / 25])
|
||||||
|> angledLine(angle = 140, length = fanSize * 12 / 25, tag = $seg01)
|
|> angledLine(angle = 140deg, length = fanSize * 12 / 25, tag = $seg01)
|
||||||
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|
||||||
|> angledLine(angle = -130, length = fanSize * 8 / 25)
|
|> angledLine(angle = -130deg, length = fanSize * 8 / 25)
|
||||||
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90)
|
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|
||||||
|> angledLine(angle = segAng(seg01) + 180, length = fanSize * 2 / 25)
|
|> angledLine(angle = segAng(seg01) + 180deg, length = fanSize * 2 / 25)
|
||||||
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40)
|
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40deg)
|
||||||
|> xLine(length = fanSize * 3 / 25)
|
|> xLine(length = fanSize * 3 / 25)
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -75,13 +75,13 @@ bodyMiddle = startSketchOn(bottomFaceSketch, face = END)
|
|||||||
housingMiddleLength / 2,
|
housingMiddleLength / 2,
|
||||||
-housingMiddleLength / 2 - housingMiddleRadius
|
-housingMiddleLength / 2 - housingMiddleRadius
|
||||||
])
|
])
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|> yLine(length = housingMiddleLength)
|
|> yLine(length = housingMiddleLength)
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|> xLine(length = -housingMiddleLength)
|
|> xLine(length = -housingMiddleLength)
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|> yLine(length = -housingMiddleLength)
|
|> yLine(length = -housingMiddleLength)
|
||||||
|> tangentialArc(radius = housingMiddleRadius, angle = 90)
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> extrude(length = fanHeight - 4 - 4)
|
|> extrude(length = fanHeight - 4 - 4)
|
||||||
|
|
||||||
|
@ -20,32 +20,32 @@ fn fanBlade(offsetHeight, startAngle) {
|
|||||||
15 * cos(startAngle),
|
15 * cos(startAngle),
|
||||||
15 * sin(startAngle)
|
15 * sin(startAngle)
|
||||||
])
|
])
|
||||||
|> arc(angleStart = startAngle, angleEnd = startAngle + 14, radius = 15)
|
|> arc(angleStart = startAngle, angleEnd = startAngle + 14deg, radius = 15)
|
||||||
|> arc(
|
|> arc(
|
||||||
endAbsolute = [
|
endAbsolute = [
|
||||||
fanSize * 22 / 50 * cos(startAngle - 20),
|
fanSize * 22 / 50 * cos(startAngle - 20deg),
|
||||||
fanSize * 22 / 50 * sin(startAngle - 20)
|
fanSize * 22 / 50 * sin(startAngle - 20deg)
|
||||||
],
|
],
|
||||||
interiorAbsolute = [
|
interiorAbsolute = [
|
||||||
fanSize * 11 / 50 * cos(startAngle + 3),
|
fanSize * 11 / 50 * cos(startAngle + 3deg),
|
||||||
fanSize * 11 / 50 * sin(startAngle + 3)
|
fanSize * 11 / 50 * sin(startAngle + 3deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> arc(
|
|> arc(
|
||||||
endAbsolute = [
|
endAbsolute = [
|
||||||
fanSize * 22 / 50 * cos(startAngle - 24),
|
fanSize * 22 / 50 * cos(startAngle - 24deg),
|
||||||
fanSize * 22 / 50 * sin(startAngle - 24)
|
fanSize * 22 / 50 * sin(startAngle - 24deg)
|
||||||
],
|
],
|
||||||
interiorAbsolute = [
|
interiorAbsolute = [
|
||||||
fanSize * 22 / 50 * cos(startAngle - 22),
|
fanSize * 22 / 50 * cos(startAngle - 22deg),
|
||||||
fanSize * 22 / 50 * sin(startAngle - 22)
|
fanSize * 22 / 50 * sin(startAngle - 22deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> arc(
|
|> arc(
|
||||||
endAbsolute = [profileStartX(%), profileStartY(%)],
|
endAbsolute = [profileStartX(%), profileStartY(%)],
|
||||||
interiorAbsolute = [
|
interiorAbsolute = [
|
||||||
fanSize * 11 / 50 * cos(startAngle - 5),
|
fanSize * 11 / 50 * cos(startAngle - 5deg),
|
||||||
fanSize * 11 / 50 * sin(startAngle - 5)
|
fanSize * 11 / 50 * sin(startAngle - 5deg)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|> close()
|
|> close()
|
||||||
@ -54,8 +54,8 @@ fn fanBlade(offsetHeight, startAngle) {
|
|||||||
|
|
||||||
// Loft the fan blade cross sections into a single blade, then pattern them about the fan center
|
// Loft the fan blade cross sections into a single blade, then pattern them about the fan center
|
||||||
crossSections = [
|
crossSections = [
|
||||||
fanBlade(offsetHeight = 4.5, startAngle = 50),
|
fanBlade(offsetHeight = 4.5, startAngle = 50deg),
|
||||||
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30),
|
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30deg),
|
||||||
fanBlade(offsetHeight = fanHeight - 2, startAngle = 0)
|
fanBlade(offsetHeight = fanHeight - 2, startAngle = 0)
|
||||||
]
|
]
|
||||||
bladeLoft = loft(crossSections)
|
bladeLoft = loft(crossSections)
|
||||||
@ -63,7 +63,7 @@ bladeLoft = loft(crossSections)
|
|||||||
instances = 9,
|
instances = 9,
|
||||||
axis = [1, 0, 0],
|
axis = [1, 0, 0],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,10 +11,10 @@ import * from "parameters.kcl"
|
|||||||
endTubePath = startSketchOn(offsetPlane(YZ, offset = -20))
|
endTubePath = startSketchOn(offsetPlane(YZ, offset = -20))
|
||||||
|> startProfile(at = [fanSize / 4, fanSize + 38])
|
|> startProfile(at = [fanSize / 4, fanSize + 38])
|
||||||
|> yLine(endAbsolute = bendRadius + 10, tag = $seg01)
|
|> yLine(endAbsolute = bendRadius + 10, tag = $seg01)
|
||||||
|> tangentialArc(radius = bendRadius, angle = -90)
|
|> tangentialArc(radius = bendRadius, angle = -90deg)
|
||||||
|> xLine(endAbsolute = 0, tag = $seg02)
|
|> xLine(endAbsolute = 0, tag = $seg02)
|
||||||
|> xLine(length = -segLen(seg02))
|
|> xLine(length = -segLen(seg02))
|
||||||
|> tangentialArc(radius = bendRadius, angle = -90)
|
|> tangentialArc(radius = bendRadius, angle = -90deg)
|
||||||
|> yLine(length = segLen(seg01))
|
|> yLine(length = segLen(seg01))
|
||||||
|
|
||||||
// Sweep and translate the outermost tube on each end
|
// Sweep and translate the outermost tube on each end
|
||||||
@ -35,13 +35,13 @@ endTube = startSketchOn(offsetPlane(XY, offset = fanSize + 38))
|
|||||||
centerTubePath = startSketchOn(offsetPlane(YZ, offset = -4))
|
centerTubePath = startSketchOn(offsetPlane(YZ, offset = -4))
|
||||||
|> startProfile(at = [fanSize / 2.67, fanSize + 38])
|
|> startProfile(at = [fanSize / 2.67, fanSize + 38])
|
||||||
|> yLine(endAbsolute = bendRadius + 15 + 10)
|
|> yLine(endAbsolute = bendRadius + 15 + 10)
|
||||||
|> tangentialArc(radius = bendRadius, angle = -45)
|
|> tangentialArc(radius = bendRadius, angle = -45deg)
|
||||||
|> angledLine(angle = -135, lengthY = 15)
|
|> angledLine(angle = -135deg, lengthY = 15)
|
||||||
|> tangentialArc(radius = bendRadius, angle = -45)
|
|> tangentialArc(radius = bendRadius, angle = -45deg)
|
||||||
|> xLine(endAbsolute = 0, tag = $seg03)
|
|> xLine(endAbsolute = 0, tag = $seg03)
|
||||||
|> xLine(length = -segLen(seg03))
|
|> xLine(length = -segLen(seg03))
|
||||||
|> tangentialArc(radius = bendRadius, angle = -155)
|
|> tangentialArc(radius = bendRadius, angle = -155deg)
|
||||||
|> tangentialArc(radius = bendRadius, angle = 65)
|
|> tangentialArc(radius = bendRadius, angle = 65deg)
|
||||||
|> yLine(endAbsolute = fanSize + 38)
|
|> yLine(endAbsolute = fanSize + 38)
|
||||||
|
|
||||||
// Draw the profile and sweep the 4 interior tubes
|
// Draw the profile and sweep the 4 interior tubes
|
||||||
@ -68,13 +68,13 @@ centerTube = startSketchOn(offsetPlane(XY, offset = fanSize + 38))
|
|||||||
heatFins = startSketchOn(offsetPlane(XY, offset = 45))
|
heatFins = startSketchOn(offsetPlane(XY, offset = 45))
|
||||||
|> startProfile(at = [0, -fanSize / 2])
|
|> startProfile(at = [0, -fanSize / 2])
|
||||||
|> xLine(length = 9)
|
|> xLine(length = 9)
|
||||||
|> angledLine(angle = -60, length = 2.5, tag = $seg04)
|
|> angledLine(angle = -60deg, length = 2.5, tag = $seg04)
|
||||||
|> xLine(length = 0.75)
|
|> xLine(length = 0.75)
|
||||||
|> arc(interiorAbsolute = [lastSegX(%) + 1, lastSegY(%) + 1.2], endAbsolute = [lastSegX(%) + 2, lastSegY(%)])
|
|> arc(interiorAbsolute = [lastSegX(%) + 1, lastSegY(%) + 1.2], endAbsolute = [lastSegX(%) + 2, lastSegY(%)])
|
||||||
|> xLine(length = 0.75)
|
|> xLine(length = 0.75)
|
||||||
|> angledLine(angle = 60, length = segLen(seg04))
|
|> angledLine(angle = 60deg, length = segLen(seg04))
|
||||||
|> xLine(endAbsolute = heatSinkDepth / 2 - 3)
|
|> xLine(endAbsolute = heatSinkDepth / 2 - 3)
|
||||||
|> tangentialArc(angle = 90, radius = 3)
|
|> tangentialArc(angle = 90deg, radius = 3)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> mirror2d(axis = X)
|
|> mirror2d(axis = X)
|
||||||
|> mirror2d(axis = Y)
|
|> mirror2d(axis = Y)
|
||||||
@ -91,11 +91,11 @@ heatFins = startSketchOn(offsetPlane(XY, offset = 45))
|
|||||||
coolerBase = startSketchOn(-XZ)
|
coolerBase = startSketchOn(-XZ)
|
||||||
baseLower = startProfile(coolerBase, at = [0, 10])
|
baseLower = startProfile(coolerBase, at = [0, 10])
|
||||||
|> xLine(length = -0.9)
|
|> xLine(length = -0.9)
|
||||||
|> arc(angleStart = 0, angleEnd = -180, radius = 3.1)
|
|> arc(angleStart = 0, angleEnd = -180deg, radius = 3.1)
|
||||||
|> xLine(length = -1.8)
|
|> xLine(length = -1.8)
|
||||||
|> arc(angleStart = 0, angleEnd = -180, radius = 3)
|
|> arc(angleStart = 0, angleEnd = -180deg, radius = 3)
|
||||||
|> xLine(length = -1.8)
|
|> xLine(length = -1.8)
|
||||||
|> arc(angleStart = 0, angleEnd = -180, radius = 3)
|
|> arc(angleStart = 0, angleEnd = -180deg, radius = 3)
|
||||||
|> xLine(length = -1.8)
|
|> xLine(length = -1.8)
|
||||||
|> xLine(length = -2)
|
|> xLine(length = -2)
|
||||||
|> yLine(length = -10)
|
|> yLine(length = -10)
|
||||||
@ -105,15 +105,15 @@ baseLower = startProfile(coolerBase, at = [0, 10])
|
|||||||
|
|
||||||
baseUpper = startProfile(coolerBase, at = [0, 10])
|
baseUpper = startProfile(coolerBase, at = [0, 10])
|
||||||
|> xLine(length = -0.9)
|
|> xLine(length = -0.9)
|
||||||
|> arc(angleStart = 0, angleEnd = 180, radius = 3.1)
|
|> arc(angleStart = 0, angleEnd = 180deg, radius = 3.1)
|
||||||
|> xLine(length = -1.8)
|
|> xLine(length = -1.8)
|
||||||
|> arc(angleStart = 0, angleEnd = 180, radius = 3)
|
|> arc(angleStart = 0, angleEnd = 180deg, radius = 3)
|
||||||
|> xLine(length = -1.8)
|
|> xLine(length = -1.8)
|
||||||
|> arc(angleStart = 0, angleEnd = 180, radius = 3)
|
|> arc(angleStart = 0, angleEnd = 180deg, radius = 3)
|
||||||
|> xLine(length = -1.8)
|
|> xLine(length = -1.8)
|
||||||
|> xLine(length = -1)
|
|> xLine(length = -1)
|
||||||
|> yLine(length = 4)
|
|> yLine(length = 4)
|
||||||
|> tangentialArc(angle = -90, radius = 2)
|
|> tangentialArc(angle = -90deg, radius = 2)
|
||||||
|> xLine(endAbsolute = 0)
|
|> xLine(endAbsolute = 0)
|
||||||
|> mirror2d(axis = Y)
|
|> mirror2d(axis = Y)
|
||||||
|> extrude(length = 2 * segLen(seg02) * 3 / 4, symmetric = true)
|
|> extrude(length = 2 * segLen(seg02) * 3 / 4, symmetric = true)
|
||||||
@ -122,15 +122,15 @@ baseUpper = startProfile(coolerBase, at = [0, 10])
|
|||||||
mountingBracket = startSketchOn(XZ)
|
mountingBracket = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 16])
|
|> startProfile(at = [-10, 16])
|
||||||
|> xLine(length = -20)
|
|> xLine(length = -20)
|
||||||
|> tangentialArc(angle = 20, radius = bendRadius)
|
|> tangentialArc(angle = 20deg, radius = bendRadius)
|
||||||
|> angledLine(angle = -160, length = 14, tag = $seg09)
|
|> angledLine(angle = -160deg, length = 14, tag = $seg09)
|
||||||
|> tangentialArc(angle = -30, radius = bendRadius + sheetThickness)
|
|> tangentialArc(angle = -30deg, radius = bendRadius + sheetThickness)
|
||||||
|> angledLine(angle = 170, length = 21.5, tag = $seg04Q)
|
|> angledLine(angle = 170deg, length = 21.5, tag = $seg04Q)
|
||||||
|> angledLine(angle = 170 - 90, length = sheetThickness, tag = $seg08)
|
|> angledLine(angle = 170deg - 90, length = sheetThickness, tag = $seg08)
|
||||||
|> angledLine(angle = segAng(seg04Q) + 180, length = segLen(seg04Q), tag = $seg05E)
|
|> angledLine(angle = segAng(seg04Q) + 180deg, length = segLen(seg04Q), tag = $seg05E)
|
||||||
|> tangentialArc(angle = 30, radius = bendRadius)
|
|> tangentialArc(angle = 30deg, radius = bendRadius)
|
||||||
|> angledLine(angle = segAng(seg09) + 180, length = segLen(seg09))
|
|> angledLine(angle = segAng(seg09) + 180deg, length = segLen(seg09))
|
||||||
|> tangentialArc(angle = -20, radius = bendRadius + sheetThickness)
|
|> tangentialArc(angle = -20deg, radius = bendRadius + sheetThickness)
|
||||||
|> xLine(endAbsolute = profileStartX(%))
|
|> xLine(endAbsolute = profileStartX(%))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg07)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg07)
|
||||||
|> close()
|
|> close()
|
||||||
@ -166,6 +166,6 @@ thruHole = startSketchOn(mountingBracket, face = seg05E)
|
|||||||
instances = 2,
|
instances = 2,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
@ -37,7 +37,7 @@ mountingWire
|
|||||||
instances = 2,
|
instances = 2,
|
||||||
axis = [0, 1, 0],
|
axis = [0, 1, 0],
|
||||||
center = [0, 0, 40 + fanSize / 2],
|
center = [0, 0, 40 + fanSize / 2],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|> patternCircular3d(
|
|> patternCircular3d(
|
||||||
@ -45,7 +45,7 @@ mountingWire
|
|||||||
instances = 2,
|
instances = 2,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
removableSticker
|
removableSticker
|
||||||
|
@ -11,29 +11,29 @@ import * from "parameters.kcl"
|
|||||||
upperArm = startSketchOn(offsetPlane(XZ, offset = fanSize / 2 + 2))
|
upperArm = startSketchOn(offsetPlane(XZ, offset = fanSize / 2 + 2))
|
||||||
|> startProfile(at = [-12, 40 + fanSize / 2])
|
|> startProfile(at = [-12, 40 + fanSize / 2])
|
||||||
|> yLine(length = 7)
|
|> yLine(length = 7)
|
||||||
|> tangentialArc(radius = 2, angle = 90)
|
|> tangentialArc(radius = 2, angle = 90deg)
|
||||||
|> xLine(length = -9)
|
|> xLine(length = -9)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> yLine(length = 14)
|
|> yLine(length = 14)
|
||||||
|> tangentialArc(radius = 2, angle = 90)
|
|> tangentialArc(radius = 2, angle = 90deg)
|
||||||
|> xLine(length = -9)
|
|> xLine(length = -9)
|
||||||
|> tangentialArc(radius = 2, angle = -80)
|
|> tangentialArc(radius = 2, angle = -80deg)
|
||||||
|> angledLine(angle = 100, endAbsoluteY = 40 + fanSize / 2 + mountingHoleSpacing / 2 - 1.5)
|
|> angledLine(angle = 100deg, endAbsoluteY = 40 + fanSize / 2 + mountingHoleSpacing / 2 - 1.5)
|
||||||
|> tangentialArc(radius = 2, angle = 80, tag = $seg07)
|
|> tangentialArc(radius = 2, angle = 80deg, tag = $seg07)
|
||||||
|
|
||||||
// Draw the XZ component of the mounting wire path
|
// Draw the XZ component of the mounting wire path
|
||||||
lowerArm = startSketchOn(offsetPlane(XZ, offset = fanSize / 2 + 2))
|
lowerArm = startSketchOn(offsetPlane(XZ, offset = fanSize / 2 + 2))
|
||||||
|> startProfile(at = [-12, 40 + fanSize / 2])
|
|> startProfile(at = [-12, 40 + fanSize / 2])
|
||||||
|> yLine(length = -7)
|
|> yLine(length = -7)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> xLine(length = -9)
|
|> xLine(length = -9)
|
||||||
|> tangentialArc(radius = 2, angle = 90)
|
|> tangentialArc(radius = 2, angle = 90deg)
|
||||||
|> yLine(length = -14)
|
|> yLine(length = -14)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> xLine(length = -9)
|
|> xLine(length = -9)
|
||||||
|> tangentialArc(radius = 2, angle = 80)
|
|> tangentialArc(radius = 2, angle = 80deg)
|
||||||
|> angledLine(angle = -100, endAbsoluteY = 40 + fanSize / 2 - (mountingHoleSpacing / 2) + 1.5)
|
|> angledLine(angle = -100deg, endAbsoluteY = 40 + fanSize / 2 - (mountingHoleSpacing / 2) + 1.5)
|
||||||
|> tangentialArc(radius = 2, angle = -80, tag = $seg08)
|
|> tangentialArc(radius = 2, angle = -80deg, tag = $seg08)
|
||||||
|
|
||||||
// Create the profile of the mounting wire and sweep along the XZ path
|
// Create the profile of the mounting wire and sweep along the XZ path
|
||||||
wireProfile = startSketchOn(offsetPlane(XY, offset = 40 + fanSize / 2))
|
wireProfile = startSketchOn(offsetPlane(XY, offset = 40 + fanSize / 2))
|
||||||
@ -47,18 +47,18 @@ sweepLowerArm = circle(wireProfile, center = [-12, -fanSize / 2 - 2], radius = 1
|
|||||||
upperHook = startSketchOn(offsetPlane(XY, offset = segEndY(seg07)))
|
upperHook = startSketchOn(offsetPlane(XY, offset = segEndY(seg07)))
|
||||||
|> startProfile(at = [segEndX(seg07), -fanSize / 2 - 2])
|
|> startProfile(at = [segEndX(seg07), -fanSize / 2 - 2])
|
||||||
|> xLine(endAbsolute = -heatSinkDepth / 2 - fanHeight)
|
|> xLine(endAbsolute = -heatSinkDepth / 2 - fanHeight)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> yLine(endAbsolute = -mountingHoleSpacing / 2 - 2)
|
|> yLine(endAbsolute = -mountingHoleSpacing / 2 - 2)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> xLine(length = fanHeight / 3)
|
|> xLine(length = fanHeight / 3)
|
||||||
|
|
||||||
// Draw the XY components of the mounting wire path
|
// Draw the XY components of the mounting wire path
|
||||||
lowerHook = startSketchOn(offsetPlane(XY, offset = segEndY(seg08)))
|
lowerHook = startSketchOn(offsetPlane(XY, offset = segEndY(seg08)))
|
||||||
|> startProfile(at = [segEndX(seg07), -fanSize / 2 - 2])
|
|> startProfile(at = [segEndX(seg07), -fanSize / 2 - 2])
|
||||||
|> xLine(endAbsolute = -heatSinkDepth / 2 - fanHeight)
|
|> xLine(endAbsolute = -heatSinkDepth / 2 - fanHeight)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> yLine(endAbsolute = -mountingHoleSpacing / 2 - 2)
|
|> yLine(endAbsolute = -mountingHoleSpacing / 2 - 2)
|
||||||
|> tangentialArc(radius = 2, angle = -90)
|
|> tangentialArc(radius = 2, angle = -90deg)
|
||||||
|> xLine(length = fanHeight / 3)
|
|> xLine(length = fanHeight / 3)
|
||||||
|
|
||||||
// Sweep the wire profile around the hook-shaped segments of the mounting wire
|
// Sweep the wire profile around the hook-shaped segments of the mounting wire
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
removableSticker = startSketchOn(-XY)
|
removableSticker = startSketchOn(-XY)
|
||||||
|> startProfile(at = [-12, -12])
|
|> startProfile(at = [-12, -12])
|
||||||
|> angledLine(angle = 0, length = 24, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 24, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 24, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = 24, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -14,11 +14,11 @@ fn cycloidalGear(gearPitch, gearHeight, holeDiameter, helixAngle: number(deg)) {
|
|||||||
gearPitch * 1.55 * cos(helixAngleP) + gearPitch * sin(-helixAngleP),
|
gearPitch * 1.55 * cos(helixAngleP) + gearPitch * sin(-helixAngleP),
|
||||||
gearPitch * 1.55 * sin(helixAngleP) + gearPitch * cos(-helixAngleP)
|
gearPitch * 1.55 * sin(helixAngleP) + gearPitch * cos(-helixAngleP)
|
||||||
])
|
])
|
||||||
|> arc(angleStart = 90 + helixAngleP, angleEnd = -90 + helixAngleP, radius = gearPitch)
|
|> arc(angleStart = 90deg + helixAngleP, angleEnd = -90deg + helixAngleP, radius = gearPitch)
|
||||||
|> tangentialArc(radius = gearPitch * 1.67, angle = 60)
|
|> tangentialArc(radius = gearPitch * 1.67, angle = 60deg)
|
||||||
|> tangentialArc(radius = gearPitch, angle = -180)
|
|> tangentialArc(radius = gearPitch, angle = -180deg)
|
||||||
|> tangentialArc(radius = gearPitch * 1.67, angle = 60)
|
|> tangentialArc(radius = gearPitch * 1.67, angle = 60deg)
|
||||||
|> tangentialArc(radius = gearPitch, angle = -180)
|
|> tangentialArc(radius = gearPitch, angle = -180deg)
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> subtract2d(tool = circle(center = [0, 0], radius = holeDiameter / 2))
|
|> subtract2d(tool = circle(center = [0, 0], radius = holeDiameter / 2))
|
||||||
@ -40,5 +40,5 @@ cycloidalGear(
|
|||||||
gearPitch = .3,
|
gearPitch = .3,
|
||||||
gearHeight = 1.5,
|
gearHeight = 1.5,
|
||||||
holeDiameter = 0.297,
|
holeDiameter = 0.297,
|
||||||
helixAngle = -80,
|
helixAngle = -80deg,
|
||||||
)
|
)
|
||||||
|
@ -27,9 +27,9 @@ fn primaryTube(n, angle001, length001, length002, length003) {
|
|||||||
sweepPath = startSketchOn(sweepPlane)
|
sweepPath = startSketchOn(sweepPlane)
|
||||||
|> startProfile(at = [0, plateHeight])
|
|> startProfile(at = [0, plateHeight])
|
||||||
|> line(end = [0, length001])
|
|> line(end = [0, length001])
|
||||||
|> tangentialArc(angle = -80, radius = bendRadius, tag = $arc01)
|
|> tangentialArc(angle = -80deg, radius = bendRadius, tag = $arc01)
|
||||||
|> angledLine(angle = tangentToEnd(arc01), length = length002)
|
|> angledLine(angle = tangentToEnd(arc01), length = length002)
|
||||||
|> tangentialArc(angle = 85, radius = bendRadius, tag = $arc02)
|
|> tangentialArc(angle = 85deg, radius = bendRadius, tag = $arc02)
|
||||||
|> angledLine(angle = tangentToEnd(arc02), length = length003)
|
|> angledLine(angle = tangentToEnd(arc02), length = length003)
|
||||||
|
|
||||||
// Create the cross section of each tube and sweep them
|
// Create the cross section of each tube and sweep them
|
||||||
@ -51,21 +51,21 @@ primaryTube(
|
|||||||
)
|
)
|
||||||
primaryTube(
|
primaryTube(
|
||||||
n = 1,
|
n = 1,
|
||||||
angle001 = 1,
|
angle001 = 1deg,
|
||||||
length001 = 3,
|
length001 = 3,
|
||||||
length002 = 6,
|
length002 = 6,
|
||||||
length003 = 5,
|
length003 = 5,
|
||||||
)
|
)
|
||||||
primaryTube(
|
primaryTube(
|
||||||
n = 2,
|
n = 2,
|
||||||
angle001 = 24.3,
|
angle001 = 24.3deg,
|
||||||
length001 = 5,
|
length001 = 5,
|
||||||
length002 = 5,
|
length002 = 5,
|
||||||
length003 = 3,
|
length003 = 3,
|
||||||
)
|
)
|
||||||
primaryTube(
|
primaryTube(
|
||||||
n = 3,
|
n = 3,
|
||||||
angle001 = 25.2,
|
angle001 = 25.2deg,
|
||||||
length001 = 5,
|
length001 = 5,
|
||||||
length002 = 5,
|
length002 = 5,
|
||||||
length003 = 3,
|
length003 = 3,
|
||||||
@ -75,20 +75,20 @@ primaryTube(
|
|||||||
flangeSketch = startSketchOn(XY)
|
flangeSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [3 + 1.3, -1.25])
|
|> startProfile(at = [3 + 1.3, -1.25])
|
||||||
|> xLine(length = -2.6, tag = $seg01)
|
|> xLine(length = -2.6, tag = $seg01)
|
||||||
|> tangentialArc(radius = .3, angle = -40)
|
|> tangentialArc(radius = .3, angle = -40deg)
|
||||||
|> tangentialArc(radius = .9, angle = 80)
|
|> tangentialArc(radius = .9, angle = 80deg)
|
||||||
|> tangentialArc(radius = .3, angle = -40)
|
|> tangentialArc(radius = .3, angle = -40deg)
|
||||||
|> xLine(length = -1.4, tag = $seg03)
|
|> xLine(length = -1.4, tag = $seg03)
|
||||||
|> yLine(length = segLen(seg01), tag = $seg04)
|
|> yLine(length = segLen(seg01), tag = $seg04)
|
||||||
|> xLine(length = 3.1, tag = $seg05)
|
|> xLine(length = 3.1, tag = $seg05)
|
||||||
|> tangentialArc(radius = .3, angle = -40)
|
|> tangentialArc(radius = .3, angle = -40deg)
|
||||||
|> tangentialArc(radius = 1.5, angle = 80)
|
|> tangentialArc(radius = 1.5, angle = 80deg)
|
||||||
|> tangentialArc(radius = .3, angle = -40)
|
|> tangentialArc(radius = .3, angle = -40deg)
|
||||||
|> xLine(length = segLen(seg05), tag = $seg07)
|
|> xLine(length = segLen(seg05), tag = $seg07)
|
||||||
|> yLine(endAbsolute = profileStartY(%), tag = $seg08)
|
|> yLine(endAbsolute = profileStartY(%), tag = $seg08)
|
||||||
|> xLine(length = -segLen(seg03), tag = $seg09)
|
|> xLine(length = -segLen(seg03), tag = $seg09)
|
||||||
|> tangentialArc(radius = .3, angle = -40)
|
|> tangentialArc(radius = .3, angle = -40deg)
|
||||||
|> tangentialArc(radius = .9, angle = 80)
|
|> tangentialArc(radius = .9, angle = 80deg)
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -20,24 +20,24 @@ gripSlotWidth = 8.0
|
|||||||
fn slot(sketch1, start, end, width) {
|
fn slot(sketch1, start, end, width) {
|
||||||
angle = if start[0] == end[0] {
|
angle = if start[0] == end[0] {
|
||||||
if end[1] > start[1] {
|
if end[1] > start[1] {
|
||||||
90
|
90deg
|
||||||
} else {
|
} else {
|
||||||
270
|
270deg
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if end[0] < start[0] {
|
if end[0] < start[0] {
|
||||||
units::toDegrees(atan((end[1] - start[1]) / (end[0] - start[0]))) + 180
|
units::toDegrees(atan((end[1] - start[1]) / (end[0] - start[0]))) + 180deg
|
||||||
} else {
|
} else {
|
||||||
units::toDegrees(atan((end[1] - start[1]) / (end[0] - start[0])))
|
units::toDegrees(atan((end[1] - start[1]) / (end[0] - start[0])))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dist = sqrt(pow(end[1] - start[1], exp = 2) + pow(end[0] - start[0], exp = 2))
|
dist = sqrt(pow(end[1] - start[1], exp = 2) + pow(end[0] - start[0], exp = 2))
|
||||||
xstart = width / 2 * cos(angle - 90) + start[0]
|
xstart = width / 2 * cos(angle - 90deg) + start[0]
|
||||||
ystart = width / 2 * sin(angle - 90) + start[1]
|
ystart = width / 2 * sin(angle - 90deg) + start[1]
|
||||||
slotSketch = startProfile(sketch1, at = [xstart, ystart])
|
slotSketch = startProfile(sketch1, at = [xstart, ystart])
|
||||||
|> angledLine(angle = angle, length = dist)
|
|> angledLine(angle, length = dist)
|
||||||
|> tangentialArc(radius = width / 2, angle = 180)
|
|> tangentialArc(radius = width / 2, angle = 180deg)
|
||||||
|> angledLine(angle = angle, length = -dist)
|
|> angledLine(angle, length = -dist)
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
return slotSketch
|
return slotSketch
|
||||||
@ -51,7 +51,7 @@ flipperProfile = startProfile(flipperSketch, at = [-flipperLength, -32.0])
|
|||||||
|> line(end = [flipperLength, 2.0])
|
|> line(end = [flipperLength, 2.0])
|
||||||
|> yLine(length = 60.0, tag = $backEdge)
|
|> yLine(length = 60.0, tag = $backEdge)
|
||||||
|> line(end = [-flipperLength, 2.0])
|
|> line(end = [-flipperLength, 2.0])
|
||||||
|> arc(angleStart = 163.087610, angleEnd = 196.912390, radius = 110.0)
|
|> arc(angleStart = 163.087610deg, angleEnd = 196.912390deg, radius = 110.0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
// Create a profile of the middle
|
// Create a profile of the middle
|
||||||
@ -137,13 +137,13 @@ gripSketch = startSketchOn(handlePlane)
|
|||||||
// Create a profile of the grip
|
// Create a profile of the grip
|
||||||
gripProfile = startProfile(gripSketch, at = [-26.806746, -10.0])
|
gripProfile = startProfile(gripSketch, at = [-26.806746, -10.0])
|
||||||
|> xLine(length = gripWidth - (2 * gripFilletRadius))
|
|> xLine(length = gripWidth - (2 * gripFilletRadius))
|
||||||
|> arc(angleStart = -90.0, angleEnd = 0.0, radius = gripFilletRadius)
|
|> arc(angleStart = -90.0deg, angleEnd = 0.0, radius = gripFilletRadius)
|
||||||
|> yLine(length = gripHeight - (2 * gripFilletRadius))
|
|> yLine(length = gripHeight - (2 * gripFilletRadius))
|
||||||
|> arc(angleStart = 0.0, angleEnd = 90.0, radius = gripFilletRadius)
|
|> arc(angleStart = 0.0, angleEnd = 90.0deg, radius = gripFilletRadius)
|
||||||
|> xLine(length = -(gripWidth - (2 * gripFilletRadius)))
|
|> xLine(length = -(gripWidth - (2 * gripFilletRadius)))
|
||||||
|> arc(angleStart = 90.0, angleEnd = 180.0, radius = gripFilletRadius)
|
|> arc(angleStart = 90.0deg, angleEnd = 180.0deg, radius = gripFilletRadius)
|
||||||
|> yLine(length = -(gripHeight - (2 * gripFilletRadius)), tag = $gripEdgeTop)
|
|> yLine(length = -(gripHeight - (2 * gripFilletRadius)), tag = $gripEdgeTop)
|
||||||
|> arc(angleStart = 180.0, angleEnd = 270.0, radius = gripFilletRadius)
|
|> arc(angleStart = 180.0deg, angleEnd = 270.0deg, radius = gripFilletRadius)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
// Extrude the grip profile to create the grip
|
// Extrude the grip profile to create the grip
|
||||||
|
@ -13,11 +13,11 @@ handleThickness = 0.65
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [carafeDiameter / 2, 5.7])
|
|> startProfile(at = [carafeDiameter / 2, 5.7])
|
||||||
|> angledLine(angle = 0, length = 0.1, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 0.1, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = -0.75, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = -0.75, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|> revolve(angle = 360, axis = Y)
|
|> revolve(angle = 360deg, axis = Y)
|
||||||
|
|
||||||
// Create an angled plane to sketch the supports
|
// Create an angled plane to sketch the supports
|
||||||
plane001 = {
|
plane001 = {
|
||||||
@ -32,19 +32,19 @@ sketch002 = startSketchOn(plane001)
|
|||||||
|> startProfile(at = [carafeDiameter / 2, 5.7])
|
|> startProfile(at = [carafeDiameter / 2, 5.7])
|
||||||
|> xLine(length = 0.1)
|
|> xLine(length = 0.1)
|
||||||
|> yLine(length = -5.2, tag = $edge1)
|
|> yLine(length = -5.2, tag = $edge1)
|
||||||
|> arc(angleStart = 180, angleEnd = 205, radius = 0.3)
|
|> arc(angleStart = 180deg, angleEnd = 205deg, radius = 0.3)
|
||||||
|> angledLine(angle = -60, length = 0.6, tag = $edge2)
|
|> angledLine(angle = -60deg, length = 0.6, tag = $edge2)
|
||||||
|> arc(angleStart = 30, angleEnd = -120, radius = 0.6)
|
|> arc(angleStart = 30deg, angleEnd = -120deg, radius = 0.6)
|
||||||
|> angledLine(angle = 150, endAbsoluteY = -0.2, tag = $edge3)
|
|> angledLine(angle = 150deg, endAbsoluteY = -0.2, tag = $edge3)
|
||||||
|> arc(angleStart = 60, angleEnd = 90, radius = 0.5)
|
|> arc(angleStart = 60deg, angleEnd = 90deg, radius = 0.5)
|
||||||
|> xLine(endAbsolute = 0.1, tag = $edgeLen)
|
|> xLine(endAbsolute = 0.1, tag = $edgeLen)
|
||||||
|> yLine(length = 0.1)
|
|> yLine(length = 0.1)
|
||||||
|> xLine(length = segLen(edgeLen) + 0.035, tag = $edge4)
|
|> xLine(length = segLen(edgeLen) + 0.035, tag = $edge4)
|
||||||
|> arc(angleStart = 90, angleEnd = 60, radius = 0.6)
|
|> arc(angleStart = 90deg, angleEnd = 60deg, radius = 0.6)
|
||||||
|> angledLine(angle = 150, length = -segLen(edge3) + 0.035, tag = $edge5)
|
|> angledLine(angle = 150deg, length = -segLen(edge3) + 0.035, tag = $edge5)
|
||||||
|> arc(angleStart = -120, angleEnd = 30, radius = 0.5)
|
|> arc(angleStart = -120deg, angleEnd = 30deg, radius = 0.5)
|
||||||
|> angledLine(angle = -60, length = -segLen(edge2) + 0.035, tag = $edge6)
|
|> angledLine(angle = -60deg, length = -segLen(edge2) + 0.035, tag = $edge6)
|
||||||
|> arc(angleStart = 205, angleEnd = 180, radius = 0.6)
|
|> arc(angleStart = 205deg, angleEnd = 180deg, radius = 0.6)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 0.75)
|
|> extrude(length = 0.75)
|
||||||
@ -52,7 +52,7 @@ sketch002 = startSketchOn(plane001)
|
|||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
instances = 4,
|
instances = 4,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ extrude001 = extrude(sketch003, length = 0.050)
|
|||||||
sketch004 = startSketchOn(extrude001, face = END)
|
sketch004 = startSketchOn(extrude001, face = END)
|
||||||
|> startProfile(at = [0.3, 0.17])
|
|> startProfile(at = [0.3, 0.17])
|
||||||
|> yLine(length = 1.2)
|
|> yLine(length = 1.2)
|
||||||
|> arc(angleStart = 90, angleEnd = -30, radius = 1.2)
|
|> arc(angleStart = 90deg, angleEnd = -30deg, radius = 1.2)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
@ -81,9 +81,9 @@ extrude002 = extrude(sketch004, length = -0.050)
|
|||||||
sketch005 = startSketchOn(XZ)
|
sketch005 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.15, 1.11])
|
|> startProfile(at = [0.15, 1.11])
|
||||||
|> xLine(endAbsolute = carafeDiameter / 2 - 0.2)
|
|> xLine(endAbsolute = carafeDiameter / 2 - 0.2)
|
||||||
|> angledLine(angle = 30, endAbsoluteX = carafeDiameter / 2 - 0.07, tag = $seg1)
|
|> angledLine(angle = 30deg, endAbsoluteX = carafeDiameter / 2 - 0.07, tag = $seg1)
|
||||||
|> angledLine(angle = -60, length = 0.050)
|
|> angledLine(angle = -60deg, length = 0.050)
|
||||||
|> angledLine(angle = 30, length = -segLen(seg1))
|
|> angledLine(angle = 30deg, length = -segLen(seg1))
|
||||||
|> xLine(endAbsolute = 0.15)
|
|> xLine(endAbsolute = 0.15)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -93,11 +93,11 @@ sketch005 = startSketchOn(XZ)
|
|||||||
sketch006 = startSketchOn(XZ)
|
sketch006 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.1, 1])
|
|> startProfile(at = [0.1, 1])
|
||||||
|> line(end = [0.1, 0])
|
|> line(end = [0.1, 0])
|
||||||
|> angledLine(angle = 10, endAbsoluteX = 0.05)
|
|> angledLine(angle = 10deg, endAbsoluteX = 0.05)
|
||||||
|> yLine(length = 10)
|
|> yLine(length = 10)
|
||||||
|> line(end = [0.6, 0])
|
|> line(end = [0.6, 0])
|
||||||
|> yLine(length = -.05)
|
|> yLine(length = -.05)
|
||||||
|> tangentialArc(radius = 0.6, angle = -90)
|
|> tangentialArc(radius = 0.6, angle = -90deg)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|> revolve(axis = Y)
|
|> revolve(axis = Y)
|
||||||
@ -115,7 +115,7 @@ sketch008 = startSketchOn(extrude003, face = END)
|
|||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
instances = 8,
|
instances = 8,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ sketch009 = startSketchOn(extrude003, face = END)
|
|||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
instances = 4,
|
instances = 4,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,16 +10,16 @@ headSideProfile = startSketchOn(XZ)
|
|||||||
|> yLine(length = 0.1)
|
|> yLine(length = 0.1)
|
||||||
|> tangentialArc(endAbsolute = [0.95, 11.92])
|
|> tangentialArc(endAbsolute = [0.95, 11.92])
|
||||||
|> tangentialArc(endAbsolute = [2.72, 11.26], tag = $seg01)
|
|> tangentialArc(endAbsolute = [2.72, 11.26], tag = $seg01)
|
||||||
|> angledLine(angle = tangentToEnd(seg01) + 90, length = .2)
|
|> angledLine(angle = tangentToEnd(seg01) + 90deg, length = .2)
|
||||||
|> angledLine(angle = tangentToEnd(seg01) - 10, length = -0.5)
|
|> angledLine(angle = tangentToEnd(seg01) - 10deg, length = -0.5)
|
||||||
|> tangentialArc(endAbsolute = [-0.91, 12.78], tag = $seg03)
|
|> tangentialArc(endAbsolute = [-0.91, 12.78], tag = $seg03)
|
||||||
|> tangentialArc(endAbsolute = [-1.67, 12.85])
|
|> tangentialArc(endAbsolute = [-1.67, 12.85])
|
||||||
|> xLine(length = -.25)
|
|> xLine(length = -.25)
|
||||||
|> tangentialArc(angle = 90, radius = .05)
|
|> tangentialArc(angle = 90deg, radius = .05)
|
||||||
|> yLine(length = -1.125, tag = $seg02)
|
|> yLine(length = -1.125, tag = $seg02)
|
||||||
|> tangentialArc(angle = 90, radius = .05)
|
|> tangentialArc(angle = 90deg, radius = .05)
|
||||||
|> xLine(length = .25, tag = $seg04)
|
|> xLine(length = .25, tag = $seg04)
|
||||||
|> angledLine(angle = 23, length = 0.1)
|
|> angledLine(angle = 23deg, length = 0.1)
|
||||||
|> tangentialArc(endAbsolute = [-0.33, profileStartY(%)])
|
|> tangentialArc(endAbsolute = [-0.33, profileStartY(%)])
|
||||||
|> xLine(endAbsolute = profileStartX(%))
|
|> xLine(endAbsolute = profileStartX(%))
|
||||||
|> close()
|
|> close()
|
||||||
@ -31,8 +31,8 @@ leftSideCut = startProfile(headTopProfile, at = [-4, -1.6])
|
|||||||
|> line(endAbsolute = [segEndX(seg02), -segLen(seg02) / 2])
|
|> line(endAbsolute = [segEndX(seg02), -segLen(seg02) / 2])
|
||||||
|> arc(
|
|> arc(
|
||||||
%,
|
%,
|
||||||
angleStart = 180,
|
angleStart = 180deg,
|
||||||
angleEnd = 270,
|
angleEnd = 270deg,
|
||||||
radius = .05,
|
radius = .05,
|
||||||
)
|
)
|
||||||
|> xLine(endAbsolute = segEndX(seg04))
|
|> xLine(endAbsolute = segEndX(seg04))
|
||||||
@ -44,7 +44,7 @@ leftSideCut = startProfile(headTopProfile, at = [-4, -1.6])
|
|||||||
|> extrude(length = -14)
|
|> extrude(length = -14)
|
||||||
|
|
||||||
rearCut = startProfile(headTopProfile, at = [3.39, -0.56])
|
rearCut = startProfile(headTopProfile, at = [3.39, -0.56])
|
||||||
|> angledLine(angle = 177, length = 0.1)
|
|> angledLine(angle = 177deg, length = 0.1)
|
||||||
|> tangentialArc(endAbsolute = [1.86, -0.37])
|
|> tangentialArc(endAbsolute = [1.86, -0.37])
|
||||||
|> tangentialArc(endAbsolute = [lastSegX(%), -lastSegY(%)])
|
|> tangentialArc(endAbsolute = [lastSegX(%), -lastSegY(%)])
|
||||||
|> tangentialArc(endAbsolute = [profileStartX(%), -profileStartY(%)])
|
|> tangentialArc(endAbsolute = [profileStartX(%), -profileStartY(%)])
|
||||||
@ -56,8 +56,8 @@ rightSideCut = startProfile(headTopProfile, at = [-4, 1.6])
|
|||||||
|> line(endAbsolute = [segEndX(seg02), segLen(seg02) / 2])
|
|> line(endAbsolute = [segEndX(seg02), segLen(seg02) / 2])
|
||||||
|> arc(
|
|> arc(
|
||||||
%,
|
%,
|
||||||
angleStart = -180,
|
angleStart = -180deg,
|
||||||
angleEnd = -270,
|
angleEnd = -270deg,
|
||||||
radius = .05,
|
radius = .05,
|
||||||
)
|
)
|
||||||
|> xLine(endAbsolute = segEndX(seg04))
|
|> xLine(endAbsolute = segEndX(seg04))
|
||||||
@ -108,11 +108,11 @@ hammerHead = union([firstProfiles, baseSupport])
|
|||||||
handleSketch = startSketchOn(XZ)
|
handleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.01, 0])
|
|> startProfile(at = [0.01, 0])
|
||||||
|> xLine(length = 1.125 / 2)
|
|> xLine(length = 1.125 / 2)
|
||||||
|> tangentialArc(angle = 90, radius = 0.05)
|
|> tangentialArc(angle = 90deg, radius = 0.05)
|
||||||
|> tangentialArc(endAbsolute = [0.38, 12.8 / 1.612])
|
|> tangentialArc(endAbsolute = [0.38, 12.8 / 1.612])
|
||||||
|> tangentialArc(endAbsolute = [0.28, 12.8])
|
|> tangentialArc(endAbsolute = [0.28, 12.8])
|
||||||
|> xLine(endAbsolute = profileStartX(%))
|
|> xLine(endAbsolute = profileStartX(%))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
handle = revolve(handleSketch, angle = 360, axis = Y)
|
handle = revolve(handleSketch, angle = 360deg, axis = Y)
|
||||||
|> appearance(color = "#f14f04")
|
|> appearance(color = "#f14f04")
|
||||||
|
@ -29,8 +29,8 @@ fn helicalGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
|> xLine(length = keywayDepth)
|
|> xLine(length = keywayDepth)
|
||||||
|> yLine(length = -keywayWidth)
|
|> yLine(length = -keywayWidth)
|
||||||
|> xLine(length = -keywayDepth)
|
|> xLine(length = -keywayDepth)
|
||||||
|> arc(angleStart = -1 * startAngle + 360, angleEnd = 180, radius = holeRadius)
|
|> arc(angleStart = -1 * startAngle + 360deg, angleEnd = 180deg, radius = holeRadius)
|
||||||
|> arc(angleStart = 180, angleEnd = startAngle, radius = holeRadius)
|
|> arc(angleStart = 180deg, angleEnd = startAngle, radius = holeRadius)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
// Define a function to create a rotated gear sketch on an offset plane
|
// Define a function to create a rotated gear sketch on an offset plane
|
||||||
@ -42,28 +42,28 @@ fn helicalGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
helicalGearSketch = startSketchOn(offsetPlane(XY, offset = offsetHeight))
|
helicalGearSketch = startSketchOn(offsetPlane(XY, offset = offsetHeight))
|
||||||
|> startProfile(at = polar(angle = helixCalc, length = baseDiameter / 2))
|
|> startProfile(at = polar(angle = helixCalc, length = baseDiameter / 2))
|
||||||
|> involuteCircular(
|
|> involuteCircular(
|
||||||
startDiameter = baseDiameter,
|
startRadius = baseDiameter / 2,
|
||||||
endDiameter = tipDiameter,
|
endRadius = tipDiameter / 2,
|
||||||
angle = helixCalc,
|
angle = helixCalc,
|
||||||
tag = $seg01,
|
tag = $seg01,
|
||||||
)
|
)
|
||||||
|> line(endAbsolute = polar(angle = 160 / nTeeth + helixCalc, length = tipDiameter / 2))
|
|> line(endAbsolute = polar(angle = 160deg / nTeeth + helixCalc, length = tipDiameter / 2))
|
||||||
|> involuteCircular(
|
|> involuteCircular(
|
||||||
startDiameter = baseDiameter,
|
startRadius = baseDiameter / 2,
|
||||||
endDiameter = tipDiameter,
|
endRadius = tipDiameter / 2,
|
||||||
angle = -(4 * atan(segEndY(seg01) / segEndX(seg01)) - (3 * helixCalc)),
|
angle = -(4 * atan(segEndY(seg01) / segEndX(seg01)) - (3 * helixCalc)),
|
||||||
reverse = true,
|
reverse = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Position the end line of the sketch at the start of the next tooth
|
// Position the end line of the sketch at the start of the next tooth
|
||||||
|> line(endAbsolute = polar(angle = 360 / nTeeth + helixCalc, length = baseDiameter / 2))
|
|> line(endAbsolute = polar(angle = 360deg / nTeeth + helixCalc, length = baseDiameter / 2))
|
||||||
|
|
||||||
// Pattern the sketch about the center by the specified number of teeth, then close the sketch
|
// Pattern the sketch about the center by the specified number of teeth, then close the sketch
|
||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
%,
|
%,
|
||||||
instances = nTeeth,
|
instances = nTeeth,
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|> close()
|
|> close()
|
||||||
@ -93,7 +93,7 @@ fn helicalGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
helicalGear(
|
helicalGear(
|
||||||
nTeeth = 21,
|
nTeeth = 21,
|
||||||
module = 2,
|
module = 2,
|
||||||
pressureAngle = 20,
|
pressureAngle = 20deg,
|
||||||
helixAngle = 35,
|
helixAngle = 35deg,
|
||||||
gearHeight = 7,
|
gearHeight = 7,
|
||||||
)
|
)
|
||||||
|
@ -29,8 +29,8 @@ fn helicalGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
|> xLine(length = keywayDepth)
|
|> xLine(length = keywayDepth)
|
||||||
|> yLine(length = -keywayWidth)
|
|> yLine(length = -keywayWidth)
|
||||||
|> xLine(length = -keywayDepth)
|
|> xLine(length = -keywayDepth)
|
||||||
|> arc(angleStart = -1 * startAngle + 360, angleEnd = 180, radius = holeRadius)
|
|> arc(angleStart = -1 * startAngle + 360deg, angleEnd = 180deg, radius = holeRadius)
|
||||||
|> arc(angleStart = 180, angleEnd = startAngle, radius = holeRadius)
|
|> arc(angleStart = 180deg, angleEnd = startAngle, radius = holeRadius)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
// Define a function to create a rotated gear sketch on an offset plane
|
// Define a function to create a rotated gear sketch on an offset plane
|
||||||
@ -47,7 +47,7 @@ fn helicalGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
angle = helixCalc,
|
angle = helixCalc,
|
||||||
tag = $seg01,
|
tag = $seg01,
|
||||||
)
|
)
|
||||||
|> line(endAbsolute = polar(angle = 160 / nTeeth + helixCalc, length = tipDiameter / 2))
|
|> line(endAbsolute = polar(angle = 160deg / nTeeth + helixCalc, length = tipDiameter / 2))
|
||||||
|> involuteCircular(
|
|> involuteCircular(
|
||||||
startRadius = baseDiameter / 2,
|
startRadius = baseDiameter / 2,
|
||||||
endRadius = tipDiameter / 2,
|
endRadius = tipDiameter / 2,
|
||||||
@ -56,14 +56,14 @@ fn helicalGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Position the end line of the sketch at the start of the next tooth
|
// Position the end line of the sketch at the start of the next tooth
|
||||||
|> line(endAbsolute = polar(angle = 360 / nTeeth + helixCalc, length = baseDiameter / 2))
|
|> line(endAbsolute = polar(angle = 360deg / nTeeth + helixCalc, length = baseDiameter / 2))
|
||||||
|
|
||||||
// Pattern the sketch about the center by the specified number of teeth, then close the sketch
|
// Pattern the sketch about the center by the specified number of teeth, then close the sketch
|
||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
%,
|
%,
|
||||||
instances = nTeeth,
|
instances = nTeeth,
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|> close()
|
|> close()
|
||||||
@ -113,7 +113,7 @@ fn ringGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
angle = helixCalc,
|
angle = helixCalc,
|
||||||
tag = $seg01,
|
tag = $seg01,
|
||||||
)
|
)
|
||||||
|> line(endAbsolute = polar(angle = 200 / nTeeth + helixCalc, length = tipDiameter / 2))
|
|> line(endAbsolute = polar(angle = 200deg / nTeeth + helixCalc, length = tipDiameter / 2))
|
||||||
|> involuteCircular(
|
|> involuteCircular(
|
||||||
startRadius = baseDiameter / 2,
|
startRadius = baseDiameter / 2,
|
||||||
endRadius = tipDiameter / 2,
|
endRadius = tipDiameter / 2,
|
||||||
@ -129,7 +129,7 @@ fn ringGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
%,
|
%,
|
||||||
instances = nTeeth,
|
instances = nTeeth,
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|> close()
|
|> close()
|
||||||
@ -164,8 +164,8 @@ fn ringGear(nTeeth, module, pressureAngle, helixAngle, gearHeight) {
|
|||||||
ringGear(
|
ringGear(
|
||||||
nTeeth = 42,
|
nTeeth = 42,
|
||||||
module = 1.5,
|
module = 1.5,
|
||||||
pressureAngle = 14,
|
pressureAngle = 14deg,
|
||||||
helixAngle = -25,
|
helixAngle = -25deg,
|
||||||
gearHeight = 5,
|
gearHeight = 5,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -173,8 +173,8 @@ ringGear(
|
|||||||
helicalGear(
|
helicalGear(
|
||||||
nTeeth = 12,
|
nTeeth = 12,
|
||||||
module = 1.5,
|
module = 1.5,
|
||||||
pressureAngle = 14,
|
pressureAngle = 14deg,
|
||||||
helixAngle = 25,
|
helixAngle = 25deg,
|
||||||
gearHeight = 5,
|
gearHeight = 5,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -183,8 +183,8 @@ numPlanetGears = 3
|
|||||||
helicalGear(
|
helicalGear(
|
||||||
nTeeth = 12,
|
nTeeth = 12,
|
||||||
module = 1.5,
|
module = 1.5,
|
||||||
pressureAngle = 14,
|
pressureAngle = 14deg,
|
||||||
helixAngle = -25,
|
helixAngle = -25deg,
|
||||||
gearHeight = 5,
|
gearHeight = 5,
|
||||||
)
|
)
|
||||||
|> translate(y = (12 + 12) / 2 * 1.5 + 2.7)
|
|> translate(y = (12 + 12) / 2 * 1.5 + 2.7)
|
||||||
@ -192,6 +192,6 @@ helicalGear(
|
|||||||
instances = numPlanetGears,
|
instances = numPlanetGears,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = false,
|
rotateDuplicates = false,
|
||||||
)
|
)
|
||||||
|