Compare commits

..

1 Commits

Author SHA1 Message Date
441e18e916 Update generated test output 2025-04-23 19:36:02 -04:00
1583 changed files with 294708 additions and 392829 deletions

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

@ -13,14 +13,10 @@ concurrency:
cancel-in-progress: true
name: cargo test
jobs:
build-test-artifacts:
name: Build test artifacts
runs-on:
- runs-on=${{ github.run_id }}
- runner=8cpu-linux-x64
- extras=s3-cache
cargotest:
name: cargo test
runs-on: ubuntu-latest-8-cores
steps:
- uses: runs-on/action@v1
- uses: actions/create-github-app-token@v1
id: app-token
with:
@ -43,6 +39,7 @@ jobs:
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest
- name: Install just
uses: taiki-e/install-action@just
@ -84,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
@ -120,67 +118,23 @@ jobs:
# Configure nextest when it's run by insta (via just).
NEXTEST_PROFILE: ci
RUST_BACKTRACE: full
- name: Build and archive tests
run: |
cd rust
cargo nextest archive --workspace --features artifact-graph --archive-file nextest-archive.tar.zst
- name: Upload archive to workflow
uses: actions/upload-artifact@v4
with:
name: nextest-archive
path: rust/nextest-archive.tar.zst
run-test-artifacts:
name: cargo test (shard ${{ matrix.partitionIndex}})
runs-on:
- runs-on=${{ github.run_id }}
- runner=32cpu-linux-x64
- extras=s3-cache
needs: build-test-artifacts
strategy:
fail-fast: false
matrix:
partitionIndex: [1, 2, 3, 4, 5, 6]
partitionTotal: [6]
steps:
- uses: runs-on/action@v1
- 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: 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.
- name: Start Vector
run: .github/ci-cd-scripts/start-vector-ubuntu.sh
env:
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
OS_NAME: ${{ env.OS_NAME }}
- uses: taiki-e/install-action@nextest
- name: Download archive
uses: actions/download-artifact@v4
with:
name: nextest-archive
- name: Run tests
RUST_MIN_STACK: 10485760000
- name: cargo test
if: steps.path-changes.outputs.outside-kcl-samples == 'true'
shell: bash
run: |-
cp nextest-archive.tar.zst rust/nextest-archive.tar.zst
ls -lah
cd rust
cargo nextest run\
--retries=2 --no-fail-fast -P ci --archive-file nextest-archive.tar.zst \
--partition count:${{ matrix.partitionIndex}}/${{ matrix.partitionTotal }} \
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
with:
token: ${{secrets.CODECOV_TOKEN}}
fail_ci_if_error: true
flags: rust
verbose: true
files: lcov.info

View File

@ -3,6 +3,7 @@ on:
push:
branches:
- main
- all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
pull_request:
schedule:
- cron: 0 * * * * # hourly
@ -277,42 +278,28 @@ jobs:
timeout-minutes: 60
env:
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') }} (shard ${{ matrix.shardIndex }})
name: playwright:electron:${{ contains(matrix.os, 'ubuntu') && 'ubuntu' || (contains(matrix.os, 'windows') && 'windows' || 'macos') }}:${{ matrix.shardIndex }}:${{ matrix.shardTotal }}
strategy:
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:
- "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]
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
shardIndex: 1
shardTotal: 1
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

@ -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

49
docs/kcl/abs.md Normal file

File diff suppressed because one or more lines are too long

46
docs/kcl/acos.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

File diff suppressed because one or more lines are too long

View File

