Compare commits

..

55 Commits

Author SHA1 Message Date
2342d04fe2 Add back old window detection heuristic 2025-04-04 18:05:29 -04:00
ddac107dc1 Test attempt number 15345203, action! 2025-04-04 16:43:49 -04:00
313a21e82a Try again 2025-04-04 14:58:06 -04:00
b9875bb8cf Fix camera failure 2025-04-04 14:28:04 -04:00
8940f9b214 tsc lint 2025-04-04 14:24:27 -04:00
0af99af15e Fix native menu tests more 2025-04-04 13:51:44 -04:00
7f18aef49b Add app console.log 2025-04-04 12:43:04 -04:00
062495c02d Hopefully fix snapshots at least 2025-04-04 12:40:14 -04:00
767fde869c Use scene.connectionEstablished 2025-04-04 11:46:04 -04:00
49fcbdddba Try something 2025-04-04 11:39:22 -04:00
e06f76a6bb Qualify fail function 2025-04-04 11:38:05 -04:00
e98a957553 Remove a test race - poll window info. 2025-04-04 11:37:20 -04:00
25af691911 Fix cache count numbers in editor test 2025-04-04 11:37:20 -04:00
cdc0fa4ed9 Fix zoom to fit at the right moments... 2025-04-04 11:37:20 -04:00
4d06a917f2 Fix the bad reload repeat issue kevin started on 2025-04-04 11:37:19 -04:00
682fa50c1a Remove NetworkHealthIndicator test that was shit 2025-04-04 11:36:27 -04:00
496522e27d a new list of circular deps 2025-04-04 11:36:27 -04:00
4c57cea22d Fix zoom to fit being frigged 2025-04-04 11:36:27 -04:00
70f9c8edf1 fmt tsc 2025-04-04 11:36:27 -04:00
9de37879e5 fmt 2025-04-04 11:36:27 -04:00
91b5549a06 Fix another cyclic mfer! 2025-04-04 11:36:27 -04:00
3471f73479 Get rid of 1 cyclic dependency 2025-04-04 11:36:27 -04:00
277c489e38 Fix up new changes 2025-04-04 11:36:26 -04:00
00122aae5e yarn fmt lint tsc 2025-04-04 11:35:44 -04:00
65adfd4497 Fix up named-views tests 2025-04-04 11:34:59 -04:00
8d0343c946 Fix 2 more 2025-04-04 11:34:59 -04:00
4c564bf332 Fix more tests 2025-04-04 11:34:59 -04:00
ed1e2aedfd Fixup after rebase 2025-04-04 11:34:59 -04:00
992fec6afb wip 2025-04-04 11:34:58 -04:00
62a18dd2b3 less flaky point and click 2025-04-04 11:34:31 -04:00
2c673fba82 wip 2025-04-04 11:34:30 -04:00
635314bb8d Fix tsc after rebase 2025-04-04 11:33:39 -04:00
c75aafa60d yarn tsc 2025-04-04 11:33:39 -04:00
fb192ee213 yarn lint 2025-04-04 11:33:39 -04:00
9e19d131eb yarn fmt 2025-04-04 11:33:39 -04:00
81f70251e1 Fix the rest of the mfing tests 2025-04-04 11:33:39 -04:00
74f9afb2ca Deflake revolve some revolve tests 2025-04-04 11:33:39 -04:00
d03343d97d More e2e fixes 2025-04-04 11:33:39 -04:00
6c8a525762 Rework initial root projects dir + deflake many projects tests 2025-04-04 11:33:39 -04:00
c8177564e1 wip 2025-04-04 11:33:39 -04:00
12bf41ab7e Clear diagnostics when unmounting code editor! 2025-04-04 11:33:39 -04:00
fbefff490c Massive extinction event for waitForExecutionDone; try to stop projects view switching from crashing 2025-04-04 11:33:38 -04:00
4c9851efbf yarn fmt 2025-04-04 11:33:20 -04:00
2cca1376e2 Fix streamIdleMode checkbox being wonky 2025-04-04 11:33:20 -04:00
c32a3edb39 wip 2025-04-04 11:33:20 -04:00
955a2ffaf9 Add back better ping indicator 2025-04-04 11:33:20 -04:00
6bc8e45aa7 Use pause/play iconology 2025-04-04 11:33:20 -04:00
be0fdc53b5 Remove camera sync 2025-04-04 11:33:20 -04:00
cfbe805e14 Fix up everything after bumping kittycad/lib 2025-04-04 11:33:20 -04:00
2a60efc5ab Move engineStreamMachine as a global actor; tons of more work 2025-04-04 11:33:20 -04:00
deb83cf62c tsc lint fmt 2025-04-04 11:33:20 -04:00
e3705bf7df cargo fmt 2025-04-04 11:33:20 -04:00
ff887af540 Correct serialization; only expose at user level 2025-04-04 11:33:20 -04:00
1e4b6ce701 Shut up codespell 2025-04-04 11:33:20 -04:00
e642731529 Add back stream idle mode 2025-04-04 11:33:20 -04:00
845 changed files with 120074 additions and 122150 deletions

View File

@ -1,3 +1,3 @@
[codespell]
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo

View File

@ -1,24 +0,0 @@
#!/bin/bash
set -euo pipefail
# Install vector
brew tap vectordotdev/brew && brew install vector
# Configure vector
mkdir -p /tmp/vector
cp .github/workflows/vector.toml /tmp/vector.toml
sed -i '' "s#OS_NAME#${OS_NAME}#g" /tmp/vector.toml
sed -i '' "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
sed -i '' "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
sed -i '' "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
sed -i '' "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
sed -i '' "s#GH_ACTIONS_AXIOM_TOKEN#${GH_ACTIONS_AXIOM_TOKEN}#g" /tmp/vector.toml
# Display settings
echo
echo 'Vector config:'
cat /tmp/vector.toml
echo
# Start in the background
$(brew --prefix)/opt/vector/bin/vector --config /tmp/vector.toml &

View File

@ -1,24 +0,0 @@
#!/bin/bash
set -euo pipefail
# Install vector
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev | bash -s -- -y
# Configure vector
mkdir -p /tmp/vector
cp .github/workflows/vector.toml /tmp/vector.toml
sed -i "s#OS_NAME#${OS_NAME}#g" /tmp/vector.toml
sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${GH_ACTIONS_AXIOM_TOKEN}#g" /tmp/vector.toml
# Display settings
echo
echo 'Vector config:'
cat /tmp/vector.toml
echo
# Start in background
${HOME}/.vector/bin/vector --config /tmp/vector.toml &

View File

@ -24,7 +24,7 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- name: Rust Cache

View File

