Compare commits

..

1 Commits

Author SHA1 Message Date
19a8a2bba8 add script to build on mac mini 2025-03-14 15:36:01 -04:00
1939 changed files with 1181665 additions and 761114 deletions

View File

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

View File

@ -1,6 +1,5 @@
NODE_ENV=development NODE_ENV=development
DEV=true DEV=true
VITE_KC_API_WS_MODELING_URL=wss://api.dev.zoo.dev/ws/modeling/commands VITE_KC_API_WS_MODELING_URL=wss://api.dev.zoo.dev/ws/modeling/commands
VITE_KC_API_BASE_URL=https://api.dev.zoo.dev VITE_KC_API_BASE_URL=https://api.dev.zoo.dev
VITE_KC_SITE_BASE_URL=https://dev.zoo.dev VITE_KC_SITE_BASE_URL=https://dev.zoo.dev
@ -9,5 +8,3 @@ VITE_KC_SKIP_AUTH=false
VITE_KC_CONNECTION_TIMEOUT_MS=5000 VITE_KC_CONNECTION_TIMEOUT_MS=5000
# ONLY add your token in .env.development.local if you want to skip auth, otherwise this token takes precedence! # ONLY add your token in .env.development.local if you want to skip auth, otherwise this token takes precedence!
#VITE_KC_DEV_TOKEN="your token from dev.zoo.dev should go in .env.development.local" #VITE_KC_DEV_TOKEN="your token from dev.zoo.dev should go in .env.development.local"
FAIL_ON_CONSOLE_ERRORS=true

12
.envrc
View File

@ -1,13 +1 @@
# Load optional shared environment variables
source_up_if_exists
# Load default development environment variables
dotenv .env.development
# Load optional environment variables overrides
dotenv_if_exists .env.development.local
# Load optional testing environment variables
dotenv_if_exists e2e/playwright/playwright-secrets.env
use flake . use flake .

71
.eslintrc Normal file
View File

@ -0,0 +1,71 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"react-perf",
"css-modules",
"jest",
"jsx-a11y",
"react",
"react-hooks",
"suggest-no-throw",
"testing-library",
"@typescript-eslint"
],
"extends": [
"plugin:css-modules/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended"
],
"rules": {
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"no-restricted-globals": [
"error",
{
"name": "isNaN",
"message": "Use Number.isNaN() instead."
},
],
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
"message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
}
],
"semi": [
"error",
"never"
],
"react-hooks/exhaustive-deps": "off",
"suggest-no-throw/suggest-no-throw": "warn",
},
"overrides": [
{
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
"extends": [
"plugin:testing-library/react"
],
"rules": {
"suggest-no-throw/suggest-no-throw": "off",
"testing-library/prefer-screen-queries": "off",
"jest/valid-expect": "off"
}
},
{
"files": ["src/**/*.test.ts"],
"extends": [
"plugin:testing-library/react"
],
"rules": {
"suggest-no-throw/suggest-no-throw": "off",
}
}
]
}

View File

@ -1,127 +0,0 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"react-perf",
"css-modules",
"jest",
"jsx-a11y",
"react",
"react-hooks",
"suggest-no-throw",
"testing-library",
"@typescript-eslint"
],
"extends": [
"plugin:css-modules/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended"
],
"rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-array-delete": "error",
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-duplicate-type-constituents": "error",
"@typescript-eslint/no-empty-object-type": "error",
"@typescript-eslint/no-extra-non-null-assertion": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-for-in-array": "error",
"no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-implied-eval": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
"@typescript-eslint/no-redundant-type-constituents": "error",
"@typescript-eslint/no-this-alias": "warn",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unnecessary-type-constraint": "error",
"no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-unused-vars": [
"error",
{
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
"ignoreRestSiblings": true,
"vars": "all",
"args": "none"
}
],
"@typescript-eslint/no-unsafe-unary-minus": "error",
"@typescript-eslint/no-wrapper-object-types": "error",
"no-throw-literal": "off", // Use @typescript-eslint/only-throw-error instead.
"@typescript-eslint/only-throw-error": "error",
"@typescript-eslint/prefer-as-const": "warn",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"no-restricted-globals": [
"error",
{
"name": "isNaN",
"message": "Use Number.isNaN() instead."
}
],
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
"message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
},
{
"selector": "CallExpression[callee.object.name='TOML'][callee.property.name='stringify']",
"message": "Do not use TOML.stringify directly. Use the wrappers in test-utils instead like settingsToToml."
},
{
"selector": "CallExpression[callee.object.name='TOML'][callee.property.name='parse']",
"message": "Do not use TOML.parse directly. Use the wrappers in test-utils instead like tomlToSettings."
}
],
"no-restricted-imports": [
"error",
{
"patterns": [
// Restrict all relative imports except for .css files.
{
"group": ["./*", "../*", "!./*.css", "!../*.css"],
"message": "Use absolute imports instead."
}
]
}
],
"semi": ["error", "never"],
"react-hooks/exhaustive-deps": "off",
"suggest-no-throw/suggest-no-throw": "error"
},
"overrides": [
{
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
"extends": ["plugin:testing-library/react"],
"rules": {
"suggest-no-throw/suggest-no-throw": "off",
"testing-library/prefer-screen-queries": "off",
"jest/valid-expect": "off"
}
},
{
"files": ["src/**/*.test.ts"],
"extends": ["plugin:testing-library/react"],
"rules": {
"suggest-no-throw/suggest-no-throw": "off"
}
},
{
"files": ["packages/**/*.ts", "rust/**/*.ts"],
"extends": [],
"rules": {
"no-restricted-imports": "off"
}
}
]
}

View File

@ -1,5 +1,5 @@
name: Bug Report name: Bug Report
description: File a bug report for the Zoo Design Studio description: File a bug report for the Zoo Modeling App
title: "[BUG]: " title: "[BUG]: "
labels: ["bug"] labels: ["bug"]
assignees: [] assignees: []
@ -70,7 +70,7 @@ body:
id: version id: version
attributes: attributes:
label: Version label: Version
description: "The version of the Zoo Design Studio you're using." description: "The version of the Zoo Modeling App you're using."
placeholder: "example: v0.15.0. You can find this in the settings." placeholder: "example: v0.15.0. You can find this in the settings."
validations: validations:
required: true required: true

View File

@ -4,7 +4,7 @@
"main": "main.js", "main": "main.js",
"dependencies": { "dependencies": {
"@actions/core": "^1.6", "@actions/core": "^1.6",
"@actions/github": "^6.0", "@actions/github": "^5.0",
"glob": "^11.0.1" "glob": "^7.1.5"
} }
} }

View File

