Compare commits
108 Commits
derive-doc
...
stream-pau
Author | SHA1 | Date | |
---|---|---|---|
c6b80eec68 | |||
1b68f5dc19 | |||
a0aa4802d1 | |||
746f76ec63 | |||
8e624935c2 | |||
0a5f22c80a | |||
142db64796 | |||
59b0cdc3ac | |||
4763257dc3 | |||
b48ba7f081 | |||
64537a59b8 | |||
c24efaf2e4 | |||
2fb16ed074 | |||
82e647db3b | |||
fa2d0a69bf | |||
e372b2680e | |||
c1c1f817c9 | |||
00c0c993f2 | |||
b505c0be07 | |||
6c2d06c2c6 | |||
a4b7dd5182 | |||
0c2ca726d0 | |||
fcfecf702b | |||
347a6ef15a | |||
eed4386f76 | |||
14afcba599 | |||
faee6cbc64 | |||
0673e98fad | |||
b4eea5f842 | |||
2c9eb7f7c0 | |||
e259b2e3e8 | |||
91049204c5 | |||
0128c67aae | |||
ecc42b1e9c | |||
31811d0269 | |||
def5959836 | |||
4c7fab405b | |||
1e12e8d36b | |||
ad775891a3 | |||
efe207f4d2 | |||
01f0162991 | |||
2bbf7fad67 | |||
98549945a4 | |||
315fdc3060 | |||
c7e77e2597 | |||
a48679c014 | |||
c5e74866a9 | |||
731cb6c532 | |||
8a36a4c205 | |||
f29f2557de | |||
5f0ffb56c4 | |||
70078176b0 | |||
098fa2b5c9 | |||
2755156b84 | |||
a8b3ec660d | |||
3747c6ff0e | |||
bc1bc817ba | |||
b415e88746 | |||
9173e368a2 | |||
25928813e3 | |||
aec9cac7c7 | |||
0e82fbf7b0 | |||
f5975bbd61 | |||
765e587f6b | |||
6ccd5e22b8 | |||
c8bf82ba04 | |||
daad2039ec | |||
b567f6dfad | |||
41e85c77ac | |||
9f615b9d3e | |||
e8b5618b34 | |||
799b2d77b4 | |||
7b569f9b4f | |||
0f0c396a0c | |||
83214a88a3 | |||
dbab7876de | |||
6706695502 | |||
fa1f8d8d02 | |||
b4e59b5c56 | |||
20495383ac | |||
7f5fb83761 | |||
2ac874971e | |||
230e3132e9 | |||
bf9bb4fb22 | |||
31e7634669 | |||
84c71aa046 | |||
721b3e8cbd | |||
89309b6ccd | |||
15b163bba8 | |||
60d047ef6a | |||
f105044a47 | |||
9388e09c47 | |||
d71f2af9bd | |||
2bb372de12 | |||
0a3a8afbbd | |||
351df2f306 | |||
05a2eada9a | |||
788270d4fc | |||
6845f0c4bc | |||
563096fba4 | |||
35133c4f45 | |||
b78c6508c2 | |||
08b776134f | |||
cca544189c | |||
69754c82a2 | |||
afbee552ee | |||
b11772b27c | |||
6dc87aa4fe |
@ -1,20 +1,21 @@
|
|||||||
name: build-apps
|
name: build-publish-apps
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
tags:
|
release:
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
types: [published]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 4 * * *'
|
- cron: '0 4 * * *'
|
||||||
# Daily at 04:00 AM UTC
|
# Daily at 04:00 AM UTC
|
||||||
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IS_RELEASE: ${{ github.ref_type == 'tag' }}
|
CUT_RELEASE_PR: ${{ github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
|
||||||
IS_NIGHTLY: ${{ github.event_name == 'schedule' }}
|
BUILD_RELEASE: ${{ github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
|
||||||
|
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Non-release build, commit {0}', github.sha) }}
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
@ -25,7 +26,6 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04 # seperate job on Ubuntu for easy string manipulations (compared to Windows)
|
runs-on: ubuntu-22.04 # seperate job on Ubuntu for easy string manipulations (compared to Windows)
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.export_version.outputs.version }}
|
version: ${{ steps.export_version.outputs.version }}
|
||||||
notes: ${{ steps.export_notes.outputs.notes }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@ -47,40 +47,48 @@ jobs:
|
|||||||
- name: Run build:wasm
|
- name: Run build:wasm
|
||||||
run: "yarn build:wasm"
|
run: "yarn build:wasm"
|
||||||
|
|
||||||
- name: Set nightly version, product name, release notes, and icons
|
- name: Set nightly version
|
||||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
if: github.event_name == 'schedule'
|
||||||
run: yarn files:flip-to-nightly
|
|
||||||
|
|
||||||
- name: Set release version
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
run: |
|
run: |
|
||||||
export VERSION=${GITHUB_REF_NAME#v}
|
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
||||||
yarn files:set-version
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
# TODO: see if we need to inject updater nightly URL here https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json
|
||||||
|
|
||||||
|
- name: Generate release notes
|
||||||
|
run: |
|
||||||
|
echo "$NOTES" > release-notes.md
|
||||||
|
cat release-notes.md
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: prepared-files
|
name: prepared-files
|
||||||
path: |
|
path: |
|
||||||
package.json
|
package.json
|
||||||
electron-builder.yml
|
|
||||||
src/wasm-lib/pkg/wasm_lib*
|
src/wasm-lib/pkg/wasm_lib*
|
||||||
release-notes.md
|
release-notes.md
|
||||||
assets/icon.ico
|
|
||||||
assets/icon.png
|
|
||||||
|
|
||||||
- id: export_version
|
- id: export_version
|
||||||
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
|
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- id: export_notes
|
- name: Prepare electron-builder.yml file for nightly
|
||||||
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
|
if: ${{ github.event_name == 'schedule' }}
|
||||||
|
run: |
|
||||||
|
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/nightly"' electron-builder.yml
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: ${{ github.event_name == 'schedule' }}
|
||||||
|
with:
|
||||||
|
name: prepared-files-nightly
|
||||||
|
path: |
|
||||||
|
electron-builder.yml
|
||||||
|
|
||||||
- name: Prepare electron-builder.yml file for updater test
|
- name: Prepare electron-builder.yml file for updater test
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v3
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
with:
|
with:
|
||||||
name: prepared-files-updater-test
|
name: prepared-files-updater-test
|
||||||
path: |
|
path: |
|
||||||
@ -101,24 +109,32 @@ jobs:
|
|||||||
platform: linux
|
platform: linux
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
|
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
|
||||||
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
name: prepared-files
|
name: prepared-files
|
||||||
|
|
||||||
- name: Copy prepared files
|
- name: Copy prepared files
|
||||||
run: |
|
run: |
|
||||||
ls -R prepared-files
|
ls -R prepared-files
|
||||||
cp prepared-files/package.json package.json
|
cp prepared-files/package.json package.json
|
||||||
cp prepared-files/electron-builder.yml electron-builder.yml
|
|
||||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
cp prepared-files/src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||||
mkdir src/wasm-lib/pkg
|
mkdir src/wasm-lib/pkg
|
||||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
|
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
|
||||||
cp prepared-files/release-notes.md release-notes.md
|
cp prepared-files/release-notes.md release-notes.md
|
||||||
cp prepared-files/assets/icon.ico assets/icon.ico
|
|
||||||
cp prepared-files/assets/icon.png assets/icon.png
|
- uses: actions/download-artifact@v3
|
||||||
|
if: ${{ github.event_name == 'schedule' }}
|
||||||
|
name: prepared-files-nightly
|
||||||
|
|
||||||
|
- name: Copy updated electron-builder.yml file for nightly build
|
||||||
|
if: ${{ github.event_name == 'schedule' }}
|
||||||
|
run: |
|
||||||
|
ls -R prepared-files-nightly
|
||||||
|
cp prepared-files-nightly/electron-builder.yml electron-builder.yml
|
||||||
|
|
||||||
- name: Sync node version and setup cache
|
- name: Sync node version and setup cache
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
@ -131,7 +147,7 @@ jobs:
|
|||||||
- run: yarn tronb:vite
|
- run: yarn tronb:vite
|
||||||
|
|
||||||
- name: Prepare certificate and variables (Windows only)
|
- name: Prepare certificate and variables (Windows only)
|
||||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'windows-2022' }}
|
||||||
run: |
|
run: |
|
||||||
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
|
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
|
||||||
cat /d/Certificate_pkcs12.p12
|
cat /d/Certificate_pkcs12.p12
|
||||||
@ -146,7 +162,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Setup certicate with SSM KSP (Windows only)
|
- name: Setup certicate with SSM KSP (Windows only)
|
||||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'windows-2022' }}
|
||||||
run: |
|
run: |
|
||||||
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
|
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
|
||||||
msiexec /i smtools-windows-x64.msi /quiet /qn
|
msiexec /i smtools-windows-x64.msi /quiet /qn
|
||||||
@ -157,13 +173,13 @@ jobs:
|
|||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Build the app (debug)
|
- name: Build the app (debug)
|
||||||
if: ${{ env.IS_RELEASE == 'false' && env.IS_NIGHTLY == 'false' }}
|
if: ${{ env.BUILD_RELEASE == 'false' }}
|
||||||
# electron-builder doesn't have a concept of release vs debug,
|
# electron-builder doesn't have a concept of release vs debug,
|
||||||
# this is just not doing any codesign or release yml generation
|
# this is just not doing any codesign or release yml generation
|
||||||
run: yarn electron-builder --config
|
run: yarn electron-builder --config
|
||||||
|
|
||||||
- name: Build the app (release)
|
- name: Build the app (release)
|
||||||
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
|
if: ${{ env.BUILD_RELEASE == 'true' }}
|
||||||
env:
|
env:
|
||||||
PUBLISH_FOR_PULL_REQUEST: true
|
PUBLISH_FOR_PULL_REQUEST: true
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
@ -180,7 +196,7 @@ jobs:
|
|||||||
- name: List artifacts in out/
|
- name: List artifacts in out/
|
||||||
run: ls -R out
|
run: ls -R out
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-arm64-${{ matrix.platform }}
|
name: out-arm64-${{ matrix.platform }}
|
||||||
# first two will pick both Zoo Modeling App-$VERSION-arm64-win.exe and Zoo Modeling App-$VERSION-win.exe
|
# first two will pick both Zoo Modeling App-$VERSION-arm64-win.exe and Zoo Modeling App-$VERSION-win.exe
|
||||||
@ -190,7 +206,7 @@ jobs:
|
|||||||
out/*-arm64-mac.*
|
out/*-arm64-mac.*
|
||||||
out/*-arm64-linux.*
|
out/*-arm64-linux.*
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-x64-${{ matrix.platform }}
|
name: out-x64-${{ matrix.platform }}
|
||||||
path: |
|
path: |
|
||||||
@ -198,29 +214,27 @@ jobs:
|
|||||||
out/*-x64-mac.*
|
out/*-x64-mac.*
|
||||||
out/*-x86_64-linux.*
|
out/*-x86_64-linux.*
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v3
|
||||||
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
|
if: ${{ env.BUILD_RELEASE == 'true' }}
|
||||||
with:
|
with:
|
||||||
name: out-yml-${{ matrix.platform }}
|
name: out-yml
|
||||||
path: |
|
path: |
|
||||||
out/latest*.yml
|
out/latest*.yml
|
||||||
|
|
||||||
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
||||||
|
|
||||||
# The steps below are for updater-test builds, only on release
|
- uses: actions/download-artifact@v3
|
||||||
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
|
||||||
name: prepared-files-updater-test
|
name: prepared-files-updater-test
|
||||||
|
|
||||||
- name: Copy updated electron-builder.yml file for updater test
|
- name: Copy updated electron-builder.yml file for updater test
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
ls -R prepared-files-updater-test
|
ls -R prepared-files-updater-test
|
||||||
cp prepared-files-updater-test/electron-builder.yml electron-builder.yml
|
cp prepared-files-updater-test/electron-builder.yml electron-builder.yml
|
||||||
|
|
||||||
- name: Build the app (updater-test)
|
- name: Build the app (updater-test)
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
env:
|
env:
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
@ -233,8 +247,8 @@ jobs:
|
|||||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||||
run: yarn electron-builder --config --publish always
|
run: yarn electron-builder --config --publish always
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v3
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
with:
|
with:
|
||||||
name: updater-test-arm64-${{ matrix.platform }}
|
name: updater-test-arm64-${{ matrix.platform }}
|
||||||
path: |
|
path: |
|
||||||
@ -242,8 +256,8 @@ jobs:
|
|||||||
out/*-arm64-mac.dmg
|
out/*-arm64-mac.dmg
|
||||||
out/*-arm64-linux.AppImage
|
out/*-arm64-linux.AppImage
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v3
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
with:
|
with:
|
||||||
name: updater-test-x64-${{ matrix.platform }}
|
name: updater-test-x64-${{ matrix.platform }}
|
||||||
path: |
|
path: |
|
||||||
@ -252,69 +266,58 @@ jobs:
|
|||||||
out/*-x86_64-linux.AppImage
|
out/*-x86_64-linux.AppImage
|
||||||
|
|
||||||
|
|
||||||
upload-apps-release:
|
publish-apps-release:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
if: ${{ github.ref_type == 'tag' || github.event_name == 'schedule' }}
|
if: ${{ github.event_name == 'release' || github.event_name == 'schedule' }}
|
||||||
|
needs: [prepare-files, build-apps]
|
||||||
env:
|
env:
|
||||||
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
||||||
VERSION: ${{ format('v{0}', needs.prepare-files.outputs.version) }}
|
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
|
||||||
needs: [prepare-files, build-apps]
|
PUB_DATE: ${{ github.event_name == 'release' && github.event.release.created_at || github.event.repository.updated_at }}
|
||||||
|
BUCKET_DIR: ${{ github.event_name == 'schedule' && 'dl.kittycad.io/releases/modeling-app/nightly' || 'dl.kittycad.io/releases/modeling-app' }}
|
||||||
|
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
||||||
|
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-arm64-win
|
name: out-arm64-win
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-x64-win
|
name: out-x64-win
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
|
||||||
name: out-yml-win
|
|
||||||
path: out
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
with:
|
||||||
name: out-arm64-mac
|
name: out-arm64-mac
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-x64-mac
|
name: out-x64-mac
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
|
||||||
name: out-yml-mac
|
|
||||||
path: out
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
with:
|
||||||
name: out-arm64-linux
|
name: out-arm64-linux
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-x64-linux
|
name: out-x64-linux
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-yml-linux
|
name: out-yml
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- name: Generate the download static endpoint
|
- name: Generate the download static endpoint
|
||||||
env:
|
|
||||||
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
|
||||||
PUB_DATE: ${{ github.event.repository.updated_at }}
|
|
||||||
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
|
||||||
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
|
||||||
run: |
|
run: |
|
||||||
RELEASE_DIR=https://${WEBSITE_DIR}
|
RELEASE_DIR=https://${WEBSITE_DIR}
|
||||||
jq --null-input \
|
jq --null-input \
|
||||||
@ -351,44 +354,78 @@ jobs:
|
|||||||
"url": $linux_x64_url
|
"url": $linux_x64_url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}' > out/last_download.json
|
}' > last_download.json
|
||||||
cat out/last_download.json
|
cat last_download.json
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-download-json
|
|
||||||
path: out/last_download.json
|
|
||||||
|
|
||||||
- name: List artifacts
|
- name: List artifacts
|
||||||
run: "ls -R out"
|
run: "ls -R out"
|
||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
|
||||||
uses: 'google-github-actions/auth@v2.1.7'
|
uses: 'google-github-actions/auth@v2.1.7'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
- name: Set up Google Cloud SDK
|
- name: Set up Google Cloud SDK
|
||||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
|
||||||
uses: google-github-actions/setup-gcloud@v2.1.2
|
uses: google-github-actions/setup-gcloud@v2.1.2
|
||||||
with:
|
with:
|
||||||
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
||||||
|
|
||||||
- name: Upload nightly files to public bucket
|
- name: Upload release files to public bucket
|
||||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
|
||||||
uses: google-github-actions/upload-cloud-storage@v2.2.1
|
uses: google-github-actions/upload-cloud-storage@v2.2.1
|
||||||
with:
|
with:
|
||||||
path: out
|
path: out
|
||||||
glob: '*'
|
glob: 'Zoo*'
|
||||||
parent: false
|
parent: false
|
||||||
destination: 'dl.kittycad.io/releases/modeling-app/nightly'
|
destination: ${{ env.BUCKET_DIR }}
|
||||||
|
|
||||||
- name: Create draft release
|
- name: Upload update endpoint to public bucket
|
||||||
uses: softprops/action-gh-release@v2
|
uses: google-github-actions/upload-cloud-storage@v2.2.1
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
with:
|
||||||
|
path: out
|
||||||
|
glob: 'latest*'
|
||||||
|
parent: false
|
||||||
|
destination: ${{ env.BUCKET_DIR }}
|
||||||
|
|
||||||
|
- name: Upload download endpoint to public bucket
|
||||||
|
uses: google-github-actions/upload-cloud-storage@v2.2.1
|
||||||
|
with:
|
||||||
|
path: last_download.json
|
||||||
|
destination: ${{ env.BUCKET_DIR }}
|
||||||
|
|
||||||
|
- name: Upload release files to Github
|
||||||
|
if: ${{ github.event_name == 'release' }}
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
name: ${{ env.VERSION }}
|
|
||||||
tag_name: ${{ env.VERSION }}
|
|
||||||
draft: true
|
|
||||||
generate_release_notes: true
|
|
||||||
files: 'out/Zoo*'
|
files: 'out/Zoo*'
|
||||||
|
|
||||||
|
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||||
|
run: |
|
||||||
|
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/last_download.json" --async
|
||||||
|
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-linux-arm64.yml" --async
|
||||||
|
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-mac.yml" --async
|
||||||
|
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest.yml" --async
|
||||||
|
|
||||||
|
announce_release:
|
||||||
|
needs: [publish-apps-release]
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
if: github.event_name == 'release'
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.x'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install requests
|
||||||
|
|
||||||
|
- name: Announce Release
|
||||||
|
env:
|
||||||
|
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
|
RELEASE_VERSION: ${{ github.event.release.tag_name }}
|
||||||
|
RELEASE_BODY: ${{ github.event.release.body}}
|
||||||
|
run: python public/announce_release.py
|
37
.github/workflows/create-release.yml
vendored
Normal file
37
.github/workflows/create-release.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
name: Create Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: read
|
||||||
|
if: contains(github.event.head_commit.message, 'Cut release v')
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v7
|
||||||
|
name: Read Cut release PR info and create release
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { owner, repo } = context.repo
|
||||||
|
const pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
commit_sha: context.sha,
|
||||||
|
})
|
||||||
|
const { title, body } = pulls.data[0]
|
||||||
|
const version = title.split('Cut release ')[1]
|
||||||
|
|
||||||
|
const result = await github.rest.repos.createRelease({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
body,
|
||||||
|
tag_name: version,
|
||||||
|
name: version,
|
||||||
|
draft: true,
|
||||||
|
})
|
||||||
|
console.log(result)
|
158
.github/workflows/publish-apps-release.yml
vendored
158
.github/workflows/publish-apps-release.yml
vendored
@ -1,158 +0,0 @@
|
|||||||
name: publish-apps-release
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-apps-release:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
cache: 'yarn'
|
|
||||||
|
|
||||||
- name: Find tag workflow id
|
|
||||||
id: tag_workflow_id
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
id=$(gh run ls --repo kittycad/modeling-app -w build-apps.yml --branch ${{ github.event.release.tag_name }} --json databaseId | jq '.[0].databaseId')
|
|
||||||
echo "id=$id" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-arm64-win
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-x64-win
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-yml-win
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-arm64-mac
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-x64-mac
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-yml-mac
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-arm64-linux
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-x64-linux
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-yml-linux
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: out-download-json
|
|
||||||
path: out
|
|
||||||
run-id: ${{ steps.tag_workflow_id.outputs.id }}
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: List artifacts
|
|
||||||
run: ls -R out
|
|
||||||
|
|
||||||
- name: Override release notes
|
|
||||||
env:
|
|
||||||
NOTES: ${{ github.event.release.body }}
|
|
||||||
run: yarn files:set-notes
|
|
||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
|
||||||
uses: 'google-github-actions/auth@v2.1.7'
|
|
||||||
with:
|
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
|
||||||
|
|
||||||
- name: Set up Google Cloud SDK
|
|
||||||
uses: google-github-actions/setup-gcloud@v2.1.2
|
|
||||||
with:
|
|
||||||
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
|
||||||
|
|
||||||
- name: Upload release files to public bucket
|
|
||||||
uses: google-github-actions/upload-cloud-storage@v2.2.1
|
|
||||||
with:
|
|
||||||
path: out
|
|
||||||
glob: '*'
|
|
||||||
parent: false
|
|
||||||
destination: 'dl.kittycad.io/releases/modeling-app/test/new-workflow'
|
|
||||||
|
|
||||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
|
||||||
run: |
|
|
||||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/last_download.json" --async
|
|
||||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-linux-arm64.yml" --async
|
|
||||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-mac.yml" --async
|
|
||||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest.yml" --async
|
|
||||||
|
|
||||||
|
|
||||||
announce_release:
|
|
||||||
needs: [publish-apps-release]
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.x'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install requests
|
|
||||||
|
|
||||||
- name: Announce Release
|
|
||||||
env:
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
RELEASE_VERSION: ${{ github.event.release.tag_name }}
|
|
||||||
RELEASE_BODY: ${{ github.event.release.body }}
|
|
||||||
run: python public/announce_release.py
|
|
55
README.md
55
README.md
@ -128,39 +128,45 @@ Before you submit a contribution PR to this repo, please ensure that:
|
|||||||
|
|
||||||
## Release a new version
|
## Release a new version
|
||||||
|
|
||||||
#### 1. Create a 'Cut release $VERSION' issue
|
#### 1. Bump the versions by running `./make-release.sh`
|
||||||
|
|
||||||
It will be used to document changelog discussions and release testing.
|
The `./make-release.sh` script has git commands to pull main but to be sure you can run the following git commands to have a fresh `main` locally.
|
||||||
|
|
||||||
https://github.com/KittyCAD/modeling-app/issues/new
|
|
||||||
|
|
||||||
#### 2. Push a new tag
|
|
||||||
|
|
||||||
Create a new tag and push it to the repo (eg. `v0.28.0` for `$VERSION`)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
VERSION=$(./scripts/semantic-release.sh)
|
git branch -D main
|
||||||
git tag $VERSION
|
git checkout main
|
||||||
git push origin --tags
|
git pull origin
|
||||||
|
./make-release.sh
|
||||||
|
# Copy within the back ticks and paste the stdout of the change log
|
||||||
|
git push --set-upstream origin <branch name created from ./make-release.sh>
|
||||||
```
|
```
|
||||||
|
|
||||||
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
|
That will create the branch with the updated json files for you:
|
||||||
|
- run `./make-release.sh` or `./make-release.sh patch` for a patch update;
|
||||||
|
- run `./make-release.sh minor` for minor; or
|
||||||
|
- run `./make-release.sh major` for major.
|
||||||
|
|
||||||
Once the workflow succeeds, a draft release will be created at https://github.com/KittyCAD/modeling-app/releases.
|
After it runs you should just need the push the branch and open a PR.
|
||||||
|
|
||||||
|
#### 2. Create a Cut Release PR
|
||||||
|
|
||||||
|
When you open the PR copy the change log from the output of the `./make-release.sh` script into the description of the PR.
|
||||||
|
|
||||||
|
**Important:** Pull request title needs to be prefixed with `Cut release v` to build in release mode and a few other things to test in the best context possible, the intent would be for instance to have `Cut release v1.2.3` for the `v1.2.3` release candidate.
|
||||||
|
|
||||||
|
The PR may then serve as a place to discuss the human-readable changelog and extra QA. The `make-release.sh` tool suggests a changelog for you too to be used as PR description, just make sure to delete lines that are not user facing.
|
||||||
|
|
||||||
#### 3. Manually test artifacts from the Cut Release PR
|
#### 3. Manually test artifacts from the Cut Release PR
|
||||||
|
|
||||||
##### Release builds
|
##### Release builds
|
||||||
|
|
||||||
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
|
The release builds can be found under the `out-{platform}` zip, at the very bottom of the `build-publish-apps` summary page for each commit on this branch.
|
||||||
|
|
||||||
Alternatively, the draft release will also include these builds.
|
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the Cut Release PR.
|
||||||
|
|
||||||
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
|
|
||||||
|
|
||||||
##### Updater-test builds
|
##### Updater-test builds
|
||||||
|
|
||||||
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
The other `build-publish-apps` output in Cut Release PRs is `updater-test-{platform}`. As we don't have a way to test this fully automatically, we have a semi-automated process. For macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
|
||||||
|
|
||||||
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
|
||||||
|
|
||||||
@ -176,15 +182,18 @@ If the prompt doesn't show up, start the app in command line to grab the electro
|
|||||||
./Zoo Modeling App-{version}-{arch}-linux.AppImage
|
./Zoo Modeling App-{version}-{arch}-linux.AppImage
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4. Publish the release
|
#### 4. Merge the Cut Release PR
|
||||||
|
|
||||||
Head over to https://github.com/KittyCAD/modeling-app/releases, paste in the changelog discussed in the issue, and publish the draft release created by the `build-apps` workflow from step 2.
|
This will kick the `create-release` action, that creates a _Draft_ release out of this Cut Release PR merge after less than a minute, with the new version as title and Cut Release PR as description.
|
||||||
|
|
||||||
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter. On success, the files will be uploaded to the public bucket and the announcement on Discord will be sent.
|
|
||||||
|
|
||||||
#### 5. Close the issue
|
#### 5. Publish the release
|
||||||
|
|
||||||
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
|
Head over to https://github.com/KittyCAD/modeling-app/releases, the draft release corresponding to the merged Cut Release PR should show up at the top as _Draft_. Click on it, verify the content, and hit _Publish_.
|
||||||
|
|
||||||
|
#### 6. Profit
|
||||||
|
|
||||||
|
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter.
|
||||||
|
|
||||||
|
|
||||||
## Fuzzing the parser
|
## Fuzzing the parser
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 176 KiB |
Binary file not shown.
Before Width: | Height: | Size: 157 KiB |
BIN
assets/icon.icns
Normal file
BIN
assets/icon.icns
Normal file
Binary file not shown.
BIN
assets/icon@2x.icns
Normal file
BIN
assets/icon@2x.icns
Normal file
Binary file not shown.
@ -36,9 +36,9 @@ myAngle = -120
|
|||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([8, 0], %)
|
|> line([8, 0], %)
|
||||||
|> angledLine({ angle = abs(myAngle), length = 5 }, %)
|
|> angledLine({ angle: abs(myAngle), length: 5 }, %)
|
||||||
|> line([-5, 0], %)
|
|> line([-5, 0], %)
|
||||||
|> angledLine({ angle = myAngle, length = 5 }, %)
|
|> angledLine({ angle: myAngle, length: 5 }, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
baseExtrusion = extrude(5, sketch001)
|
baseExtrusion = extrude(5, sketch001)
|
||||||
|
@ -34,8 +34,8 @@ acos(num: number) -> number
|
|||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = toDegrees(acos(0.5)),
|
angle: toDegrees(acos(0.5)),
|
||||||
length = 10
|
length: 10
|
||||||
}, %)
|
}, %)
|
||||||
|> line([5, 0], %)
|
|> line([5, 0], %)
|
||||||
|> lineTo([12, 0], %)
|
|> lineTo([12, 0], %)
|
||||||
|
@ -33,8 +33,8 @@ sketch001 = startSketchOn('XZ')
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([1, 2], %, $seg01)
|
|> line([1, 2], %, $seg01)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = angleToMatchLengthY(seg01, 15, %),
|
angle: angleToMatchLengthY(seg01, 15, %),
|
||||||
length = 5
|
length: 5
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -32,7 +32,7 @@ angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> yLineTo(15, %)
|
|> yLineTo(15, %)
|
||||||
|> angledLine({ angle = 30, length = 15 }, %)
|
|> angledLine({ angle: 30, length: 15 }, %)
|
||||||
|> line([8, -10], %)
|
|> line([8, -10], %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -31,8 +31,8 @@ angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLineOfXLength({ angle = 45, length = 10 }, %, $edge1)
|
|> angledLineOfXLength({ angle: 45, length: 10 }, %, $edge1)
|
||||||
|> angledLineOfXLength({ angle = -15, length = 20 }, %, $edge2)
|
|> angledLineOfXLength({ angle: -15, length: 20 }, %, $edge2)
|
||||||
|> line([0, -5], %)
|
|> line([0, -5], %)
|
||||||
|> close(%, $edge3)
|
|> close(%, $edge3)
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> angledLineOfYLength({ angle = 45, length = 10 }, %)
|
|> angledLineOfYLength({ angle: 45, length: 10 }, %)
|
||||||
|> line([0, 10], %)
|
|> line([0, 10], %)
|
||||||
|> angledLineOfYLength({ angle = 135, length = 10 }, %)
|
|> angledLineOfYLength({ angle: 135, length: 10 }, %)
|
||||||
|> line([-10, 0], %)
|
|> line([-10, 0], %)
|
||||||
|> line([0, -30], %)
|
|> line([0, -30], %)
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ exampleSketch = startSketchOn('XZ')
|
|||||||
|> lineTo([-10, 10], %, $lineToIntersect)
|
|> lineTo([-10, 10], %, $lineToIntersect)
|
||||||
|> lineTo([0, 20], %)
|
|> lineTo([0, 20], %)
|
||||||
|> angledLineThatIntersects({
|
|> angledLineThatIntersects({
|
||||||
angle = 80,
|
angle: 80,
|
||||||
intersectTag = lineToIntersect,
|
intersectTag: lineToIntersect,
|
||||||
offset = 10
|
offset: 10
|
||||||
}, %)
|
}, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLineToX({ angle = 30, to = 10 }, %)
|
|> angledLineToX({ angle: 30, to: 10 }, %)
|
||||||
|> line([0, 10], %)
|
|> line([0, 10], %)
|
||||||
|> line([-10, 0], %)
|
|> line([-10, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -31,9 +31,9 @@ angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLineToY({ angle = 60, to = 20 }, %)
|
|> angledLineToY({ angle: 60, to: 20 }, %)
|
||||||
|> line([-20, 0], %)
|
|> line([-20, 0], %)
|
||||||
|> angledLineToY({ angle = 70, to = 10 }, %)
|
|> angledLineToY({ angle: 70, to: 10 }, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = extrude(10, exampleSketch)
|
example = extrude(10, exampleSketch)
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -34,8 +34,8 @@ asin(num: number) -> number
|
|||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = toDegrees(asin(0.5)),
|
angle: toDegrees(asin(0.5)),
|
||||||
length = 20
|
length: 20
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -34,8 +34,8 @@ atan(num: number) -> number
|
|||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = toDegrees(atan(1.25)),
|
angle: toDegrees(atan(1.25)),
|
||||||
length = 20
|
length: 20
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -33,9 +33,9 @@ exampleSketch = startSketchOn('XZ')
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([0, 10], %)
|
|> line([0, 10], %)
|
||||||
|> bezierCurve({
|
|> bezierCurve({
|
||||||
to = [10, 10],
|
to: [10, 10],
|
||||||
control1 = [5, 0],
|
control1: [5, 0],
|
||||||
control2 = [5, 10]
|
control2: [5, 10]
|
||||||
}, %)
|
}, %)
|
||||||
|> lineTo([10, 0], %)
|
|> lineTo([10, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -44,8 +44,8 @@ mountingPlateSketch = startSketchOn("XY")
|
|||||||
|
|
||||||
mountingPlate = extrude(thickness, mountingPlateSketch)
|
mountingPlate = extrude(thickness, mountingPlateSketch)
|
||||||
|> chamfer({
|
|> chamfer({
|
||||||
length = chamferLength,
|
length: chamferLength,
|
||||||
tags = [
|
tags: [
|
||||||
getNextAdjacentEdge(edge1),
|
getNextAdjacentEdge(edge1),
|
||||||
getNextAdjacentEdge(edge2),
|
getNextAdjacentEdge(edge2),
|
||||||
getNextAdjacentEdge(edge3),
|
getNextAdjacentEdge(edge3),
|
||||||
@ -72,8 +72,8 @@ part001 = cube([0, 0], 20)
|
|||||||
|> close(%, $line1)
|
|> close(%, $line1)
|
||||||
|> extrude(20, %)
|
|> extrude(20, %)
|
||||||
|> chamfer({
|
|> chamfer({
|
||||||
length = 10,
|
length: 10,
|
||||||
tags = [getOppositeEdge(line1)]
|
tags: [getOppositeEdge(line1)]
|
||||||
}, %, $chamfer1) // We tag the chamfer to reference it later.
|
}, %, $chamfer1) // We tag the chamfer to reference it later.
|
||||||
|
|
||||||
sketch001 = startSketchOn(part001, chamfer1)
|
sketch001 = startSketchOn(part001, chamfer1)
|
||||||
|
@ -30,7 +30,7 @@ circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagDecl
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("-XZ")
|
exampleSketch = startSketchOn("-XZ")
|
||||||
|> circle({ center = [0, 0], radius = 10 }, %)
|
|> circle({ center: [0, 0], radius: 10 }, %)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
```
|
```
|
||||||
@ -44,7 +44,7 @@ exampleSketch = startSketchOn("XZ")
|
|||||||
|> line([0, 30], %)
|
|> line([0, 30], %)
|
||||||
|> line([-30, 0], %)
|
|> line([-30, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle({ center = [0, 15], radius = 5 }, %), %)
|
|> hole(circle({ center: [0, 15], radius: 5 }, %), %)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
```
|
```
|
||||||
|
@ -34,8 +34,8 @@ cos(num: number) -> number
|
|||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = 30,
|
angle: 30,
|
||||||
length = 3 / cos(toRadians(30))
|
length: 3 / cos(toRadians(30))
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -28,7 +28,7 @@ e() -> number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 30, length = 2 * e() ^ 2 }, %)
|
|> angledLine({ angle: 30, length: 2 * e() ^ 2 }, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -32,16 +32,16 @@ example = startSketchOn('XZ')
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> arc({
|
|> arc({
|
||||||
angleStart = 120,
|
angleStart: 120,
|
||||||
angleEnd = 0,
|
angleEnd: 0,
|
||||||
radius = 5
|
radius: 5
|
||||||
}, %)
|
}, %)
|
||||||
|> line([5, 0], %)
|
|> line([5, 0], %)
|
||||||
|> line([0, 10], %)
|
|> line([0, 10], %)
|
||||||
|> bezierCurve({
|
|> bezierCurve({
|
||||||
control1 = [-10, 0],
|
control1: [-10, 0],
|
||||||
control2 = [2, 10],
|
control2: [2, 10],
|
||||||
to = [-5, 10]
|
to: [-5, 10]
|
||||||
}, %)
|
}, %)
|
||||||
|> line([-5, -2], %)
|
|> line([-5, -2], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
@ -54,16 +54,16 @@ example = startSketchOn('XZ')
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([-10, 0], %)
|
|> startProfileAt([-10, 0], %)
|
||||||
|> arc({
|
|> arc({
|
||||||
angleStart = 120,
|
angleStart: 120,
|
||||||
angleEnd = -60,
|
angleEnd: -60,
|
||||||
radius = 5
|
radius: 5
|
||||||
}, %)
|
}, %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> line([5, 0], %)
|
|> line([5, 0], %)
|
||||||
|> bezierCurve({
|
|> bezierCurve({
|
||||||
control1 = [-3, 0],
|
control1: [-3, 0],
|
||||||
control2 = [2, 10],
|
control2: [2, 10],
|
||||||
to = [-5, 10]
|
to: [-5, 10]
|
||||||
}, %)
|
}, %)
|
||||||
|> line([-4, 10], %)
|
|> line([-4, 10], %)
|
||||||
|> line([-5, -2], %)
|
|> line([-5, -2], %)
|
||||||
|
@ -43,8 +43,8 @@ mountingPlateSketch = startSketchOn("XY")
|
|||||||
|
|
||||||
mountingPlate = extrude(thickness, mountingPlateSketch)
|
mountingPlate = extrude(thickness, mountingPlateSketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius = filletRadius,
|
radius: filletRadius,
|
||||||
tags = [
|
tags: [
|
||||||
getNextAdjacentEdge(edge1),
|
getNextAdjacentEdge(edge1),
|
||||||
getNextAdjacentEdge(edge2),
|
getNextAdjacentEdge(edge2),
|
||||||
getNextAdjacentEdge(edge3),
|
getNextAdjacentEdge(edge3),
|
||||||
@ -70,9 +70,9 @@ mountingPlateSketch = startSketchOn("XY")
|
|||||||
|
|
||||||
mountingPlate = extrude(thickness, mountingPlateSketch)
|
mountingPlate = extrude(thickness, mountingPlateSketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius = filletRadius,
|
radius: filletRadius,
|
||||||
tolerance = 0.000001,
|
tolerance: 0.000001,
|
||||||
tags = [
|
tags: [
|
||||||
getNextAdjacentEdge(edge1),
|
getNextAdjacentEdge(edge1),
|
||||||
getNextAdjacentEdge(edge2),
|
getNextAdjacentEdge(edge2),
|
||||||
getNextAdjacentEdge(edge3),
|
getNextAdjacentEdge(edge3),
|
||||||
|
@ -30,16 +30,16 @@ getNextAdjacentEdge(tag: TagIdentifier) -> Uuid
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine({ angle: 60, length: 10 }, %)
|
||||||
|> angledLine({ angle = 120, length = 10 }, %)
|
|> angledLine({ angle: 120, length: 10 }, %)
|
||||||
|> line([-10, 0], %)
|
|> line([-10, 0], %)
|
||||||
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|
|> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius = 3,
|
radius: 3,
|
||||||
tags = [getNextAdjacentEdge(referenceEdge)]
|
tags: [getNextAdjacentEdge(referenceEdge)]
|
||||||
}, %)
|
}, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -30,16 +30,16 @@ getOppositeEdge(tag: TagIdentifier) -> Uuid
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine({ angle: 60, length: 10 }, %)
|
||||||
|> angledLine({ angle = 120, length = 10 }, %)
|
|> angledLine({ angle: 120, length: 10 }, %)
|
||||||
|> line([-10, 0], %)
|
|> line([-10, 0], %)
|
||||||
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|
|> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius = 3,
|
radius: 3,
|
||||||
tags = [getOppositeEdge(referenceEdge)]
|
tags: [getOppositeEdge(referenceEdge)]
|
||||||
}, %)
|
}, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -30,16 +30,16 @@ getPreviousAdjacentEdge(tag: TagIdentifier) -> Uuid
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine({ angle: 60, length: 10 }, %)
|
||||||
|> angledLine({ angle = 120, length = 10 }, %)
|
|> angledLine({ angle: 120, length: 10 }, %)
|
||||||
|> line([-10, 0], %)
|
|> line([-10, 0], %)
|
||||||
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|
|> angledLine({ angle: 240, length: 10 }, %, $referenceEdge)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius = 3,
|
radius: 3,
|
||||||
tags = [getPreviousAdjacentEdge(referenceEdge)]
|
tags: [getPreviousAdjacentEdge(referenceEdge)]
|
||||||
}, %)
|
}, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -29,12 +29,12 @@ helix(data: HelixData, solid: Solid) -> Solid
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
part001 = startSketchOn('XY')
|
part001 = startSketchOn('XY')
|
||||||
|> circle({ center = [5, 5], radius = 10 }, %)
|
|> circle({ center: [5, 5], radius: 10 }, %)
|
||||||
|> extrude(10, %)
|
|> extrude(10, %)
|
||||||
|> helix({
|
|> helix({
|
||||||
angleStart = 0,
|
angleStart: 0,
|
||||||
ccw = true,
|
ccw: true,
|
||||||
revolutions = 16
|
revolutions: 16
|
||||||
}, %)
|
}, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ exampleSketch = startSketchOn('XY')
|
|||||||
|> line([5, 0], %)
|
|> line([5, 0], %)
|
||||||
|> line([0, -5], %)
|
|> line([0, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle({ center = [1, 1], radius = .25 }, %), %)
|
|> hole(circle({ center: [1, 1], radius: .25 }, %), %)
|
||||||
|> hole(circle({ center = [1, 4], radius = .25 }, %), %)
|
|> hole(circle({ center: [1, 4], radius: .25 }, %), %)
|
||||||
|
|
||||||
example = extrude(1, exampleSketch)
|
example = extrude(1, exampleSketch)
|
||||||
```
|
```
|
||||||
@ -54,7 +54,7 @@ fn squareHoleSketch = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exampleSketch = startSketchOn('-XZ')
|
exampleSketch = startSketchOn('-XZ')
|
||||||
|> circle({ center = [0, 0], radius = 3 }, %)
|
|> circle({ center: [0, 0], radius: 3 }, %)
|
||||||
|> hole(squareHoleSketch(), %)
|
|> hole(squareHoleSketch(), %)
|
||||||
example = extrude(1, exampleSketch)
|
example = extrude(1, exampleSketch)
|
||||||
```
|
```
|
||||||
|
@ -68,15 +68,15 @@ case = startSketchOn('-XZ')
|
|||||||
|
|
||||||
thing1 = startSketchOn(case, 'end')
|
thing1 = startSketchOn(case, 'end')
|
||||||
|> circle({
|
|> circle({
|
||||||
center = [-size / 2, -size / 2],
|
center: [-size / 2, -size / 2],
|
||||||
radius = 25
|
radius: 25
|
||||||
}, %)
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
thing2 = startSketchOn(case, 'end')
|
thing2 = startSketchOn(case, 'end')
|
||||||
|> circle({
|
|> circle({
|
||||||
center = [size / 2, -size / 2],
|
center: [size / 2, -size / 2],
|
||||||
radius = 25
|
radius: 25
|
||||||
}, %)
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -7,7 +7,6 @@ layout: manual
|
|||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
* [Types](kcl/types)
|
* [Types](kcl/types)
|
||||||
* [Modules](kcl/modules)
|
|
||||||
* [Known Issues](kcl/KNOWN-ISSUES)
|
* [Known Issues](kcl/KNOWN-ISSUES)
|
||||||
* [`abs`](kcl/abs)
|
* [`abs`](kcl/abs)
|
||||||
* [`acos`](kcl/acos)
|
* [`acos`](kcl/acos)
|
||||||
@ -20,7 +19,6 @@ layout: manual
|
|||||||
* [`angledLineToX`](kcl/angledLineToX)
|
* [`angledLineToX`](kcl/angledLineToX)
|
||||||
* [`angledLineToY`](kcl/angledLineToY)
|
* [`angledLineToY`](kcl/angledLineToY)
|
||||||
* [`arc`](kcl/arc)
|
* [`arc`](kcl/arc)
|
||||||
* [`arcTo`](kcl/arcTo)
|
|
||||||
* [`asin`](kcl/asin)
|
* [`asin`](kcl/asin)
|
||||||
* [`assert`](kcl/assert)
|
* [`assert`](kcl/assert)
|
||||||
* [`assertEqual`](kcl/assertEqual)
|
* [`assertEqual`](kcl/assertEqual)
|
||||||
@ -74,7 +72,6 @@ layout: manual
|
|||||||
* [`patternLinear2d`](kcl/patternLinear2d)
|
* [`patternLinear2d`](kcl/patternLinear2d)
|
||||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||||
* [`patternTransform`](kcl/patternTransform)
|
* [`patternTransform`](kcl/patternTransform)
|
||||||
* [`patternTransform2d`](kcl/patternTransform2d)
|
|
||||||
* [`pi`](kcl/pi)
|
* [`pi`](kcl/pi)
|
||||||
* [`polar`](kcl/polar)
|
* [`polar`](kcl/polar)
|
||||||
* [`polygon`](kcl/polygon)
|
* [`polygon`](kcl/polygon)
|
||||||
@ -86,7 +83,6 @@ layout: manual
|
|||||||
* [`reduce`](kcl/reduce)
|
* [`reduce`](kcl/reduce)
|
||||||
* [`rem`](kcl/rem)
|
* [`rem`](kcl/rem)
|
||||||
* [`revolve`](kcl/revolve)
|
* [`revolve`](kcl/revolve)
|
||||||
* [`round`](kcl/round)
|
|
||||||
* [`segAng`](kcl/segAng)
|
* [`segAng`](kcl/segAng)
|
||||||
* [`segEnd`](kcl/segEnd)
|
* [`segEnd`](kcl/segEnd)
|
||||||
* [`segEndX`](kcl/segEndX)
|
* [`segEndX`](kcl/segEndX)
|
||||||
@ -102,7 +98,6 @@ layout: manual
|
|||||||
* [`startSketchAt`](kcl/startSketchAt)
|
* [`startSketchAt`](kcl/startSketchAt)
|
||||||
* [`startSketchOn`](kcl/startSketchOn)
|
* [`startSketchOn`](kcl/startSketchOn)
|
||||||
* [`tan`](kcl/tan)
|
* [`tan`](kcl/tan)
|
||||||
* [`tangentToEnd`](kcl/tangentToEnd)
|
|
||||||
* [`tangentialArc`](kcl/tangentialArc)
|
* [`tangentialArc`](kcl/tangentialArc)
|
||||||
* [`tangentialArcTo`](kcl/tangentialArcTo)
|
* [`tangentialArcTo`](kcl/tangentialArcTo)
|
||||||
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
|
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -60,10 +60,10 @@ squareSketch = startSketchOn('XY')
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
||||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
|> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
|
|
||||||
circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
||||||
|> circle({ center = [0, 100], radius = 20 }, %)
|
|> circle({ center: [0, 100], radius: 20 }, %)
|
||||||
|
|
||||||
loft([
|
loft([
|
||||||
squareSketch,
|
squareSketch,
|
||||||
@ -85,10 +85,10 @@ squareSketch = startSketchOn('XY')
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
||||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
|> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
|
|
||||||
circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
||||||
|> circle({ center = [0, 100], radius = 20 }, %)
|
|> circle({ center: [0, 100], radius: 20 }, %)
|
||||||
|
|
||||||
loft([
|
loft([
|
||||||
squareSketch,
|
squareSketch,
|
||||||
@ -97,17 +97,17 @@ loft([
|
|||||||
], {
|
], {
|
||||||
// This can be set to override the automatically determined
|
// This can be set to override the automatically determined
|
||||||
// topological base curve, which is usually the first section encountered.
|
// topological base curve, which is usually the first section encountered.
|
||||||
baseCurveIndex = 0,
|
baseCurveIndex: 0,
|
||||||
// Attempt to approximate rational curves (such as arcs) using a bezier.
|
// Attempt to approximate rational curves (such as arcs) using a bezier.
|
||||||
// This will remove banding around interpolations between arcs and non-arcs.
|
// This will remove banding around interpolations between arcs and non-arcs.
|
||||||
// It may produce errors in other scenarios Over time, this field won't be necessary.
|
// It may produce errors in other scenarios Over time, this field won't be necessary.
|
||||||
bezApproximateRational = false,
|
bezApproximateRational: false,
|
||||||
// Tolerance for the loft operation.
|
// Tolerance for the loft operation.
|
||||||
tolerance = 0.000001,
|
tolerance: 0.000001,
|
||||||
// Degree of the interpolation. Must be greater than zero.
|
// Degree of the interpolation. Must be greater than zero.
|
||||||
// For example, use 2 for quadratic, or 3 for cubic interpolation in
|
// For example, use 2 for quadratic, or 3 for cubic interpolation in
|
||||||
// the V direction. This defaults to 2, if not specified.
|
// the V direction. This defaults to 2, if not specified.
|
||||||
vDegree = 2
|
vDegree: 2
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ map(array: [KclValue], map_fn: FunctionParam) -> [KclValue]
|
|||||||
r = 10 // radius
|
r = 10 // radius
|
||||||
fn drawCircle = (id) => {
|
fn drawCircle = (id) => {
|
||||||
return startSketchOn("XY")
|
return startSketchOn("XY")
|
||||||
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|
|> circle({ center: [id * 2 * r, 0], radius: r }, %)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call `drawCircle`, passing in each element of the array.
|
// Call `drawCircle`, passing in each element of the array.
|
||||||
@ -47,7 +47,7 @@ r = 10 // radius
|
|||||||
// Call `map`, using an anonymous function instead of a named one.
|
// Call `map`, using an anonymous function instead of a named one.
|
||||||
circles = map([1..3], (id) => {
|
circles = map([1..3], (id) => {
|
||||||
return startSketchOn("XY")
|
return startSketchOn("XY")
|
||||||
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|
|> circle({ center: [id * 2 * r, 0], radius: r }, %)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ max(args: [number]) -> number
|
|||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = 70,
|
angle: 70,
|
||||||
length = max(15, 31, 4, 13, 22)
|
length: max(15, 31, 4, 13, 22)
|
||||||
}, %)
|
}, %)
|
||||||
|> line([20, 0], %)
|
|> line([20, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -34,8 +34,8 @@ min(args: [number]) -> number
|
|||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = 70,
|
angle: 70,
|
||||||
length = min(15, 31, 4, 13, 22)
|
length: min(15, 31, 4, 13, 22)
|
||||||
}, %)
|
}, %)
|
||||||
|> line([20, 0], %)
|
|> line([20, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -41,7 +41,7 @@ sketch001 = startSketchOn('XZ')
|
|||||||
|> line([-8, -3], %)
|
|> line([-8, -3], %)
|
||||||
|> line([9, -1], %)
|
|> line([9, -1], %)
|
||||||
|> line([-19, -0], %)
|
|> line([-19, -0], %)
|
||||||
|> mirror2d({ axis = 'Y' }, %)
|
|> mirror2d({ axis: 'Y' }, %)
|
||||||
|
|
||||||
example = extrude(10, sketch001)
|
example = extrude(10, sketch001)
|
||||||
```
|
```
|
||||||
@ -54,7 +54,7 @@ sketch001 = startSketchOn('XZ')
|
|||||||
|> startProfileAt([0, 8.5], %)
|
|> startProfileAt([0, 8.5], %)
|
||||||
|> line([20, -8.5], %)
|
|> line([20, -8.5], %)
|
||||||
|> line([-20, -8.5], %)
|
|> line([-20, -8.5], %)
|
||||||
|> mirror2d({ axis = 'Y' }, %)
|
|> mirror2d({ axis: 'Y' }, %)
|
||||||
|
|
||||||
example = extrude(10, sketch001)
|
example = extrude(10, sketch001)
|
||||||
```
|
```
|
||||||
@ -71,7 +71,7 @@ sketch001 = startSketchOn('XZ')
|
|||||||
|> startProfileAt([0, 8.5], %)
|
|> startProfileAt([0, 8.5], %)
|
||||||
|> line([20, -8.5], %)
|
|> line([20, -8.5], %)
|
||||||
|> line([-20, -8.5], %)
|
|> line([-20, -8.5], %)
|
||||||
|> mirror2d({ axis = edge001 }, %)
|
|> mirror2d({ axis: edge001 }, %)
|
||||||
|
|
||||||
example = extrude(10, sketch001)
|
example = extrude(10, sketch001)
|
||||||
```
|
```
|
||||||
@ -85,11 +85,8 @@ sketch001 = startSketchOn('XZ')
|
|||||||
|> line([20, -8.5], %)
|
|> line([20, -8.5], %)
|
||||||
|> line([-20, -8.5], %)
|
|> line([-20, -8.5], %)
|
||||||
|> mirror2d({
|
|> mirror2d({
|
||||||
axis = {
|
axis: {
|
||||||
custom = {
|
custom: { axis: [0.0, 1.0], origin: [0.0, 0.0] }
|
||||||
axis = [0.0, 1.0],
|
|
||||||
origin = [0.0, 0.0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Offset a plane by a distance along its normal.
|
|||||||
For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it.
|
For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ' plane and 10 units away from it.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
offsetPlane(std_plane: StandardPlane, offset: number) -> Plane
|
offsetPlane(std_plane: StandardPlane, offset: number) -> PlaneData
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ offsetPlane(std_plane: StandardPlane, offset: number) -> Plane
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`Plane`](/docs/kcl/types/Plane) - A plane.
|
[`PlaneData`](/docs/kcl/types/PlaneData) - Data for a plane.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@ -38,7 +38,7 @@ squareSketch = startSketchOn('XY')
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
circleSketch = startSketchOn(offsetPlane('XY', 150))
|
circleSketch = startSketchOn(offsetPlane('XY', 150))
|
||||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
|> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
|
|
||||||
loft([squareSketch, circleSketch])
|
loft([squareSketch, circleSketch])
|
||||||
```
|
```
|
||||||
@ -56,7 +56,7 @@ squareSketch = startSketchOn('XZ')
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
circleSketch = startSketchOn(offsetPlane('XZ', 150))
|
circleSketch = startSketchOn(offsetPlane('XZ', 150))
|
||||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
|> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
|
|
||||||
loft([squareSketch, circleSketch])
|
loft([squareSketch, circleSketch])
|
||||||
```
|
```
|
||||||
@ -74,7 +74,7 @@ squareSketch = startSketchOn('YZ')
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
circleSketch = startSketchOn(offsetPlane('YZ', 150))
|
circleSketch = startSketchOn(offsetPlane('YZ', 150))
|
||||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
|> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
|
|
||||||
loft([squareSketch, circleSketch])
|
loft([squareSketch, circleSketch])
|
||||||
```
|
```
|
||||||
@ -92,7 +92,7 @@ squareSketch = startSketchOn('-XZ')
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
circleSketch = startSketchOn(offsetPlane('-XZ', -150))
|
circleSketch = startSketchOn(offsetPlane('-XZ', -150))
|
||||||
|> circle({ center = [0, 100], radius = 50 }, %)
|
|> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
|
|
||||||
loft([squareSketch, circleSketch])
|
loft([squareSketch, circleSketch])
|
||||||
```
|
```
|
||||||
@ -103,7 +103,7 @@ loft([squareSketch, circleSketch])
|
|||||||
// A circle on the XY plane
|
// A circle on the XY plane
|
||||||
startSketchOn("XY")
|
startSketchOn("XY")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> circle({ radius = 10, center = [0, 0] }, %)
|
|> circle({ radius: 10, center: [0, 0] }, %)
|
||||||
|
|
||||||
// Triangle on the plane 4 units above
|
// Triangle on the plane 4 units above
|
||||||
startSketchOn(offsetPlane("XY", 4))
|
startSketchOn(offsetPlane("XY", 4))
|
||||||
|
@ -35,10 +35,10 @@ exampleSketch = startSketchOn('XZ')
|
|||||||
|> line([0, -5], %)
|
|> line([0, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> patternCircular2d({
|
|> patternCircular2d({
|
||||||
center = [0, 0],
|
center: [0, 0],
|
||||||
instances = 13,
|
instances: 13,
|
||||||
arcDegrees = 360,
|
arcDegrees: 360,
|
||||||
rotateDuplicates = true
|
rotateDuplicates: true
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
example = extrude(1, exampleSketch)
|
example = extrude(1, exampleSketch)
|
||||||
|
@ -29,15 +29,15 @@ patternCircular3d(data: CircularPattern3dData, solid_set: SolidSet) -> [Solid]
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
|> circle({ center: [0, 0], radius: 1 }, %)
|
||||||
|
|
||||||
example = extrude(-5, exampleSketch)
|
example = extrude(-5, exampleSketch)
|
||||||
|> patternCircular3d({
|
|> patternCircular3d({
|
||||||
axis = [1, -1, 0],
|
axis: [1, -1, 0],
|
||||||
center = [10, -20, 0],
|
center: [10, -20, 0],
|
||||||
instances = 11,
|
instances: 11,
|
||||||
arcDegrees = 360,
|
arcDegrees: 360,
|
||||||
rotateDuplicates = true
|
rotateDuplicates: true
|
||||||
}, %)
|
}, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet) -> [Sketch]
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> circle({ center = [0, 0], radius = 1 }, %)
|
|> circle({ center: [0, 0], radius: 1 }, %)
|
||||||
|> patternLinear2d({
|
|> patternLinear2d({
|
||||||
axis = [1, 0],
|
axis: [1, 0],
|
||||||
instances = 7,
|
instances: 7,
|
||||||
distance = 4
|
distance: 4
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
example = extrude(1, exampleSketch)
|
example = extrude(1, exampleSketch)
|
||||||
|
@ -37,9 +37,9 @@ exampleSketch = startSketchOn('XZ')
|
|||||||
|
|
||||||
example = extrude(1, exampleSketch)
|
example = extrude(1, exampleSketch)
|
||||||
|> patternLinear3d({
|
|> patternLinear3d({
|
||||||
axis = [1, 0, 1],
|
axis: [1, 0, 1],
|
||||||
instances = 7,
|
instances: 7,
|
||||||
distance = 6
|
distance: 6
|
||||||
}, %)
|
}, %)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -30,8 +30,8 @@ circumference = 70
|
|||||||
|
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> circle({
|
|> circle({
|
||||||
center = [0, 0],
|
center: [0, 0],
|
||||||
radius = circumference / (2 * pi())
|
radius: circumference / (2 * pi())
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
|
@ -29,7 +29,7 @@ polar(data: PolarCoordsData) -> [number]
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(polar({ angle = 30, length = 5 }), %, $thing)
|
|> line(polar({ angle: 30, length: 5 }), %, $thing)
|
||||||
|> line([0, 5], %)
|
|> line([0, 5], %)
|
||||||
|> line([segEndX(thing), 0], %)
|
|> line([segEndX(thing), 0], %)
|
||||||
|> line([-20, 10], %)
|
|> line([-20, 10], %)
|
||||||
|
@ -32,10 +32,10 @@ polygon(data: PolygonData, sketch_surface_or_group: SketchOrSurface, tag?: TagDe
|
|||||||
// Create a regular hexagon inscribed in a circle of radius 10
|
// Create a regular hexagon inscribed in a circle of radius 10
|
||||||
hex = startSketchOn('XY')
|
hex = startSketchOn('XY')
|
||||||
|> polygon({
|
|> polygon({
|
||||||
radius = 10,
|
radius: 10,
|
||||||
numSides = 6,
|
numSides: 6,
|
||||||
center = [0, 0],
|
center: [0, 0],
|
||||||
inscribed = true
|
inscribed: true
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
example = extrude(5, hex)
|
example = extrude(5, hex)
|
||||||
@ -47,10 +47,10 @@ example = extrude(5, hex)
|
|||||||
// Create a square circumscribed around a circle of radius 5
|
// Create a square circumscribed around a circle of radius 5
|
||||||
square = startSketchOn('XY')
|
square = startSketchOn('XY')
|
||||||
|> polygon({
|
|> polygon({
|
||||||
radius = 5.0,
|
radius: 5.0,
|
||||||
numSides = 4,
|
numSides: 4,
|
||||||
center = [10, 10],
|
center: [10, 10],
|
||||||
inscribed = false
|
inscribed: false
|
||||||
}, %)
|
}, %)
|
||||||
example = extrude(5, square)
|
example = extrude(5, square)
|
||||||
```
|
```
|
||||||
|
@ -34,7 +34,7 @@ pow(num: number, pow: number) -> number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = pow(5, 2) }, %)
|
|> angledLine({ angle: 50, length: pow(5, 2) }, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ profileStart(sketch: Sketch) -> [number]
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn('XY')
|
sketch001 = startSketchOn('XY')
|
||||||
|> startProfileAt([5, 2], %)
|
|> startProfileAt([5, 2], %)
|
||||||
|> angledLine({ angle = 120, length = 50 }, %, $seg01)
|
|> angledLine({ angle: 120, length: 50 }, %, $seg01)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = segAng(seg01) + 120,
|
angle: segAng(seg01) + 120,
|
||||||
length = 50
|
length: 50
|
||||||
}, %)
|
}, %)
|
||||||
|> lineTo(profileStart(%), %)
|
|> lineTo(profileStart(%), %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -38,11 +38,8 @@ cube = startSketchAt([0, 0])
|
|||||||
|
|
||||||
fn cylinder = (radius, tag) => {
|
fn cylinder = (radius, tag) => {
|
||||||
return startSketchAt([0, 0])
|
return startSketchAt([0, 0])
|
||||||
|> circle({
|
|> circle({ radius: radius, center: segEnd(tag) }, %)
|
||||||
radius = radius,
|
|> extrude(radius, %)
|
||||||
center = segEnd(tag)
|
|
||||||
}, %)
|
|
||||||
|> extrude(radius, %)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cylinder(1, line1)
|
cylinder(1, line1)
|
||||||
|
@ -29,9 +29,9 @@ segLen(tag: TagIdentifier) -> number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %, $thing)
|
|> angledLine({ angle: 60, length: 10 }, %, $thing)
|
||||||
|> tangentialArc({ offset = -120, radius = 5 }, %)
|
|> tangentialArc({ offset: -120, radius: 5 }, %)
|
||||||
|> angledLine({ angle = -60, length = segLen(thing) }, %)
|
|> angledLine({ angle: -60, length: segLen(thing) }, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = extrude(5, exampleSketch)
|
example = extrude(5, exampleSketch)
|
||||||
|
@ -38,11 +38,11 @@ cube = startSketchAt([0, 0])
|
|||||||
|
|
||||||
fn cylinder = (radius, tag) => {
|
fn cylinder = (radius, tag) => {
|
||||||
return startSketchAt([0, 0])
|
return startSketchAt([0, 0])
|
||||||
|> circle({
|
|> circle({
|
||||||
radius = radius,
|
radius: radius,
|
||||||
center = segStart(tag)
|
center: segStart(tag)
|
||||||
}, %)
|
}, %)
|
||||||
|> extrude(radius, %)
|
|> extrude(radius, %)
|
||||||
}
|
}
|
||||||
|
|
||||||
cylinder(1, line1)
|
cylinder(1, line1)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -34,8 +34,8 @@ sin(num: number) -> number
|
|||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = 50,
|
angle: 50,
|
||||||
length = 15 / sin(toDegrees(135))
|
length: 15 / sin(toDegrees(135))
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -33,7 +33,7 @@ sqrt(num: number) -> number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = sqrt(2500) }, %)
|
|> angledLine({ angle: 50, length: sqrt(2500) }, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ exampleSketch = startSketchOn('XY')
|
|||||||
|> line([-2, 0], %)
|
|> line([-2, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = revolve({ axis = 'y', angle = 180 }, exampleSketch)
|
example = revolve({ axis: 'y', angle: 180 }, exampleSketch)
|
||||||
|
|
||||||
exampleSketch002 = startSketchOn(example, 'end')
|
exampleSketch002 = startSketchOn(example, 'end')
|
||||||
|> startProfileAt([4.5, -5], %)
|
|> startProfileAt([4.5, -5], %)
|
||||||
@ -117,11 +117,11 @@ example002 = extrude(5, exampleSketch002)
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
a1 = startSketchOn({
|
a1 = startSketchOn({
|
||||||
plane = {
|
plane: {
|
||||||
origin = { x = 0, y = 0, z = 0 },
|
origin: { x: 0, y: 0, z: 0 },
|
||||||
xAxis = { x = 1, y = 0, z = 0 },
|
xAxis: { x: 1, y: 0, z: 0 },
|
||||||
yAxis = { x = 0, y = 1, z = 0 },
|
yAxis: { x: 0, y: 1, z: 0 },
|
||||||
zAxis = { x = 0, y = 0, z = 1 }
|
zAxis: { x: 0, y: 0, z: 1 }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|
9659
docs/kcl/std.json
9659
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@ tan(num: number) -> number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = 50 * tan(1 / 2) }, %)
|
|> angledLine({ angle: 50, length: 50 * tan(1 / 2) }, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -31,9 +31,9 @@ tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> S
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine({ angle: 60, length: 10 }, %)
|
||||||
|> tangentialArc({ radius = 10, offset = -120 }, %)
|
|> tangentialArc({ radius: 10, offset: -120 }, %)
|
||||||
|> angledLine({ angle = -60, length = 10 }, %)
|
|> angledLine({ angle: -60, length: 10 }, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
example = extrude(10, exampleSketch)
|
example = extrude(10, exampleSketch)
|
||||||
|
@ -31,7 +31,7 @@ tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine({ angle: 60, length: 10 }, %)
|
||||||
|> tangentialArcTo([15, 15], %)
|
|> tangentialArcTo([15, 15], %)
|
||||||
|> line([10, -15], %)
|
|> line([10, -15], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -31,7 +31,7 @@ tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) ->
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 45, length = 10 }, %)
|
|> angledLine({ angle: 45, length: 10 }, %)
|
||||||
|> tangentialArcToRelative([0, -10], %)
|
|> tangentialArcToRelative([0, -10], %)
|
||||||
|> line([-10, 0], %)
|
|> line([-10, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -28,7 +28,7 @@ tau() -> number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = 10 * tau() }, %)
|
|> angledLine({ angle: 50, length: 10 * tau() }, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ toDegrees(num: number) -> number
|
|||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = 50,
|
angle: 50,
|
||||||
length = 70 * cos(toDegrees(pi() / 4))
|
length: 70 * cos(toDegrees(pi() / 4))
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -34,8 +34,8 @@ toRadians(num: number) -> number
|
|||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine({
|
||||||
angle = 50,
|
angle: 50,
|
||||||
length = 70 * cos(toRadians(45))
|
length: 70 * cos(toRadians(45))
|
||||||
}, %)
|
}, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
title: "ArcToData"
|
|
||||||
excerpt: "Data to draw a three point arc (arcTo)."
|
|
||||||
layout: manual
|
|
||||||
---
|
|
||||||
|
|
||||||
Data to draw a three point arc (arcTo).
|
|
||||||
|
|
||||||
**Type:** `object`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
| Property | Type | Description | Required |
|
|
||||||
|----------|------|-------------|----------|
|
|
||||||
| `end` |`[number, number]`| End point of the arc. A point in 3D space | No |
|
|
||||||
| `interior` |`[number, number]`| Interior point of the arc. A point in 3D space | No |
|
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ Data for a circular pattern on a 2D sketch.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||||
| `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No |
|
| `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No |
|
||||||
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
|
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
|
||||||
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
|
| `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No |
|
||||||
|
@ -16,7 +16,7 @@ Data for a circular pattern on a 3D model.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||||
| `axis` |`[number, number, number]`| The axis around which to make the pattern. This is a 3D vector. | No |
|
| `axis` |`[number, number, number]`| The axis around which to make the pattern. This is a 3D vector. | No |
|
||||||
| `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No |
|
| `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No |
|
||||||
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
|
| `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No |
|
||||||
|
@ -24,7 +24,7 @@ Autodesk Filmbox (FBX) format
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `fbx`| | No |
|
| `type` |enum: `fbx`| | No |
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
@ -40,7 +40,7 @@ Binary glTF 2.0. We refer to this as glTF since that is how our customers refer
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `gltf`| | No |
|
| `type` |enum: `gltf`| | No |
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
@ -56,7 +56,7 @@ Wavefront OBJ format.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `obj`| | No |
|
| `type` |enum: `obj`| | No |
|
||||||
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
|
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
|
||||||
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
|
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ The PLY Polygon File Format.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `ply`| | No |
|
| `type` |enum: `ply`| | No |
|
||||||
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
|
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
|
||||||
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
|
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ SolidWorks part (SLDPRT) format.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `sldprt`| | No |
|
| `type` |enum: `sldprt`| | No |
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
@ -108,7 +108,7 @@ ISO 10303-21 (STEP) format.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `step`| | No |
|
| `type` |enum: `step`| | No |
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
@ -124,7 +124,7 @@ ST**ereo**L**ithography format.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `format` |enum: `stl`| | No |
|
| `type` |enum: `stl`| | No |
|
||||||
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
|
| `coords` |[`System`](/docs/kcl/types/System)| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No |
|
||||||
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
|
| `units` |[`UnitLength`](/docs/kcl/types/UnitLength)| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No |
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ A plane.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `type` |enum: [`Plane`](/docs/kcl/types/Plane)| | No |
|
| `type` |enum: `Plane`| | No |
|
||||||
| `id` |`string`| The id of the plane. | No |
|
| `id` |`string`| The id of the plane. | No |
|
||||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Any KCL value. | No |
|
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Any KCL value. | No |
|
||||||
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
||||||
|
@ -16,7 +16,7 @@ Data for a linear pattern on a 2D sketch.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||||
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
|
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
|
||||||
| `axis` |`[number, number]`| The axis of the pattern. This is a 2D vector. | No |
|
| `axis` |`[number, number]`| The axis of the pattern. This is a 2D vector. | No |
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ Data for a linear pattern on a 3D model.
|
|||||||
|
|
||||||
| Property | Type | Description | Required |
|
| Property | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `instances` |`integer`| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
| `instances` |[`Uint`](/docs/kcl/types/Uint)| The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | No |
|
||||||
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
|
| `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No |
|
||||||
| `axis` |`[number, number, number]`| The axis of the pattern. | No |
|
| `axis` |`[number, number, number]`| The axis of the pattern. | No |
|
||||||
|
|
||||||
|
@ -11,6 +11,16 @@ layout: manual
|
|||||||
**This schema accepts any of the following:**
|
**This schema accepts any of the following:**
|
||||||
|
|
||||||
|
|
||||||
|
**Type:** `integer` (`int64`)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
**Type:** `number` (`double`)
|
**Type:** `number` (`double`)
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ a complete arc
|
|||||||
| `type` |enum: `Circle`| | No |
|
| `type` |enum: `Circle`| | No |
|
||||||
| `center` |`[number, number]`| the arc's center | No |
|
| `center` |`[number, number]`| the arc's center | No |
|
||||||
| `radius` |`number`| the arc's radius | No |
|
| `radius` |`number`| the arc's radius | No |
|
||||||
| `ccw` |`boolean`| arc's direction This is used to compute the tangential angle. | No |
|
| `ccw` |`boolean`| arc's direction | No |
|
||||||
| `from` |`[number, number]`| The from point. | No |
|
| `from` |`[number, number]`| The from point. | No |
|
||||||
| `to` |`[number, number]`| The to point. | No |
|
| `to` |`[number, number]`| The to point. | No |
|
||||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||||
@ -177,7 +177,6 @@ A circular arc, not necessarily tangential to the current point.
|
|||||||
| `type` |enum: `Arc`| | No |
|
| `type` |enum: `Arc`| | No |
|
||||||
| `center` |`[number, number]`| Center of the circle that this arc is drawn on. | No |
|
| `center` |`[number, number]`| Center of the circle that this arc is drawn on. | No |
|
||||||
| `radius` |`number`| Radius of the circle that this arc is drawn on. | No |
|
| `radius` |`number`| Radius of the circle that this arc is drawn on. | No |
|
||||||
| `ccw` |`boolean`| True if the arc is counterclockwise. | No |
|
|
||||||
| `from` |`[number, number]`| The from point. | No |
|
| `from` |`[number, number]`| The from point. | No |
|
||||||
| `to` |`[number, number]`| The to point. | No |
|
| `to` |`[number, number]`| The to point. | No |
|
||||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Plane"
|
|
||||||
excerpt: "A plane."
|
|
||||||
layout: manual
|
|
||||||
---
|
|
||||||
|
|
||||||
A plane.
|
|
||||||
|
|
||||||
**Type:** `object`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
| Property | Type | Description | Required |
|
|
||||||
|----------|------|-------------|----------|
|
|
||||||
| `id` |`string`| The id of the plane. | No |
|
|
||||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| A plane. | No |
|
|
||||||
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
|
||||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
|
||||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
|
||||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
|
||||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
|
||||||
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: "PlaneData"
|
title: "PlaneData"
|
||||||
excerpt: "Orientation data that can be used to construct a plane, not a plane in itself."
|
excerpt: "Data for a plane."
|
||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
Orientation data that can be used to construct a plane, not a plane in itself.
|
Data for a plane.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,18 +22,6 @@ Data for start sketch on. You can start a sketch on a plane or an solid.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
Data for start sketch on. You can start a sketch on a plane or an solid.
|
|
||||||
|
|
||||||
[`Plane`](/docs/kcl/types/Plane)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
Data for start sketch on. You can start a sketch on a plane or an solid.
|
Data for start sketch on. You can start a sketch on a plane or an solid.
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> xLine(15, %)
|
|> xLine(15, %)
|
||||||
|> angledLine({ angle = 80, length = 15 }, %)
|
|> angledLine({ angle: 80, length: 15 }, %)
|
||||||
|> line([8, -10], %)
|
|> line([8, -10], %)
|
||||||
|> xLine(10, %)
|
|> xLine(10, %)
|
||||||
|> angledLine({ angle = 120, length = 30 }, %)
|
|> angledLine({ angle: 120, length: 30 }, %)
|
||||||
|> xLine(-15, %)
|
|> xLine(-15, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> xLineTo(15, %)
|
|> xLineTo(15, %)
|
||||||
|> angledLine({ angle = 80, length = 15 }, %)
|
|> angledLine({ angle: 80, length: 15 }, %)
|
||||||
|> line([8, -10], %)
|
|> line([8, -10], %)
|
||||||
|> xLineTo(40, %)
|
|> xLineTo(40, %)
|
||||||
|> angledLine({ angle = 135, length = 30 }, %)
|
|> angledLine({ angle: 135, length: 30 }, %)
|
||||||
|> xLineTo(10, %)
|
|> xLineTo(10, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
|||||||
exampleSketch = startSketchOn('XZ')
|
exampleSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> yLine(15, %)
|
|> yLine(15, %)
|
||||||
|> angledLine({ angle = 30, length = 15 }, %)
|
|> angledLine({ angle: 30, length: 15 }, %)
|
||||||
|> line([8, -10], %)
|
|> line([8, -10], %)
|
||||||
|> yLine(-5, %)
|
|> yLine(-5, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
@ -31,7 +31,7 @@ yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn("XZ")
|
exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = 45 }, %)
|
|> angledLine({ angle: 50, length: 45 }, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ extrude001 = extrude(-10, sketch001)`
|
|||||||
await page.keyboard.press('Enter') // submit
|
await page.keyboard.press('Enter') // submit
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await expect(page.locator('.cm-activeLine')).toContainText(
|
await expect(page.locator('.cm-activeLine')).toContainText(
|
||||||
`fillet({ radius = ${KCL_DEFAULT_LENGTH}, tags = [seg01] }, %)`
|
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -62,8 +62,6 @@ test(
|
|||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
||||||
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
||||||
// The open file's name is `main.kcl`, so the export file name should be `main.gltf`
|
|
||||||
const exportFileName = `main.gltf`
|
|
||||||
|
|
||||||
// Click the export button
|
// Click the export button
|
||||||
await exportButton.click()
|
await exportButton.click()
|
||||||
@ -98,7 +96,7 @@ test(
|
|||||||
.poll(
|
.poll(
|
||||||
async () => {
|
async () => {
|
||||||
try {
|
try {
|
||||||
const outputGltf = await fsp.readFile(exportFileName)
|
const outputGltf = await fsp.readFile('output.gltf')
|
||||||
return outputGltf.byteLength
|
return outputGltf.byteLength
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return 0
|
return 0
|
||||||
@ -108,8 +106,8 @@ test(
|
|||||||
)
|
)
|
||||||
.toBeGreaterThan(300_000)
|
.toBeGreaterThan(300_000)
|
||||||
|
|
||||||
// clean up exported file
|
// clean up output.gltf
|
||||||
await fsp.rm(exportFileName)
|
await fsp.rm('output.gltf')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -140,8 +138,6 @@ test(
|
|||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
||||||
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
||||||
// The open file's name is `other.kcl`, so the export file name should be `other.gltf`
|
|
||||||
const exportFileName = `other.gltf`
|
|
||||||
|
|
||||||
// Click the export button
|
// Click the export button
|
||||||
await exportButton.click()
|
await exportButton.click()
|
||||||
@ -175,7 +171,7 @@ test(
|
|||||||
.poll(
|
.poll(
|
||||||
async () => {
|
async () => {
|
||||||
try {
|
try {
|
||||||
const outputGltf = await fsp.readFile(exportFileName)
|
const outputGltf = await fsp.readFile('output.gltf')
|
||||||
return outputGltf.byteLength
|
return outputGltf.byteLength
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return 0
|
return 0
|
||||||
@ -185,8 +181,8 @@ test(
|
|||||||
)
|
)
|
||||||
.toBeGreaterThan(100_000)
|
.toBeGreaterThan(100_000)
|
||||||
|
|
||||||
// clean up exported file
|
// clean up output.gltf
|
||||||
await fsp.rm(exportFileName)
|
await fsp.rm('output.gltf')
|
||||||
})
|
})
|
||||||
await electronApp.close()
|
await electronApp.close()
|
||||||
})
|
})
|
||||||
|
@ -568,7 +568,7 @@ test.describe('Editor tests', () => {
|
|||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
||||||
|> circle({ center = [0, 0], radius = dia/2 }, %)
|
|> circle({ center: [0, 0], radius: dia/2 }, %)
|
||||||
|> hole(squareHole(length, width, height), %)
|
|> hole(squareHole(length, width, height), %)
|
||||||
|> extrude(height, %)`)
|
|> extrude(height, %)`)
|
||||||
|
|
||||||
@ -604,8 +604,8 @@ test.describe('Editor tests', () => {
|
|||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> revolve({
|
|> revolve({
|
||||||
axis = revolveAxis,
|
axis: revolveAxis,
|
||||||
angle = 90
|
angle: 90
|
||||||
}, %)
|
}, %)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
@ -1135,189 +1135,3 @@ _test.describe('Deleting items from the file pane', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
_test.describe(
|
|
||||||
'Undo and redo do not keep history when navigating between files',
|
|
||||||
() => {
|
|
||||||
_test(
|
|
||||||
`open a file, change something, open a different file, hitting undo should do nothing`,
|
|
||||||
{ tag: '@electron' },
|
|
||||||
async ({ browserName }, testInfo) => {
|
|
||||||
const { page } = await setupElectron({
|
|
||||||
testInfo,
|
|
||||||
folderSetupFn: async (dir) => {
|
|
||||||
const testDir = join(dir, 'testProject')
|
|
||||||
await fsp.mkdir(testDir, { recursive: true })
|
|
||||||
await fsp.copyFile(
|
|
||||||
executorInputPath('cylinder.kcl'),
|
|
||||||
join(testDir, 'main.kcl')
|
|
||||||
)
|
|
||||||
await fsp.copyFile(
|
|
||||||
executorInputPath('basic_fillet_cube_end.kcl'),
|
|
||||||
join(testDir, 'other.kcl')
|
|
||||||
)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
|
||||||
page.on('console', console.log)
|
|
||||||
|
|
||||||
// Constants and locators
|
|
||||||
const projectCard = page.getByText('testProject')
|
|
||||||
const otherFile = page
|
|
||||||
.getByRole('listitem')
|
|
||||||
.filter({ has: page.getByRole('button', { name: 'other.kcl' }) })
|
|
||||||
|
|
||||||
await _test.step(
|
|
||||||
'Open project and make a change to the file',
|
|
||||||
async () => {
|
|
||||||
await projectCard.click()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
|
|
||||||
// Get the text in the code locator.
|
|
||||||
const originalText = await u.codeLocator.innerText()
|
|
||||||
// Click in the editor and add some new lines.
|
|
||||||
await u.codeLocator.click()
|
|
||||||
|
|
||||||
await page.keyboard.type(`sketch001 = startSketchOn('XY')
|
|
||||||
some other shit`)
|
|
||||||
|
|
||||||
// Ensure the content in the editor changed.
|
|
||||||
const newContent = await u.codeLocator.innerText()
|
|
||||||
|
|
||||||
expect(originalText !== newContent)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await _test.step('navigate to other.kcl', async () => {
|
|
||||||
await u.openFilePanel()
|
|
||||||
|
|
||||||
await otherFile.click()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
await u.openKclCodePanel()
|
|
||||||
await _expect(u.codeLocator).toContainText('getOppositeEdge(thing)')
|
|
||||||
})
|
|
||||||
|
|
||||||
await _test.step('hit undo', async () => {
|
|
||||||
// Get the original content of the file.
|
|
||||||
const originalText = await u.codeLocator.innerText()
|
|
||||||
// Now hit undo
|
|
||||||
await page.keyboard.down('ControlOrMeta')
|
|
||||||
await page.keyboard.press('KeyZ')
|
|
||||||
await page.keyboard.up('ControlOrMeta')
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(u.codeLocator).toContainText(originalText)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
_test(
|
|
||||||
`open a file, change something, undo it, open a different file, hitting redo should do nothing`,
|
|
||||||
{ tag: '@electron' },
|
|
||||||
// Skip on windows i think the keybindings are different for redo.
|
|
||||||
async ({ browserName }, testInfo) => {
|
|
||||||
test.skip(process.platform === 'win32', 'Skip on windows')
|
|
||||||
const { page } = await setupElectron({
|
|
||||||
testInfo,
|
|
||||||
folderSetupFn: async (dir) => {
|
|
||||||
const testDir = join(dir, 'testProject')
|
|
||||||
await fsp.mkdir(testDir, { recursive: true })
|
|
||||||
await fsp.copyFile(
|
|
||||||
executorInputPath('cylinder.kcl'),
|
|
||||||
join(testDir, 'main.kcl')
|
|
||||||
)
|
|
||||||
await fsp.copyFile(
|
|
||||||
executorInputPath('basic_fillet_cube_end.kcl'),
|
|
||||||
join(testDir, 'other.kcl')
|
|
||||||
)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
|
||||||
page.on('console', console.log)
|
|
||||||
|
|
||||||
// Constants and locators
|
|
||||||
const projectCard = page.getByText('testProject')
|
|
||||||
const otherFile = page
|
|
||||||
.getByRole('listitem')
|
|
||||||
.filter({ has: page.getByRole('button', { name: 'other.kcl' }) })
|
|
||||||
|
|
||||||
const badContent = 'this shit'
|
|
||||||
await _test.step(
|
|
||||||
'Open project and make a change to the file',
|
|
||||||
async () => {
|
|
||||||
await projectCard.click()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
|
|
||||||
// Get the text in the code locator.
|
|
||||||
const originalText = await u.codeLocator.innerText()
|
|
||||||
// Click in the editor and add some new lines.
|
|
||||||
await u.codeLocator.click()
|
|
||||||
|
|
||||||
await page.keyboard.type(badContent)
|
|
||||||
|
|
||||||
// Ensure the content in the editor changed.
|
|
||||||
const newContent = await u.codeLocator.innerText()
|
|
||||||
|
|
||||||
expect(originalText !== newContent)
|
|
||||||
|
|
||||||
// Now hit undo
|
|
||||||
await page.keyboard.down('ControlOrMeta')
|
|
||||||
await page.keyboard.press('KeyZ')
|
|
||||||
await page.keyboard.up('ControlOrMeta')
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(u.codeLocator).toContainText(originalText)
|
|
||||||
await expect(u.codeLocator).not.toContainText(badContent)
|
|
||||||
|
|
||||||
// Hit redo.
|
|
||||||
await page.keyboard.down('Shift')
|
|
||||||
await page.keyboard.down('ControlOrMeta')
|
|
||||||
await page.keyboard.press('KeyZ')
|
|
||||||
await page.keyboard.up('ControlOrMeta')
|
|
||||||
await page.keyboard.up('Shift')
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(u.codeLocator).toContainText(originalText)
|
|
||||||
await expect(u.codeLocator).toContainText(badContent)
|
|
||||||
|
|
||||||
// Now hit undo
|
|
||||||
await page.keyboard.down('ControlOrMeta')
|
|
||||||
await page.keyboard.press('KeyZ')
|
|
||||||
await page.keyboard.up('ControlOrMeta')
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(u.codeLocator).toContainText(originalText)
|
|
||||||
await expect(u.codeLocator).not.toContainText(badContent)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await _test.step('navigate to other.kcl', async () => {
|
|
||||||
await u.openFilePanel()
|
|
||||||
|
|
||||||
await otherFile.click()
|
|
||||||
await u.waitForPageLoad()
|
|
||||||
await u.openKclCodePanel()
|
|
||||||
await _expect(u.codeLocator).toContainText('getOppositeEdge(thing)')
|
|
||||||
await expect(u.codeLocator).not.toContainText(badContent)
|
|
||||||
})
|
|
||||||
|
|
||||||
await _test.step('hit redo', async () => {
|
|
||||||
// Get the original content of the file.
|
|
||||||
const originalText = await u.codeLocator.innerText()
|
|
||||||
// Now hit redo
|
|
||||||
await page.keyboard.down('Shift')
|
|
||||||
await page.keyboard.down('ControlOrMeta')
|
|
||||||
await page.keyboard.press('KeyZ')
|
|
||||||
await page.keyboard.up('ControlOrMeta')
|
|
||||||
await page.keyboard.up('Shift')
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(u.codeLocator).toContainText(originalText)
|
|
||||||
await expect(u.codeLocator).not.toContainText(badContent)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
@ -25,7 +25,7 @@ test(
|
|||||||
await test.step('check code model connection works and that button is still enable once circle is selected ', async () => {
|
await test.step('check code model connection works and that button is still enable once circle is selected ', async () => {
|
||||||
await moveToCircle()
|
await moveToCircle()
|
||||||
const circleSnippet =
|
const circleSnippet =
|
||||||
'circle({ center = [318.33, 168.1], radius = 182.8 }, %)'
|
'circle({ center: [318.33, 168.1], radius: 182.8 }, %)'
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
activeLines: [],
|
activeLines: [],
|
||||||
highlightedCode: circleSnippet,
|
highlightedCode: circleSnippet,
|
||||||
@ -168,7 +168,7 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
||||||
cameraTarget: { x: -150, y: -4500, z: -80 },
|
cameraTarget: { x: -150, y: -4500, z: -80 },
|
||||||
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
|
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
|
||||||
chamfer({length = 30,tags = [
|
chamfer({length:30,tags:[
|
||||||
seg01,
|
seg01,
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
getNextAdjacentEdge(seg02),
|
getNextAdjacentEdge(seg02),
|
||||||
@ -199,8 +199,8 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
segAng(rectangleSegmentA001) - 90,
|
segAng(rectangleSegmentA001) - 90,
|
||||||
217.26
|
217.26
|
||||||
], %, $seg01)chamfer({
|
], %, $seg01)chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [
|
tags: [
|
||||||
seg01,
|
seg01,
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
getNextAdjacentEdge(seg02)
|
getNextAdjacentEdge(seg02)
|
||||||
@ -227,8 +227,8 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
||||||
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
||||||
beforeChamferSnippet: `angledLine([0, 268.43], %, $rectangleSegmentA001)chamfer({
|
beforeChamferSnippet: `angledLine([0, 268.43], %, $rectangleSegmentA001)chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [
|
tags: [
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
getNextAdjacentEdge(seg02)
|
getNextAdjacentEdge(seg02)
|
||||||
]
|
]
|
||||||
@ -254,8 +254,8 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
cameraPos: { x: -1100, y: -7700, z: 1600 },
|
cameraPos: { x: -1100, y: -7700, z: 1600 },
|
||||||
cameraTarget: { x: 1450, y: 670, z: 4000 },
|
cameraTarget: { x: 1450, y: 670, z: 4000 },
|
||||||
beforeChamferSnippet: `chamfer({
|
beforeChamferSnippet: `chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [getNextAdjacentEdge(yo)]
|
tags: [getNextAdjacentEdge(yo)]
|
||||||
}, %)`,
|
}, %)`,
|
||||||
afterChamferSelectSnippet:
|
afterChamferSelectSnippet:
|
||||||
'sketch005 = startSketchOn(extrude001, seg06)',
|
'sketch005 = startSketchOn(extrude001, seg06)',
|
||||||
@ -292,17 +292,17 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
extrude001 = extrude(100, sketch001)
|
extrude001 = extrude(100, sketch001)
|
||||||
|> chamfer({
|
|> chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [getOppositeEdge(seg01)]
|
tags: [getOppositeEdge(seg01)]
|
||||||
}, %, $seg03)
|
}, %, $seg03)
|
||||||
|> chamfer({ length = 30, tags = [seg01] }, %, $seg04)
|
|> chamfer({ length: 30, tags: [seg01] }, %, $seg04)
|
||||||
|> chamfer({
|
|> chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [getNextAdjacentEdge(seg02)]
|
tags: [getNextAdjacentEdge(seg02)]
|
||||||
}, %, $seg05)
|
}, %, $seg05)
|
||||||
|> chamfer({
|
|> chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [getNextAdjacentEdge(yo)]
|
tags: [getNextAdjacentEdge(yo)]
|
||||||
}, %, $seg06)
|
}, %, $seg06)
|
||||||
sketch005 = startSketchOn(extrude001, seg06)
|
sketch005 = startSketchOn(extrude001, seg06)
|
||||||
|> startProfileAt([-23.43, 19.69], %)
|
|> startProfileAt([-23.43, 19.69], %)
|
||||||
@ -383,7 +383,7 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
||||||
cameraTarget: { x: -150, y: -4500, z: -80 },
|
cameraTarget: { x: -150, y: -4500, z: -80 },
|
||||||
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
|
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
|
||||||
chamfer({length=30,tags=[
|
chamfer({length:30,tags:[
|
||||||
seg01,
|
seg01,
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
getNextAdjacentEdge(seg02),
|
getNextAdjacentEdge(seg02),
|
||||||
@ -421,12 +421,12 @@ test.describe('verify sketch on chamfer works', () => {
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
extrude001 = extrude(100, sketch001)
|
extrude001 = extrude(100, sketch001)
|
||||||
chamf = chamfer({
|
chamf = chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [getOppositeEdge(seg01)]
|
tags: [getOppositeEdge(seg01)]
|
||||||
}, extrude001, $seg03)
|
}, extrude001, $seg03)
|
||||||
|> chamfer({
|
|> chamfer({
|
||||||
length = 30,
|
length: 30,
|
||||||
tags = [
|
tags: [
|
||||||
seg01,
|
seg01,
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
getNextAdjacentEdge(seg02)
|
getNextAdjacentEdge(seg02)
|
||||||
|
@ -247,7 +247,7 @@ test.describe('Can export from electron app', () => {
|
|||||||
.poll(
|
.poll(
|
||||||
async () => {
|
async () => {
|
||||||
try {
|
try {
|
||||||
const outputGltf = await fsp.readFile('main.gltf')
|
const outputGltf = await fsp.readFile('output.gltf')
|
||||||
return outputGltf.byteLength
|
return outputGltf.byteLength
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return 0
|
return 0
|
||||||
@ -257,8 +257,8 @@ test.describe('Can export from electron app', () => {
|
|||||||
)
|
)
|
||||||
.toBeGreaterThan(300_000)
|
.toBeGreaterThan(300_000)
|
||||||
|
|
||||||
// clean up exported file
|
// clean up output.gltf
|
||||||
await fsp.rm('main.gltf')
|
await fsp.rm('output.gltf')
|
||||||
})
|
})
|
||||||
|
|
||||||
await electronApp.close()
|
await electronApp.close()
|
||||||
|
@ -45,9 +45,9 @@ test.describe('Sketch tests', () => {
|
|||||||
screwHole = startSketchOn('XY')
|
screwHole = startSketchOn('XY')
|
||||||
${startProfileAt1}
|
${startProfileAt1}
|
||||||
|> arc({
|
|> arc({
|
||||||
radius = screwRadius,
|
radius: screwRadius,
|
||||||
angle_start = 0,
|
angle_start: 0,
|
||||||
angle_end = 360
|
angle_end: 360
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
part001 = startSketchOn('XY')
|
part001 = startSketchOn('XY')
|
||||||
@ -66,9 +66,9 @@ test.describe('Sketch tests', () => {
|
|||||||
|> xLine(-width / 4 + wireRadius, %)
|
|> xLine(-width / 4 + wireRadius, %)
|
||||||
|> yLine(wireOffset, %)
|
|> yLine(wireOffset, %)
|
||||||
|> arc({
|
|> arc({
|
||||||
radius = wireRadius,
|
radius: wireRadius,
|
||||||
angle_start = 0,
|
angle_start: 0,
|
||||||
angle_end = 180
|
angle_end: 180
|
||||||
}, %)
|
}, %)
|
||||||
|> yLine(-wireOffset, %)
|
|> yLine(-wireOffset, %)
|
||||||
|> xLine(-width / 4, %)
|
|> xLine(-width / 4, %)
|
||||||
@ -202,35 +202,19 @@ test.describe('Sketch tests', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
const viewport = { width: 1200, height: 500 }
|
||||||
|
await page.setViewportSize(viewport)
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
const center = {
|
||||||
await u.openAndClearDebugPanel()
|
x: viewport.width / 2,
|
||||||
await u.sendCustomCmd({
|
y: viewport.height / 2,
|
||||||
type: 'modeling_cmd_req',
|
}
|
||||||
cmd_id: uuidv4(),
|
const modelAreaSize = await u.getModelViewAreaSize()
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_look_at',
|
|
||||||
vantage: { x: 0, y: -1250, z: 580 },
|
|
||||||
center: { x: 0, y: 0, z: 0 },
|
|
||||||
up: { x: 0, y: 0, z: 1 },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await u.sendCustomCmd({
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd_id: uuidv4(),
|
|
||||||
cmd: {
|
|
||||||
type: 'default_camera_get_settings',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// If we have the code pane open, we should see the code.
|
// If we have the code pane open, we should see the code.
|
||||||
if (openPanes.includes('code')) {
|
if (openPanes.includes('code')) {
|
||||||
@ -244,7 +228,7 @@ test.describe('Sketch tests', () => {
|
|||||||
await expect(u.codeLocator).not.toBeVisible()
|
await expect(u.codeLocator).not.toBeVisible()
|
||||||
}
|
}
|
||||||
|
|
||||||
const startPX = [665, 458]
|
const startPX = [center.x + 65, 458]
|
||||||
|
|
||||||
const dragPX = 30
|
const dragPX = 30
|
||||||
let prevContent = ''
|
let prevContent = ''
|
||||||
@ -255,7 +239,7 @@ test.describe('Sketch tests', () => {
|
|||||||
// Wait for the render.
|
// Wait for the render.
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
// Select the sketch
|
// Select the sketch
|
||||||
await page.mouse.click(700, 370)
|
await page.mouse.click(center.x + 100, 370)
|
||||||
}
|
}
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
@ -266,45 +250,74 @@ test.describe('Sketch tests', () => {
|
|||||||
prevContent = await page.locator('.cm-content').innerText()
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await u.sendCustomCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_look_at',
|
||||||
|
vantage: { x: 0, y: -1250, z: 580 - modelAreaSize.w },
|
||||||
|
center: { x: 0, y: 0, z: 0 },
|
||||||
|
up: { x: 0, y: 0, z: 1 },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.sendCustomCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
const step5 = { steps: 5 }
|
const step5 = { steps: 5 }
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
||||||
|
|
||||||
// drag startProfieAt handle
|
test.step('drag startProfileAt handle', async () => {
|
||||||
await page.mouse.move(startPX[0], startPX[1])
|
await page.mouse.move(startPX[0], startPX[1])
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(startPX[0] + dragPX, startPX[1] - dragPX, step5)
|
await page.mouse.move(startPX[0] + dragPX, startPX[1] - dragPX, step5)
|
||||||
await page.mouse.up()
|
await page.mouse.up()
|
||||||
|
if (openPanes.includes('code')) {
|
||||||
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (openPanes.includes('code')) {
|
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
|
||||||
prevContent = await page.locator('.cm-content').innerText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// drag line handle
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
test.step('drag line handle', async () => {
|
||||||
await page.mouse.move(lineEnd.x - 5, lineEnd.y)
|
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
||||||
await page.mouse.down()
|
await page.mouse.move(lineEnd.x - 5, lineEnd.y)
|
||||||
await page.mouse.move(lineEnd.x + dragPX, lineEnd.y - dragPX, step5)
|
await page.mouse.down()
|
||||||
await page.mouse.up()
|
await page.mouse.move(lineEnd.x + dragPX, lineEnd.y - dragPX, step5)
|
||||||
await page.waitForTimeout(100)
|
await page.mouse.up()
|
||||||
if (openPanes.includes('code')) {
|
await page.waitForTimeout(100)
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
if (openPanes.includes('code')) {
|
||||||
prevContent = await page.locator('.cm-content').innerText()
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
}
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// drag tangentialArcTo handle
|
test.step('drag tangentialArcTo handle', async () => {
|
||||||
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
|
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
|
||||||
await page.mouse.move(tangentEnd.x, tangentEnd.y - 5)
|
await page.mouse.move(tangentEnd.x, tangentEnd.y - 5)
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(tangentEnd.x + dragPX, tangentEnd.y - dragPX, step5)
|
await page.mouse.move(
|
||||||
await page.mouse.up()
|
tangentEnd.x + dragPX,
|
||||||
await page.waitForTimeout(100)
|
tangentEnd.y - dragPX,
|
||||||
if (openPanes.includes('code')) {
|
step5
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
)
|
||||||
}
|
await page.mouse.up()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
if (openPanes.includes('code')) {
|
||||||
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Open the code pane
|
// Open the code pane
|
||||||
await u.openKclCodePanel()
|
await u.openKclCodePanel()
|
||||||
@ -354,7 +367,7 @@ test.describe('Sketch tests', () => {
|
|||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')
|
||||||
|> circle({ center = [4.61, -5.01], radius = 8 }, %)`
|
|> circle({ center: [4.61, -5.01], radius: 8 }, %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -392,7 +405,7 @@ test.describe('Sketch tests', () => {
|
|||||||
const dragPX = 40
|
const dragPX = 40
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByText('circle({ center = [4.61, -5.01], radius = 8 }, %)')
|
.getByText('circle({ center: [4.61, -5.01], radius: 8 }, %)')
|
||||||
.click()
|
.click()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
@ -429,7 +442,7 @@ test.describe('Sketch tests', () => {
|
|||||||
// expect the code to have changed
|
// expect the code to have changed
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||||
|> circle({ center = [7.26, -2.37], radius = 11.44 }, %)
|
|> circle({ center: [7.26, -2.37], radius: 11.44 }, %)
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
test('Can edit a sketch that has been extruded in the same pipe', async ({
|
test('Can edit a sketch that has been extruded in the same pipe', async ({
|
||||||
@ -547,7 +560,7 @@ test.describe('Sketch tests', () => {
|
|||||||
|> line([12.73, -0.09], %)
|
|> line([12.73, -0.09], %)
|
||||||
|> tangentialArcTo([24.95, -5.38], %)
|
|> tangentialArcTo([24.95, -5.38], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> revolve({ axis = "X",}, %)`
|
|> revolve({ axis: "X",}, %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -580,7 +593,7 @@ test.describe('Sketch tests', () => {
|
|||||||
})
|
})
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
const startPX = [665, 458]
|
const center = await u.getCenterOfModelViewArea()
|
||||||
|
|
||||||
const dragPX = 30
|
const dragPX = 30
|
||||||
|
|
||||||
@ -596,7 +609,7 @@ test.describe('Sketch tests', () => {
|
|||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
||||||
|
|
||||||
// drag startProfieAt handle
|
// drag startProfileAt handle
|
||||||
await page.mouse.move(startPX[0], startPX[1])
|
await page.mouse.move(startPX[0], startPX[1])
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(startPX[0] + dragPX, startPX[1] - dragPX, step5)
|
await page.mouse.move(startPX[0] + dragPX, startPX[1] - dragPX, step5)
|
||||||
@ -634,10 +647,11 @@ test.describe('Sketch tests', () => {
|
|||||||
|> tangentialArcTo([24.95, -5.38], %)
|
|> tangentialArcTo([24.95, -5.38], %)
|
||||||
|> line([1.97, 2.06], %)
|
|> line([1.97, 2.06], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> revolve({ axis = "X" }, %)`)
|
|> revolve({ axis: "X" }, %)`)
|
||||||
})
|
})
|
||||||
test('Can add multiple sketches', async ({ page }) => {
|
test('Can add multiple sketches', async ({ page }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
const viewportSize = { width: 1200, height: 500 }
|
const viewportSize = { width: 1200, height: 500 }
|
||||||
await page.setViewportSize(viewportSize)
|
await page.setViewportSize(viewportSize)
|
||||||
|
|
||||||
@ -661,15 +675,19 @@ test.describe('Sketch tests', () => {
|
|||||||
200
|
200
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const center = await u.getCenterOfModelViewArea()
|
||||||
|
|
||||||
let codeStr = "sketch001 = startSketchOn('XY')"
|
let codeStr = "sketch001 = startSketchOn('XY')"
|
||||||
|
|
||||||
await page.mouse.click(center.x, viewportSize.height * 0.55)
|
await page.mouse.click(center.x - 50, viewportSize.height * 0.55)
|
||||||
await expect(u.codeLocator).toHaveText(codeStr)
|
await expect(u.codeLocator).toHaveText(codeStr)
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||||
|
|
||||||
await click00r(0, 0)
|
const { click00r } = await getMovementUtils({ center, page })
|
||||||
codeStr += ` |> startProfileAt(${toSU([0, 0])}, %)`
|
|
||||||
|
let coord = await click00r(0, 0)
|
||||||
|
codeStr += ` |> startProfileAt(${coord.kcl}, %)`
|
||||||
await expect(u.codeLocator).toHaveText(codeStr)
|
await expect(u.codeLocator).toHaveText(codeStr)
|
||||||
|
|
||||||
await click00r(50, 0)
|
await click00r(50, 0)
|
||||||
@ -698,14 +716,15 @@ test.describe('Sketch tests', () => {
|
|||||||
|
|
||||||
// when exiting the sketch above the camera is still looking down at XY,
|
// when exiting the sketch above the camera is still looking down at XY,
|
||||||
// so selecting the plane again is a bit easier.
|
// so selecting the plane again is a bit easier.
|
||||||
await page.mouse.click(center.x + 200, center.y + 100)
|
await page.mouse.move(center.x - 100, center.y + 50, { steps: 5 })
|
||||||
|
await page.mouse.click(center.x - 100, center.y + 50)
|
||||||
await page.waitForTimeout(600) // TODO detect animation ending, or disable animation
|
await page.waitForTimeout(600) // TODO detect animation ending, or disable animation
|
||||||
codeStr += "sketch002 = startSketchOn('XY')"
|
codeStr += "sketch002 = startSketchOn('XY')"
|
||||||
await expect(u.codeLocator).toHaveText(codeStr)
|
await expect(u.codeLocator).toHaveText(codeStr)
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
await click00r(30, 0)
|
coord = await click00r(30, 0)
|
||||||
codeStr += ` |> startProfileAt([2.03, 0], %)`
|
codeStr += ` |> startProfileAt(${coord.kcl}, %)`
|
||||||
await expect(u.codeLocator).toHaveText(codeStr)
|
await expect(u.codeLocator).toHaveText(codeStr)
|
||||||
|
|
||||||
// TODO: I couldn't use `toSU` here because of some rounding error causing
|
// TODO: I couldn't use `toSU` here because of some rounding error causing
|
||||||
@ -763,20 +782,21 @@ test.describe('Sketch tests', () => {
|
|||||||
await u.updateCamPosition(camPos)
|
await u.updateCamPosition(camPos)
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
const center = await u.getCenterOfModelViewArea()
|
||||||
await page.mouse.move(0, 0)
|
await page.mouse.move(0, 0)
|
||||||
|
|
||||||
// select a plane
|
// select a plane
|
||||||
await page.mouse.move(700, 200, { steps: 10 })
|
await page.mouse.move(center.x + 100, 200, { steps: 10 })
|
||||||
await page.mouse.click(700, 200, { delay: 200 })
|
await page.mouse.click(center.x + 100, 200, { delay: 200 })
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`sketch001 = startSketchOn('-XZ')`
|
`sketch001 = startSketchOn('-XZ')`
|
||||||
)
|
)
|
||||||
|
|
||||||
let prevContent = await page.locator('.cm-content').innerText()
|
let prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
const pointA = [700, 200]
|
const pointA = [center.x + 100, 200]
|
||||||
const pointB = [900, 200]
|
const pointB = [center.x + 300, 200]
|
||||||
const pointC = [900, 400]
|
const pointC = [center.x + 300, 400]
|
||||||
|
|
||||||
// draw three lines
|
// draw three lines
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
@ -913,7 +933,9 @@ extrude001 = extrude(5, sketch001)
|
|||||||
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
|
|
||||||
await page.mouse.click(622, 355)
|
const center = await u.getCenterOfModelViewArea()
|
||||||
|
|
||||||
|
await page.mouse.click(center.x + 22, 355)
|
||||||
|
|
||||||
await page.waitForTimeout(800)
|
await page.waitForTimeout(800)
|
||||||
await page.getByText(`END')`).click()
|
await page.getByText(`END')`).click()
|
||||||
@ -1074,11 +1096,11 @@ sketch002 = startSketchOn(extrude001, 'END')
|
|||||||
fn lug = (origin, length, diameter, plane) => {
|
fn lug = (origin, length, diameter, plane) => {
|
||||||
lugSketch = startSketchOn(plane)
|
lugSketch = startSketchOn(plane)
|
||||||
|> startProfileAt([origin[0] + lugDiameter / 2, origin[1]], %)
|
|> startProfileAt([origin[0] + lugDiameter / 2, origin[1]], %)
|
||||||
|> angledLineOfYLength({ angle = 60, length = lugHeadLength }, %)
|
|> angledLineOfYLength({ angle: 60, length: lugHeadLength }, %)
|
||||||
|> xLineTo(0 + .001, %)
|
|> xLineTo(0 + .001, %)
|
||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> revolve({ axis = "Y" }, %)
|
|> revolve({ axis: "Y" }, %)
|
||||||
|
|
||||||
return lugSketch
|
return lugSketch
|
||||||
}
|
}
|
||||||
@ -1274,44 +1296,3 @@ test2.describe('Sketch mode should be toleratant to syntax errors', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test2.describe(`Sketching with offset planes`, () => {
|
|
||||||
test2(
|
|
||||||
`Can select an offset plane to sketch on`,
|
|
||||||
async ({ app, scene, toolbar, editor }) => {
|
|
||||||
// We seed the scene with a single offset plane
|
|
||||||
await app.initialise(`offsetPlane001 = offsetPlane("XY", 10)`)
|
|
||||||
|
|
||||||
const [planeClick, planeHover] = scene.makeMouseHelpers(650, 200)
|
|
||||||
|
|
||||||
await test2.step(`Start sketching on the offset plane`, async () => {
|
|
||||||
await toolbar.startSketchPlaneSelection()
|
|
||||||
|
|
||||||
await test2.step(`Hovering should highlight code`, async () => {
|
|
||||||
await planeHover()
|
|
||||||
await editor.expectState({
|
|
||||||
activeLines: [`offsetPlane001=offsetPlane("XY",10)`],
|
|
||||||
diagnostics: [],
|
|
||||||
highlightedCode: 'offsetPlane("XY", 10)',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await test2.step(
|
|
||||||
`Clicking should select the plane and enter sketch mode`,
|
|
||||||
async () => {
|
|
||||||
await planeClick()
|
|
||||||
// Have to wait for engine-side animation to finish
|
|
||||||
await app.page.waitForTimeout(600)
|
|
||||||
await expect2(toolbar.lineBtn).toBeEnabled()
|
|
||||||
await editor.expectEditor.toContain('startSketchOn(offsetPlane001)')
|
|
||||||
await editor.expectState({
|
|
||||||
activeLines: [`offsetPlane001=offsetPlane("XY",10)`],
|
|
||||||
diagnostics: [],
|
|
||||||
highlightedCode: '',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
@ -77,27 +77,27 @@ part001 = startSketchOn('-XZ')
|
|||||||
|> yLine(baseHeight, %)
|
|> yLine(baseHeight, %)
|
||||||
|> xLine(baseLen, %)
|
|> xLine(baseLen, %)
|
||||||
|> angledLineToY({
|
|> angledLineToY({
|
||||||
angle = topAng,
|
angle: topAng,
|
||||||
to = totalHeightHalf,
|
to: totalHeightHalf,
|
||||||
}, %, $seg04)
|
}, %, $seg04)
|
||||||
|> xLineTo(totalLen, %, $seg03)
|
|> xLineTo(totalLen, %, $seg03)
|
||||||
|> yLine(-armThick, %, $seg01)
|
|> yLine(-armThick, %, $seg01)
|
||||||
|> angledLineThatIntersects({
|
|> angledLineThatIntersects({
|
||||||
angle = HALF_TURN,
|
angle: HALF_TURN,
|
||||||
offset = -armThick,
|
offset: -armThick,
|
||||||
intersectTag = seg04
|
intersectTag: seg04
|
||||||
}, %)
|
}, %)
|
||||||
|> angledLineToY([segAng(seg04, %) + 180, ZERO], %)
|
|> angledLineToY([segAng(seg04, %) + 180, ZERO], %)
|
||||||
|> angledLineToY({
|
|> angledLineToY({
|
||||||
angle = -bottomAng,
|
angle: -bottomAng,
|
||||||
to = -totalHeightHalf - armThick,
|
to: -totalHeightHalf - armThick,
|
||||||
}, %, $seg02)
|
}, %, $seg02)
|
||||||
|> xLineTo(segEndX(seg03, %) + 0, %)
|
|> xLineTo(segEndX(seg03, %) + 0, %)
|
||||||
|> yLine(-segLen(seg01, %), %)
|
|> yLine(-segLen(seg01, %), %)
|
||||||
|> angledLineThatIntersects({
|
|> angledLineThatIntersects({
|
||||||
angle = HALF_TURN,
|
angle: HALF_TURN,
|
||||||
offset = -armThick,
|
offset: -armThick,
|
||||||
intersectTag = seg02
|
intersectTag: seg02
|
||||||
}, %)
|
}, %)
|
||||||
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|
||||||
|> xLineTo(ZERO, %)
|
|> xLineTo(ZERO, %)
|
||||||
@ -283,7 +283,7 @@ part001 = startSketchOn('-XZ')
|
|||||||
const gltfFilename = filenames.filter((t: string) =>
|
const gltfFilename = filenames.filter((t: string) =>
|
||||||
t.includes('.gltf')
|
t.includes('.gltf')
|
||||||
)[0]
|
)[0]
|
||||||
if (!gltfFilename) throw new Error('No gLTF in this archive')
|
if (!gltfFilename) throw new Error('No output.gltf in this archive')
|
||||||
cliCommand = `export ZOO_TOKEN=${secrets.snapshottoken} && zoo file snapshot --output-format=png --src-format=${outputType} ${parentPath}/${gltfFilename} ${imagePath}`
|
cliCommand = `export ZOO_TOKEN=${secrets.snapshottoken} && zoo file snapshot --output-format=png --src-format=${outputType} ${parentPath}/${gltfFilename} ${imagePath}`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +592,7 @@ test(
|
|||||||
})
|
})
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`sketch001 = startSketchOn('XZ')
|
`sketch001 = startSketchOn('XZ')
|
||||||
|> circle({ center = [14.44, -2.44], radius = 1 }, %)`
|
|> circle({ center: [14.44, -2.44], radius: 1 }, %)`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user