Compare commits

...

17 Commits

Author SHA1 Message Date
51459bb413 turn on insta snapshot for step file output (#5732)
* turn on insta snapshot for step file output

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* use a macro for the kcl-samples

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* Update rust/kcl-directory-test-macro/src/lib.rs

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* control the order

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* engine

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update steps

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-10 15:35:45 -07:00
e00dae11ba Fix cryptic parser error (#5731)
# Problem

Before: "unexpected token |>", highlights the |>

After: "This argument needs a label, but it doesn't have one", highlights the argument with no label

Closes #5724 

# Discussion

I am trying a new approach to the parser: instead of parsing the specific correct thing we need, parse a more general form, then later, narrow it down to specifics and return a nice error if it's wrong. For example, instead of parsing labeled arguments, parse labeled OR unlabeled arguments. Then later check that the only unlabeled arg is the first one, and return a nice error if there's any other. This worked nicely for this PR, hopefully the approach will work for other "cryptic error" issues.
2025-03-10 17:09:54 -05:00
831c7f764a cargo publish was too big (#5699)
* cargo publish too big

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cargo publish too big

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* bunmp again

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-10 14:29:04 -07:00
ec4ad268f7 Fix toolchain file copy to work on all platforms (#5733) 2025-03-10 16:44:44 -04:00
be640ea0bd ci: Fix e2e workflow to install rust toolchain when needed (#5728)
* ci: Fix e2e workflow to install rust toolchain when needed

* Unify conditions

* Pull out condition to variable

* Add echo so that debuggin is easier
2025-03-10 14:53:43 -04:00
f8ceab2233 Fix a recast bug and don't delete the user's code if parsing fails (#5663)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-08 09:33:45 -05:00
aea82e004a KCL: Convert x/y lines to use keyword arguments (#5615)
Previously, `xLine`, `xLineTo`, `yLine` and `yLineTo` used positional arguments. Now:

- `xLineTo` and `yLineTo` have been removed
- `xLine` and `yLine` both use keyword arguments:
  - `length`, optional (i.e. a relative distance along the X or Y axis)
  - `endAbsolute` optional (i.e. an absolute point along the X or Y axis)
  - `tag` optional
- Exactly one of `length` or `endAbsolute` must be given. Not both, not neither.

For example:

```
// Old way
|> xLine(6.04, %)
|> yLineTo(20, %, $base)

// New way
|> xLine(length = 6.04)
|> yLine(endAbsolute = 20, tag = $base)
```

This also improves some of the general-purpose keyword arguments code in modeling app's TS codebase.
2025-03-07 22:07:16 -06:00
bc3a0e3896 more updates for kcl-samples (#5696)
* screenshots and step

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* automations

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add manifest generation

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* small refactor

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update readme

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* write the readme

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes for comments

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* derive-docs tests updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update all the generated artifact commands, since we dont need to clear scene at the start of run so we dont need to recreate all the planes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-07 18:45:33 -08:00
be69039d40 bump kcl crate versions (#5697)
* bump kcl crate versions

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update lock

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-07 18:44:43 -08:00
2c6d69497c Update KCL samples readme (#5677)
update KCL samples readme
2025-03-08 00:15:36 +00:00
18db3783af Fix project settings loading in browser (#5694)
Fixes #5625. #5142 regressed the project settings loading because it
failed to fire off a new `load.project` XState event in the case where
we were loading in the browser. It also may have had a bug with project
settings loading on refresh from the file page, as we were not properly
ensuring that the `settingsActor` was in the `idle` state before sending
our `load.project` event regardless.
2025-03-08 00:14:02 +00:00
b536040feb ci: Fix e2e jobs to pass the status check even when they're not run (#5693)
* ci: Fix e2e jobs to pass the status check even when they're not run
2025-03-08 00:00:57 +00:00
dd45cd4ef9 Don't try to clone a THREE.js group in coredump (#5690)
Fixes #5117 by just grabbing the `userData` off the group, and not
trying to clone the whole class instance which errors.
2025-03-07 19:09:56 +00:00
25cc5581be Factor out a struct for the result of parse_execute (#5629)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-08 08:00:55 +13:00
f7c192b64b Fix type parsing in CodeMirror and highlight them (#5674)
* Add new types and fix capitalization in CodeMirror grammar

* Add syntax highlighting for types
2025-03-07 18:56:29 +00:00
faae169154 Update dependabot config (#5639) 2025-03-07 17:36:54 +00:00
c74b9ba940 Block indexing if host is not app.zoo.dev (#5675)
* block indexing if host is not app.zoo.dev

* fix fmt
2025-03-07 17:23:40 +01:00
620 changed files with 656599 additions and 98168 deletions

349
.github/dependabot.yml vendored
View File

@ -1,52 +1,331 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# DO NOT EDIT THIS FILE. This dependabot file was generated
# by https://github.com/KittyCAD/ciso Changes to this file should be addressed in
# the ciso repository.
version: 2
updates:
- package-ecosystem: 'npm' # See documentation for possible values
directories:
- '/'
- '/packages/codemirror-lang-kcl/'
- '/packages/codemirror-lsp-client/'
- '/rust/kcl-language-server/'
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: cargo
directory: /rust
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- package-ecosystem: 'github-actions' # See documentation for possible values
directory: '/' # Location of package manifests
schedule:
interval: weekly
day: monday
reviewers:
- adamchalmers
- jessfraz
- package-ecosystem: 'cargo' # See documentation for possible values
directory: '/rust/' # Location of package manifests
schedule:
interval: weekly
day: monday
reviewers:
- adamchalmers
- jessfraz
groups:
serde-dependencies:
patterns:
- "serde*"
wasm-bindgen-deps:
patterns:
- "wasm-bindgen*"
- package-ecosystem: "pip"
directories:
- "/public/kcl-samples/"
- "/rust/kcl-python-bindings/"
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /rust/kcl-language-server
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /packages/codemirror-lang-kcl
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /packages/codemirror-lsp-client
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /.github/actions/github-release
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: pip
directory: /public/kcl-samples
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: pip
directory: /rust/kcl-python-bindings
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: docker
directory: /.github/actions/github-release
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch

View File

@ -16,15 +16,21 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache wasm
uses: Swatinem/rust-cache@v2
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
workspaces: './rust'
cache: false # Configured below.
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
with:
tool: wasm-pack
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: rust
- name: build wasm
run: yarn build:wasm

View File

@ -33,18 +33,25 @@ jobs:
- run: yarn install
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
workspaces: './rust'
cache: false # Configured below.
# TODO: see if we can fetch from main instead if no diff at rust
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
with:
tool: wasm-pack
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: rust
- name: Run build:wasm
run: "yarn build:wasm"

View File

@ -22,7 +22,7 @@ jobs:
- name: Use correct Rust toolchain
shell: bash
run: |
cp --update=none rust/rust-toolchain.toml ./ || true
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:

View File

@ -29,7 +29,7 @@ jobs:
- name: Use correct Rust toolchain
shell: bash
run: |
cp --update=none rust/rust-toolchain.toml ./ || true
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:

View File

@ -31,7 +31,7 @@ jobs:
- name: Use correct Rust toolchain
shell: bash
run: |
cp --update=none rust/rust-toolchain.toml ./ || true
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:

View File

@ -29,7 +29,7 @@ jobs:
- name: Use correct Rust toolchain
shell: bash
run: |
cp --update=none rust/rust-toolchain.toml ./ || true
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:

View File

@ -18,10 +18,11 @@ permissions:
jobs:
path-changes:
conditions:
runs-on: ubuntu-latest
outputs:
significant: ${{ steps.path-changes.outputs.significant }}
should-run: ${{ steps.should-run.outputs.should-run }}
steps:
- uses: actions/checkout@v4
@ -47,10 +48,25 @@ jobs:
else
echo "significant=false" >> $GITHUB_OUTPUT
fi
- name: Display path changes
- name: Should run
id: should-run
shell: bash
run: |
set -euo pipefail
# We should run when this is a scheduled run or if there are
# significant changes in the diff.
if [[ ${{ github.event_name }} == 'schedule' || ${{ steps.path-changes.outputs.significant }} == 'true' ]]; then
echo "should-run=true" >> $GITHUB_OUTPUT
else
echo "should-run=false" >> $GITHUB_OUTPUT
fi
- name: Display conditions
shell: bash
run: |
# For debugging purposes.
set -euo pipefail
echo "significant: ${{ steps.path-changes.outputs.significant }}"
echo "should-run: ${{ steps.should-run.outputs.should-run }}"
electron:
timeout-minutes: 60
@ -64,8 +80,7 @@ jobs:
shardTotal: [4]
# TODO: add ref here for main and latest release tag
runs-on: ${{ matrix.os }}
needs: path-changes
if: ${{ needs.path-changes.outputs.significant == 'true' }}
needs: conditions
steps:
- uses: actions/create-github-app-token@v1
id: app-token
@ -84,25 +99,29 @@ jobs:
rust:
- 'rust/**'
- uses: actions/setup-node@v4
if: needs.conditions.outputs.should-run == 'true'
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
id: deps-install
if: needs.conditions.outputs.should-run == 'true'
shell: bash
run: yarn
- name: Cache Playwright Browsers
if: needs.conditions.outputs.should-run == 'true'
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright/
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
- name: Install Playwright Browsers
if: needs.conditions.outputs.should-run == 'true'
shell: bash
run: yarn playwright install --with-deps
- name: Download Wasm Cache
id: download-wasm
if: github.event_name != 'schedule' && steps.filter.outputs.rust == 'false'
if: ${{ needs.conditions.outputs.should-run == 'true' && github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
uses: dawidd6/action-download-artifact@v7
continue-on-error: true
with:
@ -112,27 +131,44 @@ jobs:
branch: main
path: rust/kcl-wasm-lib/pkg
- name: copy wasm blob
if: github.event_name != 'schedule' && steps.filter.outputs.rust == 'false'
if: ${{ needs.conditions.outputs.should-run == 'true' && github.event_name != 'schedule' && steps.filter.outputs.rust == 'false' }}
shell: bash
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
- name: Build WASM condition
id: wasm
if: needs.conditions.outputs.should-run == 'true'
shell: bash
run: |
set -euox pipefail
# Build wasm if this is a scheduled run, there are Rust changes, or
# downloading from the wasm cache failed.
if [[ ${{github.event_name}} == 'schedule' || ${{steps.filter.outputs.rust}} == 'true' || ${{steps.download-wasm.outcome}} == 'failure' ]]; then
echo "should-build-wasm=true" >> $GITHUB_OUTPUT
else
echo "should-build-wasm=false" >> $GITHUB_OUTPUT
fi
- name: Use correct Rust toolchain
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
with:
tool: wasm-pack
- name: Cache Wasm (because rust diff)
if: github.event_name == 'schedule' || steps.filter.outputs.rust == 'true'
uses: Swatinem/rust-cache@v2
with:
workspaces: './rust'
- name: OR Cache Wasm (because wasm cache failed)
if: steps.download-wasm.outcome == 'failure'
- name: Rust Cache
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
uses: Swatinem/rust-cache@v2
with:
workspaces: './rust'
- name: install good sed
if: ${{ startsWith(matrix.os, 'macos') }}
if: ${{ needs.conditions.outputs.should-run == 'true' && startsWith(matrix.os, 'macos') }}
shell: bash
run: |
brew install gnu-sed
@ -154,19 +190,16 @@ jobs:
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
cat /tmp/vector.toml
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
- name: Build Wasm (because rust diff)
if: github.event_name == 'schedule' || steps.filter.outputs.rust == 'true'
shell: bash
run: yarn build:wasm
- name: OR Build Wasm (because wasm cache failed)
if: steps.download-wasm.outcome == 'failure'
- name: Build Wasm
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
shell: bash
run: yarn build:wasm
- name: build web
if: needs.conditions.outputs.should-run == 'true'
shell: bash
run: yarn tronb:vite:dev
- name: Run ubuntu/chrome snapshots
if: ${{ matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 }}
if: ${{ needs.conditions.outputs.should-run == 'true' && matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 }}
shell: bash
# 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.
@ -180,7 +213,7 @@ jobs:
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
with:
name: playwright-report-snapshots-${{ matrix.os }}-snapshot-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
@ -188,11 +221,11 @@ jobs:
retention-days: 30
overwrite: true
- name: Clean up test-results
if: ${{ !cancelled() && (success() || failure()) }}
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
continue-on-error: true
run: rm -r test-results
- name: check for changes
if: ${{ matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 && github.ref != 'refs/heads/main' }}
if: ${{ needs.conditions.outputs.should-run == 'true' && matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 && github.ref != 'refs/heads/main' }}
shell: bash
id: git-check
run: |
@ -202,7 +235,7 @@ jobs:
else echo "modified=false" >> $GITHUB_OUTPUT
fi
- name: Commit changes, if any
if: steps.git-check.outputs.modified == 'true'
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.git-check.outputs.modified == 'true' }}
shell: bash
run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
@ -217,21 +250,21 @@ jobs:
git push origin ${{ github.head_ref }}
# only upload artifacts if there's actually changes
- uses: actions/upload-artifact@v4
if: steps.git-check.outputs.modified == 'true'
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.git-check.outputs.modified == 'true' }}
with:
name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
include-hidden-files: true
retention-days: 30
- uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
continue-on-error: true
with:
name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/
- name: Run playwright/electron flow (with retries)
id: retry
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && steps.deps-install.outcome == 'success' }}
uses: nick-fields/retry@v3.0.2
with:
shell: bash
@ -246,7 +279,7 @@ jobs:
VITE_KC_SKIP_AUTH: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- uses: actions/upload-artifact@v4
if: always()
if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
with:
name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/
@ -254,7 +287,7 @@ jobs:
retention-days: 30
overwrite: true
- uses: actions/upload-artifact@v4
if: always()
if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
with:
name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/

View File

@ -5,6 +5,7 @@ on:
paths:
- .github/workflows/generate-website-docs.yml
- 'docs/**'
- 'public/kcl-samples/**'
pull_request:
paths:
- .github/workflows/generate-website-docs.yml
@ -42,6 +43,14 @@ jobs:
# move new
mv -f docs/kcl/*.md documentation/content/pages/docs/kcl/
mv -f docs/kcl/types documentation/content/pages/docs/kcl/
- name: move kcl-samples
shell: bash
run: |
mkdir -p documentation/content/pages/docs/kcl-samples
# cleanup old
rm -rf documentation/content/pages/docs/kcl-samples/*
# move new
mv -f public/kcl-samples/* documentation/content/pages/docs/kcl-samples/
- name: commit the changes in the docs repo
shell: bash
run: |

View File

@ -159,10 +159,11 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
needs: [linux-x86_64, windows, macos, sdist]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v5
- name: Install codespell
- name: do uv things
run: |
cd rust/kcl-python-bindings
uv venv .venv

View File

@ -1,52 +0,0 @@
name: KCL Samples Manifest
permissions:
contents: write
pull-requests: write
on:
push:
branches:
- main
pull_request:
workflow_dispatch: # Allows manual triggering from the Actions tab
jobs:
generate-manifest:
runs-on: ubuntu-latest
steps:
# Checkout the repository
- name: Checkout repository
uses: actions/checkout@v4
# Set up Node.js
- name: Set up Node.js
uses: actions/setup-node@v4
# Run the script to generate the manifest.json
- name: Run manifest generation script
working-directory: public/kcl-samples
run: node generate-manifest.js
# Check if the manifest.json has changed
- name: Check for changes
id: check-for-changes
working-directory: public/kcl-samples
run: |
git diff --exit-code ./manifest.json || echo "changed=changes detected" >> "$GITHUB_OUTPUT"
# Stage and commit the changes if any were made
- name: Commit and push changes
if: ${{ success() && (steps.check-for-changes.outputs.changed == 'changes detected') }}
working-directory: public/kcl-samples
run: |
git add ./manifest.json
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
git fetch origin
echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }}
git commit -m "Update manifest.json"
git push origin ${{ github.head_ref }}

View File

@ -1,64 +0,0 @@
on:
push:
branches:
- main
paths:
- 'public/kcl-samples/**'
# pull_request:
# paths:
# - .github/workflows/pr-kcl-samples-repo.yml
workflow_dispatch:
name: Create PR in kcl-samples repo
permissions:
contents: read
pull-requests: write
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
pr-kcl-samples-repo:
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
# required
app-id: ${{ secrets.GH_ORG_APP_ID }}
private-key: ${{ secrets.GH_ORG_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
# Checkout the other repo since we want to update the files there.
- uses: actions/checkout@v4
with:
repository: 'KittyCAD/kcl-samples'
ref: next
path: kcl-samples-repo
token: ${{ steps.app-token.outputs.token }}
- name: Move files to repo work tree
shell: bash
run: |
rsync -av --delete \
--exclude='.git' \
--exclude='.github' \
--exclude='screenshots' \
--exclude='step' \
public/kcl-samples/ kcl-samples-repo/
- name: Commit the changes in the repo
shell: bash
run: |
set -euo pipefail
cd kcl-samples-repo
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
export NEW_BRANCH="update-from-modeling-app"
git switch -c "$NEW_BRANCH"
git add --all .
git commit -m "Updates from modeling-app repo" || exit 0
git push -f origin "$NEW_BRANCH"
gh pr create --title "Update from modeling-app" \
--body "Updating files from the modeling-app repo" \
--head "$NEW_BRANCH" \
--reviewer jtran \
--base next || true
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}

2
.gitignore vendored
View File

@ -53,8 +53,6 @@ e2e/playwright/export-snapshots/*
/public/kcl-samples.zip
/public/kcl-samples/.github
/public/kcl-samples/screenshots
/public/kcl-samples/step
/test-results/
/playwright-report/
/blob-report/

View File

@ -40,7 +40,7 @@ sketch001 = startSketchOn('XZ')
angle = angleToMatchLengthY(seg01, 15, %),
length = 5
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrusion = extrude(sketch001, length = 5)

View File

@ -35,10 +35,10 @@ angledLine(
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> yLineTo(15, %)
|> yLine(endAbsolute = 15)
|> angledLine({ angle = 30, length = 15 }, %)
|> line(end = [8, -10])
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 10)

View File

@ -37,7 +37,7 @@ sketch001 = startSketchOn('XZ')
angle = toDegrees(asin(0.5)),
length = 20
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrude001 = extrude(sketch001, length = 5)

View File

@ -37,7 +37,7 @@ sketch001 = startSketchOn('XZ')
angle = toDegrees(atan(1.25)),
length = 20
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrude001 = extrude(sketch001, length = 5)

View File

@ -41,7 +41,7 @@ sketch001 = startSketchOn('XZ')
angle = toDegrees(atan2(1.25, 2)),
length = 20
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrude001 = extrude(sketch001, length = 5)

View File

@ -35,7 +35,7 @@ sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [ceil(7.02986), 0])
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrude001 = extrude(sketch001, length = 5)

View File

@ -21,7 +21,7 @@ exampleSketch = startSketchOn("XZ")
angle = 30,
length = 2 * E ^ 2,
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 10)

View File

@ -21,7 +21,7 @@ exampleSketch = startSketchOn("XZ")
angle = 50,
length = 10 * TAU,
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

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

View File

@ -35,7 +35,7 @@ sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [floor(7.02986), 0])
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrude001 = extrude(sketch001, length = 5)

View File

@ -131,9 +131,7 @@ layout: manual
* [`toRadians`](kcl/toRadians)
* [`translate`](kcl/translate)
* [`xLine`](kcl/xLine)
* [`xLineTo`](kcl/xLineTo)
* [`yLine`](kcl/yLine)
* [`yLineTo`](kcl/yLineTo)
* [`yd`](kcl/yd)
* **std::math**
* [`E`](kcl/const_std-math-E)

View File

@ -38,7 +38,7 @@ pow(
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = pow(5, 2) }, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -35,7 +35,7 @@ sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [round(7.02986), 0])
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
extrude001 = extrude(sketch001, length = 5)

View File

@ -34,7 +34,7 @@ sqrt(num: number): number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = sqrt(2500) }, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -137,9 +137,9 @@ a1 = startSketchOn({
})
|> startProfileAt([0, 0], %)
|> line(end = [100.0, 0])
|> yLine(-100.0, %)
|> xLine(-100.0, %)
|> yLine(100.0, %)
|> yLine(length = -100.0)
|> xLine(length = -100.0)
|> yLine(length = 100.0)
|> close()
|> extrude(length = 3.14)
```

View File

@ -33,7 +33,7 @@ exampleSketch = startSketchOn("XZ")
angle = 30,
length = 3 / cos(toRadians(30)),
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -33,7 +33,7 @@ exampleSketch = startSketchOn("XZ")
angle = 50,
length = 15 / sin(toDegrees(135)),
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -33,7 +33,7 @@ exampleSketch = startSketchOn("XZ")
angle = 50,
length = 50 * tan(1/2),
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ tau(): number
exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle = 50, length = 10 * tau() }, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -37,7 +37,7 @@ exampleSketch = startSketchOn("XZ")
angle = 50,
length = 70 * cos(toDegrees(pi() / 4))
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -37,7 +37,7 @@ exampleSketch = startSketchOn("XZ")
angle = 50,
length = 70 * cos(toRadians(45))
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
example = extrude(exampleSketch, length = 5)

View File

@ -10,8 +10,9 @@ Draw a line relative to the current origin to a specified distance away from the
```js
xLine(
length: number,
sketch: Sketch,
length?: number,
endAbsolute?: number,
tag?: TagDeclarator,
): Sketch
```
@ -21,9 +22,10 @@ xLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `length` | [`number`](/docs/kcl/types/number) | | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `length` | [`number`](/docs/kcl/types/number) | How far away along the X axis should this line go? Incompatible with `endAbsolute`. | No |
| `endAbsolute` | [`number`](/docs/kcl/types/number) | Which absolute X value should this line go to? Incompatible with `length`. | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -35,12 +37,12 @@ xLine(
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> xLine(15, %)
|> xLine(length = 15)
|> angledLine({ angle = 80, length = 15 }, %)
|> line(end = [8, -10])
|> xLine(10, %)
|> xLine(length = 10)
|> angledLine({ angle = 120, length = 30 }, %)
|> xLine(-15, %)
|> xLine(length = -15)
|> close()
example = extrude(exampleSketch, length = 10)

View File

@ -10,8 +10,9 @@ Draw a line relative to the current origin to a specified distance away from the
```js
yLine(
length: number,
sketch: Sketch,
length?: number,
endAbsolute?: number,
tag?: TagDeclarator,
): Sketch
```
@ -21,9 +22,10 @@ yLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `length` | [`number`](/docs/kcl/types/number) | | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `length` | [`number`](/docs/kcl/types/number) | How far away along the Y axis should this line go? Incompatible with `endAbsolute`. | No |
| `endAbsolute` | [`number`](/docs/kcl/types/number) | Which absolute Y value should this line go to? Incompatible with `length`. | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -35,10 +37,10 @@ yLine(
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> yLine(15, %)
|> yLine(length = 15)
|> angledLine({ angle = 30, length = 15 }, %)
|> line(end = [8, -10])
|> yLine(-5, %)
|> yLine(length = -5)
|> close()
example = extrude(exampleSketch, length = 10)

View File

@ -65,7 +65,7 @@ async function doBasicSketch(
if (openPanes.includes('code')) {
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|> xLine(${commonPoints.num1}, %)`)
|> xLine(length = ${commonPoints.num1})`)
}
await page.waitForTimeout(500)
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
@ -74,8 +74,8 @@ async function doBasicSketch(
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(${commonPoints.num1}, %)
|> yLine(${commonPoints.num1 + 0.01}, %)`)
|> xLine(length = ${commonPoints.num1})
|> yLine(length = ${commonPoints.num1 + 0.01})`)
} else {
await page.waitForTimeout(500)
}
@ -86,9 +86,9 @@ async function doBasicSketch(
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(${commonPoints.num1}, %)
|> yLine(${commonPoints.num1 + 0.01}, %)
|> xLine(${commonPoints.num2 * -1}, %)`)
|> xLine(length = ${commonPoints.num1})
|> yLine(length = ${commonPoints.num1 + 0.01})
|> xLine(length = ${commonPoints.num2 * -1})`)
}
// deselect line tool
@ -146,9 +146,9 @@ async function doBasicSketch(
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(${commonPoints.num1}, %, $seg01)
|> yLine(${commonPoints.num1 + 0.01}, %)
|> xLine(-segLen(seg01), %)`)
|> xLine(length = ${commonPoints.num1}, tag = $seg01)
|> yLine(length = ${commonPoints.num1 + 0.01})
|> xLine(length = -segLen(seg01))`)
}
test.describe('Basic sketch', { tag: ['@skipWin'] }, () => {

View File

@ -16,7 +16,7 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> xLine(-20, %)
|> xLine(length = -20)
|> close()
`
)

View File

@ -800,10 +800,10 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Enter')
// finish line with comment
await page.keyboard.type('5')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
await page.keyboard.type('5')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
await page.keyboard.type(' // ')
@ -817,7 +817,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
|> startProfileAt([3.14, 12], %)
|> xLine(5, %) // lin`)
|> xLine(%, length = 5) // lin`)
// expect there to be no KCL errors
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0)
@ -873,10 +873,10 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('ArrowDown')
await page.keyboard.press('Tab')
// finish line with comment
await page.keyboard.type('5')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
await page.waitForTimeout(100)
await page.keyboard.type('5')
await page.waitForTimeout(100)
await page.keyboard.press('Tab')
await page.keyboard.type(' // ')
@ -890,7 +890,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
|> startProfileAt([3.14, 12], %)
|> xLine(5, %) // lin`)
|> xLine(%, length = 5) // lin`)
})
})
test('Can undo a click and point extrude with ctrl+z', async ({

View File

@ -8,7 +8,7 @@ const FEATURE_TREE_EXAMPLE_CODE = `export fn timesFive(x) {
export fn triangle() {
return startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> xLine(10, %)
|> xLine(length = 10)
|> line(end = [-10, -5])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -28,7 +28,7 @@ plane001 = offsetPlane('XY', offset = 10)
sketch002 = startSketchOn(plane001)
|> startProfileAt([-20, 0], %)
|> line(end = [5, -15])
|> xLine(-10, %)
|> xLine(length = -10)
|> line(endAbsolute = [-40, 0])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -402,7 +402,7 @@ test.describe('Feature Tree pane', () => {
sketch001 = startSketchOn(plane001)
profile001 = circle(sketch001, center = [0, 20], radius = 12)
profile002 = startProfileAt([0, 7.25], sketch001)
|> xLine(13.3, %)
|> xLine(length = 13.3)
profile003 = startProfileAt([0, -4.93], sketch001)
|> line(endAbsolute = [-5.56, 0])`
await context.folderSetupFn(async (dir) => {

View File

@ -28,7 +28,6 @@ export class ToolbarFixture {
rectangleBtn!: Locator
lengthConstraintBtn!: Locator
exitSketchBtn!: Locator
editSketchBtn!: Locator
fileTreeBtn!: Locator
createFileBtn!: Locator
fileCreateToast!: Locator
@ -61,7 +60,6 @@ export class ToolbarFixture {
this.rectangleBtn = page.getByTestId('corner-rectangle')
this.lengthConstraintBtn = page.getByTestId('constraint-length')
this.exitSketchBtn = page.getByTestId('sketch-exit')
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')
@ -71,6 +69,10 @@ export class ToolbarFixture {
this.fileCreateToast = page.getByText('Successfully created')
}
get editSketchBtn() {
return this.page.locator('[name="Edit Sketch"]')
}
get logoLink() {
return this.page.getByTestId('app-logo')
}

View File

@ -524,7 +524,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
const expectedCodeSnippets = {
sketchOnXzPlane: `sketch001 = startSketchOn('XZ')`,
pointAtOrigin: `startProfileAt([${originSloppy.kcl[0]}, ${originSloppy.kcl[1]}], sketch001)`,
segmentOnXAxis: `xLine(${xAxisSloppy.kcl[0]}, %)`,
segmentOnXAxis: `xLine(length = ${xAxisSloppy.kcl[0]})`,
afterSegmentDraggedOffYAxis: `startProfileAt([${offYAxis.kcl[0]}, ${offYAxis.kcl[1]}], sketch001)`,
afterSegmentDraggedOnYAxis: `startProfileAt([${yAxisSloppy.kcl[0]}, ${yAxisSloppy.kcl[1]}], sketch001)`,
}
@ -585,7 +585,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
openSketch = startSketchOn('XY')
|> startProfileAt([-5, 0], %)
|> line(endAbsolute = [0, 5])
|> xLine(5, %)
|> xLine(length = 5)
|> tangentialArcTo([10, 0], %)
`
const viewPortSize = { width: 1000, height: 500 }
@ -1350,7 +1350,7 @@ loft001 = loft([sketch001, sketch002])
)
sketch002 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> xLine(-500, %)
|> xLine(length = -500)
|> tangentialArcTo([-2000, 500], %)
`
await context.addInitScript((initialCode) => {
@ -1444,7 +1444,7 @@ sketch002 = startSketchOn('XZ')
)
sketch002 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> xLine(-500, %)
|> xLine(length = -500)
|> line(endAbsolute = [-2000, 500])
`
await context.addInitScript((initialCode) => {
@ -2365,9 +2365,9 @@ chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])
}) => {
const initialCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-20, 20], %)
|> xLine(40, %)
|> yLine(-60, %)
|> xLine(-40, %)
|> xLine(length = 40)
|> yLine(length = -60)
|> xLine(length = -40)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude001 = extrude(sketch001, length = 40)
@ -2383,7 +2383,7 @@ extrude001 = extrude(sketch001, length = 40)
const testPoint = { x: 580, y: 180 }
const [clickOnCap] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
const [clickOnWall] = scene.makeMouseHelpers(testPoint.x, testPoint.y + 70)
const mutatedCode = 'xLine(-40, %, $seg01)'
const mutatedCode = 'xLine(length = -40, tag = $seg01)'
const shellDeclaration =
"shell001 = shell(extrude001, faces = ['end', seg01], thickness = 5)"
@ -2549,9 +2549,9 @@ extrude002 = extrude(sketch002, length = 50)
}) => {
const sketchCode = `sketch001 = startSketchOn('XY')
profile001 = startProfileAt([-20, 20], sketch001)
|> xLine(40, %)
|> yLine(-60, %)
|> xLine(-40, %)
|> xLine(length = 40)
|> yLine(length = -60)
|> xLine(length = -40)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
`
@ -2637,7 +2637,7 @@ profile001 = startProfileAt([-20, 20], sketch001)
)
sketch002 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> xLine(-2000, %)
|> xLine(length = -2000)
sweep001 = sweep(sketch001, path = sketch002)
`
await context.addInitScript((initialCode) => {
@ -2798,7 +2798,7 @@ radius = 8.69
const initialCode = `
sketch002 = startSketchOn('XY')
|> startProfileAt([-2.02, 1.79], %)
|> xLine(2.6, %)
|> xLine(length = 2.6)
sketch001 = startSketchOn('-XY')
|> startProfileAt([-0.48, 1.25], %)
|> angledLine([0, 2.38], %, $rectangleSegmentA001)
@ -2830,7 +2830,7 @@ radius = 8.69
await page.getByText(codeToSelecton).click()
await toolbar.revolveButton.click()
await page.getByText('Edge', { exact: true }).click()
const lineCodeToSelection = `|> xLine(2.6, %)`
const lineCodeToSelection = `|> xLine(length = 2.6)`
await page.getByText(lineCodeToSelection).click()
await cmdBar.progressCmdBar()

View File

@ -32,9 +32,9 @@ profile001 = startProfileAt([57.81, 250.51], sketch001)
extrude001 = extrude(profile001, length = 200)
sketch002 = startSketchOn('XZ')
|> startProfileAt([-73.64, -42.89], %)
|> xLine(173.71, %)
|> xLine(length = 173.71)
|> line(end = [-22.12, -94.4])
|> xLine(-156.98, %)
|> xLine(length = -156.98)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude002 = extrude(sketch002, length = 50)

View File

@ -13,9 +13,9 @@ profile001 = startProfileAt([57.81, 250.51], sketch001)
extrude001 = extrude(profile001, length = 200)
sketch002 = startSketchOn('XZ')
|> startProfileAt([-114, 85.52], %)
|> xLine(265.36, %)
|> xLine(length = 265.36)
|> line(end = [33.17, -261.22])
|> xLine(-297.25, %)
|> xLine(length = -297.25)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude002 = extrude(sketch002, length = 50)

View File

@ -249,7 +249,7 @@ extrude001 = extrude(sketch001, length = 50)
`exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle: 50, length: 45 }, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
|>
@ -305,7 +305,7 @@ extrude001 = extrude(sketch001, length = 50)
.toContainText(`exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({ angle: 50, length: 45 }, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close()
thing: "blah"`)

View File

@ -48,26 +48,26 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
part001 = startSketchOn('XY')
${startProfileAt2}
|> xLine(width * .5, %)
|> yLine(height, %)
|> xLine(-width * .5, %)
|> xLine(length = width * .5)
|> yLine(length = height)
|> xLine(length = -width * .5)
|> close()
|> hole(screwHole, %)
|> extrude(length = thickness)
part002 = startSketchOn('-XZ')
${startProfileAt3}
|> xLine(width / 4, %)
|> xLine(length = width / 4)
|> tangentialArcTo([width / 2, 0], %)
|> xLine(-width / 4 + wireRadius, %)
|> yLine(wireOffset, %)
|> xLine(length = -width / 4 + wireRadius)
|> yLine(length = wireOffset)
|> arc({
radius = wireRadius,
angleStart = 0,
angleEnd = 180
}, %)
|> yLine(-wireOffset, %)
|> xLine(-width / 4, %)
|> yLine(length = -wireOffset)
|> xLine(length = -width / 4)
|> close()
|> extrude(length = -height)
`
@ -111,7 +111,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
'persistCode',
`sketch001 = startSketchOn('XZ')
|> startProfileAt([2.61, -4.01], %)
|> xLine(8.73, %)
|> xLine(length = 8.73)
|> tangentialArcTo([8.33, -1.31], %)`
)
})
@ -157,7 +157,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
await expect.poll(u.normalisedEditorCode, { timeout: 1000 })
.toBe(`sketch002 = startSketchOn('XZ')
sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> yLine(12.34, %)
|> yLine(length = 12.34)
`)
}).toPass({ timeout: 5_000, intervals: [1_000] })
@ -691,15 +691,15 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
await click00r(50, 0)
await page.waitForTimeout(100)
codeStr += ` |> xLine(${toU(50, 0)[0]}, %)`
codeStr += ` |> xLine(length = ${toU(50, 0)[0]})`
await expect(u.codeLocator).toHaveText(codeStr)
await click00r(0, 50)
codeStr += ` |> yLine(${toU(0, 50)[1]}, %)`
codeStr += ` |> yLine(length = ${toU(0, 50)[1]})`
await expect(u.codeLocator).toHaveText(codeStr)
await click00r(-50, 0)
codeStr += ` |> xLine(${toU(-50, 0)[0]}, %)`
codeStr += ` |> xLine(length = ${toU(-50, 0)[0]})`
await expect(u.codeLocator).toHaveText(codeStr)
// exit the sketch, reset relative clicker
@ -728,15 +728,15 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
// TODO: I couldn't use `toSU` here because of some rounding error causing
// it to be off by 0.01
await click00r(30, 0)
codeStr += ` |> xLine(2.04, %)`
codeStr += ` |> xLine(length = 2.04)`
await expect(u.codeLocator).toHaveText(codeStr)
await click00r(0, 30)
codeStr += ` |> yLine(-2.03, %)`
codeStr += ` |> yLine(length = -2.03)`
await expect(u.codeLocator).toHaveText(codeStr)
await click00r(-30, 0)
codeStr += ` |> xLine(-2.04, %)`
codeStr += ` |> xLine(length = -2.04)`
await expect(u.codeLocator).toHaveText(codeStr)
await click00r(undefined, undefined)
@ -761,8 +761,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
scale * 34.8
)}], sketch001)
|> xLine(${roundOff(scale * 139.19)}, %)
|> yLine(-${roundOff(scale * 139.2)}, %)
|> xLine(length = ${roundOff(scale * 139.19)})
|> yLine(length = -${roundOff(scale * 139.2)})
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()`
@ -1018,7 +1018,7 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> xLine(-20, %)
|> xLine(length = -20)
`)
await u.expectCmdLog('[data-message-type="execution-done"]')
@ -1094,8 +1094,8 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
lugSketch = startSketchOn(plane)
|> startProfileAt([origin[0] + lugDiameter / 2, origin[1]], %)
|> angledLineOfYLength({ angle = 60, length = lugHeadLength }, %)
|> xLineTo(0 + .001, %)
|> yLineTo(0, %)
|> xLine(endAbsolute = 0 + .001)
|> yLine(endAbsolute = 0)
|> close()
|> revolve({ axis = "Y" }, %)
@ -1368,7 +1368,7 @@ profile001 = startProfileAt([121.52, 168.25], sketch001)
|> close()
profile002 = startProfileAt([117.2, 56.08], sketch001)
|> line(end = [166.82, 25.89])
|> yLine(-107.86, %)
|> yLine(length = -107.86)
`
)
@ -1456,9 +1456,9 @@ profile002 = startProfileAt([117.2, 56.08], sketch001)
'persistCode',
`sketch001 = startSketchOn('XZ')
profile002 = startProfileAt([40.68, 87.67], sketch001)
|> xLine(239.17, %)
|> xLine(length = 239.17)
profile003 = startProfileAt([206.63, -56.73], sketch001)
|> xLine(-156.32, %)
|> xLine(length = -156.32)
`
)
})
@ -2318,7 +2318,7 @@ profile003 = startProfileAt([3.19, 13.3], sketch002)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
profile004 = startProfileAt([3.15, 9.39], sketch002)
|> xLine(6.92, %)
|> xLine(length = 6.92)
|> line(end = [-7.41, -2.85])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -2556,7 +2556,7 @@ profile001 = startProfileAt([34, 42.66], sketch001)
plane001 = offsetPlane('XZ', offset = 50)
sketch002 = startSketchOn(plane001)
profile002 = startProfileAt([39.43, 172.21], sketch002)
|> xLine(183.99, %)
|> xLine(length = 183.99)
|> line(end = [-77.95, -145.93])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -2609,7 +2609,7 @@ profile001 = startProfileAt([34, 42.66], sketch001)
plane001 = offsetPlane('XZ', offset = 50)
sketch002 = startSketchOn(plane001)
profile002 = startProfileAt([39.43, 172.21], sketch002)
|> xLine(183.99, %)
|> xLine(length = 183.99)
|> line(end = [-77.95, -145.93])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()

View File

@ -62,14 +62,14 @@ armThick = 0.5
totalLen = 9.5
part001 = startSketchOn('-XZ')
|> startProfileAt([0, 0], %)
|> yLine(baseHeight, %)
|> xLine(baseLen, %)
|> yLine(length = baseHeight)
|> xLine(length = baseLen)
|> angledLineToY({
angle = topAng,
to = totalHeightHalf,
}, %, $seg04)
|> xLineTo(totalLen, %, $seg03)
|> yLine(-armThick, %, $seg01)
|> xLine(endAbsolute = totalLen, tag = $seg03)
|> yLine(length = -armThick, tag = $seg01)
|> angledLineThatIntersects({
angle = HALF_TURN,
offset = -armThick,
@ -80,15 +80,15 @@ part001 = startSketchOn('-XZ')
angle = -bottomAng,
to = -totalHeightHalf - armThick,
}, %, $seg02)
|> xLineTo(segEndX(seg03, %) + 0, %)
|> yLine(-segLen(seg01, %), %)
|> xLine(length = endAbsolute = segEndX(seg03) + 0)
|> yLine(length = -segLen(seg01, %))
|> angledLineThatIntersects({
angle = HALF_TURN,
offset = -armThick,
intersectTag = seg02
}, %)
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|> xLineTo(ZERO, %)
|> xLine(endAbsolute = ZERO)
|> close()
|> extrude(length = 4)`
)
@ -443,7 +443,7 @@ test(
await page.waitForTimeout(500)
code += `
|> xLine(7.25, %)`
|> xLine(length = 7.25)`
await expect(page.locator('.cm-content')).toHaveText(code)
await page
@ -609,7 +609,7 @@ test.describe(
await page.waitForTimeout(100)
code += `
|> xLine(7.25, %)`
|> xLine(length = 7.25)`
await expect(u.codeLocator).toHaveText(code)
await page
@ -704,7 +704,7 @@ test.describe(
await page.waitForTimeout(100)
code += `
|> xLine(184.3, %)`
|> xLine(length = 184.3)`
await expect(u.codeLocator).toHaveText(code)
await page

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -1,5 +1,5 @@
{
"original_source_code": "sketch001 = startSketchOn('XZ')\nprofile001 = startProfileAt([57.81, 250.51], sketch001)\n |> line(end = [121.13, 56.63], tag = $seg02)\n |> line(end = [83.37, -34.61], tag = $seg01)\n |> line(end = [19.66, -116.4])\n |> line(end = [-221.8, -41.69])\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude001 = extrude(profile001, length = 200)\nsketch002 = startSketchOn('XZ')\n |> startProfileAt([-73.64, -42.89], %)\n |> xLine(173.71, %)\n |> line(end = [-22.12, -94.4])\n |> xLine(-156.98, %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude002 = extrude(sketch002, length = 50)\nsketch003 = startSketchOn('XY')\n |> startProfileAt([52.92, 157.81], %)\n |> angledLine([0, 176.4], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 53.4\n ], %, $rectangleSegmentB001)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %, $rectangleSegmentC001)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude003 = extrude(sketch003, length = 20)\n",
"original_source_code": "sketch001 = startSketchOn('XZ')\nprofile001 = startProfileAt([57.81, 250.51], sketch001)\n |> line(end = [121.13, 56.63], tag = $seg02)\n |> line(end = [83.37, -34.61], tag = $seg01)\n |> line(end = [19.66, -116.4])\n |> line(end = [-221.8, -41.69])\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude001 = extrude(profile001, length = 200)\nsketch002 = startSketchOn('XZ')\n |> startProfileAt([-73.64, -42.89], %)\n |> xLine(length = 173.71)\n |> line(end = [-22.12, -94.4])\n |> xLine(length = -156.98)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude002 = extrude(sketch002, length = 50)\nsketch003 = startSketchOn('XY')\n |> startProfileAt([52.92, 157.81], %)\n |> angledLine([0, 176.4], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 53.4\n ], %, $rectangleSegmentB001)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %, $rectangleSegmentC001)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude003 = extrude(sketch003, length = 20)\n",
"prompt": "make this neon green please, use #39FF14",
"source_ranges": [
{
@ -29,5 +29,5 @@
}
}
],
"kcl_version": "0.2.45"
"kcl_version": "0.2.47"
}

View File

@ -83,9 +83,9 @@ export const TEST_CODE_GIZMO = `part001 = startSketchOn('XZ')
|> line(end = [7.13, 4 + 0])
|> angledLine({ angle: 3 + 0, length: 3.14 + 0 }, %)
|> line(endAbsolute = [20.14 + 0, -0.14 + 0])
|> xLineTo(29 + 0, %)
|> yLine(-3.14 + 0, %, $a)
|> xLine(1.63, %)
|> xLine(endAbsolute = 29 + 0)
|> yLine(length = -3.14 + 0, tag = $a)
|> xLine(length = 1.63)
|> angledLineOfXLength({ angle: 3 + 0, length: 3.14 }, %)
|> angledLineOfYLength({ angle: 30, length: 3 + 0 }, %)
|> angledLineToX({ angle: 22.14 + 0, to: 12 }, %)
@ -150,7 +150,7 @@ sketch001 = startSketchOn(box, revolveAxis)
sketch001 = startSketchOn('XZ')
|> startProfileAt([0.0, 0.0], %)
|> xLine(0.0, %)
|> xLine(length = 0.0)
|> close()
`

View File

@ -122,7 +122,7 @@ test.describe('Test network and connection issues', () => {
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|> xLine(${commonPoints.num1}, %)`)
|> xLine(length = ${commonPoints.num1})`)
// Expect the network to be up
await expect(networkToggle).toContainText('Connected')
@ -215,7 +215,7 @@ test.describe('Test network and connection issues', () => {
await expect.poll(u.normalisedEditorCode)
.toBe(`sketch001 = startSketchOn('XZ')
profile001 = startProfileAt([12.34, -12.34], sketch001)
|> xLine(12.34, %)
|> xLine(length = 12.34)
|> line(end = [-12.34, 12.34])
`)
@ -225,9 +225,9 @@ profile001 = startProfileAt([12.34, -12.34], sketch001)
await expect.poll(u.normalisedEditorCode)
.toBe(`sketch001 = startSketchOn('XZ')
profile001 = startProfileAt([12.34, -12.34], sketch001)
|> xLine(12.34, %)
|> xLine(length = 12.34)
|> line(end = [-12.34, 12.34])
|> xLine(-12.34, %)
|> xLine(length = -12.34)
`)

View File

@ -18,7 +18,7 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> xLine(-20, %)
|> xLine(length = -20)
`
)
})
@ -57,7 +57,7 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
.click()
await expect(page.locator('.cm-content')).toHaveText(
`length001 = 20sketch001 = startSketchOn('XY') |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> angledLine([90, length001], %) |> xLine(-20, %)`
`length001 = 20sketch001 = startSketchOn('XY') |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> angledLine([90, length001], %) |> xLine(length = -20)`
)
// Make sure we didn't pop out of sketch mode.
@ -89,9 +89,9 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> line(end = [41.19, 58.97 + 5])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 120], %)
|> xLine(-385.34, %, $seg_what)
|> yLine(-170.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -385.34, tag = $seg_what)
|> yLine(length = -170.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -153,9 +153,9 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
@ -285,9 +285,9 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -395,9 +395,9 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -508,9 +508,9 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -610,9 +610,9 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -696,9 +696,9 @@ part001 = startSketchOn('XZ')
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -748,16 +748,16 @@ part002 = startSketchOn('XZ')
{
constraintName: 'Vertical',
codeAfter: [
`|> yLine(130.4, %)`,
`|> yLine(77.79, %)`,
`|> yLine(48.97, %)`,
`|> yLine(length = 130.4)`,
`|> yLine(length = 77.79)`,
`|> yLine(length = 48.97)`,
],
},
{
codeAfter: [
`|> xLine(74.36, %)`,
`|> xLine(9.16, %)`,
`|> xLine(51.19, %)`,
`|> xLine(length = 74.36)`,
`|> xLine(length = 9.16)`,
`|> xLine(length = 51.19)`,
],
constraintName: 'Horizontal',
},
@ -776,9 +776,9 @@ part002 = startSketchOn('XZ')
|> line(end = [51.19, 48.97])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -876,9 +876,9 @@ part002 = startSketchOn('XZ')
|> line(end = [9.16, 77.79])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -957,9 +957,9 @@ part002 = startSketchOn('XZ')
|> line(end = [9.16, 77.79])
part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what)
|> yLine(-264.06, %)
|> xLine(segLen(seg_what), %)
|> xLine(length = -425.34, tag = $seg_what)
|> yLine(length = -264.06)
|> xLine(length = segLen(seg_what))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])`
)
})
@ -1061,7 +1061,7 @@ part002 = startSketchOn('XZ')
await pollEditorLinesSelectedLength(page, 1)
let activeLinesContent = await page.locator('.cm-activeLine').all()
await expect(activeLinesContent[0]).toHaveText(`|> xLine(3.13, %)`)
await expect(activeLinesContent[0]).toHaveText(`|> xLine(length = 3.13)`)
// Wait for code editor to settle.
await page.waitForTimeout(2000)
@ -1105,7 +1105,9 @@ part002 = startSketchOn('XZ')
await pollEditorLinesSelectedLength(page, 1)
activeLinesContent = await page.locator('.cm-activeLine').all()
await expect(activeLinesContent[0]).toHaveText(`|> xLine(length001, %)`)
await expect(activeLinesContent[0]).toHaveText(
`|> xLine(length = length001)`
)
// checking the count of the overlays is a good proxy check that the client sketch scene is in a good state
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)

View File

@ -212,10 +212,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|> line(end = [0.5, -14 + 0])
|> angledLine({ angle = 3 + 0, length = 32 + 0 }, %)
|> line(endAbsolute = [5 + 33, 20 + 11.5 + 0])
|> xLineTo(5 + 9 - 5, %)
|> yLineTo(20 + -10.77, %, $a)
|> xLine(26.04, %)
|> yLine(21.14 + 0, %)
|> xLine(endAbsolute = 5 + 9 - 5)
|> yLine(endAbsolute = 20 + -10.77, tag = $a)
|> xLine(length = 26.04)
|> yLine(length = 21.14 + 0)
|> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)
|> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)
|> angledLineToX({ angle = 3 + 0, to = 5 + 26 }, %)
@ -239,7 +239,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await page.getByText('xLineTo(5 + 9 - 5, %)').click()
await page.getByText('xLine(endAbsolute = 5 + 9 - 5)').click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
@ -358,9 +358,9 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await clickConstrained({
hoverPos: { x: xLineTo.x, y: xLineTo.y },
constraintType: 'xAbsolute',
expectBeforeUnconstrained: 'xLineTo(5 + 9 - 5, %)',
expectAfterUnconstrained: 'xLineTo(9, %)',
expectFinal: 'xLineTo(xAbs002, %)',
expectBeforeUnconstrained: 'xLine(endAbsolute = 5 + 9 - 5)',
expectAfterUnconstrained: 'xLine(endAbsolute = 9)',
expectFinal: 'xLine(endAbsolute = xAbs002)',
ang: ang + 180,
steps: 8,
locator: '[data-overlay-toolbar-index="3"]',
@ -386,10 +386,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|> line(end = [0.5, yRel001])
|> angledLine({ angle = angle001, length = len001 }, %)
|> line(endAbsolute = [33, yAbs001])
|> xLineTo(xAbs002, %)
|> yLineTo(-10.77, %, $a)
|> xLine(26.04, %)
|> yLine(21.14 + 0, %)
|> xLine(endAbsolute = xAbs002)
|> yLine(endAbsolute = -10.77, tag = $a)
|> xLine(length = 26.04)
|> yLine(length = 21.14 + 0)
|> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)
`
)
@ -404,7 +404,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await page.getByText('xLine(26.04, %)').click()
await page.getByText('xLine(length = 26.04)').click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
@ -424,9 +424,9 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await clickUnconstrained({
hoverPos: { x: yLineTo.x, y: yLineTo.y - 200 },
constraintType: 'yAbsolute',
expectBeforeUnconstrained: 'yLineTo(-10.77, %, $a)',
expectAfterUnconstrained: 'yLineTo(yAbs002, %, $a)',
expectFinal: 'yLineTo(-10.77, %, $a)',
expectBeforeUnconstrained: 'yLine(endAbsolute = -10.77, tag = $a)',
expectAfterUnconstrained: 'yLine(endAbsolute = yAbs002, tag = $a)',
expectFinal: 'yLine(endAbsolute = -10.77, tag = $a)',
ang: ang + 180,
locator: '[data-overlay-toolbar-index="4"]',
})
@ -437,9 +437,9 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await clickUnconstrained({
hoverPos: { x: xLine.x, y: xLine.y },
constraintType: 'xRelative',
expectBeforeUnconstrained: 'xLine(26.04, %)',
expectAfterUnconstrained: 'xLine(xRel002, %)',
expectFinal: 'xLine(26.04, %)',
expectBeforeUnconstrained: 'xLine(length = 26.04)',
expectAfterUnconstrained: 'xLine(length = xRel002)',
expectFinal: 'xLine(length = 26.04)',
steps: 10,
ang: ang + 180,
locator: '[data-overlay-toolbar-index="5"]',
@ -459,10 +459,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|> line(end = [0.5, -14 + 0])
|> angledLine({ angle = 3 + 0, length = 32 + 0 }, %)
|> line(endAbsolute = [33, 11.5 + 0])
|> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, $a)
|> xLine(26.04, %)
|> yLine(21.14 + 0, %)
|> xLine(endAbsolute = 9 - 5)
|> yLine(endAbsolute = -10.77, tag = $a)
|> xLine(length = 26.04)
|> yLine(length = 21.14 + 0)
|> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)
|> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)
|> angledLineToX({ angle = 3 + 0, to = 26 }, %)
@ -488,7 +488,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await u.closeDebugPanel()
await page.waitForTimeout(500)
await page.getByText('xLineTo(9 - 5, %)').click()
await page.getByText('xLine(endAbsolute = 9 - 5)').click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
@ -506,9 +506,9 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await clickConstrained({
hoverPos: { x: yLine.x, y: yLine.y },
constraintType: 'yRelative',
expectBeforeUnconstrained: 'yLine(21.14 + 0, %)',
expectAfterUnconstrained: 'yLine(21.14, %)',
expectFinal: 'yLine(yRel001, %)',
expectBeforeUnconstrained: 'yLine(length = 21.14 + 0)',
expectAfterUnconstrained: 'yLine(length = 21.14)',
expectFinal: 'yLine(length = yRel001)',
ang: ang + 180,
locator: '[data-overlay-toolbar-index="6"]',
})
@ -591,10 +591,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|> line(end = [0.5, -14 + 0])
|> angledLine({ angle = 3 + 0, length = 32 + 0 }, %)
|> line(endAbsolute = [33, 11.5 + 0])
|> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, $a)
|> xLine(26.04, %)
|> yLine(21.14 + 0, %)
|> xLine(endAbsolute = 9 - 5)
|> yLine(endAbsolute = -10.77, tag = $a)
|> xLine(length = 26.04)
|> yLine(length = 21.14 + 0)
|> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)
|> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)
|> angledLineToX({ angle = 3 + 0, to = 26 }, %)
@ -619,7 +619,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await page.getByText('xLineTo(9 - 5, %)').click()
await page.getByText('xLine(endAbsolute = 9 - 5)').click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
@ -755,10 +755,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|> line(end = [0.5, -14 + 0])
|> angledLine({ angle = 3 + 0, length = 32 + 0 }, %)
|> line(endAbsolute = [33, 11.5 + 0])
|> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, $a)
|> xLine(26.04, %)
|> yLine(21.14 + 0, %)
|> xLine(endAbsolute = 9 - 5)
|> yLine(endAbsolute = -10.77, tag = $a)
|> xLine(length = 26.04)
|> yLine(length = 21.14 + 0)
|> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)
|> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)
|> angledLineToX({ angle = 3 + 0, to = 26 }, %)
@ -783,7 +783,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await page.getByText('xLineTo(9 - 5, %)').click()
await page.getByText('xLine(endAbsolute = 9 - 5)').click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
@ -943,10 +943,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|> line(end = [0.5, -14 + 0])
|> angledLine({ angle = 3 + 0, length = 32 + 0 }, %)
|> line(endAbsolute = [33, 11.5 + 0])
|> xLineTo(9 - 5, %)
|> yLineTo(-10.77, %, $a)
|> xLine(26.04, %)
|> yLine(21.14 + 0, %)
|> xLine(endAbsolute = 9 - 5)
|> yLine(endAbsolute = -10.77, tag = $a)
|> xLine(length = 26.04)
|> yLine(length = 21.14 + 0)
|> angledLineOfXLength({ angle = 181 + 0, length = 23.14 }, %)
|> angledLineOfYLength({ angle = -91, length = 19 + 0 }, %)
|> angledLineToX({ angle = 3 + 0, to = 26 }, %)
@ -972,7 +972,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await page.getByText('xLineTo(9 - 5, %)').click()
await page.getByText('xLine(endAbsolute = 9 - 5)').click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
@ -1056,7 +1056,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
ang = await u.getAngle(`[data-overlay-index="${6}"]`)
await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: 'yLine(21.14 + 0, %)',
codeToBeDeleted: 'yLine(length = 21.14 + 0)',
stdLibFnName: 'yLine',
ang: ang + 180,
locator: '[data-overlay-toolbar-index="6"]',
@ -1066,7 +1066,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
ang = await u.getAngle(`[data-overlay-index="${5}"]`)
await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: 'xLine(26.04, %)',
codeToBeDeleted: 'xLine(length = 26.04)',
stdLibFnName: 'xLine',
ang: ang + 180,
locator: '[data-overlay-toolbar-index="5"]',
@ -1076,7 +1076,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
ang = await u.getAngle(`[data-overlay-index="${4}"]`)
await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: 'yLineTo(-10.77, %, $a)',
codeToBeDeleted: 'yLine(endAbsolute = -10.77, tag = $a)',
stdLibFnName: 'yLineTo',
ang: ang + 180,
locator: '[data-overlay-toolbar-index="4"]',
@ -1086,7 +1086,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
ang = await u.getAngle(`[data-overlay-index="${3}"]`)
await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: 'xLineTo(9 - 5, %)',
codeToBeDeleted: 'xLine(endAbsolute = 9 - 5)',
stdLibFnName: 'xLineTo',
ang: ang + 180,
locator: '[data-overlay-toolbar-index="3"]',
@ -1151,10 +1151,10 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
const cases = [
'line(end = [22, 2], tag = $seg01)',
'angledLine([5, 23.03], %, $seg01)',
'xLine(23, %, $seg01)',
'yLine(-8, %, $seg01)',
'xLineTo(30, %, $seg01)',
'yLineTo(-4, %, $seg01)',
'xLine(length = 23, tag = $seg01)',
'yLine(length = -8, tag = $seg01)',
'xLine(endAbsolute = 30, tag = $seg01)',
'yLine(endAbsolute = -4, tag = $seg01)',
'angledLineOfXLength([3, 30], %, $seg01)',
'angledLineOfXLength({ angle = 3, length = 30 }, %, $seg01)',
'angledLineOfYLength([3, 1.5], %, $seg01)',
@ -1167,7 +1167,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
for (const doesHaveTagOutsideSketch of [true, false]) {
for (const lineOfInterest of cases) {
const isObj = lineOfInterest.includes('{ angle = 3,')
test(`${lineOfInterest.split('(')[0]}${isObj ? '-[obj-input]' : ''}${
test(`${lineOfInterest.split('=')[0]}${isObj ? '-[obj-input]' : ''}${
doesHaveTagOutsideSketch ? '-[tagOutsideSketch]' : ''
}`, async ({ page, editor, homePage }) => {
await page.addInitScript(
@ -1294,19 +1294,19 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
after: `line(end = [22.94, 2.01], tag = $seg01)`,
},
{
before: `xLine(23 + 0, %, $seg01)`,
before: `xLine(length = 23 + 0, tag = $seg01)`,
after: `line(end = [23, 0], tag = $seg01)`,
},
{
before: `yLine(-8 + 0, %, $seg01)`,
before: `yLine(length = -8 + 0, tag = $seg01)`,
after: `line(end = [0, -8], tag = $seg01)`,
},
{
before: `xLineTo(30 + 0, %, $seg01)`,
before: `xLine(endAbsolute = 30 + 0, tag = $seg01)`,
after: `line(end = [25, 0], tag = $seg01)`,
},
{
before: `yLineTo(-4 + 0, %, $seg01)`,
before: `yLine(endAbsolute = -4 + 0, tag = $seg01)`,
after: `line(end = [0, -10], tag = $seg01)`,
},
{
@ -1329,7 +1329,7 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
for (const { before, after } of cases) {
const isObj = before.includes('{ angle = 3')
test(`${before.split('(')[0]}${isObj ? '-[obj-input]' : ''}`, async ({
test(`${before.split('=')[0]}${isObj ? '-[obj-input]' : ''}`, async ({
page,
editor,
homePage,

View File

@ -75,7 +75,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|> xLine(${commonPoints.num1}, %)`)
|> xLine(length = ${commonPoints.num1})`)
await page.waitForTimeout(100)
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
@ -83,17 +83,17 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(${commonPoints.num1}, %)
|> yLine(${commonPoints.num1 + 0.01}, %)`)
|> xLine(length = ${commonPoints.num1})
|> yLine(length = ${commonPoints.num1 + 0.01})`)
await page.waitForTimeout(100)
await page.mouse.click(startXPx, 500 - PUR * 20)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(${commonPoints.num1}, %)
|> yLine(${commonPoints.num1 + 0.01}, %)
|> xLine(${commonPoints.num2 * -1}, %)`)
|> xLine(length = ${commonPoints.num1})
|> yLine(length = ${commonPoints.num1 + 0.01})
|> xLine(length = ${commonPoints.num2 * -1})`)
// deselect line tool
await page.getByRole('button', { name: 'line Line', exact: true }).click()
@ -158,7 +158,9 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
// check the same selection again by putting cursor in code first then selecting axis
await test.step(`Same selection but code selection then axis`, async () => {
await page.getByText(` |> xLine(${commonPoints.num2 * -1}, %)`).click()
await page
.getByText(` |> xLine(length = ${commonPoints.num2 * -1})`)
.click()
await page.keyboard.down('Shift')
await constrainButton.click()
await expect(absXButton).toBeDisabled()
@ -182,7 +184,9 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
process.platform === 'linux' ? 'Control' : 'Meta'
)
await page.waitForTimeout(100)
await page.getByText(` |> xLine(${commonPoints.num2 * -1}, %)`).click()
await page
.getByText(` |> xLine(length = ${commonPoints.num2 * -1})`)
.click()
await expect(page.locator('.cm-cursor')).toHaveCount(2)
await page.waitForTimeout(500)
@ -537,9 +541,9 @@ profile003 = startProfileAt([40.16, -120.48], sketch006)
|> line(end = [7.13, 4 + 0])
|> angledLine({ angle = 3 + 0, length = 3.14 + 0 }, %)
|> line(endAbsolute = [20.14 + 0, -0.14 + 0])
|> xLineTo(29 + 0, %)
|> yLine(-3.14 + 0, %, $a)
|> xLine(1.63, %)
|> xLine(endAbsolute = 29 + 0)
|> yLine(length = -3.14 + 0, tag = $a)
|> xLine(length = 1.63)
|> angledLineOfXLength({ angle = 3 + 0, length = 3.14 }, %)
|> angledLineOfYLength({ angle = 30, length = 3 + 0 }, %)
|> angledLineToX({ angle = 22.14 + 0, to = 12 }, %)

View File

@ -52,14 +52,14 @@ armThick = 0.5
totalLen = 9.5
part001 = startSketchOn('-XZ')
|> startProfileAt([0, 0], %)
|> yLine(baseHeight, %)
|> xLine(baseLen, %)
|> yLine(length = baseHeight)
|> xLine(length = baseLen)
|> angledLineToY({
angle = topAng,
to = totalHeightHalf,
}, %, $seg04)
|> xLineTo(totalLen, %, $seg03)
|> yLine(-armThick, %, $seg01)
|> xLine(endAbsolute = totalLen, tag = $seg03)
|> yLine(length = -armThick, tag = $seg01)
|> angledLineThatIntersects({
angle = HALF_TURN,
offset = -armThick,
@ -70,15 +70,15 @@ part001 = startSketchOn('-XZ')
angle = -bottomAng,
to = -totalHeightHalf - armThick,
}, %, $seg02)
|> xLineTo(segEndX(seg03) + 0, %)
|> yLine(-segLen(seg01), %)
|> xLine(endAbsolute = segEndX(seg03) + 0)
|> yLine(length = -segLen(seg01))
|> angledLineThatIntersects({
angle = HALF_TURN,
offset = -armThick,
intersectTag = seg02
}, %)
|> angledLineToY([segAng(seg02) + 180, -baseHeight], %)
|> xLineTo(ZERO, %)
|> xLine(endAbsolute = ZERO)
|> close()
|> extrude(length = 4)`
)

View File

@ -91,7 +91,7 @@
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages ./rust/kcl-language-server",
"fetch:wasm": "./scripts/get-latest-wasm-bundle.sh",
"fetch:wasm:windows": "./scripts/get-latest-wasm-bundle.ps1",
"fetch:samples": "rm -rf public/kcl-samples* && curl -L -o public/kcl-samples.zip https://github.com/KittyCAD/kcl-samples/archive/refs/heads/next.zip && unzip -o public/kcl-samples.zip -d public && mv public/kcl-samples-* public/kcl-samples",
"fetch:samples": "rm -rf public/kcl-samples* && curl -L -o public/kcl-samples.zip https://github.com/KittyCAD/kcl-samples/archive/refs/heads/achalmers/kw-args-xylineto.zip && unzip -o public/kcl-samples.zip -d public && mv public/kcl-samples-* public/kcl-samples",
"build:wasm-dev": "yarn wasm-prep && (cd rust && wasm-pack build kcl-wasm-lib --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt",
"build:wasm:nocopy": "yarn wasm-prep && cd rust && wasm-pack build kcl-wasm-lib --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings",
"build:wasm": "yarn build:wasm:nocopy && cp rust/kcl-wasm-lib/pkg/kcl_wasm_lib_bg.wasm public && yarn fmt",

View File

@ -29,6 +29,7 @@ export const kclHighlight = styleTags({
'ObjectProperty/PropertyName': t.definition(t.propertyName),
'LabeledArgument/ArgumentLabel': t.definition(t.propertyName),
TagDeclarator: t.tagName,
PrimitiveType: t.typeName,
'( )': t.paren,
'{ }': t.brace,
'[ ]': t.bracket,

View File

@ -77,7 +77,7 @@ ArgumentList { "(" commaSep<LabeledArgument | expression> ")" }
type[@isGroup=Type] {
@specialize[@name=PrimitiveType]<
identifier,
"string" | "number" | "bool" | "sketch" | "sketch_surface" | "solid"
"bool" | "number" | "string" | "tag" | "Sketch" | "SketchSurface" | "Solid" | "Plane"
> |
ArrayType { type !member "[" "]" } |
ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" }

View File

@ -1,7 +1,2 @@
.vscode
.idea
.DS_Store
screenshots/main.kcl
step/main.kcl
/project.toml
project.toml
thumbnail.png

View File

@ -14,11 +14,11 @@ fn dividerSketch(plane) {
|> tangentialArcTo([-16.6, profileStartY(%) - 15.52], %)
|> tangentialArcTo([-18.38, profileStartY(%) - 18.63], %)
|> line(end = [-1.25, -2.6])
|> xLine(6.04, %)
|> xLine(length = 6.04)
|> line(end = [6.68, 7.87])
|> tangentialArcTo([10.06, profileStartY(%) - 12.69], %)
|> line(end = [7.28, -8.47])
|> xLine(5.98, %)
|> xLine(length = 5.98)
|> line(end = [-1.3, 3.01])
|> tangentialArcTo([22.45, profileStartY(%) - 2.84], %)
|> tangentialArcTo([25.08, profileStartY(%) + 6.42], %)
@ -106,7 +106,7 @@ export fn backSlats(plane, length) {
fn armRestPath(plane) {
sketch005 = startSketchOn(plane)
|> startProfileAt([20, 33], %)
|> xLine(-20, %)
|> xLine(length = -20)
|> arc({
angleStart = 90,
angleEnd = 180,
@ -118,10 +118,10 @@ fn armRestPath(plane) {
fn armRestProfile(plane, offset) {
sketch006 = startSketchOn(plane)
|> startProfileAt([offset, 32.4], %)
|> xLine(1.3, %)
|> xLine(length = 1.3)
|> line(end = [0.3, 0.6])
|> line(end = [-0.3, 0.6])
|> xLine(-2.6, %)
|> xLine(length = -2.6)
|> line(end = [-0.3, -0.6])
|> line(end = [0.3, -0.6])
|> close()

View File

@ -22,33 +22,33 @@ fn rail8020(originStart, railHeight, railLength) {
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> xLine(0.1 * railHeight, %)
|> xLine(length = 0.1 * railHeight)
|> arc({
angleStart = 180,
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> xLine(0.06 * railHeight, %, $edge1)
|> yLine(0.087 * railHeight, %, $edge2)
|> xLine(-0.183 * railHeight, %, $edge3)
|> xLine(length = 0.06 * railHeight, tag = $edge1)
|> yLine(length = 0.087 * railHeight, tag = $edge2)
|> xLine(length = -0.183 * railHeight, tag = $edge3)
|> angledLineToY({
angle = 45,
to = (1 - 0.356) / 2 * railHeight + originStart[1]
}, %, $edge4)
|> xLine(0.232 * railHeight, %, $edge5)
|> xLine(length = 0.232 * railHeight, tag = $edge5)
|> angledLineToY({
angle = -45,
to = 0.087 * railHeight + originStart[1]
}, %, $edge6)
|> xLine(-0.183 * railHeight, %, $edge7)
|> yLine(-0.087 * railHeight, %, $edge8)
|> xLine(0.06 * railHeight, %)
|> xLine(length = -0.183 * railHeight, tag = $edge7)
|> yLine(length = -0.087 * railHeight, tag = $edge8)
|> xLine(length = 0.06 * railHeight)
|> arc({
angleStart = 180,
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> xLine(0.1 * railHeight, %)
|> xLine(length = 0.1 * railHeight)
|> arc({
angleStart = 180,
angleEnd = 0,
@ -66,33 +66,33 @@ fn rail8020(originStart, railHeight, railLength) {
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> yLine(0.1 * railHeight, %)
|> yLine(length = 0.1 * railHeight)
|> arc({
angleStart = 270,
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> yLine(0.06 * railHeight, %, $edge9)
|> xLine(-0.087 * railHeight, %, $edge10)
|> yLine(-0.183 * railHeight, %, $edge11) // edge11
|> yLine(length = 0.06 * railHeight, tag = $edge9)
|> xLine(length = -0.087 * railHeight, tag = $edge10)
|> yLine(length = -0.183 * railHeight, tag = $edge11) // edge11
|> angledLineToX({
angle = 135,
to = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[0]
}, %, $edge12) // edge12
|> yLine(0.232 * railHeight, %, $edge13) // 13
|> yLine(length = 0.232 * railHeight, tag = $edge13) // 13
|> angledLineToX({
angle = 45,
to = (1 - 0.087) * railHeight + originStart[0]
}, %, $edge14) // 14
|> yLine(-0.183 * railHeight, %, $edge15) // 15
|> xLine(0.087 * railHeight, %, $edge16)
|> yLine(0.06 * railHeight, %)
|> yLine(length = -0.183 * railHeight, tag = $edge15) // 15
|> xLine(length = 0.087 * railHeight, tag = $edge16)
|> yLine(length = 0.06 * railHeight)
|> arc({
angleStart = 270,
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> yLine(0.1 * railHeight, %)
|> yLine(length = 0.1 * railHeight)
|> arc({
angleStart = 270,
angleEnd = 90,
@ -110,33 +110,33 @@ fn rail8020(originStart, railHeight, railLength) {
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> xLine(-0.1 * railHeight, %)
|> xLine(length = -0.1 * railHeight)
|> arc({
angleStart = 0,
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> xLine(-0.06 * railHeight, %, $edge17)
|> yLine(-0.087 * railHeight, %, $edge18)
|> xLine(0.183 * railHeight, %, $edge19)
|> xLine(length = -0.06 * railHeight, tag = $edge17)
|> yLine(length = -0.087 * railHeight, tag = $edge18)
|> xLine(length = 0.183 * railHeight, tag = $edge19)
|> angledLineToY({
angle = 45,
to = ((1 - 0.356) / 2 + 0.356) * railHeight + originStart[1]
}, %, $edge20)
|> xLine(-0.232 * railHeight, %, $edge21)
|> xLine(length = -0.232 * railHeight, tag = $edge21)
|> angledLineToY({
angle = 135,
to = (1 - 0.087) * railHeight + originStart[1]
}, %, $edge22)
|> xLine(0.183 * railHeight, %, $edge23)
|> yLine(0.087 * railHeight, %, $edge24)
|> xLine(-0.06 * railHeight, %)
|> xLine(length = 0.183 * railHeight, tag = $edge23)
|> yLine(length = 0.087 * railHeight, tag = $edge24)
|> xLine(length = -0.06 * railHeight)
|> arc({
angleStart = 0,
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> xLine(-0.1 * railHeight, %)
|> xLine(length = -0.1 * railHeight)
|> arc({
angleStart = 0,
angleEnd = -180,
@ -154,33 +154,33 @@ fn rail8020(originStart, railHeight, railLength) {
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> yLine(-0.1 * railHeight, %)
|> yLine(length = -0.1 * railHeight)
|> arc({
angleStart = 90,
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> yLine(-0.06 * railHeight, %, $edge25)
|> xLine(0.087 * railHeight, %, $edge26)
|> yLine(0.183 * railHeight, %, $edge27)
|> yLine(length = -0.06 * railHeight, tag = $edge25)
|> xLine(length = 0.087 * railHeight, tag = $edge26)
|> yLine(length = 0.183 * railHeight, tag = $edge27)
|> angledLineToX({
angle = 135,
to = (1 - 0.356) / 2 * railHeight + originStart[0]
}, %, $edge28)
|> yLine(-0.232 * railHeight, %, $edge29)
|> yLine(length = -0.232 * railHeight, tag = $edge29)
|> angledLineToX({
angle = 45,
to = 0.087 * railHeight + originStart[0]
}, %, $edge30)
|> yLine(0.183 * railHeight, %, $edge31)
|> xLine(-0.087 * railHeight, %, $edge32)
|> yLine(-0.06 * railHeight, %)
|> yLine(length = 0.183 * railHeight, tag = $edge31)
|> xLine(length = -0.087 * railHeight, tag = $edge32)
|> yLine(length = -0.06 * railHeight)
|> arc({
angleStart = 90,
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> yLine(-0.1 * railHeight, %)
|> yLine(length = -0.1 * railHeight)
|> arc({
angleStart = 90,
angleEnd = -90,

View File

@ -8,8 +8,6 @@ The samples can be browsed in our documentation at <https://zoo.dev/docs/kcl-sam
## Guidelines for adding samples
Merge PRs to the `next` branch, not main. When we release Modeling App, we will merge this repo's `next` into `main`. This way, `main` is always compatible with the latest ZMA release.
KCL samples conform to a set of style guidelines to ensure consistency and readability.
1. **File Naming:** Name your KCL files descriptively and concisely, using hyphens to separate words (e.g., flange.kcl, ball-bearing.kcl).
@ -57,18 +55,18 @@ When you submit a PR to add or modify KCL samples, images and STEP files will be
[![food-service-spatula](screenshots/food-service-spatula.png)](food-service-spatula/main.kcl)
#### [french-press](french-press/main.kcl) ([step](step/french-press.step)) ([screenshot](screenshots/french-press.png))
[![french-press](screenshots/french-press.png)](french-press/main.kcl)
#### [gear-rack](gear-rack/main.kcl) ([step](step/gear-rack.step)) ([screenshot](screenshots/gear-rack.png))
[![gear-rack](screenshots/gear-rack.png)](gear-rack/main.kcl)
#### [gear](gear/main.kcl) ([step](step/gear.step)) ([screenshot](screenshots/gear.png))
[![gear](screenshots/gear.png)](gear/main.kcl)
#### [gridfinity-baseplate-magnets](gridfinity-baseplate-magnets/main.kcl) ([step](step/gridfinity-baseplate-magnets.step)) ([screenshot](screenshots/gridfinity-baseplate-magnets.png))
[![gridfinity-baseplate-magnets](screenshots/gridfinity-baseplate-magnets.png)](gridfinity-baseplate-magnets/main.kcl)
#### [gear-rack](gear-rack/main.kcl) ([step](step/gear-rack.step)) ([screenshot](screenshots/gear-rack.png))
[![gear-rack](screenshots/gear-rack.png)](gear-rack/main.kcl)
#### [gridfinity-baseplate](gridfinity-baseplate/main.kcl) ([step](step/gridfinity-baseplate.step)) ([screenshot](screenshots/gridfinity-baseplate.png))
[![gridfinity-baseplate](screenshots/gridfinity-baseplate.png)](gridfinity-baseplate/main.kcl)
#### [gridfinity-bins-stacking-lip](gridfinity-bins-stacking-lip/main.kcl) ([step](step/gridfinity-bins-stacking-lip.step)) ([screenshot](screenshots/gridfinity-bins-stacking-lip.png))
[![gridfinity-bins-stacking-lip](screenshots/gridfinity-bins-stacking-lip.png)](gridfinity-bins-stacking-lip/main.kcl)
#### [gridfinity-baseplate-magnets](gridfinity-baseplate-magnets/main.kcl) ([step](step/gridfinity-baseplate-magnets.step)) ([screenshot](screenshots/gridfinity-baseplate-magnets.png))
[![gridfinity-baseplate-magnets](screenshots/gridfinity-baseplate-magnets.png)](gridfinity-baseplate-magnets/main.kcl)
#### [gridfinity-bins](gridfinity-bins/main.kcl) ([step](step/gridfinity-bins.step)) ([screenshot](screenshots/gridfinity-bins.png))
[![gridfinity-bins](screenshots/gridfinity-bins.png)](gridfinity-bins/main.kcl)
#### [gridfinity-bins-stacking-lip](gridfinity-bins-stacking-lip/main.kcl) ([step](step/gridfinity-bins-stacking-lip.step)) ([screenshot](screenshots/gridfinity-bins-stacking-lip.png))
[![gridfinity-bins-stacking-lip](screenshots/gridfinity-bins-stacking-lip.png)](gridfinity-bins-stacking-lip/main.kcl)
#### [hex-nut](hex-nut/main.kcl) ([step](step/hex-nut.step)) ([screenshot](screenshots/hex-nut.png))
[![hex-nut](screenshots/hex-nut.png)](hex-nut/main.kcl)
#### [i-beam](i-beam/main.kcl) ([step](step/i-beam.step)) ([screenshot](screenshots/i-beam.png))
@ -81,12 +79,12 @@ When you submit a PR to add or modify KCL samples, images and STEP files will be
[![mounting-plate](screenshots/mounting-plate.png)](mounting-plate/main.kcl)
#### [multi-axis-robot](multi-axis-robot/main.kcl) ([step](step/multi-axis-robot.step)) ([screenshot](screenshots/multi-axis-robot.png))
[![multi-axis-robot](screenshots/multi-axis-robot.png)](multi-axis-robot/main.kcl)
#### [pipe](pipe/main.kcl) ([step](step/pipe.step)) ([screenshot](screenshots/pipe.png))
[![pipe](screenshots/pipe.png)](pipe/main.kcl)
#### [pipe-flange-assembly](pipe-flange-assembly/main.kcl) ([step](step/pipe-flange-assembly.step)) ([screenshot](screenshots/pipe-flange-assembly.png))
[![pipe-flange-assembly](screenshots/pipe-flange-assembly.png)](pipe-flange-assembly/main.kcl)
#### [pipe-with-bend](pipe-with-bend/main.kcl) ([step](step/pipe-with-bend.step)) ([screenshot](screenshots/pipe-with-bend.png))
[![pipe-with-bend](screenshots/pipe-with-bend.png)](pipe-with-bend/main.kcl)
#### [pipe](pipe/main.kcl) ([step](step/pipe.step)) ([screenshot](screenshots/pipe.png))
[![pipe](screenshots/pipe.png)](pipe/main.kcl)
#### [poopy-shoe](poopy-shoe/main.kcl) ([step](step/poopy-shoe.step)) ([screenshot](screenshots/poopy-shoe.png))
[![poopy-shoe](screenshots/poopy-shoe.png)](poopy-shoe/main.kcl)
#### [router-template-cross-bar](router-template-cross-bar/main.kcl) ([step](step/router-template-cross-bar.step)) ([screenshot](screenshots/router-template-cross-bar.png))
@ -101,3 +99,4 @@ When you submit a PR to add or modify KCL samples, images and STEP files will be
[![walkie-talkie](screenshots/walkie-talkie.png)](walkie-talkie/main.kcl)
#### [washer](washer/main.kcl) ([step](step/washer.step)) ([screenshot](screenshots/washer.png))
[![washer](screenshots/washer.png)](washer/main.kcl)

View File

@ -81,9 +81,9 @@ spacers = extrude(spacerSketch, length = -spacerLength)
|> appearance(color = "#dbcd70", roughness = 90, metalness = 90)
rotorSlottedSketch = startSketchOn(rotor, 'START')
|> startProfileAt([2.17, 2.56], %)
|> xLine(0.12, %)
|> yLine(2.56, %)
|> xLine(-0.12, %)
|> xLine(length = 0.12)
|> yLine(length = 2.56)
|> xLine(length = -0.12)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternCircular2d(
@ -96,9 +96,9 @@ rotorSlotted = extrude(rotorSlottedSketch, length = -rotorSinglePlateThickness /
secondRotorSlottedSketch = startSketchOn(secondRotor, 'END')
|> startProfileAt([-2.17, 2.56], %)
|> xLine(-0.12, %)
|> yLine(2.56, %)
|> xLine(0.12, %)
|> xLine(length = -0.12)
|> yLine(length = 2.56)
|> xLine(length = 0.12)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternCircular2d(

View File

@ -65,13 +65,13 @@ lugHoles = startSketchOn(lugBase, 'END')
// Add detail to the wheel center by revolving curved edge profiles
wheelCenterInner = startSketchOn('XY')
|> startProfileAt([(lugSpacing - 1.5) / 2, 0], %)
|> yLine(-wheelWidth / 10 - (wheelWidth / 20), %)
|> yLine(length = -wheelWidth / 10 - (wheelWidth / 20))
|> bezierCurve({
to = [-0.4, 0.3],
control1 = [-0.3, 0],
control2 = [0, 0.3]
}, %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> revolve({ axis = 'y' }, %)
@ -79,13 +79,13 @@ wheelCenterInner = startSketchOn('XY')
wheelCenterOuter = startSketchOn('XY')
|> startProfileAt([(lugSpacing + 1.5) / 2, 0], %)
|> yLine(-wheelWidth / 10 - (wheelWidth / 20), %)
|> yLine(length = -wheelWidth / 10 - (wheelWidth / 20))
|> bezierCurve({
to = [0.4, -0.1],
control1 = [0.3, 0],
control2 = [0.2, -0.3]
}, %)
|> yLineTo(-wheelWidth / 20, %)
|> yLine(endAbsolute = -wheelWidth / 20)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> revolve({ axis = 'y' }, %)
@ -120,7 +120,7 @@ fn spoke(spokeGap, spokeAngle, spokeThickness) {
offset / 1.5
]
}, %)
|> yLine(-wheelWidth / 15, %)
|> yLine(length = -wheelWidth / 15)
|> bezierCurve({
to = [
-(wheelDiameter - lugSpacing - 2.9) / 2,
@ -160,38 +160,38 @@ startSketchOn('XY')
wheelDiameter / 2,
-wheelWidth + backSpacing + offset
], %)
|> yLine(wheelWidth * 0.25, %)
|> yLine(length = wheelWidth * 0.25)
|> line(end = [-wheelWidth * 0.02, wheelWidth * 0.02])
|> yLine(wheelWidth * 0.25, %)
|> yLine(length = wheelWidth * 0.25)
|> line(end = [wheelWidth * 0.02, wheelWidth * 0.02])
|> yLineTo(backSpacing + offset, %)
|> yLine(endAbsolute = backSpacing + offset)
|> line(end = [wheelWidth * 0.05, wheelWidth * .01])
|> yLine(wheelWidth * 0.05, %)
|> xLine(-wheelWidth * 0.03, %)
|> yLine(-wheelWidth * 0.02, %)
|> yLine(length = wheelWidth * 0.05)
|> xLine(length = -wheelWidth * 0.03)
|> yLine(length = -wheelWidth * 0.02)
|> line(end = [-wheelWidth * 0.05, -wheelWidth * 0.01])
|> yLine(-backSpacing * 0.7, %)
|> yLine(length = -backSpacing * 0.7)
|> line(end = [
-wheelDiameter * 0.01,
-wheelWidth * 0.02
])
|> yLineTo(offset - 0.2, %)
|> yLine(endAbsolute = offset - 0.2)
|> line(end = [
-wheelDiameter * 0.03,
-wheelWidth * 0.02
])
|> yLine(-wheelWidth * 0.02, %)
|> yLine(length = -wheelWidth * 0.02)
|> line(end = [
wheelDiameter * 0.03,
-wheelWidth * 0.1
])
|> yLine(-wheelWidth * 0.05, %)
|> yLine(length = -wheelWidth * 0.05)
|> line(end = [wheelWidth * 0.02, -wheelWidth * 0.02])
|> yLineTo(-wheelWidth + backSpacing + offset - 0.28, %)
|> yLine(endAbsolute = -wheelWidth + backSpacing + offset - 0.28)
|> line(end = [wheelWidth * 0.05, -wheelWidth * 0.01])
|> yLine(-wheelWidth * 0.02, %)
|> xLine(wheelWidth * 0.03, %)
|> yLine(wheelWidth * 0.05, %)
|> yLine(length = -wheelWidth * 0.02)
|> xLine(length = wheelWidth * 0.03)
|> yLine(length = wheelWidth * 0.05)
|> close()
|> revolve({ axis = 'y' }, %)
|> appearance(color = "#ffffff", metalness = 0, roughness = 0)

View File

@ -26,13 +26,13 @@ fn lug(plane, length, diameter) {
lugSketch = startSketchOn(customPlane)
|> startProfileAt([0 + diameter / 2, 0], %)
|> angledLineOfYLength({ angle = 70, length = lugHeadLength }, %)
|> xLineTo(lugDiameter / 2, %)
|> yLineTo(lugLength, %)
|> xLine(endAbsolute = lugDiameter / 2)
|> yLine(endAbsolute = lugLength)
|> tangentialArc({ offset = 90, radius = 3 * mm() }, %)
|> xLineTo(0 + .001, %, $c1)
|> yLineTo(lugThreadDepth, %)
|> xLineTo(lugThreadDiameter, %)
|> yLineTo(0, %)
|> xLine(endAbsolute = 0 + .001, tag = $c1)
|> yLine(endAbsolute = lugThreadDepth)
|> xLine(endAbsolute = lugThreadDiameter)
|> yLine(endAbsolute = 0)
|> close()
|> revolve({ axis = "Y" }, %)
|> appearance(color = "#dbcd70", roughness = 90, metalness = 90)

View File

@ -68,19 +68,19 @@ primaryTube(3, 25.2, 5, 5, 3)
// Create the mounting flange for the header
flangeSketch = startSketchOn('XY')
|> startProfileAt([3 + 1.3, -1.25], %)
|> xLine(-2.6, %, $seg01)
|> xLine(length = -2.6, tag = $seg01)
|> tangentialArc({ radius = .3, offset = -40 }, %)
|> tangentialArc({ radius = .9, offset = 80 }, %)
|> tangentialArc({ radius = .3, offset = -40 }, %)
|> xLine(-1.4, %, $seg03)
|> yLine(segLen(seg01), %, $seg04)
|> xLine(3.1, %, $seg05)
|> xLine(length = -1.4, tag = $seg03)
|> yLine(length = segLen(seg01), tag = $seg04)
|> xLine(length = 3.1, tag = $seg05)
|> tangentialArc({ radius = .3, offset = -40 }, %)
|> tangentialArc({ radius = 1.5, offset = 80 }, %)
|> tangentialArc({ radius = .3, offset = -40 }, %)
|> xLine(segLen(seg05), %, $seg07)
|> yLineTo(profileStartY(%), %, $seg08)
|> xLine(-segLen(seg03), %, $seg09)
|> xLine(length = segLen(seg05), tag = $seg07)
|> yLine(endAbsolute = profileStartY(%), tag = $seg08)
|> xLine(length = -segLen(seg03), tag = $seg09)
|> tangentialArc({ radius = .3, offset = -40 }, %)
|> tangentialArc({ radius = .9, offset = 80 }, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)

View File

@ -49,7 +49,7 @@ sketch000 = startSketchOn('XY')
// create a profile of the flipper
flipperProfile = startProfileAt([-flipperLength, -32.0], sketch000)
|> line(end = [flipperLength, 2.0])
|> yLine(60.0, %, $backEdge)
|> yLine(length = 60.0, tag = $backEdge)
|> line(end = [-flipperLength, 2.0])
|> arc({
angleEnd = 196.912390,
@ -96,7 +96,7 @@ handleProfile = startProfileAt([0.0, flipperThickness], sketch001)
|> line(end = [-1.710101, 4.698463])
|> line(end = [-141.995517, -51.682142], tag = $handleTopEdge)
|> line(end = [-36.139148, -36.139148])
|> xLine(7.071068, %)
|> xLine(length = 7.071068)
|> close()
// create an extrusion extrude001
@ -127,25 +127,25 @@ sketch002 = startSketchOn(handlePlane)
// create a profile of the grip
gripProfile = startProfileAt([-26.806746, -10.0], sketch002)
|> xLine(gripWidth - (2 * gripFilletRadius), %)
|> xLine(length = gripWidth - (2 * gripFilletRadius))
|> arc({
angleStart = -90.0,
angleEnd = 0.0,
radius = gripFilletRadius
}, %)
|> yLine(gripHeight - (2 * gripFilletRadius), %)
|> yLine(length = gripHeight - (2 * gripFilletRadius))
|> arc({
angleStart = 0.0,
angleEnd = 90.0,
radius = gripFilletRadius
}, %)
|> xLine(-(gripWidth - (2 * gripFilletRadius)), %)
|> xLine(length = -(gripWidth - (2 * gripFilletRadius)))
|> arc({
angleStart = 90.0,
angleEnd = 180.0,
radius = gripFilletRadius
}, %)
|> yLine(-(gripHeight - (2 * gripFilletRadius)), %, $gripEdgeTop)
|> yLine(length = -(gripHeight - (2 * gripFilletRadius)), tag = $gripEdgeTop)
|> arc({
angleStart = 180.0,
angleEnd = 270.0,

View File

@ -38,8 +38,8 @@ plane001 = {
// Cross section of the metal supports
sketch002 = startSketchOn(plane001)
|> startProfileAt([carafeDiameter / 2, 5.7], %)
|> xLine(0.1, %)
|> yLine(-5.2, %, $edge1)
|> xLine(length = 0.1)
|> yLine(length = -5.2, tag = $edge1)
|> arc({
angleStart = 180,
angleEnd = 205,
@ -57,9 +57,9 @@ sketch002 = startSketchOn(plane001)
angleEnd = 90,
radius = 0.5
}, %)
|> xLineTo(0.1, %, $edgeLen)
|> yLine(0.1, %)
|> xLine(segLen(edgeLen) + 0.035, %, $edge4)
|> xLine(endAbsolute = 0.1, tag = $edgeLen)
|> yLine(length = 0.1)
|> xLine(length = segLen(edgeLen) + 0.035, tag = $edge4)
|> arc({
angleStart = 90,
angleEnd = 60,
@ -105,7 +105,7 @@ extrude001 = extrude(sketch003, length = 0.050)
sketch004 = startSketchOn(extrude001, 'END')
|> startProfileAt([0.3, 0.17], %)
|> yLine(1.2, %)
|> yLine(length = 1.2)
|> arc({
angleStart = 90,
angleEnd = -30,
@ -125,14 +125,14 @@ extrude002 = extrude(sketch004, length = -0.050)
// Filter screen
sketch005 = startSketchOn('XZ')
|> startProfileAt([0.15, 1.11], %)
|> xLineTo(carafeDiameter / 2 - 0.2, %)
|> xLine(endAbsolute = carafeDiameter / 2 - 0.2)
|> angledLineToX({
angle = 30,
to = carafeDiameter / 2 - 0.07
}, %, $seg1)
|> angledLine({ angle = -60, length = 0.050 }, %)
|> angledLine({ angle = 30, length = -segLen(seg1) }, %)
|> xLineTo(0.15, %)
|> xLine(endAbsolute = 0.15)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> revolve({ axis = 'y' }, %)
@ -142,9 +142,9 @@ sketch006 = startSketchOn('XZ')
|> startProfileAt([0.1, 1], %)
|> line(end = [0.1, 0])
|> angledLineToX({ angle = 10, to = 0.05 }, %)
|> yLine(10, %)
|> yLine(length = 10)
|> line(end = [0.6, 0])
|> yLine(-.05, %)
|> yLine(length = -.05)
|> tangentialArc({ radius = 0.6, offset = -90 }, %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -198,10 +198,10 @@ extrude006 = extrude(sketch010, length = carafeHeight)
// Draw and revolve the lid
sketch011 = startSketchOn('XZ')
|> startProfileAt([0.2, carafeHeight - 0.7], %)
|> xLine(carafeDiameter / 2 - 0.3, %)
|> yLine(0.7, %)
|> xLine(0.3, %)
|> yLine(0.4, %)
|> xLine(length = carafeDiameter / 2 - 0.3)
|> yLine(length = 0.7)
|> xLine(length = 0.3)
|> yLine(length = 0.4)
|> line(end = [-0.02, 0.02])
|> bezierCurve({
to = [-carafeDiameter / 2 - 0.1, 1],

View File

@ -95,9 +95,9 @@ keyWay = startSketchOn(body, 'END')
holeRadius * cos(startAngle),
holeRadius * sin(startAngle)
], %)
|> xLine(keywayDepth, %)
|> yLine(-keywayWidth, %)
|> xLine(-keywayDepth, %)
|> xLine(length = keywayDepth)
|> yLine(length = -keywayWidth)
|> xLine(length = -keywayDepth)
|> arc({
angleEnd = 180,
angleStart = -1 * 180 / PI * startAngle + 360,

View File

@ -1,66 +0,0 @@
const fs = require("fs");
const path = require("path");
const FILE_EXTENSION = ".kcl";
const MANIFEST_FILE = "manifest.json";
const COMMENT_PREFIX = "//";
// Function to read and parse .kcl files
const getKclMetadata = (projectPath, files) => {
const primaryKclFile = files.find((file) => file.includes("main.kcl")) ?? files.sort()[0];
const fullPathToPrimaryKcl = path.join(projectPath, primaryKclFile);
const content = fs.readFileSync(fullPathToPrimaryKcl, "utf-8");
const lines = content.split("\n");
if (lines.length < 2) {
return null;
}
const title = lines[0].replace(COMMENT_PREFIX, "").trim();
const description = lines[1].replace(COMMENT_PREFIX, "").trim();
return {
file: primaryKclFile,
// Assumed to ALWAYS be 1 level deep. That's the current practice.
pathFromProjectDirectoryToFirstFile: fullPathToPrimaryKcl.split('/').splice(-2).join('/'),
// This was added so that multiple file project samples do not load in
// the web app through the manifest.
multipleFiles: files.length > 1,
title,
description,
};
};
// Function to scan the directory and generate the manifest.json
const generateManifest = (dir) => {
const projectDirectories = fs.readdirSync(dir);
const manifest = [];
projectDirectories.forEach((file) => {
const projectPath = path.join(dir, file);
const stattedDir = fs.statSync(projectPath);
if (stattedDir.isDirectory()) {
const files = fs
.readdirSync(projectPath)
.filter((f) => f.endsWith(FILE_EXTENSION));
if (files.length === 0) {
return;
}
const metadata = getKclMetadata(projectPath, files);
if (metadata) {
manifest.push(metadata);
}
}
});
// Write the manifest.json
const outputPath = path.join(dir, MANIFEST_FILE);
fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2));
console.log(`Manifest of ${manifest.length} items written to ${outputPath}`);
};
// Run the script
console.log(`Generating ${MANIFEST_FILE}...`);
const projectDir = path.resolve(__dirname); // Set project root directory
generateManifest(projectDir);

View File

@ -25,9 +25,9 @@ height = firstStep + secondStep + thirdStep
fn face(plane) {
faceSketch = startSketchOn(plane)
|> startProfileAt([0, 0], %)
|> yLine(height, %)
|> yLine(length = height)
|> angledLineOfYLength({ angle = -45, length = thirdStep }, %)
|> yLine(-secondStep, %)
|> yLine(length = -secondStep)
|> angledLineOfYLength({ angle = -45, length = firstStep }, %)
|> close()
return faceSketch
@ -100,38 +100,38 @@ fn magnetCenterCutout(plane) {
firstStep + thirdStep,
2 * magOuterDiam
], %)
|> xLine(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2), %)
|> xLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> arc({
angleStart = 90.0,
angleEnd = 0.0,
radius = magOuterDiam / 2
}, %)
|> yLine(-(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)), %)
|> xLine(binLength - (4 * magOuterDiam), %)
|> yLine(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2), %)
|> yLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> xLine(length = binLength - (4 * magOuterDiam))
|> yLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> arc({
angleStart = 180.0,
angleEnd = 90.0,
radius = magOuterDiam / 2
}, %)
|> xLine(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2), %)
|> yLine(binLength - (4 * magOuterDiam), %)
|> xLine(-(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)), %)
|> xLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> yLine(length = binLength - (4 * magOuterDiam))
|> xLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> arc({
angleStart = 270.0,
angleEnd = 180.0,
radius = magOuterDiam / 2
}, %)
|> yLine(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2), %)
|> xLine(-(binLength - (4 * magOuterDiam)), %, $line012)
|> yLine(-(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)), %)
|> yLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> xLine(length = -(binLength - (4 * magOuterDiam)), tag = $line012)
|> yLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> arc({
angleStart = 360.0,
angleEnd = 270.0,
radius = magOuterDiam / 2
}, %)
|> xLine(-(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)), %)
|> yLine(-(binLength - (4 * magOuterDiam)), %)
|> xLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> yLine(length = -(binLength - (4 * magOuterDiam)))
|> close()
return magnetSketch
}
@ -140,9 +140,9 @@ fn magnetCenterCutout(plane) {
fn magnetBase(plane) {
magnetBaseSketch = startSketchOn(plane)
|> startProfileAt([0, 0], %)
|> xLine(binLength, %, $line001)
|> yLine(binLength, %, $line002)
|> xLineTo(profileStartX(%), %, $line003)
|> xLine(length = binLength, tag = $line001)
|> yLine(length = binLength, tag = $line002)
|> xLine(endAbsolute = profileStartX(%), tag = $line003)
|> close(tag = $line004)
|> hole(magnetCenterCutout(plane), %)
return magnetBaseSketch

View File

@ -22,9 +22,9 @@ height = firstStep + secondStep + thirdStep
fn face(plane) {
faceSketch = startSketchOn(plane)
|> startProfileAt([0, 0], %)
|> yLine(height, %)
|> yLine(length = height)
|> angledLineOfYLength({ angle = -45, length = thirdStep }, %)
|> yLine(-secondStep, %)
|> yLine(length = -secondStep)
|> angledLineOfYLength({ angle = -45, length = firstStep }, %)
|> close()
return faceSketch

View File

@ -37,10 +37,10 @@ lipHeight = lipStep1 + lipStep2 + lipStep3 + lipStep4 + lipStep5
fn face(plane) {
faceSketch = startSketchOn(plane)
|> startProfileAt([binBaseLength + binTol, 0], %)
|> yLine(height, %)
|> xLine(-binBaseLength, %)
|> yLine(length = height)
|> xLine(length = -binBaseLength)
|> angledLineOfYLength({ angle = -45, length = thirdStep }, %)
|> yLine(-secondStep, %)
|> yLine(length = -secondStep)
|> angledLineOfYLength({ angle = -45, length = firstStep }, %)
|> close()
return faceSketch
@ -98,7 +98,7 @@ singleBinFill = startSketchOn("XY")
], %)
|> line(end = [binLength - (binBaseLength * 2), 0], tag = $line000)
|> line(end = [0, binLength - (binBaseLength * 2)], tag = $line001)
|> xLineTo(profileStartX(%), %, $line002)
|> xLine(endAbsolute = profileStartX(%), tag = $line002)
|> close(tag = $line003)
|> extrude(length = height)
|> fillet(
@ -172,9 +172,9 @@ binFill = patternLinear3d(
//
binTop = startSketchOn(offsetPlane("XY", offset = height))
|> startProfileAt([0, 0], %)
|> xLine((binLength + 2 * binTol) * countBinWidth, %, $line010)
|> yLine((binLength + 2 * binTol) * countBinLength, %, $line011)
|> xLineTo(profileStartX(%), %, $line012)
|> xLine(length = (binLength + 2 * binTol) * countBinWidth, tag = $line010)
|> yLine(length = (binLength + 2 * binTol) * countBinLength, tag = $line011)
|> xLine(endAbsolute = profileStartX(%), tag = $line012)
|> close(tag = $line013)
|> extrude(length = binHeight * countBinHeight)
|> fillet(
@ -192,7 +192,7 @@ binTop = startSketchOn(offsetPlane("XY", offset = height))
fn lipFace(plane) {
faceSketch = startSketchOn(plane)
|> startProfileAt([0, 0], %)
// |> yLine(lipHeight, %, $line100)
// |> yLine(length = lipHeight, tag = $line100)
|> line(end = [0.0, 5.792893], tag = $line000)
|> arc({
angleStart = 180.0,
@ -201,9 +201,9 @@ fn lipFace(plane) {
}, %, $arc000)
// |> angledLineOfYLength({ angle: -45, length: lipStep5 }, %)
|> line(end = [1.046447, -1.046447], tag = $line001)
|> yLine(-lipStep4, %)
|> yLine(length = -lipStep4)
|> angledLineOfYLength({ angle = -45, length = lipStep3 }, %)
|> yLine(-lipStep2, %)
|> yLine(length = -lipStep2)
|> angledLineOfYLength({ angle = -135, length = lipStep1 }, %)
|> close()
return faceSketch

View File

@ -30,10 +30,10 @@ height = firstStep + secondStep + thirdStep
fn face(plane) {
faceSketch = startSketchOn(plane)
|> startProfileAt([binBaseLength + binTol, 0], %)
|> yLine(height, %)
|> xLine(-binBaseLength, %)
|> yLine(length = height)
|> xLine(length = -binBaseLength)
|> angledLineOfYLength({ angle = -45, length = thirdStep }, %)
|> yLine(-secondStep, %)
|> yLine(length = -secondStep)
|> angledLineOfYLength({ angle = -45, length = firstStep }, %)
|> close()
return faceSketch
@ -91,7 +91,7 @@ singleBinFill = startSketchOn("XY")
], %)
|> line(end = [binLength - (binBaseLength * 2), 0], tag = $line000)
|> line(end = [0, binLength - (binBaseLength * 2)], tag = $line001)
|> xLineTo(profileStartX(%), %, $line002)
|> xLine(endAbsolute = profileStartX(%), tag = $line002)
|> close(tag = $line003)
|> extrude(length = height)
|> fillet(
@ -165,9 +165,9 @@ binFill = patternLinear3d(
// create the top of the bin
binTop = startSketchOn(offsetPlane("XY", offset = height))
|> startProfileAt([0, 0], %)
|> xLine((binLength + 2 * binTol) * countBinWidth, %, $line010)
|> yLine((binLength + 2 * binTol) * countBinLength, %, $line011)
|> xLineTo(profileStartX(%), %, $line012)
|> xLine(length = (binLength + 2 * binTol) * countBinWidth, tag = $line010)
|> yLine(length = (binLength + 2 * binTol) * countBinLength, tag = $line011)
|> xLine(endAbsolute = profileStartX(%), tag = $line012)
|> close(tag = $line013)
|> extrude(length = binHeight * countBinHeight)
|> fillet(

View File

@ -13,10 +13,10 @@ wallThickness = 0.293
// Sketch a quadrant of the beam cross section, then mirror for symmetry across each axis. Extrude to the appropriate length
sketch001 = startSketchOn('-XZ')
|> startProfileAt([0, beamHeight/2], %)
|> xLine(beamWidth/2, %)
|> yLine(-wallThickness, %)
|> xLineTo(wallThickness/2, %)
|> yLineTo(0, %)
|> xLine(length = beamWidth/2)
|> yLine(length = -wallThickness)
|> xLine(endAbsolute = wallThickness/2)
|> yLine(endAbsolute = 0)
|> mirror2d({ axis = 'X' }, %)
|> mirror2d({ axis = 'Y' }, %)
|> extrude(length = beamLength)

View File

@ -1,196 +0,0 @@
import asyncio
import os
import re
from concurrent.futures import ProcessPoolExecutor
from io import BytesIO
from operator import itemgetter
from pathlib import Path
import kcl
import requests
from PIL import Image
RETRIES = 5
def export_step(kcl_path: Path, save_path: Path) -> bool:
# determine the current directory
try:
export_response = asyncio.run(
kcl.execute_and_export(str(kcl_path.parent), kcl.FileExportFormat.Step)
)
stl_path = save_path.with_suffix(".step")
with open(stl_path, "wb") as out:
out.write(bytes(export_response[0].contents))
return True
except Exception as e:
print(e)
return False
def find_files(
path: str | Path, valid_suffixes: list[str], name_pattern: str | None = None
) -> list[Path]:
"""
Recursively find files in a folder by a list of provided suffixes or file naming pattern
Args:
path: str | Path
Root folder to search
valid_suffixes: Container[str]
List of valid suffixes to find files by (e.g. ".stp", ".step")
name_pattern: str
Name pattern to additionally filter files by (e.g. "_component")
Returns:
list[Path]
"""
path = Path(path)
valid_suffixes = [i.lower() for i in valid_suffixes]
return sorted(
file for file in path.rglob("*")
if file.suffix.lower() in valid_suffixes and
(name_pattern is None or re.match(name_pattern, file.name))
)
def snapshot(kcl_path: Path, save_path: Path) -> bool:
try:
snapshot_response = asyncio.run(
kcl.execute_and_snapshot(str(kcl_path.parent), kcl.ImageFormat.Png)
)
image = Image.open(BytesIO(bytearray(snapshot_response)))
im_path = save_path.with_suffix(".png")
image.save(im_path)
return True
except Exception as e:
print(e)
return False
def update_step_file_dates(step_file_path: Path) -> None:
# https://github.com/KittyCAD/cli/blob/main/src/cmd_kcl.rs#L1092
regex = r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+\+\d{2}:\d{2}"
subst = r"1970-01-01T00:00:00.0+00:00"
with open(step_file_path, "r") as inp:
contents = inp.read()
contents = re.sub(regex, subst, contents)
with open(step_file_path, "w") as out:
out.write(contents)
def process_single_kcl(kcl_path: Path) -> dict:
# The part name is the parent folder since each file is main.kcl
part_name = kcl_path.parent.name
print(f"Processing {part_name}")
# determine the root dir, which is where this python script
root_dir = Path(__file__).parent
# step and screenshots for the part are based on the root dir
step_path = root_dir / "step" / part_name
screenshots_path = root_dir / "screenshots" / part_name
# attempt step export
export_status = export_step(kcl_path=kcl_path, save_path=step_path)
count = 1
while not export_status and count < RETRIES:
export_status = export_step(kcl_path=kcl_path, save_path=step_path)
count += 1
# attempt screenshot
snapshot_status = snapshot(kcl_path=kcl_path, save_path=screenshots_path)
count = 1
while not snapshot_status and count < RETRIES:
snapshot_status = snapshot(kcl_path=kcl_path, save_path=screenshots_path)
count += 1
# find relative paths, used for building the README.md
kcl_rel_path = kcl_path.relative_to(Path(__file__).parent)
step_rel_path = step_path.relative_to(Path(__file__).parent).with_suffix(".step")
screenshot_rel_path = screenshots_path.relative_to(Path(__file__).parent).with_suffix(".png")
# readme string for the part
readme_entry = (
f"#### [{part_name}]({kcl_rel_path}) ([step]({step_rel_path})) ([screenshot]({screenshot_rel_path}))\n"
f"[![{part_name}]({screenshot_rel_path})]({kcl_rel_path})"
)
return {"filename": f"{kcl_rel_path}", "export_status": export_status, "snapshot_status": snapshot_status,
"readme_entry": readme_entry}
def update_readme(new_content: str, search_string: str = '---\n') -> None:
with open("README.md", 'r', encoding='utf-8') as file:
lines = file.readlines()
# Find the line containing the search string
found_index = -1
for i, line in enumerate(lines):
if search_string in line:
found_index = i
break
new_lines = lines[:found_index + 1]
new_lines.append(new_content)
# Write the modified content back to the file
with open("README.md", 'w', encoding='utf-8') as file:
file.writelines(new_lines)
file.write("\n")
def main():
kcl_files = find_files(path=Path(__file__).parent, valid_suffixes=[".kcl"], name_pattern="main")
# run concurrently
with ProcessPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(process_single_kcl, kcl_file) for kcl_file in kcl_files]
results = [future.result() for future in futures]
results = sorted(results, key=itemgetter('filename'))
step_files = find_files(path=Path(__file__).parent, valid_suffixes=[".step"])
with ProcessPoolExecutor(max_workers=5) as executor:
_ = [executor.submit(update_step_file_dates, step_file) for step_file in step_files]
if False in [i["export_status"] for i in results]:
comment_body = "The following files failed to export to STEP format:\n"
for i in results:
if not i["export_status"]:
comment_body += f"{i['filename']}\n"
url = f"https://api.github.com/repos/{os.getenv('GH_REPO')}/issues/{os.getenv('GH_PR')}/comments"
headers = {
'Authorization': f'token {os.getenv("GH_TOKEN")}',
}
json_data = {
'body': comment_body,
}
requests.post(url, headers=headers, json=json_data, timeout=60)
new_readme_links = []
for result in results:
if result["export_status"] and result["snapshot_status"]:
new_readme_links.append(result["readme_entry"])
new_readme_str = "\n".join(new_readme_links)
update_readme(new_readme_str)
if __name__ == "__main__":
main()

View File

@ -69,7 +69,7 @@ fn capScrew(start, length, dia) {
-start[0] + wallToWallLength / 2,
start[2]
], %)
|> yLine(-hexWallLength / 2, %)
|> yLine(length = -hexWallLength / 2)
|> angledLine({
angle = hexStartingAngle,
length = hexWallLength

View File

@ -24,7 +24,7 @@ pipeSketch = startSketchOn('XY')
length = pipeTransitionLength
}, %)
|> line(end = [0, -pipeLargeDiaLength])
|> xLine(-thickness, %)
|> xLine(length = -thickness)
|> line(end = [0, pipeLargeDiaLength])
|> angledLineToX({
angle = -pipeTransitionAngle + 180,

View File

@ -14,20 +14,20 @@ frontLength = 7
sketch001 = startSketchOn("-YZ")
|> startProfileAt([wallsWidth / 2, 0], %)
|> xLine(wallThickness / 2, %)
|> xLine(length = wallThickness / 2)
|> angledLineToX({ angle = 60, to = wallsWidth }, %, $seg01)
|> yLineTo(height, %)
|> xLine(-wallThickness, %)
|> yLineTo(segEndY(seg01), %)
|> yLine(endAbsolute = height)
|> xLine(length = -wallThickness)
|> yLine(endAbsolute = segEndY(seg01))
|> angledLineToX({
angle = 60,
to = wallsWidth / 2 + wallThickness / 2
}, %)
|> xLine(-wallThickness, %)
|> xLine(length = -wallThickness)
|> angledLineToX({ angle = 180 - 60, to = wallThickness }, %)
|> yLineTo(height, %)
|> xLineTo(0, %)
|> yLineTo(segEndY(seg01), %)
|> yLine(endAbsolute = height)
|> xLine(endAbsolute = 0)
|> yLine(endAbsolute = segEndY(seg01))
|> angledLineToY({ angle = 180 - 60, to = 0 }, %)
|> close()
part001 = revolve({
@ -42,20 +42,20 @@ part001 = revolve({
sketch002 = startSketchOn('-YZ')
|> startProfileAt([wallsWidth / 2, 0], %)
|> xLine(wallThickness / 2, %)
|> xLine(length = wallThickness / 2)
|> angledLineToX({ angle = 60, to = wallsWidth }, %, $seg02)
|> yLineTo(height, %)
|> xLine(-wallThickness, %)
|> yLineTo(segEndY(seg01), %)
|> yLine(endAbsolute = height)
|> xLine(length = -wallThickness)
|> yLine(endAbsolute = segEndY(seg01))
|> angledLineToX({
angle = 60,
to = wallsWidth / 2 + wallThickness / 2
}, %)
|> xLine(-wallThickness, %)
|> xLine(length = -wallThickness)
|> angledLineToX({ angle = 180 - 60, to = wallThickness }, %)
|> yLineTo(height, %)
|> xLineTo(0, %)
|> yLineTo(segEndY(seg02), %)
|> yLine(endAbsolute = height)
|> xLine(endAbsolute = 0)
|> yLine(endAbsolute = segEndY(seg02))
|> angledLineToY({ angle = 180 - 60, to = 0 }, %)
|> close()
|> extrude(length = backLength - height)
@ -81,23 +81,23 @@ sketch003 = startSketchOn(customPlane)
sketch004 = startSketchOn(sketch002, 'END')
|> startProfileAt([0, 0], %)
|> yLineTo(height, %)
|> xLineTo(wallThickness, %)
|> yLineTo(segEndY(seg01), %)
|> yLine(endAbsolute = height)
|> xLine(endAbsolute = wallThickness)
|> yLine(endAbsolute = segEndY(seg01))
|> angledLineToX({
angle = 180 - 60,
to = wallsWidth / 2 - (wallThickness / 2)
}, %)
|> xLine(wallThickness, %)
|> xLine(length = wallThickness)
|> angledLineToY({ angle = 60, to = segEndY(seg01) }, %)
|> yLineTo(height, %)
|> xLine(wallThickness, %)
|> yLine(endAbsolute = height)
|> xLine(length = wallThickness)
|> tangentialArcTo([
(frontLength - wallsWidth) / 2 + wallsWidth,
height - ((height - exitHeight) / 2)
], %)
|> tangentialArcTo([frontLength, exitHeight], %)
|> yLineTo(0, %)
|> yLine(endAbsolute = 0)
|> close(tag = $seg04)
|> extrude(length = wallThickness)
@ -115,30 +115,30 @@ customPlane2 = {
}
sketch005 = startSketchOn(customPlane2)
|> startProfileAt([0, 0], %)
|> yLineTo(height, %)
|> xLineTo(wallsWidth, %)
|> yLine(endAbsolute = height)
|> xLine(endAbsolute = wallsWidth)
|> tangentialArcTo([
(frontLength - wallsWidth) / 2 + wallsWidth,
height - ((height - exitHeight) / 2)
], %)
|> tangentialArcTo([frontLength, exitHeight], %)
|> yLineTo(0, %, $seg03)
|> yLine(endAbsolute = 0, tag = $seg03)
|> close()
|> extrude(length = wallThickness)
sketch006 = startSketchOn(sketch005, seg03)
|> startProfileAt([0, -1 * (backLength - height)], %)
|> xLineTo(-exitHeight, %)
|> yLine(-wallsWidth, %)
|> xLineTo(0, %)
|> xLine(endAbsolute = -exitHeight)
|> yLine(length = -wallsWidth)
|> xLine(endAbsolute = 0)
|> close()
|> extrude(length = wallThickness)
sketch007 = startSketchOn(sketch004, 'END')
|> startProfileAt([0, 0], %)
|> xLineTo(wallThickness, %)
|> yLineTo(height, %)
|> xLineTo(0, %)
|> xLine(endAbsolute = wallThickness)
|> yLine(endAbsolute = height)
|> xLine(endAbsolute = 0)
|> close()
|> extrude(length = wallsWidth - (2 * wallThickness))
@ -157,8 +157,8 @@ customPlane3 = {
sketch008 = startSketchOn(customPlane3)
|> startProfileAt([wallThickness, wallThickness], %)
|> xLineTo(frontLength, %)
|> yLine(wallsWidth - (2 * wallThickness), %)
|> xLineTo(wallThickness, %)
|> xLine(endAbsolute = frontLength)
|> yLine(length = wallsWidth - (2 * wallThickness))
|> xLine(endAbsolute = wallThickness)
|> close()
|> extrude(length = -wallThickness)

View File

@ -1,3 +0,0 @@
pillow==11.1.0
requests==2.32.3
zoo-kcl==0.3.45

View File

@ -15,28 +15,28 @@ depth = 30
distanceToInsideEdge = slateWidthHalf + templateThickness + templateGap
sketch001 = startSketchOn('XZ')
|> startProfileAt([ZERO, depth + templateGap], %)
|> xLine(slateWidthHalf - radius, %, $seg01)
|> xLine(length = slateWidthHalf - radius, tag = $seg01)
|> arc({
angleEnd = 0,
angleStart = 90,
radius = 10 + templateGap
}, %, $seg09)
|> yLineTo(-templateThickness, %, $seg03)
|> xLine(templateThickness, %, $seg07)
|> yLineTo((segEndY(seg01) + templateThickness) / 2 - templateThickness, %, $seg02)
|> xLineTo(segEndX(seg03) + minClampingDistance, %, $seg06)
|> yLine(templateThickness * 2, %, $seg08)
|> xLineTo(segEndX(seg02) + 0, %, $seg05)
|> yLineTo(segEndY(seg01) + templateThickness, %, $seg10)
|> xLineTo(ZERO, %, $seg04)
|> xLine(-segLen(seg04), %)
|> yLine(-segLen(seg10), %)
|> xLine(-segLen(seg05), %)
|> yLine(-segLen(seg08), %)
|> xLine(segLen(seg06), %)
|> yLine(-segLen(seg02), %)
|> xLine(segLen(seg07), %)
|> yLine(segLen(seg03), %)
|> yLine(endAbsolute = -templateThickness, tag = $seg03)
|> xLine(length = templateThickness, tag = $seg07)
|> yLine(endAbsolute = (segEndY(seg01) + templateThickness) / 2 - templateThickness, tag = $seg02)
|> xLine(endAbsolute = segEndX(seg03) + minClampingDistance, tag = $seg06)
|> yLine(length = templateThickness * 2, tag = $seg08)
|> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05)
|> yLine(endAbsolute = segEndY(seg01) + templateThickness, tag = $seg10)
|> xLine(endAbsolute = ZERO, tag = $seg04)
|> xLine(length = -segLen(seg04))
|> yLine(length = -segLen(seg10))
|> xLine(length = -segLen(seg05))
|> yLine(length = -segLen(seg08))
|> xLine(length = segLen(seg06))
|> yLine(length = -segLen(seg02))
|> xLine(length = segLen(seg07))
|> yLine(length = segLen(seg03))
|> arc({
angleEnd = 90,
angleStart = 180,

View File

@ -19,21 +19,21 @@ length002 = depth + minClampingDistance
// Create the first sketch
sketch001 = startSketchOn('XZ')
|> startProfileAt([0, depth - templateGap], %)
|> xLine(length001, %, $seg01)
|> xLine(length = length001, tag = $seg01)
|> arc({
angleEnd = 0,
angleStart = 90,
radius = radius - templateGap
}, %)
|> yLineTo(-templateGap * 2 - (templateDiameter / 2), %, $seg05)
|> xLineTo(slateWidthHalf + templateThickness, %, $seg04)
|> yLine(-length002, %, $seg03)
|> xLineTo(ZERO, %, $seg02)
|> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05)
|> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04)
|> yLine(length = -length002, tag = $seg03)
|> xLine(endAbsolute = ZERO, tag = $seg02)
// |> line(end = [7.78, 11.16])
|> xLine(-segLen(seg02), %)
|> yLine(segLen(seg03), %)
|> xLine(segLen(seg04), %)
|> yLine(segLen(seg05), %)
|> xLine(length = -segLen(seg02))
|> yLine(length = segLen(seg03))
|> xLine(length = segLen(seg04))
|> yLine(length = segLen(seg05))
|> arc({
angleEnd = 90,
angleStart = 180,
@ -51,7 +51,7 @@ sketch002 = startSketchOn(extrude001, 'START')
-slateWidthHalf,
-templateGap * 2 - (templateDiameter / 2)
], %)
|> xLine(-7, %, $rectangleSegmentA001)
|> xLine(length = -7, tag = $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) + 90,
minClampingDistance
@ -72,7 +72,7 @@ sketch003 = startSketchOn(extrude001, 'START')
slateWidthHalf,
-templateGap * 2 - (templateDiameter / 2)
], %)
|> xLine(7, %, $rectangleSegmentA002)
|> xLine(length = 7, tag = $rectangleSegmentA002)
|> angledLine([
segAng(rectangleSegmentA002) - 90,
minClampingDistance

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

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