@ -4,27 +4,27 @@
set -euo pipefail set -euo pipefail
if [[ ! -f "test-results/.last-run.json" ]]; then if [[ ! -f "test-results/.last-run.json" ]]; then
# If no last run artifact, than run Playwright normally # if no last run artifact, than run plawright normally
echo "run playwright normally" echo "run playwright normally"
if [[ "$3" == *ubuntu* ]]; then if [[ "$3" == *ubuntu* ]]; then
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
elif [[ "$3" == *windows* ]]; then elif [[ "$3" == *windows* ]]; then
yarn test:playwright:electron:windows -- --shard=$1/$2 || true yarn test:playwright:electron:windows -- --shard=$1/$2 || true
elif [[ "$3" == *macos* ]]; then elif [[ "$3" == *macos* ]]; then
yarn test:playwright:electron:macos -- --shard=$1/$2 || true yarn test:playwright:electron:macos -- --shard=$1/$2 || true
else else
echo "Do not run Playwright. Unable to detect os runtime." echo "Do not run playwright. Unable to detect os runtime."
exit 1 exit 1
fi fi
# Log failures for Axiom to pick up # # send to axiom
node playwrightProcess.mjs > /tmp/github-actions.log node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
fi fi
retry=1 retry=1
max_retries=1 max_retrys=1
# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues # retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
while [[ $retry -le $max_retries ]]; do while [[ $retry -le $max_retrys ]]; do
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then if [[ $failed_tests -gt 0 ]]; then
@ -40,8 +40,8 @@ while [[ $retry -le $max_retries ]]; do
echo "Do not run playwright. Unable to detect os runtime." echo "Do not run playwright. Unable to detect os runtime."
exit 1 exit 1
fi fi
# Log failures for Axiom to pick up # send to axiom
node playwrightProcess.mjs > /tmp/github-actions.log node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
retry=$((retry + 1)) retry=$((retry + 1))
else else
echo "retried=false" >>$GITHUB_OUTPUT echo "retried=false" >>$GITHUB_OUTPUT
@ -58,7 +58,7 @@ echo "retried=false" >>$GITHUB_OUTPUT
if [[ -f "test-results/.last-run.json" ]]; then if [[ -f "test-results/.last-run.json" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json) failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then if [[ $failed_tests -gt 0 ]]; then
# If it still fails after 3 retries, then fail the job # if it still fails after 3 retrys, then fail the job
exit 1 exit 1
fi fi
fi fi

View File

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

View File

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

View File

@ -230,6 +230,39 @@ updates:
update-types: update-types:
- minor - minor
- patch - patch
- package-ecosystem: pip
directory: /public/kcl-samples
schedule:
interval: weekly
day: monday
time: '03:00'
timezone: America/Los_Angeles
open-pull-requests-limit: 5
reviewers:
- adamchalmers
- franknoirot
- irev-dev
- jessfraz
groups:
security:
applies-to: security-updates
update-types:
- major
- minor
- patch
patch:
applies-to: version-updates
update-types:
- patch
major:
applies-to: version-updates
update-types:
- major
minor:
applies-to: version-updates
update-types:
- minor
- patch
- package-ecosystem: pip - package-ecosystem: pip
directory: /rust/kcl-python-bindings directory: /rust/kcl-python-bindings
schedule: schedule:

View File

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

View File

@ -10,8 +10,7 @@ on:
- 'nightly-v[0-9]+.[0-9]+.[0-9]+' - 'nightly-v[0-9]+.[0-9]+.[0-9]+'
env: env:
# IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }} IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
IS_RELEASE: true
IS_NIGHTLY: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'nightly-v') }} IS_NIGHTLY: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'nightly-v') }}
concurrency: concurrency:
@ -78,7 +77,7 @@ jobs:
with: with:
cache: false # Configured below. cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc - uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
with: with:
tool: wasm-pack tool: wasm-pack
@ -100,11 +99,11 @@ jobs:
yarn files:set-version yarn files:set-version
yarn files:flip-to-nightly yarn files:flip-to-nightly
# - name: Set release version - name: Set release version
# if: ${{ env.IS_RELEASE == 'true' }} if: ${{ env.IS_RELEASE == 'true' }}
# run: | run: |
# export VERSION=${GITHUB_REF_NAME#v} export VERSION=${GITHUB_REF_NAME#v}
# yarn files:set-version yarn files:set-version
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
@ -184,32 +183,30 @@ jobs:
max_attempts: 3 max_attempts: 3
command: yarn install command: yarn install
# Next steps are from Digicert docs at
# https://docs.digicert.com/en/digicert-keylocker/ci-cd-integrations/scripts/github/scripts-for-signing-using-ksp-library-on-github.html#ksp-signing-using-github-action-488726
- 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.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
run: | run: |
CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12 echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
echo "$SM_CLIENT_CERT_FILE_B64" | base64 --decode > $CERTIFICATE_PATH cat /d/Certificate_pkcs12.p12
echo "SM_CLIENT_CERT_FILE=$CERTIFICATE_PATH" >> "$GITHUB_ENV" echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV" echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV" echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH
echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH
echo "C:\Program Files\DigiCert\DigiCert Keylocker Tools" >> $GITHUB_PATH echo "C:\Program Files\DigiCert\DigiCert One Signing Manager Tools" >> $GITHUB_PATH
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.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
run: | run: |
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/Keylockertools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o Keylockertools-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 Keylockertools-windows-x64.msi /quiet /qn msiexec /i smtools-windows-x64.msi /quiet /qn
smksp_registrar.exe list smksp_registrar.exe list
smctl.exe keypair ls smctl.exe keypair ls
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
smksp_cert_sync.exe smksp_cert_sync.exe
smctl windows certsync
shell: cmd shell: cmd
- name: Build the app (debug) - name: Build the app (debug)
@ -228,8 +225,8 @@ jobs:
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }} CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }} CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
# DEBUG: "electron-notarize*" WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
DEBUG: electron-builder DEBUG: "electron-notarize*"
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures # TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
with: with:
@ -244,7 +241,7 @@ jobs:
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: out-arm64-${{ matrix.platform }} name: out-arm64-${{ matrix.platform }}
# first two will pick both Zoo Design Studio-$VERSION-arm64-win.exe and Zoo Design Studio-$VERSION-win.exe # first two will pick both Zoo Modeling App-$VERSION-arm64-win.exe and Zoo Modeling App-$VERSION-win.exe
path: | path: |
out/*-${{ env.VERSION_NO_V }}-win.* out/*-${{ env.VERSION_NO_V }}-win.*
out/*-${{ env.VERSION_NO_V }}-arm64-win.* out/*-${{ env.VERSION_NO_V }}-arm64-win.*

View File

@ -34,11 +34,20 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1 uses: actions-rust-lang/setup-rust-toolchain@v1
with: with:
cache: false # Configured below. cache: false # Configured below.
- name: Start Vector - name: Install vector
run: .github/ci-cd-scripts/start-vector-ubuntu.sh run: |
env: curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }} chmod +x /tmp/vector.sh
OS_NAME: ${{ env.OS_NAME }} /tmp/vector.sh -y -no-modify-path
mkdir -p /tmp/vector
cp .github/workflows/vector.toml /tmp/vector.toml
sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
cat /tmp/vector.toml
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
- uses: taiki-e/install-action@cargo-llvm-cov - uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest - uses: taiki-e/install-action@nextest
- name: Install just - name: Install just
@ -91,14 +100,9 @@ jobs:
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
pushd rust cd rust
just overwrite-sim-test kcl_samples just overwrite-sim-test kcl_samples
popd git add kcl-lib/tests
git add \
rust/kcl-lib/tests \
public/kcl-samples/manifest.json \
public/kcl-samples/README.md \
public/kcl-samples/screenshots
git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]" git config --local user.name "github-actions[bot]"
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git

View File

@ -1,9 +1,7 @@
name: E2E Tests name: E2E Tests
on: on:
push: push:
branches: branches: [ main ]
- main
- all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
pull_request: pull_request:
schedule: schedule:
- cron: 0 * * * * # hourly - cron: 0 * * * * # hourly
@ -17,6 +15,7 @@ permissions:
pull-requests: write pull-requests: write
actions: read actions: read
jobs: jobs:
conditions: conditions:
@ -68,17 +67,15 @@ jobs:
- name: Display conditions - name: Display conditions
shell: bash shell: bash
run: | run: |
# For debugging purposes # For debugging purposes.
set -euo pipefail set -euo pipefail
echo "GITHUB_REF: $GITHUB_REF"
echo "GITHUB_HEAD_REF: $GITHUB_HEAD_REF"
echo "GITHUB_BASE_REF: $GITHUB_BASE_REF"
echo "significant: ${{ steps.path-changes.outputs.significant }}" echo "significant: ${{ steps.path-changes.outputs.significant }}"
echo "should-run: ${{ steps.should-run.outputs.should-run }}" echo "should-run: ${{ steps.should-run.outputs.should-run }}"
prepare-wasm: prepare-wasm:
# separate job on Ubuntu to build or fetch the wasm blob once on the fastest runner # seperate job on Ubuntu to build or fetch the wasm blob once on the fastest runner
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64 runs-on: namespace-profile-ubuntu-8-cores
needs: conditions needs: conditions
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -140,7 +137,7 @@ jobs:
with: with:
cache: false # Configured below. cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc - uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }} if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
with: with:
tool: wasm-pack tool: wasm-pack
@ -162,10 +159,11 @@ jobs:
name: prepared-wasm name: prepared-wasm
path: | path: |
rust/kcl-wasm-lib/pkg/kcl_wasm_lib* rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
snapshots: snapshots:
name: playwright:snapshots:ubuntu name: playwright:snapshots:ubuntu
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64 runs-on: namespace-profile-ubuntu-8-cores
needs: [conditions, prepare-wasm] needs: [conditions, prepare-wasm]
steps: steps:
- uses: actions/create-github-app-token@v1 - uses: actions/create-github-app-token@v1
@ -222,27 +220,32 @@ jobs:
- name: Run ubuntu/chrome snapshots - name: Run ubuntu/chrome snapshots
if: needs.conditions.outputs.should-run == 'true' if: needs.conditions.outputs.should-run == 'true'
uses: nick-fields/retry@v3.0.2 run: |
with: yarn test:snapshots
shell: bash
command: yarn test:snapshots
timeout_minutes: 30
max_attempts: 3
env: env:
CI: true
NODE_ENV: development
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
VITE_KC_SKIP_AUTH: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }} snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }} if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
with: with:
name: playwright-report-ubuntu-snapshot-${{ github.sha }} name: playwright-report-snapshots-${{ matrix.os }}-snapshot-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/ path: playwright-report/
include-hidden-files: true include-hidden-files: true
retention-days: 30 retention-days: 30
overwrite: true overwrite: true
- name: Check for changes - name: Clean up test-results
if: ${{ needs.conditions.outputs.should-run == 'true' && github.ref != 'refs/heads/main' }} if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
continue-on-error: true
run: rm -r test-results
- name: check for changes
if: ${{ needs.conditions.outputs.should-run == 'true' && matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 && github.ref != 'refs/heads/main' }}
shell: bash shell: bash
id: git-check id: git-check
run: | run: |
@ -253,8 +256,7 @@ jobs:
fi fi
- name: Commit changes, if any - name: Commit changes, if any
# TODO: find a more reliable way to detect visual changes if: ${{ needs.conditions.outputs.should-run == 'true' && steps.git-check.outputs.modified == 'true' }}
if: ${{ false && needs.conditions.outputs.should-run == 'true' && steps.git-check.outputs.modified == 'true' }}
shell: bash shell: bash
run: | run: |
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
@ -264,36 +266,31 @@ jobs:
git fetch origin git fetch origin
echo ${{ github.head_ref }} echo ${{ github.head_ref }}
git checkout ${{ github.head_ref }} git checkout ${{ github.head_ref }}
git commit -m "A snapshot a day keeps the bugs away! 📷🐛" || true git commit -m "A snapshot a day keeps the bugs away! 📷🐛 (OS: ${{matrix.os}})" || true
git push git push
git push origin ${{ github.head_ref }} git push origin ${{ github.head_ref }}
# only upload artifacts if there's actually changes
- uses: actions/upload-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.git-check.outputs.modified == 'true' }}
with:
name: playwright-report-ubuntu-${{ github.sha }}
path: playwright-report/
include-hidden-files: true
retention-days: 30
electron: electron:
needs: [conditions, prepare-wasm] needs: [conditions, prepare-wasm]
timeout-minutes: 60 timeout-minutes: 60
env: name: playwright:electron:${{ matrix.os }} ${{ matrix.shardIndex }} ${{ matrix.shardTotal }}
OS_NAME: ${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}:${{ matrix.shardIndex }}:${{ matrix.shardTotal }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# TODO: enable namespace-profile-windows-latest once available # TODO: enable self-hosted-windows-8-cores once available
os: os: [namespace-profile-ubuntu-8-cores, namespace-profile-macos-8-cores, windows-16-cores]
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- namespace-profile-macos-8-cores
- windows-latest-8-cores
shardIndex: [1, 2, 3, 4] shardIndex: [1, 2, 3, 4]
shardTotal: [4] shardTotal: [4]
# Disable macos and windows tests on hourly e2e tests since we only care
# about server side changes.
# Technique from https://github.com/joaomcteixeira/python-project-skeleton/pull/31/files
isScheduled:
- ${{ github.event_name == 'schedule' }}
exclude:
- os: namespace-profile-macos-8-cores
isScheduled: true
- os: windows-latest-8-cores
isScheduled: true
# TODO: add ref here for main and latest release tag # TODO: add ref here for main and latest release tag
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
@ -324,7 +321,6 @@ jobs:
run: yarn run: yarn
- name: Cache Playwright Browsers - name: Cache Playwright Browsers
if: needs.conditions.outputs.should-run == 'true'
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
@ -332,25 +328,26 @@ jobs:
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }} key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
- name: Install Playwright Browsers - name: Install Playwright Browsers
if: needs.conditions.outputs.should-run == 'true'
run: yarn playwright install --with-deps run: yarn playwright install --with-deps
- name: Build web - name: Build web
if: needs.conditions.outputs.should-run == 'true' if: needs.conditions.outputs.should-run == 'true'
run: yarn tronb:vite:dev run: yarn tronb:vite:dev
- name: Start Vector - name: Install good sed
if: ${{ needs.conditions.outputs.should-run == 'true' && !contains(matrix.os, 'windows') }} if: startsWith(matrix.os, 'macos')
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh shell: bash
env: run: |
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }} brew install gnu-sed
OS_NAME: ${{ env.OS_NAME }} echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
# TODO: Add back axiom logs
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }} if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
continue-on-error: true continue-on-error: true
with: with:
name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
- name: Run playwright/electron flow (with retries) - name: Run playwright/electron flow (with retries)
@ -359,17 +356,21 @@ jobs:
uses: nick-fields/retry@v3.0.2 uses: nick-fields/retry@v3.0.2
with: with:
shell: bash shell: bash
command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{ env.OS_NAME }} command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{matrix.os}}
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 9 max_attempts: 25
env: env:
CI: true
FAIL_ON_CONSOLE_ERRORS: true FAIL_ON_CONSOLE_ERRORS: true
NODE_ENV: development
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
VITE_KC_SKIP_AUTH: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && always() }} if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
with: with:
name: test-results-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/ path: test-results/
include-hidden-files: true include-hidden-files: true
retention-days: 30 retention-days: 30
@ -378,7 +379,7 @@ jobs:
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ needs.conditions.outputs.should-run == 'true' && always() }} if: ${{ needs.conditions.outputs.should-run == 'true' && always() }}
with: with:
name: playwright-report-${{ env.OS_NAME }}-${{ matrix.shardIndex }}-${{ github.sha }} name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/ path: playwright-report/
include-hidden-files: true include-hidden-files: true
retention-days: 30 retention-days: 30

View File

@ -376,7 +376,7 @@ jobs:
with: with:
credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}" credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}"
- name: Set up Cloud SDK - name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.4 uses: google-github-actions/setup-gcloud@v2.1.2
with: with:
project_id: kittycadapi project_id: kittycadapi
- name: "upload files to gcp" - name: "upload files to gcp"

View File

@ -28,87 +28,43 @@ jobs:
- run: yarn fmt-check - run: yarn fmt-check
yarn-build-wasm: yarn-build-wasm:
# Build the wasm blob once on the fastest runner. runs-on: ubuntu-22.04
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
- run: yarn install
- name: Install dependencies - uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
run: yarn install
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
with: with:
tool: wasm-pack tool: wasm-pack
- run: yarn build:wasm
- name: Rust Cache yarn-tsc:
uses: Swatinem/rust-cache@v2 runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install
- uses: Swatinem/rust-cache@v2
with: with:
workspaces: './rust' workspaces: './rust'
- name: Build Wasm - uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
shell: bash
run: yarn build:wasm
- uses: actions/upload-artifact@v4
with: with:
name: prepared-wasm tool: wasm-pack
path: | - run: yarn build:wasm
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
- uses: actions/upload-artifact@v4
with:
name: prepared-ts-rs-bindings
path: |
rust/kcl-lib/bindings/*
yarn-tsc:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn tsc - run: yarn tsc
yarn-lint: yarn-lint:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: yarn-build-wasm
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -117,55 +73,9 @@ jobs:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
- run: yarn install - run: yarn install
- run: yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn lint - run: yarn lint
yarn-circular-dependencies:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn circular-deps:diff
python-codespell: python-codespell:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
@ -181,7 +91,6 @@ jobs:
yarn-unit-test-kcl-samples: yarn-unit-test-kcl-samples:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: yarn-build-wasm
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -191,25 +100,10 @@ jobs:
cache: 'yarn' cache: 'yarn'
- run: yarn install - run: yarn install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc - uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
with: with:
tool: wasm-pack tool: wasm-pack
- run: yarn build:wasm
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn simpleserver:bg - run: yarn simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }} if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
@ -226,7 +120,6 @@ jobs:
yarn-unit-test: yarn-unit-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: yarn-build-wasm
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -236,25 +129,10 @@ jobs:
cache: 'yarn' cache: 'yarn'
- run: yarn install - run: yarn install
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc - uses: taiki-e/install-action@955a6ff1416eae278c9f833008a9beb4b7f9afe3
with: with:
tool: wasm-pack tool: wasm-pack
- run: yarn build:wasm
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn simpleserver:bg - run: yarn simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }} if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
@ -263,13 +141,13 @@ jobs:
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }} if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: yarn playwright install chromium --with-deps run: yarn playwright install chromium --with-deps
- name: Run unit tests - name: run unit tests
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }} if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
run: xvfb-run -a yarn test:unit run: xvfb-run -a yarn test:unit
env: env:
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- name: Check for changes - name: check for changes
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }} if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
id: git-check id: git-check
run: | run: |

View File

@ -1,8 +1,5 @@
name: update-dev-branch name: update-dev-branch
# This is used to sync the `dev` branch with the `main` branch to continuously
# deploy a second instance of the app to Vercel: https://app.dev.zoo.dev
on: on:
push: push:
branches: branches:
@ -29,4 +26,4 @@ jobs:
# reset to main # reset to main
git reset --hard origin/main git reset --hard origin/main
# force push it # force push it
git push --force origin dev git push -f origin dev

View File

@ -1,45 +0,0 @@
name: update-e2e-branch
# This is used to sync the `all-e2e` branch with the `main` branch for the
# logic in the test utility `orRunWhenFullSuiteEnabled()` that allows all e2e
# tests to run on a particular branch to analyze failures metrics in Axiom.
on:
schedule:
- cron: '0 * * * *' # runs every hour
permissions:
contents: write
jobs:
update-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Sync with main
run: |
# Create the branch
git checkout all-e2e || git checkout -b all-e2e
# Reset to main
git fetch origin
git reset --hard origin/main
# Get a new SHA to prevent overwriting the commit status on main
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git commit --allow-empty --message="[all-e2e] $(git log --max-count=1 --pretty=%B)"
# Overwrite the branch
git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git
git push --force origin all-e2e

View File

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

1
.gitignore vendored
View File

@ -50,7 +50,6 @@ e2e/playwright/**/*.png
e2e/playwright/export-snapshots/* e2e/playwright/export-snapshots/*
!e2e/playwright/export-snapshots/*.png !e2e/playwright/export-snapshots/*.png
!e2e/playwright/snapshot-tests.spec.ts-snapshots/*.png !e2e/playwright/snapshot-tests.spec.ts-snapshots/*.png
trace.zip
/public/kcl-samples.zip /public/kcl-samples.zip
/public/kcl-samples/.github /public/kcl-samples/.github

View File

@ -1,27 +1,27 @@
# Setting Up Zoo Design Studio # Setting Up Zoo Modeling App
Compared to other CAD software, getting Zoo Design Studio up and running is quick and straightforward across platforms. It's about 100MB to download and is quick to install. Compared to other CAD software, getting Zoo Modeling App up and running is quick and straightforward across platforms. It's about 100MB to download and is quick to install.
## Windows ## Windows
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Windows and for your processor type. 1. Download the [Zoo Modeling App installer](https://zoo.dev/modeling-app/download) for Windows and for your processor type.
2. Once downloaded, run the installer `Zoo Design Studio-{version}-{arch}-win.exe` which should take a few seconds. 2. Once downloaded, run the installer `Zoo Modeling App-{version}-{arch}-win.exe` which should take a few seconds.
3. The installation happens at `C:\Program Files\Zoo Design Studio`. A shortcut in the start menu is also created so you can run the app easily by clicking on it. 3. The installation happens at `C:\Program Files\Zoo Modeling App`. A shortcut in the start menu is also created so you can run the app easily by clicking on it.
## macOS ## macOS
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for macOS and for your processor type. 1. Download the [Zoo Modeling App installer](https://zoo.dev/modeling-app/download) for macOS and for your processor type.
2. Once downloaded, open the disk image `Zoo Design Studio-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory. 2. Once downloaded, open the disk image `Zoo Modeling App-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory.
3. You can then open your `Applications` directory and double-click on `Zoo Design Studio` to open. 3. You can then open your `Applications` directory and double-click on `Zoo Modeling App` to open.
## Linux ## Linux
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Linux and for your processor type. 1. Download the [Zoo Modeling App installer](https://zoo.dev/modeling-app/download) for Linux and for your processor type.
2. Install the dependencies needed to run the [AppImage format](https://appimage.org/). 2. Install the dependencies needed to run the [AppImage format](https://appimage.org/).
- On Ubuntu, install the FUSE library with these commands in a terminal. - On Ubuntu, install the FUSE library with these commands in a terminal.
@ -30,7 +30,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
sudo apt install libfuse2 sudo apt install libfuse2
``` ```
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless. - Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
- Once installed, copy the downloaded `Zoo Design Studio-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`. - Once installed, copy the downloaded `Zoo Modeling App-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`.
- `appimaged` should automatically find it and make it executable. If not, run: - `appimaged` should automatically find it and make it executable. If not, run:
```bash ```bash

181
Makefile
View File

@ -1,174 +1,12 @@
.PHONY: all .PHONY: dev
all: install build check
############################################################################### KCL_WASM_LIB_FILES := $(wildcard rust/**/*.rs)
# INSTALL TS_SRC := $(wildcard src/**/*.tsx) $(wildcard src/**/*.ts)
XSTATE_TYPEGENS := $(wildcard src/machines/*.typegen.ts)
ifeq ($(OS),Windows_NT) dev: node_modules public/wasm_lib_bg.wasm $(XSTATE_TYPEGENS)
export WINDOWS := true
ifndef MSYSTEM
export POWERSHELL := true
endif
endif
ifdef WINDOWS
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
else
CARGO ?= ~/.cargo/bin/cargo
WASM_PACK ?= ~/.cargo/bin/wasm-pack
endif
.PHONY: install
install: node_modules/.yarn-integrity $(CARGO) $(WASM_PACK) ## Install dependencies
node_modules/.yarn-integrity: package.json yarn.lock
yarn install
ifdef POWERSHELL
@ type nul > $@
else
@ touch $@
endif
$(CARGO):
ifdef WINDOWS
yarn install:rust:windows
else
yarn install:rust
endif
$(WASM_PACK):
ifdef WINDOWS
yarn install:wasm-pack:cargo
else
yarn install:wasm-pack:sh
endif
###############################################################################
# BUILD
CARGO_SOURCES := rust/.cargo/config.toml $(wildcard rust/Cargo.*) $(wildcard rust/**/Cargo.*)
RUST_SOURCES := $(wildcard rust/**/*.rs)
REACT_SOURCES := $(wildcard src/*.tsx) $(wildcard src/**/*.tsx)
TYPESCRIPT_SOURCES := tsconfig.* $(wildcard src/*.ts) $(wildcard src/**/*.ts)
VITE_SOURCES := $(wildcard vite.*) $(wildcard vite/**/*.tsx)
.PHONY: build
build: build-web build-desktop
.PHONY: build-web
build-web: install public/kcl_wasm_lib_bg.wasm build/index.html
.PHONY: build-desktop
build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES)
ifdef WINDOWS
yarn build:wasm:dev:windows
else
yarn build:wasm:dev
endif
build/index.html: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
yarn build:local
.vite/build/main.js: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
yarn tronb:vite:dev
###############################################################################
# CHECK
.PHONY: check
check: format lint
.PHONY: format
format: install ## Format the code
yarn fmt
.PHONY: lint
lint: install ## Lint the code
yarn tsc
yarn lint
###############################################################################
# RUN
TARGET ?= desktop
.PHONY: run
run: run-$(TARGET)
.PHONY: run-web
run-web: install build-web ## Start the web app
yarn start yarn start
.PHONY: run-desktop
run-desktop: install build-desktop ## Start the desktop app
yarn tron:start
###############################################################################
# TEST
E2E_GREP ?=
E2E_WORKERS ?=
E2E_FAILURES ?= 1
.PHONY: test
test: test-unit test-e2e
.PHONY: test-unit
test-unit: install ## Run the unit tests
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
yarn test:unit
.PHONY: test-e2e
test-e2e: test-e2e-$(TARGET)
.PHONY: test-e2e-web
test-e2e-web: install build-web ## Run the web e2e tests
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
ifdef E2E_GREP
yarn chrome:test --headed --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else
yarn chrome:test --headed --workers='100%'
endif
.PHONY: test-e2e-desktop
test-e2e-desktop: install build-desktop ## Run the desktop e2e tests
ifdef E2E_GREP
yarn test:playwright:electron --grep="$(E2E_GREP)" --max-failures=$(E2E_FAILURES)
else
yarn test:playwright:electron --workers='100%'
endif
###############################################################################
# CLEAN
.PHONY: clean
clean: ## Delete all artifacts
ifdef POWERSHELL
git clean --force -d -x --exclude=.env* --exclude=**/*.env
else
rm -rf .vite/ build/
rm -rf trace.zip playwright-report/ test-results/
rm -rf public/kcl_wasm_lib_bg.wasm
rm -rf rust/*/bindings/ rust/*/pkg/ rust/target/
rm -rf node_modules/ rust/*/node_modules/
endif
.PHONY: help
help: install
ifdef POWERSHELL
@ powershell -Command "Get-Content $(MAKEFILE_LIST) | Select-String -Pattern '^[^\s]+:.*##\s.*$$' | ForEach-Object { $$line = $$_.Line -split ':.*?##\s+'; Write-Host -NoNewline $$line[0].PadRight(30) -ForegroundColor Cyan; Write-Host $$line[1] }"
else
@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
endif
.DEFAULT_GOAL := help
###############################################################################
# I'm sorry this is so specific to my setup you may as well ignore this. # I'm sorry this is so specific to my setup you may as well ignore this.
# This is so you don't have to deal with electron windows popping up constantly. # This is so you don't have to deal with electron windows popping up constantly.
# It should work for you other Linux users. # It should work for you other Linux users.
@ -176,3 +14,12 @@ lee-electron-test:
Xephyr -br -ac -noreset -screen 1200x500 :2 & Xephyr -br -ac -noreset -screen 1200x500 :2 &
DISPLAY=:2 NODE_ENV=development PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn tron:test -g "when using the file tree" DISPLAY=:2 NODE_ENV=development PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn tron:test -g "when using the file tree"
killall Xephyr killall Xephyr
$(XSTATE_TYPEGENS): $(TS_SRC)
yarn xstate typegen 'src/**/*.ts?(x)'
public/kcl_wasm_lib_bg.wasm: $(KCL_WASM_LIB_FILES)
yarn build:wasm
node_modules: package.json yarn.lock
yarn install

