Compare commits
52 Commits
nightly-v2
...
lf94/speci
Author | SHA1 | Date | |
---|---|---|---|
b5bcb8a5ff | |||
5e72da5770 | |||
00be11f6d6 | |||
4fd53d527f | |||
0f75d945b1 | |||
9cc956ddff | |||
dec74f633b | |||
dfcea282ec | |||
191dcf8bb0 | |||
cb1bbe4660 | |||
ff66cb1deb | |||
ab46349d63 | |||
cffad78bf7 | |||
bfb81877d3 | |||
c56398db83 | |||
36e0d35968 | |||
62bf7d8715 | |||
a4db302174 | |||
66f3500ca9 | |||
c3bdc6f106 | |||
0a2bf4b55f | |||
bbae9b6363 | |||
180d52280d | |||
dce1dca7c7 | |||
343f6572a2 | |||
c8e58d49e0 | |||
c18546fb2f | |||
466c23a9d8 | |||
8403025c77 | |||
9ce591a1a1 | |||
f238f3882b | |||
a91208eb1c | |||
b92b0a9afe | |||
964347f43a | |||
3811c88b5c | |||
69a1473197 | |||
1f1e996cfa | |||
58167deda7 | |||
83d22a4f5f | |||
7003b19a70 | |||
687ef1429d | |||
b1b00a9a22 | |||
a0924bcfa3 | |||
5ce22e2de8 | |||
850c5c62d1 | |||
b31786c9ab | |||
936549d60f | |||
0babbcff49 | |||
02c2e80b31 | |||
da236d9a3e | |||
1104d908c0 | |||
2efea3ec06 |
@ -1,4 +1,4 @@
|
||||
src/wasm-lib/*
|
||||
rust/*
|
||||
*.typegen.ts
|
||||
packages/codemirror-lsp-client/dist/*
|
||||
e2e/playwright/snapshots/prompt-to-edit/*
|
||||
|
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@ -25,7 +25,7 @@ updates:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src/wasm-lib/' # Location of package manifests
|
||||
directory: '/rust/' # Location of package manifests
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
@ -39,3 +39,11 @@ updates:
|
||||
wasm-bindgen-deps:
|
||||
patterns:
|
||||
- "wasm-bindgen*"
|
||||
- package-ecosystem: "pip" # See documentation for possible values
|
||||
directory: "/rust/kcl-python-bindings/" # Location of package manifests
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
|
4
.github/workflows/build-and-store-wasm.yml
vendored
4
.github/workflows/build-and-store-wasm.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
- name: Cache wasm
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
workspaces: './rust'
|
||||
- uses: taiki-e/install-action@2dbeb927f58939d3aa13bf06ba0c0a34b76b9bfb
|
||||
with:
|
||||
tool: wasm-pack
|
||||
@ -33,4 +33,4 @@ jobs:
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wasm-bundle
|
||||
path: src/wasm-lib/pkg
|
||||
path: rust/kcl-wasm-lib/pkg
|
||||
|
23
.github/workflows/build-apps.yml
vendored
23
.github/workflows/build-apps.yml
vendored
@ -38,9 +38,9 @@ jobs:
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
workspaces: './rust'
|
||||
|
||||
# TODO: see if we can fetch from main instead if no diff at src/wasm-lib
|
||||
# TODO: see if we can fetch from main instead if no diff at rust
|
||||
- uses: taiki-e/install-action@2dbeb927f58939d3aa13bf06ba0c0a34b76b9bfb
|
||||
with:
|
||||
tool: wasm-pack
|
||||
@ -67,7 +67,7 @@ jobs:
|
||||
path: |
|
||||
package.json
|
||||
electron-builder.yml
|
||||
src/wasm-lib/pkg/wasm_lib*
|
||||
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
|
||||
release-notes.md
|
||||
assets/icon.ico
|
||||
assets/icon.png
|
||||
@ -117,9 +117,9 @@ jobs:
|
||||
ls -R prepared-files
|
||||
cp prepared-files/package.json package.json
|
||||
cp prepared-files/electron-builder.yml electron-builder.yml
|
||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||
mkdir src/wasm-lib/pkg
|
||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
|
||||
cp prepared-files/rust/kcl-wasm-lib/pkg/kcl_wasm_lib_bg.wasm public
|
||||
mkdir rust/kcl-wasm-lib/pkg
|
||||
cp prepared-files/rust/kcl-wasm-lib/pkg/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
|
||||
cp prepared-files/release-notes.md release-notes.md
|
||||
cp prepared-files/assets/icon.ico assets/icon.ico
|
||||
cp prepared-files/assets/icon.png assets/icon.png
|
||||
@ -132,8 +132,9 @@ jobs:
|
||||
|
||||
- name: yarn install
|
||||
# Windows is picky sometimes and fails on fetch. Step takes about ~30s
|
||||
uses: nick-fields/retry@v3.0.1
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 2
|
||||
max_attempts: 3
|
||||
command: yarn install
|
||||
@ -183,8 +184,9 @@ jobs:
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
DEBUG: "electron-notarize*"
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.1
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn tronb:package:prod
|
||||
@ -244,8 +246,9 @@ jobs:
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
DEBUG: "electron-notarize*"
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.1
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn tronb:package:prod
|
||||
@ -386,7 +389,7 @@ jobs:
|
||||
# see https://github.com/actions/checkout/issues/1471
|
||||
git fetch --prune --unshallow --tags
|
||||
export TAG="nightly-${VERSION}"
|
||||
export PREVIOUS_TAG=$(git describe --tags --match="nightly-v[0-9]*" --abbrev=0)
|
||||
export PREVIOUS_TAG=$(git tag --list --sort=-committerdate "nightly-v[0-9]*" | head -n2 | tail -n1)
|
||||
export NOTES=$(./scripts/get-nightly-changelog.sh)
|
||||
yarn files:set-notes
|
||||
|
||||
|
8
.github/workflows/cargo-check.yml
vendored
8
.github/workflows/cargo-check.yml
vendored
@ -17,23 +17,21 @@ jobs:
|
||||
cargocheck:
|
||||
name: cargo check
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
dir: ['src/wasm-lib']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install latest rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.85
|
||||
override: true
|
||||
default: true
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
|
||||
- name: Run check
|
||||
run: |
|
||||
cd "${{ matrix.dir }}"
|
||||
cd rust
|
||||
# We specifically want to test the disable-println feature
|
||||
# Since it is not enabled by default, we need to specify it
|
||||
# This is used in kcl-lsp
|
||||
|
8
.github/workflows/cargo-clippy.yml
vendored
8
.github/workflows/cargo-clippy.yml
vendored
@ -23,17 +23,15 @@ jobs:
|
||||
cargoclippy:
|
||||
name: cargo clippy
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
dir: ['src/wasm-lib']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: taiki-e/install-action@just
|
||||
- name: Install latest rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.85
|
||||
override: true
|
||||
default: true
|
||||
components: clippy
|
||||
|
||||
- name: Rust Cache
|
||||
@ -41,7 +39,7 @@ jobs:
|
||||
|
||||
- name: Run clippy
|
||||
run: |
|
||||
cd "${{ matrix.dir }}"
|
||||
cd rust
|
||||
just lint
|
||||
# If this fails, run "cargo check" to update Cargo.lock,
|
||||
# then add Cargo.lock to the PR.
|
||||
|
8
.github/workflows/cargo-fmt.yml
vendored
8
.github/workflows/cargo-fmt.yml
vendored
@ -26,16 +26,14 @@ jobs:
|
||||
cargofmt:
|
||||
name: cargo fmt
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
dir: ['src/wasm-lib']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install latest rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.85
|
||||
override: true
|
||||
default: true
|
||||
components: rustfmt
|
||||
|
||||
- name: Rust Cache
|
||||
@ -43,6 +41,6 @@ jobs:
|
||||
|
||||
- name: Run cargo fmt
|
||||
run: |
|
||||
cd "${{ matrix.dir }}"
|
||||
cd rust
|
||||
cargo fmt -- --check
|
||||
shell: bash
|
||||
|
14
.github/workflows/cargo-test.yml
vendored
14
.github/workflows/cargo-test.yml
vendored
@ -9,21 +9,19 @@ permissions: read-all
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
name: cargo test of wasm-lib
|
||||
name: cargo test
|
||||
jobs:
|
||||
cargotest:
|
||||
name: cargo test
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
strategy:
|
||||
matrix:
|
||||
dir: ['src/wasm-lib']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install latest rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.85
|
||||
override: true
|
||||
default: true
|
||||
- name: Install vector
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
|
||||
@ -45,8 +43,8 @@ jobs:
|
||||
- name: cargo test
|
||||
shell: bash
|
||||
run: |-
|
||||
cd "${{ matrix.dir }}"
|
||||
cargo llvm-cov nextest --workspace --lcov --output-path lcov.info --test-threads=1 --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log
|
||||
cd rust
|
||||
cargo llvm-cov nextest --workspace --lcov --output-path lcov.info --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
|
||||
RUST_MIN_STACK: 10485760000
|
||||
@ -55,7 +53,7 @@ jobs:
|
||||
with:
|
||||
token: ${{secrets.CODECOV_TOKEN}}
|
||||
fail_ci_if_error: true
|
||||
flags: wasm-lib
|
||||
flags: rust
|
||||
verbose: true
|
||||
files: lcov.info
|
||||
|
||||
|
53
.github/workflows/e2e-tests.yml
vendored
53
.github/workflows/e2e-tests.yml
vendored
@ -3,6 +3,8 @@ on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: 0 * * * * # hourly
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
@ -15,23 +17,6 @@ permissions:
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
check-rust-changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
rust-changed: ${{ steps.filter.outputs.rust }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- id: filter
|
||||
name: Check for Rust changes
|
||||
uses: dorny/paths-filter@v3
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'src/wasm-lib/**'
|
||||
|
||||
electron:
|
||||
timeout-minutes: 60
|
||||
name: playwright:electron:${{ matrix.os }} ${{ matrix.shardIndex }} ${{ matrix.shardTotal }}
|
||||
@ -42,8 +27,8 @@ jobs:
|
||||
os: [namespace-profile-ubuntu-8-cores, namespace-profile-macos-8-cores, windows-16-cores]
|
||||
shardIndex: [1, 2, 3, 4]
|
||||
shardTotal: [4]
|
||||
# TODO: add ref here for main and latest release tag
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: check-rust-changes
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
@ -54,12 +39,19 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
- id: filter
|
||||
name: Check for Rust changes
|
||||
uses: dorny/paths-filter@v3
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'rust/**'
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- uses: KittyCAD/action-install-cli@main
|
||||
- name: Install dependencies
|
||||
id: deps-install
|
||||
shell: bash
|
||||
run: yarn
|
||||
- name: Cache Playwright Browsers
|
||||
@ -73,7 +65,7 @@ jobs:
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Download Wasm Cache
|
||||
id: download-wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
if: github.event_name != 'schedule' && steps.filter.outputs.rust == 'false'
|
||||
uses: dawidd6/action-download-artifact@v7
|
||||
continue-on-error: true
|
||||
with:
|
||||
@ -81,11 +73,11 @@ jobs:
|
||||
name: wasm-bundle
|
||||
workflow: build-and-store-wasm.yml
|
||||
branch: main
|
||||
path: src/wasm-lib/pkg
|
||||
path: rust/kcl-wasm-lib/pkg
|
||||
- name: copy wasm blob
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
if: github.event_name != 'schedule' && steps.filter.outputs.rust == 'false'
|
||||
shell: bash
|
||||
run: cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||
run: cp rust/kcl-wasm-lib/pkg/kcl_wasm_lib_bg.wasm public
|
||||
continue-on-error: true
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
@ -93,15 +85,15 @@ jobs:
|
||||
with:
|
||||
tool: wasm-pack
|
||||
- name: Cache Wasm (because rust diff)
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
if: github.event_name == 'schedule' || steps.filter.outputs.rust == 'true'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
workspaces: './rust'
|
||||
- name: OR Cache Wasm (because wasm cache failed)
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
workspaces: './rust'
|
||||
- name: install good sed
|
||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
shell: bash
|
||||
@ -126,7 +118,7 @@ jobs:
|
||||
cat /tmp/vector.toml
|
||||
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
|
||||
- name: Build Wasm (because rust diff)
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
if: github.event_name == 'schedule' || steps.filter.outputs.rust == 'true'
|
||||
shell: bash
|
||||
run: yarn build:wasm
|
||||
- name: OR Build Wasm (because wasm cache failed)
|
||||
@ -142,7 +134,7 @@ jobs:
|
||||
# TODO: break this in its own job, for now it's not slowing down the overall execution as ubuntu is the quickest,
|
||||
# but we could do better. This forces a large 1/1 shard of all 20 snapshot tests that runs in about 3 minutes.
|
||||
run: |
|
||||
PLATFORM=web yarn playwright test --config=playwright.config.ts --retries="3" --update-snapshots --grep=@snapshot --trace=on --shard=1/1
|
||||
yarn test:snapshots
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: development
|
||||
@ -202,9 +194,10 @@ jobs:
|
||||
path: test-results/
|
||||
- name: Run playwright/electron flow (with retries)
|
||||
id: retry
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
uses: nick-fields/retry@v3.0.1
|
||||
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{matrix.os}}
|
||||
timeout_minutes: 30
|
||||
max_attempts: 25
|
||||
|
179
.github/workflows/kcl-python-bindings.yml
vendored
Normal file
179
.github/workflows/kcl-python-bindings.yml
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
# This file is autogenerated by maturin v1.6.0 and then modified
|
||||
# To update, run
|
||||
#
|
||||
# maturin generate-ci github
|
||||
#
|
||||
name: kcl-python-bindings
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- 'rust/kcl-python-bindings/**'
|
||||
- '**.rs'
|
||||
- .github/workflows/kcl-python-bindings.yml
|
||||
tags:
|
||||
- 'kcl-*'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- 'rust/kcl-python-bindings/**'
|
||||
- '**.rs'
|
||||
- .github/workflows/kcl-python-bindings.yml
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
linux-x86_64:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
working-directory: rust/kcl-python-bindings
|
||||
target: x86_64
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
manylinux: auto
|
||||
before-script-linux: |
|
||||
yum install openssl-devel -y
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-linux-x86_64
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
windows:
|
||||
runs-on: windows-16-cores
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- x64
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
architecture: ${{ matrix.target }}
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
working-directory: rust/kcl-python-bindings
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-windows-${{ matrix.target }}
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
macos:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- x86_64
|
||||
- aarch64
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
working-directory: rust/kcl-python-bindings
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-macos-${{ matrix.target }}
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
- uses: taiki-e/install-action@just
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd rust/kcl-python-bindings
|
||||
just setup-uv
|
||||
just test
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN }}
|
||||
|
||||
sdist:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install the latest version of uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
- name: Install codespell
|
||||
run: |
|
||||
uv venv .venv
|
||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||
uv pip install pip --upgrade
|
||||
- name: Build sdist
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
working-directory: rust/kcl-python-bindings
|
||||
command: sdist
|
||||
args: --out dist
|
||||
- name: Upload sdist
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-sdist
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
needs: [linux-x86_64, windows, macos, sdist]
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- name: Install the latest version of uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
- name: Install codespell
|
||||
run: |
|
||||
cd rust/kcl-python-bindings
|
||||
uv venv .venv
|
||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||
uv pip install pip --upgrade
|
||||
- name: Publish to PyPI
|
||||
uses: PyO3/maturin-action@v1
|
||||
env:
|
||||
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||||
with:
|
||||
working-directory: rust/kcl-python-bindings
|
||||
command: upload
|
||||
args: --non-interactive --skip-existing wheels-*/*
|
24
.github/workflows/ruff.yml
vendored
Normal file
24
.github/workflows/ruff.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: ruff
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
paths:
|
||||
- '**.py'
|
||||
- .github/workflows/ruff.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.py'
|
||||
- .github/workflows/ruff.yml
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
jobs:
|
||||
ruff:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/ruff-action@v3
|
||||
|
2
.github/workflows/static-analysis.yml
vendored
2
.github/workflows/static-analysis.yml
vendored
@ -54,7 +54,7 @@ jobs:
|
||||
- run: yarn install
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
workspaces: './rust'
|
||||
|
||||
- uses: taiki-e/install-action@2dbeb927f58939d3aa13bf06ba0c0a34b76b9bfb
|
||||
with:
|
||||
|
25
.gitignore
vendored
25
.gitignore
vendored
@ -26,16 +26,15 @@ yarn-error.log*
|
||||
.idea
|
||||
.vscode
|
||||
.helix
|
||||
src/wasm-lib/.idea
|
||||
src/wasm-lib/.vscode
|
||||
|
||||
# rust
|
||||
src/wasm-lib/target
|
||||
src/wasm-lib/bindings
|
||||
src/wasm-lib/kcl/bindings
|
||||
public/wasm_lib_bg.wasm
|
||||
src/wasm-lib/lcov.info
|
||||
src/wasm-lib/grackle/test_json_output
|
||||
rust/target
|
||||
rust/kcl-lib/bindings
|
||||
public/kcl_wasm_lib_bg.wasm
|
||||
rust/lcov.info
|
||||
rust/kcl-wasm-lib/pkg
|
||||
*.snap.new
|
||||
rust/kcl-lib/fuzz/Cargo.lock
|
||||
|
||||
e2e/playwright/playwright-secrets.env
|
||||
e2e/playwright/temp1.png
|
||||
@ -59,16 +58,18 @@ e2e/playwright/export-snapshots/*
|
||||
## generated files
|
||||
src/**/*.typegen.ts
|
||||
|
||||
src/wasm-lib/grackle/stdlib_cube_partial.json
|
||||
Mac_App_Distribution.provisionprofile
|
||||
|
||||
*.tsbuildinfo
|
||||
src/wasm-lib/pkg
|
||||
|
||||
.eslintcache
|
||||
venv
|
||||
.vite/
|
||||
|
||||
# electron
|
||||
out/
|
||||
*.snap.new
|
||||
|
||||
# python
|
||||
__pycache__/
|
||||
uv.lock
|
||||
rust/kcl-python-bindings/dist
|
||||
venv
|
||||
|
@ -7,8 +7,7 @@ coverage
|
||||
*.rs
|
||||
*.hbs
|
||||
target
|
||||
src/wasm-lib/pkg
|
||||
src/wasm-lib/kcl/bindings
|
||||
rust/
|
||||
e2e/playwright/export-snapshots
|
||||
e2e/playwright/snapshots/prompt-to-edit
|
||||
|
||||
|
4
Makefile
4
Makefile
@ -1,6 +1,6 @@
|
||||
.PHONY: dev
|
||||
|
||||
WASM_LIB_FILES := $(wildcard src/wasm-lib/**/*.rs)
|
||||
KCL_WASM_LIB_FILES := $(wildcard rust/**/*.rs)
|
||||
TS_SRC := $(wildcard src/**/*.tsx) $(wildcard src/**/*.ts)
|
||||
XSTATE_TYPEGENS := $(wildcard src/machines/*.typegen.ts)
|
||||
|
||||
@ -18,7 +18,7 @@ lee-electron-test:
|
||||
$(XSTATE_TYPEGENS): $(TS_SRC)
|
||||
yarn xstate typegen 'src/**/*.ts?(x)'
|
||||
|
||||
public/wasm_lib_bg.wasm: $(WASM_LIB_FILES)
|
||||
public/kcl_wasm_lib_bg.wasm: $(KCL_WASM_LIB_FILES)
|
||||
yarn build:wasm
|
||||
|
||||
node_modules: package.json yarn.lock
|
||||
|
36
README.md
36
README.md
@ -40,7 +40,7 @@ The 3D view in Modeling App is just a video stream from our hosted geometry engi
|
||||
|
||||
[Original demo video](https://drive.google.com/file/d/183_wjqGdzZ8EEZXSqZ3eDcJocYPCyOdC/view?pli=1)
|
||||
|
||||
[Original demo slides](https://github.com/KittyCAD/Eng/files/10398178/demo.pdf)
|
||||
[Original demo slides](https://github.com/user-attachments/files/19010536/demo.pdf)
|
||||
|
||||
## Get started
|
||||
|
||||
@ -52,18 +52,21 @@ Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=r
|
||||
|
||||
On Windows, it's also recommended to [upgrade your PowerShell version](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5#winget), we're using 7.
|
||||
|
||||
Then in the repo run the following to install and use the node version specified in `.nvmrc`. You might need to specify your processor architecture with `--arch arm64` or `--arch x64` if it's not autodetected.
|
||||
Then in the repo run the following to install and use the node version specified in `.nvmrc`. You might need to specify your processor architecture with `--arch arm64` or `--arch x64` if it's not autodetected.
|
||||
|
||||
```
|
||||
fnm install --corepack-enabled
|
||||
fnm use
|
||||
```
|
||||
|
||||
Install the NPM dependencies with:
|
||||
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. We have package scripts to run rustup, see `package.json` for reference:
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
yarn install:rust
|
||||
@ -75,6 +78,7 @@ yarn install:wasm-pack:cargo
|
||||
```
|
||||
|
||||
Then to build the WASM layer, run:
|
||||
|
||||
```
|
||||
# macOS/Linux
|
||||
yarn build:wasm
|
||||
@ -135,6 +139,7 @@ To package the app for your platform with electron-builder, run `yarn tronb:pack
|
||||
Which commands from setup are one off vs need to be run every time?
|
||||
|
||||
The following will need to be run when checking out a new commit and guarantees the build is not stale:
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
yarn build:wasm
|
||||
@ -185,11 +190,12 @@ Manually test against this [list](https://github.com/KittyCAD/modeling-app/issue
|
||||
|
||||
##### Updater-test builds
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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)
|
||||
& 'C:\Program Files\Zoo Modeling App\Zoo Modeling App.exe'
|
||||
@ -205,15 +211,14 @@ If the prompt doesn't show up, start the app in command line to grab the electro
|
||||
|
||||
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
|
||||
|
||||
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
|
||||
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
|
||||
|
||||
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
|
||||
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
|
||||
|
||||
#### 5. Close the issue
|
||||
|
||||
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
|
||||
|
||||
|
||||
## Fuzzing the parser
|
||||
|
||||
Make sure you install cargo fuzz:
|
||||
@ -223,7 +228,7 @@ $ cargo install cargo-fuzz
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cd src/wasm-lib/kcl
|
||||
$ cd rust/kcl-lib
|
||||
|
||||
# list the fuzz targets
|
||||
$ cargo fuzz list
|
||||
@ -251,6 +256,7 @@ snapshottoken=<your-snapshot-token>
|
||||
For a portable way to run Playwright you'll need Docker.
|
||||
|
||||
#### Generic example
|
||||
|
||||
After that, open a terminal and run:
|
||||
|
||||
```bash
|
||||
@ -263,7 +269,6 @@ and in another terminal, run:
|
||||
PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn playwright test --project="Google Chrome" <test suite>
|
||||
```
|
||||
|
||||
|
||||
#### Specific example
|
||||
|
||||
open a terminal and run:
|
||||
@ -281,7 +286,6 @@ PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn playwright test --project=
|
||||
run a specific test change the test from `test('...` to `test.only('...`
|
||||
(note if you commit this, the tests will instantly fail without running any of the tests)
|
||||
|
||||
|
||||
**Gotcha**: running the docker container with a mismatched image against your `./node_modules/playwright` will cause a failure. Make sure the versions are matched and up to date.
|
||||
|
||||
run headed
|
||||
@ -375,17 +379,19 @@ Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testin
|
||||
- `just`
|
||||
|
||||
#### Setting KITTYCAD_API_TOKEN
|
||||
|
||||
Use the production zoo.dev token, set this environment variable before running the tests
|
||||
|
||||
#### Installing cargonextest
|
||||
|
||||
```
|
||||
cd src/wasm-lib
|
||||
cd rust
|
||||
cargo search cargo-nextest
|
||||
cargo install cargo-nextest
|
||||
```
|
||||
|
||||
#### just
|
||||
|
||||
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
|
||||
|
||||
#### Running the tests
|
||||
@ -395,7 +401,7 @@ install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-bina
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
# Make sure you installed just
|
||||
cd src/wasm-lib
|
||||
cd rust
|
||||
just test
|
||||
```
|
||||
|
||||
@ -403,7 +409,7 @@ just test
|
||||
# Without just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
cd src/wasm-lib
|
||||
cd rust
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
```
|
||||
|
||||
@ -412,13 +418,14 @@ Where `XXX` is an API token from the production engine (NOT the dev environment)
|
||||
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
|
||||
|
||||
```
|
||||
cd src/wasm-lib
|
||||
cd rust
|
||||
KITTYCAD_API_TOKEN=XXX cargo run nextest
|
||||
```
|
||||
|
||||
### Mapping CI CD jobs to local commands
|
||||
|
||||
When you see the CI CD fail on jobs you may wonder three things
|
||||
|
||||
- Do I have a bug in my code?
|
||||
- Is the test flaky?
|
||||
- Is there a bug in `main`?
|
||||
@ -437,7 +444,6 @@ yarn test-setup
|
||||
|
||||
> Gotcha, are packages up to date and is the wasm built?
|
||||
|
||||
|
||||
```
|
||||
yarn tsc
|
||||
yarn fmt-check
|
||||
@ -493,7 +499,7 @@ PS: for the debug panel, the following JSON is useful for snapping the camera
|
||||
|
||||
## KCL
|
||||
|
||||
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/src/wasm-lib/kcl).
|
||||
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib).
|
||||
|
||||
### Logging
|
||||
|
||||
|
@ -9,7 +9,11 @@ Returns the angle to match the given length for x.
|
||||
|
||||
|
||||
```js
|
||||
angleToMatchLengthX(tag: TagIdentifier, to: number, sketch: Sketch) -> number
|
||||
angleToMatchLengthX(
|
||||
tag: TagIdentifier,
|
||||
to: number,
|
||||
sketch: Sketch,
|
||||
) -> number
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Returns the angle to match the given length for y.
|
||||
|
||||
|
||||
```js
|
||||
angleToMatchLengthY(tag: TagIdentifier, to: number, sketch: Sketch) -> number
|
||||
angleToMatchLengthY(
|
||||
tag: TagIdentifier,
|
||||
to: number,
|
||||
sketch: Sketch,
|
||||
) -> number
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Draw a line segment relative to the current origin using the polar
|
||||
measure of some angle and distance.
|
||||
|
||||
```js
|
||||
angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLine(
|
||||
data: AngledLineData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some relative length in the 'x' dimension.
|
||||
|
||||
```js
|
||||
angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineOfXLength(
|
||||
data: AngledLineData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some relative length in the 'y' dimension.
|
||||
|
||||
```js
|
||||
angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineOfYLength(
|
||||
data: AngledLineData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Draw an angled line from the current origin, constructing a line segment
|
||||
such that the newly created line intersects the desired target line segment.
|
||||
|
||||
```js
|
||||
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineThatIntersects(
|
||||
data: AngledLineThatIntersectsData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some length, ending at the provided value in the 'x' dimension.
|
||||
|
||||
```js
|
||||
angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineToX(
|
||||
data: AngledLineToData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some length, ending at the provided value in the 'y' dimension.
|
||||
|
||||
```js
|
||||
angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineToY(
|
||||
data: AngledLineToData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,12 @@ Set the appearance of a solid. This only works on solids, not sketches or indivi
|
||||
This will work on any solid, including extruded solids, revolved solids, and shelled solids.
|
||||
|
||||
```js
|
||||
appearance(solidSet: SolidSet, color: String, metalness?: number, roughness?: number) -> SolidSet
|
||||
appearance(
|
||||
solidSet: SolidSet,
|
||||
color: String,
|
||||
metalness?: number,
|
||||
roughness?: number,
|
||||
) -> SolidSet
|
||||
```
|
||||
|
||||
|
||||
@ -48,7 +53,7 @@ example = extrude(exampleSketch, length = 5)
|
||||
```js
|
||||
// Add color to a revolved solid.
|
||||
sketch001 = startSketchOn('XY')
|
||||
|> circle({ center = [15, 0], radius = 5 }, %)
|
||||
|> circle(center = [15, 0], radius = 5)
|
||||
|> revolve({ angle = 360, axis = 'y' }, %)
|
||||
|> appearance(color = '#ff0000', metalness = 90, roughness = 90)
|
||||
```
|
||||
@ -190,10 +195,10 @@ sweepPath = startSketchOn('XZ')
|
||||
|> line(end = [0, 7])
|
||||
|
||||
pipeHole = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 1.5)
|
||||
|
||||
sweepSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> hole(pipeHole, %)
|
||||
|> sweep(path = sweepPath)
|
||||
|> appearance(color = "#ff0000", metalness = 50, roughness = 50)
|
||||
|
@ -11,7 +11,11 @@ The arc is constructed such that the current position of the sketch is placed al
|
||||
Unless this makes a lot of sense and feels like what you're looking for to construct your shape, you're likely looking for tangentialArc.
|
||||
|
||||
```js
|
||||
arc(data: ArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
arc(
|
||||
data: ArcData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Draw a 3 point arc.
|
||||
The arc is constructed such that the start point is the current position of the sketch and two more points defined as the end and interior point. The interior point is placed between the start point and end point. The radius of the arc will be controlled by how far the interior point is placed from the start and end.
|
||||
|
||||
```js
|
||||
arcTo(data: ArcToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
arcTo(
|
||||
data: ArcToData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@ Check a value at runtime, and raise an error if the argument provided
|
||||
is false.
|
||||
|
||||
```js
|
||||
assert(data: bool, message: string) -> ()
|
||||
assert(
|
||||
data: bool,
|
||||
message: string,
|
||||
) -> ()
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,12 @@ Check that a numerical value equals another at runtime,
|
||||
otherwise raise an error.
|
||||
|
||||
```js
|
||||
assertEqual(left: number, right: number, epsilon: number, message: string) -> ()
|
||||
assertEqual(
|
||||
left: number,
|
||||
right: number,
|
||||
epsilon: number,
|
||||
message: string,
|
||||
) -> ()
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Check that a numerical value is greater than another at runtime,
|
||||
otherwise raise an error.
|
||||
|
||||
```js
|
||||
assertGreaterThan(left: number, right: number, message: string) -> ()
|
||||
assertGreaterThan(
|
||||
left: number,
|
||||
right: number,
|
||||
message: string,
|
||||
) -> ()
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Check that a numerical value is greater than or equal to another at runtime,
|
||||
otherwise raise an error.
|
||||
|
||||
```js
|
||||
assertGreaterThanOrEq(left: number, right: number, message: string) -> ()
|
||||
assertGreaterThanOrEq(
|
||||
left: number,
|
||||
right: number,
|
||||
message: string,
|
||||
) -> ()
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Check that a numerical value is less than to another at runtime,
|
||||
otherwise raise an error.
|
||||
|
||||
```js
|
||||
assertLessThan(left: number, right: number, message: string) -> ()
|
||||
assertLessThan(
|
||||
left: number,
|
||||
right: number,
|
||||
message: string,
|
||||
) -> ()
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Check that a numerical value is less than or equal to another at runtime,
|
||||
otherwise raise an error.
|
||||
|
||||
```js
|
||||
assertLessThanOrEq(left: number, right: number, message: string) -> ()
|
||||
assertLessThanOrEq(
|
||||
left: number,
|
||||
right: number,
|
||||
message: string,
|
||||
) -> ()
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@ Compute the four quadrant arctangent of Y and X (in radians).
|
||||
|
||||
|
||||
```js
|
||||
atan2(y: number, x: number) -> number
|
||||
atan2(
|
||||
y: number,
|
||||
x: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -9,7 +9,11 @@ Draw a smooth, continuous, curved line segment from the current origin to
|
||||
the desired (x, y), using a number of control points to shape the curve's shape.
|
||||
|
||||
```js
|
||||
bezierCurve(data: BezierData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
bezierCurve(
|
||||
data: BezierData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,12 @@ Cut a straight transitional edge along a tagged path.
|
||||
Chamfer is similar in function and use to a fillet, except a fillet will blend the transition along an edge, rather than cut a sharp, straight transitional edge.
|
||||
|
||||
```js
|
||||
chamfer(solid: Solid, length: number, tags: [EdgeReference], tag?: TagDeclarator) -> Solid
|
||||
chamfer(
|
||||
solid: Solid,
|
||||
length: number,
|
||||
tags: [EdgeReference],
|
||||
tag?: TagDeclarator,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,12 @@ Construct a 2-dimensional circle, of the specified radius, centered at
|
||||
the provided (x, y) origin point.
|
||||
|
||||
```js
|
||||
circle(data: CircleData, sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclarator) -> Sketch
|
||||
circle(
|
||||
sketchOrSurface: SketchOrSurface,
|
||||
center: [number],
|
||||
radius: number,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -17,9 +22,10 @@ circle(data: CircleData, sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclara
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`CircleData`](/docs/kcl/types/CircleData) | Data for drawing an circle | Yes |
|
||||
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `sketchOrSurface` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on. | Yes |
|
||||
| `center` | `[number]` | The center of the circle. | Yes |
|
||||
| `radius` | `number` | The radius of the circle. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this circle | No |
|
||||
|
||||
### Returns
|
||||
|
||||
@ -30,7 +36,7 @@ circle(data: CircleData, sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclara
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn("-XZ")
|
||||
|> circle({ center = [0, 0], radius = 10 }, %)
|
||||
|> circle(center = [0, 0], radius = 10)
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
```
|
||||
@ -44,7 +50,7 @@ exampleSketch = startSketchOn("XZ")
|
||||
|> line(end = [0, 30])
|
||||
|> line(end = [-30, 0])
|
||||
|> close()
|
||||
|> hole(circle({ center = [0, 15], radius = 5 }, %), %)
|
||||
|> hole(circle(center = [0, 15], radius = 5), %)
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
```
|
||||
|
@ -9,7 +9,13 @@ Construct a circle derived from 3 points.
|
||||
|
||||
|
||||
```js
|
||||
circleThreePoint(p1: [number], p2: [number], p3: [number], sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclarator) -> Sketch
|
||||
circleThreePoint(
|
||||
p1: [number],
|
||||
p2: [number],
|
||||
p3: [number],
|
||||
sketchSurfaceOrGroup: SketchOrSurface,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@ Construct a line segment from the current origin back to the profile's
|
||||
origin, ensuring the resulting 2-dimensional sketch is not open-ended.
|
||||
|
||||
```js
|
||||
close(sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
close(
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ std::math::PI: number = 3.14159265358979323846264338327950288_
|
||||
circumference = 70
|
||||
|
||||
exampleSketch = startSketchOn("XZ")
|
||||
|> circle({ center = [0, 0], radius = circumference/ (2 * PI) }, %)
|
||||
|> circle(center = [0, 0], radius = circumference/ (2 * PI))
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
```
|
||||
|
@ -9,7 +9,10 @@ Extend a 2-dimensional sketch through a third dimension in order to
|
||||
create new 3-dimensional volume, or if extruded into an existing volume, cut into an existing solid.
|
||||
|
||||
```js
|
||||
extrude(sketchSet: SketchSet, length: number) -> SolidSet
|
||||
extrude(
|
||||
sketchSet: SketchSet,
|
||||
length: number,
|
||||
) -> SolidSet
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,13 @@ Blend a transitional edge along a tagged path, smoothing the sharp edge.
|
||||
Fillet is similar in function and use to a chamfer, except a chamfer will cut a sharp transition along an edge while fillet will smoothly blend the transition.
|
||||
|
||||
```js
|
||||
fillet(solid: Solid, radius: number, tags: [EdgeReference], tolerance?: number, tag?: TagDeclarator) -> Solid
|
||||
fillet(
|
||||
solid: Solid,
|
||||
radius: number,
|
||||
tags: [EdgeReference],
|
||||
tolerance?: number,
|
||||
tag?: TagDeclarator,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,14 @@ Create a helix.
|
||||
|
||||
|
||||
```js
|
||||
helix(revolutions: number, angleStart: number, ccw?: bool, radius: number, axis: Axis3dOrEdgeReference, length?: number) -> HelixValue
|
||||
helix(
|
||||
revolutions: number,
|
||||
angleStart: number,
|
||||
ccw?: bool,
|
||||
radius: number,
|
||||
axis: Axis3dOrEdgeReference,
|
||||
length?: number,
|
||||
) -> HelixValue
|
||||
```
|
||||
|
||||
|
||||
@ -44,7 +51,7 @@ helixPath = helix(
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('YZ')
|
||||
|> circle({ center = [0, 0], radius = 0.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 0.5)
|
||||
|> sweep(path = helixPath)
|
||||
```
|
||||
|
||||
@ -67,7 +74,7 @@ helixPath = helix(
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 0.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 0.5)
|
||||
|> sweep(path = helixPath)
|
||||
```
|
||||
|
||||
@ -91,7 +98,7 @@ helixPath = helix(
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
||||
|> circle(center = [0, 0], radius = 1)
|
||||
|> sweep(path = helixPath)
|
||||
```
|
||||
|
||||
|
@ -9,7 +9,10 @@ Create a helix on a cylinder.
|
||||
|
||||
|
||||
```js
|
||||
helixRevolutions(data: HelixRevolutionsData, solid: Solid) -> Solid
|
||||
helixRevolutions(
|
||||
data: HelixRevolutionsData,
|
||||
solid: Solid,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -29,7 +32,7 @@ helixRevolutions(data: HelixRevolutionsData, solid: Solid) -> Solid
|
||||
|
||||
```js
|
||||
part001 = startSketchOn('XY')
|
||||
|> circle({ center = [5, 5], radius = 10 }, %)
|
||||
|> circle(center = [5, 5], radius = 10)
|
||||
|> extrude(length = 10)
|
||||
|> helixRevolutions({
|
||||
angleStart = 0,
|
||||
|
@ -9,7 +9,10 @@ Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch.
|
||||
|
||||
|
||||
```js
|
||||
hole(holeSketch: SketchSet, sketch: Sketch) -> Sketch
|
||||
hole(
|
||||
holeSketch: SketchSet,
|
||||
sketch: Sketch,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -34,8 +37,8 @@ exampleSketch = startSketchOn(XY)
|
||||
|> line(end = [5, 0])
|
||||
|> line(end = [0, -5])
|
||||
|> close()
|
||||
|> hole(circle({ center = [1, 1], radius = .25 }, %), %)
|
||||
|> hole(circle({ center = [1, 4], radius = .25 }, %), %)
|
||||
|> hole(circle(center = [1, 1], radius = .25), %)
|
||||
|> hole(circle(center = [1, 4], radius = .25), %)
|
||||
|
||||
example = extrude(exampleSketch, length = 1)
|
||||
```
|
||||
@ -54,7 +57,7 @@ fn squareHoleSketch() {
|
||||
}
|
||||
|
||||
exampleSketch = startSketchOn(-XZ)
|
||||
|> circle({ center = [0, 0], radius = 3 }, %)
|
||||
|> circle(center = [0, 0], radius = 3)
|
||||
|> hole(squareHoleSketch(), %)
|
||||
example = extrude(exampleSketch, length = 1)
|
||||
```
|
||||
|
@ -9,7 +9,10 @@ Make the inside of a 3D object hollow.
|
||||
Remove volume from a 3-dimensional shape such that a wall of the provided thickness remains around the exterior of the shape.
|
||||
|
||||
```js
|
||||
hollow(thickness: number, solid: Solid) -> Solid
|
||||
hollow(
|
||||
thickness: number,
|
||||
solid: Solid,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -67,17 +70,11 @@ case = startSketchOn('-XZ')
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [-size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
thing2 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
hollow(0.5, case)
|
||||
|
@ -15,7 +15,10 @@ For formats lacking unit data (such as STL, OBJ, or PLY files), the default unit
|
||||
Note: The import command currently only works when using the native Modeling App.
|
||||
|
||||
```js
|
||||
import(filePath: String, options?: ImportFormat) -> ImportedGeometry
|
||||
import(
|
||||
filePath: String,
|
||||
options?: ImportFormat,
|
||||
) -> ImportedGeometry
|
||||
```
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ n = int(ceil(5 / 2))
|
||||
assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3")
|
||||
// Draw n cylinders.
|
||||
startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> extrude(length = 5)
|
||||
|> patternTransform(
|
||||
instances = n,
|
||||
|
@ -9,7 +9,10 @@ Compute the angle of the given leg for x.
|
||||
|
||||
|
||||
```js
|
||||
legAngX(hypotenuse: number, leg: number) -> number
|
||||
legAngX(
|
||||
hypotenuse: number,
|
||||
leg: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -9,7 +9,10 @@ Compute the angle of the given leg for y.
|
||||
|
||||
|
||||
```js
|
||||
legAngY(hypotenuse: number, leg: number) -> number
|
||||
legAngY(
|
||||
hypotenuse: number,
|
||||
leg: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -9,7 +9,10 @@ Compute the length of the given leg.
|
||||
|
||||
|
||||
```js
|
||||
legLen(hypotenuse: number, leg: number) -> number
|
||||
legLen(
|
||||
hypotenuse: number,
|
||||
leg: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -9,7 +9,12 @@ Extend the current sketch with a new straight line.
|
||||
|
||||
|
||||
```js
|
||||
line(sketch: Sketch, endAbsolute?: [number], end?: [number], tag?: TagDeclarator) -> Sketch
|
||||
line(
|
||||
sketch: Sketch,
|
||||
endAbsolute?: [number],
|
||||
end?: [number],
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,13 @@ Create a 3D surface or solid by interpolating between two or more sketches.
|
||||
The sketches need to closed and on the same plane.
|
||||
|
||||
```js
|
||||
loft(sketches: [Sketch], vDegree: NonZeroU32, bezApproximateRational: bool, baseCurveIndex?: integer, tolerance?: number) -> Solid
|
||||
loft(
|
||||
sketches: [Sketch],
|
||||
vDegree: NonZeroU32,
|
||||
bezApproximateRational: bool,
|
||||
baseCurveIndex?: integer,
|
||||
tolerance?: number,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -63,10 +69,10 @@ squareSketch = startSketchOn('XY')
|
||||
|> close()
|
||||
|
||||
circleSketch0 = startSketchOn(offsetPlane('XY', offset = 75))
|
||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
||||
|> circle(center = [0, 100], radius = 50)
|
||||
|
||||
circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
|
||||
|> circle({ center = [0, 100], radius = 20 }, %)
|
||||
|> circle(center = [0, 100], radius = 20)
|
||||
|
||||
loft([
|
||||
squareSketch,
|
||||
@ -88,10 +94,10 @@ squareSketch = startSketchOn('XY')
|
||||
|> close()
|
||||
|
||||
circleSketch0 = startSketchOn(offsetPlane('XY', offset = 75))
|
||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
||||
|> circle(center = [0, 100], radius = 50)
|
||||
|
||||
circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
|
||||
|> circle({ center = [0, 100], radius = 20 }, %)
|
||||
|> circle(center = [0, 100], radius = 20)
|
||||
|
||||
loft(
|
||||
[
|
||||
|
@ -9,7 +9,10 @@ Compute the logarithm of the number with respect to an arbitrary base.
|
||||
The result might not be correctly rounded owing to implementation details; `log2()` can produce more accurate results for base 2, and `log10()` can produce more accurate results for base 10.
|
||||
|
||||
```js
|
||||
log(num: number, base: number) -> number
|
||||
log(
|
||||
num: number,
|
||||
base: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -9,7 +9,10 @@ Apply a function to every element of a list.
|
||||
Given a list like `[a, b, c]`, and a function like `f`, returns `[f(a), f(b), f(c)]`
|
||||
|
||||
```js
|
||||
map(array: [KclValue], mapFn: FunctionSource) -> [KclValue]
|
||||
map(
|
||||
array: [KclValue],
|
||||
mapFn: FunctionSource,
|
||||
) -> [KclValue]
|
||||
```
|
||||
|
||||
|
||||
@ -31,7 +34,7 @@ map(array: [KclValue], mapFn: FunctionSource) -> [KclValue]
|
||||
r = 10 // radius
|
||||
fn drawCircle(id) {
|
||||
return startSketchOn("XY")
|
||||
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|
||||
|> circle(center = [id * 2 * r, 0], radius = r)
|
||||
}
|
||||
|
||||
// Call `drawCircle`, passing in each element of the array.
|
||||
@ -47,7 +50,7 @@ r = 10 // radius
|
||||
// Call `map`, using an anonymous function instead of a named one.
|
||||
circles = map([1..3], fn(id) {
|
||||
return startSketchOn("XY")
|
||||
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|
||||
|> circle(center = [id * 2 * r, 0], radius = r)
|
||||
})
|
||||
```
|
||||
|
||||
|
@ -11,7 +11,10 @@ Only works on unclosed sketches for now.
|
||||
Mirror occurs around a local sketch axis rather than a global axis.
|
||||
|
||||
```js
|
||||
mirror2d(data: Mirror2dData, sketchSet: SketchSet) -> [Sketch]
|
||||
mirror2d(
|
||||
data: Mirror2dData,
|
||||
sketchSet: SketchSet,
|
||||
) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@ Offset a plane by a distance along its normal.
|
||||
For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it.
|
||||
|
||||
```js
|
||||
offsetPlane(plane: PlaneData, offset: number) -> Plane
|
||||
offsetPlane(
|
||||
plane: PlaneData,
|
||||
offset: number,
|
||||
) -> Plane
|
||||
```
|
||||
|
||||
|
||||
@ -38,7 +41,7 @@ squareSketch = startSketchOn('XY')
|
||||
|> close()
|
||||
|
||||
circleSketch = startSketchOn(offsetPlane('XY', offset = 150))
|
||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
||||
|> circle(center = [0, 100], radius = 50)
|
||||
|
||||
loft([squareSketch, circleSketch])
|
||||
```
|
||||
@ -56,7 +59,7 @@ squareSketch = startSketchOn('XZ')
|
||||
|> close()
|
||||
|
||||
circleSketch = startSketchOn(offsetPlane('XZ', offset = 150))
|
||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
||||
|> circle(center = [0, 100], radius = 50)
|
||||
|
||||
loft([squareSketch, circleSketch])
|
||||
```
|
||||
@ -74,7 +77,7 @@ squareSketch = startSketchOn('YZ')
|
||||
|> close()
|
||||
|
||||
circleSketch = startSketchOn(offsetPlane('YZ', offset = 150))
|
||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
||||
|> circle(center = [0, 100], radius = 50)
|
||||
|
||||
loft([squareSketch, circleSketch])
|
||||
```
|
||||
@ -92,7 +95,7 @@ squareSketch = startSketchOn('-XZ')
|
||||
|> close()
|
||||
|
||||
circleSketch = startSketchOn(offsetPlane('-XZ', offset = -150))
|
||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
||||
|> circle(center = [0, 100], radius = 50)
|
||||
|
||||
loft([squareSketch, circleSketch])
|
||||
```
|
||||
@ -103,7 +106,7 @@ loft([squareSketch, circleSketch])
|
||||
// A circle on the XY plane
|
||||
startSketchOn("XY")
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> circle({ radius = 10, center = [0, 0] }, %)
|
||||
|> circle(radius = 10, center = [0, 0])
|
||||
|
||||
// Triangle on the plane 4 units above
|
||||
startSketchOn(offsetPlane("XY", offset = 4))
|
||||
|
@ -9,7 +9,14 @@ Repeat a 2-dimensional sketch some number of times along a partial or
|
||||
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
|
||||
|
||||
```js
|
||||
patternCircular2d(sketchSet: SketchSet, instances: integer, center: [number], arcDegrees: number, rotateDuplicates: bool, useOriginal?: bool) -> [Sketch]
|
||||
patternCircular2d(
|
||||
sketchSet: SketchSet,
|
||||
instances: integer,
|
||||
center: [number],
|
||||
arcDegrees: number,
|
||||
rotateDuplicates: bool,
|
||||
useOriginal?: bool,
|
||||
) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,15 @@ Repeat a 3-dimensional solid some number of times along a partial or
|
||||
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
|
||||
|
||||
```js
|
||||
patternCircular3d(solidSet: SolidSet, instances: integer, axis: [number], center: [number], arcDegrees: number, rotateDuplicates: bool, useOriginal?: bool) -> [Solid]
|
||||
patternCircular3d(
|
||||
solidSet: SolidSet,
|
||||
instances: integer,
|
||||
axis: [number],
|
||||
center: [number],
|
||||
arcDegrees: number,
|
||||
rotateDuplicates: bool,
|
||||
useOriginal?: bool,
|
||||
) -> [Solid]
|
||||
```
|
||||
|
||||
|
||||
@ -34,7 +42,7 @@ patternCircular3d(solidSet: SolidSet, instances: integer, axis: [number], center
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
||||
|> circle(center = [0, 0], radius = 1)
|
||||
|
||||
example = extrude(exampleSketch, length = -5)
|
||||
|> patternCircular3d(
|
||||
|
@ -9,7 +9,13 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount
|
||||
of distance between each repetition, some specified number of times.
|
||||
|
||||
```js
|
||||
patternLinear2d(sketchSet: SketchSet, instances: integer, distance: number, axis: [number], useOriginal?: bool) -> [Sketch]
|
||||
patternLinear2d(
|
||||
sketchSet: SketchSet,
|
||||
instances: integer,
|
||||
distance: number,
|
||||
axis: [number],
|
||||
useOriginal?: bool,
|
||||
) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
@ -32,7 +38,7 @@ patternLinear2d(sketchSet: SketchSet, instances: integer, distance: number, axis
|
||||
|
||||
```js
|
||||
exampleSketch = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
||||
|> circle(center = [0, 0], radius = 1)
|
||||
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4)
|
||||
|
||||
example = extrude(exampleSketch, length = 1)
|
||||
|
@ -11,7 +11,13 @@ of distance between each repetition, some specified number of times.
|
||||
///
|
||||
|
||||
```js
|
||||
patternLinear3d(solidSet: SolidSet, instances: integer, distance: number, axis: [number], useOriginal?: bool) -> [Solid]
|
||||
patternLinear3d(
|
||||
solidSet: SolidSet,
|
||||
instances: integer,
|
||||
distance: number,
|
||||
axis: [number],
|
||||
useOriginal?: bool,
|
||||
) -> [Solid]
|
||||
```
|
||||
|
||||
|
||||
@ -58,17 +64,11 @@ case = startSketchOn('XY')
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [-size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
thing2 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
// We pass in the "case" here since we want to pattern the whole sketch.
|
||||
@ -95,10 +95,7 @@ case = startSketchOn('XY')
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [-size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
// We pass in `thing1` here with `useOriginal` since we want to pattern just this object on the face.
|
||||
|
@ -35,7 +35,12 @@ The transform function returns a transform object. All properties of the object
|
||||
- `rotation.origin` (either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local")
|
||||
|
||||
```js
|
||||
patternTransform(solidSet: SolidSet, instances: integer, transform: FunctionSource, useOriginal?: bool) -> [Solid]
|
||||
patternTransform(
|
||||
solidSet: SolidSet,
|
||||
instances: integer,
|
||||
transform: FunctionSource,
|
||||
useOriginal?: bool,
|
||||
) -> [Solid]
|
||||
```
|
||||
|
||||
|
||||
@ -63,7 +68,7 @@ fn transform(id) {
|
||||
|
||||
// Sketch 4 cylinders.
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> extrude(length = 5)
|
||||
|> patternTransform(instances = 4, transform = transform)
|
||||
```
|
||||
@ -79,7 +84,7 @@ fn transform(id) {
|
||||
}
|
||||
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> extrude(length = 5)
|
||||
|> patternTransform(instances = 4, transform = transform)
|
||||
```
|
||||
@ -179,7 +184,7 @@ fn transform(replicaId) {
|
||||
fn layer() {
|
||||
return startSketchOn("XY")
|
||||
// or some other plane idk
|
||||
|> circle({ center = [0, 0], radius = 1 }, %, $tag1)
|
||||
|> circle(center = [0, 0], radius = 1, tag = $tag1)
|
||||
|> extrude(length = h)
|
||||
}
|
||||
// The vase is 100 layers tall.
|
||||
|
@ -9,7 +9,12 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
|
||||
|
||||
|
||||
```js
|
||||
patternTransform2d(sketchSet: SketchSet, instances: integer, transform: FunctionSource, useOriginal?: bool) -> [Sketch]
|
||||
patternTransform2d(
|
||||
sketchSet: SketchSet,
|
||||
instances: integer,
|
||||
transform: FunctionSource,
|
||||
useOriginal?: bool,
|
||||
) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
@ -37,7 +42,7 @@ fn transform(id) {
|
||||
|
||||
// Sketch 4 circles.
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> patternTransform2d(instances = 4, transform = transform)
|
||||
```
|
||||
|
||||
|
@ -31,10 +31,7 @@ pi() -> number
|
||||
circumference = 70
|
||||
|
||||
exampleSketch = startSketchOn("XZ")
|
||||
|> circle({
|
||||
center = [0, 0],
|
||||
radius = circumference / (2 * pi())
|
||||
}, %)
|
||||
|> circle(center = [0, 0], radius = circumference / (2 * pi()))
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
```
|
||||
|
@ -9,7 +9,11 @@ Create a regular polygon with the specified number of sides that is either inscr
|
||||
|
||||
|
||||
```js
|
||||
polygon(data: PolygonData, sketchSurfaceOrGroup: SketchOrSurface, tag?: TagDeclarator) -> Sketch
|
||||
polygon(
|
||||
data: PolygonData,
|
||||
sketchSurfaceOrGroup: SketchOrSurface,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@ Compute the number to a power.
|
||||
|
||||
|
||||
```js
|
||||
pow(num: number, pow: number) -> number
|
||||
pow(
|
||||
num: number,
|
||||
pow: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -9,7 +9,10 @@ Append an element to the end of an array.
|
||||
Returns a new array with the element appended.
|
||||
|
||||
```js
|
||||
push(array: [KclValue], elem: KclValue) -> KclValue
|
||||
push(
|
||||
array: [KclValue],
|
||||
elem: KclValue,
|
||||
) -> KclValue
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Take a starting value. Then, for each element of an array, calculate the next va
|
||||
using the previous value and the element.
|
||||
|
||||
```js
|
||||
reduce(array: [KclValue], start: KclValue, reduceFn: FunctionSource) -> KclValue
|
||||
reduce(
|
||||
array: [KclValue],
|
||||
start: KclValue,
|
||||
reduceFn: FunctionSource,
|
||||
) -> KclValue
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@ Compute the remainder after dividing `num` by `div`.
|
||||
If `num` is negative, the result will be too.
|
||||
|
||||
```js
|
||||
rem(num: number, divisor: number) -> number
|
||||
rem(
|
||||
num: number,
|
||||
divisor: number,
|
||||
) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
@ -11,7 +11,10 @@ This, like extrude, is able to create a 3-dimensional solid from a 2-dimensional
|
||||
Revolve occurs around a local sketch axis rather than a global axis.
|
||||
|
||||
```js
|
||||
revolve(data: RevolveData, sketch: Sketch) -> Solid
|
||||
revolve(
|
||||
data: RevolveData,
|
||||
sketch: Sketch,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -48,7 +51,7 @@ part001 = startSketchOn('XY')
|
||||
```js
|
||||
// A donut shape.
|
||||
sketch001 = startSketchOn('XY')
|
||||
|> circle({ center = [15, 0], radius = 5 }, %)
|
||||
|> circle(center = [15, 0], radius = 5)
|
||||
|> revolve({ angle = 360, axis = 'y' }, %)
|
||||
```
|
||||
|
||||
@ -103,7 +106,7 @@ box = startSketchOn('XY')
|
||||
|> extrude(length = 20)
|
||||
|
||||
sketch001 = startSketchOn(box, "END")
|
||||
|> circle({ center = [10, 10], radius = 4 }, %)
|
||||
|> circle(center = [10, 10], radius = 4)
|
||||
|> revolve({ angle = -90, axis = 'y' }, %)
|
||||
```
|
||||
|
||||
@ -119,7 +122,7 @@ box = startSketchOn('XY')
|
||||
|> extrude(length = 20)
|
||||
|
||||
sketch001 = startSketchOn(box, "END")
|
||||
|> circle({ center = [10, 10], radius = 4 }, %)
|
||||
|> circle(center = [10, 10], radius = 4)
|
||||
|> revolve({
|
||||
angle = 90,
|
||||
axis = getOppositeEdge(revolveAxis)
|
||||
@ -138,7 +141,7 @@ box = startSketchOn('XY')
|
||||
|> extrude(length = 20)
|
||||
|
||||
sketch001 = startSketchOn(box, "END")
|
||||
|> circle({ center = [10, 10], radius = 4 }, %)
|
||||
|> circle(center = [10, 10], radius = 4)
|
||||
|> revolve({
|
||||
angle = 90,
|
||||
axis = getOppositeEdge(revolveAxis),
|
||||
|
@ -23,7 +23,15 @@ So, in the context of a 3D model:
|
||||
When rotating a part around an axis, you specify the axis of rotation and the angle of rotation.
|
||||
|
||||
```js
|
||||
rotate(solid: Solid, roll?: number, pitch?: number, yaw?: number, axis?: [number], angle?: number, global?: bool) -> Solid
|
||||
rotate(
|
||||
solid: Solid,
|
||||
roll?: number,
|
||||
pitch?: number,
|
||||
yaw?: number,
|
||||
axis?: [number],
|
||||
angle?: number,
|
||||
global?: bool,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -61,10 +69,10 @@ sweepPath = startSketchOn('XZ')
|
||||
|
||||
// Create a hole for the pipe.
|
||||
pipeHole = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 1.5)
|
||||
|
||||
sweepSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> hole(pipeHole, %)
|
||||
|> sweep(path = sweepPath)
|
||||
|> rotate(roll = 10, pitch = 10, yaw = 90)
|
||||
@ -87,10 +95,10 @@ sweepPath = startSketchOn('XZ')
|
||||
|
||||
// Create a hole for the pipe.
|
||||
pipeHole = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 1.5)
|
||||
|
||||
sweepSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> hole(pipeHole, %)
|
||||
|> sweep(path = sweepPath)
|
||||
|> rotate(axis = [0, 0, 1.0], angle = 90)
|
||||
|
@ -11,7 +11,11 @@ By default the transform is applied in local sketch axis, therefore the origin w
|
||||
If you want to apply the transform in global space, set `global` to `true`. The origin of the model will move. If the model is not centered on origin and you scale globally it will look like the model moves and gets bigger at the same time. Say you have a square `(1,1) - (1,2) - (2,2) - (2,1)` and you scale by 2 globally it will become `(2,2) - (2,4)`...etc so the origin has moved from `(1.5, 1.5)` to `(2,2)`.
|
||||
|
||||
```js
|
||||
scale(solid: Solid, scale: [number], global?: bool) -> Solid
|
||||
scale(
|
||||
solid: Solid,
|
||||
scale: [number],
|
||||
global?: bool,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -45,10 +49,10 @@ sweepPath = startSketchOn('XZ')
|
||||
|
||||
// Create a hole for the pipe.
|
||||
pipeHole = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 1.5)
|
||||
|
||||
sweepSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> hole(pipeHole, %)
|
||||
|> sweep(path = sweepPath)
|
||||
|> scale(scale = [1.0, 1.0, 2.5])
|
||||
|
@ -40,10 +40,7 @@ cube = startSketchOn('XY')
|
||||
fn cylinder(radius, tag) {
|
||||
return startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> circle({
|
||||
radius = radius,
|
||||
center = segEnd(tag)
|
||||
}, %)
|
||||
|> circle(radius = radius, center = segEnd(tag))
|
||||
|> extrude(length = radius)
|
||||
}
|
||||
|
||||
|
@ -40,10 +40,7 @@ cube = startSketchOn('XY')
|
||||
fn cylinder(radius, tag) {
|
||||
return startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> circle({
|
||||
radius = radius,
|
||||
center = segStart(tag)
|
||||
}, %)
|
||||
|> circle(radius = radius, center = segStart(tag))
|
||||
|> extrude(length = radius)
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,11 @@ Remove volume from a 3-dimensional shape such that a wall of the
|
||||
provided thickness remains, taking volume starting at the provided face, leaving it open in that direction.
|
||||
|
||||
```js
|
||||
shell(solidSet: SolidSet, thickness: number, faces: [FaceTag]) -> SolidSet
|
||||
shell(
|
||||
solidSet: SolidSet,
|
||||
thickness: number,
|
||||
faces: [FaceTag],
|
||||
) -> SolidSet
|
||||
```
|
||||
|
||||
|
||||
@ -104,17 +108,11 @@ case = startSketchOn('-XZ')
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [-size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
thing2 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
// We put "case" in the shell function to shell the entire object.
|
||||
@ -135,17 +133,11 @@ case = startSketchOn('XY')
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [-size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
thing2 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
// We put "thing1" in the shell function to shell the end face of the object.
|
||||
@ -169,17 +161,11 @@ case = startSketchOn('XY')
|
||||
|> extrude(length = 65)
|
||||
|
||||
thing1 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [-size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [-size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
thing2 = startSketchOn(case, 'end')
|
||||
|> circle({
|
||||
center = [size / 2, -size / 2],
|
||||
radius = 25
|
||||
}, %)
|
||||
|> circle(center = [size / 2, -size / 2], radius = 25)
|
||||
|> extrude(length = 50)
|
||||
|
||||
// We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
||||
|
@ -9,7 +9,11 @@ Start a new profile at a given point.
|
||||
|
||||
|
||||
```js
|
||||
startProfileAt(to: [number], sketchSurface: SketchSurface, tag?: TagDeclarator) -> Sketch
|
||||
startProfileAt(
|
||||
to: [number],
|
||||
sketchSurface: SketchSurface,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -17,7 +17,10 @@ This is important to understand because if you were to then sketch on the result
|
||||
The point is if you want to export the result of a sketch on a face, you only need to export the final Solid that was created from the sketch on the face, since it will include all the parent faces and Solids.
|
||||
|
||||
```js
|
||||
startSketchOn(data: SketchData, tag?: FaceTag) -> SketchSurface
|
||||
startSketchOn(
|
||||
data: SketchData,
|
||||
tag?: FaceTag,
|
||||
) -> SketchSurface
|
||||
```
|
||||
|
||||
|
||||
|
5063
docs/kcl/std.json
5063
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,12 @@ Extrude a sketch along a path.
|
||||
This, like extrude, is able to create a 3-dimensional solid from a 2-dimensional sketch. However, unlike extrude, this creates a solid by using the extent of the sketch as its path. This is useful for creating more complex shapes that can't be created with a simple extrusion.
|
||||
|
||||
```js
|
||||
sweep(sketch: Sketch, path: SweepPath, sectional?: bool, tolerance?: number) -> Solid
|
||||
sweep(
|
||||
sketch: Sketch,
|
||||
path: SweepPath,
|
||||
sectional?: bool,
|
||||
tolerance?: number,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -44,10 +49,10 @@ sweepPath = startSketchOn('XZ')
|
||||
|
||||
// Create a hole for the pipe.
|
||||
pipeHole = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 1.5)
|
||||
|
||||
sweepSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> hole(pipeHole, %)
|
||||
|> sweep(path = sweepPath)
|
||||
```
|
||||
@ -70,7 +75,7 @@ helixPath = helix(
|
||||
|
||||
// Create a spring by sweeping around the helix path.
|
||||
springSketch = startSketchOn('YZ')
|
||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
||||
|> circle(center = [0, 0], radius = 1)
|
||||
|> sweep(path = helixPath)
|
||||
```
|
||||
|
||||
|
@ -91,7 +91,7 @@ bottom = startSketchOn("XY")
|
||||
|
||||
```js
|
||||
circSketch = startSketchOn("XY")
|
||||
|> circle({ center = [0, 0], radius = 3 }, %, $circ)
|
||||
|> circle(center = [0, 0], radius = 3, tag = $circ)
|
||||
|
||||
triangleSketch = startSketchOn("XY")
|
||||
|> startProfileAt([-5, 0], %)
|
||||
|
@ -9,7 +9,11 @@ Draw a curved line segment along part of an imaginary circle.
|
||||
The arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle.
|
||||
|
||||
```js
|
||||
tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
tangentialArc(
|
||||
data: TangentialArcData,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Starting at the current sketch's origin, draw a curved line segment along
|
||||
some part of an imaginary circle until it reaches the desired (x, y) coordinates.
|
||||
|
||||
```js
|
||||
tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
tangentialArcTo(
|
||||
to: [number],
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Starting at the current sketch's origin, draw a curved line segment along
|
||||
some part of an imaginary circle until it reaches a point the given (x, y) distance away.
|
||||
|
||||
```js
|
||||
tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
tangentialArcToRelative(
|
||||
delta: [number],
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Move a solid.
|
||||
|
||||
|
||||
```js
|
||||
translate(solid: Solid, translate: [number], global?: bool) -> Solid
|
||||
translate(
|
||||
solid: Solid,
|
||||
translate: [number],
|
||||
global?: bool,
|
||||
) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -43,10 +47,10 @@ sweepPath = startSketchOn('XZ')
|
||||
|
||||
// Create a hole for the pipe.
|
||||
pipeHole = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 1.5 }, %)
|
||||
|> circle(center = [0, 0], radius = 1.5)
|
||||
|
||||
sweepSketch = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = 2 }, %)
|
||||
|> circle(center = [0, 0], radius = 2)
|
||||
|> hole(pipeHole, %)
|
||||
|> sweep(path = sweepPath)
|
||||
|> translate(translate = [1.0, 1.0, 2.5])
|
||||
|
@ -9,7 +9,11 @@ Draw a line relative to the current origin to a specified distance away
|
||||
from the current position along the 'x' axis.
|
||||
|
||||
```js
|
||||
xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
xLine(
|
||||
length: number,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Draw a line parallel to the X axis, that ends at the given X.
|
||||
E.g. if the previous line ended at (1, 1), then xLineTo(4) draws a line from (1, 1) to (4, 1)
|
||||
|
||||
```js
|
||||
xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
xLineTo(
|
||||
to: number,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Draw a line relative to the current origin to a specified distance away
|
||||
from the current position along the 'y' axis.
|
||||
|
||||
```js
|
||||
yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
yLine(
|
||||
length: number,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -9,7 +9,11 @@ Draw a line parallel to the Y axis, that ends at the given Y.
|
||||
E.g. if the previous line ended at (1, 1), then yLineTo(4) draws a line from (1, 1) to (1, 4)
|
||||
|
||||
```js
|
||||
yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
yLineTo(
|
||||
to: number,
|
||||
sketch: Sketch,
|
||||
tag?: TagDeclarator,
|
||||
) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { HomePageFixture } from './fixtures/homePageFixture'
|
||||
import { getUtils } from './test-utils'
|
||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { SceneFixture } from './fixtures/sceneFixture'
|
||||
|
||||
test.describe(
|
||||
'Can create sketches on all planes and their back sides',
|
||||
@ -11,16 +12,17 @@ test.describe(
|
||||
const sketchOnPlaneAndBackSideTest = async (
|
||||
page: Page,
|
||||
homePage: HomePageFixture,
|
||||
scene: SceneFixture,
|
||||
plane: string,
|
||||
clickCoords: { x: number; y: number }
|
||||
) => {
|
||||
const u = await getUtils(page)
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
// FIXME: Cannot use scene.waitForExecutionDone() since there is no KCL code
|
||||
await page.waitForTimeout(10000)
|
||||
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
||||
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
||||
|
||||
await u.openDebugPanel()
|
||||
|
||||
const coord =
|
||||
@ -43,7 +45,7 @@ test.describe(
|
||||
},
|
||||
}
|
||||
|
||||
const code = `sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.9, -1.22], sketch001)`
|
||||
const code = `sketch001 = startSketchOn('${plane}')profile001 = startProfileAt([0.91, -1.22], sketch001)`
|
||||
|
||||
await u.openDebugPanel()
|
||||
|
||||
@ -56,17 +58,14 @@ test.describe(
|
||||
|
||||
await u.closeDebugPanel()
|
||||
await page.mouse.click(clickCoords.x, clickCoords.y)
|
||||
await page.waitForTimeout(300) // wait for animation
|
||||
await page.waitForTimeout(600) // wait for animation
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'line Line', exact: true })
|
||||
).toBeVisible()
|
||||
|
||||
// draw a line
|
||||
const startXPx = 600
|
||||
|
||||
await u.closeDebugPanel()
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await page.mouse.click(707, 393)
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||
|
||||
@ -81,49 +80,50 @@ test.describe(
|
||||
await u.clearCommandLogs()
|
||||
await u.removeCurrentCode()
|
||||
}
|
||||
test('XY', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(
|
||||
page,
|
||||
homePage,
|
||||
'XY',
|
||||
{ x: 600, y: 388 } // red plane
|
||||
// { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too.
|
||||
)
|
||||
})
|
||||
|
||||
test('YZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', {
|
||||
x: 700,
|
||||
y: 250,
|
||||
}) // green plane
|
||||
})
|
||||
const planeConfigs = [
|
||||
{
|
||||
plane: 'XY',
|
||||
coords: { x: 600, y: 388 },
|
||||
description: 'red plane',
|
||||
},
|
||||
{
|
||||
plane: 'YZ',
|
||||
coords: { x: 700, y: 250 },
|
||||
description: 'green plane',
|
||||
},
|
||||
{
|
||||
plane: 'XZ',
|
||||
coords: { x: 684, y: 427 },
|
||||
description: 'blue plane',
|
||||
},
|
||||
{
|
||||
plane: '-XY',
|
||||
coords: { x: 600, y: 118 },
|
||||
description: 'back of red plane',
|
||||
},
|
||||
{
|
||||
plane: '-YZ',
|
||||
coords: { x: 700, y: 219 },
|
||||
description: 'back of green plane',
|
||||
},
|
||||
{
|
||||
plane: '-XZ',
|
||||
coords: { x: 700, y: 80 },
|
||||
description: 'back of blue plane',
|
||||
},
|
||||
]
|
||||
|
||||
test('XZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-XZ', {
|
||||
x: 700,
|
||||
y: 80,
|
||||
}) // blue plane
|
||||
})
|
||||
|
||||
test('-XY', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', {
|
||||
x: 600,
|
||||
y: 118,
|
||||
}) // back of red plane
|
||||
})
|
||||
|
||||
test('-YZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', {
|
||||
x: 700,
|
||||
y: 219,
|
||||
}) // back of green plan
|
||||
})
|
||||
|
||||
test('-XZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, 'XZ', {
|
||||
x: 700,
|
||||
y: 427,
|
||||
}) // back of blue plane
|
||||
})
|
||||
for (const config of planeConfigs) {
|
||||
test(config.plane, async ({ page, homePage, scene }) => {
|
||||
await sketchOnPlaneAndBackSideTest(
|
||||
page,
|
||||
homePage,
|
||||
scene,
|
||||
config.plane,
|
||||
config.coords
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -125,6 +125,12 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
await expect(cmdSearchBar).toBeFocused()
|
||||
|
||||
await test.step(`Pressing backspace in the command selection step does not dismiss`, async () => {
|
||||
await page.keyboard.press('Backspace')
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
await expect(cmdSearchBar).toBeFocused()
|
||||
})
|
||||
|
||||
// Try typing in the command bar
|
||||
await cmdSearchBar.fill(commandName)
|
||||
await expect(commandOption).toBeVisible()
|
||||
|
@ -689,7 +689,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
||||
|> circle({ center: [0, 0], radius: dia/2 }, %)
|
||||
|> circle(center: [0, 0], radius: dia/2)
|
||||
|> hole(squareHole(length, width, height), %)
|
||||
|> extrude(length = height)`)
|
||||
|
||||
|
@ -50,13 +50,13 @@ const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn('XZ')
|
||||
|> close(%)
|
||||
extrude001 = extrude(sketch001, length = 10)
|
||||
sketch002 = startSketchOn(extrude001, rectangleSegmentB001)
|
||||
|> circle({
|
||||
|> circle(
|
||||
center = [-1, 2],
|
||||
radius = .5
|
||||
}, %)
|
||||
)
|
||||
plane001 = offsetPlane('XZ', offset = -5)
|
||||
sketch003 = startSketchOn(plane001)
|
||||
|> circle({ center = [0, 0], radius = 5 }, %)
|
||||
|> circle(center = [0, 0], radius = 5)
|
||||
`
|
||||
|
||||
test.describe('Feature Tree pane', () => {
|
||||
@ -201,7 +201,7 @@ test.describe('Feature Tree pane', () => {
|
||||
await toolbar.exitSketchBtn.click()
|
||||
})
|
||||
|
||||
await test.step('On an offset plane should *not* work', async () => {
|
||||
await test.step('On an offset plane should work', async () => {
|
||||
// Tooltip is getting in the way of clicking, so I'm first closing the pane
|
||||
await toolbar.closeFeatureTreePane()
|
||||
await (await toolbar.getFeatureTreeOperation('Sketch', 2)).dblclick()
|
||||
@ -212,13 +212,7 @@ test.describe('Feature Tree pane', () => {
|
||||
})
|
||||
await expect(
|
||||
toolbar.exitSketchBtn,
|
||||
'We should not be in sketch mode now'
|
||||
).not.toBeVisible()
|
||||
await expect(
|
||||
page.getByText(
|
||||
'Editing sketches on faces or offset planes through the feature tree is not yet supported'
|
||||
),
|
||||
'We should see a toast message about this'
|
||||
'We should be in sketch mode now'
|
||||
).toBeVisible()
|
||||
})
|
||||
}
|
||||
@ -234,11 +228,11 @@ test.describe('Feature Tree pane', () => {
|
||||
}) => {
|
||||
const initialInput = '23'
|
||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 5 }, %)
|
||||
|> circle(center = [0, 0], radius = 5)
|
||||
renamedExtrude = extrude(sketch001, length = ${initialInput})`
|
||||
const newConstantName = 'distance001'
|
||||
const expectedCode = `sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 5 }, %)
|
||||
|> circle(center = [0, 0], radius = 5)
|
||||
${newConstantName} = 23
|
||||
renamedExtrude = extrude(sketch001, length = ${newConstantName})`
|
||||
|
||||
|
@ -107,7 +107,7 @@ test.describe('when using the file tree to', () => {
|
||||
|
||||
// File the main.kcl with contents
|
||||
const kclCube = await fsp.readFile(
|
||||
'src/wasm-lib/tests/executor/inputs/cube.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/cube.kcl',
|
||||
'utf-8'
|
||||
)
|
||||
await pasteCodeInEditor(kclCube)
|
||||
@ -245,7 +245,7 @@ test.describe('when using the file tree to', () => {
|
||||
await createProject({ name: 'project-000', page })
|
||||
// File the main.kcl with contents
|
||||
const kclCube = await fsp.readFile(
|
||||
'src/wasm-lib/tests/executor/inputs/cube.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/cube.kcl',
|
||||
'utf-8'
|
||||
)
|
||||
await pasteCodeInEditor(kclCube)
|
||||
@ -283,7 +283,7 @@ test.describe('when using the file tree to', () => {
|
||||
|
||||
// Create a small file
|
||||
const kclCube = await fsp.readFile(
|
||||
'src/wasm-lib/tests/executor/inputs/cube.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/cube.kcl',
|
||||
'utf-8'
|
||||
)
|
||||
// pasted into main.kcl
|
||||
@ -297,7 +297,7 @@ test.describe('when using the file tree to', () => {
|
||||
await expect(legoFile).toBeVisible({ timeout: 60_000 })
|
||||
await legoFile.click()
|
||||
const kclLego = await fsp.readFile(
|
||||
'src/wasm-lib/tests/executor/inputs/lego.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/lego.kcl',
|
||||
'utf-8'
|
||||
)
|
||||
await pasteCodeInEditor(kclLego)
|
||||
|
@ -47,6 +47,8 @@ export class CmdBarFixture {
|
||||
private _serialiseCmdBar = async (): Promise<CmdBarSerialised> => {
|
||||
if (!(await this.page.getByTestId('command-bar-wrapper').isVisible())) {
|
||||
return { stage: 'commandBarClosed' }
|
||||
} else if (await this.page.getByTestId('cmd-bar-search').isVisible()) {
|
||||
return { stage: 'pickCommand' }
|
||||
}
|
||||
const reviewForm = this.page.locator('#review-form')
|
||||
const getHeaderArgs = async () => {
|
||||
|
@ -45,7 +45,7 @@ export class AuthenticatedApp {
|
||||
}
|
||||
getInputFile = (fileName: string) => {
|
||||
return fsp.readFile(
|
||||
join('src', 'wasm-lib', 'tests', 'executor', 'inputs', fileName),
|
||||
join('rust', 'kcl-lib', 'e2e', 'executor', 'inputs', fileName),
|
||||
'utf-8'
|
||||
)
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import type { Page, Locator } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
import { expect } from '../zoo-test'
|
||||
import { isArray, uuidv4 } from 'lib/utils'
|
||||
import { CmdBarFixture } from './cmdBarFixture'
|
||||
import {
|
||||
closeDebugPanel,
|
||||
doAndWaitForImageDiff,
|
||||
getPixelRGBs,
|
||||
openAndClearDebugPanel,
|
||||
sendCustomCmd,
|
||||
getUtils,
|
||||
} from '../test-utils'
|
||||
|
||||
type MouseParams = {
|
||||
@ -40,9 +42,13 @@ export class SceneFixture {
|
||||
public page: Page
|
||||
public streamWrapper!: Locator
|
||||
public loadingIndicator!: Locator
|
||||
public networkToggleConnected!: Locator
|
||||
public startEditSketchBtn!: Locator
|
||||
|
||||
get exeIndicator() {
|
||||
return this.page.getByTestId('model-state-indicator-execution-done')
|
||||
return this.page
|
||||
.getByTestId('model-state-indicator-execution-done')
|
||||
.or(this.page.getByTestId('model-state-indicator-receive-reliable'))
|
||||
}
|
||||
|
||||
constructor(page: Page) {
|
||||
@ -70,7 +76,11 @@ export class SceneFixture {
|
||||
this.page = page
|
||||
|
||||
this.streamWrapper = page.getByTestId('stream')
|
||||
this.networkToggleConnected = page.getByTestId('network-toggle-ok')
|
||||
this.loadingIndicator = this.streamWrapper.getByTestId('loading')
|
||||
this.startEditSketchBtn = page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.or(page.getByRole('button', { name: 'Edit Sketch' }))
|
||||
}
|
||||
|
||||
makeMouseHelpers = (
|
||||
@ -229,6 +239,27 @@ export class SceneFixture {
|
||||
await expect(this.exeIndicator).toBeVisible({ timeout: 30000 })
|
||||
}
|
||||
|
||||
connectionEstablished = async () => {
|
||||
const timeout = 30000
|
||||
await expect(this.networkToggleConnected).toBeVisible({ timeout })
|
||||
}
|
||||
|
||||
settled = async (cmdBar: CmdBarFixture) => {
|
||||
const u = await getUtils(this.page)
|
||||
|
||||
await cmdBar.openCmdBar()
|
||||
await cmdBar.chooseCommand('Settings · app · show debug panel')
|
||||
await cmdBar.selectOption({ name: 'on' }).click()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
|
||||
await this.waitForExecutionDone()
|
||||
await expect(this.startEditSketchBtn).not.toBeDisabled()
|
||||
await expect(this.startEditSketchBtn).toBeVisible()
|
||||
}
|
||||
|
||||
expectPixelColor = async (
|
||||
colour: [number, number, number] | [number, number, number][],
|
||||
coords: { x: number; y: number },
|
||||
|
@ -61,7 +61,7 @@ export class ToolbarFixture {
|
||||
this.rectangleBtn = page.getByTestId('corner-rectangle')
|
||||
this.lengthConstraintBtn = page.getByTestId('constraint-length')
|
||||
this.exitSketchBtn = page.getByTestId('sketch-exit')
|
||||
this.editSketchBtn = page.getByText('Edit Sketch')
|
||||
this.editSketchBtn = page.locator('[name="Edit Sketch"]')
|
||||
this.fileTreeBtn = page.locator('[id="files-button-holder"]')
|
||||
this.createFileBtn = page.getByTestId('create-file-button')
|
||||
this.treeInputField = page.getByTestId('tree-input-field')
|
||||
|
@ -9,7 +9,7 @@ import { Locator } from '@playwright/test'
|
||||
|
||||
// test file is for testing point an click code gen functionality that's not sketch mode related
|
||||
|
||||
test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
||||
test.describe('Point-and-click tests', () => {
|
||||
test('verify extruding circle works', async ({
|
||||
context,
|
||||
homePage,
|
||||
@ -22,7 +22,7 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
||||
path.resolve(
|
||||
__dirname,
|
||||
'../../',
|
||||
'./src/wasm-lib/tests/executor/inputs/test-circle-extrude.kcl'
|
||||
'./rust/kcl-lib/e2e/executor/inputs/test-circle-extrude.kcl'
|
||||
),
|
||||
'utf-8'
|
||||
)
|
||||
@ -42,27 +42,25 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
||||
|
||||
await test.step('check code model connection works and that button is still enable once circle is selected ', async () => {
|
||||
await moveToCircle()
|
||||
const circleSnippet =
|
||||
'circle({ center = [318.33, 168.1], radius = 182.8 }, %)'
|
||||
const circleSnippet = 'circle(center = [318.33, 168.1], radius = 182.8)'
|
||||
await editor.expectState({
|
||||
activeLines: ["constsketch002=startSketchOn('XZ')"],
|
||||
activeLines: ["sketch002=startSketchOn('XZ')"],
|
||||
highlightedCode: circleSnippet,
|
||||
diagnostics: [],
|
||||
})
|
||||
|
||||
await test.step('check code model connection works and that button is still enable once circle is selected ', async () => {
|
||||
await moveToCircle()
|
||||
const circleSnippet =
|
||||
'circle({ center = [318.33, 168.1], radius = 182.8 }, %)'
|
||||
const circleSnippet = 'circle(center = [318.33, 168.1], radius = 182.8)'
|
||||
await editor.expectState({
|
||||
activeLines: ["constsketch002=startSketchOn('XZ')"],
|
||||
activeLines: ["sketch002=startSketchOn('XZ')"],
|
||||
highlightedCode: circleSnippet,
|
||||
diagnostics: [],
|
||||
})
|
||||
|
||||
await clickCircle()
|
||||
await editor.expectState({
|
||||
activeLines: [circleSnippet.slice(-5)],
|
||||
activeLines: ['|>' + circleSnippet],
|
||||
highlightedCode: circleSnippet,
|
||||
diagnostics: [],
|
||||
})
|
||||
@ -193,7 +191,7 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
|
||||
path.resolve(
|
||||
__dirname,
|
||||
'../../',
|
||||
'./src/wasm-lib/tests/executor/inputs/e2e-can-sketch-on-chamfer.kcl'
|
||||
'./rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer.kcl'
|
||||
),
|
||||
'utf-8'
|
||||
)
|
||||
@ -381,7 +379,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
||||
path.resolve(
|
||||
__dirname,
|
||||
'../../',
|
||||
'./src/wasm-lib/tests/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl'
|
||||
'./rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl'
|
||||
),
|
||||
'utf-8'
|
||||
)
|
||||
@ -581,7 +579,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
||||
const u = await getUtils(page)
|
||||
|
||||
const initialCode = `closedSketch = startSketchOn('XZ')
|
||||
|> circle({ center = [8, 5], radius = 2 }, %)
|
||||
|> circle(center = [8, 5], radius = 2)
|
||||
openSketch = startSketchOn('XY')
|
||||
|> startProfileAt([-5, 0], %)
|
||||
|> line(endAbsolute = [0, 5])
|
||||
@ -633,8 +631,8 @@ openSketch = startSketchOn('XY')
|
||||
await expect(toolbar.startSketchBtn).not.toBeVisible()
|
||||
await expect(toolbar.exitSketchBtn).toBeVisible()
|
||||
await editor.expectState({
|
||||
activeLines: [`|>circle({center=[8,5],radius=2},%)`],
|
||||
highlightedCode: 'circle({center=[8,5],radius=2},%)',
|
||||
activeLines: [`|>circle(center=[8,5],radius=2)`],
|
||||
highlightedCode: 'circle(center=[8,5],radius=2)',
|
||||
diagnostics: [],
|
||||
})
|
||||
})
|
||||
@ -1192,10 +1190,10 @@ openSketch = startSketchOn('XY')
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 30 }, %)
|
||||
|> circle(center = [0, 0], radius = 30)
|
||||
plane001 = offsetPlane('XZ', offset = 50)
|
||||
sketch002 = startSketchOn(plane001)
|
||||
|> circle({ center = [0, 0], radius = 20 }, %)
|
||||
|> circle(center = [0, 0], radius = 20)
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
localStorage.setItem('persistCode', initialCode)
|
||||
@ -1278,10 +1276,10 @@ openSketch = startSketchOn('XY')
|
||||
scene,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 30 }, %)
|
||||
|> circle(center = [0, 0], radius = 30)
|
||||
plane001 = offsetPlane('XZ', offset = 50)
|
||||
sketch002 = startSketchOn(plane001)
|
||||
|> circle({ center = [0, 0], radius = 20 }, %)
|
||||
|> circle(center = [0, 0], radius = 20)
|
||||
loft001 = loft([sketch001, sketch002])
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
@ -1304,7 +1302,7 @@ loft001 = loft([sketch001, sketch002])
|
||||
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
||||
await clickOnSketch1()
|
||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
||||
|> circle({ center = [0, 0], radius = 30 }, %)
|
||||
|> circle(center = [0, 0], radius = 30)
|
||||
`)
|
||||
await page.keyboard.press('Delete')
|
||||
// Check for sketch 1
|
||||
@ -1315,7 +1313,7 @@ loft001 = loft([sketch001, sketch002])
|
||||
await page.waitForTimeout(1000)
|
||||
await clickOnSketch2()
|
||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
||||
|> circle({ center = [0, 0], radius = 20 }, %)
|
||||
|> circle(center = [0, 0], radius = 20)
|
||||
`)
|
||||
await page.keyboard.press('Delete')
|
||||
// Check for plane001
|
||||
@ -1344,10 +1342,10 @@ loft001 = loft([sketch001, sketch002])
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('YZ')
|
||||
|> circle({
|
||||
|> circle(
|
||||
center = [0, 0],
|
||||
radius = 500
|
||||
}, %)
|
||||
)
|
||||
sketch002 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> xLine(-500, %)
|
||||
@ -1438,10 +1436,10 @@ sketch002 = startSketchOn('XZ')
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('YZ')
|
||||
|> circle({
|
||||
|> circle(
|
||||
center = [0, 0],
|
||||
radius = 500
|
||||
}, %)
|
||||
)
|
||||
sketch002 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> xLine(-500, %)
|
||||
@ -2270,7 +2268,7 @@ chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 30 }, %)
|
||||
|> circle(center = [0, 0], radius = 30)
|
||||
extrude001 = extrude(sketch001, length = 30)
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
@ -2445,19 +2443,19 @@ extrude001 = extrude(sketch001, length = 40)
|
||||
|
||||
const shellSketchOnFacesCases = [
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 100 }, %)
|
||||
|> circle(center = [0, 0], radius = 100)
|
||||
|> extrude(length = 100)
|
||||
|
||||
sketch002 = startSketchOn(sketch001, 'END')
|
||||
|> circle({ center = [0, 0], radius = 50 }, %)
|
||||
|> circle(center = [0, 0], radius = 50)
|
||||
|> extrude(length = 50)
|
||||
`,
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [0, 0], radius = 100 }, %)
|
||||
|> circle(center = [0, 0], radius = 100)
|
||||
extrude001 = extrude(sketch001, length = 100)
|
||||
|
||||
sketch002 = startSketchOn(extrude001, 'END')
|
||||
|> circle({ center = [0, 0], radius = 50 }, %)
|
||||
|> circle(center = [0, 0], radius = 50)
|
||||
extrude002 = extrude(sketch002, length = 50)
|
||||
`,
|
||||
]
|
||||
@ -2631,10 +2629,10 @@ profile001 = startProfileAt([-20, 20], sketch001)
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('YZ')
|
||||
|> circle({
|
||||
|> circle(
|
||||
center = [0, 0],
|
||||
radius = 500
|
||||
}, %)
|
||||
)
|
||||
sketch002 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> xLine(-2000, %)
|
||||
@ -2761,10 +2759,10 @@ segAng(rectangleSegmentA001),
|
||||
|> close()
|
||||
extrude001 = extrude(sketch001, length = 50)
|
||||
sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
||||
|> circle({
|
||||
|> circle(
|
||||
center = [-11.34, 10.0],
|
||||
radius = 8.69
|
||||
}, %)
|
||||
)
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
localStorage.setItem('persistCode', initialCode)
|
||||
@ -2811,10 +2809,10 @@ radius = 8.69
|
||||
|> close()
|
||||
extrude001 = extrude(sketch001, length = 5)
|
||||
sketch003 = startSketchOn(extrude001, 'START')
|
||||
|> circle({
|
||||
|> circle(
|
||||
center = [-0.69, 0.56],
|
||||
radius = 0.28
|
||||
}, %)
|
||||
)
|
||||
`
|
||||
|
||||
await context.addInitScript((initialCode) => {
|
||||
@ -2849,10 +2847,11 @@ radius = 8.69
|
||||
cmdBar,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn('XZ')
|
||||
profile001 = circle({
|
||||
profile001 = circle(
|
||||
sketch001,
|
||||
center = [0, 0],
|
||||
radius = 100
|
||||
}, sketch001)
|
||||
)
|
||||
extrude001 = extrude(profile001, length = 100)
|
||||
`
|
||||
await context.addInitScript((initialCode) => {
|
||||
@ -2864,7 +2863,7 @@ extrude001 = extrude(profile001, length = 100)
|
||||
|
||||
// One dumb hardcoded screen pixel value
|
||||
const testPoint = { x: 500, y: 250 }
|
||||
const initialColor: [number, number, number] = [135, 135, 135]
|
||||
const initialColor: [number, number, number] = [123, 123, 123]
|
||||
|
||||
await test.step(`Confirm extrude exists with default appearance`, async () => {
|
||||
await toolbar.closePane('code')
|
||||
@ -2877,23 +2876,41 @@ extrude001 = extrude(profile001, length = 100)
|
||||
shapeColor: [number, number, number]
|
||||
) {
|
||||
await toolbar.openPane('feature-tree')
|
||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
||||
'Extrude',
|
||||
0
|
||||
)
|
||||
await operationButton.click({ button: 'right' })
|
||||
const menuButton = page.getByTestId('context-menu-set-appearance')
|
||||
await menuButton.click()
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Appearance',
|
||||
currentArgKey: 'color',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Color: '',
|
||||
},
|
||||
highlightedHeaderArg: 'color',
|
||||
stage: 'arguments',
|
||||
const enterAppearanceFlow = async (stepName: string) =>
|
||||
test.step(stepName, async () => {
|
||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
||||
'Extrude',
|
||||
0
|
||||
)
|
||||
await operationButton.click({ button: 'right' })
|
||||
const menuButton = page.getByTestId('context-menu-set-appearance')
|
||||
await menuButton.click()
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Appearance',
|
||||
currentArgKey: 'color',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Color: '',
|
||||
},
|
||||
highlightedHeaderArg: 'color',
|
||||
stage: 'arguments',
|
||||
})
|
||||
})
|
||||
|
||||
await enterAppearanceFlow(`Open Set Appearance flow`)
|
||||
|
||||
await test.step(`Validate hidden argument "nodeToEdit" can't be reached with Backspace`, async () => {
|
||||
await page.keyboard.press('Backspace')
|
||||
await cmdBar.expectState({
|
||||
stage: 'pickCommand',
|
||||
})
|
||||
await page.keyboard.press('Escape')
|
||||
await cmdBar.expectState({
|
||||
stage: 'commandBarClosed',
|
||||
})
|
||||
})
|
||||
|
||||
await enterAppearanceFlow(`Restart Appearance flow`)
|
||||
const item = page.getByText(option, { exact: true })
|
||||
await item.click()
|
||||
await cmdBar.expectState({
|
||||
@ -2905,7 +2922,7 @@ extrude001 = extrude(profile001, length = 100)
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
await toolbar.closePane('feature-tree')
|
||||
await scene.expectPixelColor(shapeColor, testPoint, 40)
|
||||
await scene.expectPixelColor(shapeColor, testPoint, 10)
|
||||
await toolbar.openPane('code')
|
||||
if (hex === 'default') {
|
||||
const anyAppearanceDeclaration = `|> appearance(`
|
||||
@ -2931,9 +2948,9 @@ extrude001 = extrude(profile001, length = 100)
|
||||
await setApperanceAndCheck('Purple', '#FF00FF', [180, 0, 180])
|
||||
await setApperanceAndCheck('Yellow', '#FFFF00', [180, 180, 0])
|
||||
await setApperanceAndCheck('Black', '#000000', [0, 0, 0])
|
||||
await setApperanceAndCheck('Dark Grey', '#080808', [10, 10, 10])
|
||||
await setApperanceAndCheck('Light Grey', '#D3D3D3', [190, 190, 190])
|
||||
await setApperanceAndCheck('White', '#FFFFFF', [200, 200, 200])
|
||||
await setApperanceAndCheck('Dark Grey', '#080808', [0x33, 0x33, 0x33])
|
||||
await setApperanceAndCheck('Light Grey', '#D3D3D3', [176, 176, 176])
|
||||
await setApperanceAndCheck('White', '#FFFFFF', [184, 184, 184])
|
||||
await setApperanceAndCheck(
|
||||
'Default (clear appearance)',
|
||||
'default',
|
||||
|
@ -556,7 +556,7 @@ test(
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/router-template-slate/main.kcl`
|
||||
)
|
||||
const _1975 = new Date('1975-01-01T00:01:11')
|
||||
@ -564,7 +564,7 @@ test(
|
||||
|
||||
await fsp.mkdir(`${dir}/bracket`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
||||
`${dir}/bracket/main.kcl`
|
||||
)
|
||||
const _1985 = new Date('1985-01-01T00:02:22')
|
||||
@ -573,7 +573,7 @@ test(
|
||||
await new Promise((r) => setTimeout(r, 1_000))
|
||||
await fsp.mkdir(`${dir}/lego`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/lego.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/lego.kcl',
|
||||
`${dir}/lego/main.kcl`
|
||||
)
|
||||
const _1995 = new Date('1995-01-01T00:03:33')
|
||||
@ -755,7 +755,7 @@ test(
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/router-template-slate/main.kcl`
|
||||
)
|
||||
})
|
||||
@ -785,7 +785,7 @@ test.describe(`Project management commands`, () => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/${projectName}/main.kcl`
|
||||
)
|
||||
})
|
||||
@ -846,7 +846,7 @@ test.describe(`Project management commands`, () => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/${projectName}/main.kcl`
|
||||
)
|
||||
})
|
||||
@ -897,7 +897,7 @@ test.describe(`Project management commands`, () => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/${projectName}/main.kcl`
|
||||
)
|
||||
})
|
||||
@ -952,7 +952,7 @@ test.describe(`Project management commands`, () => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/${projectName}/main.kcl`
|
||||
)
|
||||
})
|
||||
@ -1123,11 +1123,11 @@ test(
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/${projectName}/main.kcl`
|
||||
)
|
||||
await fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
||||
`${dir}/${projectName}/otherThingToClickOn.kcl`
|
||||
)
|
||||
})
|
||||
@ -1540,9 +1540,9 @@ test(
|
||||
})
|
||||
await fsp.copyFile(
|
||||
path.join(
|
||||
'src',
|
||||
'wasm-lib',
|
||||
'tests',
|
||||
'rust',
|
||||
'kcl-lib',
|
||||
'e2e',
|
||||
'executor',
|
||||
'inputs',
|
||||
'router-template-slate.kcl'
|
||||
@ -1552,9 +1552,9 @@ test(
|
||||
await fsp.mkdir(path.join(dir, 'bracket'), { recursive: true })
|
||||
await fsp.copyFile(
|
||||
path.join(
|
||||
'src',
|
||||
'wasm-lib',
|
||||
'tests',
|
||||
'rust',
|
||||
'kcl-lib',
|
||||
'e2e',
|
||||
'executor',
|
||||
'inputs',
|
||||
'focusrite_scarlett_mounting_braket.kcl'
|
||||
@ -1673,11 +1673,11 @@ test(
|
||||
])
|
||||
await Promise.all([
|
||||
fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/router-template-slate.kcl',
|
||||
`${dir}/router-template-slate/main.kcl`
|
||||
),
|
||||
fsp.copyFile(
|
||||
'src/wasm-lib/tests/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
||||
'rust/kcl-lib/e2e/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
||||
`${dir}/bracket/main.kcl`
|
||||
),
|
||||
])
|
||||
@ -1928,7 +1928,7 @@ test(
|
||||
{ tag: '@electron' },
|
||||
async ({ context, page }, testInfo) => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
// src/wasm-lib/tests/executor/inputs/mike_stress_test.kcl
|
||||
// rust/kcl-lib/e2e/executor/inputs/mike_stress_test.kcl
|
||||
const name = 'mike_stress_test'
|
||||
const testDir = path.join(dir, name)
|
||||
await fsp.mkdir(testDir, { recursive: true })
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user