@ -8,17 +8,17 @@ Draw a line segment relative to the current origin using the polar measure of so
```kcl
```js
angledLine(
sketch: [Sketch](/docs/kcl/types/Sketch),
angle: [number](/docs/kcl/types/number),
length?: [number](/docs/kcl/types/number),
lengthX?: [number](/docs/kcl/types/number),
lengthY?: [number](/docs/kcl/types/number),
endAbsoluteX?: [number](/docs/kcl/types/number),
endAbsoluteY?: [number](/docs/kcl/types/number),
tag?: [TagDeclarator](/docs/kcl/types#tag-declaration),
): [Sketch](/docs/kcl/types/Sketch)
sketch: Sketch,
angle: number,
length?: number,
lengthX?: number,
lengthY?: number,
endAbsoluteX?: number,
endAbsoluteY?: number,
tag?: TagDeclarator,
): Sketch
```
@ -33,7 +33,7 @@ angledLine(
| `lengthY` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` 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`, `endAbsoluteX`, `endAbsoluteY` 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`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -42,9 +42,9 @@ angledLine(
### Examples
```kcl
```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

@ -8,14 +8,14 @@ Draw an angled line from the current origin, constructing a line segment such th
```kcl
```js
angledLineThatIntersects(
sketch: [Sketch](/docs/kcl/types/Sketch),
angle: [number](/docs/kcl/types/number),
intersectTag: [TagIdentifier](/docs/kcl/types#tag-identifier),
offset?: [number](/docs/kcl/types/number),
tag?: [TagDeclarator](/docs/kcl/types#tag-declaration),
): [Sketch](/docs/kcl/types/Sketch)
sketch: Sketch,
angle: number,
intersectTag: TagIdentifier,
offset?: number,
tag?: TagDeclarator,
): Sketch
```
@ -27,7 +27,7 @@ angledLineThatIntersects(
| `angle` | [`number`](/docs/kcl/types/number) | Which angle should the line be drawn at? | Yes |
| `intersectTag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the line to intersect with | Yes |
| `offset` | [`number`](/docs/kcl/types/number) | The offset from the intersecting line. Defaults to 0. | No |
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -36,9 +36,9 @@ angledLineThatIntersects(
### Examples
```kcl
```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/asin.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -8,15 +8,15 @@ Check a value meets some expected conditions at runtime. Program terminates with
```kcl
```js
assert(
actual: [number](/docs/kcl/types/number),
isGreaterThan?: [number](/docs/kcl/types/number),
isLessThan?: [number](/docs/kcl/types/number),
isGreaterThanOrEqual?: [number](/docs/kcl/types/number),
isLessThanOrEqual?: [number](/docs/kcl/types/number),
isEqualTo?: [number](/docs/kcl/types/number),
tolerance?: [number](/docs/kcl/types/number),
actual: number,
isGreaterThan?: number,
isLessThan?: number,
isGreaterThanOrEqual?: number,
isLessThanOrEqual?: number,
isEqualTo?: number,
tolerance?: number,
error?: String,
): ()
```
@ -42,7 +42,7 @@ assert(
### Examples
```kcl
```js
n = 10
assert(n, isEqualTo = 10)
assert(

45
docs/kcl/assertEqual.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

File diff suppressed because one or more lines are too long

View File

@ -8,9 +8,9 @@ Asserts that a value is the boolean value true.
```kcl
```js
assertIs(
actual: [bool](/docs/kcl/types/bool),
actual: bool,
error?: String,
): ()
```
@ -30,7 +30,7 @@ assertIs(
### Examples
```kcl
```js
kclIsFun = true
assertIs(kclIsFun)
```

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/atan.md Normal file

File diff suppressed because one or more lines are too long

49
docs/kcl/atan2.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -8,14 +8,14 @@ Draw a smooth, continuous, curved line segment from the current origin to the de
```kcl
```js
bezierCurve(
sketch: [Sketch](/docs/kcl/types/Sketch),
control1: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
control2: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
end: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
tag?: [TagDeclarator](/docs/kcl/types#tag-declaration),
): [Sketch](/docs/kcl/types/Sketch)
sketch: Sketch,
control1: [number],
control2: [number],
end: [number],
tag?: TagDeclarator,
): Sketch
```
@ -27,7 +27,7 @@ bezierCurve(
| `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` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -36,9 +36,9 @@ bezierCurve(
### Examples
```kcl
```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])
|> line(endAbsolute = [10, 0])

46
docs/kcl/ceil.md Normal file

File diff suppressed because one or more lines are too long

95
docs/kcl/chamfer.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -8,14 +8,14 @@ Construct a circle derived from 3 points.
```kcl
```js
circleThreePoint(
sketchSurfaceOrGroup: [[Sketch](/docs/kcl/types/Sketch)OrSurface](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch)OrSurface),
p1: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
p2: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
p3: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
tag?: [TagDeclarator](/docs/kcl/types#tag-declaration),
): [Sketch](/docs/kcl/types/Sketch)
sketchSurfaceOrGroup: SketchOrSurface,
p1: [number],
p2: [number],
p3: [number],
tag?: TagDeclarator,
): Sketch
```
@ -27,7 +27,7 @@ circleThreePoint(
| `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 |
| `p3` | [`[number]`](/docs/kcl/types/number) | 3rd point to derive the circle. | Yes |
| `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
@ -36,7 +36,7 @@ circleThreePoint(
### Examples
```kcl
```js
exampleSketch = startSketchOn(XY)
|> circleThreePoint(p1 = [10, 10], p2 = [20, 8], p3 = [15, 5])
|> extrude(length = 5)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ Identifies the ending face of an extrusion. I.e., the new face created by an ext
```kcl
```js
std::END: string = 'end'
```

View File

@ -8,7 +8,7 @@ Identifies the starting face of an extrusion. I.e., the face which is extruded.
```kcl
```js
std::START: string = 'start'
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::X
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::XY
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::XZ
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::Y
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::YZ
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::Z
```

View File

@ -8,15 +8,15 @@ The value of Eulers number `e`.
```kcl
```js
std::math::E: number = 2.71828182845904523536028747135266250_
```
### Examples
```kcl
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 30,
length = 2 * E ^ 2,

View File

@ -8,17 +8,17 @@ The value of `pi`, Archimedes constant (π).
```kcl
std::math::PI: number(_?) = 3.14159265358979323846264338327950288_?
```js
std::math::PI: number = 3.14159265358979323846264338327950288_
```
### Examples
```kcl
```js
circumference = 70
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = (circumference / (2 * PI)): number(mm))
|> circle(center = [0, 0], radius = circumference / (2 * PI))
example = extrude(exampleSketch, length = 5)
```

View File

@ -8,15 +8,15 @@ The value of `tau`, the full circle constant (τ). Equal to 2π.
```kcl
```js
std::math::TAU: number = 6.28318530717958647692528676655900577_
```
### Examples
```kcl
```js
exampleSketch = startSketchOn(XZ)
|> startProfile(at = [0, 0])
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 50,
length = 10 * TAU,

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::turns::HALF_TURN: number(deg) = 180deg
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::turns::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::turns::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -8,7 +8,7 @@ layout: manual
```kcl
```js
std::turns::ZERO: number = 0
```

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()

File diff suppressed because one or more lines are too long

94
docs/kcl/fillet.md Normal file

File diff suppressed because one or more lines are too long

46
docs/kcl/floor.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -8,8 +8,8 @@ Get the shared edge between two faces.
```kcl
getCommon[Edge](/docs/kcl/types/Edge)(faces: [[TagIdentifier](/docs/kcl/types#tag-identifier)]): Uuid
```js
getCommonEdge(faces: [TagIdentifier]): Uuid
```
@ -26,13 +26,13 @@ getCommon[Edge](/docs/kcl/types/Edge)(faces: [[TagIdentifier](/docs/kcl/types#ta
### Examples
```kcl
```js
// Get an edge shared between two faces, created after a chamfer.
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

@ -8,8 +8,8 @@ Get the next adjacent edge to the edge given.
```kcl
getNextAdjacent[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/types#tag-identifier)): Uuid
```js
getNextAdjacentEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getNextAdjacent[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/type
| 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
@ -26,9 +26,9 @@ getNextAdjacent[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/type
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Get the opposite edge to the edge given.
```kcl
getOpposite[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/types#tag-identifier)): Uuid
```js
getOppositeEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getOpposite[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/types#ta
| 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
@ -26,9 +26,9 @@ getOpposite[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/types#ta
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Get the previous adjacent edge to the edge given.
```kcl
getPreviousAdjacent[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/types#tag-identifier)): Uuid
```js
getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getPreviousAdjacent[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/
| 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
@ -26,9 +26,9 @@ getPreviousAdjacent[Edge](/docs/kcl/types/Edge)(edge: [TagIdentifier](/docs/kcl/
### Examples
```kcl
```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

@ -30,22 +30,34 @@ layout: manual
* [`Y`](kcl/consts/std-Y)
* [`YZ`](kcl/consts/std-YZ)
* [`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)
* [`asin`](kcl/asin)
* [`assert`](kcl/assert)
* [`assertIs`](kcl/assertIs)
* [`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)
* [`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)
@ -54,9 +66,15 @@ layout: manual
* [`legAngY`](kcl/legAngY)
* [`legLen`](kcl/legLen)
* [`line`](kcl/line)
* [`ln`](kcl/ln)
* [`loft`](kcl/loft)
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`map`](kcl/map)
* [`offsetPlane`](kcl/std-offsetPlane)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d)
@ -65,13 +83,16 @@ layout: manual
* [`patternTransform2d`](kcl/patternTransform2d)
* [`polygon`](kcl/polygon)
* [`pop`](kcl/pop)
* [`pow`](kcl/pow)
* [`profileStart`](kcl/profileStart)
* [`profileStartX`](kcl/profileStartX)
* [`profileStartY`](kcl/profileStartY)
* [`push`](kcl/push)
* [`reduce`](kcl/reduce)
* [`rem`](kcl/rem)
* [`revolve`](kcl/std-revolve)
* [`rotate`](kcl/rotate)
* [`round`](kcl/round)
* [`scale`](kcl/scale)
* [`segAng`](kcl/segAng)
* [`segEnd`](kcl/segEnd)
@ -81,13 +102,22 @@ layout: manual
* [`segStart`](kcl/segStart)
* [`segStartX`](kcl/segStartX)
* [`segStartY`](kcl/segStartY)
* [`startProfile`](kcl/startProfile)
* [`shell`](kcl/shell)
* [`sqrt`](kcl/sqrt)
* [`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)
* [`translate`](kcl/translate)
* [`union`](kcl/union)
* [`xLine`](kcl/xLine)
@ -96,35 +126,13 @@ layout: manual
* [`E`](kcl/consts/std-math-E)
* [`PI`](kcl/consts/std-math-PI)
* [`TAU`](kcl/consts/std-math-TAU)
* [`abs`](kcl/std-math-abs)
* [`acos`](kcl/std-math-acos)
* [`asin`](kcl/std-math-asin)
* [`atan`](kcl/std-math-atan)
* [`atan2`](kcl/std-math-atan2)
* [`ceil`](kcl/std-math-ceil)
* [`cos`](kcl/std-math-cos)
* [`floor`](kcl/std-math-floor)
* [`ln`](kcl/std-math-ln)
* [`log`](kcl/std-math-log)
* [`log10`](kcl/std-math-log10)
* [`log2`](kcl/std-math-log2)
* [`max`](kcl/std-math-max)
* [`min`](kcl/std-math-min)
* [`polar`](kcl/std-math-polar)
* [`pow`](kcl/std-math-pow)
* [`rem`](kcl/std-math-rem)
* [`round`](kcl/std-math-round)
* [`sin`](kcl/std-math-sin)
* [`sqrt`](kcl/std-math-sqrt)
* [`tan`](kcl/std-math-tan)
* **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)
@ -141,12 +149,3 @@ layout: manual
* [`Point3d`](kcl/types/Point3d)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* **std::units**
* [`units::toCentimeters`](kcl/std-units-toCentimeters)
* [`units::toDegrees`](kcl/std-units-toDegrees)
* [`units::toFeet`](kcl/std-units-toFeet)
* [`units::toInches`](kcl/std-units-toInches)
* [`units::toMeters`](kcl/std-units-toMeters)
* [`units::toMillimeters`](kcl/std-units-toMillimeters)
* [`units::toRadians`](kcl/std-units-toRadians)
* [`units::toYards`](kcl/std-units-toYards)

File diff suppressed because one or more lines are too long

View File

@ -8,15 +8,15 @@ Extend the current sketch with a new involute circular curve.
```kcl
```js
involuteCircular(
sketch: [Sketch](/docs/kcl/types/Sketch),
startRadius: [number](/docs/kcl/types/number),
endRadius: [number](/docs/kcl/types/number),
angle: [number](/docs/kcl/types/number),
reverse?: [bool](/docs/kcl/types/bool),
tag?: [TagDeclarator](/docs/kcl/types#tag-declaration),
): [Sketch](/docs/kcl/types/Sketch)
sketch: Sketch,
startRadius: number,
endRadius: number,
angle: number,
reverse?: bool,
tag?: TagDeclarator,
): Sketch
```
@ -29,7 +29,7 @@ involuteCircular(
| `endRadius` | [`number`](/docs/kcl/types/number) | The involute is described between two circles, end_radius is the radius of the outer circle. | Yes |
| `angle` | [`number`](/docs/kcl/types/number) | The angle to rotate the involute by. A value of zero will produce a curve with a tangent along the x-axis at the start point of the curve. | Yes |
| `reverse` | [`bool`](/docs/kcl/types/bool) | If reverse is true, the segment will start from the end of the involute, otherwise it will start from that start. Defaults to false. | No |
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -38,11 +38,11 @@ involuteCircular(
### Examples
```kcl
```js
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

@ -22,5 +22,6 @@ once fixed in engine will just start working here with no language changes.
chamfer cases work currently.
- **Appearance**: Changing the appearance on a loft does not work.
Changing the appearance on an imported model does not work.
- **CSG Booleans**: Coplanar (bodies that share a plane) unions, subtractions, and intersections are not currently supported.

View File

@ -8,8 +8,8 @@ Extract the 'x' axis value of the last line segment in the provided 2-d sketch.
```kcl
lastSegX(sketch: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/types/number)
```js
lastSegX(sketch: Sketch): number
```
@ -26,9 +26,9 @@ lastSegX(sketch: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/types/num
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Extract the 'y' axis value of the last line segment in the provided 2-d sketch.
```kcl
lastSegY(sketch: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/types/number)
```js
lastSegY(sketch: Sketch): number
```
@ -26,9 +26,9 @@ lastSegY(sketch: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/types/num
### Examples
```kcl
```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

@ -8,11 +8,11 @@ Compute the angle of the given leg for x.
```kcl
```js
legAngX(
hypotenuse: [number](/docs/kcl/types/number),
leg: [number](/docs/kcl/types/number),
): [number](/docs/kcl/types/number)
hypotenuse: number,
leg: number,
): number
```
### Tags
@ -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
@ -34,8 +34,8 @@ legAngX(
### Examples
```kcl
legAngX(hypotenuse = 5, leg = 3)
```js
legAngX(5, 3)
```

View File

@ -8,11 +8,11 @@ Compute the angle of the given leg for y.
```kcl
```js
legAngY(
hypotenuse: [number](/docs/kcl/types/number),
leg: [number](/docs/kcl/types/number),
): [number](/docs/kcl/types/number)
hypotenuse: number,
leg: number,
): number
```
### Tags
@ -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
@ -34,8 +34,8 @@ legAngY(
### Examples
```kcl
legAngY(hypotenuse = 5, leg = 3)
```js
legAngY(5, 3)
```

View File

@ -8,11 +8,11 @@ Compute the length of the given leg.
```kcl
```js
legLen(
hypotenuse: [number](/docs/kcl/types/number),
leg: [number](/docs/kcl/types/number),
): [number](/docs/kcl/types/number)
hypotenuse: number,
leg: number,
): number
```
### Tags
@ -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
@ -34,8 +34,8 @@ legLen(
### Examples
```kcl
legLen(hypotenuse = 5, leg = 3)
```js
legLen(5, 3)
```

View File

@ -8,13 +8,13 @@ Extend the current sketch with a new straight line.
```kcl
```js
line(
sketch: [Sketch](/docs/kcl/types/Sketch),
endAbsolute?: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
end?: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
tag?: [TagDeclarator](/docs/kcl/types#tag-declaration),
): [Sketch](/docs/kcl/types/Sketch)
sketch: Sketch,
endAbsolute?: [number],
end?: [number],
tag?: TagDeclarator,
): Sketch
```
@ -25,7 +25,7 @@ line(
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `endAbsolute` | [`[number]`](/docs/kcl/types/number) | Which absolute point should this line go to? Incompatible with `end`. | No |
| `end` | [`[number]`](/docs/kcl/types/number) | How far away (along the X and Y axes) should this line go? Incompatible with `endAbsolute`. | No |
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -34,9 +34,9 @@ line(
### Examples
```kcl
```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])

46
docs/kcl/ln.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

50
docs/kcl/log.md Normal file

File diff suppressed because one or more lines are too long

46
docs/kcl/log10.md Normal file

File diff suppressed because one or more lines are too long

46
docs/kcl/log2.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

45
docs/kcl/max.md Normal file

File diff suppressed because one or more lines are too long

45
docs/kcl/min.md Normal file

File diff suppressed because one or more lines are too long

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.

121
docs/kcl/offsetPlane.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -8,15 +8,15 @@ Repeat a 2-dimensional sketch some number of times along a partial or complete c
```kcl
```js
patternCircular2d(
sketchSet: [[[Sketch](/docs/kcl/types/Sketch)]](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch)),
sketchSet: [Sketch],
instances: integer,
center: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
arcDegrees: [number](/docs/kcl/types/number),
rotateDuplicates: [bool](/docs/kcl/types/bool),
useOriginal?: [bool](/docs/kcl/types/bool),
): [[[Sketch](/docs/kcl/types/Sketch)]](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch))
center: [number],
arcDegrees: number,
rotateDuplicates: bool,
useOriginal?: bool,
): [Sketch]
```
@ -38,9 +38,9 @@ patternCircular2d(
### Examples
```kcl
```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

@ -8,16 +8,16 @@ Repeat a 3-dimensional solid some number of times along a partial or complete ci
```kcl
```js
patternCircular3d(
solids: [[[Solid](/docs/kcl/types/Solid)]](/docs/kcl/types/[Solid](/docs/kcl/types/Solid)),
solids: [Solid],
instances: integer,
axis: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
center: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
arcDegrees: [number](/docs/kcl/types/number),
rotateDuplicates: [bool](/docs/kcl/types/bool),
useOriginal?: [bool](/docs/kcl/types/bool),
): [[[Solid](/docs/kcl/types/Solid)]](/docs/kcl/types/[Solid](/docs/kcl/types/Solid))
axis: [number],
center: [number],
arcDegrees: number,
rotateDuplicates: bool,
useOriginal?: bool,
): [Solid]
```
@ -40,7 +40,7 @@ patternCircular3d(
### Examples
```kcl
```js
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 1)

View File

@ -8,14 +8,14 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount of dis
```kcl
```js
patternLinear2d(
sketches: [[[Sketch](/docs/kcl/types/Sketch)]](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch)),
sketches: [Sketch],
instances: integer,
distance: [number](/docs/kcl/types/number),
axis: [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number)),
useOriginal?: [bool](/docs/kcl/types/bool),
): [[[Sketch](/docs/kcl/types/Sketch)]](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch))
distance: number,
axis: [number],
useOriginal?: bool,
): [Sketch]
```
@ -36,7 +36,7 @@ patternLinear2d(
### Examples
```kcl
```js
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 1)
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,13 +8,13 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
```kcl
```js
patternTransform2d(
sketches: [[[Sketch](/docs/kcl/types/Sketch)]](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch)),
sketches: [Sketch],
instances: integer,
transform: FunctionSource,
useOriginal?: [bool](/docs/kcl/types/bool),
): [[[Sketch](/docs/kcl/types/Sketch)]](/docs/kcl/types/[Sketch](/docs/kcl/types/Sketch))
useOriginal?: bool,
): [Sketch]
```
@ -34,7 +34,7 @@ patternTransform2d(
### Examples
```kcl
```js
// Each instance will be shifted along the X axis.
fn transform(id) {
return { translate = [4 * id, 0] }

File diff suppressed because one or more lines are too long

View File

@ -8,8 +8,8 @@ Remove the last element from an array.
Returns a new array with the last element removed.
```kcl
pop(array: [[[KclValue](/docs/kcl/types/KclValue)]](/docs/kcl/types/[KclValue](/docs/kcl/types/KclValue))): [KclValue](/docs/kcl/types/KclValue)
```js
pop(array: [KclValue]): KclValue
```
@ -17,7 +17,7 @@ pop(array: [[[KclValue](/docs/kcl/types/KclValue)]](/docs/kcl/types/[KclValue](/
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `array` | [`[KclValue]`](/docs/kcl/types/KclValue) | The array to pop from. Must not be empty. | Yes |
| `array` | [`[KclValue]`](/docs/kcl/types/KclValue) | The array to pop from. Must not be empty. | Yes |
### Returns
@ -26,7 +26,7 @@ pop(array: [[[KclValue](/docs/kcl/types/KclValue)]](/docs/kcl/types/[KclValue](/
### Examples
```kcl
```js
arr = [1, 2, 3, 4]
new_arr = pop(arr)
assert(

49
docs/kcl/pow.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -8,8 +8,8 @@ Extract the provided 2-dimensional sketch's profile's origin value.
```kcl
profileStart(profile: [Sketch](/docs/kcl/types/Sketch)): [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number))
```js
profileStart(profile: Sketch): [number]
```
@ -26,9 +26,9 @@ profileStart(profile: [Sketch](/docs/kcl/types/Sketch)): [[[number](/docs/kcl/ty
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Extract the provided 2-dimensional sketch's profile's origin's 'x' value.
```kcl
profileStartX(profile: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/types/number)
```js
profileStartX(profile: Sketch): number
```
@ -26,9 +26,9 @@ profileStartX(profile: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/typ
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Extract the provided 2-dimensional sketch's profile's origin's 'y' value.
```kcl
profileStartY(profile: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/types/number)
```js
profileStartY(profile: Sketch): number
```
@ -26,9 +26,9 @@ profileStartY(profile: [Sketch](/docs/kcl/types/Sketch)): [number](/docs/kcl/typ
### Examples
```kcl
```js
sketch001 = startSketchOn(XY)
|> startProfile(at = [5, 2])
|> startProfileAt([5, 2], %)
|> angledLine(angle = -60, length = 14)
|> angledLine(angle = 30, endAbsoluteY = profileStartY(%))
```

View File

@ -8,11 +8,11 @@ Append an element to the end of an array.
Returns a new array with the element appended.
```kcl
```js
push(
array: [[[KclValue](/docs/kcl/types/KclValue)]](/docs/kcl/types/[KclValue](/docs/kcl/types/KclValue)),
item: [KclValue](/docs/kcl/types/KclValue),
): [KclValue](/docs/kcl/types/KclValue)
array: [KclValue],
elem: KclValue,
): KclValue
```
@ -20,8 +20,8 @@ push(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `array` | [`[KclValue]`](/docs/kcl/types/KclValue) | The array which you're adding a new item to. | Yes |
| `item` | [`KclValue`](/docs/kcl/types/KclValue) | The new item to add to the array | Yes |
| `array` | [`[KclValue]`](/docs/kcl/types/KclValue) | | Yes |
| `elem` | [`KclValue`](/docs/kcl/types/KclValue) | Any KCL value. | Yes |
### Returns
@ -30,9 +30,9 @@ push(
### Examples
```kcl
```js
arr = [1, 2, 3]
new_arr = push(arr, item = 4)
new_arr = push(arr, 4)
assert(
new_arr[3],
isEqualTo = 4,

File diff suppressed because one or more lines are too long

48
docs/kcl/rem.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

46
docs/kcl/round.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

@ -8,8 +8,8 @@ Compute the angle (in degrees) of the provided line segment.
```kcl
segAng(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl/types/number)
```js
segAng(tag: TagIdentifier): number
```
@ -17,7 +17,7 @@ segAng(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,9 +26,9 @@ segAng(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Compute the ending point of the provided line segment.
```kcl
segEnd(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number))
```js
segEnd(tag: TagIdentifier): [number]
```
@ -17,7 +17,7 @@ segEnd(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [[[number](/docs/k
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,10 +26,10 @@ segEnd(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [[[number](/docs/k
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Compute the ending point of the provided line segment along the 'x' axis.
```kcl
segEndX(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl/types/number)
```js
segEndX(tag: TagIdentifier): number
```
@ -17,7 +17,7 @@ segEndX(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kc
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,9 +26,9 @@ segEndX(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kc
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Compute the ending point of the provided line segment along the 'y' axis.
```kcl
segEndY(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl/types/number)
```js
segEndY(tag: TagIdentifier): number
```
@ -17,7 +17,7 @@ segEndY(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kc
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,9 +26,9 @@ segEndY(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kc
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Compute the length of the provided line segment.
```kcl
segLen(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl/types/number)
```js
segLen(tag: TagIdentifier): number
```
@ -17,7 +17,7 @@ segLen(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,9 +26,9 @@ segLen(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Compute the starting point of the provided line segment.
```kcl
segStart(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [[[number](/docs/kcl/types/number)]](/docs/kcl/types/[number](/docs/kcl/types/number))
```js
segStart(tag: TagIdentifier): [number]
```
@ -17,7 +17,7 @@ segStart(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [[[number](/docs
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,10 +26,10 @@ segStart(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [[[number](/docs
### Examples
```kcl
```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

@ -8,8 +8,8 @@ Compute the starting point of the provided line segment along the 'x' axis.
```kcl
segStartX(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/kcl/types/number)
```js
segStartX(tag: TagIdentifier): number
```
@ -17,7 +17,7 @@ segStartX(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns
@ -26,9 +26,9 @@ segStartX(tag: [TagIdentifier](/docs/kcl/types#tag-identifier)): [number](/docs/
### Examples
```kcl
```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])

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