View File

@ -1,17 +1,17 @@
![Zoo Design Studio](/public/zma-logomark-outlined.png) ![Zoo Modeling App](/public/zma-logomark-outlined.png)
## Zoo Design Studio ## Zoo Modeling App
download at [zoo.dev/modeling-app/download](https://zoo.dev/modeling-app/download) download at [zoo.dev/modeling-app/download](https://zoo.dev/modeling-app/download)
A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev). A CAD application from the future, brought to you by the [Zoo team](https://zoo.dev).
Design Studio is our take on what a modern modelling experience can be. It is applying several lessons learned in the decades since most major CAD tools came into existence: Modeling App is our take on what a modern modelling experience can be. It is applying several lessons learned in the decades since most major CAD tools came into existence:
- All artifacts—including parts and assemblies—should be represented as human-readable code. At the end of the day, your CAD project should be "plain text" - All artifacts—including parts and assemblies—should be represented as human-readable code. At the end of the day, your CAD project should be "plain text"
- This makes version control—which is a solved problem in software engineering—trivial for CAD - This makes version control—which is a solved problem in software engineering—trivial for CAD
- All GUI (or point-and-click) interactions should be actions performed on this code representation under the hood - All GUI (or point-and-click) interactions should be actions performed on this code representation under the hood
- This unlocks a hybrid approach to modeling. Whether you point-and-click as you always have or you write your own KCL code, you are performing the same action in Design Studio - This unlocks a hybrid approach to modeling. Whether you point-and-click as you always have or you write your own KCL code, you are performing the same action in Modeling App
- Everything graphics _has_ to be built for the GPU - Everything graphics _has_ to be built for the GPU
- Most CAD applications have had to retrofit support for GPUs, but our geometry engine is made for GPUs (primarily Nvidia's Vulkan), getting the order of magnitude rendering performance boost with it - Most CAD applications have had to retrofit support for GPUs, but our geometry engine is made for GPUs (primarily Nvidia's Vulkan), getting the order of magnitude rendering performance boost with it
- Make the resource-intensive pieces of an application auto-scaling - Make the resource-intensive pieces of an application auto-scaling
@ -19,9 +19,9 @@ Design Studio is our take on what a modern modelling experience can be. It is ap
We are excited about what a small team of people could build in a short time with our API. We welcome you to try our API, build your own applications, or contribute to ours! We are excited about what a small team of people could build in a short time with our API. We welcome you to try our API, build your own applications, or contribute to ours!
Design Studio is a _hybrid_ user interface for CAD modeling. You can point-and-click to design parts (and soon assemblies), but everything you make is really just [`kcl` code](https://github.com/KittyCAD/kcl-experiments) under the hood. All of your CAD models can be checked into source control such as GitHub and responsibly versioned, rolled back, and more. Modeling App is a _hybrid_ user interface for CAD modeling. You can point-and-click to design parts (and soon assemblies), but everything you make is really just [`kcl` code](https://github.com/KittyCAD/kcl-experiments) under the hood. All of your CAD models can be checked into source control such as GitHub and responsibly versioned, rolled back, and more.
The 3D view in Design Studio is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine. The 3D view in Modeling App is just a video stream from our hosted geometry engine. The app sends new modeling commands to the engine via WebSockets, which returns back video frames of the view within the engine.
## Tools ## Tools
@ -105,7 +105,7 @@ Finally, to run the web app only, run:
yarn start yarn start
``` ```
If you're not a Zoo employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development.local` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to `localhost:3000` again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again. If you're not a Zoo employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens of course, then navigate to localhost:3000 again. Note that navigating to `localhost:3000/signin` removes your token so you will need to set the token again.
### Development environment variables ### Development environment variables
@ -122,7 +122,7 @@ Third-Party Cookies".
## Desktop ## Desktop
To spin up the desktop app, `yarn install` and `yarn build:wasm` need to have been done before hand then: To spin up the desktop app, `yarn install` and `yarn build:wasm` need to have been done before hand then
``` ```
yarn tron:start yarn tron:start
@ -130,13 +130,13 @@ yarn tron:start
This will start the application and hot-reload on changes. This will start the application and hot-reload on changes.
Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (Linux and Windows). Devtools can be opened with the usual Cmd-Opt-I (Mac) or Ctrl-Shift-I (Linux and Windows).
To package the app for your platform with electron-builder, run `yarn tronb:package:dev` (or `yarn tronb:package:prod` to point to the .env.production variables). To package the app for your platform with electron-builder, run `yarn tronb:package:dev` (or `yarn tronb:package:prod` to point to the .env.production variables)
## Checking out commits / Bisecting ## Checking out commits / Bisecting
Which commands from setup are one off vs. need to be run every time? Which commands from setup are one off vs need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale: The following will need to be run when checking out a new commit and guarantees the build is not stale:
@ -198,13 +198,13 @@ If the prompt doesn't show up, start the app in command line to grab the electro
``` ```
# Windows (PowerShell) # Windows (PowerShell)
& 'C:\Program Files\Zoo Design Studio\Zoo Design Studio.exe' & 'C:\Program Files\Zoo Modeling App\Zoo Modeling App.exe'
# macOS # macOS
/Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App /Applications/Zoo\ Modeling\ App.app/Contents/MacOS/Zoo\ Modeling\ App
# Linux # Linux
./Zoo Design Studio-{version}-{arch}-linux.AppImage ./Zoo Modeling App-{version}-{arch}-linux.AppImage
``` ```
#### 4. Publish the release #### 4. Publish the release

View File

@ -33,12 +33,12 @@ abs(num: number): number
```js ```js
myAngle = -120 myAngle = -120
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [8, 0]) |> line(end = [8, 0])
|> angledLine(angle = abs(myAngle), length = 5) |> angledLine({ angle = abs(myAngle), length = 5 }, %)
|> line(end = [-5, 0]) |> line(end = [-5, 0])
|> angledLine(angle = myAngle, length = 5) |> angledLine({ angle = myAngle, length = 5 }, %)
|> close() |> close()
baseExtrusion = extrude(sketch001, length = 5) baseExtrusion = extrude(sketch001, length = 5)

View File

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

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

48
docs/kcl/angledLineToX.md Normal file

File diff suppressed because one or more lines are too long

48
docs/kcl/angledLineToY.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -10,11 +10,11 @@ This will work on any solid, including extruded solids, revolved solids, and she
```js ```js
appearance( appearance(
solids: [Solid], solidSet: SolidSet,
color: String, color: String,
metalness?: number, metalness?: number,
roughness?: number, roughness?: number,
): [Solid] ): SolidSet
``` ```
@ -22,21 +22,21 @@ appearance(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | The solid(s) whose appearance is being set | Yes | | `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | The solid(s) whose appearance is being set | Yes |
| `color` | `String` | Color of the new material, a hex string like '#ff0000' | Yes | | `color` | `String` | Color of the new material, a hex string like '#ff0000' | Yes |
| `metalness` | [`number`](/docs/kcl/types/number) | Metalness of the new material, a percentage like 95.7. | No | | `metalness` | [`number`](/docs/kcl/types/number) | Metalness of the new material, a percentage like 95.7. | No |
| `roughness` | [`number`](/docs/kcl/types/number) | Roughness of the new material, a percentage like 95.7. | No | | `roughness` | [`number`](/docs/kcl/types/number) | Roughness of the new material, a percentage like 95.7. | No |
### Returns ### Returns
[`[Solid]`](/docs/kcl/types/Solid) [`SolidSet`](/docs/kcl/types/SolidSet) - A solid or a group of solids.
### Examples ### Examples
```js ```js
// Add color to an extruded solid. // Add color to an extruded solid.
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(endAbsolute = [10, 0]) |> line(endAbsolute = [10, 0])
|> line(endAbsolute = [0, 10]) |> line(endAbsolute = [0, 10])
@ -52,9 +52,9 @@ example = extrude(exampleSketch, length = 5)
```js ```js
// Add color to a revolved solid. // Add color to a revolved solid.
sketch001 = startSketchOn(XY) sketch001 = startSketchOn('XY')
|> circle(center = [15, 0], radius = 5) |> circle(center = [15, 0], radius = 5)
|> revolve(angle = 360, axis = Y) |> revolve({ angle = 360, axis = 'y' }, %)
|> appearance(color = '#ff0000', metalness = 90, roughness = 90) |> appearance(color = '#ff0000', metalness = 90, roughness = 90)
``` ```
@ -63,7 +63,7 @@ sketch001 = startSketchOn(XY)
```js ```js
// Add color to different solids. // Add color to different solids.
fn cube(center) { fn cube(center) {
return startSketchOn(XY) return startSketchOn('XY')
|> startProfileAt([center[0] - 10, center[1] - 10], %) |> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10]) |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10]) |> line(endAbsolute = [center[0] + 10, center[1] + 10])
@ -95,7 +95,7 @@ appearance(
```js ```js
// You can set the appearance before or after you shell it will yield the same result. // You can set the appearance before or after you shell it will yield the same result.
// This example shows setting the appearance _after_ the shell. // This example shows setting the appearance _after_ the shell.
firstSketch = startSketchOn(XY) firstSketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %) |> startProfileAt([-12, 12], %)
|> line(end = [24, 0]) |> line(end = [24, 0])
|> line(end = [0, -24]) |> line(end = [0, -24])
@ -112,7 +112,7 @@ shell(firstSketch, faces = ['end'], thickness = 0.25)
```js ```js
// You can set the appearance before or after you shell it will yield the same result. // You can set the appearance before or after you shell it will yield the same result.
// This example shows setting the appearance _before_ the shell. // This example shows setting the appearance _before_ the shell.
firstSketch = startSketchOn(XY) firstSketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %) |> startProfileAt([-12, 12], %)
|> line(end = [24, 0]) |> line(end = [24, 0])
|> line(end = [0, -24]) |> line(end = [0, -24])
@ -129,7 +129,7 @@ shell(firstSketch, faces = ['end'], thickness = 0.25)
```js ```js
// Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern. // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
// This example shows _before_ the pattern. // This example shows _before_ the pattern.
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [0, 2]) |> line(end = [0, 2])
|> line(end = [3, 1]) |> line(end = [3, 1])
@ -146,7 +146,7 @@ example = extrude(exampleSketch, length = 1)
```js ```js
// Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern. // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
// This example shows _after_ the pattern. // This example shows _after_ the pattern.
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [0, 2]) |> line(end = [0, 2])
|> line(end = [3, 1]) |> line(end = [3, 1])
@ -162,7 +162,7 @@ example = extrude(exampleSketch, length = 1)
```js ```js
// Color the result of a 2D pattern that was extruded. // Color the result of a 2D pattern that was extruded.
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> startProfileAt([.5, 25], %) |> startProfileAt([.5, 25], %)
|> line(end = [0, 5]) |> line(end = [0, 5])
|> line(end = [-1, 0]) |> line(end = [-1, 0])
@ -184,8 +184,9 @@ example = extrude(exampleSketch, length = 1)
```js ```js
// Color the result of a sweep. // Color the result of a sweep.
// Create a path for the sweep. // Create a path for the sweep.
sweepPath = startSketchOn(XZ) sweepPath = startSketchOn('XZ')
|> startProfileAt([0.05, 0.05], %) |> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7]) |> line(end = [0, 7])
|> tangentialArc({ offset = 90, radius = 5 }, %) |> tangentialArc({ offset = 90, radius = 5 }, %)
@ -193,10 +194,10 @@ sweepPath = startSketchOn(XZ)
|> tangentialArc({ offset = -90, radius = 5 }, %) |> tangentialArc({ offset = -90, radius = 5 }, %)
|> line(end = [0, 7]) |> line(end = [0, 7])
pipeHole = startSketchOn(XY) pipeHole = startSketchOn('XY')
|> circle(center = [0, 0], radius = 1.5) |> circle(center = [0, 0], radius = 1.5)
sweepSketch = startSketchOn(XY) sweepSketch = startSketchOn('XY')
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> hole(pipeHole, %) |> hole(pipeHole, %)
|> sweep(path = sweepPath) |> sweep(path = sweepPath)

View File

@ -31,9 +31,12 @@ asin(num: number): number
### Examples ### Examples
```js ```js
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(asin(0.5)), length = 20) |> angledLine({
angle = toDegrees(asin(0.5)),
length = 20
}, %)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()

View File

@ -31,9 +31,12 @@ atan(num: number): number
### Examples ### Examples
```js ```js
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(atan(1.25)), length = 20) |> angledLine({
angle = toDegrees(atan(1.25)),
length = 20
}, %)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()

View File

@ -35,9 +35,12 @@ atan2(
### Examples ### Examples
```js ```js
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(atan2(1.25, 2)), length = 20) |> angledLine({
angle = toDegrees(atan2(1.25, 2)),
length = 20
}, %)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()

View File

@ -31,7 +31,7 @@ ceil(num: number): number
### Examples ### Examples
```js ```js
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10]) |> line(endAbsolute = [12, 10])
|> line(end = [ceil(7.02986), 0]) |> line(end = [ceil(7.02986), 0])

View File

@ -41,7 +41,7 @@ length = 10
thickness = 1 thickness = 1
chamferLength = 2 chamferLength = 2
mountingPlateSketch = startSketchOn(XY) mountingPlateSketch = startSketchOn("XY")
|> startProfileAt([-width / 2, -length / 2], %) |> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2], tag = $edge1) |> line(endAbsolute = [width / 2, -length / 2], tag = $edge1)
|> line(endAbsolute = [width / 2, length / 2], tag = $edge2) |> line(endAbsolute = [width / 2, length / 2], tag = $edge2)
@ -65,7 +65,7 @@ mountingPlate = extrude(mountingPlateSketch, length = thickness)
```js ```js
// Sketch on the face of a chamfer. // Sketch on the face of a chamfer.
fn cube(pos, scale) { fn cube(pos, scale) {
sg = startSketchOn(XY) sg = startSketchOn('XY')
|> startProfileAt(pos, %) |> startProfileAt(pos, %)
|> line(end = [0, scale]) |> line(end = [0, scale])
|> line(end = [scale, 0]) |> line(end = [scale, 0])

60
docs/kcl/circle.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -10,10 +10,10 @@ Construct a circle derived from 3 points.
```js ```js
circleThreePoint( circleThreePoint(
sketchSurfaceOrGroup: SketchOrSurface,
p1: [number], p1: [number],
p2: [number], p2: [number],
p3: [number], p3: [number],
sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator, tag?: TagDeclarator,
): Sketch ): Sketch
``` ```
@ -23,10 +23,10 @@ circleThreePoint(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on. | Yes |
| `p1` | [`[number]`](/docs/kcl/types/number) | 1st point to derive the circle. | Yes | | `p1` | [`[number]`](/docs/kcl/types/number) | 1st point to derive the circle. | Yes |
| `p2` | [`[number]`](/docs/kcl/types/number) | 2nd point to derive the circle. | Yes | | `p2` | [`[number]`](/docs/kcl/types/number) | 2nd point to derive the circle. | Yes |
| `p3` | [`[number]`](/docs/kcl/types/number) | 3rd point to derive the circle. | Yes | | `p3` | [`[number]`](/docs/kcl/types/number) | 3rd point to derive the circle. | Yes |
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Identifier for the circle to reference elsewhere. | No | | [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Identifier for the circle to reference elsewhere. | No |
### Returns ### Returns
@ -37,7 +37,7 @@ circleThreePoint(
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XY) exampleSketch = startSketchOn("XY")
|> circleThreePoint(p1 = [10, 10], p2 = [20, 8], p3 = [15, 5]) |> circleThreePoint(p1 = [10, 10], p2 = [20, 8], p3 = [15, 5])
|> extrude(length = 5) |> extrude(length = 5)
``` ```

File diff suppressed because one or more lines are too long

View File

@ -9,12 +9,13 @@ layout: manual
### `std` ### `std`
- [`X`](/docs/kcl/consts/std-X) - [`HALF_TURN`](/docs/kcl/consts/std-HALF_TURN)
- [`QUARTER_TURN`](/docs/kcl/consts/std-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-THREE_QUARTER_TURN)
- [`XY`](/docs/kcl/consts/std-XY) - [`XY`](/docs/kcl/consts/std-XY)
- [`XZ`](/docs/kcl/consts/std-XZ) - [`XZ`](/docs/kcl/consts/std-XZ)
- [`Y`](/docs/kcl/consts/std-Y)
- [`YZ`](/docs/kcl/consts/std-YZ) - [`YZ`](/docs/kcl/consts/std-YZ)
- [`Z`](/docs/kcl/consts/std-Z) - [`ZERO`](/docs/kcl/consts/std-ZERO)
### `std::math` ### `std::math`
@ -22,10 +23,3 @@ layout: manual
- [`PI`](/docs/kcl/consts/std-math-PI) - [`PI`](/docs/kcl/consts/std-math-PI)
- [`TAU`](/docs/kcl/consts/std-math-TAU) - [`TAU`](/docs/kcl/consts/std-math-TAU)
### `std::turns`
- [`HALF_TURN`](/docs/kcl/consts/std-turns-HALF_TURN)
- [`QUARTER_TURN`](/docs/kcl/consts/std-turns-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-turns-THREE_QUARTER_TURN)
- [`ZERO`](/docs/kcl/consts/std-turns-ZERO)

View File

@ -0,0 +1,15 @@
---
title: "std::HALF_TURN"
excerpt: ""
layout: manual
---
```js
std::HALF_TURN: number(deg) = 180deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::Y"
excerpt: ""
layout: manual
---
```js
std::Y
```

View File

@ -1,15 +0,0 @@
---
title: "std::Z"
excerpt: ""
layout: manual
---
```js
std::Z
```

View File

@ -1,5 +1,5 @@
--- ---
title: "std::X" title: "std::ZERO"
excerpt: "" excerpt: ""
layout: manual layout: manual
--- ---
@ -9,7 +9,7 @@ layout: manual
```js ```js
std::X std::ZERO: number = 0
``` ```

View File

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

View File

@ -17,8 +17,8 @@ std::math::PI: number = 3.14159265358979323846264338327950288_
```js ```js
circumference = 70 circumference = 70
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> circle(center = [0, 0], radius = circumference / (2 * PI)) |> circle(center = [0, 0], radius = circumference/ (2 * PI))
example = extrude(exampleSketch, length = 5) example = extrude(exampleSketch, length = 5)
``` ```

View File

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

View File

@ -1,15 +0,0 @@
---
title: "std::turns::HALF_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::HALF_TURN: number(deg) = 180deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::turns::QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::turns::THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::turns::ZERO"
excerpt: ""
layout: manual
---
```js
std::turns::ZERO: number = 0
```

View File

@ -28,9 +28,9 @@ e(): number
### Examples ### Examples
```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 }, %)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@ length = 10
thickness = 1 thickness = 1
filletRadius = 2 filletRadius = 2
mountingPlateSketch = startSketchOn(XY) mountingPlateSketch = startSketchOn("XY")
|> startProfileAt([-width / 2, -length / 2], %) |> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2], tag = $edge1) |> line(endAbsolute = [width / 2, -length / 2], tag = $edge1)
|> line(endAbsolute = [width / 2, length / 2], tag = $edge2) |> line(endAbsolute = [width / 2, length / 2], tag = $edge2)
@ -69,7 +69,7 @@ length = 10
thickness = 1 thickness = 1
filletRadius = 1 filletRadius = 1
mountingPlateSketch = startSketchOn(XY) mountingPlateSketch = startSketchOn("XY")
|> startProfileAt([-width / 2, -length / 2], %) |> startProfileAt([-width / 2, -length / 2], %)
|> line(endAbsolute = [width / 2, -length / 2], tag = $edge1) |> line(endAbsolute = [width / 2, -length / 2], tag = $edge1)
|> line(endAbsolute = [width / 2, length / 2], tag = $edge2) |> line(endAbsolute = [width / 2, length / 2], tag = $edge2)

View File

@ -31,7 +31,7 @@ floor(num: number): number
### Examples ### Examples
```js ```js
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10]) |> line(endAbsolute = [12, 10])
|> line(end = [floor(7.02986), 0]) |> line(end = [floor(7.02986), 0])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

107
docs/kcl/helix.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@ Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch.
```js ```js
hole( hole(
holeSketch: [Sketch], holeSketch: SketchSet,
sketch: Sketch, sketch: Sketch,
): Sketch ): Sketch
``` ```
@ -20,7 +20,7 @@ hole(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `holeSketch` | [`[Sketch]`](/docs/kcl/types/Sketch) | | Yes | | `holeSketch` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes | | `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
### Returns ### Returns

View File

@ -32,7 +32,7 @@ hollow(
```js ```js
// Hollow a basic sketch. // Hollow a basic sketch.
firstSketch = startSketchOn(XY) firstSketch = startSketchOn('XY')
|> startProfileAt([-12, 12], %) |> startProfileAt([-12, 12], %)
|> line(end = [24, 0]) |> line(end = [24, 0])
|> line(end = [0, -24]) |> line(end = [0, -24])
@ -46,7 +46,7 @@ firstSketch = startSketchOn(XY)
```js ```js
// Hollow a basic sketch. // Hollow a basic sketch.
firstSketch = startSketchOn(-XZ) firstSketch = startSketchOn('-XZ')
|> startProfileAt([-12, 12], %) |> startProfileAt([-12, 12], %)
|> line(end = [24, 0]) |> line(end = [24, 0])
|> line(end = [0, -24]) |> line(end = [0, -24])
@ -61,7 +61,7 @@ firstSketch = startSketchOn(-XZ)
```js ```js
// Hollow a sketch on face object. // Hollow a sketch on face object.
size = 100 size = 100
case = startSketchOn(-XZ) case = startSketchOn('-XZ')
|> startProfileAt([-size, -size], %) |> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0]) |> line(end = [2 * size, 0])
|> line(end = [0, 2 * size]) |> line(end = [0, 2 * size])

View File

@ -12,7 +12,7 @@ Import a CAD file.
For formats lacking unit data (such as STL, OBJ, or PLY files), the default unit of measurement is millimeters. Alternatively you may specify the unit by passing your desired measurement unit in the options parameter. When importing a GLTF file, the bin file will be imported as well. Import paths are relative to the current project directory. For formats lacking unit data (such as STL, OBJ, or PLY files), the default unit of measurement is millimeters. Alternatively you may specify the unit by passing your desired measurement unit in the options parameter. When importing a GLTF file, the bin file will be imported as well. Import paths are relative to the current project directory.
Note: The import command currently only works when using the native Design Studio. Note: The import command currently only works when using the native Modeling App.
```js ```js
import( import(
@ -69,7 +69,7 @@ model = import("tests/inputs/cube.step")
```js ```js
import height, buildSketch from "common.kcl" import height, buildSketch from "common.kcl"
plane = XZ plane = 'XZ'
margin = 2 margin = 2
s1 = buildSketch(plane, [0, 0]) s1 = buildSketch(plane, [0, 0])
s2 = buildSketch(plane, [0, height() + margin]) s2 = buildSketch(plane, [0, height() + margin])

40
docs/kcl/inch.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
--- ---
title: "KCL Standard Library" title: "KCL Standard Library"
excerpt: "Documentation for the KCL standard library for the Zoo Design Studio." excerpt: "Documentation for the KCL standard library for the Zoo Modeling App."
layout: manual layout: manual
--- ---
@ -22,28 +22,26 @@ layout: manual
* [`string`](kcl/types/string) * [`string`](kcl/types/string)
* [`tag`](kcl/types/tag) * [`tag`](kcl/types/tag)
* **std** * **std**
* [`Axis2d`](kcl/types/Axis2d) * [`HALF_TURN`](kcl/consts/std-HALF_TURN)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane) * [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d) * [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN)
* [`Point3d`](kcl/types/Point3d)
* [`Sketch`](kcl/types/Sketch) * [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid) * [`Solid`](kcl/types/Solid)
* [`X`](kcl/consts/std-X) * [`THREE_QUARTER_TURN`](kcl/consts/std-THREE_QUARTER_TURN)
* [`XY`](kcl/consts/std-XY) * [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ) * [`XZ`](kcl/consts/std-XZ)
* [`Y`](kcl/consts/std-Y)
* [`YZ`](kcl/consts/std-YZ) * [`YZ`](kcl/consts/std-YZ)
* [`Z`](kcl/consts/std-Z) * [`ZERO`](kcl/consts/std-ZERO)
* [`abs`](kcl/abs) * [`abs`](kcl/abs)
* [`acos`](kcl/acos) * [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX) * [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY) * [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine) * [`angledLine`](kcl/angledLine)
* [`angledLineOfXLength`](kcl/angledLineOfXLength)
* [`angledLineOfYLength`](kcl/angledLineOfYLength)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects) * [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`angledLineToX`](kcl/angledLineToX)
* [`angledLineToY`](kcl/angledLineToY)
* [`appearance`](kcl/appearance) * [`appearance`](kcl/appearance)
* [`arc`](kcl/arc) * [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo) * [`arcTo`](kcl/arcTo)
@ -59,24 +57,22 @@ layout: manual
* [`bezierCurve`](kcl/bezierCurve) * [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil) * [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer) * [`chamfer`](kcl/chamfer)
* [`circle`](kcl/circle)
* [`circleThreePoint`](kcl/circleThreePoint) * [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close) * [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`extrude`](kcl/extrude) * [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet) * [`fillet`](kcl/fillet)
* [`floor`](kcl/floor) * [`floor`](kcl/floor)
* [`fromCm`](kcl/fromCm) * [`ft`](kcl/ft)
* [`fromFt`](kcl/fromFt)
* [`fromInches`](kcl/fromInches)
* [`fromM`](kcl/fromM)
* [`fromMm`](kcl/fromMm)
* [`fromYd`](kcl/fromYd)
* [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge) * [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge) * [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge) * [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/std-helix) * [`helix`](kcl/helix)
* [`helixRevolutions`](kcl/helixRevolutions)
* [`hole`](kcl/hole) * [`hole`](kcl/hole)
* [`hollow`](kcl/hollow) * [`hollow`](kcl/hollow)
* [`inch`](kcl/inch)
* [`lastSegX`](kcl/lastSegX) * [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY) * [`lastSegY`](kcl/lastSegY)
* [`legAngX`](kcl/legAngX) * [`legAngX`](kcl/legAngX)
@ -88,9 +84,12 @@ layout: manual
* [`log`](kcl/log) * [`log`](kcl/log)
* [`log10`](kcl/log10) * [`log10`](kcl/log10)
* [`log2`](kcl/log2) * [`log2`](kcl/log2)
* [`m`](kcl/m)
* [`map`](kcl/map) * [`map`](kcl/map)
* [`max`](kcl/max) * [`max`](kcl/max)
* [`min`](kcl/min) * [`min`](kcl/min)
* [`mirror2d`](kcl/mirror2d)
* [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane) * [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d) * [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d) * [`patternCircular3d`](kcl/patternCircular3d)
@ -98,6 +97,7 @@ layout: manual
* [`patternLinear3d`](kcl/patternLinear3d) * [`patternLinear3d`](kcl/patternLinear3d)
* [`patternTransform`](kcl/patternTransform) * [`patternTransform`](kcl/patternTransform)
* [`patternTransform2d`](kcl/patternTransform2d) * [`patternTransform2d`](kcl/patternTransform2d)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon) * [`polygon`](kcl/polygon)
* [`pop`](kcl/pop) * [`pop`](kcl/pop)
* [`pow`](kcl/pow) * [`pow`](kcl/pow)
@ -107,7 +107,7 @@ layout: manual
* [`push`](kcl/push) * [`push`](kcl/push)
* [`reduce`](kcl/reduce) * [`reduce`](kcl/reduce)
* [`rem`](kcl/rem) * [`rem`](kcl/rem)
* [`revolve`](kcl/std-revolve) * [`revolve`](kcl/revolve)
* [`rotate`](kcl/rotate) * [`rotate`](kcl/rotate)
* [`round`](kcl/round) * [`round`](kcl/round)
* [`scale`](kcl/scale) * [`scale`](kcl/scale)
@ -133,19 +133,11 @@ layout: manual
* [`translate`](kcl/translate) * [`translate`](kcl/translate)
* [`xLine`](kcl/xLine) * [`xLine`](kcl/xLine)
* [`yLine`](kcl/yLine) * [`yLine`](kcl/yLine)
* [`yd`](kcl/yd)
* **std::math** * **std::math**
* [`E`](kcl/consts/std-math-E) * [`E`](kcl/consts/std-math-E)
* [`PI`](kcl/consts/std-math-PI) * [`PI`](kcl/consts/std-math-PI)
* [`TAU`](kcl/consts/std-math-TAU) * [`TAU`](kcl/consts/std-math-TAU)
* [`cos`](kcl/std-math-cos) * [`cos`](kcl/std-math-cos)
* [`polar`](kcl/std-math-polar)
* [`sin`](kcl/std-math-sin) * [`sin`](kcl/std-math-sin)
* [`tan`](kcl/std-math-tan) * [`tan`](kcl/std-math-tan)
* **std::sketch**
* [`circle`](kcl/std-sketch-circle)
* [`mirror2d`](kcl/std-sketch-mirror2d)
* **std::turns**
* [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN)
* [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN)
* [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN)
* [`turns::ZERO`](kcl/consts/std-turns-ZERO)