@ -77,7 +77,7 @@ jobs:
with:
cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
with:
tool: wasm-pack
@ -207,13 +207,6 @@ jobs:
smctl.exe keypair ls
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
smksp_cert_sync.exe
smctl windows certsync
# This last line `smctl windows certsync` was added after windows codesign failures started happening
# with nightly-v25.4.10. It looks like `smksp_cert_sync.exe` used to do the sync to the local cert store,
# but stopped doing it overnight. This extra call that I randomly got from this azure-related doc page
# https://docs.digicert.com/en/digicert-keylocker/code-signing/sign-with-third-party-signing-tools/windows-applications/sign-azure-apps-with-signtool-using-ksp-library.html#sync-certificates--windows-only--618365
# seems to be doing that extra sync that we need for scripts/sign-win.js to work.
# TODO: we still need to make sign-win.js errors fail the workflow, see issue #6276
shell: cmd
- name: Build the app (debug)
@ -385,7 +378,7 @@ jobs:
NOTES: ${{ needs.prepare-files.outputs.notes }}
PUB_DATE: ${{ github.event.repository.updated_at }}
WEBSITE_DIR: ${{ env.IS_NIGHTLY == 'true' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Design%20Studio%20%28Nightly%29' || 'Zoo%20Design%20Studio' }}
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
run: |
RELEASE_DIR=https://${WEBSITE_DIR}
jq --null-input \

View File

@ -34,11 +34,20 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- name: Start Vector
run: .github/ci-cd-scripts/start-vector-ubuntu.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: Install vector
run: |
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
chmod +x /tmp/vector.sh
/tmp/vector.sh -y -no-modify-path
mkdir -p /tmp/vector
cp .github/workflows/vector.toml /tmp/vector.toml
sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
cat /tmp/vector.toml
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
- uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest
- name: Install just

View File

@ -140,7 +140,7 @@ jobs:
with:
cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
with:
tool: wasm-pack
@ -231,11 +231,6 @@ jobs:
env:
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
TAB_API_URL: ${{ secrets.TAB_API_URL }}
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
TARGET: web
- uses: actions/upload-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
@ -286,7 +281,7 @@ jobs:
os:
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- namespace-profile-macos-8-cores
- windows-latest-8-cores
- windows-latest
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
# Disable macos and windows tests on hourly e2e tests since we only care
@ -297,7 +292,7 @@ jobs:
exclude:
- os: namespace-profile-macos-8-cores
isScheduled: true
- os: windows-latest-8-cores
- os: windows-latest
isScheduled: true
# TODO: add ref here for main and latest release tag
runs-on: ${{ matrix.os }}
@ -344,12 +339,22 @@ jobs:
if: needs.conditions.outputs.should-run == 'true'
run: yarn tronb:vite:dev
- name: Start Vector
if: ${{ needs.conditions.outputs.should-run == 'true' && !contains(matrix.os, 'windows') }}
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- name: Install vector
if: ${{ needs.conditions.outputs.should-run == 'true' && contains(matrix.os, 'ubuntu') }}
shell: bash
run: |
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
chmod +x /tmp/vector.sh
/tmp/vector.sh -y -no-modify-path
mkdir -p /tmp/vector
cp .github/workflows/vector.toml /tmp/vector.toml
sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
cat /tmp/vector.toml
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
- uses: actions/download-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
@ -365,16 +370,11 @@ jobs:
with:
shell: bash
command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{ env.OS_NAME }}
timeout_minutes: 30
max_attempts: 9
timeout_minutes: 45
max_attempts: 15
env:
FAIL_ON_CONSOLE_ERRORS: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
TAB_API_URL: ${{ secrets.TAB_API_URL }}
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
TARGET: desktop
- uses: actions/upload-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}

View File

@ -1,55 +0,0 @@
name: Test Nix Flake
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
nix-flake-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: nix flake check for all platforms
run: |
nix flake check --all-systems
nix-build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: nix build . for x86_64-linux
run: nix build .
nix-build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: nix build . for x86_64-darwin
run: nix build .

View File

@ -51,7 +51,7 @@ jobs:
with:
cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
@ -191,7 +191,7 @@ jobs:
cache: 'yarn'
- run: yarn install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
@ -236,7 +236,7 @@ jobs:
cache: 'yarn'
- run: yarn install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack

View File

