Compare commits
59 Commits
delete-net
...
nrc-no-ang
Author | SHA1 | Date | |
---|---|---|---|
7b7d587141 | |||
5db6564804 | |||
dd6a980915 | |||
2516df3a39 | |||
52125f0566 | |||
e489222b6a | |||
d93a57d7bf | |||
d34aea345b | |||
0b6102b0ac | |||
9e0873ed84 | |||
8587eb5fea | |||
b898c27e74 | |||
3026866a16 | |||
92fc294eae | |||
21e967ea7f | |||
3f00e7186c | |||
d3a4fd8b55 | |||
2be7107cca | |||
94f194a984 | |||
4fe880a970 | |||
8f5fbfc273 | |||
e660f52bb0 | |||
d74fdd9369 | |||
334145f0be | |||
c24073b6ae | |||
078b7f3bf7 | |||
3d65676ccb | |||
ce566fb6e5 | |||
b23fc9f623 | |||
5c2dfb8e40 | |||
0e341d7863 | |||
6a03ff9596 | |||
d7bd0c937d | |||
d3b2483f4f | |||
7838b7c9fd | |||
130ecf1f88 | |||
550d8b3753 | |||
696222a070 | |||
edb424988d | |||
1e487ef3bd | |||
811ef3e72d | |||
980e3c4bc2 | |||
78b6854c6b | |||
068b9129cf | |||
05fba3c50c | |||
7944a4ce41 | |||
4640f1a3ad | |||
cd79059d97 | |||
2d95e19048 | |||
d047587bc1 | |||
128e1093fb | |||
afdc305e3e | |||
4bc5439996 | |||
be14022f97 | |||
eda78ef5ae | |||
0cc833e687 | |||
33e83747f3 | |||
c3a8fc6d93 | |||
8ff84e269c |
57
.github/workflows/build-apps.yml
vendored
57
.github/workflows/build-apps.yml
vendored
@ -13,7 +13,7 @@ env:
|
|||||||
IS_NIGHTLY: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
IS_NIGHTLY: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -123,18 +123,6 @@ jobs:
|
|||||||
- id: export_notes
|
- id: export_notes
|
||||||
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
|
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Prepare electron-builder.yml file for updater test
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
run: |
|
|
||||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
with:
|
|
||||||
name: prepared-files-updater-test
|
|
||||||
path: |
|
|
||||||
electron-builder.yml
|
|
||||||
|
|
||||||
|
|
||||||
build-apps:
|
build-apps:
|
||||||
needs: [prepare-files]
|
needs: [prepare-files]
|
||||||
@ -259,49 +247,6 @@ jobs:
|
|||||||
|
|
||||||
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
||||||
|
|
||||||
# The steps below are for updater-test builds, only on release
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
name: prepared-files-updater-test
|
|
||||||
|
|
||||||
- name: Copy updated electron-builder.yml file for updater test
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
run: |
|
|
||||||
ls -R prepared-files-updater-test
|
|
||||||
cp prepared-files-updater-test/electron-builder.yml electron-builder.yml
|
|
||||||
|
|
||||||
- name: Build the app (updater-test)
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
env:
|
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
||||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
||||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
||||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
||||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
||||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
|
||||||
run: npm run tronb:package:prod
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
with:
|
|
||||||
name: updater-test-arm64-${{ matrix.platform }}
|
|
||||||
path: |
|
|
||||||
out/*-arm64-win.exe
|
|
||||||
out/*-arm64-mac.dmg
|
|
||||||
out/*-arm64-linux.AppImage
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
with:
|
|
||||||
name: updater-test-x64-${{ matrix.platform }}
|
|
||||||
path: |
|
|
||||||
out/*-x64-win.exe
|
|
||||||
out/*-x64-mac.dmg
|
|
||||||
out/*-x86_64-linux.AppImage
|
|
||||||
|
|
||||||
|
|
||||||
upload-apps-release:
|
upload-apps-release:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
38
.github/workflows/e2e-tests.yml
vendored
38
.github/workflows/e2e-tests.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
- 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@v7
|
uses: dawidd6/action-download-artifact@v7
|
||||||
@ -52,7 +52,7 @@ jobs:
|
|||||||
branch: main
|
branch: main
|
||||||
path: rust/kcl-wasm-lib/pkg
|
path: rust/kcl-wasm-lib/pkg
|
||||||
|
|
||||||
- name: Build WASM condition
|
- name: Build Wasm condition
|
||||||
id: wasm
|
id: wasm
|
||||||
run: |
|
run: |
|
||||||
set -euox pipefail
|
set -euox pipefail
|
||||||
@ -70,7 +70,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
||||||
|
|
||||||
- name: Install rust
|
- name: Install Rust
|
||||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
@ -81,7 +81,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
|
|
||||||
- name: Rust Cache
|
- name: Use Rust cache
|
||||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
@ -117,7 +117,7 @@ jobs:
|
|||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
name: prepared-wasm
|
name: prepared-wasm
|
||||||
|
|
||||||
- name: Copy prepared wasm
|
- name: Copy prepared Wasm
|
||||||
run: |
|
run: |
|
||||||
ls -R prepared-wasm
|
ls -R prepared-wasm
|
||||||
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
||||||
@ -133,20 +133,17 @@ jobs:
|
|||||||
id: deps-install
|
id: deps-install
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
- name: Cache Playwright Browsers
|
- name: Cache browsers
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cache/ms-playwright/
|
~/.cache/ms-playwright/
|
||||||
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
|
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
|
||||||
|
|
||||||
- name: Install Playwright Browsers
|
- name: Install browsers
|
||||||
run: npm run playwright install --with-deps
|
run: npm run playwright install --with-deps
|
||||||
|
|
||||||
- name: build web
|
- name: Capture snapshots
|
||||||
run: npm run tronb:vite:dev
|
|
||||||
|
|
||||||
- name: Run ubuntu/chrome snapshots
|
|
||||||
uses: nick-fields/retry@v3.0.2
|
uses: nick-fields/retry@v3.0.2
|
||||||
with:
|
with:
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -170,7 +167,7 @@ jobs:
|
|||||||
retention-days: 30
|
retention-days: 30
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|
||||||
- name: Check for changes
|
- name: Check diff
|
||||||
if: ${{ github.ref != 'refs/heads/main' }}
|
if: ${{ github.ref != 'refs/heads/main' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
id: git-check
|
id: git-check
|
||||||
@ -181,9 +178,8 @@ jobs:
|
|||||||
else echo "modified=false" >> $GITHUB_OUTPUT
|
else echo "modified=false" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Commit changes, if any
|
- name: Commit changes
|
||||||
# TODO: find a more reliable way to detect visual changes
|
if: ${{ steps.git-check.outputs.modified == 'true' }}
|
||||||
if: ${{ false && steps.git-check.outputs.modified == 'true' }}
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
|
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
|
||||||
@ -193,7 +189,7 @@ jobs:
|
|||||||
git fetch origin
|
git fetch origin
|
||||||
echo ${{ github.head_ref }}
|
echo ${{ github.head_ref }}
|
||||||
git checkout ${{ github.head_ref }}
|
git checkout ${{ github.head_ref }}
|
||||||
git commit -m "A snapshot a day keeps the bugs away! 📷🐛" || true
|
git commit --message "Update snapshots" || true
|
||||||
git push
|
git push
|
||||||
git push origin ${{ github.head_ref }}
|
git push origin ${{ github.head_ref }}
|
||||||
|
|
||||||
@ -234,10 +230,16 @@ jobs:
|
|||||||
shardTotal: 8
|
shardTotal: 8
|
||||||
- os: namespace-profile-macos-8-cores
|
- os: namespace-profile-macos-8-cores
|
||||||
shardIndex: 1
|
shardIndex: 1
|
||||||
shardTotal: 1
|
shardTotal: 2
|
||||||
|
- os: namespace-profile-macos-8-cores
|
||||||
|
shardIndex: 2
|
||||||
|
shardTotal: 2
|
||||||
- os: windows-latest-8-cores
|
- os: windows-latest-8-cores
|
||||||
shardIndex: 1
|
shardIndex: 1
|
||||||
shardTotal: 1
|
shardTotal: 2
|
||||||
|
- os: windows-latest-8-cores
|
||||||
|
shardIndex: 2
|
||||||
|
shardTotal: 2
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
@ -130,7 +130,7 @@ git tag $VERSION
|
|||||||
git push origin --tags
|
git push origin --tags
|
||||||
```
|
```
|
||||||
|
|
||||||
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
|
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files.
|
||||||
|
|
||||||
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
|
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
|
||||||
|
|
||||||
@ -142,13 +142,10 @@ The release builds can be found under the `out-{arch}-{platform}` zip files, at
|
|||||||
|
|
||||||
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
||||||
|
|
||||||
##### Updater-test builds
|
A prompt should show up asking for a downgrade to the last release version. Running through that at the end of testing
|
||||||
|
and making sure the current release candidate has the ability to be updated to what electron-updater points to is critical,
|
||||||
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
but what is actually being downloaded and installed isn't.
|
||||||
|
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing.
|
||||||
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
|
||||||
|
|
||||||
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
|
|
||||||
|
|
||||||
```
|
```
|
||||||
# Windows (PowerShell)
|
# Windows (PowerShell)
|
||||||
|
@ -34,7 +34,7 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
|
|||||||
- WebSockets (via [KittyCAD TS client](https://github.com/KittyCAD/kittycad.ts))
|
- WebSockets (via [KittyCAD TS client](https://github.com/KittyCAD/kittycad.ts))
|
||||||
- Code Editor
|
- Code Editor
|
||||||
- [CodeMirror](https://codemirror.net/)
|
- [CodeMirror](https://codemirror.net/)
|
||||||
- Custom WASM LSP Server
|
- [Custom WASM LSP Server](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib/src/lsp/kcl)
|
||||||
- Modeling
|
- Modeling
|
||||||
- [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts)
|
- [KittyCAD TypeScript client](https://github.com/KittyCAD/kittycad.ts)
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ angledLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> yLine(endAbsolute = 15)
|
|> yLine(endAbsolute = 15)
|
||||||
|> angledLine(angle = 30, length = 15)
|
|> angledLine(angle = 30deg, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -42,7 +42,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> line(endAbsolute = [5, 10])
|
|> line(endAbsolute = [5, 10])
|
||||||
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|
||||||
|> line(endAbsolute = [0, 20])
|
|> line(endAbsolute = [0, 20])
|
||||||
|> angledLineThatIntersects(angle = 80, intersectTag = lineToIntersect, offset = 10)
|
|> angledLineThatIntersects(angle = 80deg, intersectTag = lineToIntersect, offset = 10)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -46,7 +46,7 @@ Unless this makes a lot of sense and feels like what you're looking for to const
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> arc(angleStart = 0, angleEnd = 280, radius = 16)
|
|> arc(angleStart = 0deg, angleEnd = 280deg, radius = 16)
|
||||||
|> close()
|
|> close()
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
```
|
```
|
||||||
|
@ -19,7 +19,7 @@ E: number = 2.71828182845904523536028747135266250_
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30deg,
|
||||||
length = 2 * E ^ 2,
|
length = 2 * E ^ 2,
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -19,7 +19,7 @@ TAU: number = 6.28318530717958647692528676655900577_
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 10 * TAU,
|
length = 10 * TAU,
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
16
docs/kcl-std/consts/std-sweep-SKETCH_PLANE.md
Normal file
16
docs/kcl-std/consts/std-sweep-SKETCH_PLANE.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
title: "sweep::SKETCH_PLANE"
|
||||||
|
subtitle: "Constant in std::sweep"
|
||||||
|
excerpt: "Local/relative to a position centered within the plane being sketched on"
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Local/relative to a position centered within the plane being sketched on
|
||||||
|
|
||||||
|
```kcl
|
||||||
|
sweep::SKETCH_PLANE: string = 'sketchPlane'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
docs/kcl-std/consts/std-sweep-TRAJECTORY.md
Normal file
16
docs/kcl-std/consts/std-sweep-TRAJECTORY.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
title: "sweep::TRAJECTORY"
|
||||||
|
subtitle: "Constant in std::sweep"
|
||||||
|
excerpt: "Local/relative to the trajectory curve"
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
Local/relative to the trajectory curve
|
||||||
|
|
||||||
|
```kcl
|
||||||
|
sweep::TRAJECTORY: string = 'trajectoryCurve'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ You can provide more than one sketch to extrude, and they will all be extruded i
|
|||||||
example = startSketchOn(XZ)
|
example = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = 0, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = 0deg, radius = 5)
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> line(end = [0, 10])
|
|> line(end = [0, 10])
|
||||||
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
@ -56,7 +56,7 @@ example = startSketchOn(XZ)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 0])
|
|> startProfile(at = [-10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
@ -72,7 +72,7 @@ example = extrude(exampleSketch, length = 10)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 0])
|
|> startProfile(at = [-10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
@ -88,7 +88,7 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 0])
|
|> startProfile(at = [-10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
|
@ -80,7 +80,7 @@ fn decagon(@radius) {
|
|||||||
|
|
||||||
// Start the decagon sketch at this point.
|
// Start the decagon sketch at this point.
|
||||||
startOfDecagonSketch = startSketchOn(XY)
|
startOfDecagonSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [(cos(0)*radius), (sin(0) * radius)])
|
|> startProfile(at = [(cos(0deg)*radius), (sin(0deg) * radius)])
|
||||||
|
|
||||||
// Use a `reduce` to draw the remaining decagon sides.
|
// Use a `reduce` to draw the remaining decagon sides.
|
||||||
// For each number in the array 1..10, run the given function,
|
// For each number in the array 1..10, run the given function,
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -27,7 +27,7 @@ abs(@input: number): number
|
|||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
myAngle = -120
|
myAngle = -120deg
|
||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|
@ -30,7 +30,7 @@ cos(@num: number(Angle)): number(_)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30deg,
|
||||||
length = 3 / cos(30deg),
|
length = 3 / cos(30deg),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ max(@input: [number; 1+]): number
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 70,
|
angle = 70deg,
|
||||||
length = max([15, 31, 4, 13, 22])
|
length = max([15, 31, 4, 13, 22])
|
||||||
)
|
)
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|
@ -30,7 +30,7 @@ min(@input: [number; 1+]): number
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 70,
|
angle = 70deg,
|
||||||
length = min([15, 31, 4, 13, 22])
|
length = min([15, 31, 4, 13, 22])
|
||||||
)
|
)
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|
@ -34,7 +34,7 @@ cartesian (x/y/z grid) coordinates.
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = polar(angle = 30, length = 5), tag = $thing)
|
|> line(end = polar(angle = 30deg, length = 5), tag = $thing)
|
||||||
|> line(end = [0, 5])
|
|> line(end = [0, 5])
|
||||||
|> line(end = [segEndX(thing), 0])
|
|> line(end = [segEndX(thing), 0])
|
||||||
|> line(end = [-20, 10])
|
|> line(end = [-20, 10])
|
||||||
|
@ -34,7 +34,7 @@ pow(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = pow(5, exp = 2),
|
length = pow(5, exp = 2),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ sin(@num: number(Angle)): number(_)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 15 / sin(135deg),
|
length = 15 / sin(135deg),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ sqrt(@input: number): number
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = sqrt(2500),
|
length = sqrt(2500),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ tan(@num: number(Angle)): number(_)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 50 * tan((1/2): number(rad)),
|
length = 50 * tan((1/2): number(rad)),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -30,7 +30,7 @@ units::toDegrees(@num: number(Angle)): number(deg)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 70 * cos(units::toDegrees((PI/4): number(rad))),
|
length = 70 * cos(units::toDegrees((PI/4): number(rad))),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,8 +30,8 @@ units::toRadians(@num: number(Angle)): number(rad)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 70 * cos(units::toRadians(45)),
|
length = 70 * cos(units::toRadians(45deg)),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -30,10 +30,10 @@ getNextAdjacentEdge(@edge: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> angledLine(angle = 120, length = 10)
|
|> angledLine(angle = 120deg, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -30,10 +30,10 @@ getOppositeEdge(@edge: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> angledLine(angle = 120, length = 10)
|
|> angledLine(angle = 120deg, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -30,10 +30,10 @@ getPreviousAdjacentEdge(@edge: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> angledLine(angle = 120, length = 10)
|
|> angledLine(angle = 120deg, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -128,6 +128,9 @@ layout: manual
|
|||||||
* [`E`](/docs/kcl-std/consts/std-math-E)
|
* [`E`](/docs/kcl-std/consts/std-math-E)
|
||||||
* [`PI`](/docs/kcl-std/consts/std-math-PI)
|
* [`PI`](/docs/kcl-std/consts/std-math-PI)
|
||||||
* [`TAU`](/docs/kcl-std/consts/std-math-TAU)
|
* [`TAU`](/docs/kcl-std/consts/std-math-TAU)
|
||||||
|
* [**std::sweep**](/docs/kcl-std/modules/std-sweep)
|
||||||
|
* [`sweep::SKETCH_PLANE`](/docs/kcl-std/consts/std-sweep-SKETCH_PLANE)
|
||||||
|
* [`sweep::TRAJECTORY`](/docs/kcl-std/consts/std-sweep-TRAJECTORY)
|
||||||
* [**std::turns**](/docs/kcl-std/modules/std-turns)
|
* [**std::turns**](/docs/kcl-std/modules/std-turns)
|
||||||
* [`turns::HALF_TURN`](/docs/kcl-std/consts/std-turns-HALF_TURN)
|
* [`turns::HALF_TURN`](/docs/kcl-std/consts/std-turns-HALF_TURN)
|
||||||
* [`turns::QUARTER_TURN`](/docs/kcl-std/consts/std-turns-QUARTER_TURN)
|
* [`turns::QUARTER_TURN`](/docs/kcl-std/consts/std-turns-QUARTER_TURN)
|
||||||
|
@ -43,11 +43,11 @@ a = 10
|
|||||||
b = 14
|
b = 14
|
||||||
startSketchOn(XZ)
|
startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> involuteCircular(startRadius = a, endRadius = b, angle = 60)
|
|> involuteCircular(startRadius = a, endRadius = b, angle = 60deg)
|
||||||
|> involuteCircular(
|
|> involuteCircular(
|
||||||
startRadius = a,
|
startRadius = a,
|
||||||
endRadius = b,
|
endRadius = b,
|
||||||
angle = 60,
|
angle = 60deg,
|
||||||
reverse = true,
|
reverse = true,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
File diff suppressed because one or more lines are too long
17
docs/kcl-std/modules/std-sweep.md
Normal file
17
docs/kcl-std/modules/std-sweep.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
title: "sweep"
|
||||||
|
subtitle: "Module in std"
|
||||||
|
excerpt: ""
|
||||||
|
layout: manual
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Functions and constants
|
||||||
|
|
||||||
|
* [`sweep::SKETCH_PLANE`](/docs/kcl-std/consts/std-sweep-SKETCH_PLANE)
|
||||||
|
* [`sweep::TRAJECTORY`](/docs/kcl-std/consts/std-sweep-TRAJECTORY)
|
||||||
|
|
@ -19,6 +19,7 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui
|
|||||||
* [`math`](/docs/kcl-std/modules/std-math)
|
* [`math`](/docs/kcl-std/modules/std-math)
|
||||||
* [`sketch`](/docs/kcl-std/modules/std-sketch)
|
* [`sketch`](/docs/kcl-std/modules/std-sketch)
|
||||||
* [`solid`](/docs/kcl-std/modules/std-solid)
|
* [`solid`](/docs/kcl-std/modules/std-solid)
|
||||||
|
* [`sweep::sweep`](/docs/kcl-std/modules/std-sweep)
|
||||||
* [`transform`](/docs/kcl-std/modules/std-transform)
|
* [`transform`](/docs/kcl-std/modules/std-transform)
|
||||||
* [`turns::turns`](/docs/kcl-std/modules/std-turns)
|
* [`turns::turns`](/docs/kcl-std/modules/std-turns)
|
||||||
* [`types`](/docs/kcl-std/modules/std-types)
|
* [`types`](/docs/kcl-std/modules/std-types)
|
||||||
|
@ -48,7 +48,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
instances = 13,
|
instances = 13,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ example = extrude(exampleSketch, length = -5)
|
|||||||
axis = [1, -1, 0],
|
axis = [1, -1, 0],
|
||||||
center = [10, -20, 0],
|
center = [10, -20, 0],
|
||||||
instances = 11,
|
instances = 11,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
@ -123,7 +123,7 @@ fn transform(@i) {
|
|||||||
pow(0.9, exp = i)
|
pow(0.9, exp = i)
|
||||||
],
|
],
|
||||||
// Turn by 15 degrees each time.
|
// Turn by 15 degrees each time.
|
||||||
rotation = { angle = 15 * i, origin = "local" }
|
rotation = { angle = 15deg * i, origin = "local" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ fn transform(@i) {
|
|||||||
return {
|
return {
|
||||||
translate = [0, 0, -i * width],
|
translate = [0, 0, -i * width],
|
||||||
rotation = {
|
rotation = {
|
||||||
angle = 90 * i,
|
angle = 90deg * i,
|
||||||
// Rotate around the overall scene's origin.
|
// Rotate around the overall scene's origin.
|
||||||
origin = "global"
|
origin = "global"
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ fn transform(@i) {
|
|||||||
// Transform functions can return multiple transforms. They'll be applied in order.
|
// Transform functions can return multiple transforms. They'll be applied in order.
|
||||||
return [
|
return [
|
||||||
{ translate = [30 * i, 0, 0] },
|
{ translate = [30 * i, 0, 0] },
|
||||||
{ rotation = { angle = 45 * i } }
|
{ rotation = { angle = 45deg * i } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
startSketchOn(XY)
|
startSketchOn(XY)
|
||||||
|
@ -29,8 +29,8 @@ profileStart(@profile: Sketch): [number]
|
|||||||
```kcl
|
```kcl
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
|> startProfile(at = [5, 2])
|
|> startProfile(at = [5, 2])
|
||||||
|> angledLine(angle = 120, length = 50, tag = $seg01)
|
|> angledLine(angle = 120deg, length = 50, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(seg01) + 120, length = 50)
|
|> angledLine(angle = segAng(seg01) + 120deg, length = 50)
|
||||||
|> line(end = profileStart(%))
|
|> line(end = profileStart(%))
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 20)
|
|> extrude(length = 20)
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -29,9 +29,9 @@ segLen(@tag: TagIdentifier): number
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 60, length = 10, tag = $thing)
|
|> angledLine(angle = 60deg, length = 10, tag = $thing)
|
||||||
|> tangentialArc(angle = -120, radius = 5)
|
|> tangentialArc(angle = -120deg, radius = 5)
|
||||||
|> angledLine(angle = -60, length = segLen(thing))
|
|> angledLine(angle = -60deg, length = segLen(thing))
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -146,7 +146,7 @@ exampleSketch = startSketchOn(XY)
|
|||||||
|> line(end = [-2, 0])
|
|> line(end = [-2, 0])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = revolve(exampleSketch, axis = Y, angle = 180)
|
example = revolve(exampleSketch, axis = Y, angle = 180deg)
|
||||||
|
|
||||||
exampleSketch002 = startSketchOn(example, face = END)
|
exampleSketch002 = startSketchOn(example, face = END)
|
||||||
|> startProfile(at = [4.5, -5])
|
|> startProfile(at = [4.5, -5])
|
||||||
@ -178,7 +178,7 @@ exampleSketch = startSketchOn(XY)
|
|||||||
example = revolve(
|
example = revolve(
|
||||||
exampleSketch,
|
exampleSketch,
|
||||||
axis = Y,
|
axis = Y,
|
||||||
angle = 180,
|
angle = 180deg,
|
||||||
tagEnd = $end01,
|
tagEnd = $end01,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -41,7 +41,7 @@ When using radius and angle, draw a curved line segment along part of an imagina
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 45, length = 10)
|
|> angledLine(angle = 45deg, length = 10)
|
||||||
|> tangentialArc(end = [0, -10])
|
|> tangentialArc(end = [0, -10])
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> close()
|
|> close()
|
||||||
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 10)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> tangentialArc(endAbsolute = [15, 15])
|
|> tangentialArc(endAbsolute = [15, 15])
|
||||||
|> line(end = [10, -15])
|
|> line(end = [10, -15])
|
||||||
|> close()
|
|> close()
|
||||||
@ -67,9 +67,9 @@ example = extrude(exampleSketch, length = 10)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> tangentialArc(radius = 10, angle = -120)
|
|> tangentialArc(radius = 10, angle = -120deg)
|
||||||
|> angledLine(angle = -60, length = 10)
|
|> angledLine(angle = -60deg, length = 10)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -15,9 +15,9 @@ way:
|
|||||||
```js
|
```js
|
||||||
startSketchOn(XZ)
|
startSketchOn(XZ)
|
||||||
|> startProfile(at = origin)
|
|> startProfile(at = origin)
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
length = 196.99,
|
length = 196.99,
|
||||||
tag = $rectangleSegmentB001,
|
tag = $rectangleSegmentB001,
|
||||||
)
|
)
|
||||||
@ -49,9 +49,9 @@ However if the code was written like this:
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn(XZ)
|
return startSketchOn(XZ)
|
||||||
|> startProfile(at = origin)
|
|> startProfile(at = origin)
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
length = 196.99,
|
length = 196.99,
|
||||||
tag = $rectangleSegmentB001)
|
tag = $rectangleSegmentB001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
@ -78,9 +78,9 @@ For example the following code works.
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn(XZ)
|
return startSketchOn(XZ)
|
||||||
|> startProfile(at = origin)
|
|> startProfile(at = origin)
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
length = 196.99
|
length = 196.99
|
||||||
tag = $rectangleSegmentB001,
|
tag = $rectangleSegmentB001,
|
||||||
)
|
)
|
||||||
|
@ -38,10 +38,10 @@ xLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> xLine(length = 15)
|
|> xLine(length = 15)
|
||||||
|> angledLine(angle = 80, length = 15)
|
|> angledLine(angle = 80deg, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> xLine(length = 10)
|
|> xLine(length = 10)
|
||||||
|> angledLine(angle = 120, length = 30)
|
|> angledLine(angle = 120deg, length = 30)
|
||||||
|> xLine(length = -15)
|
|> xLine(length = -15)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ yLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> yLine(length = 15)
|
|> yLine(length = 15)
|
||||||
|> angledLine(angle = 30, length = 15)
|
|> angledLine(angle = 30deg, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> yLine(length = -5)
|
|> yLine(length = -5)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -134,8 +134,6 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
await expect(codePaneButtonHolder).toContainText('notification', {
|
await expect(codePaneButtonHolder).toContainText('notification', {
|
||||||
@ -158,10 +156,14 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
await expect(
|
await expect(
|
||||||
page
|
page
|
||||||
.getByText(
|
.getByText(
|
||||||
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
'Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis'
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
|
// Make sure ApiError is not on the page.
|
||||||
|
// This ensures we didn't nest the json
|
||||||
|
await expect(page.getByText('ApiError')).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
||||||
@ -179,7 +181,7 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await scene.settled(cmdBar)
|
// await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
|
@ -58,12 +58,6 @@ test(
|
|||||||
await expect(submitButton).toBeVisible()
|
await expect(submitButton).toBeVisible()
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Look out for the toast message
|
|
||||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
|
||||||
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
await expect(alreadyExportingToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
// Expect it to succeed
|
// Expect it to succeed
|
||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
||||||
@ -72,7 +66,6 @@ test(
|
|||||||
|
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
const successToastMessage = page.getByText(`Exported successfully`)
|
||||||
await expect(successToastMessage).toBeVisible()
|
await expect(successToastMessage).toBeVisible()
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
// Check for the exported file
|
// Check for the exported file
|
||||||
const firstFileFullPath = path.resolve(
|
const firstFileFullPath = path.resolve(
|
||||||
|
@ -912,7 +912,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
|> close()
|
|> close()
|
||||||
|> revolve(
|
|> revolve(
|
||||||
axis = revolveAxis,
|
axis = revolveAxis,
|
||||||
angle = 90
|
angle = 90deg
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -1533,7 +1533,6 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await scene.expectPixelColor(
|
await scene.expectPixelColor(
|
||||||
TEST_COLORS.DARK_MODE_BKGD,
|
TEST_COLORS.DARK_MODE_BKGD,
|
||||||
|
@ -38,7 +38,7 @@ extrude001 = extrude(sketch002, length = 10)
|
|||||||
|
|
||||||
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 0, length = 4, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2, 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(%)])
|
||||||
|
@ -155,6 +155,12 @@ export class CmdBarFixture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeCmdBar = async () => {
|
||||||
|
const cmdBarCloseBtn = this.page.getByTestId('command-bar-close-button')
|
||||||
|
await cmdBarCloseBtn.click()
|
||||||
|
await expect(this.cmdBarElement).not.toBeVisible()
|
||||||
|
}
|
||||||
|
|
||||||
get cmdSearchInput() {
|
get cmdSearchInput() {
|
||||||
return this.page.getByTestId('cmd-bar-search')
|
return this.page.getByTestId('cmd-bar-search')
|
||||||
}
|
}
|
||||||
@ -298,4 +304,27 @@ export class CmdBarFixture {
|
|||||||
`Monitoring text-to-cad API requests. Output will be saved to: ${outputPath}`
|
`Monitoring text-to-cad API requests. Output will be saved to: ${outputPath}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async toBeOpened() {
|
||||||
|
// Check that the command bar is opened
|
||||||
|
await expect(this.cmdBarElement).toBeVisible({ timeout: 10_000 })
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectArgValue(value: string) {
|
||||||
|
// Check the placeholder project name exists
|
||||||
|
const actualArgument = await this.cmdBarElement
|
||||||
|
.getByTestId('cmd-bar-arg-value')
|
||||||
|
.inputValue()
|
||||||
|
const expectedArgument = value
|
||||||
|
expect(actualArgument).toBe(expectedArgument)
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectCommandName(value: string) {
|
||||||
|
// Check the placeholder project name exists
|
||||||
|
const actual = await this.cmdBarElement
|
||||||
|
.getByTestId('command-name')
|
||||||
|
.textContent()
|
||||||
|
const expected = value
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ export class HomePageFixture {
|
|||||||
projectTextName!: Locator
|
projectTextName!: Locator
|
||||||
sortByDateBtn!: Locator
|
sortByDateBtn!: Locator
|
||||||
sortByNameBtn!: Locator
|
sortByNameBtn!: Locator
|
||||||
|
appHeader!: Locator
|
||||||
tutorialBtn!: Locator
|
tutorialBtn!: Locator
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
@ -44,6 +45,7 @@ export class HomePageFixture {
|
|||||||
|
|
||||||
this.sortByDateBtn = this.page.getByTestId('home-sort-by-modified')
|
this.sortByDateBtn = this.page.getByTestId('home-sort-by-modified')
|
||||||
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
|
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
|
||||||
|
this.appHeader = this.page.getByTestId('app-header')
|
||||||
this.tutorialBtn = this.page.getByTestId('home-tutorial-button')
|
this.tutorialBtn = this.page.getByTestId('home-tutorial-button')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,4 +127,11 @@ export class HomePageFixture {
|
|||||||
|
|
||||||
await this.createAndGoToProject(name)
|
await this.createAndGoToProject(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isNativeFileMenuCreated = async () => {
|
||||||
|
await expect(this.appHeader).toHaveAttribute(
|
||||||
|
'data-native-file-menu',
|
||||||
|
'true'
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ export class SceneFixture {
|
|||||||
public networkToggleConnected!: Locator
|
public networkToggleConnected!: Locator
|
||||||
public engineConnectionsSpinner!: Locator
|
public engineConnectionsSpinner!: Locator
|
||||||
public startEditSketchBtn!: Locator
|
public startEditSketchBtn!: Locator
|
||||||
|
public appHeader!: Locator
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page
|
this.page = page
|
||||||
@ -57,6 +58,7 @@ export class SceneFixture {
|
|||||||
this.startEditSketchBtn = page
|
this.startEditSketchBtn = page
|
||||||
.getByRole('button', { name: 'Start Sketch' })
|
.getByRole('button', { name: 'Start Sketch' })
|
||||||
.or(page.getByRole('button', { name: 'Edit Sketch' }))
|
.or(page.getByRole('button', { name: 'Edit Sketch' }))
|
||||||
|
this.appHeader = this.page.getByTestId('app-header')
|
||||||
}
|
}
|
||||||
private _serialiseScene = async (): Promise<SceneSerialised> => {
|
private _serialiseScene = async (): Promise<SceneSerialised> => {
|
||||||
const camera = await this.getCameraInfo()
|
const camera = await this.getCameraInfo()
|
||||||
@ -280,6 +282,13 @@ export class SceneFixture {
|
|||||||
await expect(buttonToTest).toBeVisible()
|
await expect(buttonToTest).toBeVisible()
|
||||||
await buttonToTest.click()
|
await buttonToTest.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isNativeFileMenuCreated = async () => {
|
||||||
|
await expect(this.appHeader).toHaveAttribute(
|
||||||
|
'data-native-file-menu',
|
||||||
|
'true'
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isColourArray(
|
function isColourArray(
|
||||||
|
@ -16,7 +16,7 @@ test.describe('Import UI tests', () => {
|
|||||||
path.join(projectDir, 'toBeImported.kcl'),
|
path.join(projectDir, 'toBeImported.kcl'),
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfile(sketch001, at = [281.54, 305.81])
|
profile001 = startProfile(sketch001, at = [281.54, 305.81])
|
||||||
|> angledLine(angle = 0, length = 123.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 123.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -33,7 +33,7 @@ importedCube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfile(sketch001, at = [-134.53, -56.17])
|
profile001 = startProfile(sketch001, at = [-134.53, -56.17])
|
||||||
|> angledLine(angle = 0, length = 79.05, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 79.05, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -365,7 +365,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
clickCoords: { x: 677, y: 87 },
|
clickCoords: { x: 677, y: 87 },
|
||||||
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
||||||
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
||||||
beforeChamferSnippet: `angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)chamfer(
|
beforeChamferSnippet: `angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)chamfer(
|
||||||
length = 30,
|
length = 30,
|
||||||
tags = [
|
tags = [
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
@ -407,7 +407,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|
||||||
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
@ -419,28 +419,28 @@ extrude001 = extrude(sketch001, length = 100)
|
|||||||
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg03)
|
sketch002 = startSketchOn(extrude001, face = seg03)
|
||||||
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
||||||
|> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = 11.39, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch003 = startSketchOn(extrude001, face = seg04)
|
sketch003 = startSketchOn(extrude001, face = seg04)
|
||||||
profile002 = startProfile(sketch003, at = [-209.64, 255.28])
|
profile002 = startProfile(sketch003, at = [-209.64, 255.28])
|
||||||
|> angledLine(angle = 0, length = 11.56, tag = $rectangleSegmentA003)
|
|> angledLine(angle = 0deg, length = 11.56, tag = $rectangleSegmentA003)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003) - 90, length = 106.84)
|
|> angledLine(angle = segAng(rectangleSegmentA003) - 90, length = 106.84)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch004 = startSketchOn(extrude001, face = seg05)
|
sketch004 = startSketchOn(extrude001, face = seg05)
|
||||||
profile003 = startProfile(sketch004, at = [82.57, 322.96])
|
profile003 = startProfile(sketch004, at = [82.57, 322.96])
|
||||||
|> angledLine(angle = 0, length = 11.16, tag = $rectangleSegmentA004)
|
|> angledLine(angle = 0deg, length = 11.16, tag = $rectangleSegmentA004)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07)
|
|> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch005 = startSketchOn(extrude001, face = seg06)
|
sketch005 = startSketchOn(extrude001, face = seg06)
|
||||||
profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
||||||
|> angledLine(angle = 0, length = 9.1, tag = $rectangleSegmentA005)
|
|> angledLine(angle = 0deg, length = 9.1, tag = $rectangleSegmentA005)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07)
|
|> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005))
|
|> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -504,7 +504,7 @@ profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
|||||||
`@settings(defaultLengthUnit = in)
|
`@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [75.8, 317.2])
|
|> startProfile(at = [75.8, 317.2])
|
||||||
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
@ -526,7 +526,7 @@ chamf = chamfer(
|
|||||||
)
|
)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg03)
|
sketch002 = startSketchOn(extrude001, face = seg03)
|
||||||
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
||||||
|> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = 11.39, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -1776,7 +1776,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
initialCode: `@settings(defaultLengthUnit = in)
|
initialCode: `@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(YZ)
|
sketch001 = startSketchOn(YZ)
|
||||||
profile001 = startProfile(sketch001, at = [-400, -400])
|
profile001 = startProfile(sketch001, at = [-400, -400])
|
||||||
|> angledLine(angle = 0, length = 800, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 800, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 800)
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 800)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -1931,50 +1931,37 @@ sketch002 = startSketchOn(XZ)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`Sweep point-and-click failing validation`, async ({
|
test(`Sweep point-and-click helix`, async ({
|
||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
|
editor,
|
||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const initialCode = `@settings(defaultLengthUnit = in)
|
const circleCode = `circle(sketch001, center = [0, -1], radius = .1)`
|
||||||
sketch001 = startSketchOn(YZ)
|
const initialCode = `helix001 = helix(
|
||||||
|> circle(
|
axis = X,
|
||||||
center = [0, 0],
|
radius = 1,
|
||||||
radius = 500
|
length = 10,
|
||||||
)
|
revolutions = 10,
|
||||||
sketch002 = startSketchOn(XZ)
|
angleStart = 0,
|
||||||
|> startProfile(at = [0, 0])
|
ccw = false,
|
||||||
|> xLine(length = -500)
|
)
|
||||||
|> line(endAbsolute = [-2000, 500])
|
sketch001 = startSketchOn(XZ)
|
||||||
`
|
profile001 = ${circleCode}`
|
||||||
|
const sweepDeclaration = 'sweep001 = sweep(profile001, path = helix001)'
|
||||||
|
|
||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
localStorage.setItem('persistCode', initialCode)
|
localStorage.setItem('persistCode', initialCode)
|
||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
await test.step(`Add sweep through the command bar flow`, async () => {
|
||||||
const testPoint = { x: 700, y: 250 }
|
await toolbar.openPane('feature-tree')
|
||||||
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
|
||||||
const [clickOnSketch2] = scene.makeMouseHelpers(
|
|
||||||
testPoint.x - 50,
|
|
||||||
testPoint.y
|
|
||||||
)
|
|
||||||
|
|
||||||
await test.step(`Look for sketch001`, async () => {
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
await scene.expectPixelColor([53, 53, 53], testPoint, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step(`Go through the command bar flow and fail validation with a toast`, async () => {
|
|
||||||
await toolbar.sweepButton.click()
|
await toolbar.sweepButton.click()
|
||||||
await expect
|
|
||||||
.poll(() => page.getByText('Please select one').count())
|
|
||||||
.toBe(1)
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
currentArgKey: 'sketches',
|
currentArgKey: 'sketches',
|
||||||
@ -1987,7 +1974,8 @@ sketch002 = startSketchOn(XZ)
|
|||||||
highlightedHeaderArg: 'sketches',
|
highlightedHeaderArg: 'sketches',
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
await clickOnSketch1()
|
await editor.scrollToText(circleCode)
|
||||||
|
await page.getByText(circleCode).click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
@ -2001,11 +1989,39 @@ sketch002 = startSketchOn(XZ)
|
|||||||
highlightedHeaderArg: 'path',
|
highlightedHeaderArg: 'path',
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
await clickOnSketch2()
|
const helix = await toolbar.getFeatureTreeOperation('Helix', 0)
|
||||||
|
await helix.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Sweep',
|
||||||
|
currentArgKey: 'path',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Sectional: '',
|
||||||
|
Sketches: '1 face',
|
||||||
|
Path: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'path',
|
||||||
|
stage: 'arguments',
|
||||||
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await expect(
|
await cmdBar.expectState({
|
||||||
page.getByText('Unable to sweep with the current selection. Reason:')
|
commandName: 'Sweep',
|
||||||
).toBeVisible()
|
headerArguments: {
|
||||||
|
Sketches: '1 face',
|
||||||
|
Path: '1 helix',
|
||||||
|
Sectional: '',
|
||||||
|
},
|
||||||
|
stage: 'review',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await editor.expectEditor.toContain(sweepDeclaration)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Delete sweep via feature tree selection', async () => {
|
||||||
|
const sweep = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
||||||
|
await sweep.click()
|
||||||
|
await page.keyboard.press('Delete')
|
||||||
|
await editor.expectEditor.not.toContain(sweepDeclaration)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3627,67 +3643,6 @@ profile001 = startProfile(sketch001, at = [-20, 20])
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`Shell dry-run validation rejects sweeps`, async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
const initialCode = `sketch001 = startSketchOn(YZ)
|
|
||||||
|> circle(
|
|
||||||
center = [0, 0],
|
|
||||||
radius = 500
|
|
||||||
)
|
|
||||||
sketch002 = startSketchOn(XZ)
|
|
||||||
|> startProfile(at = [0, 0])
|
|
||||||
|> xLine(length = -2000)
|
|
||||||
sweep001 = sweep(sketch001, path = sketch002)
|
|
||||||
`
|
|
||||||
await context.addInitScript((initialCode) => {
|
|
||||||
localStorage.setItem('persistCode', initialCode)
|
|
||||||
}, initialCode)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
|
||||||
const testPoint = { x: 500, y: 250 }
|
|
||||||
const [clickOnSweep] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
|
||||||
|
|
||||||
await test.step(`Confirm sweep exists`, async () => {
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
await scene.expectPixelColor([231, 231, 231], testPoint, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step(`Go through the Shell flow and fail validation with a toast`, async () => {
|
|
||||||
await toolbar.shellButton.click()
|
|
||||||
await expect
|
|
||||||
.poll(() => page.getByText('Please select one').count())
|
|
||||||
.toBe(1)
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'selection',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '',
|
|
||||||
Thickness: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'selection',
|
|
||||||
commandName: 'Shell',
|
|
||||||
})
|
|
||||||
await clickOnSweep()
|
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await expect(
|
|
||||||
page.getByText('Unable to shell with the current selection. Reason:')
|
|
||||||
).toBeVisible()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test.describe('Revolve point and click workflows', () => {
|
test.describe('Revolve point and click workflows', () => {
|
||||||
test('Base case workflow, auto spam continue in command bar', async ({
|
test('Base case workflow, auto spam continue in command bar', async ({
|
||||||
context,
|
context,
|
||||||
@ -3701,7 +3656,7 @@ sweep001 = sweep(sketch001, path = sketch002)
|
|||||||
const initialCode = `
|
const initialCode = `
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-100.0, 100.0])
|
|> startProfile(at = [-100.0, 100.0])
|
||||||
|> angledLine(angle = 0, length = 200.0, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 200.0, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 200, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 200, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle=segAng(rectangleSegmentA001),
|
angle=segAng(rectangleSegmentA001),
|
||||||
@ -3713,7 +3668,7 @@ tag=$rectangleSegmentC001,
|
|||||||
extrude001 = extrude(sketch001, length = 200)
|
extrude001 = extrude(sketch001, length = 200)
|
||||||
sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||||
|> startProfile(at = [-66.77, 84.81])
|
|> startProfile(at = [-66.77, 84.81])
|
||||||
|> angledLine(angle = 180, length = 27.08, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 180deg, length = 27.08, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle=segAng(rectangleSegmentA002) - 90,
|
angle=segAng(rectangleSegmentA002) - 90,
|
||||||
length=27.8,
|
length=27.8,
|
||||||
@ -3747,7 +3702,7 @@ tag=$rectangleSegmentC002,
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
|
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360deg, axis = X)`
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
@ -3780,7 +3735,7 @@ tag=$rectangleSegmentC002,
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = ' + newAngle)
|
newCodeToFind.replace('angle = 360deg', 'angle = ' + newAngle)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
test('revolve surface around edge from an extruded solid2d', async ({
|
test('revolve surface around edge from an extruded solid2d', async ({
|
||||||
@ -3794,7 +3749,7 @@ tag=$rectangleSegmentC002,
|
|||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-102.57, 101.72])
|
|> startProfile(at = [-102.57, 101.72])
|
||||||
|> angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 202.6, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 202.6, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 202.6, 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(%)])
|
||||||
@ -3820,13 +3775,13 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.getByText('Edge', { exact: true }).click()
|
await page.getByText('Edge', { exact: true }).click()
|
||||||
const lineCodeToSelection = `angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)`
|
const lineCodeToSelection = `angledLine(angle = 0deg, length = 202.6, tag = $rectangleSegmentA001)`
|
||||||
await page.getByText(lineCodeToSelection).click()
|
await page.getByText(lineCodeToSelection).click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = rectangleSegmentA001)`
|
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360deg, axis = rectangleSegmentA001)`
|
||||||
await editor.expectEditor.toContain(newCodeToFind)
|
await editor.expectEditor.toContain(newCodeToFind)
|
||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
@ -3864,7 +3819,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain('angle001 = ' + newAngle)
|
await editor.expectEditor.toContain('angle001 = ' + newAngle)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = angle001')
|
newCodeToFind.replace('angle = 360deg', 'angle = angle001')
|
||||||
)
|
)
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
})
|
})
|
||||||
@ -3883,7 +3838,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
|> xLine(length = 2.6)
|
|> xLine(length = 2.6)
|
||||||
sketch001 = startSketchOn(-XY)
|
sketch001 = startSketchOn(-XY)
|
||||||
|> startProfile(at = [-0.48, 1.25])
|
|> startProfile(at = [-0.48, 1.25])
|
||||||
|> angledLine(angle = 0, length = 2.38, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 2.38, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.4, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.4, 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(%)])
|
||||||
@ -3921,7 +3876,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch003, angle = 360, axis = seg01)`
|
const newCodeToFind = `revolve001 = revolve(sketch003, angle = 360deg, axis = seg01)`
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
@ -3954,7 +3909,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = ' + newAngle)
|
newCodeToFind.replace('angle = 360deg', 'angle = ' + newAngle)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -4938,9 +4893,39 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await page.getByTestId('context-menu-delete').click()
|
await page.getByTestId('context-menu-delete').click()
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
await editor.expectEditor.not.toContain(
|
await editor.expectEditor.not.toContain(
|
||||||
`revolve001 = revolve([profile001, profile002], axis = XY, angle = 180)`,
|
`revolve001 = revolve([profile001, profile002], axis = XY, angle = 180deg)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test(`Point and click codemods can't run on KCL errors`, async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const badCode = `sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = circle(sketch001, center = [0, 0], radius = 1)
|
||||||
|
extrude001 = extrude(profile001 length = 1)`
|
||||||
|
await context.addInitScript((initialCode) => {
|
||||||
|
localStorage.setItem('persistCode', initialCode)
|
||||||
|
}, badCode)
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
|
await test.step(`Start Sketch is disabled`, async () => {
|
||||||
|
await expect(toolbar.startSketchBtn).not.toBeEnabled()
|
||||||
|
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Helix is disabled`, async () => {
|
||||||
|
await expect(toolbar.helixButton).not.toBeEnabled()
|
||||||
|
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1818,7 +1818,6 @@ test(
|
|||||||
'extrude-custom-plane.kcl',
|
'extrude-custom-plane.kcl',
|
||||||
'extrude-inside-fn-with-tags.kcl',
|
'extrude-inside-fn-with-tags.kcl',
|
||||||
'fillet-and-shell.kcl',
|
'fillet-and-shell.kcl',
|
||||||
'fillet_duplicate_tags.kcl',
|
|
||||||
'focusrite_scarlett_mounting_bracket.kcl',
|
'focusrite_scarlett_mounting_bracket.kcl',
|
||||||
'function_sketch.kcl',
|
'function_sketch.kcl',
|
||||||
'function_sketch_with_position.kcl',
|
'function_sketch_with_position.kcl',
|
||||||
@ -1826,7 +1825,6 @@ test(
|
|||||||
'helix_defaults.kcl',
|
'helix_defaults.kcl',
|
||||||
'helix_defaults_negative_extrude.kcl',
|
'helix_defaults_negative_extrude.kcl',
|
||||||
'helix_with_length.kcl',
|
'helix_with_length.kcl',
|
||||||
'i_shape.kcl',
|
|
||||||
'kittycad_svg.kcl',
|
'kittycad_svg.kcl',
|
||||||
'lego.kcl',
|
'lego.kcl',
|
||||||
'lsystem.kcl',
|
'lsystem.kcl',
|
||||||
|
@ -47,7 +47,7 @@ b
|
|||||||
|
|
||||||
const importedFile = `sketch003 = startSketchOn(XY)
|
const importedFile = `sketch003 = startSketchOn(XY)
|
||||||
|> startProfile(at = [52.92, 157.81])
|
|> startProfile(at = [52.92, 157.81])
|
||||||
|> angledLine(angle = 0, length = 176.4, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 176.4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 53.4,
|
length = 53.4,
|
||||||
|
@ -23,7 +23,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
extrude002 = extrude(sketch002, length = 50)
|
extrude002 = extrude(sketch002, length = 50)
|
||||||
sketch003 = startSketchOn(XY)
|
sketch003 = startSketchOn(XY)
|
||||||
|> startProfile(at = [52.92, 157.81])
|
|> startProfile(at = [52.92, 157.81])
|
||||||
|> angledLine(angle = 0, length = 176.4, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 176.4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 53.4, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 53.4, 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(%)])
|
||||||
|
@ -19,11 +19,12 @@ test.describe('Regression tests', () => {
|
|||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
// because the model has `line([0,0]..` it is valid code, but the model is invalid
|
// because the model has `line([0,0]..` it is valid code, but the model is invalid
|
||||||
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
|
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
|
||||||
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
|
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
|
||||||
const u = await getUtils(page)
|
// const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
@ -40,7 +41,8 @@ test.describe('Regression tests', () => {
|
|||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await scene.connectionEstablished()
|
||||||
|
// await u.waitForPageLoad()
|
||||||
|
|
||||||
// error in guter
|
// error in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
@ -51,8 +53,11 @@ test.describe('Regression tests', () => {
|
|||||||
// the close doesn't work
|
// the close doesn't work
|
||||||
// when https://github.com/KittyCAD/modeling-app/issues/3268 is closed
|
// when https://github.com/KittyCAD/modeling-app/issues/3268 is closed
|
||||||
// this test will need updating
|
// this test will need updating
|
||||||
const crypticErrorText = `ApiError`
|
const crypticErrorText = `Cannot close a path that is non-planar or with duplicate vertices.
|
||||||
|
Internal engine error on request`
|
||||||
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
|
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
|
||||||
|
// Ensure we didn't nest the json.
|
||||||
|
await expect(page.getByText('ApiError')).not.toBeVisible()
|
||||||
})
|
})
|
||||||
test('user should not have to press down twice in cmdbar', async ({
|
test('user should not have to press down twice in cmdbar', async ({
|
||||||
page,
|
page,
|
||||||
@ -67,7 +72,7 @@ test.describe('Regression tests', () => {
|
|||||||
'persistCode',
|
'persistCode',
|
||||||
`sketch001 = startSketchOn(XY)
|
`sketch001 = startSketchOn(XY)
|
||||||
|> startProfile(at = [82.33, 238.21])
|
|> startProfile(at = [82.33, 238.21])
|
||||||
|> angledLine(angle = 0, length = 288.63, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 288.63, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 197.97, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 197.97, 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(%)])
|
||||||
@ -185,8 +190,8 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
page.locator('.pretty-json-container >> text=myVar:"67')
|
page.locator('.pretty-json-container >> text=myVar:"67')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
test('ProgramMemory can be serialised', async ({ page, homePage }) => {
|
test('ProgramMemory can be serialised', async ({ page, homePage, scene }) => {
|
||||||
const u = await getUtils(page)
|
// const u = await getUtils(page)
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
@ -211,11 +216,12 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
// Listen for all console events and push the message text to an array
|
// Listen for all console events and push the message text to an array
|
||||||
page.on('console', (message) => messages.push(message.text()))
|
page.on('console', (message) => messages.push(message.text()))
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
// await u.waitForPageLoad()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// wait for execution done
|
// wait for execution done
|
||||||
await u.openDebugPanel()
|
// await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
// await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
const forbiddenMessages = ['cannot serialize tagged newtype variant']
|
const forbiddenMessages = ['cannot serialize tagged newtype variant']
|
||||||
forbiddenMessages.forEach((forbiddenMessage) => {
|
forbiddenMessages.forEach((forbiddenMessage) => {
|
||||||
@ -229,6 +235,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -238,7 +245,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
'persistCode',
|
'persistCode',
|
||||||
`exampleSketch = startSketchOn(XZ)
|
`exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 50, length = 45 )
|
|> angledLine(angle = 50deg, length = 45 )
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|>
|
|>
|
||||||
@ -247,11 +254,10 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
await expect(async () => {
|
await expect(async () => {
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
|
|
||||||
// error in guter
|
// error in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||||
timeout: 1_000,
|
timeout: 1_000,
|
||||||
@ -295,7 +301,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
page.locator('.cm-content')
|
page.locator('.cm-content')
|
||||||
).toContainText(`exampleSketch = startSketchOn(XZ)
|
).toContainText(`exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 50, length = 45 )
|
|> angledLine(angle = 50deg, length = 45 )
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
@ -315,7 +321,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
`@settings(defaultLengthUnit = mm)
|
`@settings(defaultLengthUnit = mm)
|
||||||
sketch002 = startSketchOn(XY)
|
sketch002 = startSketchOn(XY)
|
||||||
profile002 = startProfile(sketch002, at = [72.24, -52.05])
|
profile002 = startProfile(sketch002, at = [72.24, -52.05])
|
||||||
|> angledLine(angle = 0, length = 181.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 181.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -329,10 +335,10 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
)
|
)
|
||||||
|
|
||||||
const websocketPromise = page.waitForEvent('websocket')
|
const websocketPromise = page.waitForEvent('websocket')
|
||||||
await toolbar.closePane('code')
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await toolbar.closePane('code')
|
||||||
const websocket = await websocketPromise
|
const websocket = await websocketPromise
|
||||||
|
|
||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
@ -545,14 +551,15 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
expect(alreadyExportingToastMessage).not.toBeVisible(),
|
expect(alreadyExportingToastMessage).not.toBeVisible(),
|
||||||
])
|
])
|
||||||
|
|
||||||
await expect(successToastMessage).toHaveCount(2)
|
const count = await successToastMessage.count()
|
||||||
|
await expect(count).toBeGreaterThanOrEqual(2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
test(
|
||||||
`Network health indicator only appears in modeling view`,
|
`Network health indicator only appears in modeling view`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = path.join(dir, 'bracket')
|
const bracketDir = path.join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -561,9 +568,7 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
path.join(bracketDir, 'main.kcl')
|
path.join(bracketDir, 'main.kcl')
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
const u = await getUtils(page)
|
|
||||||
|
|
||||||
// Locators
|
// Locators
|
||||||
const projectsHeading = page.getByRole('heading', {
|
const projectsHeading = page.getByRole('heading', {
|
||||||
@ -583,10 +588,8 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Check the modeling view', async () => {
|
await test.step('Check the modeling view', async () => {
|
||||||
|
await expect(projectsHeading).not.toBeVisible()
|
||||||
await expect(networkHealthIndicator).toBeVisible()
|
await expect(networkHealthIndicator).toBeVisible()
|
||||||
await expect(networkHealthIndicator).toContainText('Problem')
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
await expect(networkHealthIndicator).toContainText('Connected')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -1222,7 +1222,7 @@ profile001 = startProfile(sketch001, at = [299.72, 230.82])
|
|||||||
fn lug(origin, length, diameter, plane) {
|
fn lug(origin, length, diameter, plane) {
|
||||||
lugSketch = startSketchOn(plane)
|
lugSketch = startSketchOn(plane)
|
||||||
|> startProfile(at = [origin[0] + lugDiameter / 2, origin[1]])
|
|> startProfile(at = [origin[0] + lugDiameter / 2, origin[1]])
|
||||||
|> angledLine(angle = 60, lengthY = lugHeadLength)
|
|> angledLine(angle = 60deg, lengthY = lugHeadLength)
|
||||||
|> xLine(endAbsolute = 0 + .001)
|
|> xLine(endAbsolute = 0 + .001)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
@ -1287,7 +1287,7 @@ extrude001 = extrude(profile001, length = 200)
|
|||||||
|> translate(x = 3.14, y = 3.14, z = -50.154)
|
|> translate(x = 3.14, y = 3.14, z = -50.154)
|
||||||
sketch002 = startSketchOn(XY)
|
sketch002 = startSketchOn(XY)
|
||||||
profile002 = startProfile(sketch002, at = [72.2, -52.05])
|
profile002 = startProfile(sketch002, at = [72.2, -52.05])
|
||||||
|> angledLine(angle = 0, length = 181.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 181.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $mySeg)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $mySeg)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
||||||
@ -1365,18 +1365,18 @@ solid001 = subtract([extrude001], tools = [extrude002])
|
|||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
`fn in2mm = (inches) => {
|
`fn in2mm(@inches) {
|
||||||
return inches * 25.4
|
return inches * 25.4
|
||||||
}
|
}
|
||||||
|
|
||||||
const railTop = in2mm(.748)
|
railTop = in2mm(.748)
|
||||||
const railSide = in2mm(.024)
|
railSide = in2mm(.024)
|
||||||
const railBaseWidth = in2mm(.612)
|
railBaseWidth = in2mm(.612)
|
||||||
const railWideWidth = in2mm(.835)
|
railWideWidth = in2mm(.835)
|
||||||
const railBaseLength = in2mm(.200)
|
railBaseLength = in2mm(.200)
|
||||||
const railClampable = in2mm(.200)
|
railClampable = in2mm(.200)
|
||||||
|
|
||||||
const rail = startSketchOn(XZ)
|
rail = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-railTop / 2, railClampable + railBaseLength])
|
|> startProfile(at = [-railTop / 2, railClampable + railBaseLength])
|
||||||
|> line(endAbsolute = [
|
|> line(endAbsolute = [
|
||||||
railTop / 2,
|
railTop / 2,
|
||||||
@ -2058,7 +2058,7 @@ 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) - 90, 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(%)])
|
||||||
@ -2073,7 +2073,7 @@ 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) - 90, 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(%)])
|
||||||
@ -2092,7 +2092,7 @@ 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) + 90, 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(%)])
|
||||||
@ -2108,7 +2108,7 @@ 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) + 90, 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(%)])
|
||||||
@ -2258,7 +2258,7 @@ 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) - 90, 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(%)])
|
||||||
@ -2370,7 +2370,7 @@ 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) + 90, 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(%)])
|
||||||
@ -2396,7 +2396,7 @@ 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) - 90, 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(%)])
|
||||||
@ -2501,7 +2501,7 @@ profile001 = startProfile(sketch001, at = [-63.43, 193.08])
|
|||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
profile003 = startProfile(sketch001, at = [16.79, 38.24])
|
profile003 = startProfile(sketch001, at = [16.79, 38.24])
|
||||||
|> angledLine(angle = 0, length = 182.82, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 182.82, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 105.71)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 105.71)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2726,7 +2726,7 @@ 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) - 90, 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(%)])
|
||||||
@ -2744,7 +2744,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)
|
||||||
@ -2768,14 +2768,14 @@ 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) - 90, 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()
|
||||||
extrude003 = extrude(profile011, length = 2.5)
|
extrude003 = extrude(profile011, length = 2.5)
|
||||||
// TODO this breaks the test,
|
// TODO this breaks the test,
|
||||||
// revolve002 = revolve(profile008, angle = 45, axis = seg02)
|
// revolve002 = revolve(profile008, angle = 45deg, axis = seg02)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -2921,7 +2921,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 ({
|
||||||
@ -2990,7 +2990,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)
|
||||||
})
|
})
|
||||||
@ -3212,7 +3212,7 @@ 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 = -28)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151,
|
||||||
@ -3348,7 +3348,7 @@ 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 = -56)
|
||||||
|> angledLine(angle = -151, length = 116.27)
|
|> angledLine(angle = -151, length = 116.27)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -3387,7 +3387,7 @@ 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 = -28)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151,
|
||||||
@ -3496,6 +3496,69 @@ profile001 = startProfile(sketch001, at = [-102.72, 237.44])
|
|||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Ensure feature tree is not showing previous file's content when switching to a file with KCL errors.
|
||||||
|
test('Feature tree shows correct sketch count per file', async ({
|
||||||
|
context,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
// Setup project with files.
|
||||||
|
const GOOD_KCL = `sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = startProfile(sketch001, at = [220.81, 253.8])
|
||||||
|
|> line(end = [132.84, -151.31])
|
||||||
|
|> line(end = [25.51, 167.15])
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
sketch002 = startSketchOn(XZ)
|
||||||
|
profile002 = startProfile(sketch002, at = [158.35, -70.82])
|
||||||
|
|> line(end = [73.9, -152.19])
|
||||||
|
|> line(end = [85.33, 135.48])
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()`
|
||||||
|
|
||||||
|
const ERROR_KCL = `sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = startProfile(sketch001, at = [127.56, 179.02])
|
||||||
|
|> line(end = [132.84, -112.6])
|
||||||
|
|> line(end = [85.33, 234.01])
|
||||||
|
|> line(enfd = [-137.23, -54.55])`
|
||||||
|
|
||||||
|
await context.folderSetupFn(async (dir) => {
|
||||||
|
const projectDir = path.join(dir, 'multi-file-sketch-test')
|
||||||
|
await fs.mkdir(projectDir, { recursive: true })
|
||||||
|
await Promise.all([
|
||||||
|
fs.writeFile(path.join(projectDir, 'good.kcl'), GOOD_KCL, 'utf-8'),
|
||||||
|
fs.writeFile(path.join(projectDir, 'error.kcl'), ERROR_KCL, 'utf-8'),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 800 })
|
||||||
|
|
||||||
|
await homePage.openProject('multi-file-sketch-test')
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
await toolbar.openFeatureTreePane()
|
||||||
|
await toolbar.openPane('files')
|
||||||
|
|
||||||
|
await toolbar.openFile('good.kcl')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
toolbar.featureTreePane.getByRole('button', { name: 'Sketch' })
|
||||||
|
).toHaveCount(2)
|
||||||
|
|
||||||
|
await toolbar.openFile('error.kcl')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
toolbar.featureTreePane.getByRole('button', { name: 'Sketch' })
|
||||||
|
).toHaveCount(0)
|
||||||
|
})
|
||||||
|
|
||||||
test('adding a syntax error, recovers after fixing', async ({
|
test('adding a syntax error, recovers after fixing', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
|
|
||||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
|
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
|
||||||
@ -9,6 +8,7 @@ import {
|
|||||||
settingsToToml,
|
settingsToToml,
|
||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
|
||||||
|
|
||||||
test.beforeEach(async ({ page, context }) => {
|
test.beforeEach(async ({ page, context }) => {
|
||||||
// Make the user avatar image always 404
|
// Make the user avatar image always 404
|
||||||
@ -766,7 +766,7 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('theme persists', async ({ page, context }) => {
|
test('theme persists', async ({ page, context, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@ -784,7 +784,7 @@ test('theme persists', async ({ page, context }) => {
|
|||||||
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
// await page.getByRole('link', { name: 'Settings Settings (tooltip)' }).click()
|
// await page.getByRole('link', { name: 'Settings Settings (tooltip)' }).click()
|
||||||
@ -812,7 +812,7 @@ test('theme persists', async ({ page, context }) => {
|
|||||||
// Disconnect and reconnect to check the theme persists through a reload
|
// Disconnect and reconnect to check the theme persists through a reload
|
||||||
|
|
||||||
// Expect the network to be down
|
// Expect the network to be down
|
||||||
await expect(networkToggle).toContainText('Offline')
|
await expect(networkToggle).toContainText('Problem')
|
||||||
|
|
||||||
// simulate network up
|
// simulate network up
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
@ -845,7 +845,7 @@ 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 = -90, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
@ -873,6 +873,50 @@ sweepSketch = startSketchOn(XY)
|
|||||||
mask: lowerRightMasks(page),
|
mask: lowerRightMasks(page),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
test('code color goober works with single quotes', async ({
|
||||||
|
page,
|
||||||
|
context,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await context.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`// Create a pipe using a sweep.
|
||||||
|
|
||||||
|
// Create a path for the sweep.
|
||||||
|
sweepPath = startSketchOn(XZ)
|
||||||
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|
|> line(end = [0, 7])
|
||||||
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|
|> line(end = [-3, 0])
|
||||||
|
|> tangentialArc(angle = -90, radius = 5)
|
||||||
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
|
sweepSketch = startSketchOn(XY)
|
||||||
|
|> startProfile(at = [2, 0])
|
||||||
|
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|
||||||
|
|> sweep(path = sweepPath)
|
||||||
|
|> appearance(
|
||||||
|
color = '#bb00ff',
|
||||||
|
metalness = 90,
|
||||||
|
roughness = 90
|
||||||
|
)
|
||||||
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1200, height: 1000 })
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await expect(page, 'expect small color widget').toHaveScreenshot({
|
||||||
|
maxDiffPixels: 100,
|
||||||
|
mask: lowerRightMasks(page),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('code color goober opening window', async ({
|
test('code color goober opening window', async ({
|
||||||
page,
|
page,
|
||||||
@ -890,7 +934,7 @@ 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 = -90, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
@ -62,16 +62,16 @@ export const TEST_CODE_GIZMO = `@settings(defaultLengthUnit = in)
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [20, 0])
|
|> startProfile(at = [20, 0])
|
||||||
|> line(end = [7.13, 4 + 0])
|
|> line(end = [7.13, 4 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 3.14 + 0 )
|
|> angledLine(angle = 3deg + 0, length = 3.14 + 0 )
|
||||||
|> line(endAbsolute = [20.14 + 0, -0.14 + 0])
|
|> line(endAbsolute = [20.14 + 0, -0.14 + 0])
|
||||||
|> xLine(endAbsolute = 29 + 0)
|
|> xLine(endAbsolute = 29 + 0)
|
||||||
|> yLine(length = -3.14 + 0, tag = $a)
|
|> yLine(length = -3.14 + 0, tag = $a)
|
||||||
|> xLine(length = 1.63)
|
|> xLine(length = 1.63)
|
||||||
|> angledLine(angle = 3 + 0, lengthX = 3.14 )
|
|> angledLine(angle = 3deg + 0, lengthX = 3.14 )
|
||||||
|> angledLine(angle = 30, lengthY = 3 + 0 )
|
|> angledLine(angle = 30deg, lengthY = 3 + 0 )
|
||||||
|> angledLine(angle = 22.14 + 0, endAbsoluteX = 12)
|
|> angledLine(angle = 22.14deg + 0, endAbsoluteX = 12)
|
||||||
|> angledLine(angle = 30, endAbsoluteY = 11.14)
|
|> angledLine(angle = 30deg, endAbsoluteY = 11.14)
|
||||||
|> angledLineThatIntersects(angle = 3.14, intersectTag = a, offset = 0)
|
|> angledLineThatIntersects(angle = 3.14deg, intersectTag = a, offset = 0)
|
||||||
|> tangentialArc(endAbsolute = [13.14 + 0, 13.14])
|
|> tangentialArc(endAbsolute = [13.14 + 0, 13.14])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5 + 7)
|
|> extrude(length = 5 + 7)
|
||||||
@ -122,7 +122,7 @@ sketch001 = startSketchOn(box, face = revolveAxis)
|
|||||||
|> close()
|
|> close()
|
||||||
|> revolve(
|
|> revolve(
|
||||||
axis = revolveAxis,
|
axis = revolveAxis,
|
||||||
angle = 90
|
angle = 90deg
|
||||||
)
|
)
|
||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|
@ -1,236 +1,257 @@
|
|||||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
|
import type { EngineCommand } from '@src/lang/std/artifactGraph'
|
||||||
import { uuidv4 } from '@src/lib/utils'
|
import { uuidv4 } from '@src/lib/utils'
|
||||||
|
|
||||||
import { commonPoints, getUtils } from '@e2e/playwright/test-utils'
|
import {
|
||||||
|
commonPoints,
|
||||||
|
getUtils,
|
||||||
|
TEST_COLORS,
|
||||||
|
circleMove,
|
||||||
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe(
|
test.describe('Test network related behaviors', () => {
|
||||||
'Test network and connection issues',
|
test(
|
||||||
{
|
'simulate network down and network little widget',
|
||||||
tag: ['@macos', '@windows'],
|
{ tag: '@skipLocalEngine' },
|
||||||
},
|
async ({ page, homePage }) => {
|
||||||
() => {
|
const networkToggleConnectedText = page.getByText('Connected')
|
||||||
test(
|
const networkToggleWeakText = page.getByText('Network health (Weak)')
|
||||||
'simulate network down and network little widget',
|
|
||||||
{ tag: '@skipLocalEngine' },
|
|
||||||
async ({ page, homePage }) => {
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
const networkToggle = page.getByTestId('network-toggle')
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
// This is how we wait until the stream is online
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).not.toBeDisabled({ timeout: 15000 })
|
|
||||||
|
|
||||||
const networkWidget = page.locator('[data-testid="network-toggle"]')
|
// This is how we wait until the stream is online
|
||||||
await expect(networkWidget).toBeVisible()
|
await expect(
|
||||||
await networkWidget.hover()
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
const networkPopover = page.locator('[data-testid="network-popover"]')
|
const networkWidget = page.locator('[data-testid="network-toggle"]')
|
||||||
await expect(networkPopover).not.toBeVisible()
|
await expect(networkWidget).toBeVisible()
|
||||||
|
await networkWidget.hover()
|
||||||
|
|
||||||
// (First check) Expect the network to be up
|
const networkPopover = page.locator('[data-testid="network-popover"]')
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await expect(networkPopover).not.toBeVisible()
|
||||||
|
|
||||||
// Click the network widget
|
// (First check) Expect the network to be up
|
||||||
await networkWidget.click()
|
await expect(
|
||||||
|
networkToggleConnectedText.or(networkToggleWeakText)
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
// Check the modal opened.
|
// Click the network widget
|
||||||
await expect(networkPopover).toBeVisible()
|
await networkWidget.click()
|
||||||
|
|
||||||
// Click off the modal.
|
// Check the modal opened.
|
||||||
await page.mouse.click(100, 100)
|
await expect(networkPopover).toBeVisible()
|
||||||
await expect(networkPopover).not.toBeVisible()
|
|
||||||
|
|
||||||
// Turn off the network
|
// Click off the modal.
|
||||||
await u.emulateNetworkConditions({
|
await page.mouse.click(100, 100)
|
||||||
offline: true,
|
await expect(networkPopover).not.toBeVisible()
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
|
||||||
latency: 0,
|
|
||||||
downloadThroughput: -1,
|
|
||||||
uploadThroughput: -1,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Expect the network to be down
|
// Turn off the network
|
||||||
await expect(networkToggle).toContainText('Problem')
|
await u.emulateNetworkConditions({
|
||||||
|
offline: true,
|
||||||
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
|
latency: 0,
|
||||||
|
downloadThroughput: -1,
|
||||||
|
uploadThroughput: -1,
|
||||||
|
})
|
||||||
|
|
||||||
// Click the network widget
|
// Expect the network to be down
|
||||||
await networkWidget.click()
|
await expect(networkToggle).toContainText('Problem')
|
||||||
|
|
||||||
// Check the modal opened.
|
// Click the network widget
|
||||||
await expect(networkPopover).toBeVisible()
|
await networkWidget.click()
|
||||||
|
|
||||||
// Click off the modal.
|
// Check the modal opened.
|
||||||
await page.mouse.click(0, 0)
|
await expect(networkPopover).toBeVisible()
|
||||||
await expect(networkPopover).not.toBeVisible()
|
|
||||||
|
|
||||||
// Turn back on the network
|
// Click off the modal.
|
||||||
await u.emulateNetworkConditions({
|
await page.mouse.click(0, 0)
|
||||||
offline: false,
|
await expect(networkPopover).not.toBeVisible()
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
|
||||||
latency: 0,
|
|
||||||
downloadThroughput: -1,
|
|
||||||
uploadThroughput: -1,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(
|
// Turn back on the network
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
await u.emulateNetworkConditions({
|
||||||
).not.toBeDisabled({ timeout: 15000 })
|
offline: false,
|
||||||
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
|
latency: 0,
|
||||||
|
downloadThroughput: -1,
|
||||||
|
uploadThroughput: -1,
|
||||||
|
})
|
||||||
|
|
||||||
// (Second check) expect the network to be up
|
await expect(
|
||||||
await expect(networkToggle).toContainText('Connected')
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
}
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
)
|
|
||||||
|
|
||||||
test(
|
// (Second check) expect the network to be up
|
||||||
'Engine disconnect & reconnect in sketch mode',
|
await expect(
|
||||||
{ tag: '@skipLocalEngine' },
|
networkToggleConnectedText.or(networkToggleWeakText)
|
||||||
async ({ page, homePage, toolbar, scene, cmdBar }) => {
|
).toBeVisible()
|
||||||
const networkToggle = page.getByTestId('network-toggle')
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const u = await getUtils(page)
|
test(
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
'Engine disconnect & reconnect in sketch mode',
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
{ tag: '@skipLocalEngine' },
|
||||||
|
async ({ page, homePage, toolbar, scene, cmdBar }) => {
|
||||||
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
const networkToggleConnectedText = page.getByText('Connected')
|
||||||
|
const networkToggleWeakText = page.getByText('Network health (Weak)')
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
const u = await getUtils(page)
|
||||||
await u.waitForPageLoad()
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await homePage.goToModelingScene()
|
||||||
// click on "Start Sketch" button
|
await u.waitForPageLoad()
|
||||||
await u.clearCommandLogs()
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
|
|
||||||
// select a plane
|
await u.openDebugPanel()
|
||||||
await page.mouse.click(700, 200)
|
// click on "Start Sketch" button
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
// select a plane
|
||||||
`sketch001 = startSketchOn(XZ)`
|
await page.mouse.click(700, 200)
|
||||||
)
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
|
`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)`
|
||||||
|
)
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
const startXPx = 600
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
|
||||||
`sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})`
|
|
||||||
)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
const startXPx = 600
|
||||||
await page.waitForTimeout(100)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
|
`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})`
|
||||||
|
)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
page.locator('.cm-content')
|
await page.waitForTimeout(100)
|
||||||
).toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})
|
|
||||||
|
await expect(
|
||||||
|
page.locator('.cm-content')
|
||||||
|
).toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfile(sketch001, at = ${commonPoints.startAt})
|
||||||
|> xLine(length = ${commonPoints.num1})`)
|
|> xLine(length = ${commonPoints.num1})`)
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await networkToggle.hover()
|
||||||
|
await expect(
|
||||||
|
networkToggleConnectedText.or(networkToggleWeakText)
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
// simulate network down
|
// simulate network down
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
offline: true,
|
offline: true,
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
latency: 0,
|
latency: 0,
|
||||||
downloadThroughput: -1,
|
downloadThroughput: -1,
|
||||||
uploadThroughput: -1,
|
uploadThroughput: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Expect the network to be down
|
// Expect the network to be down
|
||||||
await expect(networkToggle).toContainText('Problem')
|
await networkToggle.hover()
|
||||||
|
await expect(networkToggle).toContainText('Problem')
|
||||||
|
|
||||||
// Ensure we are not in sketch mode
|
// Ensure we are not in sketch mode
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).not.toBeVisible()
|
).not.toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// simulate network up
|
// simulate network up
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
offline: false,
|
offline: false,
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
latency: 0,
|
latency: 0,
|
||||||
downloadThroughput: -1,
|
downloadThroughput: -1,
|
||||||
uploadThroughput: -1,
|
uploadThroughput: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the app to be ready for use
|
// Wait for the app to be ready for use
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled({ timeout: 15000 })
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await networkToggle.hover()
|
||||||
await scene.settled(cmdBar)
|
await expect(
|
||||||
|
networkToggleConnectedText.or(networkToggleWeakText)
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
// Click off the code pane.
|
await scene.settled(cmdBar)
|
||||||
await page.mouse.click(100, 100)
|
|
||||||
|
|
||||||
// select a line
|
// Click off the code pane.
|
||||||
await page
|
await page.mouse.click(100, 100)
|
||||||
.getByText(`startProfile(sketch001, at = ${commonPoints.startAt})`)
|
|
||||||
.click()
|
|
||||||
|
|
||||||
// enter sketch again
|
// select a line
|
||||||
await toolbar.editSketch()
|
await page
|
||||||
|
.getByText(`startProfile(sketch001, at = ${commonPoints.startAt})`)
|
||||||
|
.click()
|
||||||
|
|
||||||
// Click the line tool
|
// enter sketch again
|
||||||
await page
|
await toolbar.editSketch()
|
||||||
.getByRole('button', { name: 'line Line', exact: true })
|
|
||||||
.click()
|
|
||||||
|
|
||||||
await page.waitForTimeout(150)
|
// Click the line tool
|
||||||
|
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||||
|
|
||||||
const camCommand: EngineCommand = {
|
await page.waitForTimeout(150)
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_look_at',
|
|
||||||
center: { x: 109, y: 0, z: -152 },
|
|
||||||
vantage: { x: 115, y: -505, z: -152 },
|
|
||||||
up: { x: 0, y: 0, z: 1 },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const updateCamCommand: EngineCommand = {
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_get_settings',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
await toolbar.openPane('debug')
|
|
||||||
await u.sendCustomCmd(camCommand)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await u.sendCustomCmd(updateCamCommand)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
|
|
||||||
// click to continue profile
|
const camCommand: EngineCommand = {
|
||||||
await page.mouse.click(1007, 400)
|
type: 'modeling_cmd_req',
|
||||||
await page.waitForTimeout(100)
|
cmd_id: uuidv4(),
|
||||||
// Ensure we can continue sketching
|
cmd: {
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
type: 'default_camera_look_at',
|
||||||
await expect
|
center: { x: 109, y: 0, z: -152 },
|
||||||
.poll(u.normalisedEditorCode)
|
vantage: { x: 115, y: -505, z: -152 },
|
||||||
.toBe(`sketch001 = startSketchOn(XZ)
|
up: { x: 0, y: 0, z: 1 },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const updateCamCommand: EngineCommand = {
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
await toolbar.openPane('debug')
|
||||||
|
await u.sendCustomCmd(camCommand)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.sendCustomCmd(updateCamCommand)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
// click to continue profile
|
||||||
|
await page.mouse.click(1007, 400)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
// Ensure we can continue sketching
|
||||||
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
|
await expect
|
||||||
|
.poll(u.normalisedEditorCode)
|
||||||
|
.toBe(`@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
|
||||||
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
||||||
|> xLine(length = 12.34)
|
|> xLine(length = 12.34)
|
||||||
|> line(end = [-12.34, 12.34])
|
|> line(end = [-12.34, 12.34])
|
||||||
|
|
||||||
`)
|
`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
|
|
||||||
await expect
|
await expect
|
||||||
.poll(u.normalisedEditorCode)
|
.poll(u.normalisedEditorCode)
|
||||||
.toBe(`sketch001 = startSketchOn(XZ)
|
.toBe(`@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
|
||||||
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
||||||
|> xLine(length = 12.34)
|
|> xLine(length = 12.34)
|
||||||
|> line(end = [-12.34, 12.34])
|
|> line(end = [-12.34, 12.34])
|
||||||
@ -238,22 +259,105 @@ profile001 = startProfile(sketch001, at = [12.34, -12.34])
|
|||||||
|
|
||||||
`)
|
`)
|
||||||
|
|
||||||
// Unequip line tool
|
// Unequip line tool
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
// Make sure we didn't pop out of sketch mode.
|
// Make sure we didn't pop out of sketch mode.
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'line Line', exact: true })
|
page.getByRole('button', { name: 'line Line', exact: true })
|
||||||
).not.toHaveAttribute('aria-pressed', 'true')
|
).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
// Exit sketch
|
// Exit sketch
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).not.toBeVisible()
|
).not.toBeVisible()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
test(
|
||||||
|
'Paused stream freezes view frame, unpause reconnect is seamless to user',
|
||||||
|
{ tag: ['@electron', '@skipLocalEngine'] },
|
||||||
|
async ({ page, homePage, scene, cmdBar, toolbar, tronApp }) => {
|
||||||
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
const networkToggleConnectedText = page.getByText('Connected')
|
||||||
|
const networkToggleWeakText = page.getByText('Network health (Weak)')
|
||||||
|
|
||||||
|
if (!tronApp) {
|
||||||
|
fail()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
await tronApp.cleanProjectDir({
|
||||||
)
|
app: {
|
||||||
|
stream_idle_mode: 5000,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn(XY)
|
||||||
|
profile001 = startProfile(sketch001, at = [0.0, 0.0])
|
||||||
|
|> line(end = [10.0, 0])
|
||||||
|
|> line(end = [0, 10.0])
|
||||||
|
|> close()`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const dim = { width: 1200, height: 500 }
|
||||||
|
await page.setBodyDimensions(dim)
|
||||||
|
|
||||||
|
await test.step('Go to modeling scene', async () => {
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Verify pausing behavior', async () => {
|
||||||
|
// Wait 5s + 1s to pause.
|
||||||
|
await page.waitForTimeout(6000)
|
||||||
|
|
||||||
|
// We should now be paused. To the user, it should appear we're still
|
||||||
|
// connected.
|
||||||
|
await networkToggle.hover()
|
||||||
|
await expect(
|
||||||
|
networkToggleConnectedText.or(networkToggleWeakText)
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
|
const center = {
|
||||||
|
x: dim.width / 2,
|
||||||
|
y: dim.height / 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
let probe = { x: 0, y: 0 }
|
||||||
|
|
||||||
|
// ... and the model's still visibly there
|
||||||
|
probe.x = center.x + dim.width / 100
|
||||||
|
probe.y = center.y
|
||||||
|
await scene.expectPixelColor(TEST_COLORS.GREY, probe, 15)
|
||||||
|
probe = { ...center }
|
||||||
|
|
||||||
|
// Now move the mouse around to unpause!
|
||||||
|
await circleMove(page, probe.x, probe.y, 20, 10)
|
||||||
|
|
||||||
|
// ONCE AGAIN! Check the view area hasn't changed at all.
|
||||||
|
// Check the pixel a couple times as it reconnects.
|
||||||
|
// NOTE: Remember, idle behavior is still on at this point -
|
||||||
|
// if this test takes longer than 5s shit WILL go south!
|
||||||
|
probe.x = center.x + dim.width / 100
|
||||||
|
probe.y = center.y
|
||||||
|
await scene.expectPixelColor(TEST_COLORS.GREY, probe, 15)
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
await scene.expectPixelColor(TEST_COLORS.GREY, probe, 15)
|
||||||
|
probe = { ...center }
|
||||||
|
|
||||||
|
// Ensure we're still connected
|
||||||
|
await networkToggle.hover()
|
||||||
|
await expect(
|
||||||
|
networkToggleConnectedText.or(networkToggleWeakText)
|
||||||
|
).toBeVisible()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
@ -21,6 +21,7 @@ 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 { 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'
|
||||||
@ -43,6 +44,8 @@ export const lowerRightMasks = (page: Page) => [
|
|||||||
export type TestColor = [number, number, number]
|
export type TestColor = [number, number, number]
|
||||||
export const TEST_COLORS: { [key: string]: TestColor } = {
|
export const TEST_COLORS: { [key: string]: TestColor } = {
|
||||||
WHITE: [249, 249, 249],
|
WHITE: [249, 249, 249],
|
||||||
|
OFFWHITE: [237, 237, 237],
|
||||||
|
GREY: [142, 142, 142],
|
||||||
YELLOW: [255, 255, 0],
|
YELLOW: [255, 255, 0],
|
||||||
BLUE: [0, 0, 255],
|
BLUE: [0, 0, 255],
|
||||||
DARK_MODE_BKGD: [27, 27, 27],
|
DARK_MODE_BKGD: [27, 27, 27],
|
||||||
@ -809,8 +812,6 @@ export const doExport = async (
|
|||||||
|
|
||||||
await page.getByRole('button', { name: 'Submit command' }).click()
|
await page.getByRole('button', { name: 'Submit command' }).click()
|
||||||
|
|
||||||
// This usually happens immediately after. If we're too slow we don't
|
|
||||||
// catch it.
|
|
||||||
await expect(page.getByText('Exported successfully')).toBeVisible()
|
await expect(page.getByText('Exported successfully')).toBeVisible()
|
||||||
|
|
||||||
if (exportFrom === 'sidebarButton' || exportFrom === 'commandBar') {
|
if (exportFrom === 'sidebarButton' || exportFrom === 'commandBar') {
|
||||||
@ -1151,3 +1152,77 @@ export function perProjectSettingsToToml(
|
|||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
return TOML.stringify(settings as any)
|
return TOML.stringify(settings as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function clickElectronNativeMenuById(
|
||||||
|
tronApp: ElectronZoo,
|
||||||
|
menuId: string
|
||||||
|
) {
|
||||||
|
const clickWasTriggered = await tronApp.electron.evaluate(
|
||||||
|
async ({ app }, menuId) => {
|
||||||
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const menu = app.applicationMenu.getMenuItemById(menuId)
|
||||||
|
if (!menu) return false
|
||||||
|
menu.click()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
menuId
|
||||||
|
)
|
||||||
|
expect(clickWasTriggered).toBe(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function findElectronNativeMenuById(
|
||||||
|
tronApp: ElectronZoo,
|
||||||
|
menuId: string
|
||||||
|
) {
|
||||||
|
const found = await tronApp.electron.evaluate(async ({ app }, menuId) => {
|
||||||
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const menu = app.applicationMenu.getMenuItemById(menuId)
|
||||||
|
if (!menu) return false
|
||||||
|
return true
|
||||||
|
}, menuId)
|
||||||
|
expect(found).toBe(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openSettingsExpectText(page: Page, text: string) {
|
||||||
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
|
await expect(settings).toBeVisible()
|
||||||
|
// You are viewing the user tab
|
||||||
|
const actualText = settings.getByText(text)
|
||||||
|
await expect(actualText).toBeVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openSettingsExpectLocator(page: Page, selector: string) {
|
||||||
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
|
await expect(settings).toBeVisible()
|
||||||
|
// You are viewing the keybindings tab
|
||||||
|
const settingsLocator = settings.locator(selector)
|
||||||
|
await expect(settingsLocator).toBeVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A developer helper function to make playwright send all the console logs to stdout
|
||||||
|
* Call this within your E2E test and pass in the page or the tronApp to get as many
|
||||||
|
* logs piped to stdout for debugging
|
||||||
|
*/
|
||||||
|
export async function enableConsoleLogEverything({
|
||||||
|
page,
|
||||||
|
tronApp,
|
||||||
|
}: { page?: Page; tronApp?: ElectronZoo }) {
|
||||||
|
page?.on('console', (msg) => {
|
||||||
|
console.log(`[Page-log]: ${msg.text()}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tronApp?.electron.on('window', async (electronPage) => {
|
||||||
|
electronPage.on('console', (msg) => {
|
||||||
|
console.log(`[Renderer] ${msg.type()}: ${msg.text()}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
tronApp?.electron.on('console', (msg) => {
|
||||||
|
console.log(`[Main] ${msg.type()}: ${msg.text()}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -57,7 +57,7 @@ test.describe('Testing constraints', () => {
|
|||||||
.click()
|
.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.
|
||||||
@ -852,7 +852,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',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1174,7 +1174,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)'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ test.describe(`Testing gizmo, fixture-based`, () => {
|
|||||||
`@settings(defaultLengthUnit = in)
|
`@settings(defaultLengthUnit = in)
|
||||||
sketch002 = startSketchOn(XZ)
|
sketch002 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-108.83, -57.48])
|
|> startProfile(at = [-108.83, -57.48])
|
||||||
|> angledLine(angle = 0, length = 105.13, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 105.13, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 77.9)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 77.9)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -33,8 +33,8 @@ test.describe('Testing loading external models', () => {
|
|||||||
|
|
||||||
// Locators and constants
|
// Locators and constants
|
||||||
const newSample = {
|
const newSample = {
|
||||||
file: 'parametric-bearing-pillow-block' + FILE_EXT,
|
file: 'pillow-block-bearing' + FILE_EXT,
|
||||||
title: 'Parametric Bearing Pillow Block',
|
title: 'Pillow Block Bearing',
|
||||||
}
|
}
|
||||||
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
const samplesCommandOption = page.getByRole('option', {
|
const samplesCommandOption = page.getByRole('option', {
|
||||||
@ -100,9 +100,9 @@ test.describe('Testing loading external models', () => {
|
|||||||
|
|
||||||
// Locators and constants
|
// Locators and constants
|
||||||
const sampleOne = {
|
const sampleOne = {
|
||||||
file: 'parametric-bearing-pillow-block' + FILE_EXT,
|
file: 'ball-bearing' + FILE_EXT,
|
||||||
title: 'Parametric Bearing Pillow Block',
|
title: 'Ball Bearing',
|
||||||
file1: 'parametric-bearing-pillow-block-1' + FILE_EXT,
|
file1: 'ball-bearing-1' + FILE_EXT,
|
||||||
}
|
}
|
||||||
const projectCard = page.getByRole('link', { name: 'bracket' })
|
const projectCard = page.getByRole('link', { name: 'bracket' })
|
||||||
const overwriteWarning = page.getByText(
|
const overwriteWarning = page.getByText(
|
||||||
|
@ -207,17 +207,17 @@ test.describe('Testing segment overlays', () => {
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [5 + 0, 20 + 0])
|
|> startProfile(at = [5 + 0, 20 + 0])
|
||||||
|> line(end = [0.5, -14 + 0])
|
|> line(end = [0.5, -14 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
|> angledLine(angle = 3deg + 0, length = 32 + 0)
|
||||||
|> line(endAbsolute = [5 + 33, 20 + 11.5 + 0])
|
|> line(endAbsolute = [5 + 33, 20 + 11.5 + 0])
|
||||||
|> xLine(endAbsolute = 5 + 9 - 5)
|
|> xLine(endAbsolute = 5 + 9 - 5)
|
||||||
|> yLine(endAbsolute = 20 + -10.77, tag = $a)
|
|> yLine(endAbsolute = 20 + -10.77, tag = $a)
|
||||||
|> xLine(length = 26.04)
|
|> xLine(length = 26.04)
|
||||||
|> yLine(length = 21.14 + 0)
|
|> yLine(length = 21.14 + 0)
|
||||||
|> angledLine(angle = 181 + 0, lengthX = 23.14)
|
|> angledLine(angle = 181deg + 0, lengthX = 23.14)
|
||||||
|> angledLine(angle = -91, lengthY = 19 + 0)
|
|> angledLine(angle = -91, lengthY = 19 + 0)
|
||||||
|> angledLine(angle = 3 + 0, endAbsoluteX = 5 + 26)
|
|> angledLine(angle = 3deg + 0, endAbsoluteX = 5 + 26)
|
||||||
|> angledLine(angle = 89, endAbsoluteY = 20 + 9.14 + 0)
|
|> angledLine(angle = 89deg, endAbsoluteY = 20 + 9.14 + 0)
|
||||||
|> angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)
|
|> angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)
|
||||||
|> tangentialArc(endAbsolute = [5 + 3.14 + 13, 20 + 3.14])
|
|> tangentialArc(endAbsolute = [5 + 3.14 + 13, 20 + 3.14])
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -295,8 +295,9 @@ test.describe('Testing segment overlays', () => {
|
|||||||
await clickConstrained({
|
await clickConstrained({
|
||||||
hoverPos: { x: angledLine.x, y: angledLine.y },
|
hoverPos: { x: angledLine.x, y: angledLine.y },
|
||||||
constraintType: 'angle',
|
constraintType: 'angle',
|
||||||
expectBeforeUnconstrained: 'angledLine(angle = 3 + 0, length = 32 + 0)',
|
expectBeforeUnconstrained:
|
||||||
expectAfterUnconstrained: 'angledLine(angle = 3, length = 32 + 0)',
|
'angledLine(angle = 3deg + 0, length = 32 + 0)',
|
||||||
|
expectAfterUnconstrained: 'angledLine(angle = 3deg, length = 32 + 0)',
|
||||||
expectFinal: 'angledLine(angle = angle001, length = 32 + 0)',
|
expectFinal: 'angledLine(angle = angle001, length = 32 + 0)',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="1"]',
|
locator: '[data-overlay-toolbar-index="1"]',
|
||||||
@ -383,7 +384,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
|> yLine(endAbsolute = -10.77, tag = $a)
|
|> yLine(endAbsolute = -10.77, tag = $a)
|
||||||
|> xLine(length = 26.04)
|
|> xLine(length = 26.04)
|
||||||
|> yLine(length = 21.14 + 0)
|
|> yLine(length = 21.14 + 0)
|
||||||
|> angledLine(angle = 181 + 0, lengthX = 23.14)
|
|> angledLine(angle = 181deg + 0, lengthX = 23.14)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -450,17 +451,17 @@ test.describe('Testing segment overlays', () => {
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [0.5, -14 + 0])
|
|> line(end = [0.5, -14 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
|> angledLine(angle = 3deg + 0, length = 32 + 0)
|
||||||
|> line(endAbsolute = [33, 11.5 + 0])
|
|> line(endAbsolute = [33, 11.5 + 0])
|
||||||
|> xLine(endAbsolute = 9 - 5)
|
|> xLine(endAbsolute = 9 - 5)
|
||||||
|> yLine(endAbsolute = -10.77, tag = $a)
|
|> yLine(endAbsolute = -10.77, tag = $a)
|
||||||
|> xLine(length = 26.04)
|
|> xLine(length = 26.04)
|
||||||
|> yLine(length = 21.14 + 0)
|
|> yLine(length = 21.14 + 0)
|
||||||
|> angledLine(angle = 181 + 0, lengthX = 23.14)
|
|> angledLine(angle = 181deg + 0, lengthX = 23.14)
|
||||||
|> angledLine(angle = -91, lengthY = 19 + 0)
|
|> angledLine(angle = -91, lengthY = 19 + 0)
|
||||||
|> angledLine(angle = 3 + 0, endAbsoluteX = 26)
|
|> angledLine(angle = 3deg + 0, endAbsoluteX = 26)
|
||||||
|> angledLine(angle = 89, endAbsoluteY = 9.14 + 0)
|
|> angledLine(angle = 89deg, endAbsoluteY = 9.14 + 0)
|
||||||
|> angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)
|
|> angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)
|
||||||
|> tangentialArc(endAbsolute = [3.14 + 13, 3.14])
|
|> tangentialArc(endAbsolute = [3.14 + 13, 3.14])
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -511,7 +512,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y },
|
hoverPos: { x: angledLineOfXLength.x, y: angledLineOfXLength.y },
|
||||||
constraintType: 'angle',
|
constraintType: 'angle',
|
||||||
expectBeforeUnconstrained:
|
expectBeforeUnconstrained:
|
||||||
'angledLine(angle = 181 + 0, lengthX = 23.14)',
|
'angledLine(angle = 181deg + 0, lengthX = 23.14)',
|
||||||
expectAfterUnconstrained: 'angledLine(angle = -179, lengthX = 23.14)',
|
expectAfterUnconstrained: 'angledLine(angle = -179, lengthX = 23.14)',
|
||||||
expectFinal: 'angledLine(angle = angle001, lengthX = 23.14)',
|
expectFinal: 'angledLine(angle = angle001, lengthX = 23.14)',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
@ -571,17 +572,17 @@ test.describe('Testing segment overlays', () => {
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [0.5, -14 + 0])
|
|> line(end = [0.5, -14 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
|> angledLine(angle = 3deg + 0, length = 32 + 0)
|
||||||
|> line(endAbsolute = [33, 11.5 + 0])
|
|> line(endAbsolute = [33, 11.5 + 0])
|
||||||
|> xLine(endAbsolute = 9 - 5)
|
|> xLine(endAbsolute = 9 - 5)
|
||||||
|> yLine(endAbsolute = -10.77, tag = $a)
|
|> yLine(endAbsolute = -10.77, tag = $a)
|
||||||
|> xLine(length = 26.04)
|
|> xLine(length = 26.04)
|
||||||
|> yLine(length = 21.14 + 0)
|
|> yLine(length = 21.14 + 0)
|
||||||
|> angledLine(angle = 181 + 0, lengthX = 23.14)
|
|> angledLine(angle = 181deg + 0, lengthX = 23.14)
|
||||||
|> angledLine(angle = -91, lengthY = 19 + 0)
|
|> angledLine(angle = -91, lengthY = 19 + 0)
|
||||||
|> angledLine(angle = 3 + 0, endAbsoluteX = 26)
|
|> angledLine(angle = 3deg + 0, endAbsoluteX = 26)
|
||||||
|> angledLine(angle = 89, endAbsoluteY = 9.14 + 0)
|
|> angledLine(angle = 89deg, endAbsoluteY = 9.14 + 0)
|
||||||
|> angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)
|
|> angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)
|
||||||
|> tangentialArc(endAbsolute = [3.14 + 13, 1.14])
|
|> tangentialArc(endAbsolute = [3.14 + 13, 1.14])
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -616,8 +617,8 @@ test.describe('Testing segment overlays', () => {
|
|||||||
hoverPos: { x: angledLineToX.x, y: angledLineToX.y },
|
hoverPos: { x: angledLineToX.x, y: angledLineToX.y },
|
||||||
constraintType: 'angle',
|
constraintType: 'angle',
|
||||||
expectBeforeUnconstrained:
|
expectBeforeUnconstrained:
|
||||||
'angledLine(angle = 3 + 0, endAbsoluteX = 26)',
|
'angledLine(angle = 3deg + 0, endAbsoluteX = 26)',
|
||||||
expectAfterUnconstrained: 'angledLine(angle = 3, endAbsoluteX = 26)',
|
expectAfterUnconstrained: 'angledLine(angle = 3deg, endAbsoluteX = 26)',
|
||||||
expectFinal: 'angledLine(angle = angle001, endAbsoluteX = 26)',
|
expectFinal: 'angledLine(angle = angle001, endAbsoluteX = 26)',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="9"]',
|
locator: '[data-overlay-toolbar-index="9"]',
|
||||||
@ -641,9 +642,9 @@ test.describe('Testing segment overlays', () => {
|
|||||||
await clickUnconstrained({
|
await clickUnconstrained({
|
||||||
hoverPos: { x: angledLineToY.x, y: angledLineToY.y },
|
hoverPos: { x: angledLineToY.x, y: angledLineToY.y },
|
||||||
constraintType: 'angle',
|
constraintType: 'angle',
|
||||||
expectBeforeUnconstrained: 'angledLine(angle = 89, to = 9.14 + 0)',
|
expectBeforeUnconstrained: 'angledLine(angle = 89deg, to = 9.14 + 0)',
|
||||||
expectAfterUnconstrained: 'angledLine(angle = angle002, to = 9.14 + 0)',
|
expectAfterUnconstrained: 'angledLine(angle = angle002, to = 9.14 + 0)',
|
||||||
expectFinal: 'angledLine(angle = 89, to = 9.14 + 0)',
|
expectFinal: 'angledLine(angle = 89deg, to = 9.14 + 0)',
|
||||||
steps: process.platform === 'darwin' ? 8 : 9,
|
steps: process.platform === 'darwin' ? 8 : 9,
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="10"]',
|
locator: '[data-overlay-toolbar-index="10"]',
|
||||||
@ -653,9 +654,10 @@ test.describe('Testing segment overlays', () => {
|
|||||||
hoverPos: { x: angledLineToY.x, y: angledLineToY.y },
|
hoverPos: { x: angledLineToY.x, y: angledLineToY.y },
|
||||||
constraintType: 'yAbsolute',
|
constraintType: 'yAbsolute',
|
||||||
expectBeforeUnconstrained:
|
expectBeforeUnconstrained:
|
||||||
'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)',
|
'angledLine(angle = 89deg, endAbsoluteY = 9.14 + 0)',
|
||||||
expectAfterUnconstrained: 'angledLine(angle = 89, endAbsoluteY = 9.14)',
|
expectAfterUnconstrained:
|
||||||
expectFinal: 'angledLine(angle = 89, endAbsoluteY = yAbs001)',
|
'angledLine(angle = 89deg, endAbsoluteY = 9.14)',
|
||||||
|
expectFinal: 'angledLine(angle = 89deg, endAbsoluteY = yAbs001)',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: '[data-overlay-toolbar-index="10"]',
|
locator: '[data-overlay-toolbar-index="10"]',
|
||||||
})
|
})
|
||||||
@ -671,7 +673,7 @@ test.describe('Testing segment overlays', () => {
|
|||||||
y: angledLineThatIntersects.y,
|
y: angledLineThatIntersects.y,
|
||||||
},
|
},
|
||||||
constraintType: 'angle',
|
constraintType: 'angle',
|
||||||
expectBeforeUnconstrained: `angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)`,
|
expectBeforeUnconstrained: `angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)`,
|
||||||
expectAfterUnconstrained: `angledLineThatIntersects(angle = angle003, intersectTag = a,offset = 9)`,
|
expectAfterUnconstrained: `angledLineThatIntersects(angle = angle003, intersectTag = a,offset = 9)`,
|
||||||
expectFinal: `angledLineThatIntersects(angle = -176, offset = 9, intersectTag = a)`,
|
expectFinal: `angledLineThatIntersects(angle = -176, offset = 9, intersectTag = a)`,
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
@ -705,17 +707,17 @@ test.describe('Testing segment overlays', () => {
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [0.5, -14 + 0])
|
|> line(end = [0.5, -14 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
|> angledLine(angle = 3deg + 0, length = 32 + 0)
|
||||||
|> line(endAbsolute = [33, 11.5 + 0])
|
|> line(endAbsolute = [33, 11.5 + 0])
|
||||||
|> xLine(endAbsolute = 9 - 5)
|
|> xLine(endAbsolute = 9 - 5)
|
||||||
|> yLine(endAbsolute = -10.77, tag = $a)
|
|> yLine(endAbsolute = -10.77, tag = $a)
|
||||||
|> xLine(length = 26.04)
|
|> xLine(length = 26.04)
|
||||||
|> yLine(length = 21.14 + 0)
|
|> yLine(length = 21.14 + 0)
|
||||||
|> angledLine(angle = 181 + 0, lengthX = 23.14)
|
|> angledLine(angle = 181deg + 0, lengthX = 23.14)
|
||||||
|> angledLine(angle = -91, lengthY = 19 + 0)
|
|> angledLine(angle = -91, lengthY = 19 + 0)
|
||||||
|> angledLine(angle = 3 + 0, endAbsoluteX = 26)
|
|> angledLine(angle = 3deg + 0, endAbsoluteX = 26)
|
||||||
|> angledLine(angle = 89, endAbsoluteY = 9.14 + 0)
|
|> angledLine(angle = 89deg, endAbsoluteY = 9.14 + 0)
|
||||||
|> angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)
|
|> angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)
|
||||||
|> tangentialArc(endAbsolute = [3.14 + 13, -3.14])
|
|> tangentialArc(endAbsolute = [3.14 + 13, -3.14])
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -992,17 +994,17 @@ part001 = startSketchOn(XZ)
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [0.5, -14 + 0])
|
|> line(end = [0.5, -14 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 32 + 0)
|
|> angledLine(angle = 3deg + 0, length = 32 + 0)
|
||||||
|> line(endAbsolute = [33, 11.5 + 0])
|
|> line(endAbsolute = [33, 11.5 + 0])
|
||||||
|> xLine(endAbsolute = 9 - 5)
|
|> xLine(endAbsolute = 9 - 5)
|
||||||
|> yLine(endAbsolute = -10.77, tag = $a)
|
|> yLine(endAbsolute = -10.77, tag = $a)
|
||||||
|> xLine(length = 26.04)
|
|> xLine(length = 26.04)
|
||||||
|> yLine(length = 21.14 + 0)
|
|> yLine(length = 21.14 + 0)
|
||||||
|> angledLine(angle = 181 + 0, lengthX = 23.14)
|
|> angledLine(angle = 181deg + 0, lengthX = 23.14)
|
||||||
|> angledLine(angle = -91, lengthY = 19 + 0)
|
|> angledLine(angle = -91, lengthY = 19 + 0)
|
||||||
|> angledLine(angle = 3 + 0, endAbsoluteX = 26)
|
|> angledLine(angle = 3deg + 0, endAbsoluteX = 26)
|
||||||
|> angledLine(angle = 89, endAbsoluteY = 9.14 + 0)
|
|> angledLine(angle = 89deg, endAbsoluteY = 9.14 + 0)
|
||||||
|> angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)
|
|> angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)
|
||||||
|> tangentialArc(endAbsolute = [3.14 + 13, 1.14])
|
|> tangentialArc(endAbsolute = [3.14 + 13, 1.14])
|
||||||
|> arc(interiorAbsolute = [16.25, 5.12], endAbsolute = [21.61, 4.15])
|
|> arc(interiorAbsolute = [16.25, 5.12], endAbsolute = [21.61, 4.15])
|
||||||
|> arc(angleStart = 40.27, angleEnd = -38.05, radius = 9.03)
|
|> arc(angleStart = 40.27, angleEnd = -38.05, radius = 9.03)
|
||||||
@ -1078,7 +1080,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: `angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)`,
|
codeToBeDeleted: `angledLineThatIntersects(angle = 4.14deg, intersectTag = a, offset = 9)`,
|
||||||
stdLibFnName: 'angledLineThatIntersects',
|
stdLibFnName: 'angledLineThatIntersects',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
steps: 7,
|
steps: 7,
|
||||||
@ -1091,7 +1093,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 89, endAbsoluteY = 9.14 + 0)',
|
codeToBeDeleted: 'angledLine(angle = 89deg, endAbsoluteY = 9.14 + 0)',
|
||||||
stdLibFnName: 'angledLineToY',
|
stdLibFnName: 'angledLineToY',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
@ -1103,7 +1105,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 3 + 0, endAbsoluteX = 26)',
|
codeToBeDeleted: 'angledLine(angle = 3deg + 0, endAbsoluteX = 26)',
|
||||||
stdLibFnName: 'angledLineToX',
|
stdLibFnName: 'angledLineToX',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
@ -1127,7 +1129,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 181 + 0, lengthX = 23.14)',
|
codeToBeDeleted: 'angledLine(angle = 181deg + 0, lengthX = 23.14)',
|
||||||
stdLibFnName: 'angledLineOfXLength',
|
stdLibFnName: 'angledLineOfXLength',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
@ -1222,7 +1224,7 @@ part001 = startSketchOn(XZ)
|
|||||||
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
ang = await u.getAngle(`[data-overlay-index="${overlayIndex}"]`)
|
||||||
await deleteSegmentSequence({
|
await deleteSegmentSequence({
|
||||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||||
codeToBeDeleted: 'angledLine(angle = 3 + 0, length = 32 + 0)',
|
codeToBeDeleted: 'angledLine(angle = 3deg + 0, length = 32 + 0)',
|
||||||
stdLibFnName: 'angledLine',
|
stdLibFnName: 'angledLine',
|
||||||
ang: ang + 180,
|
ang: ang + 180,
|
||||||
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
locator: `[data-overlay-toolbar-index="${overlayIndex}"]`,
|
||||||
@ -1245,19 +1247,19 @@ part001 = startSketchOn(XZ)
|
|||||||
test.describe('Testing delete with dependent segments', () => {
|
test.describe('Testing delete with dependent segments', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
'line(end = [22, 2], tag = $seg01)',
|
'line(end = [22, 2], tag = $seg01)',
|
||||||
'angledLine(angle = 5, length = 23.03, tag = $seg01)',
|
'angledLine(angle = 5deg, length = 23.03, tag = $seg01)',
|
||||||
'xLine(length = 23, tag = $seg01)',
|
'xLine(length = 23, tag = $seg01)',
|
||||||
'yLine(length = -8, tag = $seg01)',
|
'yLine(length = -8, tag = $seg01)',
|
||||||
'xLine(endAbsolute = 30, tag = $seg01)',
|
'xLine(endAbsolute = 30, tag = $seg01)',
|
||||||
'yLine(endAbsolute = -4, tag = $seg01)',
|
'yLine(endAbsolute = -4, tag = $seg01)',
|
||||||
'angledLine(angle = 3, lengthX = 30, tag = $seg01)',
|
'angledLine(angle = 3deg, lengthX = 30, tag = $seg01)',
|
||||||
'angledLine(angle = 3, lengthY = 1.5, tag = $seg01)',
|
'angledLine(angle = 3deg, lengthY = 1.5, tag = $seg01)',
|
||||||
'angledLine(angle = 3, endAbsoluteX = 30, tag = $seg01)',
|
'angledLine(angle = 3deg, endAbsoluteX = 30, tag = $seg01)',
|
||||||
'angledLine(angle = 3, endAbsoluteY = 7, tag = $seg01)',
|
'angledLine(angle = 3deg, endAbsoluteY = 7, tag = $seg01)',
|
||||||
]
|
]
|
||||||
for (const doesHaveTagOutsideSketch of [true, false]) {
|
for (const doesHaveTagOutsideSketch of [true, false]) {
|
||||||
for (const lineOfInterest of cases) {
|
for (const lineOfInterest of cases) {
|
||||||
const isObj = lineOfInterest.includes('{ angle = 3,')
|
const isObj = lineOfInterest.includes('{ angle = 3deg,')
|
||||||
test(`${lineOfInterest}${isObj ? '-[obj-input]' : ''}${
|
test(`${lineOfInterest}${isObj ? '-[obj-input]' : ''}${
|
||||||
doesHaveTagOutsideSketch ? '-[tagOutsideSketch]' : ''
|
doesHaveTagOutsideSketch ? '-[tagOutsideSketch]' : ''
|
||||||
}`, async ({ page, editor, homePage }) => {
|
}`, async ({ page, editor, homePage }) => {
|
||||||
@ -1383,7 +1385,7 @@ part001 = startSketchOn(XZ)
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
before: `angledLine(angle = 5 + 0, length = 23.03 + 0, tag = $seg01)`,
|
before: `angledLine(angle = 5deg + 0, length = 23.03 + 0, tag = $seg01)`,
|
||||||
after: `line(end = [22.94, 2.01], tag = $seg01)`,
|
after: `line(end = [22.94, 2.01], tag = $seg01)`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1403,19 +1405,19 @@ part001 = startSketchOn(XZ)
|
|||||||
after: `line(end = [0, -10], tag = $seg01)`,
|
after: `line(end = [0, -10], tag = $seg01)`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: `angledLine(angle = 3 + 0, lengthX = 30 + 0, tag = $seg01)`,
|
before: `angledLine(angle = 3deg + 0, lengthX = 30 + 0, tag = $seg01)`,
|
||||||
after: `line(end = [30, 1.57], tag = $seg01)`,
|
after: `line(end = [30, 1.57], tag = $seg01)`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: `angledLine(angle = 3 + 0, lengthY = 1.5 + 0, tag = $seg01)`,
|
before: `angledLine(angle = 3deg + 0, lengthY = 1.5 + 0, tag = $seg01)`,
|
||||||
after: `line(end = [28.62, 1.5], tag = $seg01)`,
|
after: `line(end = [28.62, 1.5], tag = $seg01)`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: `angledLine(angle = 3 + 0, endAbsoluteX = 30 + 0, tag = $seg01)`,
|
before: `angledLine(angle = 3deg + 0, endAbsoluteX = 30 + 0, tag = $seg01)`,
|
||||||
after: `line(end = [25, 1.31], tag = $seg01)`,
|
after: `line(end = [25, 1.31], tag = $seg01)`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
before: `angledLine(angle = 3 + 0, endAbsoluteY = 7 + 0, tag = $seg01)`,
|
before: `angledLine(angle = 3deg + 0, endAbsoluteY = 7 + 0, tag = $seg01)`,
|
||||||
after: `line(end = [19.08, 1], tag = $seg01)`,
|
after: `line(end = [19.08, 1], tag = $seg01)`,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -307,15 +307,15 @@ part009 = startSketchOn(XY)
|
|||||||
|> startProfile(at = [pipeLargeDia - (thickness / 2), 38])
|
|> startProfile(at = [pipeLargeDia - (thickness / 2), 38])
|
||||||
|> line(end = [thickness, 0])
|
|> line(end = [thickness, 0])
|
||||||
|> line(end = [0, -1])
|
|> line(end = [0, -1])
|
||||||
|> angledLine(angle = 60, endAbsoluteX = pipeSmallDia + thickness)
|
|> angledLine(angle = 60deg, endAbsoluteX = pipeSmallDia + thickness)
|
||||||
|> line(end = [0, -pipeLength])
|
|> line(end = [0, -pipeLength])
|
||||||
|> angledLine(angle = -60, endAbsoluteX = pipeLargeDia + thickness)
|
|> angledLine(angle = -60, endAbsoluteX = pipeLargeDia + thickness)
|
||||||
|> line(end = [0, -1])
|
|> line(end = [0, -1])
|
||||||
|> line(end = [-thickness, 0])
|
|> line(end = [-thickness, 0])
|
||||||
|> line(end = [0, 1])
|
|> line(end = [0, 1])
|
||||||
|> angledLine(angle = 120, endAbsoluteX = pipeSmallDia)
|
|> angledLine(angle = 120deg, endAbsoluteX = pipeSmallDia)
|
||||||
|> line(end = [0, pipeLength])
|
|> line(end = [0, pipeLength])
|
||||||
|> angledLine(angle = 60, endAbsoluteX = pipeLargeDia)
|
|> angledLine(angle = 60deg, endAbsoluteX = pipeLargeDia)
|
||||||
|> close()
|
|> close()
|
||||||
rev = revolve(part009, axis = Y)
|
rev = revolve(part009, axis = Y)
|
||||||
sketch006 = startSketchOn(XY)
|
sketch006 = startSketchOn(XY)
|
||||||
@ -325,7 +325,7 @@ profile001 = circle(
|
|||||||
radius = 17.96
|
radius = 17.96
|
||||||
)
|
)
|
||||||
profile002 = startProfile(sketch006, at = [86.92, -63.81])
|
profile002 = startProfile(sketch006, at = [86.92, -63.81])
|
||||||
|> angledLine(angle = 0, length = 63.81, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 63.81, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 17.05)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 17.05)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -464,7 +464,7 @@ profile002 = startProfile(sketch002, at = [-11.08, 2.39])
|
|||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(profile002, length = 15)
|
extrude001 = extrude(profile002, length = 15)
|
||||||
profile001 = startProfile(sketch001, at = [7.49, 9.96])
|
profile001 = startProfile(sketch001, at = [7.49, 9.96])
|
||||||
|> angledLine(angle = 0, length = 5.05, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 5.05, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.81)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.81)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -513,16 +513,16 @@ profile001 = startProfile(sketch001, at = [7.49, 9.96])
|
|||||||
part001 = startSketchOn(XZ)
|
part001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [20, 0])
|
|> startProfile(at = [20, 0])
|
||||||
|> line(end = [7.13, 4 + 0])
|
|> line(end = [7.13, 4 + 0])
|
||||||
|> angledLine(angle = 3 + 0, length = 3.14 + 0 )
|
|> angledLine(angle = 3deg + 0, length = 3.14 + 0 )
|
||||||
|> line(endAbsolute = [20.14 + 0, -0.14 + 0])
|
|> line(endAbsolute = [20.14 + 0, -0.14 + 0])
|
||||||
|> xLine(endAbsolute = 29 + 0)
|
|> xLine(endAbsolute = 29 + 0)
|
||||||
|> yLine(length = -3.14 + 0, tag = $a)
|
|> yLine(length = -3.14 + 0, tag = $a)
|
||||||
|> xLine(length = 1.63)
|
|> xLine(length = 1.63)
|
||||||
|> angledLine(angle = 3 + 0, lengthX = 3.14)
|
|> angledLine(angle = 3deg + 0, lengthX = 3.14)
|
||||||
|> angledLine(angle = 30, lengthY = 3 + 0)
|
|> angledLine(angle = 30deg, lengthY = 3 + 0)
|
||||||
|> angledLine(angle = 22.14 + 0, endAbsoluteX = 12)
|
|> angledLine(angle = 22.14deg + 0, endAbsoluteX = 12)
|
||||||
|> angledLine(angle = 30, endAbsoluteY = 11.14)
|
|> angledLine(angle = 30deg, endAbsoluteY = 11.14)
|
||||||
|> angledLineThatIntersects(angle = 3.14, intersectTag = a, offset = 0)
|
|> angledLineThatIntersects(angle = 3.14deg, intersectTag = a, offset = 0)
|
||||||
|> tangentialArc(endAbsolute = [13.14 + 0, 13.14])
|
|> tangentialArc(endAbsolute = [13.14 + 0, 13.14])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5 + 7)
|
|> extrude(length = 5 + 7)
|
||||||
@ -655,7 +655,7 @@ part001 = startSketchOn(XZ)
|
|||||||
'flatExtrusionFace',
|
'flatExtrusionFace',
|
||||||
flatExtrusionFace,
|
flatExtrusionFace,
|
||||||
`angledLineThatIntersects(angle=3.14,intersectTag=a,offset=0)extrude(length=5+7)`,
|
`angledLineThatIntersects(angle=3.14,intersectTag=a,offset=0)extrude(length=5+7)`,
|
||||||
'angledLineThatIntersects(angle = 3.14, intersectTag = a, offset = 0)'
|
'angledLineThatIntersects(angle = 3.14deg, intersectTag = a, offset = 0)'
|
||||||
)
|
)
|
||||||
|
|
||||||
await checkCodeAtHoverPosition(
|
await checkCodeAtHoverPosition(
|
||||||
@ -707,19 +707,19 @@ part001 = startSketchOn(XZ)
|
|||||||
'straightSegmentEdge',
|
'straightSegmentEdge',
|
||||||
straightSegmentEdge,
|
straightSegmentEdge,
|
||||||
`angledLine(angle=30,endAbsoluteY=11.14)`,
|
`angledLine(angle=30,endAbsoluteY=11.14)`,
|
||||||
'angledLine(angle = 30, endAbsoluteY = 11.14)'
|
'angledLine(angle = 30deg, endAbsoluteY = 11.14)'
|
||||||
)
|
)
|
||||||
await checkCodeAtHoverPosition(
|
await checkCodeAtHoverPosition(
|
||||||
'straightSegmentOppositeEdge',
|
'straightSegmentOppositeEdge',
|
||||||
straightSegmentOppositeEdge,
|
straightSegmentOppositeEdge,
|
||||||
`angledLine(angle=30,endAbsoluteY=11.14)`,
|
`angledLine(angle=30,endAbsoluteY=11.14)`,
|
||||||
'angledLine(angle = 30, endAbsoluteY = 11.14)'
|
'angledLine(angle = 30deg, endAbsoluteY = 11.14)'
|
||||||
)
|
)
|
||||||
await checkCodeAtHoverPosition(
|
await checkCodeAtHoverPosition(
|
||||||
'straightSegmentAdjacentEdge',
|
'straightSegmentAdjacentEdge',
|
||||||
straightSegmentAdjacentEdge,
|
straightSegmentAdjacentEdge,
|
||||||
`angledLineThatIntersects(angle=3.14,intersectTag=a,offset=0)`,
|
`angledLineThatIntersects(angle=3.14,intersectTag=a,offset=0)`,
|
||||||
'angledLineThatIntersects(angle = 3.14, intersectTag = a, offset = 0)'
|
'angledLineThatIntersects(angle = 3.14deg, intersectTag = a, offset = 0)'
|
||||||
)
|
)
|
||||||
|
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
@ -728,7 +728,7 @@ part001 = startSketchOn(XZ)
|
|||||||
await u.codeLocator.fill(`@settings(defaultLengthUnit = in)
|
await u.codeLocator.fill(`@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|
||||||
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
|
LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
|
||||||
ELECTRON_OVERRIDE_DIST_PATH =
|
ELECTRON_OVERRIDE_DIST_PATH =
|
||||||
if pkgs.stdenv.isDarwin
|
if pkgs.stdenv.isDarwin
|
||||||
then "${pkgs.electron}/Applications"
|
then "${pkgs.electron}/Applications/Electron.app/Contents/MacOS/"
|
||||||
else "${pkgs.electron}/bin";
|
else "${pkgs.electron}/bin";
|
||||||
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
|
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
|
||||||
PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = "${pkgs.playwright-driver.browsers}/chromium-1091/chrome-linux/chrome";
|
PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = "${pkgs.playwright-driver.browsers}/chromium-1091/chrome-linux/chrome";
|
||||||
|
@ -19,7 +19,7 @@ fn rail8020(originStart, railHeight, railLength) {
|
|||||||
|> xLine(length = 0.06 * railHeight, tag = $edge1)
|
|> xLine(length = 0.06 * railHeight, tag = $edge1)
|
||||||
|> yLine(length = 0.087 * railHeight, tag = $edge2)
|
|> yLine(length = 0.087 * railHeight, tag = $edge2)
|
||||||
|> xLine(length = -0.183 * railHeight, tag = $edge3)
|
|> xLine(length = -0.183 * railHeight, tag = $edge3)
|
||||||
|> angledLine(angle = 45, endAbsoluteY = (1 - 0.356) / 2 * railHeight + originStart[1], tag = $edge4)
|
|> angledLine(angle = 45deg, endAbsoluteY = (1 - 0.356) / 2 * railHeight + originStart[1], tag = $edge4)
|
||||||
|> xLine(length = 0.232 * railHeight, tag = $edge5)
|
|> xLine(length = 0.232 * railHeight, tag = $edge5)
|
||||||
|> angledLine(angle = -45, endAbsoluteY = 0.087 * railHeight + originStart[1], tag = $edge6)
|
|> angledLine(angle = -45, endAbsoluteY = 0.087 * railHeight + originStart[1], tag = $edge6)
|
||||||
|> xLine(length = -0.183 * railHeight, tag = $edge7)
|
|> xLine(length = -0.183 * railHeight, tag = $edge7)
|
||||||
@ -37,9 +37,9 @@ fn rail8020(originStart, railHeight, railLength) {
|
|||||||
|> yLine(length = 0.06 * railHeight, tag = $edge9)
|
|> yLine(length = 0.06 * railHeight, tag = $edge9)
|
||||||
|> xLine(length = -0.087 * railHeight, tag = $edge10)
|
|> xLine(length = -0.087 * railHeight, tag = $edge10)
|
||||||
|> yLine(length = -0.183 * railHeight, tag = $edge11) // edge11
|
|> yLine(length = -0.183 * railHeight, tag = $edge11) // edge11
|
||||||
|> angledLine(angle = 135, endAbsoluteX = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[0], tag = $edge12) // edge12
|
|> angledLine(angle = 135deg, endAbsoluteX = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[0], tag = $edge12) // edge12
|
||||||
|> yLine(length = 0.232 * railHeight, tag = $edge13) // 13
|
|> yLine(length = 0.232 * railHeight, tag = $edge13) // 13
|
||||||
|> angledLine(angle = 45, endAbsoluteX = (1 - 0.087) * railHeight + originStart[0], tag = $edge14) // 14
|
|> angledLine(angle = 45deg, endAbsoluteX = (1 - 0.087) * railHeight + originStart[0], tag = $edge14) // 14
|
||||||
|> yLine(length = -0.183 * railHeight, tag = $edge15) // 15
|
|> yLine(length = -0.183 * railHeight, tag = $edge15) // 15
|
||||||
|> xLine(length = 0.087 * railHeight, tag = $edge16)
|
|> xLine(length = 0.087 * railHeight, tag = $edge16)
|
||||||
|> yLine(length = 0.06 * railHeight)
|
|> yLine(length = 0.06 * railHeight)
|
||||||
@ -55,9 +55,9 @@ fn rail8020(originStart, railHeight, railLength) {
|
|||||||
|> xLine(length = -0.06 * railHeight, tag = $edge17)
|
|> xLine(length = -0.06 * railHeight, tag = $edge17)
|
||||||
|> yLine(length = -0.087 * railHeight, tag = $edge18)
|
|> yLine(length = -0.087 * railHeight, tag = $edge18)
|
||||||
|> xLine(length = 0.183 * railHeight, tag = $edge19)
|
|> xLine(length = 0.183 * railHeight, tag = $edge19)
|
||||||
|> angledLine(angle = 45, endAbsoluteY = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[1], tag = $edge20)
|
|> angledLine(angle = 45deg, endAbsoluteY = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[1], tag = $edge20)
|
||||||
|> xLine(length = -0.232 * railHeight, tag = $edge21)
|
|> xLine(length = -0.232 * railHeight, tag = $edge21)
|
||||||
|> angledLine(angle = 135, endAbsoluteY = (1 - 0.087) * railHeight + originStart[1], tag = $edge22)
|
|> angledLine(angle = 135deg, endAbsoluteY = (1 - 0.087) * railHeight + originStart[1], tag = $edge22)
|
||||||
|> xLine(length = 0.183 * railHeight, tag = $edge23)
|
|> xLine(length = 0.183 * railHeight, tag = $edge23)
|
||||||
|> yLine(length = 0.087 * railHeight, tag = $edge24)
|
|> yLine(length = 0.087 * railHeight, tag = $edge24)
|
||||||
|> xLine(length = -0.06 * railHeight)
|
|> xLine(length = -0.06 * railHeight)
|
||||||
@ -73,9 +73,9 @@ fn rail8020(originStart, railHeight, railLength) {
|
|||||||
|> yLine(length = -0.06 * railHeight, tag = $edge25)
|
|> yLine(length = -0.06 * railHeight, tag = $edge25)
|
||||||
|> xLine(length = 0.087 * railHeight, tag = $edge26)
|
|> xLine(length = 0.087 * railHeight, tag = $edge26)
|
||||||
|> yLine(length = 0.183 * railHeight, tag = $edge27)
|
|> yLine(length = 0.183 * railHeight, tag = $edge27)
|
||||||
|> angledLine(angle = 135, endAbsoluteX = (1 - 0.356) / 2 * railHeight + originStart[0], tag = $edge28)
|
|> angledLine(angle = 135deg, endAbsoluteX = (1 - 0.356) / 2 * railHeight + originStart[0], tag = $edge28)
|
||||||
|> yLine(length = -0.232 * railHeight, tag = $edge29)
|
|> yLine(length = -0.232 * railHeight, tag = $edge29)
|
||||||
|> angledLine(angle = 45, endAbsoluteX = 0.087 * railHeight + originStart[0], tag = $edge30)
|
|> angledLine(angle = 45deg, endAbsoluteX = 0.087 * railHeight + originStart[0], tag = $edge30)
|
||||||
|> yLine(length = 0.183 * railHeight, tag = $edge31)
|
|> yLine(length = 0.183 * railHeight, tag = $edge31)
|
||||||
|> xLine(length = -0.087 * railHeight, tag = $edge32)
|
|> xLine(length = -0.087 * railHeight, tag = $edge32)
|
||||||
|> yLine(length = -0.06 * railHeight)
|
|> yLine(length = -0.06 * railHeight)
|
||||||
|
@ -31,14 +31,24 @@ When you submit a PR to add or modify KCL samples, images will be generated and
|
|||||||
[](ball-bearing/main.kcl)
|
[](ball-bearing/main.kcl)
|
||||||
#### [bench](bench/main.kcl) ([screenshot](screenshots/bench.png))
|
#### [bench](bench/main.kcl) ([screenshot](screenshots/bench.png))
|
||||||
[](bench/main.kcl)
|
[](bench/main.kcl)
|
||||||
|
#### [bone-plate](bone-plate/main.kcl) ([screenshot](screenshots/bone-plate.png))
|
||||||
|
[](bone-plate/main.kcl)
|
||||||
#### [bottle](bottle/main.kcl) ([screenshot](screenshots/bottle.png))
|
#### [bottle](bottle/main.kcl) ([screenshot](screenshots/bottle.png))
|
||||||
[](bottle/main.kcl)
|
[](bottle/main.kcl)
|
||||||
#### [bracket](bracket/main.kcl) ([screenshot](screenshots/bracket.png))
|
#### [bracket](bracket/main.kcl) ([screenshot](screenshots/bracket.png))
|
||||||
[](bracket/main.kcl)
|
[](bracket/main.kcl)
|
||||||
#### [car-wheel-assembly](car-wheel-assembly/main.kcl) ([screenshot](screenshots/car-wheel-assembly.png))
|
#### [car-wheel-assembly](car-wheel-assembly/main.kcl) ([screenshot](screenshots/car-wheel-assembly.png))
|
||||||
[](car-wheel-assembly/main.kcl)
|
[](car-wheel-assembly/main.kcl)
|
||||||
|
#### [cold-plate](cold-plate/main.kcl) ([screenshot](screenshots/cold-plate.png))
|
||||||
|
[](cold-plate/main.kcl)
|
||||||
#### [color-cube](color-cube/main.kcl) ([screenshot](screenshots/color-cube.png))
|
#### [color-cube](color-cube/main.kcl) ([screenshot](screenshots/color-cube.png))
|
||||||
[](color-cube/main.kcl)
|
[](color-cube/main.kcl)
|
||||||
|
#### [counterdrilled-weldment](counterdrilled-weldment/main.kcl) ([screenshot](screenshots/counterdrilled-weldment.png))
|
||||||
|
[](counterdrilled-weldment/main.kcl)
|
||||||
|
#### [countersunk-plate](countersunk-plate/main.kcl) ([screenshot](screenshots/countersunk-plate.png))
|
||||||
|
[](countersunk-plate/main.kcl)
|
||||||
|
#### [cpu-cooler](cpu-cooler/main.kcl) ([screenshot](screenshots/cpu-cooler.png))
|
||||||
|
[](cpu-cooler/main.kcl)
|
||||||
#### [cycloidal-gear](cycloidal-gear/main.kcl) ([screenshot](screenshots/cycloidal-gear.png))
|
#### [cycloidal-gear](cycloidal-gear/main.kcl) ([screenshot](screenshots/cycloidal-gear.png))
|
||||||
[](cycloidal-gear/main.kcl)
|
[](cycloidal-gear/main.kcl)
|
||||||
#### [dodecahedron](dodecahedron/main.kcl) ([screenshot](screenshots/dodecahedron.png))
|
#### [dodecahedron](dodecahedron/main.kcl) ([screenshot](screenshots/dodecahedron.png))
|
||||||
@ -55,8 +65,6 @@ When you submit a PR to add or modify KCL samples, images will be generated and
|
|||||||
[](food-service-spatula/main.kcl)
|
[](food-service-spatula/main.kcl)
|
||||||
#### [french-press](french-press/main.kcl) ([screenshot](screenshots/french-press.png))
|
#### [french-press](french-press/main.kcl) ([screenshot](screenshots/french-press.png))
|
||||||
[](french-press/main.kcl)
|
[](french-press/main.kcl)
|
||||||
#### [gear](gear/main.kcl) ([screenshot](screenshots/gear.png))
|
|
||||||
[](gear/main.kcl)
|
|
||||||
#### [gear-rack](gear-rack/main.kcl) ([screenshot](screenshots/gear-rack.png))
|
#### [gear-rack](gear-rack/main.kcl) ([screenshot](screenshots/gear-rack.png))
|
||||||
[](gear-rack/main.kcl)
|
[](gear-rack/main.kcl)
|
||||||
#### [gridfinity-baseplate](gridfinity-baseplate/main.kcl) ([screenshot](screenshots/gridfinity-baseplate.png))
|
#### [gridfinity-baseplate](gridfinity-baseplate/main.kcl) ([screenshot](screenshots/gridfinity-baseplate.png))
|
||||||
@ -67,6 +75,18 @@ When you submit a PR to add or modify KCL samples, images will be generated and
|
|||||||
[](gridfinity-bins/main.kcl)
|
[](gridfinity-bins/main.kcl)
|
||||||
#### [gridfinity-bins-stacking-lip](gridfinity-bins-stacking-lip/main.kcl) ([screenshot](screenshots/gridfinity-bins-stacking-lip.png))
|
#### [gridfinity-bins-stacking-lip](gridfinity-bins-stacking-lip/main.kcl) ([screenshot](screenshots/gridfinity-bins-stacking-lip.png))
|
||||||
[](gridfinity-bins-stacking-lip/main.kcl)
|
[](gridfinity-bins-stacking-lip/main.kcl)
|
||||||
|
#### [hammer](hammer/main.kcl) ([screenshot](screenshots/hammer.png))
|
||||||
|
[](hammer/main.kcl)
|
||||||
|
#### [helical-gear](helical-gear/main.kcl) ([screenshot](screenshots/helical-gear.png))
|
||||||
|
[](helical-gear/main.kcl)
|
||||||
|
#### [helical-planetary-gearset](helical-planetary-gearset/main.kcl) ([screenshot](screenshots/helical-planetary-gearset.png))
|
||||||
|
[](helical-planetary-gearset/main.kcl)
|
||||||
|
#### [helium-tank](helium-tank/main.kcl) ([screenshot](screenshots/helium-tank.png))
|
||||||
|
[](helium-tank/main.kcl)
|
||||||
|
#### [herringbone-gear](herringbone-gear/main.kcl) ([screenshot](screenshots/herringbone-gear.png))
|
||||||
|
[](herringbone-gear/main.kcl)
|
||||||
|
#### [herringbone-planetary-gearset](herringbone-planetary-gearset/main.kcl) ([screenshot](screenshots/herringbone-planetary-gearset.png))
|
||||||
|
[](herringbone-planetary-gearset/main.kcl)
|
||||||
#### [hex-nut](hex-nut/main.kcl) ([screenshot](screenshots/hex-nut.png))
|
#### [hex-nut](hex-nut/main.kcl) ([screenshot](screenshots/hex-nut.png))
|
||||||
[](hex-nut/main.kcl)
|
[](hex-nut/main.kcl)
|
||||||
#### [i-beam](i-beam/main.kcl) ([screenshot](screenshots/i-beam.png))
|
#### [i-beam](i-beam/main.kcl) ([screenshot](screenshots/i-beam.png))
|
||||||
@ -83,8 +103,8 @@ When you submit a PR to add or modify KCL samples, images will be generated and
|
|||||||
[](mounting-plate/main.kcl)
|
[](mounting-plate/main.kcl)
|
||||||
#### [multi-axis-robot](multi-axis-robot/main.kcl) ([screenshot](screenshots/multi-axis-robot.png))
|
#### [multi-axis-robot](multi-axis-robot/main.kcl) ([screenshot](screenshots/multi-axis-robot.png))
|
||||||
[](multi-axis-robot/main.kcl)
|
[](multi-axis-robot/main.kcl)
|
||||||
#### [parametric-bearing-pillow-block](parametric-bearing-pillow-block/main.kcl) ([screenshot](screenshots/parametric-bearing-pillow-block.png))
|
#### [pillow-block-bearing](pillow-block-bearing/main.kcl) ([screenshot](screenshots/pillow-block-bearing.png))
|
||||||
[](parametric-bearing-pillow-block/main.kcl)
|
[](pillow-block-bearing/main.kcl)
|
||||||
#### [pipe](pipe/main.kcl) ([screenshot](screenshots/pipe.png))
|
#### [pipe](pipe/main.kcl) ([screenshot](screenshots/pipe.png))
|
||||||
[](pipe/main.kcl)
|
[](pipe/main.kcl)
|
||||||
#### [pipe-flange-assembly](pipe-flange-assembly/main.kcl) ([screenshot](screenshots/pipe-flange-assembly.png))
|
#### [pipe-flange-assembly](pipe-flange-assembly/main.kcl) ([screenshot](screenshots/pipe-flange-assembly.png))
|
||||||
@ -93,6 +113,8 @@ When you submit a PR to add or modify KCL samples, images will be generated and
|
|||||||
[](pipe-with-bend/main.kcl)
|
[](pipe-with-bend/main.kcl)
|
||||||
#### [poopy-shoe](poopy-shoe/main.kcl) ([screenshot](screenshots/poopy-shoe.png))
|
#### [poopy-shoe](poopy-shoe/main.kcl) ([screenshot](screenshots/poopy-shoe.png))
|
||||||
[](poopy-shoe/main.kcl)
|
[](poopy-shoe/main.kcl)
|
||||||
|
#### [prosthetic-hip](prosthetic-hip/main.kcl) ([screenshot](screenshots/prosthetic-hip.png))
|
||||||
|
[](prosthetic-hip/main.kcl)
|
||||||
#### [router-template-cross-bar](router-template-cross-bar/main.kcl) ([screenshot](screenshots/router-template-cross-bar.png))
|
#### [router-template-cross-bar](router-template-cross-bar/main.kcl) ([screenshot](screenshots/router-template-cross-bar.png))
|
||||||
[](router-template-cross-bar/main.kcl)
|
[](router-template-cross-bar/main.kcl)
|
||||||
#### [router-template-slate](router-template-slate/main.kcl) ([screenshot](screenshots/router-template-slate.png))
|
#### [router-template-slate](router-template-slate/main.kcl) ([screenshot](screenshots/router-template-slate.png))
|
||||||
@ -101,10 +123,20 @@ When you submit a PR to add or modify KCL samples, images will be generated and
|
|||||||
[](sheet-metal-bracket/main.kcl)
|
[](sheet-metal-bracket/main.kcl)
|
||||||
#### [socket-head-cap-screw](socket-head-cap-screw/main.kcl) ([screenshot](screenshots/socket-head-cap-screw.png))
|
#### [socket-head-cap-screw](socket-head-cap-screw/main.kcl) ([screenshot](screenshots/socket-head-cap-screw.png))
|
||||||
[](socket-head-cap-screw/main.kcl)
|
[](socket-head-cap-screw/main.kcl)
|
||||||
|
#### [spur-gear](spur-gear/main.kcl) ([screenshot](screenshots/spur-gear.png))
|
||||||
|
[](spur-gear/main.kcl)
|
||||||
|
#### [spur-reduction-gearset](spur-reduction-gearset/main.kcl) ([screenshot](screenshots/spur-reduction-gearset.png))
|
||||||
|
[](spur-reduction-gearset/main.kcl)
|
||||||
|
#### [surgical-drill-guide](surgical-drill-guide/main.kcl) ([screenshot](screenshots/surgical-drill-guide.png))
|
||||||
|
[](surgical-drill-guide/main.kcl)
|
||||||
|
#### [tooling-nest-block](tooling-nest-block/main.kcl) ([screenshot](screenshots/tooling-nest-block.png))
|
||||||
|
[](tooling-nest-block/main.kcl)
|
||||||
#### [utility-sink](utility-sink/main.kcl) ([screenshot](screenshots/utility-sink.png))
|
#### [utility-sink](utility-sink/main.kcl) ([screenshot](screenshots/utility-sink.png))
|
||||||
[](utility-sink/main.kcl)
|
[](utility-sink/main.kcl)
|
||||||
#### [walkie-talkie](walkie-talkie/main.kcl) ([screenshot](screenshots/walkie-talkie.png))
|
#### [walkie-talkie](walkie-talkie/main.kcl) ([screenshot](screenshots/walkie-talkie.png))
|
||||||
[](walkie-talkie/main.kcl)
|
[](walkie-talkie/main.kcl)
|
||||||
#### [washer](washer/main.kcl) ([screenshot](screenshots/washer.png))
|
#### [washer](washer/main.kcl) ([screenshot](screenshots/washer.png))
|
||||||
[](washer/main.kcl)
|
[](washer/main.kcl)
|
||||||
|
#### [wing-spar](wing-spar/main.kcl) ([screenshot](screenshots/wing-spar.png))
|
||||||
|
[](wing-spar/main.kcl)
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ import * from "parameters.kcl"
|
|||||||
// Bottom mounting face
|
// Bottom mounting face
|
||||||
bottomFaceSketch = startSketchOn(XY)
|
bottomFaceSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|
||||||
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, 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(XY)
|
|||||||
// 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)
|
||||||
|
|
||||||
@ -93,8 +93,8 @@ bodyFanHole = startSketchOn(bodyMiddle, face = END)
|
|||||||
// Top mounting face. Cut a hole in the face to accommodate the fan
|
// Top mounting face. Cut a hole in the face to accommodate the fan
|
||||||
topFaceSketch = startSketchOn(bodyMiddle, face = END)
|
topFaceSketch = startSketchOn(bodyMiddle, face = END)
|
||||||
topHoles = startProfile(topFaceSketch, at = [-fanSize / 2, -fanSize / 2])
|
topHoles = startProfile(topFaceSketch, at = [-fanSize / 2, -fanSize / 2])
|
||||||
|> angledLine(angle = 0, length = fanSize, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = fanSize, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = fanSize, tag = $rectangleSegmentB002)
|
|> angledLine(angle = segAng(rectangleSegmentA002) + 90deg, length = fanSize, tag = $rectangleSegmentB002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -11,11 +11,11 @@ import * from "parameters.kcl"
|
|||||||
fanCenter = startSketchOn(XZ)
|
fanCenter = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-0.0001, fanHeight])
|
|> startProfile(at = [-0.0001, fanHeight])
|
||||||
|> xLine(endAbsolute = -15 + 1.5)
|
|> xLine(endAbsolute = -15 + 1.5)
|
||||||
|> tangentialArc(radius = 1.5, angle = 90)
|
|> tangentialArc(radius = 1.5, angle = 90deg)
|
||||||
|> yLine(endAbsolute = 4.5)
|
|> yLine(endAbsolute = 4.5)
|
||||||
|> xLine(endAbsolute = -13)
|
|> xLine(endAbsolute = -13)
|
||||||
|> yLine(endAbsolute = profileStartY(%) - 5)
|
|> yLine(endAbsolute = profileStartY(%) - 5)
|
||||||
|> tangentialArc(radius = 1, angle = -90)
|
|> tangentialArc(radius = 1, angle = -90deg)
|
||||||
|> xLine(endAbsolute = -1)
|
|> xLine(endAbsolute = -1)
|
||||||
|> yLine(length = 2)
|
|> yLine(length = 2)
|
||||||
|> xLine(length = -0.15)
|
|> xLine(length = -0.15)
|
||||||
@ -39,32 +39,32 @@ fn fanBlade(offsetHeight, startAngle: number(deg)) {
|
|||||||
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 + 1deg, 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()
|
||||||
@ -73,9 +73,9 @@ fn fanBlade(offsetHeight, startAngle: number(deg)) {
|
|||||||
|
|
||||||
// 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 = 0deg)
|
||||||
]
|
]
|
||||||
loft(crossSections)
|
loft(crossSections)
|
||||||
|> appearance(color = "#f3e2d8")
|
|> appearance(color = "#f3e2d8")
|
||||||
@ -83,6 +83,6 @@ loft(crossSections)
|
|||||||
instances = 9,
|
instances = 9,
|
||||||
axis = [0, 0, 1],
|
axis = [0, 0, 1],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
@ -27,13 +27,13 @@ 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 = 0deg, 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
|
||||||
balls = revolve(ballsSketch, axis = X)
|
balls = revolve(ballsSketch, 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,
|
||||||
@ -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,
|
||||||
|
@ -57,9 +57,9 @@ fn connectorSketch(@plane, start) {
|
|||||||
|
|
||||||
export fn connector(@plane, length) {
|
export fn connector(@plane, length) {
|
||||||
connectorSketch(plane, start = [-12, 8])
|
connectorSketch(plane, start = [-12, 8])
|
||||||
|> extrude(length = length)
|
|> extrude(length)
|
||||||
connectorSketch(plane, start = [16, 8])
|
connectorSketch(plane, start = [16, 8])
|
||||||
|> extrude(length = length)
|
|> extrude(length)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,18 +79,18 @@ fn seatSlatSketch(@plane) {
|
|||||||
|
|
||||||
export fn seatSlats(@plane, length) {
|
export fn seatSlats(@plane, length) {
|
||||||
seatSlatSketch(plane)
|
seatSlatSketch(plane)
|
||||||
|> extrude(length = length)
|
|> extrude(length)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn backSlatsSketch(@plane) {
|
fn backSlatsSketch(@plane) {
|
||||||
sketch004 = startSketchOn(plane)
|
sketch004 = startSketchOn(plane)
|
||||||
|> startProfile(at = [22, 38.5])
|
|> startProfile(at = [22, 38.5])
|
||||||
|> angledLine(angle = 173, length = 2)
|
|> angledLine(angle = 173deg, length = 2)
|
||||||
|> line(end = [-1.74, 2.03])
|
|> line(end = [-1.74, 2.03])
|
||||||
|> angledLine(angle = 82, length = 6.6)
|
|> angledLine(angle = 82deg, length = 6.6)
|
||||||
|> line(end = [2.23, 1.42])
|
|> line(end = [2.23, 1.42])
|
||||||
|> angledLine(angle = -7, length = 2)
|
|> angledLine(angle = -7deg, length = 2)
|
||||||
|> line(endAbsolute = profileStart(%))
|
|> line(endAbsolute = profileStart(%))
|
||||||
|> close()
|
|> close()
|
||||||
|> patternLinear2d(instances = 2, distance = 11, axis = [-0.137, -1])
|
|> patternLinear2d(instances = 2, distance = 11, axis = [-0.137, -1])
|
||||||
@ -99,7 +99,7 @@ fn backSlatsSketch(@plane) {
|
|||||||
|
|
||||||
export fn backSlats(@plane, length) {
|
export fn backSlats(@plane, length) {
|
||||||
b = backSlatsSketch(plane)
|
b = backSlatsSketch(plane)
|
||||||
|> extrude(length = length)
|
|> extrude(length)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ fn armRestPath(@plane) {
|
|||||||
sketch005 = startSketchOn(plane)
|
sketch005 = startSketchOn(plane)
|
||||||
|> startProfile(at = [20, 33])
|
|> startProfile(at = [20, 33])
|
||||||
|> xLine(length = -20)
|
|> xLine(length = -20)
|
||||||
|> arc(angleStart = 90, angleEnd = 180, radius = 10)
|
|> arc(angleStart = 90deg, angleEnd = 180deg, radius = 10)
|
||||||
return sketch005
|
return sketch005
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
public/kcl-samples/bone-plate/main.kcl
Normal file
55
public/kcl-samples/bone-plate/main.kcl
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Bone Plate
|
||||||
|
// A bone plate is a medical device used in orthopedics to stabilize and fix bone fractures during the healing process. They are typically made of stainless steel or titanium and are secured to the bone with screws. Bone plates come in various types, including locking, compression, and bridge plates, each with specific applications
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = mm)
|
||||||
|
|
||||||
|
// Define parameters
|
||||||
|
boltSize = 4.5
|
||||||
|
|
||||||
|
// Revolve the profile of a compression plate designed to fit a bone
|
||||||
|
plateRevolve = startSketchOn(YZ)
|
||||||
|
|> startProfile(at = [22.9, 0])
|
||||||
|
|> arc(angleStart = 180deg, angleEnd = 176deg, radius = 120)
|
||||||
|
|> arc(angleStart = -60deg, angleEnd = 54deg, radius = 5)
|
||||||
|
|> arc(angleStart = 180deg, angleEnd = 176deg, radius = 120)
|
||||||
|
|> arc(angleStart = -60deg, angleEnd = 54deg, radius = 5)
|
||||||
|
|> arc(angleStart = 180deg, angleEnd = 176deg, radius = 120)
|
||||||
|
|> arc(angleStart = -60deg, angleEnd = 54deg, radius = 5)
|
||||||
|
|> arc(angleStart = 180deg, angleEnd = 174deg, radius = 170)
|
||||||
|
|> tangentialArc(endAbsolute = [41.8, 91.88])
|
||||||
|
|> tangentialArc(endAbsolute = [56.92, 117.08], tag = $seg01)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg01), length = 23.16)
|
||||||
|
|> tangentialArc(endAbsolute = [60.93, 140.44], tag = $seg02)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg02), length = 25.65)
|
||||||
|
|> tangentialArc(endAbsolute = [48.35, 85.53])
|
||||||
|
|> tangentialArc(endAbsolute = [35.2, 67.73], tag = $seg03)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg03), length = 49.06)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
|> revolve(axis = Y, angle = 65deg, symmetric = true)
|
||||||
|
|
||||||
|
// Create a hole sketch with the size and location of each bolt hole
|
||||||
|
holeSketch = startSketchOn(XZ)
|
||||||
|
hole01 = circle(holeSketch, center = [0, 12.25], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole02 = circle(holeSketch, center = [0, 29.5], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole03 = circle(holeSketch, center = [0, 46.25], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole04 = circle(holeSketch, center = [0, 77], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole05 = circle(holeSketch, center = [0, 100], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole06 = circle(holeSketch, center = [0, 130], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole07 = circle(holeSketch, center = [-20, 130], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
hole08 = circle(holeSketch, center = [20, 130], radius = boltSize / 2)
|
||||||
|
|> extrude(length = -100)
|
||||||
|
|
||||||
|
// Cut each guiding clearance hole from the bone plate
|
||||||
|
solid001 = subtract([plateRevolve], tools = union([hole01, hole02]))
|
||||||
|
solid002 = subtract([solid001], tools = union([hole03, hole04]))
|
||||||
|
solid003 = subtract([solid002], tools = union([hole05, hole06]))
|
||||||
|
solid004 = subtract([solid003], tools = union([hole07, hole08]))
|
@ -17,44 +17,44 @@ brakeCaliperSketch = startSketchOn(XY)
|
|||||||
0,
|
0,
|
||||||
rotorTotalThickness + caliperTolerance - caliperInnerEdgeRadius
|
rotorTotalThickness + caliperTolerance - caliperInnerEdgeRadius
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = 90, radius = caliperInnerEdgeRadius)
|
|> tangentialArc(angle = 90deg, radius = caliperInnerEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
-caliperPadLength + 2 * caliperInnerEdgeRadius,
|
-caliperPadLength + 2 * caliperInnerEdgeRadius,
|
||||||
0
|
0
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = caliperInnerEdgeRadius)
|
|> tangentialArc(angle = -90deg, radius = caliperInnerEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
0,
|
0,
|
||||||
caliperThickness - (caliperInnerEdgeRadius * 2)
|
caliperThickness - (caliperInnerEdgeRadius * 2)
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = caliperInnerEdgeRadius)
|
|> tangentialArc(angle = -90deg, radius = caliperInnerEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
caliperPadLength + caliperThickness - caliperOuterEdgeRadius - caliperInnerEdgeRadius,
|
caliperPadLength + caliperThickness - caliperOuterEdgeRadius - caliperInnerEdgeRadius,
|
||||||
0
|
0
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = caliperOuterEdgeRadius)
|
|> tangentialArc(angle = -90deg, radius = caliperOuterEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
0,
|
0,
|
||||||
-2 * caliperTolerance - (2 * caliperThickness) - rotorTotalThickness + 2 * caliperOuterEdgeRadius
|
-2 * caliperTolerance - (2 * caliperThickness) - rotorTotalThickness + 2 * caliperOuterEdgeRadius
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = caliperOuterEdgeRadius)
|
|> tangentialArc(angle = -90deg, radius = caliperOuterEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
-caliperPadLength - caliperThickness + caliperOuterEdgeRadius + caliperInnerEdgeRadius,
|
-caliperPadLength - caliperThickness + caliperOuterEdgeRadius + caliperInnerEdgeRadius,
|
||||||
0
|
0
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = caliperInnerEdgeRadius)
|
|> tangentialArc(angle = -90deg, radius = caliperInnerEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
0,
|
0,
|
||||||
caliperThickness - (2 * caliperInnerEdgeRadius)
|
caliperThickness - (2 * caliperInnerEdgeRadius)
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = caliperInnerEdgeRadius)
|
|> tangentialArc(angle = -90deg, radius = caliperInnerEdgeRadius)
|
||||||
|> line(end = [
|
|> line(end = [
|
||||||
caliperPadLength - (2 * caliperInnerEdgeRadius),
|
caliperPadLength - (2 * caliperInnerEdgeRadius),
|
||||||
0
|
0
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = 90, radius = caliperInnerEdgeRadius)
|
|> tangentialArc(angle = 90deg, radius = caliperInnerEdgeRadius)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
// Revolve the brake caliper sketch
|
// Revolve the brake caliper sketch
|
||||||
revolve(brakeCaliperSketch, axis = Y, angle = -70)
|
revolve(brakeCaliperSketch, axis = Y, angle = -70deg)
|
||||||
|> appearance(color = "#c82d2d", metalness = 90, roughness = 90)
|
|> appearance(color = "#c82d2d", metalness = 90, roughness = 90)
|
||||||
|
@ -17,7 +17,7 @@ tireSketch = startSketchOn(XY)
|
|||||||
],
|
],
|
||||||
tag = $edge1,
|
tag = $edge1,
|
||||||
)
|
)
|
||||||
|> tangentialArc(angle = -90, radius = bendRadius)
|
|> tangentialArc(angle = -90deg, radius = bendRadius)
|
||||||
|> line(endAbsolute = [
|
|> line(endAbsolute = [
|
||||||
tireOuterDiameter / 2,
|
tireOuterDiameter / 2,
|
||||||
tireDepth / 2 - tireTreadOffset
|
tireDepth / 2 - tireTreadOffset
|
||||||
@ -36,7 +36,7 @@ tireSketch = startSketchOn(XY)
|
|||||||
tireOuterDiameter / 2,
|
tireOuterDiameter / 2,
|
||||||
-tireDepth / 2 + bendRadius
|
-tireDepth / 2 + bendRadius
|
||||||
])
|
])
|
||||||
|> tangentialArc(angle = -90, radius = bendRadius)
|
|> tangentialArc(angle = -90deg, radius = bendRadius)
|
||||||
|> line(endAbsolute = [tireInnerDiameter / 2, -tireDepth / 2], tag = $edge2)
|
|> line(endAbsolute = [tireInnerDiameter / 2, -tireDepth / 2], tag = $edge2)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ customPlane = {
|
|||||||
fn lug(plane, length, diameter) {
|
fn lug(plane, length, diameter) {
|
||||||
lugSketch = startSketchOn(customPlane)
|
lugSketch = startSketchOn(customPlane)
|
||||||
|> startProfile(at = [0 + diameter / 2, 0])
|
|> startProfile(at = [0 + diameter / 2, 0])
|
||||||
|> angledLine(angle = 70, lengthY = lugHeadLength)
|
|> angledLine(angle = 70deg, lengthY = lugHeadLength)
|
||||||
|> xLine(endAbsolute = lugDiameter / 2)
|
|> xLine(endAbsolute = lugDiameter / 2)
|
||||||
|> yLine(endAbsolute = lugLength)
|
|> yLine(endAbsolute = lugLength)
|
||||||
|> tangentialArc(angle = 90, radius = 3mm)
|
|> tangentialArc(angle = 90deg, radius = 3mm)
|
||||||
|> xLine(endAbsolute = 0 + .001, tag = $c1)
|
|> xLine(endAbsolute = 0 + .001, tag = $c1)
|
||||||
|> yLine(endAbsolute = lugThreadDepth)
|
|> yLine(endAbsolute = lugThreadDepth)
|
||||||
|> xLine(endAbsolute = lugThreadDiameter)
|
|> xLine(endAbsolute = lugThreadDiameter)
|
||||||
|
@ -24,7 +24,7 @@ carWheel
|
|||||||
// Place the lug nuts
|
// Place the lug nuts
|
||||||
lugNut
|
lugNut
|
||||||
|> patternCircular3d(
|
|> patternCircular3d(
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
axis = [0, 1, 0],
|
axis = [0, 1, 0],
|
||||||
center = [0, 0, 0],
|
center = [0, 0, 0],
|
||||||
instances = lugCount,
|
instances = lugCount,
|
||||||
|
@ -12,7 +12,7 @@ export wheelWidth = 9.5
|
|||||||
export wheelDiameter = 19
|
export wheelDiameter = 19
|
||||||
export spokeCount = 6
|
export spokeCount = 6
|
||||||
export spokeGap = 0.2
|
export spokeGap = 0.2
|
||||||
export spokeAngle = 0.02
|
export spokeAngle = 0.02deg
|
||||||
export spokeThickness = 0.95
|
export spokeThickness = 0.95
|
||||||
|
|
||||||
// Lug Nut
|
// Lug Nut
|
||||||
|
67
public/kcl-samples/cold-plate/main.kcl
Normal file
67
public/kcl-samples/cold-plate/main.kcl
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Cold Plate
|
||||||
|
// A cold plate is a thermal management device used to remove heat from a device or component, typically by transferring heat to a liquid coolant that flows through the plate. It's a conductive cooling solution, commonly made of materials like aluminum or copper, with internal channels or tubes for the coolant
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
// Define parameters
|
||||||
|
tubeDiameter = 5 / 8
|
||||||
|
wallThickness = 0.080
|
||||||
|
bendRadius = 1
|
||||||
|
|
||||||
|
// Create the cold plate with indentions to secure each pass of the brazed copper tube
|
||||||
|
coldPlate = startSketchOn(YZ)
|
||||||
|
|> startProfile(at = [0, tubeDiameter * 2])
|
||||||
|
|> xLine(length = bendRadius - (tubeDiameter / 2))
|
||||||
|
|> yLine(length = -tubeDiameter)
|
||||||
|
|> tangentialArc(angle = 180deg, radius = tubeDiameter / 2)
|
||||||
|
|> yLine(length = tubeDiameter)
|
||||||
|
|> xLine(length = bendRadius * 2 - tubeDiameter, tag = $seg07)
|
||||||
|
|> yLine(length = -tubeDiameter, tag = $seg09)
|
||||||
|
|> tangentialArc(angle = 180deg, radius = tubeDiameter / 2)
|
||||||
|
|> yLine(length = tubeDiameter, tag = $seg08)
|
||||||
|
|> xLine(length = bendRadius - (tubeDiameter / 2))
|
||||||
|
|> angledLine(angle = -77deg, length = tubeDiameter / 3)
|
||||||
|
|> tangentialArc(angle = 77deg, radius = tubeDiameter, tag = $seg01)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg01), length = 1)
|
||||||
|
|> yLine(endAbsolute = 0)
|
||||||
|
|> xLine(endAbsolute = 0)
|
||||||
|
|> mirror2d(axis = Y)
|
||||||
|
|> close()
|
||||||
|
|> extrude(length = 10, symmetric = true)
|
||||||
|
|
||||||
|
// Sketch the path for the copper tube to follow
|
||||||
|
copperTubePath = startSketchOn(offsetPlane(XY, offset = tubeDiameter))
|
||||||
|
|> startProfile(at = [-7.35, -bendRadius * 3])
|
||||||
|
|> xLine(length = 14.13, tag = $seg05)
|
||||||
|
|> tangentialArc(angle = 180deg, radius = bendRadius, tag = $seg02)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg02), length = 13.02, tag = $seg06)
|
||||||
|
|> tangentialArc(angle = -180deg, radius = bendRadius, tag = $seg03)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg03), length = segLen(seg06))
|
||||||
|
|> tangentialArc(angle = 180deg, radius = bendRadius, tag = $seg04)
|
||||||
|
|> angledLine(angle = tangentToEnd(seg04), length = segLen(seg05))
|
||||||
|
|
||||||
|
// Create the profile for the inner and outer diameter of the hollow copper tube
|
||||||
|
tubeWall = startSketchOn(offsetPlane(YZ, offset = -7.35))
|
||||||
|
|> circle(center = [-bendRadius * 3, tubeDiameter], radius = tubeDiameter / 2)
|
||||||
|
|> subtract2d(%, tool = circle(center = [-bendRadius * 3, tubeDiameter], radius = tubeDiameter / 2 - wallThickness))
|
||||||
|
|> sweep(path = copperTubePath)
|
||||||
|
|> appearance(color = "#b81b0a")
|
||||||
|
|
||||||
|
// Model a brazed cap to cover each tube. Constrain the caps using the walls of the plate
|
||||||
|
brazedCap = startSketchOn(YZ)
|
||||||
|
|> startProfile(at = segEnd(seg07))
|
||||||
|
|> arc(interiorAbsolute = [bendRadius * 3, tubeDiameter * 1.85], endAbsolute = segEnd(seg08))
|
||||||
|
|> yLine(endAbsolute = segStartY(seg08))
|
||||||
|
|> arc(
|
||||||
|
interiorAbsolute = [
|
||||||
|
bendRadius * 3,
|
||||||
|
segEndY(seg09) + tubeDiameter / 2
|
||||||
|
],
|
||||||
|
endAbsolute = segEnd(seg09),
|
||||||
|
)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
|> extrude(length = 10, symmetric = true)
|
||||||
|
|> patternLinear3d(instances = 4, distance = bendRadius * 2, axis = [0, -1, 0])
|
||||||
|
|> appearance(color = "#6b261e")
|
@ -23,8 +23,8 @@ tealPlane = offsetPlane(YZ, offset = -halfSize)
|
|||||||
fn sketchRectangle(profile, color) {
|
fn sketchRectangle(profile, color) {
|
||||||
return profile
|
return profile
|
||||||
|> startProfile(at = [-halfSize, halfSize])
|
|> startProfile(at = [-halfSize, halfSize])
|
||||||
|> angledLine(angle = 0, length = size, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = size, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = size, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = size, 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()
|
||||||
|
120
public/kcl-samples/counterdrilled-weldment/main.kcl
Normal file
120
public/kcl-samples/counterdrilled-weldment/main.kcl
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
// Counterdrilled Weldment
|
||||||
|
// A metal weldment consisting of a counterdrilled plate, a centrally mounted housing tube, and four structural support fins.
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
// Define parameters
|
||||||
|
boltSpacingX = 5
|
||||||
|
boltSpacingY = 3
|
||||||
|
boltDiameter = 1 / 4
|
||||||
|
counterdrillDiameter = 7 / 16
|
||||||
|
counterdrillDepth = 3 / 16
|
||||||
|
tubeInnerDiameter = 1 + 1 / 4
|
||||||
|
tubeThickness = 0.115
|
||||||
|
tubeHeight = 2
|
||||||
|
stockThickness = .5
|
||||||
|
|
||||||
|
// Calculate the dimensions of the block using the specified bolt spacing. The size of the block can be defined by adding a multiple of the counterdrill diameter to the bolt spacing
|
||||||
|
blockLength = boltSpacingX + boltDiameter * 6
|
||||||
|
blockWidth = boltSpacingY + boltDiameter * 6
|
||||||
|
|
||||||
|
// Draw the base plate
|
||||||
|
plateSketch = startSketchOn(XY)
|
||||||
|
|> startProfile(at = [-blockLength / 2, -blockWidth / 2])
|
||||||
|
|> angledLine(angle = 0deg, length = blockLength, tag = $rectangleSegmentA001)
|
||||||
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = blockWidth, tag = $rectangleSegmentB001)
|
||||||
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
||||||
|
|> close()
|
||||||
|
|> subtract2d(tool = circle(center = [0, 0], radius = tubeInnerDiameter / 2))
|
||||||
|
plateBody = extrude(plateSketch, length = stockThickness)
|
||||||
|
|> chamfer(
|
||||||
|
length = boltDiameter * 2,
|
||||||
|
tags = [
|
||||||
|
getNextAdjacentEdge(rectangleSegmentB001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentA001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentC001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentD001)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
// Define hole positions
|
||||||
|
holePositions = [
|
||||||
|
[-boltSpacingX / 2, -boltSpacingY / 2],
|
||||||
|
[-boltSpacingX / 2, boltSpacingY / 2],
|
||||||
|
[boltSpacingX / 2, -boltSpacingY / 2],
|
||||||
|
[boltSpacingX / 2, boltSpacingY / 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
// Function to create a counterdrilled hole
|
||||||
|
fn counterdrill(@holePosition) {
|
||||||
|
cbdrill = startSketchOn(plateBody, face = END)
|
||||||
|
|> circle(center = holePosition, radius = counterdrillDiameter / 2)
|
||||||
|
|> extrude(length = -counterdrillDepth)
|
||||||
|
cbBolt = startSketchOn(cbdrill, face = START)
|
||||||
|
|> circle(center = holePosition, radius = boltDiameter / 2, tag = $hole01)
|
||||||
|
|> extrude(length = -stockThickness + counterdrillDepth)
|
||||||
|
// Use a chamfer to create a 90-degree counterdrill edge
|
||||||
|
|> chamfer(length = (counterdrillDiameter - boltDiameter) / 2 * sqrt(2), tags = [hole01])
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place a counterdrilled hole at each bolt hole position
|
||||||
|
map(holePositions, f = counterdrill)
|
||||||
|
|
||||||
|
// Drill a small pin hole in the side of the tube
|
||||||
|
pinhole = startSketchOn(YZ)
|
||||||
|
|> circle(center = [0, 2.2], radius = 0.125)
|
||||||
|
|> extrude(length = -10)
|
||||||
|
|
||||||
|
// Model the central tube and subtract the pin hole
|
||||||
|
centralTube = startSketchOn(offsetPlane(XY, offset = stockThickness))
|
||||||
|
|> circle(center = [0, 0], radius = tubeInnerDiameter / 2 + tubeThickness)
|
||||||
|
|> subtract2d(tool = circle(center = [0, 0], radius = tubeInnerDiameter / 2))
|
||||||
|
|> extrude(length = tubeHeight)
|
||||||
|
|> subtract(tools = [pinhole])
|
||||||
|
|
||||||
|
// Create a function to create a fin which spans from the central tube to the bolt hole
|
||||||
|
fn fin(@i) {
|
||||||
|
diagPlane = {
|
||||||
|
origin = [0.0, 0.0, 0.0],
|
||||||
|
xAxis = [
|
||||||
|
boltSpacingX / 2 * i,
|
||||||
|
boltSpacingY / 2,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
yAxis = [0.0, 0.0, 1.0]
|
||||||
|
}
|
||||||
|
|
||||||
|
finSketch = startSketchOn(diagPlane)
|
||||||
|
|> startProfile(at = [
|
||||||
|
tubeInnerDiameter / 2 + tubeThickness,
|
||||||
|
stockThickness
|
||||||
|
])
|
||||||
|
|> xLine(endAbsolute = sqrt((boltSpacingX / 2) ^ 2 + (boltSpacingY / 2) ^ 2) - counterdrillDiameter)
|
||||||
|
|> yLine(length = 0.15)
|
||||||
|
|> line(endAbsolute = [
|
||||||
|
profileStartX(%) + 0.15,
|
||||||
|
stockThickness + tubeHeight * .8
|
||||||
|
])
|
||||||
|
|> xLine(length = -0.15)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
|> extrude(length = tubeThickness, symmetric = true)
|
||||||
|
|
||||||
|
// Use a circular pattern to create an identical fin on the opposite side
|
||||||
|
otherFin = patternCircular3d(
|
||||||
|
finSketch,
|
||||||
|
instances = 2,
|
||||||
|
axis = [0, 0, 1],
|
||||||
|
center = [0, 0, 0],
|
||||||
|
arcDegrees = 360,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place a pair of support fins along each diagonal axis of the bolt pattern
|
||||||
|
fin(1)
|
||||||
|
fin(-1)
|
50
public/kcl-samples/countersunk-plate/main.kcl
Normal file
50
public/kcl-samples/countersunk-plate/main.kcl
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Plate with countersunk holes
|
||||||
|
// A small mounting plate with a countersunk hole at each end
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = in)
|
||||||
|
|
||||||
|
// Define parameters
|
||||||
|
boltSpacing = 5
|
||||||
|
boltDiameter = 1 / 4
|
||||||
|
centerHoleDiameter = 1 + 3 / 4
|
||||||
|
plateThickness = 0.375
|
||||||
|
|
||||||
|
// Check that the plate is thick enough to countersink a hole
|
||||||
|
// assertGreaterThan(plateThickness, boltDiameter, "This plate is not thick enough for the necessary countersink dimensions")
|
||||||
|
|
||||||
|
// A bit of math to calculate the tangent line between the two diameters
|
||||||
|
r1 = centerHoleDiameter / 2 * 1.5 + .35
|
||||||
|
r2 = boltDiameter * 2 + .25
|
||||||
|
d = boltSpacing / 2
|
||||||
|
tangentAngle = asin((r1 - r2) / d)
|
||||||
|
tangentLength = (r1 - r2) / tan(tangentAngle)
|
||||||
|
|
||||||
|
plateBody = startSketchOn(XY)
|
||||||
|
// Use polar coordinates to start the sketch at the tangent point of the larger radius
|
||||||
|
|> startProfile(at = polar(angle = 90deg - tangentAngle, length = r1))
|
||||||
|
|> angledLine(angle = -tangentAngle, length = tangentLength)
|
||||||
|
|> tangentialArc(radius = r2, angle = (tangentAngle - 90deg) * 2)
|
||||||
|
|> angledLine(angle = tangentAngle, length = -tangentLength)
|
||||||
|
|> tangentialArc(radius = r1, angle = -tangentAngle * 2)
|
||||||
|
|> angledLine(angle = -tangentAngle, length = -tangentLength)
|
||||||
|
|> tangentialArc(radius = r2, angle = (tangentAngle - 90deg) * 2)
|
||||||
|
|> angledLine(angle = tangentAngle, length = tangentLength)
|
||||||
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
|> subtract2d(tool = circle(center = [0, 0], radius = centerHoleDiameter / 2 * 1.5))
|
||||||
|
|> extrude(%, length = plateThickness)
|
||||||
|
|
||||||
|
// Function to create a countersunk hole
|
||||||
|
fn countersink(@holePosition) {
|
||||||
|
startSketchOn(plateBody, face = END)
|
||||||
|
|> circle(center = [holePosition, 0], radius = boltDiameter / 2, tag = $hole01)
|
||||||
|
|> extrude(length = -plateThickness)
|
||||||
|
// Use a chamfer to create a 90-degree countersink
|
||||||
|
|> chamfer(length = boltDiameter, tags = [hole01])
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place a countersunk hole at each bolt hole position
|
||||||
|
countersink(-boltSpacing / 2)
|
||||||
|
countersink(boltSpacing / 2)
|
153
public/kcl-samples/cpu-cooler/fan-housing.kcl
Normal file
153
public/kcl-samples/cpu-cooler/fan-housing.kcl
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Fan Housing
|
||||||
|
// The plastic housing that contains the fan and the motor
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = mm)
|
||||||
|
|
||||||
|
// Import parameters
|
||||||
|
import * from "parameters.kcl"
|
||||||
|
|
||||||
|
// Model the housing which holds the motor, the fan, and the mounting provisions
|
||||||
|
// Bottom mounting face
|
||||||
|
bottomFaceSketch = startSketchOn(YZ)
|
||||||
|
|> startProfile(at = [-fanSize / 2, -fanSize / 2])
|
||||||
|
|> angledLine(angle = 0deg, length = fanSize, tag = $rectangleSegmentA001)
|
||||||
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90deg, length = fanSize, tag = $rectangleSegmentB001)
|
||||||
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD001)
|
||||||
|
|> close()
|
||||||
|
|> subtract2d(tool = circle(center = [0, 0], radius = 4))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
mountingHoleSpacing / 2,
|
||||||
|
mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
-mountingHoleSpacing / 2,
|
||||||
|
mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
mountingHoleSpacing / 2,
|
||||||
|
-mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
-mountingHoleSpacing / 2,
|
||||||
|
-mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> extrude(length = 4)
|
||||||
|
|
||||||
|
// Add large openings to the bottom face to allow airflow through the fan
|
||||||
|
airflowPattern = startSketchOn(bottomFaceSketch, face = END)
|
||||||
|
|> startProfile(at = [fanSize * 7 / 25, -fanSize * 9 / 25])
|
||||||
|
|> angledLine(angle = 140deg, length = fanSize * 12 / 25, tag = $seg01)
|
||||||
|
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|
||||||
|
|> angledLine(angle = -130deg, length = fanSize * 8 / 25)
|
||||||
|
|> tangentialArc(radius = fanSize * 1 / 50, angle = 90deg)
|
||||||
|
|> angledLine(angle = segAng(seg01) + 180deg, length = fanSize * 2 / 25)
|
||||||
|
|> tangentialArc(radius = fanSize * 8 / 25, angle = 40deg)
|
||||||
|
|> xLine(length = fanSize * 3 / 25)
|
||||||
|
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
|> patternCircular2d(
|
||||||
|
instances = 4,
|
||||||
|
center = [0, 0],
|
||||||
|
arcDegrees = 360,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
||||||
|
|> extrude(length = -4)
|
||||||
|
|
||||||
|
// Create the middle segment of the fan housing body
|
||||||
|
housingMiddleLength = fanSize / 3
|
||||||
|
housingMiddleRadius = fanSize / 3 - 1
|
||||||
|
bodyMiddle = startSketchOn(bottomFaceSketch, face = END)
|
||||||
|
|> startProfile(at = [
|
||||||
|
housingMiddleLength / 2,
|
||||||
|
-housingMiddleLength / 2 - housingMiddleRadius
|
||||||
|
])
|
||||||
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|
|> yLine(length = housingMiddleLength)
|
||||||
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|
|> xLine(length = -housingMiddleLength)
|
||||||
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|
|> yLine(length = -housingMiddleLength)
|
||||||
|
|> tangentialArc(radius = housingMiddleRadius, angle = 90deg)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> extrude(length = fanHeight - 4 - 4)
|
||||||
|
|
||||||
|
// Cut a hole in the body to accommodate the fan
|
||||||
|
bodyFanHole = startSketchOn(bodyMiddle, face = END)
|
||||||
|
|> circle(center = [0, 0], radius = fanSize * 23 / 50)
|
||||||
|
|> extrude(length = -(fanHeight - 4 - 4))
|
||||||
|
|
||||||
|
// Top mounting face. Cut a hole in the face to accommodate the fan
|
||||||
|
topFaceSketch = startSketchOn(bodyMiddle, face = END)
|
||||||
|
topHoles = startProfile(topFaceSketch, at = [-fanSize / 2, -fanSize / 2])
|
||||||
|
|> angledLine(angle = 0deg, length = fanSize, tag = $rectangleSegmentA002)
|
||||||
|
|> angledLine(angle = segAng(rectangleSegmentA002) + 90deg, length = fanSize, tag = $rectangleSegmentB002)
|
||||||
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002), tag = $rectangleSegmentC002)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $rectangleSegmentD002)
|
||||||
|
|> close()
|
||||||
|
|> subtract2d(tool = circle(center = [0, 0], radius = fanSize * 23 / 50))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
mountingHoleSpacing / 2,
|
||||||
|
mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
-mountingHoleSpacing / 2,
|
||||||
|
mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
mountingHoleSpacing / 2,
|
||||||
|
-mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> subtract2d(tool = circle(
|
||||||
|
center = [
|
||||||
|
-mountingHoleSpacing / 2,
|
||||||
|
-mountingHoleSpacing / 2
|
||||||
|
],
|
||||||
|
radius = mountingHoleSize / 2,
|
||||||
|
))
|
||||||
|
|> extrude(length = 4)
|
||||||
|
|
||||||
|
// Create a housing for the electric motor to sit
|
||||||
|
motorHousing = startSketchOn(bottomFaceSketch, face = END)
|
||||||
|
|> circle(center = [0, 0], radius = 11.2)
|
||||||
|
|> extrude(length = 16)
|
||||||
|
|
||||||
|
startSketchOn(motorHousing, face = END)
|
||||||
|
|> circle(center = [0, 0], radius = 10)
|
||||||
|
|> extrude(length = -16)
|
||||||
|
|> appearance(color = "#a55e2c")
|
||||||
|
|> fillet(
|
||||||
|
radius = abs(fanSize - mountingHoleSpacing) / 2,
|
||||||
|
tags = [
|
||||||
|
getNextAdjacentEdge(rectangleSegmentA001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentB001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentC001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentD001),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentA002),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentB002),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentC002),
|
||||||
|
getNextAdjacentEdge(rectangleSegmentD002)
|
||||||
|
],
|
||||||
|
)
|
71
public/kcl-samples/cpu-cooler/fan.kcl
Normal file
71
public/kcl-samples/cpu-cooler/fan.kcl
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Fan
|
||||||
|
// Spinning axial fan that moves airflow
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = mm)
|
||||||
|
|
||||||
|
// Import parameters
|
||||||
|
import * from "parameters.kcl"
|
||||||
|
|
||||||
|
// Model the center of the fan
|
||||||
|
fanCenter = startSketchOn(YZ)
|
||||||
|
|> circle(center = [0, 0], radius = fanHeight / 2, tag = $centerBend)
|
||||||
|
|> extrude(%, length = fanHeight)
|
||||||
|
|> fillet(radius = 1.5, tags = [getOppositeEdge(centerBend)])
|
||||||
|
|
||||||
|
// Create a function for a lofted fan blade cross section that rotates about the center hub of the fan
|
||||||
|
fn fanBlade(offsetHeight, startAngle) {
|
||||||
|
fanBlade = startSketchOn(offsetPlane(YZ, offset = offsetHeight))
|
||||||
|
|> startProfile(at = [
|
||||||
|
15 * cos(startAngle),
|
||||||
|
15 * sin(startAngle)
|
||||||
|
])
|
||||||
|
|> arc(angleStart = startAngle, angleEnd = startAngle + 14deg, radius = 15)
|
||||||
|
|> arc(
|
||||||
|
endAbsolute = [
|
||||||
|
fanSize * 22 / 50 * cos(startAngle - 20deg),
|
||||||
|
fanSize * 22 / 50 * sin(startAngle - 20deg)
|
||||||
|
],
|
||||||
|
interiorAbsolute = [
|
||||||
|
fanSize * 11 / 50 * cos(startAngle + 3deg),
|
||||||
|
fanSize * 11 / 50 * sin(startAngle + 3deg)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|> arc(
|
||||||
|
endAbsolute = [
|
||||||
|
fanSize * 22 / 50 * cos(startAngle - 24deg),
|
||||||
|
fanSize * 22 / 50 * sin(startAngle - 24deg)
|
||||||
|
],
|
||||||
|
interiorAbsolute = [
|
||||||
|
fanSize * 22 / 50 * cos(startAngle - 22deg),
|
||||||
|
fanSize * 22 / 50 * sin(startAngle - 22deg)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|> arc(
|
||||||
|
endAbsolute = [profileStartX(%), profileStartY(%)],
|
||||||
|
interiorAbsolute = [
|
||||||
|
fanSize * 11 / 50 * cos(startAngle - 5deg),
|
||||||
|
fanSize * 11 / 50 * sin(startAngle - 5deg)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|> close()
|
||||||
|
return fanBlade
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loft the fan blade cross sections into a single blade, then pattern them about the fan center
|
||||||
|
crossSections = [
|
||||||
|
fanBlade(offsetHeight = 4.5, startAngle = 50deg),
|
||||||
|
fanBlade(offsetHeight = (fanHeight - 2 - 4) / 2, startAngle = 30deg),
|
||||||
|
fanBlade(offsetHeight = fanHeight - 2, startAngle = 0deg)
|
||||||
|
]
|
||||||
|
bladeLoft = loft(crossSections)
|
||||||
|
|> patternCircular3d(
|
||||||
|
instances = 9,
|
||||||
|
axis = [1, 0, 0],
|
||||||
|
center = [0, 0, 0],
|
||||||
|
arcDegrees = 360deg,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
||||||
|
|
||||||
|
[fanCenter, bladeLoft]
|
||||||
|
|> appearance(color = "#110803")
|
171
public/kcl-samples/cpu-cooler/heat-sink.kcl
Normal file
171
public/kcl-samples/cpu-cooler/heat-sink.kcl
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// Heat Sink
|
||||||
|
// Conductive metal device made from brazed tubes and fins
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = mm)
|
||||||
|
|
||||||
|
// Import parameters
|
||||||
|
import * from "parameters.kcl"
|
||||||
|
|
||||||
|
// Draw the sweep path for the outermost tubes
|
||||||
|
endTubePath = startSketchOn(offsetPlane(YZ, offset = -20))
|
||||||
|
|> startProfile(at = [fanSize / 4, fanSize + 38])
|
||||||
|
|> yLine(endAbsolute = bendRadius + 10, tag = $seg01)
|
||||||
|
|> tangentialArc(radius = bendRadius, angle = -90deg)
|
||||||
|
|> xLine(endAbsolute = 0, tag = $seg02)
|
||||||
|
|> xLine(length = -segLen(seg02))
|
||||||
|
|> tangentialArc(radius = bendRadius, angle = -90deg)
|
||||||
|
|> yLine(length = segLen(seg01))
|
||||||
|
|
||||||
|
// Sweep and translate the outermost tube on each end
|
||||||
|
endTube = startSketchOn(offsetPlane(XY, offset = fanSize + 38))
|
||||||
|
|> circle(center = [-20, fanSize / 4], radius = 3)
|
||||||
|
|> subtract2d(tool = circle(center = [-20, fanSize / 4], radius = 2.5))
|
||||||
|
|> sweep(path = endTubePath)
|
||||||
|
|> patternCircular3d(
|
||||||
|
%,
|
||||||
|
instances = 2,
|
||||||
|
axis = [0, 0, 1],
|
||||||
|
center = [0, 0, 0],
|
||||||
|
arcDegrees = 360deg,
|
||||||
|
rotateDuplicates = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Draw the sweep path for the 4 interior tubes
|
||||||
|
centerTubePath = startSketchOn(offsetPlane(YZ, offset = -4))
|
||||||
|
|> startProfile(at = [fanSize / 2.67, fanSize + 38])
|
||||||
|
|> yLine(endAbsolute = bendRadius + 15 + 10)
|
||||||
|
|> tangentialArc(radius = bendRadius, angle = -45deg)
|
||||||
|
|> angledLine(angle = -135deg, lengthY = 15)
|
||||||
|
|> tangentialArc(radius = bendRadius, angle = -45deg)
|
||||||
|
|> xLine(endAbsolute = 0, tag = $seg03)
|
||||||
|
|> xLine(length = -segLen(seg03))
|
||||||
|
|> tangentialArc(radius = bendRadius, angle = -155deg)
|
||||||
|
|> tangentialArc(radius = bendRadius, angle = 65deg)
|
||||||
|
|> yLine(endAbsolute = fanSize + 38)
|
||||||
|
|
||||||
|
// Draw the profile and sweep the 4 interior tubes
|
||||||
|
centerTube = startSketchOn(offsetPlane(XY, offset = fanSize + 38))
|
||||||
|
|> circle(center = [-4, fanSize / 2.67], radius = 3)
|
||||||
|
|> subtract2d(tool = circle(center = [-4, fanSize / 2.67], radius = 2.5))
|
||||||
|
|> sweep(path = centerTubePath)
|
||||||
|
|> patternCircular3d(
|
||||||
|
%,
|
||||||
|
instances = 2,
|
||||||
|
axis = [0, 0, 1],
|
||||||
|
center = [-4 * 2, 0, 0],
|
||||||
|
arcDegrees = 360,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
||||||
|
|> patternLinear3d(
|
||||||
|
%,
|
||||||
|
instances = 2,
|
||||||
|
distance = 4 * 4,
|
||||||
|
axis = [1, 0, 0],
|
||||||
|
)
|
||||||
|
|
||||||
|
// Draw a heat fin with built-in clips to secure the mounting wire. Pattern the fin upwards by the height of the fan
|
||||||
|
heatFins = startSketchOn(offsetPlane(XY, offset = 45))
|
||||||
|
|> startProfile(at = [0, -fanSize / 2])
|
||||||
|
|> xLine(length = 9)
|
||||||
|
|> angledLine(angle = -60deg, length = 2.5, tag = $seg04)
|
||||||
|
|> xLine(length = 0.75)
|
||||||
|
|> arc(interiorAbsolute = [lastSegX(%) + 1, lastSegY(%) + 1.2], endAbsolute = [lastSegX(%) + 2, lastSegY(%)])
|
||||||
|
|> xLine(length = 0.75)
|
||||||
|
|> angledLine(angle = 60deg, length = segLen(seg04))
|
||||||
|
|> xLine(endAbsolute = heatSinkDepth / 2 - 3)
|
||||||
|
|> tangentialArc(angle = 90deg, radius = 3)
|
||||||
|
|> yLine(endAbsolute = 0)
|
||||||
|
|> mirror2d(axis = X)
|
||||||
|
|> mirror2d(axis = Y)
|
||||||
|
|> close()
|
||||||
|
|> extrude(length = 1)
|
||||||
|
|> patternLinear3d(
|
||||||
|
%,
|
||||||
|
instances = 31,
|
||||||
|
distance = (fanSize - 10) / 30,
|
||||||
|
axis = [0, 0, 1],
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create the mounting base for the CPU cooler. The base should consist of two pieces that secure around each of the tubes at the bottom
|
||||||
|
coolerBase = startSketchOn(-XZ)
|
||||||
|
baseLower = startProfile(coolerBase, at = [0, 10])
|
||||||
|
|> xLine(length = -0.9)
|
||||||
|
|> arc(angleStart = 0deg, angleEnd = -180deg, radius = 3.1)
|
||||||
|
|> xLine(length = -1.8)
|
||||||
|
|> arc(angleStart = 0deg, angleEnd = -180deg, radius = 3)
|
||||||
|
|> xLine(length = -1.8)
|
||||||
|
|> arc(angleStart = 0deg, angleEnd = -180deg, radius = 3)
|
||||||
|
|> xLine(length = -1.8)
|
||||||
|
|> xLine(length = -2)
|
||||||
|
|> yLine(length = -10)
|
||||||
|
|> xLine(endAbsolute = 0)
|
||||||
|
|> mirror2d(axis = Y)
|
||||||
|
|> extrude(length = 2 * segLen(seg02), symmetric = true)
|
||||||
|
|
||||||
|
baseUpper = startProfile(coolerBase, at = [0, 10])
|
||||||
|
|> xLine(length = -0.9)
|
||||||
|
|> arc(angleStart = 0deg, angleEnd = 180deg, radius = 3.1)
|
||||||
|
|> xLine(length = -1.8)
|
||||||
|
|> arc(angleStart = 0deg, angleEnd = 180deg, radius = 3)
|
||||||
|
|> xLine(length = -1.8)
|
||||||
|
|> arc(angleStart = 0deg, angleEnd = 180deg, radius = 3)
|
||||||
|
|> xLine(length = -1.8)
|
||||||
|
|> xLine(length = -1)
|
||||||
|
|> yLine(length = 4)
|
||||||
|
|> tangentialArc(angle = -90deg, radius = 2)
|
||||||
|
|> xLine(endAbsolute = 0)
|
||||||
|
|> mirror2d(axis = Y)
|
||||||
|
|> extrude(length = 2 * segLen(seg02) * 3 / 4, symmetric = true)
|
||||||
|
|
||||||
|
// Create a flexible mounting bracket to secure the heat sink to the motherboard once adhered
|
||||||
|
mountingBracket = startSketchOn(XZ)
|
||||||
|
|> startProfile(at = [-10, 16])
|
||||||
|
|> xLine(length = -20)
|
||||||
|
|> tangentialArc(angle = 20deg, radius = bendRadius)
|
||||||
|
|> angledLine(angle = -160deg, length = 14, tag = $seg09)
|
||||||
|
|> tangentialArc(angle = -30deg, radius = bendRadius + sheetThickness)
|
||||||
|
|> angledLine(angle = 170deg, length = 21.5, tag = $seg04Q)
|
||||||
|
|> angledLine(angle = 170deg - 90deg, length = sheetThickness, tag = $seg08)
|
||||||
|
|> angledLine(angle = segAng(seg04Q) + 180deg, length = segLen(seg04Q), tag = $seg05E)
|
||||||
|
|> tangentialArc(angle = 30deg, radius = bendRadius)
|
||||||
|
|> angledLine(angle = segAng(seg09) + 180deg, length = segLen(seg09))
|
||||||
|
|> tangentialArc(angle = -20deg, radius = bendRadius + sheetThickness)
|
||||||
|
|> xLine(endAbsolute = profileStartX(%))
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg07)
|
||||||
|
|> close()
|
||||||
|
|> extrude(
|
||||||
|
length = 16,
|
||||||
|
symmetric = true,
|
||||||
|
tagEnd = $capEnd001,
|
||||||
|
tagStart = $capStart001,
|
||||||
|
)
|
||||||
|
|> fillet(
|
||||||
|
radius = 2,
|
||||||
|
tags = [
|
||||||
|
getCommonEdge(faces = [seg07, capEnd001]),
|
||||||
|
getCommonEdge(faces = [seg08, capEnd001]),
|
||||||
|
getCommonEdge(faces = [seg08, capStart001]),
|
||||||
|
getCommonEdge(faces = [seg07, capStart001])
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create a clearance hole in the bracket for an M3 screw and countersink the hole
|
||||||
|
thruHole = startSketchOn(mountingBracket, face = seg05E)
|
||||||
|
|> circle(center = [70, 0], radius = 3.4 / 2, tag = $seg06E)
|
||||||
|
|> extrude(length = -sheetThickness)
|
||||||
|
|> chamfer(
|
||||||
|
length = sheetThickness * 0.75,
|
||||||
|
tags = [
|
||||||
|
getCommonEdge(faces = [seg05E, seg06E])
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
// Duplicate the bracket to the other side of the heat sink base
|
||||||
|
|> patternCircular3d(
|
||||||
|
instances = 2,
|
||||||
|
axis = [0, 0, 1],
|
||||||
|
center = [0, 0, 0],
|
||||||
|
arcDegrees = 360deg,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
51
public/kcl-samples/cpu-cooler/main.kcl
Normal file
51
public/kcl-samples/cpu-cooler/main.kcl
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// CPU Cooler
|
||||||
|
// A CPU cooler is a device designed to dissipate heat generated by the CPU of a computer. They consist of a brazed heat sink made from aluminum or copper alloys, and one or two axial fans to move airflow across the heat sink.
|
||||||
|
|
||||||
|
// Set units
|
||||||
|
@settings(defaultLengthUnit = mm)
|
||||||
|
|
||||||
|
// Import all parts and parameters into assembly file
|
||||||
|
import * from "parameters.kcl"
|
||||||
|
import "fan-housing.kcl" as fanHousing
|
||||||
|
import "motor.kcl" as motor
|
||||||
|
import "fan.kcl" as fan
|
||||||
|
import "heat-sink.kcl" as heatSink
|
||||||
|
import "mounting-wire.kcl" as mountingWire
|
||||||
|
import "removable-sticker.kcl" as removableSticker
|
||||||
|
|
||||||
|
// Produce the model for each imported part
|
||||||
|
heatSink
|
||||||
|
|
||||||
|
fn translatePart(part) {
|
||||||
|
part
|
||||||
|
|> translate(x = heatSinkDepth / 2, z = 40 + fanSize / 2)
|
||||||
|
|> patternLinear3d(
|
||||||
|
%,
|
||||||
|
instances = 2,
|
||||||
|
distance = heatSinkDepth + fanHeight,
|
||||||
|
axis = [-1, 0, 0],
|
||||||
|
)
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
translatePart(part = fanHousing)
|
||||||
|
translatePart(part = motor)
|
||||||
|
translatePart(part = fan)
|
||||||
|
|
||||||
|
mountingWire
|
||||||
|
|> patternCircular3d(
|
||||||
|
%,
|
||||||
|
instances = 2,
|
||||||
|
axis = [0, 1, 0],
|
||||||
|
center = [0, 0, 40 + fanSize / 2],
|
||||||
|
arcDegrees = 360deg,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
||||||
|
|> patternCircular3d(
|
||||||
|
%,
|
||||||
|
instances = 2,
|
||||||
|
axis = [0, 0, 1],
|
||||||
|
center = [0, 0, 0],
|
||||||
|
arcDegrees = 360deg,
|
||||||
|
rotateDuplicates = true,
|
||||||
|
)
|
||||||
|
removableSticker
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user