View File

@ -36,7 +36,7 @@ int(num: number): number
n = int(ceil(5 / 2)) n = int(ceil(5 / 2))
assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3") assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3")
// Draw n cylinders. // Draw n cylinders.
startSketchOn(XZ) startSketchOn('XZ')
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> extrude(length = 5) |> extrude(length = 5)
|> patternTransform( |> patternTransform(

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
--- ---
title: "KCL Known Issues" title: "KCL Known Issues"
excerpt: "Known issues with the KCL standard library for the Zoo Design Studio." excerpt: "Known issues with the KCL standard library for the Zoo Modeling App."
layout: manual layout: manual
--- ---

View File

@ -27,7 +27,7 @@ lastSegX(sketch: Sketch): number
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [5, 0]) |> line(end = [5, 0])
|> line(end = [20, 5]) |> line(end = [20, 5])

View File

@ -27,7 +27,7 @@ lastSegY(sketch: Sketch): number
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [5, 0]) |> line(end = [5, 0])
|> line(end = [20, 5]) |> line(end = [20, 5])

View File

@ -31,7 +31,7 @@ ln(num: number): number
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [ln(100), 15]) |> line(end = [ln(100), 15])
|> line(end = [5, -6]) |> line(end = [5, -6])

View File

@ -15,8 +15,6 @@ loft(
bezApproximateRational: bool, bezApproximateRational: bool,
baseCurveIndex?: integer, baseCurveIndex?: integer,
tolerance?: number, tolerance?: number,
tagStart?: TagDeclarator,
tagEnd?: TagDeclarator,
): Solid ): Solid
``` ```
@ -30,8 +28,6 @@ loft(
| `bezApproximateRational` | [`bool`](/docs/kcl/types/bool) | Attempt to approximate rational curves (such as arcs) using a bezier. 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. | Yes | | `bezApproximateRational` | [`bool`](/docs/kcl/types/bool) | Attempt to approximate rational curves (such as arcs) using a bezier. 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. | Yes |
| `baseCurveIndex` | `integer` | This can be set to override the automatically determined topological base curve, which is usually the first section encountered. | No | | `baseCurveIndex` | `integer` | This can be set to override the automatically determined topological base curve, which is usually the first section encountered. | No |
| `tolerance` | [`number`](/docs/kcl/types/number) | Tolerance for the loft operation. | No | | `tolerance` | [`number`](/docs/kcl/types/number) | Tolerance for the loft operation. | No |
| `tagStart` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | A named tag for the face at the start of the loft, i.e. the original sketch | No |
| `tagEnd` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | A named tag for the face at the end of the loft, i.e. the last sketch | No |
### Returns ### Returns
@ -42,7 +38,7 @@ loft(
```js ```js
// Loft a square and a triangle. // Loft a square and a triangle.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn('XY')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -50,7 +46,7 @@ squareSketch = startSketchOn(XY)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
triangleSketch = startSketchOn(offsetPlane(XY, offset = 75)) triangleSketch = startSketchOn(offsetPlane('XY', offset = 75))
|> startProfileAt([0, 125], %) |> startProfileAt([0, 125], %)
|> line(end = [-15, -30]) |> line(end = [-15, -30])
|> line(end = [30, 0]) |> line(end = [30, 0])
@ -64,7 +60,7 @@ loft([squareSketch, triangleSketch])
```js ```js
// Loft a square, a circle, and another circle. // Loft a square, a circle, and another circle.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn('XY')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -72,10 +68,10 @@ squareSketch = startSketchOn(XY)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
circleSketch0 = startSketchOn(offsetPlane(XY, offset = 75)) circleSketch0 = startSketchOn(offsetPlane('XY', offset = 75))
|> circle(center = [0, 100], radius = 50) |> circle(center = [0, 100], radius = 50)
circleSketch1 = startSketchOn(offsetPlane(XY, offset = 150)) circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
|> circle(center = [0, 100], radius = 20) |> circle(center = [0, 100], radius = 20)
loft([ loft([
@ -89,7 +85,7 @@ loft([
```js ```js
// Loft a square, a circle, and another circle with options. // Loft a square, a circle, and another circle with options.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn('XY')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -97,10 +93,10 @@ squareSketch = startSketchOn(XY)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
circleSketch0 = startSketchOn(offsetPlane(XY, offset = 75)) circleSketch0 = startSketchOn(offsetPlane('XY', offset = 75))
|> circle(center = [0, 100], radius = 50) |> circle(center = [0, 100], radius = 50)
circleSketch1 = startSketchOn(offsetPlane(XY, offset = 150)) circleSketch1 = startSketchOn(offsetPlane('XY', offset = 150))
|> circle(center = [0, 100], radius = 20) |> circle(center = [0, 100], radius = 20)
loft( loft(

View File

@ -35,7 +35,7 @@ log(
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [log(100, 5), 0]) |> line(end = [log(100, 5), 0])
|> line(end = [5, 8]) |> line(end = [5, 8])

View File

@ -31,7 +31,7 @@ log10(num: number): number
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [log10(100), 0]) |> line(end = [log10(100), 0])
|> line(end = [5, 8]) |> line(end = [5, 8])

View File

@ -31,7 +31,7 @@ log2(num: number): number
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [log2(100), 0]) |> line(end = [log2(100), 0])
|> line(end = [5, 8]) |> line(end = [5, 8])

File diff suppressed because one or more lines are too long

View File

@ -33,7 +33,7 @@ map(
```js ```js
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)
} }
@ -49,7 +49,7 @@ circles = map([1..3], drawCircle)
r = 10 // radius 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], fn(id) { circles = map([1..3], fn(id) {
return startSketchOn(XY) return startSketchOn("XY")
|> circle(center = [id * 2 * r, 0], radius = r) |> circle(center = [id * 2 * r, 0], radius = r)
}) })
``` ```

View File

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

View File

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

104
docs/kcl/mirror2d.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
--- ---
title: "KCL Modules" title: "KCL Modules"
excerpt: "Documentation of modules for the KCL language for the Zoo Design Studio." excerpt: "Documentation of modules for the KCL language for the Zoo Modeling App."
layout: manual layout: manual
--- ---
@ -95,7 +95,7 @@ import "tests/inputs/cube.obj"
When importing a GLTF file, the bin file will be imported as well. When importing a GLTF file, the bin file will be imported as well.
Import paths are relative to the current project directory. Imports currently only work when Import paths are relative to the current project directory. Imports currently only work when
using the native Design Studio, not in the browser. using the native Modeling App, not in the browser.
### Supported values ### Supported values

View File

@ -32,7 +32,7 @@ offsetPlane(
```js ```js
// Loft a square and a circle on the `XY` plane using offset. // Loft a square and a circle on the `XY` plane using offset.
squareSketch = startSketchOn(XY) squareSketch = startSketchOn('XY')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -40,7 +40,7 @@ squareSketch = startSketchOn(XY)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
circleSketch = startSketchOn(offsetPlane(XY, offset = 150)) circleSketch = startSketchOn(offsetPlane('XY', offset = 150))
|> circle(center = [0, 100], radius = 50) |> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch]) loft([squareSketch, circleSketch])
@ -50,7 +50,7 @@ loft([squareSketch, circleSketch])
```js ```js
// Loft a square and a circle on the `XZ` plane using offset. // Loft a square and a circle on the `XZ` plane using offset.
squareSketch = startSketchOn(XZ) squareSketch = startSketchOn('XZ')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -58,7 +58,7 @@ squareSketch = startSketchOn(XZ)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
circleSketch = startSketchOn(offsetPlane(XZ, offset = 150)) circleSketch = startSketchOn(offsetPlane('XZ', offset = 150))
|> circle(center = [0, 100], radius = 50) |> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch]) loft([squareSketch, circleSketch])
@ -68,7 +68,7 @@ loft([squareSketch, circleSketch])
```js ```js
// Loft a square and a circle on the `YZ` plane using offset. // Loft a square and a circle on the `YZ` plane using offset.
squareSketch = startSketchOn(YZ) squareSketch = startSketchOn('YZ')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -76,7 +76,7 @@ squareSketch = startSketchOn(YZ)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
circleSketch = startSketchOn(offsetPlane(YZ, offset = 150)) circleSketch = startSketchOn(offsetPlane('YZ', offset = 150))
|> circle(center = [0, 100], radius = 50) |> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch]) loft([squareSketch, circleSketch])
@ -86,7 +86,7 @@ loft([squareSketch, circleSketch])
```js ```js
// Loft a square and a circle on the `-XZ` plane using offset. // Loft a square and a circle on the `-XZ` plane using offset.
squareSketch = startSketchOn(-XZ) squareSketch = startSketchOn('-XZ')
|> startProfileAt([-100, 200], %) |> startProfileAt([-100, 200], %)
|> line(end = [200, 0]) |> line(end = [200, 0])
|> line(end = [0, -200]) |> line(end = [0, -200])
@ -94,7 +94,7 @@ squareSketch = startSketchOn(-XZ)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
circleSketch = startSketchOn(offsetPlane(-XZ, offset = -150)) circleSketch = startSketchOn(offsetPlane('-XZ', offset = -150))
|> circle(center = [0, 100], radius = 50) |> circle(center = [0, 100], radius = 50)
loft([squareSketch, circleSketch]) loft([squareSketch, circleSketch])
@ -104,12 +104,12 @@ loft([squareSketch, circleSketch])
```js ```js
// 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, offset = 4)) startSketchOn(offsetPlane("XY", offset = 4))
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [10, 0]) |> line(end = [10, 0])
|> line(end = [0, 10]) |> line(end = [0, 10])