@ -8,7 +8,6 @@ include = ["/tmp/github-actions.log"]
type = "remap"
inputs = [ "github-actions-file" ]
source = '''
.platform = "OS_NAME"
.action = "GITHUB_WORKFLOW"
.repo = "GITHUB_REPOSITORY"
.sha = "GITHUB_SHA"

1
.gitignore vendored
View File

@ -26,7 +26,6 @@ yarn-error.log*
.idea
.vscode
.helix
result
# rust
rust/target

View File

@ -5,15 +5,8 @@ all: install build check
# INSTALL
ifeq ($(OS),Windows_NT)
export WINDOWS := true
ifndef MSYSTEM
export POWERSHELL := true
endif
endif
ifdef WINDOWS
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
CARGO ?= ~/.cargo/bin/cargo.exe
WASM_PACK ?= ~/.cargo/bin/wasm-pack.exe
else
CARGO ?= ~/.cargo/bin/cargo
WASM_PACK ?= ~/.cargo/bin/wasm-pack
@ -24,21 +17,21 @@ install: node_modules/.yarn-integrity $(CARGO) $(WASM_PACK) ## Install dependenc
node_modules/.yarn-integrity: package.json yarn.lock
yarn install
ifdef POWERSHELL
ifeq ($(OS),Windows_NT)
@ type nul > $@
else
@ touch $@
endif
$(CARGO):
ifdef WINDOWS
ifeq ($(OS),Windows_NT)
yarn install:rust:windows
else
yarn install:rust
endif
$(WASM_PACK):
ifdef WINDOWS
ifeq ($(OS),Windows_NT)
yarn install:wasm-pack:cargo
else
yarn install:wasm-pack:sh
@ -64,7 +57,7 @@ build-web: install public/kcl_wasm_lib_bg.wasm build/index.html
build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES)
ifdef WINDOWS
ifeq ($(OS),Windows_NT)
yarn build:wasm:dev:windows
else
yarn build:wasm:dev
@ -147,8 +140,8 @@ endif
.PHONY: clean
clean: ## Delete all artifacts
ifdef POWERSHELL
git clean --force -d -x --exclude=.env* --exclude=**/*.env
ifeq ($(OS),Windows_NT)
git clean --force -d -X
else
rm -rf .vite/ build/
rm -rf trace.zip playwright-report/ test-results/
@ -159,7 +152,7 @@ endif
.PHONY: help
help: install
ifdef POWERSHELL
ifeq ($(OS),Windows_NT)
@ powershell -Command "Get-Content $(MAKEFILE_LIST) | Select-String -Pattern '^[^\s]+:.*##\s.*$$' | ForEach-Object { $$line = $$_.Line -split ':.*?##\s+'; Write-Host -NoNewline $$line[0].PadRight(30) -ForegroundColor Cyan; Write-Host $$line[1] }"
else
@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

View File

@ -36,9 +36,9 @@ myAngle = -120
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [8, 0])
|> angledLine(angle = abs(myAngle), length = 5)
|> angledLine({ angle = abs(myAngle), length = 5 }, %)
|> line(end = [-5, 0])
|> angledLine(angle = myAngle, length = 5)
|> angledLine({ angle = myAngle, length = 5 }, %)
|> close()
baseExtrusion = extrude(sketch001, length = 5)

View File

@ -33,7 +33,10 @@ acos(num: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(acos(0.5)), length = 10)
|> angledLine({
angle = toDegrees(acos(0.5)),
length = 10
}, %)
|> line(end = [5, 0])
|> line(endAbsolute = [12, 0])
|> close()

View File

@ -36,7 +36,7 @@ angleToMatchLengthX(
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [2, 5], tag = $seg01)
|> angledLine(angle = -angleToMatchLengthX(seg01, 7, %), endAbsoluteX = 10)
|> angledLineToX([-angleToMatchLengthX(seg01, 7, %), 10], %)
|> close()
extrusion = extrude(sketch001, length = 5)

View File

@ -36,7 +36,10 @@ angleToMatchLengthY(
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [1, 2], tag = $seg01)
|> angledLine(angle = angleToMatchLengthY(seg01, 15, %), length = 5)
|> angledLine({
angle = angleToMatchLengthY(seg01, 15, %),
length = 5
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -10,13 +10,8 @@ Draw a line segment relative to the current origin using the polar measure of so
```js
angledLine(
data: AngledLineData,
sketch: Sketch,
angle: number,
length?: number,
lengthX?: number,
lengthY?: number,
endAbsoluteX?: number,
endAbsoluteY?: number,
tag?: TagDeclarator,
): Sketch
```
@ -26,14 +21,9 @@ angledLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `angle` | [`number`](/docs/kcl/types/number) | Which angle should the line be drawn at? | Yes |
| `length` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
| `lengthX` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
| `lengthY` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
| `endAbsoluteX` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
| `endAbsoluteY` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
### Returns
@ -46,7 +36,7 @@ angledLine(
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> yLine(endAbsolute = 15)
|> angledLine(angle = 30, length = 15)
|> angledLine({ angle = 30, length = 15 }, %)
|> line(end = [8, -10])
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

48
docs/kcl/angledLineToX.md Normal file

File diff suppressed because one or more lines are too long

48
docs/kcl/angledLineToY.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -188,9 +188,9 @@ example = extrude(exampleSketch, length = 1)
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
pipeHole = startSketchOn(XY)

View File

@ -33,7 +33,10 @@ asin(num: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(asin(0.5)), length = 20)
|> angledLine({
angle = toDegrees(asin(0.5)),
length = 20
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -33,7 +33,10 @@ atan(num: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(atan(1.25)), length = 20)
|> angledLine({
angle = toDegrees(atan(1.25)),
length = 20
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -37,7 +37,10 @@ atan2(
```js
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(atan2(1.25, 2)), length = 20)
|> angledLine({
angle = toDegrees(atan2(1.25, 2)),
length = 20
}, %)
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

View File

@ -17,10 +17,10 @@ std::math::E: number = 2.71828182845904523536028747135266250_
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
|> angledLine({
angle = 30,
length = 2 * E ^ 2,
)
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -17,10 +17,10 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
|> angledLine({
angle = 50,
length = 10 * TAU,
)
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -30,7 +30,7 @@ e(): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 30, length = 2 * e() ^ 2)
|> angledLine({ angle = 30, length = 2 * e() ^ 2 }, %)
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -30,10 +30,10 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle = 120, length = 10 }, %)
|> line(end = [-10, 0])
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -30,10 +30,10 @@ getOppositeEdge(tag: TagIdentifier): Uuid
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle = 120, length = 10 }, %)
|> line(end = [-10, 0])
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -30,10 +30,10 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10)
|> angledLine({ angle = 60, length = 10 }, %)
|> angledLine({ angle = 120, length = 10 }, %)
|> line(end = [-10, 0])
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -65,7 +65,7 @@ case = startSketchOn(-XZ)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
|> tangentialArcTo([-size, size], %)
|> close()
|> extrude(length = 65)

80
docs/kcl/import.md Normal file

File diff suppressed because one or more lines are too long

40
docs/kcl/inch.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,11 @@ layout: manual
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine)
* [`angledLineOfXLength`](kcl/angledLineOfXLength)
* [`angledLineOfYLength`](kcl/angledLineOfYLength)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`angledLineToX`](kcl/angledLineToX)
* [`angledLineToY`](kcl/angledLineToY)
* [`appearance`](kcl/appearance)
* [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo)
@ -61,15 +65,11 @@ layout: manual
* [`chamfer`](kcl/chamfer)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`fromCm`](kcl/fromCm)
* [`fromFt`](kcl/fromFt)
* [`fromInches`](kcl/fromInches)
* [`fromM`](kcl/fromM)
* [`fromMm`](kcl/fromMm)
* [`fromYd`](kcl/fromYd)
* [`ft`](kcl/ft)
* [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
@ -77,7 +77,7 @@ layout: manual
* [`helix`](kcl/std-helix)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`intersect`](kcl/intersect)
* [`inch`](kcl/inch)
* [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY)
* [`legAngX`](kcl/legAngX)
@ -89,9 +89,11 @@ layout: manual
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`m`](kcl/m)
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
@ -99,6 +101,7 @@ layout: manual
* [`patternLinear3d`](kcl/patternLinear3d)
* [`patternTransform`](kcl/patternTransform)
* [`patternTransform2d`](kcl/patternTransform2d)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon)
* [`pop`](kcl/pop)
* [`pow`](kcl/pow)
@ -124,22 +127,22 @@ layout: manual
* [`sqrt`](kcl/sqrt)
* [`startProfileAt`](kcl/startProfileAt)
* [`startSketchOn`](kcl/startSketchOn)
* [`subtract`](kcl/subtract)
* [`sweep`](kcl/sweep)
* [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc)
* [`tangentialArcTo`](kcl/tangentialArcTo)
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`translate`](kcl/translate)
* [`union`](kcl/union)
* [`xLine`](kcl/xLine)
* [`yLine`](kcl/yLine)
* [`yd`](kcl/yd)
* **std::math**
* [`E`](kcl/consts/std-math-E)
* [`PI`](kcl/consts/std-math-PI)
* [`TAU`](kcl/consts/std-math-TAU)
* [`cos`](kcl/std-math-cos)
* [`polar`](kcl/std-math-polar)
* [`sin`](kcl/std-math-sin)
* [`tan`](kcl/std-math-tan)
* **std::sketch**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -33,7 +33,10 @@ max(args: [number]): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 70, length = max(15, 31, 4, 13, 22))
|> angledLine({
angle = 70,
length = max(15, 31, 4, 13, 22)
}, %)
|> line(end = [20, 0])
|> close()

View File

@ -33,7 +33,10 @@ min(args: [number]): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 70, length = min(15, 31, 4, 13, 22))
|> angledLine({
angle = 70,
length = min(15, 31, 4, 13, 22)
}, %)
|> line(end = [20, 0])
|> close()

File diff suppressed because one or more lines are too long

View File

@ -57,7 +57,7 @@ case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
|> tangentialArcTo([-size, size], %)
|> close(%)
|> extrude(length = 65)
@ -88,7 +88,7 @@ case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
|> tangentialArcTo([-size, size], %)
|> close(%)
|> extrude(length = 65)

43
docs/kcl/polar.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -37,7 +37,7 @@ pow(
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = pow(5, 2))
|> angledLine({ angle = 50, length = pow(5, 2) }, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -29,8 +29,11 @@ profileStart(sketch: Sketch): [number]
```js
sketch001 = startSketchOn(XY)
|> startProfileAt([5, 2], %)
|> angledLine(angle = 120, length = 50, tag = $seg01)
|> angledLine(angle = segAng(seg01) + 120, length = 50)
|> angledLine({ angle = 120, length = 50 }, %, $seg01)
|> angledLine({
angle = segAng(seg01) + 120,
length = 50
}, %)
|> line(end = profileStart(%))
|> close()
|> 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

View File

@ -78,7 +78,7 @@ assertEqual(sum, 6, 0.00001, "1 + 2 + 3 summed is 6")
```js
// Declare a function that sketches a decagon.
fn decagon(radius) {
// Each side of the decagon is turned this many radians from the previous angle.
// Each side of the decagon is turned this many degrees from the previous angle.
stepAngle = 1 / 10 * TAU
// Start the decagon sketch at this point.

View File

@ -65,9 +65,9 @@ rotate(
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
// Create a hole for the pipe.
@ -90,9 +90,9 @@ sweepSketch = startSketchOn(XY)
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
// Create a hole for the pipe.
@ -115,9 +115,9 @@ sweepSketch = startSketchOn(XY)
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
// Create a hole for the pipe.
@ -151,9 +151,15 @@ cube
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
50.61
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -162,7 +168,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> tangentialArc({ radius = 80, offset = -90 }, %)
|> xLine(length = 384.93)
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)

View File

@ -49,9 +49,9 @@ scale(
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
// Create a hole for the pipe.
@ -85,9 +85,15 @@ cube
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
50.61
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -96,7 +102,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> tangentialArc({ radius = 80, offset = -90 }, %)
|> xLine(length = 384.93)
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)

View File

@ -32,9 +32,9 @@ exampleSketch = startSketchOn(XZ)
|> line(end = [10, 0])
|> line(end = [5, 10], tag = $seg01)
|> line(end = [-10, 0])
|> angledLine(angle = segAng(seg01), length = 10)
|> angledLine([segAng(seg01), 10], %)
|> line(end = [-10, 0])
|> angledLine(angle = segAng(seg01), length = -15)
|> angledLine([segAng(seg01), -15], %)
|> close()
example = extrude(exampleSketch, length = 4)

View File

@ -29,9 +29,9 @@ segLen(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 60, length = 10, tag = $thing)
|> tangentialArc(angle = -120, radius = 5)
|> angledLine(angle = -60, length = segLen(thing))
|> angledLine({ angle = 60, length = 10 }, %, $thing)
|> tangentialArc({ offset = -120, radius = 5 }, %)
|> angledLine({ angle = -60, length = segLen(thing) }, %)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -6,7 +6,7 @@ layout: manual
# KCL Settings
There are three levels of settings available in Zoo Design Studio:
There are three levels of settings available in the KittyCAD Design Studiolication:
1. [User Settings](/docs/kcl/settings/user): Global settings that apply to all projects, stored in `user.toml`
2. [Project Settings](/docs/kcl/settings/project): Settings specific to a project, stored in `project.toml`
@ -14,7 +14,7 @@ There are three levels of settings available in Zoo Design Studio:
## Configuration Files
Zoo Design Studio uses TOML files for configuration:
The KittyCAD Design Studio uses TOML files for configuration:
* **User Settings**: `user.toml` - See [complete documentation](/docs/kcl/settings/user)
* **Project Settings**: `project.toml` - See [complete documentation](/docs/kcl/settings/project)

View File

@ -96,7 +96,7 @@ Permanently dismiss the banner warning to download the desktop app. This setting
##### stream_idle_mode
When the user is idle, teardown the stream after some time.
When the user is idle, and this is true, the stream will be torn down.
**Default:** None

View File

@ -103,7 +103,7 @@ case = startSketchOn(-XZ)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
|> tangentialArcTo([-size, size], %)
|> close()
|> extrude(length = 65)
@ -128,7 +128,7 @@ case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
|> tangentialArcTo([-size, size], %)
|> close()
|> extrude(length = 65)
@ -156,7 +156,7 @@ case = startSketchOn(XY)
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
|> tangentialArcTo([-size, size], %)
|> close()
|> extrude(length = 65)

View File

@ -33,7 +33,7 @@ sqrt(num: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = sqrt(2500))
|> angledLine({ angle = 50, length = sqrt(2500) }, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -9,15 +9,7 @@ Create a helix.
```js
helix(
revolutions: number(_),
angleStart: number(deg),
ccw?: bool,
radius?: number(mm),
axis?: Axis3d | Edge,
length?: number(mm),
cylinder?: Solid,
): Helix
helix(revolutions: number(_), angleStart: number(deg), ccw?: bool, radius?: number(mm), axis?: Axis3d | Edge, length?: number(mm), cylinder?: Solid): Helix
```

View File

@ -29,10 +29,10 @@ cos(@num: number(rad)): number(_)
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
|> angledLine({
angle = 30,
length = 3 / cos(toRadians(30)),
)
}, %)
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,10 +29,10 @@ tan(@num: number(rad)): number(_)
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
|> angledLine({
angle = 50,
length = 50 * tan(1/2),
)
}, %)
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

View File

@ -6,16 +6,10 @@ layout: manual
Construct a 2-dimensional circle, of the specified radius, centered at
the provided (x, y) origin point.
Construct a 2-dimensional circle, of the specified radius, centered atthe provided (x, y) origin point.
```js
circle(
@sketch_or_surface: Sketch | Plane | Face,
center: Point2d,
radius: number,
tag?: tag,
): Sketch
circle(@sketch_or_surface: Sketch | Plane | Face, center: Point2d, radius: number, tag?: tag): Sketch
```

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -47,9 +47,9 @@ sweep(
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
// Create a hole for the pipe.
@ -91,9 +91,15 @@ springSketch = startSketchOn(YZ)
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
50.61
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -102,7 +108,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> tangentialArc({ radius = 80, offset = -90 }, %)
|> xLine(length = 384.93)
sweep([rectangleSketch, circleSketch], path = sweepPath)
@ -120,7 +126,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> tangentialArc({ radius = 80, offset = -90 }, %)
|> xLine(length = 384.93)
sweep(circleSketch, path = sweepPath, sectional = true)

View File

@ -31,9 +31,12 @@ tangentToEnd(tag: TagIdentifier): number
pillSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [20, 0])
|> tangentialArc(end = [0, 10], tag = $arc1)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> tangentialArc(end = [0, -10])
|> tangentialArcToRelative([0, 10], %, $arc1)
|> angledLine({
angle = tangentToEnd(arc1),
length = 20
}, %)
|> tangentialArcToRelative([0, -10], %)
|> close()
pillExtrude = extrude(pillSketch, length = 10)
@ -46,9 +49,12 @@ pillExtrude = extrude(pillSketch, length = 10)
pillSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 20])
|> tangentialArc(endAbsolute = [10, 20], tag = $arc1)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> tangentialArc(end = [-10, 0])
|> tangentialArcTo([10, 20], %, $arc1)
|> angledLine({
angle = tangentToEnd(arc1),
length = 20
}, %)
|> tangentialArcToRelative([-10, 0], %)
|> close()
pillExtrude = extrude(pillSketch, length = 10)
@ -60,7 +66,10 @@ pillExtrude = extrude(pillSketch, length = 10)
rectangleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0], tag = $seg1)
|> angledLine(angle = tangentToEnd(seg1), length = 10)
|> angledLine({
angle = tangentToEnd(seg1),
length = 10
}, %)
|> line(end = [0, 10])
|> line(end = [-20, 0])
|> close()
@ -74,7 +83,7 @@ rectangleExtrude = extrude(rectangleSketch, length = 10)
bottom = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> arcTo({ end = [10, 10], interior = [5, 1] }, %, $arc1)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> angledLine([tangentToEnd(arc1), 20], %)
|> close()
```
@ -86,7 +95,7 @@ circSketch = startSketchOn(XY)
triangleSketch = startSketchOn(XY)
|> startProfileAt([-5, 0], %)
|> angledLine(angle = tangentToEnd(circ), length = 10)
|> angledLine([tangentToEnd(circ), 10], %)
|> line(end = [-15, 0])
|> close()
```

File diff suppressed because one or more lines are too long

View File

@ -35,7 +35,7 @@ tangentialArcTo(
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 60, length = 10)
|> angledLine({ angle = 60, length = 10 }, %)
|> tangentialArcTo([15, 15], %)
|> line(end = [10, -15])
|> close()

View File

@ -35,7 +35,7 @@ tangentialArcToRelative(
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 45, length = 10)
|> angledLine({ angle = 45, length = 10 }, %)
|> tangentialArcToRelative([0, -10], %)
|> line(end = [-10, 0])
|> close()

View File

@ -30,7 +30,7 @@ tau(): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = 10 * tau())
|> angledLine({ angle = 50, length = 10 * tau() }, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -33,7 +33,10 @@ toDegrees(num: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = 70 * cos(toDegrees(pi() / 4)))
|> angledLine({
angle = 50,
length = 70 * cos(toDegrees(pi() / 4))
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -33,7 +33,10 @@ toRadians(num: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = 70 * cos(toRadians(45)))
|> angledLine({
angle = 50,
length = 70 * cos(toRadians(45))
}, %)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -45,9 +45,9 @@ translate(
sweepPath = startSketchOn(XZ)
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> tangentialArc({ offset = 90, radius = 5 }, %)
|> line(end = [-3, 0])
|> tangentialArc(angle = -90, radius = 5)
|> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7])
// Create a hole for the pipe.
@ -86,9 +86,15 @@ cube
sketch001 = startSketchOn(XY)
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
50.61
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -97,7 +103,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> tangentialArc({ radius = 80, offset = -90 }, %)
|> xLine(length = 384.93)
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)

View File

@ -184,17 +184,15 @@ way:
```norun
startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|> angledLine({
angle = segAng(rectangleSegmentA001) - 90,
length = 196.99,
tag = $rectangleSegmentB001,
)
|> angledLine(
}, %, $rectangleSegmentB001)
|> angledLine({
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001),
tag = $rectangleSegmentC001,
)
}, %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
```
@ -219,17 +217,15 @@ However if the code was written like this:
fn rect(origin) {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|> angledLine({
angle = segAng(rectangleSegmentA001) - 90,
length = 196.99,
tag = $rectangleSegmentB001,
)
|> angledLine(
length = 196.99
}, %, $rectangleSegmentB001)
|> angledLine({
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001)
tag = $rectangleSegmentC001,
)
}, %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
}
@ -249,17 +245,15 @@ For example the following code works.
fn rect(origin) {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|> angledLine({
angle = segAng(rectangleSegmentA001) - 90,
length = 196.99,
tag = $rectangleSegmentB001,
)
|> angledLine(
length = 196.99
}, %, $rectangleSegmentB001)
|> angledLine({
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001)
tag = $rectangleSegmentC001,
)
}, %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
}

View File

@ -252,7 +252,7 @@ Data for an imported geometry.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `ImportedGeometry`| | No |
| `type` |enum: [`ImportedGeometry`](/docs/kcl/types/ImportedGeometry)| | No |
| `id` |[`string`](/docs/kcl/types/string)| The ID of the imported geometry. | No |
| `value` |`[` [`string`](/docs/kcl/types/string) `]`| The original file paths. | No |

View File

@ -0,0 +1,22 @@
---
title: "PolarCoordsData"
excerpt: "Data for polar coordinates."
layout: manual
---
Data for polar coordinates.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `angle` |[`number`](/docs/kcl/types/number)| The angle of the line (in degrees). | No |
| `length` |[`number`](/docs/kcl/types/number)| The length of the line. | No |

View File

@ -14,17 +14,15 @@ way:
```js
startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|> angledLine({
angle = segAng(rectangleSegmentA001) - 90,
length = 196.99,
tag = $rectangleSegmentB001,
)
|> angledLine(
}, %, $rectangleSegmentB001)
|> angledLine({
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001),
tag = $rectangleSegmentC001,
)
}, %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
```
@ -48,16 +46,15 @@ However if the code was written like this:
fn rect(origin) {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|> angledLine({
angle = segAng(rectangleSegmentA001) - 90,
length = 196.99,
tag = $rectangleSegmentB001)
|> angledLine(
length = 196.99
}, %, $rectangleSegmentB001)
|> angledLine({
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001),
tag = $rectangleSegmentC001
)
length = -segLen(rectangleSegmentA001)
}, %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
}
@ -77,15 +74,15 @@ For example the following code works.
fn rect(origin) {
return startSketchOn('XZ')
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|> angledLine({
angle = segAng(rectangleSegmentA001) - 90,
length = 196.99
, %, $rectangleSegmentB001)
|> angledLine(
}, %, $rectangleSegmentB001)
|> angledLine({
angle = segAng(rectangleSegmentA001),
length = -segLen(rectangleSegmentA001)
, %, $rectangleSegmentC001)
}, %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
}

File diff suppressed because one or more lines are too long

View File

@ -38,10 +38,10 @@ xLine(
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> xLine(length = 15)
|> angledLine(angle = 80, length = 15)
|> angledLine({ angle = 80, length = 15 }, %)
|> line(end = [8, -10])
|> xLine(length = 10)
|> angledLine(angle = 120, length = 30)
|> angledLine({ angle = 120, length = 30 }, %)
|> xLine(length = -15)
|> close()

View File

@ -38,7 +38,7 @@ yLine(
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> yLine(length = 15)
|> angledLine(angle = 30, length = 15)
|> angledLine({ angle = 30, length = 15 }, %)
|> line(end = [8, -10])
|> yLine(length = -5)
|> close()

File diff suppressed because one or more lines are too long

View File

@ -137,7 +137,7 @@ async function doBasicSketch(
await page.waitForTimeout(100)
}
await page.getByRole('button', { name: 'constraints: open menu' }).click()
await page.getByRole('button', { name: 'Length: open menu' }).click()
await page.getByRole('button', { name: 'Equal Length' }).click()
// Open the code pane.

View File

@ -38,7 +38,7 @@ test.describe('Point and click for boolean workflows', () => {
path.resolve(
__dirname,
'../../',
'./rust/kcl-lib/e2e/executor/inputs/boolean-setup-with-sketch-on-faces.kcl'
'./rust/kcl-lib/e2e/executor/inputs/boolean-setup-with'
),
'utf-8'
)

View File

@ -32,41 +32,54 @@ test(
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await test.step('on open of project', async () => {
// Open the project
const projectName = page.getByText(`bracket`)
await expect(projectName).toBeVisible()
await projectName.click()
await scene.settled(cmdBar)
page.on('console', console.log)
// Expect zero errors in gutter
await test.step('on open of project', async () => {
await expect(page.getByText(`bracket`)).toBeVisible()
// open the project
await page.getByText(`bracket`).click()
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the export button
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
// Wait for the model to finish loading
await scene.settled(cmdBar)
const gltfOption = page.getByText('glTF')
const submitButton = page.getByText('Confirm Export')
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// The open file's name is `main.kcl`, so the export file name should be `main.gltf`
const exportFileName = `main.gltf`
// Click the export button
await exportButton.click()
// Select the first format option
const gltfOption = cmdBar.selectOption({ name: 'glTF' })
const exportFileName = `main.gltf` // source file is named `main.kcl`
await expect(gltfOption).toBeVisible()
await expect(page.getByText('STL')).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.waitForTimeout(500)
await page.keyboard.press('Enter')
// Find the toast.
// 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
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
// Expect it to succeed.
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
@ -74,7 +87,6 @@ test(
await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
// Check for the exported file
const firstFileFullPath = path.resolve(
getPlaywrightDownloadDir(tronApp.projectDirName),
exportFileName
@ -101,50 +113,59 @@ test(
const u = await getUtils(page)
await u.openFilePanel()
// Click on the other file
const otherKclButton = page.getByRole('button', { name: 'other.kcl' })
// Click the file
await otherKclButton.click()
// Close the file pane
await u.closeFilePanel()
await scene.settled(cmdBar)
// Expect zero errors in gutter
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the export button
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
const gltfOption = page.getByText('glTF')
const submitButton = page.getByText('Confirm Export')
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// The open file's name is `other.kcl`, so the export file name should be `other.gltf`
const exportFileName = `other.gltf`
// Click the export button
await exportButton.click()
// Select the first format option
const gltfOption = cmdBar.selectOption({ name: 'glTF' })
const exportFileName = `other.gltf` // source file is named `other.kcl`
await expect(gltfOption).toBeVisible()
await expect(page.getByText('STL')).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// 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
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
await test.step('Check the success toast message shows and nothing else', async () =>
Promise.all([
expect(alreadyExportingToastMessage).not.toBeVisible(),
expect(errorToastMessage).not.toBeVisible(),
expect(engineErrorToastMessage).not.toBeVisible(),
expect(successToastMessage).toBeVisible(),
expect(exportingToastMessage).not.toBeVisible(),
]))
// Check for the exported file=
const secondFileFullPath = path.resolve(
getPlaywrightDownloadDir(tronApp.projectDirName),
exportFileName

View File

@ -920,7 +920,7 @@ sketch001 = startSketchOn(XZ)
`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -5.38])
|> tangentialArcTo([24.95, -5.38], %)
|> close()`
)
})
@ -969,7 +969,7 @@ sketch001 = startSketchOn(XZ)
// expect the code to have changed
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn(XZ) |> startProfileAt([4.61, -14.01], %) |> line(end = [12.73, -0.09]) |> tangentialArc(endAbsolute = [24.95, -5.38]) |> close()extrude001 = extrude(sketch001, length = 5)`
`sketch001 = startSketchOn(XZ) |> startProfileAt([4.61, -14.01], %) |> line(end = [12.73, -0.09]) |> tangentialArcTo([24.95, -5.38], %) |> close()extrude001 = extrude(sketch001, length = 5)`
)
// Now hit undo
@ -982,7 +982,7 @@ sketch001 = startSketchOn(XZ)
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -5.38])
|> tangentialArcTo([24.95, -5.38], %)
|> close()`)
})
@ -998,7 +998,7 @@ sketch001 = startSketchOn(XZ)
sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -0.38])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`
)
@ -1072,7 +1072,7 @@ sketch001 = startSketchOn(XZ)
// we wait so it saves the code
await page.waitForTimeout(800)
// drag tangentialArc handle
// drag tangentialArcTo handle
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
@ -1089,7 +1089,7 @@ sketch001 = startSketchOn(XZ)
`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [15.4, -2.78])
|> tangentialArc(endAbsolute = [27.6, -3.05])
|> tangentialArcTo([27.6, -3.05], %)
|> close()
|> extrude(length = 5)`,
{ shouldNormalise: true }
@ -1104,7 +1104,7 @@ sketch001 = startSketchOn(XZ)
`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [15.4, -2.78])
|> tangentialArc(endAbsolute = [24.95, -0.38])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`,
{ shouldNormalise: true }
@ -1119,7 +1119,7 @@ sketch001 = startSketchOn(XZ)
`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -0.38])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`,
{ shouldNormalise: true }
@ -1135,7 +1135,7 @@ sketch001 = startSketchOn(XZ)
`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -0.38])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`,
{ shouldNormalise: true }
@ -1144,7 +1144,7 @@ sketch001 = startSketchOn(XZ)
)
test(
`Can import a local OBJ file`,
`Can use the import stdlib function on a local OBJ file`,
{ tag: '@electron' },
async ({ page, context }, testInfo) => {
test.fixme(orRunWhenFullSuiteEnabled())
@ -1194,7 +1194,7 @@ sketch001 = startSketchOn(XZ)
.toBeLessThan(15)
})
await test.step(`Write the import function line`, async () => {
await u.codeLocator.fill(`import 'cube.obj'\ncube`)
await u.codeLocator.fill(`import('cube.obj')`)
await page.waitForTimeout(800)
})
await test.step(`Reset the camera before checking`, async () => {
@ -1319,85 +1319,4 @@ sketch001 = startSketchOn(XZ)
const element = page.locator('[data-overlay-index="1"]')
await expect(element).toHaveAttribute('data-overlay-visible', 'true')
})
test(`Only show axis planes when there are no errors`, async ({
page,
homePage,
scene,
cmdBar,
}) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
profile001 = circle(sketch001, center = [-100.0, -100.0], radius = 50.0)
sketch002 = startSketchOn(XZ)
profile002 = circle(sketch002, center = [-100.0, 100.0], radius = 50.0)
extrude001 = extrude(profile002, length = 0)` // length = 0 is causing the error
)
})
const viewportSize = { width: 1200, height: 800 }
await page.setBodyDimensions(viewportSize)
await homePage.goToModelingScene()
await scene.connectionEstablished()
await scene.settled(cmdBar)
await scene.expectPixelColor(
TEST_COLORS.DARK_MODE_BKGD,
// This is a position where the blue part of the axis plane is visible if its rendered
{ x: viewportSize.width * 0.75, y: viewportSize.height * 0.2 },
15
)
})
test(`test-toolbar-buttons`, async ({
page,
homePage,
toolbar,
scene,
cmdBar,
}) => {
await test.step('Load an empty file', async () => {
await page.addInitScript(async () => {
localStorage.setItem('persistCode', '')
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// wait until scene is ready to be interacted with
await scene.connectionEstablished()
await scene.settled(cmdBar)
})
await test.step('Test toolbar button correct selection', async () => {
await toolbar.expectToolbarMode.toBe('modeling')
await toolbar.startSketchPlaneSelection()
// Click on a default plane
await page.mouse.click(700, 200)
// tools cannot be selected immediately, couldn't find an event to await instead.
await page.waitForTimeout(1000)
await toolbar.selectCenterRectangle()
await expect(page.getByTestId('center-rectangle')).toHaveAttribute(
'aria-pressed',
'true'
)
})
await test.step('Test Toolbar dropdown remembering last selection', async () => {
// Select another tool
await page.getByTestId('circle-center').click()
// center-rectangle should still be the active option in the rectangle dropdown
await expect(page.getByTestId('center-rectangle')).toBeVisible()
})
})
})

View File

@ -19,7 +19,7 @@ length001 = timesFive(1) * 5
sketch001 = startSketchOn(XZ)
|> startProfileAt([20, 10], %)
|> line(end = [10, 10])
|> angledLine(angle = -45, length = length001)
|> angledLine([-45, length001], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
revolve001 = revolve(sketch001, axis = X)
@ -38,9 +38,15 @@ extrude001 = extrude(sketch002, length = 10)
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(angle = 0, length = 4, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2, tag = $rectangleSegmentB001)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|> angledLine([0, 4], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
2
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close(%)
extrude001 = extrude(sketch001, length = 10)

View File

@ -154,6 +154,7 @@ export class ElectronZoo {
if (!this.electron) {
this.electron = await electron.launch(options)
this.page = await this.electron.firstWindow()
// Mac takes quite a long time to create the first window in CI.
// Turns out we can't trust firstWindow() either. So loop.
let timeoutId: ReturnType<typeof setTimeout>

View File

@ -99,6 +99,7 @@ export class HomePageFixture {
createAndGoToProject = async (projectTitle = 'untitled') => {
await this.projectsLoaded()
await this.projectButtonNew.click()
await this.projectTextName.click()
await this.projectTextName.fill(projectTitle)
await this.projectButtonContinue.click()
}

View File

@ -49,9 +49,7 @@ export class SceneFixture {
constructor(page: Page) {
this.page = page
this.streamWrapper = page.getByTestId('stream')
this.networkToggleConnected = page
.getByTestId('network-toggle-ok')
.or(page.getByTestId('network-toggle-other'))
this.networkToggleConnected = page.getByTestId('network-toggle-ok')
this.startEditSketchBtn = page
.getByRole('button', { name: 'Start Sketch' })
.or(page.getByRole('button', { name: 'Edit Sketch' }))
@ -233,7 +231,7 @@ export class SceneFixture {
settled = async (cmdBar: CmdBarFixture) => {
const u = await getUtils(this.page)
await expect(this.startEditSketchBtn).not.toBeDisabled({ timeout: 15_000 })
await expect(this.startEditSketchBtn).not.toBeDisabled()
await expect(this.startEditSketchBtn).toBeVisible()
await cmdBar.openCmdBar()

View File

@ -44,7 +44,6 @@ export class ToolbarFixture {
featureTreePane!: Locator
gizmo!: Locator
gizmoDisabled!: Locator
insertButton!: Locator
constructor(page: Page) {
this.page = page
@ -79,8 +78,6 @@ export class ToolbarFixture {
// element or two different elements can represent these states.
this.gizmo = page.getByTestId('gizmo')
this.gizmoDisabled = page.getByTestId('gizmo-disabled')
this.insertButton = page.getByTestId('insert-pane-button')
}
get logoLink() {
@ -169,7 +166,7 @@ export class ToolbarFixture {
}
selectCenterRectangle = async () => {
await this.page
.getByRole('button', { name: 'caret down rectangles:' })
.getByRole('button', { name: 'caret down Corner rectangle:' })
.click()
await expect(
this.page.getByTestId('dropdown-center-rectangle')
@ -178,7 +175,7 @@ export class ToolbarFixture {
}
selectBoolean = async (operation: 'union' | 'subtract' | 'intersect') => {
await this.page
.getByRole('button', { name: 'caret down booleans: open menu' })
.getByRole('button', { name: 'caret down Union: open menu' })
.click()
const operationTestId = `dropdown-boolean-${operation}`
await expect(this.page.getByTestId(operationTestId)).toBeVisible()
@ -186,19 +183,25 @@ export class ToolbarFixture {
}
selectCircleThreePoint = async () => {
await this.page.getByRole('button', { name: 'caret down circles:' }).click()
await this.page
.getByRole('button', { name: 'caret down Center circle:' })
.click()
await expect(
this.page.getByTestId('dropdown-circle-three-points')
).toBeVisible()
await this.page.getByTestId('dropdown-circle-three-points').click()
}
selectArc = async () => {
await this.page.getByRole('button', { name: 'caret down arcs:' }).click()
await this.page
.getByRole('button', { name: 'caret down Tangential Arc:' })
.click()
await expect(this.page.getByTestId('dropdown-arc')).toBeVisible()
await this.page.getByTestId('dropdown-arc').click()
}
selectThreePointArc = async () => {
await this.page.getByRole('button', { name: 'caret down arcs:' }).click()
await this.page
.getByRole('button', { name: 'caret down Tangential Arc:' })
.click()
await expect(
this.page.getByTestId('dropdown-three-point-arc')
).toBeVisible()

View File

@ -21,9 +21,15 @@ test.describe('Import UI tests', () => {
path.join(projectDir, 'toBeImported.kcl'),
`sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([281.54, 305.81], sketch001)
|> angledLine(angle = 0, length = 123.43, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> angledLine([0, 123.43], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
85.99
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude(profile001, length = 100)`
@ -38,9 +44,15 @@ importedCube
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([-134.53, -56.17], sketch001)
|> angledLine(angle = 0, length = 79.05, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|> angledLine([0, 79.05], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
76.28
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $seg01)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|> close()
extrude001 = extrude(profile001, length = 100)

View File

@ -1,63 +0,0 @@
import type { Reporter, TestCase, TestResult } from '@playwright/test/reporter'
class MyAPIReporter implements Reporter {
onTestEnd(test: TestCase, result: TestResult): void {
if (!process.env.TAB_API_URL || !process.env.TAB_API_KEY) {
return
}
const payload = {
// Required information
project: 'https://github.com/KittyCAD/modeling-app',
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
test: test.titlePath().slice(2).join(' '),
status: result.status,
// Optional information
duration: result.duration / 1000,
message: result.error?.stack,
target: process.env.TARGET || null,
platform: process.env.RUNNER_OS || process.platform,
// Extra test and result data
annotations: test.annotations.map((a) => a.type),
retries: result.retry,
// Extra environment variables
CI_COMMIT_SHA: process.env.CI_COMMIT_SHA || null,
CI_PR_NUMBER: process.env.CI_PR_NUMBER || null,
GITHUB_BASE_REF: process.env.GITHUB_BASE_REF || null,
GITHUB_EVENT_NAME: process.env.GITHUB_EVENT_NAME || null,
GITHUB_HEAD_REF: process.env.GITHUB_HEAD_REF || null,
GITHUB_REF_NAME: process.env.GITHUB_REF_NAME || null,
GITHUB_REF: process.env.GITHUB_REF || null,
GITHUB_SHA: process.env.GITHUB_SHA || null,
GITHUB_WORKFLOW: process.env.GITHUB_WORKFLOW || null,
RUNNER_ARCH: process.env.RUNNER_ARCH || null,
}
void (async () => {
try {
const response = await fetch(`${process.env.TAB_API_URL}/api/results`, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json',
'X-API-Key': process.env.TAB_API_KEY || '',
}),
body: JSON.stringify(payload),
})
if (!response.ok && !process.env.CI) {
console.error(
'TAB API - Failed to send test result:',
await response.text()
)
}
} catch {
if (!process.env.CI) {
console.error('TAB API - Unable to send test result')
}
}
})()
}
}
export default MyAPIReporter

View File

@ -6,9 +6,7 @@ import type { NamedView } from '@rust/kcl-lib/bindings/NamedView'
import {
createProject,
orRunWhenFullSuiteEnabled,
perProjectSettingsToToml,
runningOnMac,
perProjectsettingsToToml,
tomlToPerProjectSettings,
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
@ -59,13 +57,10 @@ function tomlStringOverWriteNamedViewUuids(toml: string): string {
settings.settings.app.named_views = remappedNamedViews
}
}
return perProjectSettingsToToml(settings)
return perProjectsettingsToToml(settings)
}
test.describe('Named view tests', () => {
if (runningOnMac()) {
test.fixme(orRunWhenFullSuiteEnabled())
}
test('Verify project.toml is not created', async ({ page }, testInfo) => {
// Create project and load it
const projectName = 'named-views'
@ -109,9 +104,6 @@ test.describe('Named view tests', () => {
PROJECT_SETTINGS_FILE_NAME
)
const toastMessage = page.getByText('Named view uuid1 created.')
await expect(toastMessage).toBeInViewport()
// Expect project.toml to be generated on disk since a named view was created
await expect(async () => {
let exists = await fileExists(tempProjectSettingsFilePath)
@ -137,6 +129,7 @@ test.describe('Named view tests', () => {
}, testInfo) => {
const projectName = 'named-views'
const myNamedView1 = 'uuid1'
const myNamedView2 = 'uuid2'
// Create project and go into the project
await createProject({ name: projectName, page })
@ -148,9 +141,6 @@ test.describe('Named view tests', () => {
await cmdBar.argumentInput.fill(myNamedView1)
await cmdBar.progressCmdBar(false)
let toastMessage = page.getByText('Named view uuid1 created.')
await expect(toastMessage).toBeInViewport()
// Generate file paths for project.toml
const projectDirName = testInfo.outputPath('electron-test-projects-dir')
const tempProjectSettingsFilePath = join(
@ -179,20 +169,17 @@ test.describe('Named view tests', () => {
// Delete a named view
await cmdBar.openCmdBar()
await cmdBar.chooseCommand('delete named view')
cmdBar.selectOption({ name: myNamedView1 })
cmdBar.selectOption({ name: myNamedView2 })
await cmdBar.progressCmdBar(false)
toastMessage = page.getByText('Named view uuid1 removed.')
await expect(toastMessage).toBeInViewport()
await expect(async () => {
// Read project.toml into memory again since we deleted a named view
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
tomlString = tomlStringOverWriteNamedViewUuids(tomlString)
// Write the entire tomlString to a snapshot.
// There are many key/value pairs to check this is a safer match.
// // Write the entire tomlString to a snapshot.
// // There are many key/value pairs to check this is a safer match.
expect(tomlString).toMatchSnapshot('verify-named-view-gets-deleted')
}).toPass()
})
@ -214,9 +201,6 @@ test.describe('Named view tests', () => {
await cmdBar.argumentInput.fill(myNamedView)
await cmdBar.progressCmdBar(false)
let toastMessage = page.getByText('Named view uuid1 created.')
await expect(toastMessage).toBeInViewport()
// Generate file paths for project.toml
const projectDirName = testInfo.outputPath('electron-test-projects-dir')
const tempProjectSettingsFilePath = join(
@ -273,19 +257,26 @@ test.describe('Named view tests', () => {
await cmdBar.argumentInput.fill(myNamedView1)
await cmdBar.progressCmdBar(false)
let toastMessage = page.getByText('Named view uuid1 created.')
await expect(toastMessage).toBeInViewport()
await page.waitForTimeout(1000)
await scene.moveCameraTo({ x: 608, y: 0, z: 0 }, { x: 0, y: 0, z: 0 })
await page.waitForTimeout(2500)
const orbitMouseStart = { x: 800, y: 130 }
const orbitMouseEnd = { x: 0, y: 130 }
await page.mouse.move(orbitMouseStart.x, orbitMouseStart.y)
await page.mouse.down({ button: 'middle' })
await page.mouse.move(orbitMouseEnd.x, orbitMouseEnd.y, {
steps: 3,
})
await page.mouse.up({ button: 'middle' })
await page.waitForTimeout(1000)
await cmdBar.openCmdBar()
await cmdBar.chooseCommand('create named view')
await cmdBar.argumentInput.fill(myNamedView2)
await cmdBar.progressCmdBar(false)
toastMessage = page.getByText('Named view uuid2 created.')
await expect(toastMessage).toBeInViewport()
// Wait a moment for the project.toml to get written to disk with the new view point
await page.waitForTimeout(1000)
// Generate paths for the project.toml
const tempProjectSettingsFilePath = join(

View File

@ -1,16 +0,0 @@
[settings]
modeling = { }
text_editor = { }
command_bar = { }
[settings.app.named_views.0656fb1a-9640-473e-b334-591dc70c0138]
name = "uuid1"
eye_offset = 1_378.0059
fov_y = 45
is_ortho = false
ortho_scale_enabled = true
ortho_scale_factor = 1.6
pivot_position = [ 0, 0, 0 ]
pivot_rotation = [ 0.5380994, 0.0, 0.0, 0.8428814 ]
world_coord_system = "right_handed_up_z"
version = 1

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