Compare commits

..

2 Commits

1432 changed files with 153394 additions and 302343 deletions

View File

@ -19,11 +19,6 @@
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error",
@ -66,7 +61,6 @@
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"react/no-unknown-property": "error",
"no-restricted-globals": [
"error",
{

View File

@ -26,8 +26,8 @@ max_retries=1
# Retry failed tests, doing our own retries because using inbuilt Playwright retries causes connection issues
while [[ $retry -le $max_retries ]]; do
if [[ -f "test-results/.last-run.json" ]]; then
status=$(jq -r '.status' test-results/.last-run.json)
if [[ "$status" == "failed" ]]; then
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then
echo "retried=true" >>$GITHUB_OUTPUT
echo "run playwright with last failed tests and retry $retry"
if [[ "$3" == *ubuntu* ]]; then
@ -56,11 +56,10 @@ done
echo "retried=false" >>$GITHUB_OUTPUT
if [[ -f "test-results/.last-run.json" ]]; then
status=$(jq -r '.status' test-results/.last-run.json)
if [[ "$status" == "failed" ]]; then
# If it still fails after retries, then fail the job
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
if [[ $failed_tests -gt 0 ]]; then
# If it still fails after 3 retries, then fail the job
exit 1
fi
fi
exit 0

View File

@ -26,8 +26,12 @@ name: cargo bench
jobs:
cargo-bench:
name: cargo bench
runs-on: ubuntu-latest
runs-on:
- runs-on=${{ github.run_id }}
- runner=32cpu-linux-x64
- extras=s3-cache
steps:
- uses: runs-on/action@v1
- uses: actions/checkout@v4
- name: Use correct Rust toolchain
shell: bash

View File

@ -15,12 +15,8 @@ name: cargo test
jobs:
cargotest:
name: cargo test
runs-on:
- runs-on=${{ github.run_id }}
- runner=32cpu-linux-x64
- extras=s3-cache
runs-on: ubuntu-latest-8-cores
steps:
- uses: runs-on/action@v1
- uses: actions/create-github-app-token@v1
id: app-token
with:
@ -85,10 +81,11 @@ jobs:
run: |
set -euo pipefail
cd rust
cargo nextest run --workspace --features artifact-graph --retries=2 --no-fail-fast --profile ci simulation_tests::kcl_samples 2>&1 | tee /tmp/github-actions.log
cargo nextest run --workspace --retries=2 --no-fail-fast --profile ci simulation_tests::kcl_samples 2>&1 | tee /tmp/github-actions.log
env:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: Commit differences
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
shell: bash
@ -121,14 +118,16 @@ jobs:
# Configure nextest when it's run by insta (via just).
NEXTEST_PROFILE: ci
RUST_BACKTRACE: full
RUST_MIN_STACK: 10485760000
- name: cargo test
if: steps.path-changes.outputs.outside-kcl-samples == 'true'
shell: bash
run: |-
cd rust
cargo llvm-cov nextest --workspace --features artifact-graph --lcov --output-path lcov.info --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log
cargo llvm-cov nextest --workspace --lcov --output-path lcov.info --retries=2 --no-fail-fast -P ci 2>&1 | tee /tmp/github-actions.log
env:
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
RUST_MIN_STACK: 10485760000
- name: Upload to codecov.io
if: steps.path-changes.outputs.outside-kcl-samples == 'true'
uses: codecov/codecov-action@v5

View File

@ -3,6 +3,7 @@ on:
push:
branches:
- main
- all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
pull_request:
schedule:
- cron: 0 * * * * # hourly
@ -282,37 +283,23 @@ jobs:
fail-fast: false
matrix:
# TODO: enable namespace-profile-windows-latest once available
include:
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 1
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 2
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 3
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 4
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 5
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 6
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 7
shardTotal: 8
- os: "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
shardIndex: 8
shardTotal: 8
- os: namespace-profile-macos-8-cores
shardIndex: 1
shardTotal: 1
os:
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- namespace-profile-macos-6-cores
- windows-latest-8-cores
shardIndex: [1, 2, 3, 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-6-cores
isScheduled: true
- os: windows-latest-8-cores
shardIndex: 1
shardTotal: 1
isScheduled: true
# TODO: add ref here for main and latest release tag
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

45
.github/workflows/update-e2e-branch.yml vendored Normal file
View File

@ -0,0 +1,45 @@
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

@ -5,6 +5,6 @@ command = "vscode-eslint-language-server"
[[language]]
name = "typescript"
auto-format = true
formatter = { command = "./node_modules/@biomejs/biome/bin/biome", args = ["format", "--write", "--stdin-file-path=foo.ts"] }
# language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]
formatter = { command = "node_modules/.bin/prettier", args = ["--parser", "typescript"] }
language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]

View File

@ -1 +0,0 @@
npm run fmt

4
.husky/pre-push Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run fmt-check

View File

@ -9,7 +9,7 @@ Compute the absolute value of a number.
```js
abs(input: number): number
abs(num: number): number
```
### Tags
@ -21,7 +21,7 @@ abs(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the absolute value of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -34,7 +34,7 @@ abs(input: number): number
myAngle = -120
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [8, 0])
|> angledLine(angle = abs(myAngle), length = 5)
|> line(end = [-5, 0])

View File

@ -9,7 +9,7 @@ Compute the arccosine of a number (in radians).
```js
acos(input: number): number
acos(num: number): number
```
### Tags
@ -21,7 +21,7 @@ acos(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute arccosine of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ acos(input: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(acos(0.5)), length = 10)
|> line(end = [5, 0])
|> line(endAbsolute = [12, 0])

View File

@ -34,7 +34,7 @@ angleToMatchLengthX(
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [2, 5], tag = $seg01)
|> angledLine(angle = -angleToMatchLengthX(seg01, 7, %), endAbsoluteX = 10)
|> close()

View File

@ -34,7 +34,7 @@ angleToMatchLengthY(
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [1, 2], tag = $seg01)
|> angledLine(angle = angleToMatchLengthY(seg01, 15, %), length = 5)
|> yLine(endAbsolute = 0)

View File

@ -44,7 +44,7 @@ angledLine(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> yLine(endAbsolute = 15)
|> angledLine(angle = 30, length = 15)
|> line(end = [8, -10])

View File

@ -38,7 +38,7 @@ angledLineThatIntersects(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [5, 10])
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|> line(endAbsolute = [0, 20])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

45
docs/kcl/arcTo.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Compute the arcsine of a number (in radians).
```js
asin(input: number): number
asin(num: number): number
```
### Tags
@ -21,7 +21,7 @@ asin(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute arcsine of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ asin(input: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(asin(0.5)), length = 20)
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,10 +6,10 @@ layout: manual
Compute the arctangent of a number (in radians).
Consider using `atan2()` instead for the true inverse of tangent.
```js
atan(input: number): number
atan(num: number): number
```
### Tags
@ -21,7 +21,7 @@ atan(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute arctangent of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ atan(input: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(atan(1.25)), length = 20)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -36,7 +36,7 @@ atan2(
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(angle = toDegrees(atan2(y = 1.25, x = 2)), length = 20)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -10,10 +10,8 @@ Draw a smooth, continuous, curved line segment from the current origin to the de
```js
bezierCurve(
data: BezierData,
sketch: Sketch,
control1: [number],
control2: [number],
end: [number],
tag?: TagDeclarator,
): Sketch
```
@ -23,11 +21,9 @@ bezierCurve(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `control1` | [`[number]`](/docs/kcl/types/number) | First control point for the cubic | Yes |
| `control2` | [`[number]`](/docs/kcl/types/number) | Second control point for the cubic | Yes |
| `end` | [`[number]`](/docs/kcl/types/number) | How far away (along the X and Y axes) should this line go? | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| `data` | [`BezierData`](/docs/kcl/types/BezierData) | Data to draw a bezier curve. | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
### Returns
@ -38,9 +34,13 @@ bezierCurve(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [0, 10])
|> bezierCurve(control1 = [5, 0], control2 = [5, 10], end = [10, 10])
|> bezierCurve({
to = [10, 10],
control1 = [5, 0],
control2 = [5, 10]
}, %)
|> line(endAbsolute = [10, 0])
|> close()

View File

@ -9,7 +9,7 @@ Compute the smallest integer greater than or equal to a number.
```js
ceil(input: number): number
ceil(num: number): number
```
### Tags
@ -21,7 +21,7 @@ ceil(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to round. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ ceil(input: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [ceil(7.02986), 0])
|> yLine(endAbsolute = 0)

95
docs/kcl/chamfer.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

@ -32,7 +32,7 @@ close(
```js
startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 10])
|> line(end = [10, 0])
|> close()
@ -43,7 +43,7 @@ startSketchOn(XZ)
```js
exampleSketch = startSketchOn(-XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10])
|> close()

View File

@ -16,7 +16,7 @@ std::math::E: number = 2.71828182845904523536028747135266250_
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 30,
length = 2 * E ^ 2,

View File

@ -16,7 +16,7 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 50,
length = 10 * TAU,

View File

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

View File

@ -40,12 +40,20 @@ extrude(
```js
example = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> arc(angleStart = 120, angleEnd = 0, radius = 5)
|> arc({
angleStart = 120,
angleEnd = 0,
radius = 5
}, %)
|> line(end = [5, 0])
|> line(end = [0, 10])
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve({
control1 = [-10, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-5, -2])
|> close()
|> extrude(length = 10)
@ -55,11 +63,19 @@ example = startSketchOn(XZ)
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [-10, 0])
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()
@ -71,11 +87,19 @@ example = extrude(exampleSketch, length = 10)
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [-10, 0])
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()
@ -87,11 +111,19 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [-10, 0])
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()

94
docs/kcl/fillet.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Compute the largest integer less than or equal to a number.
```js
floor(input: number): number
floor(num: number): number
```
### Tags
@ -21,7 +21,7 @@ floor(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to round. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ floor(input: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [floor(7.02986), 0])
|> yLine(endAbsolute = 0)

View File

@ -4,12 +4,8 @@ excerpt: "Converts a number from centimeters to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from centimeters to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`.

View File

@ -4,12 +4,8 @@ excerpt: "Converts a number from feet to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from feet to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`.

View File

@ -4,12 +4,8 @@ excerpt: "Converts a number from inches to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from inches to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`.

View File

@ -4,12 +4,8 @@ excerpt: "Converts a number from meters to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from meters to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`.

View File

@ -4,12 +4,8 @@ excerpt: "Converts a number from mm to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from mm to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`.

View File

@ -4,12 +4,8 @@ excerpt: "Converts a number from yards to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from yards to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`.

View File

@ -32,7 +32,7 @@ getCommonEdge(faces: [TagIdentifier]): Uuid
scale = 20
part001 = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [0, scale])
|> line(end = [scale, 0])
|> line(end = [0, -scale])

View File

@ -9,7 +9,7 @@ Get the next adjacent edge to the edge given.
```js
getNextAdjacentEdge(edge: TagIdentifier): Uuid
getNextAdjacentEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getNextAdjacentEdge(edge: TagIdentifier): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the next adjacent edge of. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
### Returns
@ -28,7 +28,7 @@ getNextAdjacentEdge(edge: TagIdentifier): Uuid
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10)

View File

@ -9,7 +9,7 @@ Get the opposite edge to the edge given.
```js
getOppositeEdge(edge: TagIdentifier): Uuid
getOppositeEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getOppositeEdge(edge: TagIdentifier): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the opposite edge of. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
### Returns
@ -28,7 +28,7 @@ getOppositeEdge(edge: TagIdentifier): Uuid
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10)

View File

@ -9,7 +9,7 @@ Get the previous adjacent edge to the edge given.
```js
getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the previous adjacent edge of. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
### Returns
@ -28,7 +28,7 @@ getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> angledLine(angle = 60, length = 10)
|> angledLine(angle = 120, length = 10)

67
docs/kcl/hole.md Normal file

File diff suppressed because one or more lines are too long

85
docs/kcl/hollow.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -22,8 +22,18 @@ layout: manual
* [`string`](kcl/types/string)
* [`tag`](kcl/types/tag)
* **std**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`END`](kcl/consts/std-END)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`START`](kcl/consts/std-START)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* [`X`](kcl/consts/std-X)
* [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ)
@ -32,27 +42,43 @@ layout: manual
* [`Z`](kcl/consts/std-Z)
* [`abs`](kcl/abs)
* [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`appearance`](kcl/appearance)
* [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo)
* [`asin`](kcl/asin)
* [`assert`](kcl/assert)
* [`assertIs`](kcl/assertIs)
* [`assertEqual`](kcl/assertEqual)
* [`assertGreaterThan`](kcl/assertGreaterThan)
* [`assertGreaterThanOrEq`](kcl/assertGreaterThanOrEq)
* [`assertLessThan`](kcl/assertLessThan)
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
* [`atan`](kcl/atan)
* [`atan2`](kcl/atan2)
* [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`clone`](kcl/clone)
* [`close`](kcl/close)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`fromCm`](kcl/fromCm)
* [`fromFt`](kcl/fromFt)
* [`fromInches`](kcl/fromInches)
* [`fromM`](kcl/fromM)
* [`fromMm`](kcl/fromMm)
* [`fromYd`](kcl/fromYd)
* [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/std-helix)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`intersect`](kcl/intersect)
* [`involuteCircular`](kcl/involuteCircular)
* [`lastSegX`](kcl/lastSegX)
@ -69,7 +95,7 @@ layout: manual
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`offsetPlane`](kcl/std-offsetPlane)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d)
@ -97,22 +123,16 @@ layout: manual
* [`segStart`](kcl/segStart)
* [`segStartX`](kcl/segStartX)
* [`segStartY`](kcl/segStartY)
* [`shell`](kcl/shell)
* [`sqrt`](kcl/sqrt)
* [`startProfile`](kcl/startProfile)
* [`startProfileAt`](kcl/startProfileAt)
* [`startSketchOn`](kcl/startSketchOn)
* [`subtract`](kcl/subtract)
* [`subtract2d`](kcl/subtract2d)
* [`sweep`](kcl/sweep)
* [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc)
* [`toCentimeters`](kcl/std-toCentimeters)
* [`toDegrees`](kcl/std-toDegrees)
* [`toFeet`](kcl/std-toFeet)
* [`toInches`](kcl/std-toInches)
* [`toMeters`](kcl/std-toMeters)
* [`toMillimeters`](kcl/std-toMillimeters)
* [`toRadians`](kcl/std-toRadians)
* [`toYards`](kcl/std-toYards)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`translate`](kcl/translate)
* [`union`](kcl/union)
* [`xLine`](kcl/xLine)
@ -128,24 +148,8 @@ layout: manual
* **std::sketch**
* [`circle`](kcl/std-sketch-circle)
* [`mirror2d`](kcl/std-sketch-mirror2d)
* **std::solid**
* [`chamfer`](kcl/std-solid-chamfer)
* [`fillet`](kcl/std-solid-fillet)
* [`hollow`](kcl/std-solid-hollow)
* [`shell`](kcl/std-solid-shell)
* **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)
* **std::types**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)

View File

@ -34,7 +34,7 @@ int(num: number): number
```js
n = int(ceil(5 / 2))
assert(n, isEqualTo = 3, error = "5/2 = 2.5, rounded up makes 3")
assertEqual(n, 3, 0.0001, "5/2 = 2.5, rounded up makes 3")
// Draw n cylinders.
startSketchOn(XZ)
|> circle(center = [0, 0], radius = 2)

View File

@ -36,7 +36,7 @@ intersect(
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> startProfileAt([center[0] - size, center[1] - size], %)
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])
@ -61,7 +61,7 @@ intersectedPart = intersect([part001, part002])
fn cube(center, size) {
return startSketchOn(XY)
|> startProfile(at = [center[0] - size, center[1] - size])
|> startProfileAt([center[0] - size, center[1] - size], %)
|> line(endAbsolute = [center[0] + size, center[1] - size])
|> line(endAbsolute = [center[0] + size, center[1] + size])
|> line(endAbsolute = [center[0] - size, center[1] + size])

View File

@ -42,7 +42,7 @@ involuteCircular(
a = 10
b = 14
startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> involuteCircular(startRadius = a, endRadius = b, angle = 60)
|> involuteCircular(
startRadius = a,

View File

@ -21,6 +21,4 @@ once fixed in engine will just start working here with no language changes.
- **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple
chamfer cases work currently.
- **Appearance**: Changing the appearance on a loft does not work.
- **CSG Booleans**: Coplanar (bodies that share a plane) unions, subtractions, and intersections are not currently supported.
- **Appearance**: Changing the appearance on a loft does not work.

View File

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

View File

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

View File

@ -24,8 +24,8 @@ legAngX(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -35,7 +35,7 @@ legAngX(
### Examples
```js
legAngX(hypotenuse = 5, leg = 3)
legAngX(5, 3)
```

View File

@ -24,8 +24,8 @@ legAngY(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -35,7 +35,7 @@ legAngY(
### Examples
```js
legAngY(hypotenuse = 5, leg = 3)
legAngY(5, 3)
```

View File

@ -24,8 +24,8 @@ legLen(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -35,7 +35,7 @@ legLen(
### Examples
```js
legLen(hypotenuse = 5, leg = 3)
legLen(5, 3)
```

View File

@ -36,7 +36,7 @@ line(
```js
triangle = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
// The END argument means it ends at exactly [10, 0].
// This is an absolute measurement, it is NOT relative to
// the start of the sketch.
@ -47,7 +47,7 @@ triangle = startSketchOn(XZ)
|> extrude(length = 5)
box = startSketchOn(XZ)
|> startProfile(at = [10, 10])
|> startProfileAt([10, 10], %)
// The 'to' argument means move the pen this much.
// So, [10, 0] is a relative distance away from the current point.
|> line(end = [10, 0])

View File

@ -9,7 +9,7 @@ Compute the natural logarithm of the number.
```js
ln(input: number): number
ln(num: number): number
```
### Tags
@ -21,7 +21,7 @@ ln(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the logarithm of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ ln(input: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [ln(100), 15])
|> line(end = [5, -6])
|> line(end = [-10, -10])

View File

@ -43,7 +43,7 @@ loft(
```js
// Loft a square and a triangle.
squareSketch = startSketchOn(XY)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])
@ -51,7 +51,7 @@ squareSketch = startSketchOn(XY)
|> close()
triangleSketch = startSketchOn(offsetPlane(XY, offset = 75))
|> startProfile(at = [0, 125])
|> startProfileAt([0, 125], %)
|> line(end = [-15, -30])
|> line(end = [30, 0])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
@ -65,7 +65,7 @@ loft([squareSketch, triangleSketch])
```js
// Loft a square, a circle, and another circle.
squareSketch = startSketchOn(XY)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])
@ -90,7 +90,7 @@ loft([
```js
// Loft a square, a circle, and another circle with options.
squareSketch = startSketchOn(XY)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])

View File

@ -10,7 +10,7 @@ The result might not be correctly rounded owing to implementation details; `log2
```js
log(
input: number,
num: number,
base: number,
): number
```
@ -24,8 +24,8 @@ log(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the logarithm of. | Yes |
| `base` | [`number`](/docs/kcl/types/number) | The base of the logarithm. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
| `base` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -36,8 +36,8 @@ log(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> line(end = [log(100, base = 5), 0])
|> startProfileAt([0, 0], %)
|> line(end = [log(100, 5), 0])
|> line(end = [5, 8])
|> line(end = [-10, 0])
|> close()

View File

@ -32,7 +32,7 @@ log10(num: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [log10(100), 0])
|> line(end = [5, 8])
|> line(end = [-10, 0])

View File

@ -9,7 +9,7 @@ Compute the base 2 logarithm of the number.
```js
log2(input: number): number
log2(num: number): number
```
### Tags
@ -21,7 +21,7 @@ log2(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the logarithm of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ log2(input: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [log2(100), 0])
|> line(end = [5, 8])
|> line(end = [-10, 0])

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Compute the maximum of the given arguments.
```js
max(input: [number]): number
max(args: [number]): number
```
### Tags
@ -21,7 +21,7 @@ max(input: [number]): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`[number]`](/docs/kcl/types/number) | An array of numbers to compute the maximum of. | Yes |
| `args` | [`[number]`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,8 +32,8 @@ max(input: [number]): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 70, length = max([15, 31, 4, 13, 22]))
|> startProfileAt([0, 0], %)
|> angledLine(angle = 70, length = max(15, 31, 4, 13, 22))
|> line(end = [20, 0])
|> close()

View File

@ -9,7 +9,7 @@ Compute the minimum of the given arguments.
```js
min(input: [number]): number
min(args: [number]): number
```
### Tags
@ -21,7 +21,7 @@ min(input: [number]): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`[number]`](/docs/kcl/types/number) | An array of numbers to compute the minimum of. | Yes |
| `args` | [`[number]`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,8 +32,8 @@ min(input: [number]): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 70, length = min([15, 31, 4, 13, 22]))
|> startProfileAt([0, 0], %)
|> angledLine(angle = 70, length = min(15, 31, 4, 13, 22))
|> line(end = [20, 0])
|> close()

View File

@ -10,7 +10,7 @@ isolated from other files as a separate module.
When you define a function, you can use `export` before it to make it available
to other modules.
```kcl
```
// util.kcl
export fn increment(x) {
return x + 1
@ -31,11 +31,11 @@ Imported files _must_ be in the same project so that units are uniform across
modules. This means that it must be in the same directory.
Import statements must be at the top-level of a file. It is not allowed to have
an `import` statement inside a function or in the body of an ifelse.
an `import` statement inside a function or in the body of an if-else.
Multiple functions can be exported in a file.
```kcl
```
// util.kcl
export fn increment(x) {
return x + 1
@ -58,215 +58,6 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
import increment as inc, decrement as dec from "util.kcl"
```
---
## Functions vs `clone`
There are two common patterns for reusing geometry:
1. **Wrap the construction in a function** flexible and fully parametric.
2. **Duplicate an existing object with `clone`** lightningfast, but an exact
duplicate.
### Parametric function example
```kcl
fn cube(center) {
return startSketchOn(XY)
|> startProfile(at = [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])
|> close()
|> extrude(length = 10)
}
myCube = cube([0, 0])
```
*Pros*
- Any argument can be a parameter size, position, appearance, etc.
- Works great inside loops, arrays, or optimisation sweeps.
*Cons*
- Every invocation rebuilds the entire feature tree.
- **Slower** than a straight duplicate each call is its own render job.
### `clone` example
```kcl
sketch001 = startSketchOn(-XZ)
|> circle(center = [0, 0], radius = 10)
|> extrude(length = 5)
|> appearance(color = "#ff0000", metalness = 90, roughness = 90)
sketch002 = clone(sketch001) // ✓ instant copy
```
*Pros*
- Roughly an O(1) operation we just duplicate the underlying engine handle.
- Perfect when you need ten identical bolts or two copies of the same imported STEP file.
*Cons*
- **Not parametric** the clone is exactly the same shape as the source.
- If you need to tweak dimensions perinstance, youre back to a function.
> **Rule of thumb** Reach for `clone` when the geometry is already what you want. Reach for a function when you need customisation.
---
## Modulelevel parallelism
Under the hood, the Design Studio runs **every module in parallel** where it can. This means:
- The toplevel code of `foo.kcl`, `bar.kcl`, and `baz.kcl` all start executing immediately and concurrently.
- Imports that read foreign files (STEP/OBJ/…) overlap their I/O and background render.
- CPUbound calculations in separate modules get their own worker threads.
### Why modules beat onebigfile
If you shoehorn everything into `main.kcl`, each statement runs sequentially:
```norun
import "big.step" as gizmo // blocks main while reading
gizmo |> translate(x=50) // blocks again while waiting for render
```
Split `gizmo` into its own file and the read/render can overlap whatever else `main.kcl` is doing.
```norun
// gizmo.kcl (worker A)
import "big.step"
// main.kcl (worker B)
import "gizmo.kcl" as gizmo // nonblocking
// ... other setup ...
gizmo |> translate(x=50) // only blocks here
```
### Gotcha: defining but **not** calling functions
Defining a function inside a module is instantaneous we just record the bytecode. The heavy lifting happens when the function is **called**. So:
```norun
// util.kcl
export fn makeBolt(size) { /* … expensive CAD … */ }
```
If `main.kcl` waits until the very end to call `makeBolt`, *none* of that work was parallelised youve pushed the cost back onto the serial tail of your script.
**Better:** call it early or move the invocation into another module.
```norun
// bolt_instance.kcl
import makeBolt from "util.kcl"
bolt = makeBolt(5) // executed in parallel
bolt
```
Now `main.kcl` can `import "bolt_instance.kcl" as bolt` and get the result that was rendered while it was busy doing other things.
---
## Whole module import
You can also import the whole module. This is useful if you want to use the
result of a module as a variable, like a part.
```norun
import "tests/inputs/cube.kcl" as cube
cube
|> translate(x=10)
```
This imports the whole module and makes it available as `cube`. You can then
use it like any other object. The `cube` variable is now a reference to the
result of the module. This means that if you change the module, the `cube`
variable will change as well.
In `cube.kcl`, you cannot have multiple objects. It has to be a single part. If
you have multiple objects, you will get an error. This is because the module is
expected to return a single object that can be used as a variable.
The last expression or variable definition becomes the module's return value.
The module is expected to return a single object that can be used as a variable
by whatever imports it.
So for example, this is allowed:
```norun
... a bunch of code to create cube and cube2 ...
myUnion = union([cube, cube2])
```
You can also do this:
```norun
... a bunch of code to create cube and cube2 ...
union([cube, cube2])
```
Either way, the last line will return the union of the two objects.
Or what you could do instead is:
```norun
... a bunch of code to create cube and cube2 ...
myUnion = union([cube, cube2])
myUnion
```
This will assign the union of the two objects to a variable, and then return it
on the last statement. It's simply another way of doing the same thing.
The final statement is what's important because it's the return value of the
entire module. The module is expected to return a single object that can be used
as a variable by the file that imports it.
---
## Multiple instances of the same import
Whether you are importing a file from another CAD system or a KCL file, that
file represents object(s) in memory. If you import the same file multiple times,
it will only be rendered once.
If you want to have multiple instances of the same object, you can use the
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
```norun
import cube from "tests/inputs/cube.kcl"
cube
|> translate(x=10)
clone(cube)
|> translate(x=20)
```
In the sample above, the `cube` object is imported from a KCL file. The first
instance is translated 10 units in the x direction. The second instance is
cloned and translated 20 units in the x direction. The two instances are now
separate objects in memory, and can be manipulated independently.
Here is an example with a file from another CAD system:
```kcl
import "tests/inputs/cube.step" as cube
cube
|> translate(x=10)
clone(cube)
|> translate(x=20)
```
---
## Importing files from other CAD systems
`import` can also be used to import files from other CAD systems. The format of the statement is the
@ -278,18 +69,26 @@ import "tests/inputs/cube.obj"
// Use `cube` just like a KCL object.
```
```kcl
import "tests/inputs/cube.sldprt" as cube
```norun
import "tests/inputs/cube-2.sldprt" as cube
// Use `cube` just like a KCL object.
```
You can make the file format explicit using a format attribute (useful if using a different
extension), e.g.,
```norun
@(format = obj)
import "tests/inputs/cube"
```
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 using an attribute. Likewise, you can also specify a coordinate system. E.g.,
by using an attirbute. Likewise, you can also specify a coordinate system. E.g.,
```kcl
@(lengthUnit = ft, coords = opengl)
```norun
@(unitLength = ft, coords = opengl)
import "tests/inputs/cube.obj"
```
@ -311,55 +110,97 @@ Coordinate systems:
- `opengl`, forward: +Z, up: +Y, handedness: right
- `vulkan`, forward: +Z, up: -Y, handedness: left
---
### Performance
## Performance deepdive for foreignfile imports
Parallelized foreignfile imports now let you overlap file reads, initialization,
Parallelized foreign-file imports now let you overlap file reads, initialization,
and rendering. To maximize throughput, you need to understand the three distinct
stages—reading, initializing (background render start), and invocation (blocking)
—and structure your code to defer blocking operations until the end.
### Foreign import execution stages
#### Foreign Import Execution Stages
1. **Import (Read / Initialization) Stage**
```kcl
1. **Import (Read) Stage**
```norun
import "tests/inputs/cube.step" as cube
```
- Reads the file from disk and makes its API available.
- Starts engine rendering but **does not block** your script.
- This kickstarts the render pipeline while you keep executing other code.
```
- Reads the file from disk and makes its API available.
- **Does _not_** start Engine rendering or block your script.
2. **Invocation (Blocking) Stage**
```kcl
2. **Initialization (Background Render) Stage**
```norun
import "tests/inputs/cube.step" as cube
cube
|> translate(z=10) // ← blocks here only
```
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
myCube = cube // <- This line starts background rendering
```
- Invoking the imported symbol (assignment or plain call) triggers Engine rendering _in the background_.
- This kickstarts the render pipeline but doesnt block—you can continue other work while the Engine processes the model.
### Best practices
3. **Invocation (Blocking) Stage**
```norun
import "tests/inputs/cube.step" as cube
#### 1. Defer blocking calls
myCube = cube
```kcl
import "tests/inputs/cube.step" as cube // 1) Read / Background render starts
myCube
|> translate(z=10) // <- This line blocks
```
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
- This is the only point where your script will block.
> **Nuance:** Foreign imports differ from pure KCL modules—calling the same import symbol multiple times (e.g., `screw` twice) starts background rendering twice.
#### Best Practices
##### 1. Defer Blocking Calls
Initialize early but delay all transformations until after your heavy computation:
```norun
import "tests/inputs/cube.step" as cube // 1) Read
myCube = cube // 2) Background render starts
// --- perform other operations and calculations here ---
// --- perform other operations and calculations or setup here ---
cube
|> translate(z=10) // 2) Blocks only here
myCube
|> translate(z=10) // 3) Blocks only here
```
#### 2. Split heavy work into separate modules
##### 2. Encapsulate Imports in Modules
Keep `main.kcl` free of reads and initialization; wrap them:
Place computationally expensive or IOheavy work into its own module so it can render in parallel while `main.kcl` continues.
#### Future improvements
Upcoming releases will autoanalyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.
```norun
// imports.kcl
import "tests/inputs/cube.step" as cube // Read only
export myCube = cube // Kick off rendering
```
```norun
// main.kcl
import myCube from "imports.kcl" // Import the initialized object
// ... computations ...
myCube
|> translate(z=10) // Blocking call at the end
```
##### 3. Avoid Immediate Method Calls
```norun
import "tests/inputs/cube.step" as cube
cube
|> translate(z=10) // Blocks immediately, negating parallelism
```
Both calling methods right on `cube` immediately or leaving an implicit import without assignment introduce blocking.
#### Future Improvements
Upcoming releases will autoanalyze dependencies and only block when truly necessary. Until then, explicit deferral and modular wrapping give you the best performance.

View File

@ -33,7 +33,7 @@ offsetPlane(
```js
// Loft a square and a circle on the `XY` plane using offset.
squareSketch = startSketchOn(XY)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])
@ -51,7 +51,7 @@ loft([squareSketch, circleSketch])
```js
// Loft a square and a circle on the `XZ` plane using offset.
squareSketch = startSketchOn(XZ)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])
@ -69,7 +69,7 @@ loft([squareSketch, circleSketch])
```js
// Loft a square and a circle on the `YZ` plane using offset.
squareSketch = startSketchOn(YZ)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])
@ -87,7 +87,7 @@ loft([squareSketch, circleSketch])
```js
// Loft a square and a circle on the `-XZ` plane using offset.
squareSketch = startSketchOn(-XZ)
|> startProfile(at = [-100, 200])
|> startProfileAt([-100, 200], %)
|> line(end = [200, 0])
|> line(end = [0, -200])
|> line(end = [-200, 0])
@ -105,12 +105,12 @@ loft([squareSketch, circleSketch])
```js
// A circle on the XY plane
startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> circle(radius = 10, center = [0, 0])
// Triangle on the plane 4 units above
startSketchOn(offsetPlane(XY, offset = 4))
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10])
|> close()

View File

@ -40,7 +40,7 @@ patternCircular2d(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [.5, 25])
|> startProfileAt([.5, 25], %)
|> line(end = [0, 5])
|> line(end = [-1, 0])
|> line(end = [0, -5])

View File

@ -38,7 +38,7 @@ patternLinear3d(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [0, 2])
|> line(end = [3, 1])
|> line(end = [0, -4])
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 1)
// Pattern a whole sketch on face.
size = 100
case = startSketchOn(XY)
|> startProfile(at = [-size, -size])
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])
@ -85,7 +85,7 @@ patternLinear3d(
// Pattern an object on a face.
size = 100
case = startSketchOn(XY)
|> startProfile(at = [-size, -size])
|> startProfileAt([-size, -size], %)
|> line(end = [2 * size, 0])
|> line(end = [0, 2 * size])
|> tangentialArc(endAbsolute = [-size, size])

View File

@ -102,7 +102,7 @@ fn cube(length, center) {
p3 = [l + x, -l + y]
return startSketchOn(XY)
|> startProfile(at = p0)
|> startProfileAt(p0, %)
|> line(endAbsolute = p1)
|> line(endAbsolute = p2)
|> line(endAbsolute = p3)
@ -117,11 +117,7 @@ fn transform(i) {
// Move down each time.
translate = [0, 0, -i * width],
// Make the cube longer, wider and flatter each time.
scale = [
pow(1.1, exp = i),
pow(1.1, exp = i),
pow(0.9, exp = i)
],
scale = [pow(1.1, i), pow(1.1, i), pow(0.9, i)],
// Turn by 15 degrees each time.
rotation = { angle = 15 * i, origin = "local" }
}
@ -144,7 +140,7 @@ fn cube(length, center) {
p3 = [l + x, -l + y]
return startSketchOn(XY)
|> startProfile(at = p0)
|> startProfileAt(p0, %)
|> line(endAbsolute = p1)
|> line(endAbsolute = p2)
|> line(endAbsolute = p3)
@ -178,7 +174,7 @@ t = 0.005 // taper factor [0-1)
// Defines how to modify each layer of the vase.
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
fn transform(replicaId) {
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8: number(rad)))
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
return {
translate = [0, 0, replicaId * 10],
scale = [scale, scale, 0]
@ -208,13 +204,13 @@ fn transform(i) {
]
}
startSketchOn(XY)
|> startProfile(at = [0, 0])
|> polygon(
|> startProfileAt([0, 0], %)
|> polygon({
radius = 10,
numSides = 4,
center = [0, 0],
inscribed = false,
)
inscribed = false
}, %)
|> extrude(length = 4)
|> patternTransform(instances = 3, transform = transform)
```

View File

@ -10,11 +10,9 @@ Create a regular polygon with the specified number of sides that is either inscr
```js
polygon(
data: PolygonData,
sketchSurfaceOrGroup: SketchOrSurface,
radius: number,
numSides: u64,
center: [number],
inscribed?: bool,
tag?: TagDeclarator,
): Sketch
```
@ -23,11 +21,9 @@ polygon(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on | Yes |
| `radius` | [`number`](/docs/kcl/types/number) | The radius of the polygon | Yes |
| `numSides` | `u64` | The number of sides in the polygon | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center point of the polygon | Yes |
| `inscribed` | [`bool`](/docs/kcl/types/bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius | No |
| `data` | [`PolygonData`](/docs/kcl/types/PolygonData) | Data for drawing a polygon | Yes |
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
### Returns
@ -39,12 +35,12 @@ polygon(
```js
// Create a regular hexagon inscribed in a circle of radius 10
hex = startSketchOn(XY)
|> polygon(
|> polygon({
radius = 10,
numSides = 6,
center = [0, 0],
inscribed = true,
)
inscribed = true
}, %)
example = extrude(hex, length = 5)
```
@ -54,12 +50,12 @@ example = extrude(hex, length = 5)
```js
// Create a square circumscribed around a circle of radius 5
square = startSketchOn(XY)
|> polygon(
|> polygon({
radius = 5.0,
numSides = 4,
center = [10, 10],
inscribed = false,
)
inscribed = false
}, %)
example = extrude(square, length = 5)
```

File diff suppressed because one or more lines are too long

View File

@ -10,8 +10,8 @@ Compute the number to a power.
```js
pow(
input: number,
exp: number,
num: number,
pow: number,
): number
```
@ -24,8 +24,8 @@ pow(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to raise. | Yes |
| `exp` | [`number`](/docs/kcl/types/number) | The power to raise to. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
| `pow` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -36,8 +36,8 @@ pow(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> angledLine(angle = 50, length = pow(5, exp = 2))
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = pow(5, 2))
|> yLine(endAbsolute = 0)
|> close()

View File

@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin value.
```js
profileStart(profile: Sketch): [number]
profileStart(sketch: Sketch): [number]
```
@ -17,7 +17,7 @@ profileStart(profile: Sketch): [number]
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
### Returns
@ -28,7 +28,7 @@ profileStart(profile: Sketch): [number]
```js
sketch001 = startSketchOn(XY)
|> startProfile(at = [5, 2])
|> startProfileAt([5, 2], %)
|> angledLine(angle = 120, length = 50, tag = $seg01)
|> angledLine(angle = segAng(seg01) + 120, length = 50)
|> line(end = profileStart(%))

View File

@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin's 'x' value.
```js
profileStartX(profile: Sketch): number
profileStartX(sketch: Sketch): number
```
@ -17,7 +17,7 @@ profileStartX(profile: Sketch): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
### Returns
@ -28,7 +28,7 @@ profileStartX(profile: Sketch): number
```js
sketch001 = startSketchOn(XY)
|> startProfile(at = [5, 2])
|> startProfileAt([5, 2], %)
|> angledLine(angle = -26.6, length = 50)
|> angledLine(angle = 90, length = 50)
|> angledLine(angle = 30, endAbsoluteX = profileStartX(%))

View File

@ -9,7 +9,7 @@ Extract the provided 2-dimensional sketch's profile's origin's 'y' value.
```js
profileStartY(profile: Sketch): number
profileStartY(sketch: Sketch): number
```
@ -17,7 +17,7 @@ profileStartY(profile: Sketch): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `profile` | [`Sketch`](/docs/kcl/types/Sketch) | Profile whose start is being used | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
### Returns
@ -28,7 +28,7 @@ profileStartY(profile: Sketch): number
```js
sketch001 = startSketchOn(XY)
|> startProfile(at = [5, 2])
|> startProfileAt([5, 2], %)
|> angledLine(angle = -60, length = 14)
|> angledLine(angle = 30, endAbsoluteY = profileStartY(%))
```

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

@ -63,7 +63,7 @@ rotate(
// Create a path for the sweep.
sweepPath = startSketchOn(XZ)
|> startProfile(at = [0.05, 0.05])
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0])
@ -76,7 +76,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> subtract2d(tool = pipeHole)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
|> rotate(roll = 10, pitch = 10, yaw = 90)
```
@ -88,7 +88,7 @@ sweepSketch = startSketchOn(XY)
// Create a path for the sweep.
sweepPath = startSketchOn(XZ)
|> startProfile(at = [0.05, 0.05])
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0])
@ -101,7 +101,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> subtract2d(tool = pipeHole)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
|> rotate(roll = 10)
```
@ -113,7 +113,7 @@ sweepSketch = startSketchOn(XY)
// Create a path for the sweep.
sweepPath = startSketchOn(XZ)
|> startProfile(at = [0.05, 0.05])
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0])
@ -126,7 +126,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> subtract2d(tool = pipeHole)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
|> rotate(axis = [0, 0, 1.0], angle = 90)
```
@ -150,7 +150,7 @@ cube
sketch001 = startSketchOn(XY)
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
@ -160,7 +160,7 @@ rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfile(sketch002, at = [0, 0])
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> xLine(length = 384.93)
@ -178,7 +178,7 @@ rotate(parts, axis = [0, 0, 1.0], angle = 90)
sketch001 = startSketchOn(XY)
fn square() {
return startProfile(sketch001, at = [-10, 10])
return startProfileAt([-10, 10], sketch001)
|> xLine(length = 20)
|> yLine(length = -20)
|> xLine(length = -20)

View File

@ -9,7 +9,7 @@ Round a number to the nearest integer.
```js
round(input: number): number
round(num: number): number
```
### Tags
@ -21,7 +21,7 @@ round(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to round. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ round(input: number): number
```js
sketch001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [12, 10])
|> line(end = [round(7.02986), 0])
|> yLine(endAbsolute = 0)

View File

@ -47,7 +47,7 @@ scale(
// Create a path for the sweep.
sweepPath = startSketchOn(XZ)
|> startProfile(at = [0.05, 0.05])
|> startProfileAt([0.05, 0.05], %)
|> line(end = [0, 7])
|> tangentialArc(angle = 90, radius = 5)
|> line(end = [-3, 0])
@ -60,7 +60,7 @@ pipeHole = startSketchOn(XY)
sweepSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> subtract2d(tool = pipeHole)
|> hole(pipeHole, %)
|> sweep(path = sweepPath)
|> scale(z = 2.5)
```
@ -84,7 +84,7 @@ cube
sketch001 = startSketchOn(XY)
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
@ -94,7 +94,7 @@ rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
sketch002 = startSketchOn(YZ)
sweepPath = startProfile(sketch002, at = [0, 0])
sweepPath = startProfileAt([0, 0], sketch002)
|> yLine(length = 231.81)
|> tangentialArc(radius = 80, angle = -90)
|> xLine(length = 384.93)

View File

@ -28,7 +28,7 @@ segAng(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [5, 10], tag = $seg01)
|> line(end = [-10, 0])

View File

@ -29,7 +29,7 @@ segEnd(tag: TagIdentifier): [number]
```js
w = 15
cube = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [w, 0], tag = $line1)
|> line(end = [0, w], tag = $line2)
|> line(end = [-w, 0], tag = $line3)
@ -39,7 +39,7 @@ cube = startSketchOn(XY)
fn cylinder(radius, tag) {
return startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> circle(radius = radius, center = segEnd(tag))
|> extrude(length = radius)
}

View File

@ -28,7 +28,7 @@ segEndX(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [20, 0], tag = $thing)
|> line(end = [0, 5])
|> line(end = [segEndX(thing), 0])

View File

@ -28,7 +28,7 @@ segEndY(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing)
|> line(end = [-10, 0])

View File

@ -28,7 +28,7 @@ segLen(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(angle = 60, length = 10, tag = $thing)
|> tangentialArc(angle = -120, radius = 5)
|> angledLine(angle = -60, length = segLen(thing))

View File

@ -29,7 +29,7 @@ segStart(tag: TagIdentifier): [number]
```js
w = 15
cube = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [w, 0], tag = $line1)
|> line(end = [0, w], tag = $line2)
|> line(end = [-w, 0], tag = $line3)
@ -39,7 +39,7 @@ cube = startSketchOn(XY)
fn cylinder(radius, tag) {
return startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> circle(radius = radius, center = segStart(tag))
|> extrude(length = radius)
}

View File

@ -28,7 +28,7 @@ segStartX(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [20, 0], tag = $thing)
|> line(end = [0, 5])
|> line(end = [20 - segStartX(thing), 0])

View File

@ -28,7 +28,7 @@ segStartY(tag: TagIdentifier): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [20, 0])
|> line(end = [0, 3], tag = $thing)
|> line(end = [-10, 0])

177
docs/kcl/shell.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Compute the square root of a number.
```js
sqrt(input: number): number
sqrt(num: number): number
```
### Tags
@ -21,7 +21,7 @@ sqrt(input: number): number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `input` | [`number`](/docs/kcl/types/number) | The number to compute the square root of. | Yes |
| `num` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -32,7 +32,7 @@ sqrt(input: number): number
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(angle = 50, length = sqrt(2500))
|> yLine(endAbsolute = 0)
|> close()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -40,7 +40,7 @@ startSketchOn(
```js
exampleSketch = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10])
|> line(end = [-10, 0])
@ -49,7 +49,7 @@ exampleSketch = startSketchOn(XY)
example = extrude(exampleSketch, length = 5)
exampleSketch002 = startSketchOn(example, face = END)
|> startProfile(at = [1, 1])
|> startProfileAt([1, 1], %)
|> line(end = [8, 0])
|> line(end = [0, 8])
|> line(end = [-8, 0])
@ -58,7 +58,7 @@ exampleSketch002 = startSketchOn(example, face = END)
example002 = extrude(exampleSketch002, length = 5)
exampleSketch003 = startSketchOn(example002, face = END)
|> startProfile(at = [2, 2])
|> startProfileAt([2, 2], %)
|> line(end = [6, 0])
|> line(end = [0, 6])
|> line(end = [-6, 0])
@ -74,7 +74,7 @@ example003 = extrude(exampleSketch003, length = 5)
exampleSketch = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10])
|> line(end = [-10, 0])
@ -83,7 +83,7 @@ exampleSketch = startSketchOn(XY)
example = extrude(exampleSketch, length = 5, tagEnd = $end01)
exampleSketch002 = startSketchOn(example, face = end01)
|> startProfile(at = [1, 1])
|> startProfileAt([1, 1], %)
|> line(end = [8, 0])
|> line(end = [0, 8])
|> line(end = [-8, 0])
@ -92,7 +92,7 @@ exampleSketch002 = startSketchOn(example, face = end01)
example002 = extrude(exampleSketch002, length = 5, tagEnd = $end02)
exampleSketch003 = startSketchOn(example002, face = end02)
|> startProfile(at = [2, 2])
|> startProfileAt([2, 2], %)
|> line(end = [6, 0])
|> line(end = [0, 6])
|> line(end = [-6, 0])
@ -105,7 +105,7 @@ example003 = extrude(exampleSketch003, length = 5)
```js
exampleSketch = startSketchOn(XY)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10], tag = $sketchingFace)
|> line(end = [-10, 0])
@ -114,7 +114,7 @@ exampleSketch = startSketchOn(XY)
example = extrude(exampleSketch, length = 10)
exampleSketch002 = startSketchOn(example, face = sketchingFace)
|> startProfile(at = [1, 1])
|> startProfileAt([1, 1], %)
|> line(end = [8, 0])
|> line(end = [0, 8])
|> line(end = [-8, 0])
@ -123,7 +123,7 @@ exampleSketch002 = startSketchOn(example, face = sketchingFace)
example002 = extrude(exampleSketch002, length = 10)
exampleSketch003 = startSketchOn(example002, face = sketchingFace002)
|> startProfile(at = [-8, 12])
|> startProfileAt([-8, 12], %)
|> line(end = [0, 6])
|> line(end = [6, 0])
|> line(end = [0, -6])
@ -136,7 +136,7 @@ example003 = extrude(exampleSketch003, length = 5)
```js
exampleSketch = startSketchOn(XY)
|> startProfile(at = [4, 12])
|> startProfileAt([4, 12], %)
|> line(end = [2, 0])
|> line(end = [0, -6])
|> line(end = [4, -6])
@ -149,7 +149,7 @@ exampleSketch = startSketchOn(XY)
example = revolve(exampleSketch, axis = Y, angle = 180)
exampleSketch002 = startSketchOn(example, face = END)
|> startProfile(at = [4.5, -5])
|> startProfileAt([4.5, -5], %)
|> line(end = [0, 5])
|> line(end = [5, 0])
|> line(end = [0, -5])
@ -165,7 +165,7 @@ example002 = extrude(exampleSketch002, length = 5)
exampleSketch = startSketchOn(XY)
|> startProfile(at = [4, 12])
|> startProfileAt([4, 12], %)
|> line(end = [2, 0])
|> line(end = [0, -6])
|> line(end = [4, -6])
@ -183,7 +183,7 @@ example = revolve(
)
exampleSketch002 = startSketchOn(example, face = end01)
|> startProfile(at = [4.5, -5])
|> startProfileAt([4.5, -5], %)
|> line(end = [0, 5])
|> line(end = [5, 0])
|> line(end = [0, -5])
@ -201,7 +201,7 @@ a1 = startSketchOn({
yAxis = { x = 0, y = 1, z = 0 },
zAxis = { x = 0, y = 0, z = 1 }
})
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [100.0, 0])
|> yLine(length = -100.0)
|> xLine(length = -100.0)

View File

@ -26,7 +26,7 @@ helix(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `revolutions` | `number(_)` | Number of revolutions. | Yes |
| `angleStart` | `number(Angle)` | Start angle. | Yes |
| `angleStart` | `number(Angle)` | Start angle (in degrees). | Yes |
| `ccw` | [`bool`](/docs/kcl/types/bool) | Is the helix rotation counter clockwise? The default is `false`. | No |
| `radius` | `number(Length)` | Radius of the helix. | No |
| `axis` | `Axis3d | Edge` | Axis to use for the helix. | No |
@ -62,7 +62,7 @@ springSketch = startSketchOn(YZ)
```js
// Create a helix around an edge.
helper001 = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = [0, 10], tag = $edge001)
helixPath = helix(

View File

@ -28,10 +28,10 @@ cos(@num: number(Angle)): number(_)
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 30,
length = 3 / cos(30deg),
length = 3 / cos(toRadians(30)),
)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -11,7 +11,7 @@ cartesian (x/y/z grid) coordinates.
```js
polar(
angle: number(rad),
angle: number(Angle),
length: number(Length),
): Point2d
```
@ -21,7 +21,7 @@ polar(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `angle` | `number(rad)` | | Yes |
| `angle` | `number(Angle)` | | Yes |
| `length` | `number(Length)` | | Yes |
### Returns
@ -33,7 +33,7 @@ polar(
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> line(end = polar(angle = 30, length = 5), tag = $thing)
|> line(end = [0, 5])
|> line(end = [segEndX(thing), 0])

View File

@ -28,10 +28,10 @@ sin(@num: number(Angle)): number(_)
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 50,
length = 15 / sin(135deg),
length = 15 / sin(toRadians(135)),
)
|> yLine(endAbsolute = 0)
|> close()

View File

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

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