View File

@ -10,7 +10,7 @@ Repeat a 2-dimensional sketch some number of times along a partial or complete c
```js ```js
patternCircular2d( patternCircular2d(
sketchSet: [Sketch], sketchSet: SketchSet,
instances: integer, instances: integer,
center: [number], center: [number],
arcDegrees: number, arcDegrees: number,
@ -24,7 +24,7 @@ patternCircular2d(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketchSet` | [`[Sketch]`](/docs/kcl/types/Sketch) | Which sketch(es) to pattern | Yes | | `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | Which sketch(es) to pattern | Yes |
| `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. | Yes | | `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. | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center about which to make the pattern. This is a 2D vector. | Yes | | `center` | [`[number]`](/docs/kcl/types/number) | The center about which to make the pattern. This is a 2D vector. | Yes |
| `arcDegrees` | [`number`](/docs/kcl/types/number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes | | `arcDegrees` | [`number`](/docs/kcl/types/number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes |
@ -39,7 +39,7 @@ patternCircular2d(
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> startProfileAt([.5, 25], %) |> startProfileAt([.5, 25], %)
|> line(end = [0, 5]) |> line(end = [0, 5])
|> line(end = [-1, 0]) |> line(end = [-1, 0])

View File

@ -10,7 +10,7 @@ Repeat a 3-dimensional solid some number of times along a partial or complete ci
```js ```js
patternCircular3d( patternCircular3d(
solids: [Solid], solidSet: SolidSet,
instances: integer, instances: integer,
axis: [number], axis: [number],
center: [number], center: [number],
@ -25,7 +25,7 @@ patternCircular3d(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | Which solid(s) to pattern | Yes | | `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | Which solid(s) to pattern | Yes |
| `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. | Yes | | `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. | Yes |
| `axis` | [`[number]`](/docs/kcl/types/number) | The axis around which to make the pattern. This is a 3D vector | Yes | | `axis` | [`[number]`](/docs/kcl/types/number) | The axis around which to make the pattern. This is a 3D vector | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center about which to make the pattern. This is a 3D vector. | Yes | | `center` | [`[number]`](/docs/kcl/types/number) | The center about which to make the pattern. This is a 3D vector. | Yes |
@ -41,7 +41,7 @@ patternCircular3d(
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> circle(center = [0, 0], radius = 1) |> circle(center = [0, 0], radius = 1)
example = extrude(exampleSketch, length = -5) example = extrude(exampleSketch, length = -5)

View File

@ -10,7 +10,7 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount of dis
```js ```js
patternLinear2d( patternLinear2d(
sketches: [Sketch], sketchSet: SketchSet,
instances: integer, instances: integer,
distance: number, distance: number,
axis: [number], axis: [number],
@ -23,7 +23,7 @@ patternLinear2d(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | The sketch(es) to duplicate | Yes | | `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch(es) to duplicate | Yes |
| `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. | Yes | | `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. | Yes |
| `distance` | [`number`](/docs/kcl/types/number) | Distance between each repetition. Also known as 'spacing'. | Yes | | `distance` | [`number`](/docs/kcl/types/number) | Distance between each repetition. Also known as 'spacing'. | Yes |
| `axis` | [`[number]`](/docs/kcl/types/number) | The axis of the pattern. A 2D vector. | Yes | | `axis` | [`[number]`](/docs/kcl/types/number) | The axis of the pattern. A 2D vector. | Yes |
@ -37,7 +37,7 @@ patternLinear2d(
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> circle(center = [0, 0], radius = 1) |> circle(center = [0, 0], radius = 1)
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4) |> patternLinear2d(axis = [1, 0], instances = 7, distance = 4)

View File

@ -10,7 +10,7 @@ Repeat a 3-dimensional solid along a linear path, with a dynamic amount of dista
```js ```js
patternLinear3d( patternLinear3d(
solids: [Solid], solidSet: SolidSet,
instances: integer, instances: integer,
distance: number, distance: number,
axis: [number], axis: [number],
@ -23,7 +23,7 @@ patternLinear3d(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | The solid(s) to duplicate | Yes | | `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | The solid(s) to duplicate | Yes |
| `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. | Yes | | `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. | Yes |
| `distance` | [`number`](/docs/kcl/types/number) | Distance between each repetition. Also known as 'spacing'. | Yes | | `distance` | [`number`](/docs/kcl/types/number) | Distance between each repetition. Also known as 'spacing'. | Yes |
| `axis` | [`[number]`](/docs/kcl/types/number) | The axis of the pattern. A 2D vector. | Yes | | `axis` | [`[number]`](/docs/kcl/types/number) | The axis of the pattern. A 2D vector. | Yes |
@ -37,7 +37,7 @@ patternLinear3d(
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line(end = [0, 2]) |> line(end = [0, 2])
|> line(end = [3, 1]) |> line(end = [3, 1])
@ -53,7 +53,7 @@ example = extrude(exampleSketch, length = 1)
```js ```js
// Pattern a whole sketch on face. // Pattern a whole sketch on face.
size = 100 size = 100
case = startSketchOn(XY) case = startSketchOn('XY')
|> startProfileAt([-size, -size], %) |> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0]) |> line(end = [2 * size, 0])
|> line(end = [0, 2 * size]) |> line(end = [0, 2 * size])
@ -84,7 +84,7 @@ patternLinear3d(
```js ```js
// Pattern an object on a face. // Pattern an object on a face.
size = 100 size = 100
case = startSketchOn(XY) case = startSketchOn('XY')
|> startProfileAt([-size, -size], %) |> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0]) |> line(end = [2 * size, 0])
|> line(end = [0, 2 * size]) |> line(end = [0, 2 * size])

View File

@ -36,7 +36,7 @@ The transform function returns a transform object. All properties of the object
```js ```js
patternTransform( patternTransform(
solids: [Solid], solidSet: SolidSet,
instances: integer, instances: integer,
transform: FunctionSource, transform: FunctionSource,
useOriginal?: bool, useOriginal?: bool,
@ -48,7 +48,7 @@ patternTransform(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | The solid(s) to duplicate | Yes | | `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | The solid(s) to duplicate | Yes |
| `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. | Yes | | `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. | Yes |
| `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes | | `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
| `useOriginal` | [`bool`](/docs/kcl/types/bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No | | `useOriginal` | [`bool`](/docs/kcl/types/bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
@ -67,7 +67,7 @@ fn transform(id) {
} }
// Sketch 4 cylinders. // Sketch 4 cylinders.
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> extrude(length = 5) |> extrude(length = 5)
|> patternTransform(instances = 4, transform = transform) |> patternTransform(instances = 4, transform = transform)
@ -83,7 +83,7 @@ fn transform(id) {
return { translate = [4 * (1 + id), 0, 0] } return { translate = [4 * (1 + id), 0, 0] }
} }
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> extrude(length = 5) |> extrude(length = 5)
|> patternTransform(instances = 4, transform = transform) |> patternTransform(instances = 4, transform = transform)
@ -101,7 +101,7 @@ fn cube(length, center) {
p2 = [l + x, l + y] p2 = [l + x, l + y]
p3 = [l + x, -l + y] p3 = [l + x, -l + y]
return startSketchOn(XY) return startSketchOn('XY')
|> startProfileAt(p0, %) |> startProfileAt(p0, %)
|> line(endAbsolute = p1) |> line(endAbsolute = p1)
|> line(endAbsolute = p2) |> line(endAbsolute = p2)
@ -139,7 +139,7 @@ fn cube(length, center) {
p2 = [l + x, l + y] p2 = [l + x, l + y]
p3 = [l + x, -l + y] p3 = [l + x, -l + y]
return startSketchOn(XY) return startSketchOn('XY')
|> startProfileAt(p0, %) |> startProfileAt(p0, %)
|> line(endAbsolute = p1) |> line(endAbsolute = p1)
|> line(endAbsolute = p2) |> line(endAbsolute = p2)
@ -182,7 +182,7 @@ fn transform(replicaId) {
} }
// Each layer is just a pretty thin cylinder. // Each layer is just a pretty thin cylinder.
fn layer() { fn layer() {
return startSketchOn(XY) return startSketchOn("XY")
// or some other plane idk // or some other plane idk
|> circle(center = [0, 0], radius = 1, tag = $tag1) |> circle(center = [0, 0], radius = 1, tag = $tag1)
|> extrude(length = h) |> extrude(length = h)
@ -203,7 +203,7 @@ fn transform(i) {
{ rotation = { angle = 45 * i } } { rotation = { angle = 45 * i } }
] ]
} }
startSketchOn(XY) startSketchOn('XY')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> polygon({ |> polygon({
radius = 10, radius = 10,

View File

@ -10,7 +10,7 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
```js ```js
patternTransform2d( patternTransform2d(
sketches: [Sketch], sketchSet: SketchSet,
instances: integer, instances: integer,
transform: FunctionSource, transform: FunctionSource,
useOriginal?: bool, useOriginal?: bool,
@ -22,7 +22,7 @@ patternTransform2d(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | The sketch(es) to duplicate | Yes | | `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch(es) to duplicate | Yes |
| `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. | Yes | | `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. | Yes |
| `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes | | `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
| `useOriginal` | [`bool`](/docs/kcl/types/bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No | | `useOriginal` | [`bool`](/docs/kcl/types/bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
@ -41,7 +41,7 @@ fn transform(id) {
} }
// Sketch 4 circles. // Sketch 4 circles.
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn('XZ')
|> circle(center = [0, 0], radius = 2) |> circle(center = [0, 0], radius = 2)
|> patternTransform2d(instances = 4, transform = transform) |> patternTransform2d(instances = 4, transform = transform)
``` ```

View File

@ -30,7 +30,7 @@ pi(): number
```js ```js
circumference = 70 circumference = 70
exampleSketch = startSketchOn(XZ) exampleSketch = startSketchOn("XZ")
|> circle(center = [0, 0], radius = circumference / (2 * pi())) |> circle(center = [0, 0], radius = circumference / (2 * pi()))
example = extrude(exampleSketch, length = 5) example = extrude(exampleSketch, length = 5)

43
docs/kcl/polar.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -34,7 +34,7 @@ polygon(
```js ```js
// 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,
@ -49,7 +49,7 @@ example = extrude(hex, length = 5)
```js ```js
// 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,

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