Compare commits

...

13 Commits

Author SHA1 Message Date
ccb3edb0ec Update rust/kcl-lib/src/execution/memory.rs
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-03-28 21:01:24 -07:00
252050468d ascii art diagram
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-28 14:30:45 -07:00
358b34de4c Fix translate scale & better docs (#6053)
* change translate & scale to be better & docs

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

* autocomplete

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

* gen std

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

* kcl-samples

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

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-28 21:14:29 +00:00
9973e5fde3 Fix to preserve comments when changing file units (#6052) 2025-03-28 21:07:53 +00:00
36875e05fd Fix .length on undefined WASM error (#6048) 2025-03-28 14:48:47 -04:00
42123383bb Add path argument error to console error whitelist (#6046)
* Add path argument error to console error whitelist

* Lint
2025-03-28 13:50:54 -04:00
ef4c606ed1 Update sweep-related icons to be less detailed, show result (#6047)
* WIP trying out various icons

* Update to use outcome bodies for icons
2025-03-28 16:42:31 +00:00
1ebb73b935 Fix 'originalCode' undefined in a test (#6027) 2025-03-28 12:36:54 -04:00
b57d31c0e7 Fix build:wasm:dev for --dev builds (#6038)
This is useful since it preserves Rust backtraces in WASM.
2025-03-28 08:40:21 -04:00
678ebbc310 Make Helix available in numbered releases (#6024)
* Helix release outside of dev and nightly

* Make length non required on edge mode so we get the edge length by default
2025-03-28 11:25:32 +00:00
cc2efd316c Add more TS lints and fix types (#6037)
* Add as const lint

* Add lint for no implied eval

* Fix incorrect type and add lints

* Add more type lints

* Remove redundant type assertions and add lint

* Fix to turn off incorrect base rules

* Fix yarn lint workflow to wait for build:wasm

* Change so that we don't build:wasm more than once in the workflow
2025-03-28 04:24:24 +00:00
d1f811f91d Boolean create UI (#5906)
* first steps, add to cmd bar etc

* cmdbar working well enough

* mvp

* lint

* fix after rebase

* intersect and union mvps

* add test

* some clean up

* further fix up

* Update src/lang/modifyAst/boolean.ts

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* Update src/lang/modifyAst/boolean.ts

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>

* pierre's comments

* tsc

* add comment

---------

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-03-28 03:56:48 +00:00
7ca3afff9f Add CSG operations to the Feature Tree (#6028)
* Add operation tracking for CSG boolean functions

* Add CSG operations to the Feature Tree

* Add just command

* Add union sim test

* Update output with new sim test

* Add CSG subtract test

* Update output from subtract test

* Add intersect sim test

* Update output for intersect test
2025-03-28 09:48:55 +11:00
94 changed files with 17805 additions and 2786 deletions

View File

@ -20,9 +20,20 @@
"plugin:react-hooks/recommended"
],
"rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-array-delete": "error",
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-duplicate-type-constituents": "error",
"@typescript-eslint/no-empty-object-type": "error",
"@typescript-eslint/no-floating-promises": "error",
"no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-implied-eval": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unnecessary-type-constraint": "error",
"no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-unused-vars": ["error", {
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
@ -30,6 +41,7 @@
"vars": "all",
"args": "none"
}],
"@typescript-eslint/prefer-as-const": "warn",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",

View File

@ -28,43 +28,57 @@ jobs:
- run: yarn fmt-check
yarn-build-wasm:
runs-on: ubuntu-22.04
# Build the wasm blob once on the fastest runner.
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Install dependencies
run: yarn install
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
yarn-tsc:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install
- uses: Swatinem/rust-cache@v2
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: './rust'
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
- run: yarn tsc
- name: Build Wasm
shell: bash
run: yarn build:wasm
yarn-lint:
runs-on: ubuntu-22.04
- uses: actions/upload-artifact@v4
with:
name: prepared-wasm
path: |
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
- uses: actions/upload-artifact@v4
with:
name: prepared-ts-rs-bindings
path: |
rust/kcl-lib/bindings/*
yarn-tsc:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
@ -73,7 +87,53 @@ jobs:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn tsc
yarn-lint:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn lint
python-codespell:
@ -91,6 +151,7 @@ jobs:
yarn-unit-test-kcl-samples:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
@ -103,7 +164,22 @@ jobs:
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
@ -120,6 +196,7 @@ jobs:
yarn-unit-test:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
@ -132,7 +209,22 @@ jobs:
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}

View File

@ -37,7 +37,7 @@ build-web: public/kcl_wasm_lib_bg.wasm build/index.html
build-desktop: public/kcl_wasm_lib_bg.wasm .vite/build/main.js
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES)$(RUST_SOURCES)
yarn build:wasm
yarn build:wasm:dev
build/index.html: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
yarn build:local
@ -99,7 +99,7 @@ test-e2e-web: install build-web ## Run the web e2e tests
.PHONY: test-e2e-desktop
test-e2e-desktop: install build-desktop ## Run the desktop e2e tests
yarn test:playwright:electron --workers=$(E2E_WORKERS) --max-failures=$(E2E_FAILURES) --grep=$(E2E_GREP)
yarn test:playwright:electron --workers=$(E2E_WORKERS) --max-failures=$(E2E_FAILURES) --grep="$(E2E_GREP)"
###############################################################################
# CLEAN

View File

@ -6,6 +6,10 @@ layout: manual
Rotate a solid or a sketch.
This is really useful for assembling parts together. You can create a part and then rotate it to the correct orientation.
For sketches, you can use this to rotate a sketch and then loft it with another sketch.
### Using Roll, Pitch, and Yaw
When rotating a part in 3D space, "roll," "pitch," and "yaw" refer to the three rotational axes used to describe its orientation: roll is rotation around the longitudinal axis (front-to-back), pitch is rotation around the lateral axis (wing-to-wing), and yaw is rotation around the vertical axis (up-down); essentially, it's like tilting the part on its side (roll), tipping the nose up or down (pitch), and turning it left or right (yaw).
@ -166,7 +170,7 @@ fn square() {
profile001 = square()
profile002 = square()
|> translate(translate = [0, 0, 20])
|> translate(x = 0, y = 0, z = 20)
|> rotate(axis = [0, 0, 1.0], angle = 45)
loft([profile001, profile002])

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,117 @@
import { test, expect } from './zoo-test'
import fs from 'node:fs/promises'
import path from 'node:path'
test.describe('Point and click for boolean workflows', () => {
// Boolean operations to test
const booleanOperations = [
{
name: 'union',
code: 'union([extrude001, extrude006])',
},
{
name: 'subtract',
code: 'subtract([extrude001], tools = [extrude006])',
},
{
name: 'intersect',
code: 'intersect([extrude001, extrude006])',
},
] as const
for (let i = 0; i < booleanOperations.length; i++) {
const operation = booleanOperations[i]
const operationName = operation.name
const commandName = `Boolean ${
operationName.charAt(0).toUpperCase() + operationName.slice(1)
}`
test(`Create boolean operation -- ${operationName}`, async ({
context,
homePage,
cmdBar,
editor,
toolbar,
scene,
page,
}) => {
const file = await fs.readFile(
path.resolve(
__dirname,
'../../',
'./rust/kcl-lib/e2e/executor/inputs/boolean-setup-with'
),
'utf-8'
)
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
await scene.settled(cmdBar)
// Test coordinates for selection - these might need adjustment based on actual scene layout
const cylinderPoint = { x: 592, y: 174 }
const secondObjectPoint = { x: 683, y: 273 }
// Create mouse helpers for selecting objects
const [clickFirstObject] = scene.makeMouseHelpers(
cylinderPoint.x,
cylinderPoint.y,
{ steps: 10 }
)
const [clickSecondObject] = scene.makeMouseHelpers(
secondObjectPoint.x,
secondObjectPoint.y,
{ steps: 10 }
)
await test.step(`Test ${operationName} operation`, async () => {
// Click the boolean operation button in the toolbar
await toolbar.selectBoolean(operationName)
// Verify command bar is showing the right command
await expect(cmdBar.page.getByTestId('command-name')).toContainText(
commandName
)
// Select first object in the scene, expect there to be a pixel diff from the selection color change
await clickFirstObject({ pixelDiff: 50 })
// For subtract, we need to proceed to the next step before selecting the second object
if (operationName !== 'subtract') {
// should down shift key to select multiple objects
await page.keyboard.down('Shift')
}
// Select second object
await clickSecondObject({ pixelDiff: 50 })
// Confirm the operation in the command bar
await cmdBar.progressCmdBar()
if (operationName === 'union' || operationName === 'intersect') {
await cmdBar.expectState({
stage: 'review',
headerArguments: {
Solids: '2 paths',
},
commandName,
})
} else if (operationName === 'subtract') {
await cmdBar.expectState({
stage: 'review',
headerArguments: {
Tool: '1 path',
Target: '1 path',
},
commandName,
})
}
await cmdBar.submit()
await editor.expectEditor.toContain(operation.code)
})
})
}
})

View File

@ -181,6 +181,14 @@ export class ToolbarFixture {
).toBeVisible()
await this.page.getByTestId('dropdown-center-rectangle').click()
}
selectBoolean = async (operation: 'union' | 'subtract' | 'intersect') => {
await this.page
.getByRole('button', { name: 'caret down Union: open menu' })
.click()
const operationTestId = `dropdown-boolean-${operation}`
await expect(this.page.getByTestId(operationTestId)).toBeVisible()
await this.page.getByTestId(operationTestId).click()
}
selectCircleThreePoint = async () => {
await this.page

View File

@ -258,14 +258,6 @@ export const isErrorWhitelisted = (exception: Error) => {
foundInSpec: 'e2e/playwright/testing-settings.spec.ts',
},
// TODO: fix this error in the code
{
name: 'TypeError',
message: "Cannot read properties of undefined (reading 'length')",
stack: '',
project: 'Google Chrome',
foundInSpec: '', // many tests are impacted by this error
},
// TODO: fix this error in the code
{
name: 'ReferenceError',
message: '_testUtils is not defined',
@ -273,7 +265,6 @@ export const isErrorWhitelisted = (exception: Error) => {
project: 'Google Chrome',
foundInSpec: 'e2e/playwright/snapshot-tests.spec.ts',
},
// TODO: fix this error in the code
{
name: 'TypeError',
message: 'Failed to fetch',
@ -282,14 +273,6 @@ export const isErrorWhitelisted = (exception: Error) => {
foundInSpec: 'e2e/playwright/snapshot-tests.spec.ts',
},
// TODO: fix this error in the code
{
name: 'ReferenceError',
message: 'originalCode is not defined',
stack: '',
project: 'Google Chrome',
foundInSpec: 'e2e/playwright/onboarding-tests.spec.ts',
},
// TODO: fix this error in the code
{
name: 'ReferenceError',
message: 'createNewVariableCheckbox is not defined',
@ -297,6 +280,14 @@ export const isErrorWhitelisted = (exception: Error) => {
project: 'Google Chrome',
foundInSpec: 'e2e/playwright/testing-constraints.spec.ts',
},
{
name: 'Error',
message: 'The "path" argument must be of type string. Received undefined',
stack:
'Error: The "path" argument must be of type string. Received undefined',
project: 'Google Chrome',
foundInSpec: '', // many tests are impacted by this error
},
]
const cleanString = (str: string) => str.replace(/[`"]/g, '')

View File

@ -230,9 +230,9 @@ test.describe('Onboarding tests', () => {
// Override beforeEach test setup
await context.addInitScript(
async ({ settingsKey, settings }) => {
async ({ settingsKey, settings, code }) => {
// Give some initial code, so we can test that it's cleared
localStorage.setItem('persistCode', originalCode)
localStorage.setItem('persistCode', code)
localStorage.setItem(settingsKey, settings)
},
{
@ -240,6 +240,7 @@ test.describe('Onboarding tests', () => {
settings: settingsToToml({
settings: TEST_SETTINGS_ONBOARDING_EXPORT,
}),
code: originalCode,
}
)

View File

@ -1097,7 +1097,6 @@ openSketch = startSketchOn(XY)
Mode: '',
AngleStart: '',
Revolutions: '',
Length: '',
Radius: '',
CounterClockWise: '',
},
@ -1194,14 +1193,14 @@ openSketch = startSketchOn(XY)
{
selectionType: 'segment',
testPoint: { x: 513, y: 221 },
expectedOutput: `helix001 = helix( axis = seg01, radius = 1, length = 100, revolutions = 20, angleStart = 0, ccw = false,)`,
expectedEditedOutput: `helix001 = helix( axis = seg01, radius = 1, length = 50, revolutions = 20, angleStart = 0, ccw = false,)`,
expectedOutput: `helix001 = helix( axis = seg01, radius = 1, revolutions = 20, angleStart = 0, ccw = false,)`,
expectedEditedOutput: `helix001 = helix( axis = seg01, radius = 5, revolutions = 20, angleStart = 0, ccw = false,)`,
},
{
selectionType: 'sweepEdge',
testPoint: { x: 564, y: 364 },
expectedOutput: `helix001 = helix( axis = getOppositeEdge(seg01), radius = 1, length = 100, revolutions = 20, angleStart = 0, ccw = false,)`,
expectedEditedOutput: `helix001 = helix( axis = getOppositeEdge(seg01), radius = 1, length = 50, revolutions = 20, angleStart = 0, ccw = false,)`,
expectedOutput: `helix001 = helix( axis = getOppositeEdge(seg01), radius = 1, revolutions = 20, angleStart = 0, ccw = false,)`,
expectedEditedOutput: `helix001 = helix( axis = getOppositeEdge(seg01), radius = 5, revolutions = 20, angleStart = 0, ccw = false,)`,
},
]
helixCases.map(
@ -1244,7 +1243,6 @@ openSketch = startSketchOn(XY)
AngleStart: '',
Mode: '',
CounterClockWise: '',
Length: '',
Radius: '',
Revolutions: '',
},
@ -1261,8 +1259,6 @@ openSketch = startSketchOn(XY)
await cmdBar.progressCmdBar()
await page.keyboard.insertText('1')
await cmdBar.progressCmdBar()
await page.keyboard.insertText('100')
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'review',
headerArguments: {
@ -1271,7 +1267,6 @@ openSketch = startSketchOn(XY)
AngleStart: '0',
Revolutions: '20',
Radius: '1',
Length: '100',
CounterClockWise: '',
},
commandName: 'Helix',
@ -1292,8 +1287,8 @@ openSketch = startSketchOn(XY)
0
)
await operationButton.dblclick()
const initialInput = '100'
const newInput = '50'
const initialInput = '1'
const newInput = '5'
await cmdBar.expectState({
commandName: 'Helix',
stage: 'arguments',
@ -1302,13 +1297,14 @@ openSketch = startSketchOn(XY)
headerArguments: {
AngleStart: '0',
Revolutions: '20',
Radius: '1',
Length: initialInput,
Radius: initialInput,
CounterClockWise: '',
},
highlightedHeaderArg: 'CounterClockWise',
})
await page.keyboard.press('Shift+Backspace')
await page
.getByRole('button', { name: 'radius', exact: false })
.click()
await expect(cmdBar.currentArgumentInput).toBeVisible()
await cmdBar.currentArgumentInput
.locator('.cm-content')
@ -1319,8 +1315,7 @@ openSketch = startSketchOn(XY)
headerArguments: {
AngleStart: '0',
Revolutions: '20',
Radius: '1',
Length: newInput,
Radius: newInput,
CounterClockWise: '',
},
commandName: 'Helix',
@ -1391,7 +1386,6 @@ extrude001 = extrude(profile001, length = 100)
Mode: '',
AngleStart: '',
Revolutions: '',
Length: '',
Radius: '',
CounterClockWise: '',
},

View File

@ -94,9 +94,11 @@
"fetch:wasm": "./scripts/get-latest-wasm-bundle.sh",
"fetch:wasm:windows": "./scripts/get-latest-wasm-bundle.ps1",
"fetch:samples": "rm -rf public/kcl-samples* && curl -L -o public/kcl-samples.zip https://github.com/KittyCAD/kcl-samples/archive/refs/heads/achalmers/kw-args-xylineto.zip && unzip -o public/kcl-samples.zip -d public && mv public/kcl-samples-* public/kcl-samples",
"build:wasm-dev": "yarn wasm-prep && (cd rust && wasm-pack build kcl-wasm-lib --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt:generated",
"build:wasm": "./scripts/build-wasm.sh",
"build:wasm:windows": "./scripts/build-wasm.ps1",
"build:wasm-dev": "yarn build:wasm:dev",
"build:wasm:dev": "./scripts/build-wasm-dev.sh",
"build:wasm:dev:windows": "./scripts/build-wasm-dev.ps1",
"remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./rust/kcl-wasm-lib/pkg/kcl_wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./rust/kcl-wasm-lib/pkg/kcl_wasm_lib.js\" || echo \"sed for both mac and linux\"",
"lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
"lint": "eslint --max-warnings 0 --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",

View File

@ -90,7 +90,7 @@ export default class StreamDemuxer extends Queue<Uint8Array> {
}
add(bytes: Uint8Array): void {
const message = Codec.decode(bytes) as vsrpc.Message
const message = Codec.decode<vsrpc.Message>(bytes)
if (this.trace) {
Tracer.server(message)
}

View File

@ -12,7 +12,7 @@ import "car-tire.kcl" as carTire
import lugCount from "globals.kcl"
carRotor
|> translate(translate = [0, 0.5, 0])
|> translate(x = 0, y = 0.5, z = 0)
carWheel
lugNut
|> patternCircular3d(
@ -23,5 +23,5 @@ lugNut
rotateDuplicates = false,
)
brakeCaliper
|> translate(translate = [0, 0.5, 0])
|> translate(x = 0, y = 0.5, z = 0)
carTire

View File

@ -19,27 +19,27 @@ import pipe from "1120t74-pipe.kcl"
flange()
flange()
|> rotate(axis = [0, 1, 0], angle = 180)
|> translate(translate = [
0,
0,
flangeBackHeight * 2 + gasketThickness
])
|> translate(
x = 0,
y = 0,
z = flangeBackHeight * 2 + gasketThickness,
)
// place gasket between the flanges
gasket()
|> translate(translate = [
0,
0,
-flangeBackHeight - gasketThickness
])
|> translate(
x = 0,
y = 0,
z = -flangeBackHeight - gasketThickness
)
// place eight washers (four front, four back)
washer()
|> translate(translate = [
mountingHolePlacementDiameter / 2,
0,
flangeBaseThickness
])
|> translate(
x = mountingHolePlacementDiameter / 2,
y = 0,
z = flangeBaseThickness
)
|> patternCircular3d(
%,
instances = 4,
@ -57,11 +57,11 @@ washer()
// place four bolts
bolt()
|> translate(translate = [
mountingHolePlacementDiameter / 2,
0,
flangeBaseThickness + washerThickness
])
|> translate(
x = mountingHolePlacementDiameter / 2,
y = 0,
z = flangeBaseThickness + washerThickness,
)
|> rotate(roll = 90, pitch = 0, yaw = 0)
|> patternCircular3d(
%,
@ -74,11 +74,11 @@ bolt()
// place four hex nuts
hexNut()
|> translate(translate = [
mountingHolePlacementDiameter / 2,
0,
-(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + washerThickness + hexNutThickness)
])
|> translate(
x = mountingHolePlacementDiameter / 2,
y = 0,
z = -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + washerThickness + hexNutThickness),
)
|> patternCircular3d(
%,
instances = 4,
@ -97,13 +97,11 @@ pipe()
yaw = 0,
)
|> translate(
%,
translate = [
0,
0,
flangeBaseThickness + flangeFrontHeight - 0.5
],
global = true,
%,
x = 0,
y = 0,
z = flangeBaseThickness + flangeFrontHeight - 0.5,
global = true,
)
pipe()
@ -114,11 +112,9 @@ pipe()
yaw = 0,
)
|> translate(
%,
translate = [
0,
0,
-(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + flangeFrontHeight - 0.5)
],
global = true,
%,
x = 0,
y = 0,
z = -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + flangeFrontHeight - 0.5),
global = true,
)

View File

@ -20,51 +20,36 @@ body()
// import the antenna
antenna()
|> translate(translate = [-width / 2 + .45, -0.10, height / 2])
|> translate(x = -width / 2 + .45, y = -0.10, z = height / 2)
// import the case
case()
|> translate(translate = [0, -1, 0])
|> translate(x = 0, y = -1, z = 0)
// import the talk button
talkButton()
|> translate(translate = [width / 2, -thickness / 2, .5])
|> translate(x = width / 2, y = -thickness / 2, z = .5)
// import the frequency knob
knob()
|> translate(translate = [
width / 2 - 0.70,
-thickness / 2,
height / 2
])
|> translate(
x = width / 2 - 0.70,
y = -thickness / 2,
z = height / 2
)
// import the buttons
button()
|> translate(translate = [
-(screenWidth / 2 + tolerance),
-1,
screenYPosition
])
button()
|> translate(translate = [
-(screenWidth / 2 + tolerance),
-1,
screenYPosition - buttonHeight - (tolerance * 2)
])
button()
|> rotate(
%,
roll = 0,
pitch = 180,
yaw = 0,
)
|> translate(
translate = [
screenWidth / 2 + tolerance,
-1,
screenYPosition - buttonHeight
],
global = true,
x = -(screenWidth / 2 + tolerance),
y = -1,
z = screenYPosition
)
button()
|> translate(
x = -(screenWidth / 2 + tolerance),
y = -1,
z = screenYPosition - buttonHeight - (tolerance * 2)
)
button()
|> rotate(
@ -74,10 +59,21 @@ button()
yaw = 0,
)
|> translate(
translate = [
screenWidth / 2 + tolerance,
-1,
screenYPosition - (buttonHeight * 2) - (tolerance * 2)
],
x = screenWidth / 2 + tolerance,
y = -1,
z = screenYPosition - buttonHeight,
global = true,
)
button()
|> rotate(
%,
roll = 0,
pitch = 180,
yaw = 0,
)
|> translate(
x = screenWidth / 2 + tolerance,
y = -1,
z = screenYPosition - (buttonHeight * 2) - (tolerance * 2),
global = true,
)

View File

@ -43,6 +43,10 @@ overwrite-sim-test test_name:
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- tests::{{test_name}}::kcl_test_execute
EXPECTORATE=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests::{{test_name}}::test_after_engine
# Regenerate all the simulation test output.
redo-sim-tests:
EXPECTORATE=overwrite TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib --no-quiet -- simulation_tests
test:
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --no-fail-fast

View File

@ -0,0 +1,77 @@
@settings(defaultLengthUnit = mm)
sketch001 = startSketchOn(XZ)
profile001 = circle(sketch001, center = [154.36, 113.92], radius = 41.09)
extrude001 = extrude(profile001, length = 200)
sketch002 = startSketchOn(XY)
profile002 = startProfileAt([72.24, -52.05], sketch002)
|> angledLine([0, 181.26], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
21.54
], %)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $mySeg)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude002 = extrude(profile002, length = 150)
|> chamfer(
%,
length = 15,
tags = [mySeg],
tag = $seg02,
)
sketch003 = startSketchOn(extrude002, mySeg)
profile003 = startProfileAt([207.36, 126.19], sketch003)
|> angledLine([0, 33.57], %, $rectangleSegmentA002)
|> angledLine([
segAng(rectangleSegmentA002) - 90,
99.11
], %)
|> angledLine([
segAng(rectangleSegmentA002),
-segLen(rectangleSegmentA002)
], %, $seg01)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude003 = extrude(profile003, length = -20)
sketch004 = startSketchOn(extrude003, seg01)
profile004 = startProfileAt([-235.38, 66.16], sketch004)
|> angledLine([0, 24.21], %, $rectangleSegmentA003)
|> angledLine([
segAng(rectangleSegmentA003) - 90,
3.72
], %)
|> angledLine([
segAng(rectangleSegmentA003),
-segLen(rectangleSegmentA003)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude004 = extrude(profile004, length = 30)
sketch005 = startSketchOn(extrude002, seg02)
profile005 = startProfileAt([-129.93, -59.19], sketch005)
|> xLine(length = 48.79)
|> line(end = [1.33, 11.03])
|> xLine(length = -60.56, tag = $seg03)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude005 = extrude(profile005, length = -10)
sketch006 = startSketchOn(extrude005, seg03)
profile006 = startProfileAt([-95.86, 38.73], sketch006)
|> angledLine([0, 3.48], %, $rectangleSegmentA004)
|> angledLine([
segAng(rectangleSegmentA004) - 90,
3.36
], %)
|> angledLine([
segAng(rectangleSegmentA004),
-segLen(rectangleSegmentA004)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude006 = extrude(profile006, length = 13)

View File

@ -1141,7 +1141,7 @@ mod tests {
let snippet = scale_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"scale(${0:%}, scale = [${1:3.14}, ${2:3.14}, ${3:3.14}])${}"#
r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"#
);
}
@ -1152,7 +1152,7 @@ mod tests {
let snippet = translate_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"translate(${0:%}, translate = [${1:3.14}, ${2:3.14}, ${3:3.14}])${}"#
r#"translate(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"#
);
}

View File

@ -121,6 +121,13 @@ impl EngineConnection {
}
})?;
if value.is_null() || value.is_undefined() {
return Err(KclError::Engine(KclErrorDetails {
message: "Received null or undefined response from engine".into(),
source_ranges: vec![source_range],
}));
}
// Convert JsValue to a Uint8Array
let data = js_sys::Uint8Array::from(value);

View File

@ -201,6 +201,35 @@
//! check safety, it is not ever used for any decision. In any case, modifying the env storage is
//! must be safe if the env is in either state, so even if the transition happens at the same time
//! as the storage modification, it is ok.
//!
//! Here is an ascii art diagram of the memory system:
//!
//! +----------------------------+
//! | ProgramMemory |
//! |----------------------------|
//! | Envs: |
//! | |
//! | [ Env 1 ] |
//! | - Vars: { "a" = 10 } |
//! | - Epoch: 1 |
//! | - Owner ID: 0 | <- read-only
//! | |
//! | [ Env 2 ] |
//! | - Vars: { "b" = a } |
//! | - Epoch: 2 |
//! | - Owner ID: 42 | <- owned by Stack 42
//! | |
//! +-------------^--------------+
//! |
//! | shared, immutable OR
//! | uniquely owned mutable reference
//! +---------+---------+
//! | Stack 42 |
//! |-------------------|
//! | stack_id: 42 |
//! | env_stack: [2] |
//! | epoch: 2 |
//! +-------------------+
use std::{
cell::UnsafeCell,

View File

@ -2044,6 +2044,8 @@ let w = f() + f()
// Ensure the settings are as expected.
assert_eq!(settings_state, ctx.settings);
ctx.close().await;
}
#[tokio::test(flavor = "multi_thread")]
@ -2057,6 +2059,9 @@ let w = f() + f()
let program2 = crate::Program::parse_no_errs("z = x + 1").unwrap();
let result = ctx2.run_mock(program2, true).await.unwrap();
assert_eq!(result.variables.get("z").unwrap().as_f64().unwrap(), 3.0);
ctx.close().await;
ctx2.close().await;
}
#[tokio::test(flavor = "multi_thread")]

View File

@ -133,6 +133,13 @@ impl<T> Node<T> {
})
}
fn reset_source(&mut self) {
self.start = 0;
self.end = 0;
self.module_id = ModuleId::default();
self.comment_start = 0;
}
pub fn as_source_range(&self) -> SourceRange {
SourceRange::new(self.start, self.end, self.module_id)
}
@ -345,7 +352,10 @@ impl Node<Program> {
let mut found = false;
for node in &mut new_program.inner_attrs {
if node.name() == Some(annotations::SETTINGS) {
*node = Node::no_src(Annotation::new_from_meta_settings(&settings));
node.inner = Annotation::new_from_meta_settings(&settings);
// Previous source range no longer makes sense, but we want to
// preserve other things like comments.
node.reset_source();
found = true;
break;
}
@ -4140,6 +4150,50 @@ startSketchOn(XY)
r#"@settings(defaultLengthUnit = mm)
startSketchOn(XY)
"#
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_change_meta_settings_preserves_comments() {
let code = r#"// Title
// Set Units
@settings(defaultLengthUnit = in)
// Between
// Above Code
5
"#;
let program = crate::parsing::top_level_parse(code).unwrap();
let new_program = program
.change_meta_settings(crate::execution::MetaSettings {
default_length_units: crate::execution::types::UnitLen::Cm,
..Default::default()
})
.unwrap();
let result = new_program.meta_settings().unwrap();
assert!(result.is_some());
let meta_settings = result.unwrap();
assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Cm);
let formatted = new_program.recast(&Default::default(), 0);
assert_eq!(
formatted,
r#"// Title
// Set Units
@settings(defaultLengthUnit = cm)
// Between
// Above Code
5
"#
);
}

View File

@ -2379,3 +2379,66 @@ mod rotate_after_fillet {
super::execute(TEST_NAME, true).await
}
}
mod union_cubes {
const TEST_NAME: &str = "union_cubes";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[tokio::test(flavor = "multi_thread")]
async fn unparse() {
super::unparse(TEST_NAME).await
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await
}
}
mod subtract_cylinder_from_cube {
const TEST_NAME: &str = "subtract_cylinder_from_cube";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[tokio::test(flavor = "multi_thread")]
async fn unparse() {
super::unparse(TEST_NAME).await
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await
}
}
mod intersect_cubes {
const TEST_NAME: &str = "intersect_cubes";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[tokio::test(flavor = "multi_thread")]
async fn unparse() {
super::unparse(TEST_NAME).await
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await
}
}

View File

@ -45,7 +45,7 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// ```
#[stdlib {
name = "union",
feature_tree_operation = false,
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
deprecated = true,
@ -107,7 +107,7 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// ```
#[stdlib {
name = "intersect",
feature_tree_operation = false,
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
deprecated = true,
@ -164,7 +164,7 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
/// ```
#[stdlib {
name = "subtract",
feature_tree_operation = false,
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
deprecated = true,

View File

@ -28,15 +28,22 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
]),
exec_state,
)?;
let scale = args.get_kw_arg("scale")?;
let scale_x = args.get_kw_arg("x")?;
let scale_y = args.get_kw_arg("y")?;
let scale_z = args.get_kw_arg("z")?;
let global = args.get_kw_arg_opt("global")?;
let objects = inner_scale(objects, scale, global, exec_state, args).await?;
let objects = inner_scale(objects, scale_x, scale_y, scale_z, global, exec_state, args).await?;
Ok(objects.into())
}
/// Scale a solid or a sketch.
///
/// This is really useful for resizing parts. You can create a part and then scale it to the
/// correct size.
///
/// For sketches, you can use this to scale a sketch and then loft it with another sketch.
///
/// By default the transform is applied in local sketch axis, therefore the origin will not move.
///
/// If you want to apply the transform in global space, set `global` to `true`. The origin of the
@ -78,7 +85,9 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> hole(pipeHole, %)
/// |> sweep(path = sweepPath)
/// |> scale(
/// scale = [1.0, 1.0, 2.5],
/// x = 1.0,
/// y = 1.0,
/// z = 2.5,
/// )
/// ```
///
@ -89,7 +98,9 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
///
/// cube
/// |> scale(
/// scale = [1.0, 1.0, 2.5],
/// x = 1.0,
/// y = 1.0,
/// z = 2.5,
/// )
/// ```
///
@ -124,7 +135,7 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
///
/// // Scale the sweep.
/// scale(parts, scale = [1.0, 1.0, 0.5])
/// scale(parts, x = 1.0, y = 1.0, z = 0.5)
/// ```
#[stdlib {
name = "scale",
@ -133,13 +144,17 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
unlabeled_first = true,
args = {
objects = {docs = "The solid, sketch, or set of solids or sketches to scale."},
scale = {docs = "The scale factor for the x, y, and z axes."},
x = {docs = "The scale factor for the x axis."},
y = {docs = "The scale factor for the y axis."},
z = {docs = "The scale factor for the z axis."},
global = {docs = "If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move."}
}
}]
async fn inner_scale(
objects: SolidOrSketchOrImportedGeometry,
scale: [f64; 3],
x: f64,
y: f64,
z: f64,
global: Option<bool>,
exec_state: &mut ExecState,
args: Args,
@ -159,11 +174,7 @@ async fn inner_scale(
object_id,
transforms: vec![shared::ComponentTransform {
scale: Some(shared::TransformBy::<Point3d<f64>> {
property: Point3d {
x: scale[0],
y: scale[1],
z: scale[2],
},
property: Point3d { x, y, z },
set: false,
is_local: !global.unwrap_or(false),
}),
@ -190,15 +201,23 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
]),
exec_state,
)?;
let translate = args.get_kw_arg("translate")?;
let translate_x = args.get_kw_arg("x")?;
let translate_y = args.get_kw_arg("y")?;
let translate_z = args.get_kw_arg("z")?;
let global = args.get_kw_arg_opt("global")?;
let objects = inner_translate(objects, translate, global, exec_state, args).await?;
let objects = inner_translate(objects, translate_x, translate_y, translate_z, global, exec_state, args).await?;
Ok(objects.into())
}
/// Move a solid or a sketch.
///
/// This is really useful for assembling parts together. You can create a part
/// and then move it to the correct location.
///
/// Translate is really useful for sketches if you want to move a sketch
/// and then rotate it using the `rotate` function to create a loft.
///
/// ```no_run
/// // Move a pipe.
///
@ -232,7 +251,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// |> hole(pipeHole, %)
/// |> sweep(path = sweepPath)
/// |> translate(
/// translate = [1.0, 1.0, 2.5],
/// x = 1.0,
/// y = 1.0,
/// z = 2.5,
/// )
/// ```
///
@ -243,7 +264,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
///
/// cube
/// |> translate(
/// translate = [1.0, 1.0, 2.5],
/// x = 1.0,
/// y = 1.0,
/// z = 2.5,
/// )
/// ```
///
@ -278,7 +301,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
///
/// // Move the sweeps.
/// translate(parts, translate = [1.0, 1.0, 2.5])
/// translate(parts, x = 1.0, y = 1.0, z = 2.5)
/// ```
///
/// ```no_run
@ -301,7 +324,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
///
/// square(10)
/// |> translate(
/// translate = [5, 5, 0],
/// x = 5,
/// y = 5,
/// z = 0,
/// )
/// |> extrude(
/// length = 10,
@ -324,7 +349,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// profile001 = square()
///
/// profile002 = square()
/// |> translate(translate = [0, 0, 20])
/// |> translate(x = 0, y = 0, z = 20)
/// |> rotate(axis = [0, 0, 1.0], angle = 45)
///
/// loft([profile001, profile002])
@ -336,13 +361,17 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
unlabeled_first = true,
args = {
objects = {docs = "The solid, sketch, or set of solids or sketches to move."},
translate = {docs = "The amount to move the solid or sketch in all three axes."},
x = {docs = "The amount to move the solid or sketch along the x axis."},
y = {docs = "The amount to move the solid or sketch along the y axis."},
z = {docs = "The amount to move the solid or sketch along the z axis."},
global = {docs = "If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move."}
}
}]
async fn inner_translate(
objects: SolidOrSketchOrImportedGeometry,
translate: [f64; 3],
x: f64,
y: f64,
z: f64,
global: Option<bool>,
exec_state: &mut ExecState,
args: Args,
@ -363,9 +392,9 @@ async fn inner_translate(
transforms: vec![shared::ComponentTransform {
translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
property: shared::Point3d {
x: LengthUnit(translate[0]),
y: LengthUnit(translate[1]),
z: LengthUnit(translate[2]),
x: LengthUnit(x),
y: LengthUnit(y),
z: LengthUnit(z),
},
set: false,
is_local: !global.unwrap_or(false),
@ -506,6 +535,11 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// Rotate a solid or a sketch.
///
/// This is really useful for assembling parts together. You can create a part
/// and then rotate it to the correct orientation.
///
/// For sketches, you can use this to rotate a sketch and then loft it with another sketch.
///
/// ### Using Roll, Pitch, and Yaw
///
/// When rotating a part in 3D space, "roll," "pitch," and "yaw" refer to the
@ -667,7 +701,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// profile001 = square()
///
/// profile002 = square()
/// |> translate(translate = [0, 0, 20])
/// |> translate(x = 0, y = 0, z = 20)
/// |> rotate(axis = [0, 0, 1.0], angle = 45)
///
/// loft([profile001, profile002])

View File

@ -151,54 +151,65 @@ description: Result of parsing import_transform.kcl
"label": {
"commentStart": 159,
"end": 0,
"name": "translate",
"name": "x",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 171,
"elements": [
{
"commentStart": 172,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
},
{
"commentStart": 178,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
},
{
"commentStart": 184,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
],
"commentStart": 163,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 169,
"end": 0,
"name": "y",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 173,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 179,
"end": 0,
"name": "z",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 183,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
}
],
@ -235,65 +246,76 @@ description: Result of parsing import_transform.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 205,
"commentStart": 203,
"end": 0,
"name": "scale",
"name": "x",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 213,
"elements": [
{
"commentStart": 214,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
},
{
"commentStart": 220,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
},
{
"commentStart": 226,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
],
"commentStart": 207,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 213,
"end": 0,
"name": "y",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 217,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 223,
"end": 0,
"name": "z",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 227,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
}
],
"callee": {
"abs_path": false,
"commentStart": 196,
"commentStart": 194,
"end": 0,
"name": {
"commentStart": 196,
"commentStart": 194,
"end": 0,
"name": "scale",
"start": 0,
@ -303,13 +325,13 @@ description: Result of parsing import_transform.kcl
"start": 0,
"type": "Name"
},
"commentStart": 196,
"commentStart": 194,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"commentStart": 202,
"commentStart": 200,
"end": 0,
"start": 0,
"type": "PipeSubstitution",

View File

@ -7,5 +7,5 @@ screw
pitch = 3.14,
yaw = 3.14,
)
|> translate(%, translate = [3.14, 3.14, 3.14])
|> scale(%, scale = [3.14, 3.14, 3.14])
|> translate(%, x = 3.14, y = 3.14, z = 3.14)
|> scale(%, x = 3.14, y = 3.14, z = 3.14)

View File

@ -11,5 +11,15 @@ screw
pitch = 3.14,
yaw = 3.14,
)
|> translate(%, translate = [3.14, 3.14, 3.14])
|> scale(%, scale = [3.14, 3.14, 3.14])
|> translate(
%,
x = 3.14,
y = 3.14,
z = 3.14,
)
|> scale(
%,
x = 3.14,
y = 3.14,
z = 3.14,
)

View File

@ -0,0 +1,554 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands intersect_cubes.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -10.0,
"y": -10.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": -10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": 10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -10.0,
"y": 10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -2.0,
"y": -2.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 18.0,
"y": -2.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 18.0,
"y": 18.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -2.0,
"y": 18.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
}
]

View File

@ -0,0 +1,6 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact graph flowchart intersect_cubes.kcl
extension: md
snapshot_kind: binary
---

View File

@ -0,0 +1,117 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[52, 103, 0]"]
3["Segment<br>[111, 163, 0]"]
4["Segment<br>[171, 223, 0]"]
5["Segment<br>[231, 283, 0]"]
6["Segment<br>[291, 298, 0]"]
7[Solid2d]
end
subgraph path24 [Path]
24["Path<br>[52, 103, 0]"]
25["Segment<br>[111, 163, 0]"]
26["Segment<br>[171, 223, 0]"]
27["Segment<br>[231, 283, 0]"]
28["Segment<br>[291, 298, 0]"]
29[Solid2d]
end
1["Plane<br>[27, 44, 0]"]
8["Sweep Extrusion<br>[306, 326, 0]"]
9[Wall]
10[Wall]
11[Wall]
12[Wall]
13["Cap Start"]
14["Cap End"]
15["SweepEdge Opposite"]
16["SweepEdge Adjacent"]
17["SweepEdge Opposite"]
18["SweepEdge Adjacent"]
19["SweepEdge Opposite"]
20["SweepEdge Adjacent"]
21["SweepEdge Opposite"]
22["SweepEdge Adjacent"]
23["Plane<br>[27, 44, 0]"]
30["Sweep Extrusion<br>[306, 326, 0]"]
31[Wall]
32[Wall]
33[Wall]
34[Wall]
35["Cap Start"]
36["Cap End"]
37["SweepEdge Opposite"]
38["SweepEdge Adjacent"]
39["SweepEdge Opposite"]
40["SweepEdge Adjacent"]
41["SweepEdge Opposite"]
42["SweepEdge Adjacent"]
43["SweepEdge Opposite"]
44["SweepEdge Adjacent"]
1 --- 2
2 --- 3
2 --- 4
2 --- 5
2 --- 6
2 ---- 8
2 --- 7
3 --- 9
3 --- 15
3 --- 16
4 --- 10
4 --- 17
4 --- 18
5 --- 11
5 --- 19
5 --- 20
6 --- 12
6 --- 21
6 --- 22
8 --- 9
8 --- 10
8 --- 11
8 --- 12
8 --- 13
8 --- 14
8 --- 15
8 --- 16
8 --- 17
8 --- 18
8 --- 19
8 --- 20
8 --- 21
8 --- 22
23 --- 24
24 --- 25
24 --- 26
24 --- 27
24 --- 28
24 ---- 30
24 --- 29
25 --- 31
25 --- 37
25 --- 38
26 --- 32
26 --- 39
26 --- 40
27 --- 33
27 --- 41
27 --- 42
28 --- 34
28 --- 43
28 --- 44
30 --- 31
30 --- 32
30 --- 33
30 --- 34
30 --- 35
30 --- 36
30 --- 37
30 --- 38
30 --- 39
30 --- 40
30 --- 41
30 --- 42
30 --- 43
30 --- 44
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
fn cube(center) {
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
part001 = cube([0, 0])
part002 = cube([8, 8])
fullPart = intersect([part001, part002])

View File

@ -0,0 +1,158 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed intersect_cubes.kcl
---
[
{
"type": "UserDefinedFunctionCall",
"name": "cube",
"functionSourceRange": [
7,
328,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "cube",
"functionSourceRange": [
7,
328,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "UserDefinedFunctionReturn"
},
{
"labeledArgs": {
"solids": {
"value": {
"type": "Array",
"value": [
{
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
}
},
"name": "intersect",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
}
]

View File

@ -0,0 +1,543 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing intersect_cubes.kcl
---
{
"cube": {
"type": "Function"
},
"fullPart": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
-10.0
],
"tag": null,
"to": [
10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
-10.0
],
"tag": null,
"to": [
10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
10.0
],
"tag": null,
"to": [
-10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
10.0
],
"tag": null,
"to": [
-10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-10.0,
-10.0
],
"to": [
-10.0,
-10.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"part001": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
-10.0
],
"tag": null,
"to": [
10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
-10.0
],
"tag": null,
"to": [
10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
10.0
],
"tag": null,
"to": [
-10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
10.0
],
"tag": null,
"to": [
-10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-10.0,
-10.0
],
"to": [
-10.0,
-10.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"part002": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-2.0,
-2.0
],
"tag": null,
"to": [
18.0,
-2.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
18.0,
-2.0
],
"tag": null,
"to": [
18.0,
18.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
18.0,
18.0
],
"tag": null,
"to": [
-2.0,
18.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-2.0,
18.0
],
"tag": null,
"to": [
-2.0,
-2.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-2.0,
-2.0
],
"to": [
-2.0,
-2.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -0,0 +1,18 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing intersect_cubes.kcl
---
fn cube(center) {
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
part001 = cube([0, 0])
part002 = cube([8, 8])
fullPart = intersect([part001, part002])

View File

@ -168,54 +168,65 @@ description: Result of parsing car-wheel-assembly.kcl
"label": {
"commentStart": 366,
"end": 0,
"name": "translate",
"name": "x",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 378,
"elements": [
{
"commentStart": 379,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"commentStart": 382,
"end": 0,
"raw": "0.5",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.5,
"suffix": "None"
}
},
{
"commentStart": 387,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"commentStart": 370,
"end": 0,
"raw": "0",
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 373,
"end": 0,
"name": "y",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 377,
"end": 0,
"raw": "0.5",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.5,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 382,
"end": 0,
"name": "z",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 386,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
}
],
@ -253,14 +264,14 @@ description: Result of parsing car-wheel-assembly.kcl
"type": "ExpressionStatement"
},
{
"commentStart": 391,
"commentStart": 389,
"end": 0,
"expression": {
"abs_path": false,
"commentStart": 391,
"commentStart": 389,
"end": 0,
"name": {
"commentStart": 391,
"commentStart": 389,
"end": 0,
"name": "carWheel",
"start": 0,
@ -276,16 +287,16 @@ description: Result of parsing car-wheel-assembly.kcl
"type": "ExpressionStatement"
},
{
"commentStart": 400,
"commentStart": 398,
"end": 0,
"expression": {
"body": [
{
"abs_path": false,
"commentStart": 400,
"commentStart": 398,
"end": 0,
"name": {
"commentStart": 400,
"commentStart": 398,
"end": 0,
"name": "lugNut",
"start": 0,
@ -301,14 +312,14 @@ description: Result of parsing car-wheel-assembly.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 438,
"commentStart": 436,
"end": 0,
"name": "arcDegrees",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 451,
"commentStart": 449,
"end": 0,
"raw": "360",
"start": 0,
@ -323,17 +334,17 @@ description: Result of parsing car-wheel-assembly.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 463,
"commentStart": 461,
"end": 0,
"name": "axis",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 470,
"commentStart": 468,
"elements": [
{
"commentStart": 471,
"commentStart": 469,
"end": 0,
"raw": "0",
"start": 0,
@ -345,7 +356,7 @@ description: Result of parsing car-wheel-assembly.kcl
}
},
{
"commentStart": 474,
"commentStart": 472,
"end": 0,
"raw": "1",
"start": 0,
@ -357,7 +368,7 @@ description: Result of parsing car-wheel-assembly.kcl
}
},
{
"commentStart": 477,
"commentStart": 475,
"end": 0,
"raw": "0",
"start": 0,
@ -378,17 +389,17 @@ description: Result of parsing car-wheel-assembly.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 488,
"commentStart": 486,
"end": 0,
"name": "center",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 497,
"commentStart": 495,
"elements": [
{
"commentStart": 498,
"commentStart": 496,
"end": 0,
"raw": "0",
"start": 0,
@ -400,7 +411,7 @@ description: Result of parsing car-wheel-assembly.kcl
}
},
{
"commentStart": 501,
"commentStart": 499,
"end": 0,
"raw": "0",
"start": 0,
@ -412,7 +423,7 @@ description: Result of parsing car-wheel-assembly.kcl
}
},
{
"commentStart": 504,
"commentStart": 502,
"end": 0,
"raw": "0",
"start": 0,
@ -433,7 +444,7 @@ description: Result of parsing car-wheel-assembly.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 515,
"commentStart": 513,
"end": 0,
"name": "instances",
"start": 0,
@ -441,10 +452,10 @@ description: Result of parsing car-wheel-assembly.kcl
},
"arg": {
"abs_path": false,
"commentStart": 527,
"commentStart": 525,
"end": 0,
"name": {
"commentStart": 527,
"commentStart": 525,
"end": 0,
"name": "lugCount",
"start": 0,
@ -459,14 +470,14 @@ description: Result of parsing car-wheel-assembly.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 544,
"commentStart": 542,
"end": 0,
"name": "rotateDuplicates",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 563,
"commentStart": 561,
"end": 0,
"raw": "false",
"start": 0,
@ -478,10 +489,10 @@ description: Result of parsing car-wheel-assembly.kcl
],
"callee": {
"abs_path": false,
"commentStart": 412,
"commentStart": 410,
"end": 0,
"name": {
"commentStart": 412,
"commentStart": 410,
"end": 0,
"name": "patternCircular3d",
"start": 0,
@ -491,7 +502,7 @@ description: Result of parsing car-wheel-assembly.kcl
"start": 0,
"type": "Name"
},
"commentStart": 412,
"commentStart": 410,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -499,7 +510,7 @@ description: Result of parsing car-wheel-assembly.kcl
"unlabeled": null
}
],
"commentStart": 400,
"commentStart": 398,
"end": 0,
"start": 0,
"type": "PipeExpression",
@ -510,16 +521,16 @@ description: Result of parsing car-wheel-assembly.kcl
"type": "ExpressionStatement"
},
{
"commentStart": 577,
"commentStart": 575,
"end": 0,
"expression": {
"body": [
{
"abs_path": false,
"commentStart": 577,
"commentStart": 575,
"end": 0,
"name": {
"commentStart": 577,
"commentStart": 575,
"end": 0,
"name": "brakeCaliper",
"start": 0,
@ -535,65 +546,76 @@ description: Result of parsing car-wheel-assembly.kcl
{
"type": "LabeledArg",
"label": {
"commentStart": 605,
"commentStart": 603,
"end": 0,
"name": "translate",
"name": "x",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 617,
"elements": [
{
"commentStart": 618,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"commentStart": 621,
"end": 0,
"raw": "0.5",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.5,
"suffix": "None"
}
},
{
"commentStart": 626,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"commentStart": 607,
"end": 0,
"raw": "0",
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 610,
"end": 0,
"name": "y",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 614,
"end": 0,
"raw": "0.5",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.5,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 619,
"end": 0,
"name": "z",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 623,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
}
],
"callee": {
"abs_path": false,
"commentStart": 595,
"commentStart": 593,
"end": 0,
"name": {
"commentStart": 595,
"commentStart": 593,
"end": 0,
"name": "translate",
"start": 0,
@ -603,7 +625,7 @@ description: Result of parsing car-wheel-assembly.kcl
"start": 0,
"type": "Name"
},
"commentStart": 595,
"commentStart": 593,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
@ -611,7 +633,7 @@ description: Result of parsing car-wheel-assembly.kcl
"unlabeled": null
}
],
"commentStart": 577,
"commentStart": 575,
"end": 0,
"start": 0,
"type": "PipeExpression",
@ -622,14 +644,14 @@ description: Result of parsing car-wheel-assembly.kcl
"type": "ExpressionStatement"
},
{
"commentStart": 630,
"commentStart": 626,
"end": 0,
"expression": {
"abs_path": false,
"commentStart": 630,
"commentStart": 626,
"end": 0,
"name": {
"commentStart": 630,
"commentStart": 626,
"end": 0,
"name": "carTire",
"start": 0,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2097,54 +2097,65 @@ description: Result of parsing scale_after_fillet.kcl
"label": {
"commentStart": 1593,
"end": 0,
"name": "scale",
"name": "x",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 1601,
"elements": [
{
"commentStart": 1602,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
},
{
"commentStart": 1608,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
},
{
"commentStart": 1614,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
],
"commentStart": 1597,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 1603,
"end": 0,
"name": "y",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 1607,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 1613,
"end": 0,
"name": "z",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 1617,
"end": 0,
"raw": "3.14",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.14,
"suffix": "None"
}
}
}
],
@ -2177,7 +2188,7 @@ description: Result of parsing scale_after_fillet.kcl
"nonCodeNodes": {
"1": [
{
"commentStart": 1620,
"commentStart": 1622,
"end": 0,
"start": 0,
"type": "NonCodeNode",

View File

@ -52,6 +52,6 @@ export fn bolt() {
}
bolt()
|> scale(scale = [3.14, 3.14, 3.14])
|> scale(x = 3.14, y = 3.14, z = 3.14)
// https://www.mcmaster.com/91251a404/

View File

@ -56,6 +56,6 @@ export fn bolt() {
}
bolt()
|> scale(scale = [3.14, 3.14, 3.14])
|> scale(x = 3.14, y = 3.14, z = 3.14)
// https://www.mcmaster.com/91251a404/

View File

@ -0,0 +1,468 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands subtract_cylinder_from_cube.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -10.0,
"y": -10.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": -10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": 10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -10.0,
"y": 10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 2.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "arc",
"center": {
"x": 0.0,
"y": 0.0
},
"radius": 2.0,
"start": {
"unit": "degrees",
"value": 0.0
},
"end": {
"unit": "degrees",
"value": 360.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
}
]

View File

@ -0,0 +1,6 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact graph flowchart subtract_cylinder_from_cube.kcl
extension: md
snapshot_kind: binary
---

View File

@ -0,0 +1,84 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[52, 103, 0]"]
3["Segment<br>[111, 163, 0]"]
4["Segment<br>[171, 223, 0]"]
5["Segment<br>[231, 283, 0]"]
6["Segment<br>[291, 298, 0]"]
7[Solid2d]
end
subgraph path24 [Path]
24["Path<br>[388, 423, 0]"]
25["Segment<br>[388, 423, 0]"]
26[Solid2d]
end
1["Plane<br>[27, 44, 0]"]
8["Sweep Extrusion<br>[306, 326, 0]"]
9[Wall]
10[Wall]
11[Wall]
12[Wall]
13["Cap Start"]
14["Cap End"]
15["SweepEdge Opposite"]
16["SweepEdge Adjacent"]
17["SweepEdge Opposite"]
18["SweepEdge Adjacent"]
19["SweepEdge Opposite"]
20["SweepEdge Adjacent"]
21["SweepEdge Opposite"]
22["SweepEdge Adjacent"]
23["Plane<br>[363, 382, 0]"]
27["Sweep Extrusion<br>[429, 449, 0]"]
28[Wall]
29["Cap Start"]
30["Cap End"]
31["SweepEdge Opposite"]
32["SweepEdge Adjacent"]
1 --- 2
2 --- 3
2 --- 4
2 --- 5
2 --- 6
2 ---- 8
2 --- 7
3 --- 9
3 --- 15
3 --- 16
4 --- 10
4 --- 17
4 --- 18
5 --- 11
5 --- 19
5 --- 20
6 --- 12
6 --- 21
6 --- 22
8 --- 9
8 --- 10
8 --- 11
8 --- 12
8 --- 13
8 --- 14
8 --- 15
8 --- 16
8 --- 17
8 --- 18
8 --- 19
8 --- 20
8 --- 21
8 --- 22
23 --- 24
24 --- 25
24 ---- 27
24 --- 26
25 --- 28
25 --- 31
25 --- 32
27 --- 28
27 --- 29
27 --- 30
27 --- 31
27 --- 32
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
fn cube(center) {
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
part001 = cube([0, 0])
part002 = startSketchOn('XY')
|> circle(center = [0, 0], radius = 2)
|> extrude(length = 10)
fullPart = subtract([part001], tools=[part002])

View File

@ -0,0 +1,216 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed subtract_cylinder_from_cube.kcl
---
[
{
"type": "UserDefinedFunctionCall",
"name": "cube",
"functionSourceRange": [
7,
328,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "UserDefinedFunctionReturn"
},
{
"labeledArgs": {
"data": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"labeledArgs": {
"tools": {
"value": {
"type": "Array",
"value": [
{
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
}
},
"name": "subtract",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
}
}
]

View File

@ -0,0 +1,471 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing subtract_cylinder_from_cube.kcl
---
{
"cube": {
"type": "Function"
},
"fullPart": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
-10.0
],
"tag": null,
"to": [
10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
-10.0
],
"tag": null,
"to": [
10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
10.0
],
"tag": null,
"to": [
-10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
10.0
],
"tag": null,
"to": [
-10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-10.0,
-10.0
],
"to": [
-10.0,
-10.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"part001": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
-10.0
],
"tag": null,
"to": [
10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
-10.0
],
"tag": null,
"to": [
10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
10.0
],
"tag": null,
"to": [
-10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
10.0
],
"tag": null,
"to": [
-10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-10.0,
-10.0
],
"to": [
-10.0,
-10.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"part002": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudeArc"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"ccw": true,
"center": [
0.0,
0.0
],
"from": [
2.0,
0.0
],
"radius": 2.0,
"tag": null,
"to": [
2.0,
0.0
],
"type": "Circle",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
2.0,
0.0
],
"to": [
2.0,
0.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -0,0 +1,20 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing subtract_cylinder_from_cube.kcl
---
fn cube(center) {
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
part001 = cube([0, 0])
part002 = startSketchOn(XY)
|> circle(center = [0, 0], radius = 2)
|> extrude(length = 10)
fullPart = subtract([part001], tools = [part002])

View File

@ -2097,54 +2097,65 @@ description: Result of parsing translate_after_fillet.kcl
"label": {
"commentStart": 1597,
"end": 0,
"name": "translate",
"name": "x",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 1601,
"end": 0,
"raw": "10",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 10.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 1605,
"end": 0,
"name": "y",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 1609,
"elements": [
{
"commentStart": 1610,
"end": 0,
"raw": "10",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 10.0,
"suffix": "None"
}
},
{
"commentStart": 1614,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"commentStart": 1617,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 0,
"raw": "0",
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 1612,
"end": 0,
"name": "z",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 1616,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
}
],
@ -2177,7 +2188,7 @@ description: Result of parsing translate_after_fillet.kcl
"nonCodeNodes": {
"1": [
{
"commentStart": 1620,
"commentStart": 1618,
"end": 0,
"start": 0,
"type": "NonCodeNode",

View File

@ -52,6 +52,6 @@ export fn bolt() {
}
bolt()
|> translate(translate = [10, 0, 0])
|> translate(x = 10, y = 0, z = 0)
// https://www.mcmaster.com/91251a404/

View File

@ -56,6 +56,6 @@ export fn bolt() {
}
bolt()
|> translate(translate = [10, 0, 0])
|> translate(x = 10, y = 0, z = 0)
// https://www.mcmaster.com/91251a404/

View File

@ -0,0 +1,554 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands union_cubes.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -10.0,
"y": -10.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": -10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": 10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -10.0,
"y": 10.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"size": 60.0,
"clobber": false,
"hide": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 10.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 30.0,
"y": 0.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 30.0,
"y": 20.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 10.0,
"y": 20.0,
"z": 0.0
},
"relative": false
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "enable_sketch_mode",
"entity_id": "[uuid]",
"ortho": false,
"animated": false,
"adjust_camera": false,
"planar_normal": {
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_opposite_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_next_adjacent_edge",
"object_id": "[uuid]",
"edge_id": "[uuid]",
"face_id": "[uuid]"
}
}
]

View File

@ -0,0 +1,6 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact graph flowchart union_cubes.kcl
extension: md
snapshot_kind: binary
---

View File

@ -0,0 +1,117 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[52, 103, 0]"]
3["Segment<br>[111, 163, 0]"]
4["Segment<br>[171, 223, 0]"]
5["Segment<br>[231, 283, 0]"]
6["Segment<br>[291, 298, 0]"]
7[Solid2d]
end
subgraph path24 [Path]
24["Path<br>[52, 103, 0]"]
25["Segment<br>[111, 163, 0]"]
26["Segment<br>[171, 223, 0]"]
27["Segment<br>[231, 283, 0]"]
28["Segment<br>[291, 298, 0]"]
29[Solid2d]
end
1["Plane<br>[27, 44, 0]"]
8["Sweep Extrusion<br>[306, 326, 0]"]
9[Wall]
10[Wall]
11[Wall]
12[Wall]
13["Cap Start"]
14["Cap End"]
15["SweepEdge Opposite"]
16["SweepEdge Adjacent"]
17["SweepEdge Opposite"]
18["SweepEdge Adjacent"]
19["SweepEdge Opposite"]
20["SweepEdge Adjacent"]
21["SweepEdge Opposite"]
22["SweepEdge Adjacent"]
23["Plane<br>[27, 44, 0]"]
30["Sweep Extrusion<br>[306, 326, 0]"]
31[Wall]
32[Wall]
33[Wall]
34[Wall]
35["Cap Start"]
36["Cap End"]
37["SweepEdge Opposite"]
38["SweepEdge Adjacent"]
39["SweepEdge Opposite"]
40["SweepEdge Adjacent"]
41["SweepEdge Opposite"]
42["SweepEdge Adjacent"]
43["SweepEdge Opposite"]
44["SweepEdge Adjacent"]
1 --- 2
2 --- 3
2 --- 4
2 --- 5
2 --- 6
2 ---- 8
2 --- 7
3 --- 9
3 --- 15
3 --- 16
4 --- 10
4 --- 17
4 --- 18
5 --- 11
5 --- 19
5 --- 20
6 --- 12
6 --- 21
6 --- 22
8 --- 9
8 --- 10
8 --- 11
8 --- 12
8 --- 13
8 --- 14
8 --- 15
8 --- 16
8 --- 17
8 --- 18
8 --- 19
8 --- 20
8 --- 21
8 --- 22
23 --- 24
24 --- 25
24 --- 26
24 --- 27
24 --- 28
24 ---- 30
24 --- 29
25 --- 31
25 --- 37
25 --- 38
26 --- 32
26 --- 39
26 --- 40
27 --- 33
27 --- 41
27 --- 42
28 --- 34
28 --- 43
28 --- 44
30 --- 31
30 --- 32
30 --- 33
30 --- 34
30 --- 35
30 --- 36
30 --- 37
30 --- 38
30 --- 39
30 --- 40
30 --- 41
30 --- 42
30 --- 43
30 --- 44
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
fn cube(center) {
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
part001 = cube([0, 0])
part002 = cube([20, 10])
fullPart = union([part001, part002])

View File

@ -0,0 +1,158 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed union_cubes.kcl
---
[
{
"type": "UserDefinedFunctionCall",
"name": "cube",
"functionSourceRange": [
7,
328,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "cube",
"functionSourceRange": [
7,
328,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "UserDefinedFunctionReturn"
},
{
"labeledArgs": {
"solids": {
"value": {
"type": "Array",
"value": [
{
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
}
},
"name": "union",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
}
]

View File

@ -0,0 +1,543 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing union_cubes.kcl
---
{
"cube": {
"type": "Function"
},
"fullPart": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
-10.0
],
"tag": null,
"to": [
10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
-10.0
],
"tag": null,
"to": [
10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
10.0
],
"tag": null,
"to": [
-10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
10.0
],
"tag": null,
"to": [
-10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-10.0,
-10.0
],
"to": [
-10.0,
-10.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"part001": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
-10.0
],
"tag": null,
"to": [
10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
-10.0
],
"tag": null,
"to": [
10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
10.0
],
"tag": null,
"to": [
-10.0,
10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
-10.0,
10.0
],
"tag": null,
"to": [
-10.0,
-10.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
-10.0,
-10.0
],
"to": [
-10.0,
-10.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"part002": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
0.0
],
"tag": null,
"to": [
30.0,
0.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
30.0,
0.0
],
"tag": null,
"to": [
30.0,
20.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
30.0,
20.0
],
"tag": null,
"to": [
10.0,
20.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
10.0,
20.0
],
"tag": null,
"to": [
10.0,
0.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
}
},
"start": {
"from": [
10.0,
0.0
],
"to": [
10.0,
0.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,18 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing union_cubes.kcl
---
fn cube(center) {
return startSketchOn(XY)
|> startProfileAt([center[0] - 10, center[1] - 10], %)
|> line(endAbsolute = [center[0] + 10, center[1] - 10])
|> line(endAbsolute = [center[0] + 10, center[1] + 10])
|> line(endAbsolute = [center[0] - 10, center[1] + 10])
|> close()
|> extrude(length = 10)
}
part001 = cube([0, 0])
part002 = cube([20, 10])
fullPart = union([part001, part002])

View File

@ -0,0 +1,18 @@
# Stop the script when a cmdlet or a native command fails
# from https://www.meziantou.net/stop-the-script-when-an-error-occurs-in-powershell.htm
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
rm -Recurse -Force rust/kcl-wasm-lib/pkg
mkdir -p rust/kcl-wasm-lib/pkg
rm -Recurse -Force rust/kcl-lib/bindings
cd rust
$env:RUSTFLAGS='--cfg getrandom_backend="wasm_js"'
wasm-pack build kcl-wasm-lib --dev --target web --out-dir pkg
$env:RUSTFLAGS=''
cargo test -p kcl-lib export_bindings
cd ..
copy rust\kcl-wasm-lib\pkg\kcl_wasm_lib_bg.wasm public
yarn fmt:generated

16
scripts/build-wasm-dev.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
set -euo pipefail
rm -rf rust/kcl-wasm-lib/pkg
mkdir -p rust/kcl-wasm-lib/pkg
rm -rf rust/kcl-lib/bindings
cd rust
export RUSTFLAGS='--cfg getrandom_backend="wasm_js"'
wasm-pack build kcl-wasm-lib --dev --target web --out-dir pkg
export RUSTFLAGS=''
cargo test -p kcl-lib export_bindings
cd ..
cp rust/kcl-wasm-lib/pkg/kcl_wasm_lib_bg.wasm public
yarn fmt:generated

View File

@ -669,7 +669,7 @@ const ConstraintSymbol = ({
return Promise.reject(pResult)
const _node1 = getNodeFromPath<CallExpression | CallExpressionKw>(
pResult.program!,
pResult.program,
pathToNode,
['CallExpression', 'CallExpressionKw'],
true

View File

@ -43,8 +43,8 @@ export const INTERSECTION_PLANE_LAYER = 1
export const SKETCH_LAYER = 2
// redundant types so that it can be changed temporarily but CI will catch the wrong type
export const DEBUG_SHOW_INTERSECTION_PLANE: false = false
export const DEBUG_SHOW_BOTH_SCENES: false = false
export const DEBUG_SHOW_INTERSECTION_PLANE = false
export const DEBUG_SHOW_BOTH_SCENES = false
export const RAYCASTABLE_PLANE = 'raycastable-plane'

View File

@ -1037,7 +1037,7 @@ class ArcSegment implements SegmentUtils {
endAngle,
scale,
color: grey, // Red color for the angle indicator
}) as Line
})
angleIndicator.name = 'angleIndicator'
// Create a new angle indicator for the end angle
@ -1048,7 +1048,7 @@ class ArcSegment implements SegmentUtils {
endAngle: (endAngle * Math.PI) / 180,
scale,
color: grey, // Green color for the end angle indicator
}) as Line
})
endAngleIndicator.name = 'endAngleIndicator'
// Create a length indicator for the end angle

View File

@ -1,8 +1,7 @@
import {
IconDefinition as SolidIconDefinition,
IconDefinition,
faCircleExclamation,
} from '@fortawesome/free-solid-svg-icons'
import { IconDefinition as BrandIconDefinition } from '@fortawesome/free-brands-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { CustomIcon, CustomIconName } from './CustomIcon'
@ -14,7 +13,7 @@ const iconSizes = {
}
export interface ActionIconProps extends React.PropsWithChildren {
icon?: SolidIconDefinition | BrandIconDefinition | CustomIconName
icon?: IconDefinition | CustomIconName
iconColor?: string
className?: string
bgClassName?: string

View File

@ -98,9 +98,7 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
.map(([argName, arg], i) => {
const argValue =
(typeof argumentsToSubmit[argName] === 'function'
? (argumentsToSubmit[argName] as Function)(
commandBarState.context
)
? argumentsToSubmit[argName](commandBarState.context)
: argumentsToSubmit[argName]) || ''
return (

View File

@ -6,7 +6,7 @@ import {
getSelectionCountByType,
getSelectionTypeDisplayText,
} from 'lib/selections'
import { kclManager } from 'lib/singletons'
import { engineCommandManager, kclManager } from 'lib/singletons'
import { reportRejection } from 'lib/trap'
import { toSync } from 'lib/utils'
import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine'
@ -112,6 +112,23 @@ function CommandBarSelectionInput({
onSubmit(selection)
}
// Clear selection if needed
useEffect(() => {
arg.clearSelectionFirst &&
engineCommandManager.modelingSend({
type: 'Set selection',
data: {
selectionType: 'singleCodeCursor',
},
})
}, [arg.clearSelectionFirst])
// Set selection filter if needed, and reset it when the component unmounts
useEffect(() => {
arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter)
return () => kclManager.defaultSelectionFilter(selection)
}, [arg.selectionFilter])
return (
<form id="arg-form" onSubmit={handleSubmit}>
<label

View File

@ -7,6 +7,7 @@ import {
} from 'lib/selections'
import { useSelector } from '@xstate/react'
import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine'
import { kclManager } from 'lib/singletons'
const selectionSelector = (snapshot: any) => snapshot?.context.selectionRanges
@ -56,6 +57,12 @@ export default function CommandBarSelectionMixedInput({
}
}, [])
// Set selection filter if needed, and reset it when the component unmounts
useEffect(() => {
arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter)
return () => kclManager.defaultSelectionFilter(selection)
}, [arg.selectionFilter])
function handleChange() {
inputRef.current?.focus()
}

View File

@ -387,7 +387,7 @@ const CustomIconMap = {
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10 2.51583L10.3536 2.86938L12.3536 4.86938L11.6465 5.57649L10.5 4.43004V10.1012C11.0826 10.3071 11.5 10.8627 11.5 11.5158C11.5 12.3443 10.8284 13.0158 10 13.0158C9.17157 13.0158 8.5 12.3443 8.5 11.5158C8.5 10.8627 8.9174 10.3071 9.5 10.1012V4.43004L8.35356 5.57649L7.64645 4.86938L9.64645 2.86938L10 2.51583ZM3.95886 10.8441L8.5 8.06893V9.24088L4.91773 11.43L10 14.5359L15.0823 11.43L11.5 9.24087V8.06893L16.0411 10.8441L17 11.43L17 13.4842H16V12.0412L10.5 15.4023V17.4842H9.5V15.4023L4 12.0412V13.4842H3V11.43L3.95886 10.8441Z"
d="M10 3.29317L10.2346 3.41776L15.728 6.33576L15.9935 6.47676V6.77733V12.7391V13.0185L15.7555 13.165L10.2621 16.5456L10 16.7068L9.73796 16.5456L4.24448 13.165L4.00653 13.0185V12.7391V6.77733V6.47676L4.27198 6.33576L9.76546 3.41776L10 3.29317ZM10 4.42549L5.56039 6.78371L10 9.21124L14.4396 6.78371L10 4.42549ZM14.9935 7.62059L10.5 10.0776V15.225L14.9935 12.4597V7.62059ZM9.50001 15.225V10.0776L5.00653 7.62059V12.4597L9.50001 15.225Z"
fill="currentColor"
/>
</svg>
@ -732,7 +732,7 @@ const CustomIconMap = {
<path
fillRule="evenodd"
clipRule="evenodd"
d="M13.7954 6.22689C14.7749 5.73715 15 5.2456 15 5C15 4.7544 14.7749 4.26285 13.7954 3.77311C12.8758 3.31327 11.5353 3 10 3C8.46473 3 7.12424 3.31327 6.20457 3.77311C5.22509 4.26285 5 4.7544 5 5C5 5.2456 5.22509 5.73715 6.20457 6.22689C6.29872 6.27397 6.39728 6.3195 6.5 6.36333L6.5 7.43698C4.98593 6.89239 4 6.00376 4 5C4 3.34315 6.68629 2 10 2C13.3137 2 16 3.34315 16 5C16 6.00376 15.0141 6.89239 13.5 7.43698V6.36333C13.6027 6.3195 13.7013 6.27397 13.7954 6.22689ZM11.5 8.5531V9.72505L15.0823 11.9142L10 15.0201L4.91773 11.9142L8.5 9.72505V8.5531L3.95886 11.3282L3 11.9142V13.9683H4V12.5253L9.5 15.8864V17.9683H10.5V15.8864L16 12.5253V13.9683H17L17 11.9142L16.0411 11.3282L11.5 8.5531ZM10 4.29289L10.3536 4.64645L12.3536 6.64644L11.6465 7.35355L10.5 6.20711V10.5854C11.0826 10.7913 11.5 11.3469 11.5 12C11.5 12.8284 10.8284 13.5 10 13.5C9.17157 13.5 8.5 12.8284 8.5 12C8.5 11.3469 8.91741 10.7913 9.5 10.5854V6.20711L8.35356 7.35355L7.64645 6.64644L9.64645 4.64645L10 4.29289Z"
d="M9.9995 4.85357C9.15003 4.85357 8.32765 5.04209 7.7242 5.3905C7.11795 5.74052 6.92818 6.12938 6.92818 6.41547C6.92818 6.70156 7.11795 7.09042 7.7242 7.44044C8.32765 7.78884 9.15003 7.97737 9.9995 7.97737C10.849 7.97737 11.6714 7.78884 12.2748 7.44044C12.8811 7.09042 13.0708 6.70156 13.0708 6.41547C13.0708 6.12938 12.8811 5.74052 12.2748 5.3905C11.6714 5.04209 10.849 4.85357 9.9995 4.85357ZM9.9995 3.85357C10.978 3.85357 11.9836 4.06765 12.7748 4.52447C13.4807 4.93205 13.9615 5.50902 14.0544 6.1775L15.8813 12.0861L15.9958 12.4564L15.6656 12.6596L10.2616 15.9852L9.9995 16.1464L9.73745 15.9852L4.33339 12.6596L4.00415 12.457L4.11736 12.0873L5.96911 6.04134C6.10445 5.43072 6.56665 4.90411 7.2242 4.52447C8.01544 4.06765 9.02101 3.85357 9.9995 3.85357ZM6.49467 7.7401L5.18673 12.0105L9.4995 14.6646V8.95868C8.68544 8.8976 7.88098 8.68566 7.2242 8.30647C6.9414 8.1432 6.69474 7.95274 6.49467 7.7401ZM10.4995 8.95868V14.6646L14.8114 12.0111L13.4942 7.75085C13.2959 7.95916 13.0528 8.14595 12.7748 8.30647C12.118 8.68566 11.3136 8.8976 10.4995 8.95868Z"
fill="currentColor"
/>
</svg>
@ -1048,7 +1048,7 @@ const CustomIconMap = {
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.89927 4.693C7.36143 4.41381 7.87 4.21672 8.40842 4.10376C7.83595 4.69964 7.47 5.50199 7.47 6.31393C7.47 7.34818 8.06376 8.11443 8.9218 8.3459C8.85859 8.44278 8.80068 8.54347 8.74845 8.64757C8.69108 8.76191 8.6411 8.87927 8.59864 8.99896L9.87934 8.72674C10.0433 8.52252 10.2451 8.35006 10.4752 8.21957L10.4736 8.21676C11.6445 7.74118 12.53 6.5014 12.53 5.2384C12.53 4.20393 11.936 3.43756 11.0776 3.20628L11.0781 3.19471C9.34471 2.75461 7.64421 2.9631 6.28878 3.78191C4.93335 4.60073 4.01395 5.97492 3.69937 7.6522C3.55495 8.4222 3.54245 9.23235 3.65633 10.0495L3.88904 10L4.59283 9.85042C4.53004 9.23247 4.55179 8.62188 4.6613 8.038C4.93318 6.58836 5.7278 5.40068 6.89927 4.693ZM7.47005 15.1799C6.65634 14.4835 5.96657 13.6244 5.46142 12.6658L4.54925 12.8597L4.57626 12.9127C5.40057 14.5194 6.672 15.8914 8.18092 16.8103C8.28057 16.8945 8.38913 16.9684 8.50564 17.0308L9.08339 16.1011C8.87304 15.9884 8.70487 15.8151 8.5944 15.5972C8.48392 15.3793 8.43471 15.1238 8.45129 14.8543C8.46788 14.5848 8.54973 14.31 8.68929 14.0552C8.82885 13.8005 9.02162 13.574 9.24981 13.3967C9.47801 13.2193 9.73427 13.0969 9.99495 13.0406C10.2556 12.9843 10.5123 12.996 10.7413 13.0747C10.9608 13.15 11.1481 13.2845 11.2874 13.4665C11.7756 13.525 12.1412 13.4705 12.4217 13.3627C12.354 13.1483 12.2554 12.9503 12.128 12.7748C11.8981 12.4582 11.5819 12.225 11.2086 12.0968C11.1027 12.0605 10.9931 12.0329 10.8808 12.0141C10.6353 11.9374 10.407 11.816 10.2071 11.6571L9.0562 11.9017C9.09421 11.9513 9.13379 11.9999 9.17491 12.0473C9.2375 12.1194 9.30323 12.1884 9.37183 12.254C9.16516 12.3521 8.9652 12.4755 8.77697 12.6218C8.40494 12.9109 8.09066 13.2801 7.86313 13.6955C7.6356 14.1108 7.50216 14.5588 7.47513 14.9982C7.47137 15.0592 7.46969 15.1198 7.47005 15.1799ZM9.99038 7.3647L10 7.36268C10.8571 7.18051 11.5518 6.32252 11.5518 5.44631C11.5518 4.5701 10.8571 4.00748 10 4.18965C9.14293 4.37183 8.44815 5.22981 8.44815 6.10602C8.44815 6.9614 9.11029 7.51793 9.93915 7.37442C9.95332 7.36608 9.96757 7.35785 9.98189 7.34973L9.99038 7.3647ZM16.6 8.29822L16.1109 8.40218L14.074 8.83515V9.83515L16.1109 9.40218L16.6 9.29822V8.29822ZM7.96305 11.1341L12.037 10.2681V9.26813L7.96305 10.1341V11.1341ZM3.8891 12L5.92607 11.567V10.567L3.8891 11L3.40002 11.104V12.104L3.8891 12ZM15.4172 11.1225L15.9703 10.8085L16.0604 11.4381L16.4532 14.1827L15.5948 14.3056L15.5027 13.662L15.5423 12.9555L15.3598 13.5867C15.1404 13.9788 14.8672 14.3472 14.529 14.662C13.8137 15.3278 12.8466 15.7187 11.5898 15.635C11.3638 16.0194 10.9459 16.2774 10.4678 16.2774C9.74943 16.2774 9.16711 15.6951 9.16711 14.9767C9.16711 14.2584 9.74943 13.6761 10.4678 13.6761C11.1178 13.6761 11.6565 14.153 11.753 14.776C12.7384 14.8173 13.4355 14.4952 13.9382 14.0273C14.4048 13.5929 14.7326 13.0058 14.9513 12.384L13.4607 13.2302L13.0326 12.4761L15.4172 11.1225Z"
d="M4.97327 10C4.97327 6.80658 7.36805 4.28237 10.2454 4.28237C10.3165 4.28237 10.387 4.28406 10.4572 4.28741C10.3234 4.38231 10.1981 4.48718 10.0831 4.59971C9.66718 5.00672 9.35509 5.54523 9.28757 6.13142C9.25522 6.4123 9.28279 6.67823 9.36215 6.91776C8.7912 7.07426 8.34416 7.4985 8.05428 8.021C7.71049 8.64064 7.55775 9.44003 7.64354 10.2751C7.72936 11.1104 8.042 11.8668 8.50239 12.413C8.96051 12.9566 9.6047 13.3307 10.3298 13.2686C10.6312 13.2428 10.91 13.1468 11.1582 12.9971C11.3304 13.3048 11.6082 13.5576 11.9545 13.74C12.4863 14.0202 13.1232 14.1081 13.7186 14.0462C13.7798 14.0398 13.8412 14.0318 13.9024 14.0221C12.9641 15.0711 11.6798 15.7176 10.2454 15.7176C7.36805 15.7176 4.97327 13.1934 4.97327 10ZM10.2454 3.28237C11.2075 3.28237 12.0872 3.53636 12.8836 3.93906C12.9184 3.95564 12.9526 3.97334 12.9861 3.99218C13.5751 4.32277 13.8895 4.9548 13.8061 5.67865C13.7386 6.26484 13.4265 6.80335 13.0105 7.21036C12.5931 7.61883 12.04 7.92623 11.4392 8.0229C11.0197 8.0904 10.6153 8.04835 10.2653 7.89614L10.2521 7.89037C10.1541 7.84893 9.99432 7.83721 9.77368 7.85609C9.46998 7.88207 9.1612 8.08711 8.92871 8.50614C8.69698 8.92382 8.57054 9.51335 8.63831 10.1729C8.70605 10.8322 8.95064 11.3932 9.26703 11.7686C9.5857 12.1467 9.93784 12.2985 10.2445 12.2723C10.5632 12.245 10.8934 12.0327 11.1204 11.6221C11.1374 11.5865 11.1559 11.5513 11.1757 11.5164C11.2866 11.3214 11.438 11.1435 11.6225 10.9865C12.0767 10.6 12.6795 10.3834 13.2743 10.3216C13.8698 10.2596 14.5067 10.3475 15.0385 10.6277C15.8132 11.0358 16.2217 11.8039 15.935 12.5969C15.9205 12.6369 15.9045 12.6763 15.8868 12.7152C14.9186 15.0185 12.8217 16.7176 10.2454 16.7176C6.74706 16.7176 3.97327 13.6744 3.97327 10C3.97327 6.32561 6.74706 3.28237 10.2454 3.28237ZM12.5022 4.86738C12.4834 4.85752 12.4645 4.84778 12.4455 4.83814C12.2919 4.76722 12.0795 4.73165 11.8133 4.77448C11.4407 4.83443 11.0707 5.03242 10.7825 5.31444C10.4928 5.59793 10.3168 5.93501 10.281 6.24584C10.2381 6.61795 10.4 6.86003 10.6545 6.97486L10.6664 6.9801C10.8179 7.04538 11.0245 7.07676 11.2803 7.0356C11.653 6.97564 12.0229 6.77766 12.3111 6.49563C12.6008 6.21215 12.7768 5.87507 12.8127 5.56423C12.8526 5.21705 12.7138 4.98872 12.5022 4.86738ZM12.0511 12.0001C12.0391 12.0242 12.0267 12.0482 12.014 12.0719C11.9553 12.2043 11.9565 12.3248 11.9952 12.4311C12.0421 12.5603 12.1642 12.7202 12.4206 12.8553C12.7448 13.0261 13.1759 13.0972 13.6152 13.0515C14.055 13.0058 14.4537 12.8483 14.7224 12.6196C14.8489 12.512 14.927 12.4058 14.9718 12.3114C14.9803 12.2909 14.9888 12.2703 14.9971 12.2497C15.0698 12.0387 15.0148 11.7455 14.5723 11.5124C14.2481 11.3416 13.817 11.2705 13.3778 11.3162C12.9379 11.3619 12.5392 11.5195 12.2706 11.7481C12.1687 11.8348 12.098 11.9208 12.0511 12.0001Z"
fill="currentColor"
/>
</svg>
@ -1148,7 +1148,7 @@ const CustomIconMap = {
<path
fillRule="evenodd"
clipRule="evenodd"
d="M15.4743 3.19282L15.7063 2.49694L14.9738 2.53539L11.7806 2.703L11.833 3.70162L12.2189 3.68137L13.0309 3.47351L12.4065 3.79549C11.5985 4.23813 10.7423 4.7732 10.0381 5.41523C9.28624 6.1008 8.66584 6.94665 8.50598 7.97341C8.36948 8.8502 8.57961 9.78564 9.20597 10.7756C9.07507 10.9983 9 11.2577 9 11.5347C9 12.3631 9.67157 13.0347 10.5 13.0347C11.3284 13.0347 12 12.3631 12 11.5347C12 10.7063 11.3284 10.0347 10.5 10.0347C10.3174 10.0347 10.1425 10.0673 9.98067 10.127C9.51409 9.34655 9.40701 8.68651 9.49408 8.12725C9.60506 7.41442 10.0472 6.76028 10.7119 6.15418C11.3749 5.54964 12.218 5.03092 13.0491 4.58458C13.4267 4.38176 13.797 4.19644 14.1426 4.02567L13.5257 5.87659L14.4743 6.19282L15.4743 3.19282ZM10.4854 8.10284C10.4627 8.2645 10.4579 8.44276 10.4848 8.63934L15.0823 11.4489L10 14.5548L4.91773 11.4489L7.66526 9.76987C7.56422 9.41819 7.50187 9.06536 7.47765 8.71258L3.95886 10.8629L3 11.4489V13.5031H4V12.06L9.5 15.4211V17.5031H10.5V15.4211L16 12.06V13.5031H17L17 11.4489L16.0411 10.8629L10.6351 7.55929C10.5598 7.74567 10.5101 7.92698 10.4854 8.10284Z"
d="M13.2244 5.21542C12.7054 5.21541 12.2135 5.33116 11.8622 5.53399C11.5544 5.7117 11.4656 5.8865 11.4482 5.98748L11.4492 6.07746C11.469 6.18657 11.5595 6.35486 11.8622 6.5296C12.2135 6.73243 12.7054 6.84817 13.2244 6.84817C13.7434 6.84817 14.2354 6.73243 14.5867 6.5296C14.8973 6.35026 14.9846 6.17771 15.0011 6.06896V5.98963C14.9845 5.88898 14.8967 5.71296 14.5867 5.53399C14.2354 5.33116 13.7434 5.21542 13.2244 5.21542ZM16.0011 6.13177C16.0065 6.06023 16.0059 5.98711 15.9988 5.91256C15.9489 5.38456 15.5851 4.95575 15.0867 4.66796C14.5476 4.35671 13.8725 4.21542 13.2244 4.21542C12.5764 4.21541 11.9013 4.35671 11.3622 4.66796C10.8637 4.95575 10.4999 5.38455 10.45 5.91255C10.4421 5.99636 10.4424 6.07837 10.4501 6.15834L10.4658 7.50046L7.9749 6.14153L7.96667 6.13704L7.95828 6.13286C6.85997 5.58608 5.83833 5.76171 5.10363 6.3622C4.39705 6.9397 3.99599 7.87502 3.99599 8.80303V13.9334C3.97948 14.5257 4.3658 15.0159 4.91332 15.332C5.45242 15.6433 6.12752 15.7846 6.77554 15.7846C7.42356 15.7846 8.09866 15.6433 8.63776 15.332C9.18527 15.0159 9.57161 14.5257 9.55509 13.9334L9.5551 12.8862L11.8715 14.1386L11.8813 14.1439L11.8914 14.1488C13.0016 14.6864 14.036 14.6066 14.8049 14.1168C15.5567 13.6378 16.0011 12.7977 16.0011 11.9264L16.0011 6.13177ZM15.0011 7.44303C14.4771 7.72126 13.8386 7.84817 13.2244 7.84817C12.6171 7.84817 11.986 7.72406 11.4653 7.45225L11.4757 8.34239L11.4758 8.35085L11.4756 8.35932L11.4477 9.62112L10.4479 9.59897L10.4692 8.64142L7.50456 7.02407C6.75157 6.65229 6.15623 6.7934 5.73647 7.13648C5.28711 7.50376 4.99599 8.1415 4.99599 8.80303V13.9411V13.95L4.99568 13.9588C4.99232 14.0538 5.04963 14.256 5.41332 14.466C5.76463 14.6688 6.25654 14.7846 6.77554 14.7846C7.29453 14.7846 7.78644 14.6688 8.13776 14.466C8.50145 14.256 8.55877 14.0538 8.55541 13.9588L8.55509 13.95V13.9411L8.5551 12.3442L7.78422 11.9237L8.26314 11.0458L9.29291 11.6076L9.29456 11.6085L12.337 13.2535C13.1716 13.6544 13.8297 13.5524 14.2676 13.2734C14.7242 12.9825 15.0011 12.4644 15.0011 11.9264L15.0011 7.44303Z"
fill="currentColor"
/>
</svg>

View File

@ -517,10 +517,7 @@ interface FileTreeProps {
className?: string
file?: IndexLoaderData['file']
onNavigateToFile: (
focusableElement?:
| HTMLElement
| React.MutableRefObject<HTMLElement | null>
| undefined
focusableElement?: HTMLElement | React.MutableRefObject<HTMLElement | null>
) => void
}

View File

@ -1431,7 +1431,6 @@ export const ModelingMachineProvider = ({
parsed = pResult.program
if (trap(parsed)) return Promise.reject(parsed)
parsed = parsed as Node<Program>
if (!result.pathToReplaced)
return Promise.reject(new Error('No path to replaced node'))
const {

View File

@ -8,9 +8,9 @@ export const NODE_ENV = env.NODE_ENV as string | undefined
export const VITE_KC_API_WS_MODELING_URL = env.VITE_KC_API_WS_MODELING_URL as
| string
| undefined
export const VITE_KC_API_BASE_URL = env.VITE_KC_API_BASE_URL as string
export const VITE_KC_SITE_BASE_URL = env.VITE_KC_SITE_BASE_URL as string
export const VITE_KC_SITE_APP_URL = env.VITE_KC_SITE_APP_URL as string
export const VITE_KC_API_BASE_URL = env.VITE_KC_API_BASE_URL
export const VITE_KC_SITE_BASE_URL = env.VITE_KC_SITE_BASE_URL
export const VITE_KC_SITE_APP_URL = env.VITE_KC_SITE_APP_URL
export const VITE_KC_SKIP_AUTH = env.VITE_KC_SKIP_AUTH as string | undefined
export const VITE_KC_CONNECTION_TIMEOUT_MS =
env.VITE_KC_CONNECTION_TIMEOUT_MS as string | undefined

View File

@ -0,0 +1,338 @@
import { Node } from '@rust/kcl-lib/bindings/Node'
import EditorManager from 'editor/manager'
import CodeManager from 'lang/codeManager'
import { KclManager } from 'lang/KclSingleton'
import { updateModelingState } from 'lang/modelingWorkflows'
import {
createArrayExpression,
createCallExpressionStdLibKw,
createLabeledArg,
createLocalName,
createVariableDeclaration,
findUniqueName,
} from 'lang/modifyAst'
import { getNodeFromPath } from 'lang/queryAst'
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
import { getFaceCodeRef } from 'lang/std/artifactGraph'
import { EngineCommandManager } from 'lang/std/engineConnection'
import {
Artifact,
ArtifactGraph,
Program,
VariableDeclaration,
} from 'lang/wasm'
import { EXECUTION_TYPE_REAL } from 'lib/constants'
import { Selection, Selections } from 'lib/selections'
import { err } from 'lib/trap'
import { isArray } from 'lib/utils'
export async function applySubtractFromTargetOperatorSelections(
target: Selection,
tool: Selection,
dependencies: {
kclManager: KclManager
engineCommandManager: EngineCommandManager
codeManager: CodeManager
editorManager: EditorManager
}
): Promise<Error | void> {
const ast = dependencies.kclManager.ast
if (!target.artifact || !tool.artifact) {
return new Error('No artifact found')
}
const orderedChildrenTarget = findAllChildrenAndOrderByPlaceInCode(
target.artifact,
dependencies.engineCommandManager.artifactGraph
)
const orderedChildrenTool = findAllChildrenAndOrderByPlaceInCode(
tool.artifact,
dependencies.engineCommandManager.artifactGraph
)
const lastVarTarget = getLastVariable(orderedChildrenTarget, ast)
const lastVarTool = getLastVariable(orderedChildrenTool, ast)
if (!lastVarTarget || !lastVarTool) {
return new Error('No variable found')
}
const modifiedAst = booleanSubtractAstMod({
ast,
targets: [lastVarTarget?.variableDeclaration?.node],
tools: [lastVarTool?.variableDeclaration.node],
})
await updateModelingState(modifiedAst, EXECUTION_TYPE_REAL, dependencies)
}
export async function applyUnionFromTargetOperatorSelections(
solids: Selections,
dependencies: {
kclManager: KclManager
engineCommandManager: EngineCommandManager
codeManager: CodeManager
editorManager: EditorManager
}
): Promise<Error | void> {
const ast = dependencies.kclManager.ast
const artifacts: Artifact[] = []
for (const selection of solids.graphSelections) {
if (selection.artifact) {
artifacts.push(selection.artifact)
}
}
if (artifacts.length < 2) {
return new Error('Not enough artifacts selected')
}
const orderedChildrenEach = artifacts.map((artifact) =>
findAllChildrenAndOrderByPlaceInCode(
artifact,
dependencies.engineCommandManager.artifactGraph
)
)
const lastVars: VariableDeclaration[] = []
for (const orderedArtifactLeafs of orderedChildrenEach) {
const lastVar = getLastVariable(orderedArtifactLeafs, ast)
if (!lastVar) continue
lastVars.push(lastVar.variableDeclaration.node)
}
if (lastVars.length < 2) {
return new Error('Not enough variables found')
}
const modifiedAst = booleanUnionAstMod({
ast,
solids: lastVars,
})
await updateModelingState(modifiedAst, EXECUTION_TYPE_REAL, dependencies)
}
export async function applyIntersectFromTargetOperatorSelections(
solids: Selections,
dependencies: {
kclManager: KclManager
engineCommandManager: EngineCommandManager
codeManager: CodeManager
editorManager: EditorManager
}
): Promise<Error | void> {
const ast = dependencies.kclManager.ast
const artifacts: Artifact[] = []
for (const selection of solids.graphSelections) {
if (selection.artifact) {
artifacts.push(selection.artifact)
}
}
if (artifacts.length < 2) {
return new Error('Not enough artifacts selected')
}
const orderedChildrenEach = artifacts.map((artifact) =>
findAllChildrenAndOrderByPlaceInCode(
artifact,
dependencies.engineCommandManager.artifactGraph
)
)
const lastVars: VariableDeclaration[] = []
for (const orderedArtifactLeafs of orderedChildrenEach) {
const lastVar = getLastVariable(orderedArtifactLeafs, ast)
if (!lastVar) continue
lastVars.push(lastVar.variableDeclaration.node)
}
if (lastVars.length < 2) {
return new Error('Not enough variables found')
}
const modifiedAst = booleanIntersectAstMod({
ast,
solids: lastVars,
})
await updateModelingState(modifiedAst, EXECUTION_TYPE_REAL, dependencies)
}
/** returns all children of a given artifact, and sorts them DESC by start sourceRange
* The usecase is we want the last declare relevant child to use in the boolean operations
* but might be useful else where.
*/
export function findAllChildrenAndOrderByPlaceInCode(
artifact: Artifact,
artifactGraph: ArtifactGraph
): Artifact[] {
const result: string[] = []
const stack: string[] = [artifact.id]
const getArtifacts = (stringIds: string[]): Artifact[] => {
const artifactsWithCodeRefs: Artifact[] = []
for (const id of stringIds) {
const artifact = artifactGraph.get(id)
if (artifact) {
const codeRef = getFaceCodeRef(artifact)
if (codeRef && codeRef.range[1] > 0) {
artifactsWithCodeRefs.push(artifact)
}
}
}
return artifactsWithCodeRefs
}
const pushToSomething = (
resultId: string,
childrenIdOrIds: null | string | string[]
) => {
if (isArray(childrenIdOrIds)) {
if (childrenIdOrIds.length) {
stack.push(...childrenIdOrIds)
result.push(resultId)
} else {
}
} else {
if (childrenIdOrIds) {
stack.push(childrenIdOrIds)
result.push(resultId)
} else {
}
}
}
while (stack.length > 0) {
const currentId = stack.pop()!
const current = artifactGraph.get(currentId)
if (current?.type === 'path') {
pushToSomething(currentId, current?.sweepId)
pushToSomething(currentId, current?.segIds)
} else if (current?.type === 'sweep') {
pushToSomething(currentId, current?.surfaceIds)
} else if (current?.type === 'wall' || current?.type === 'cap') {
pushToSomething(currentId, current?.pathIds)
} else if (current?.type === 'segment') {
pushToSomething(currentId, current?.edgeCutId)
pushToSomething(currentId, current?.surfaceId)
} else if (current?.type === 'edgeCut') {
pushToSomething(currentId, current?.surfaceId)
} else if (current?.type === 'startSketchOnPlane') {
pushToSomething(currentId, current?.planeId)
} else if (current?.type === 'plane') {
pushToSomething(currentId, current.pathIds)
}
}
const codeRefArtifacts = getArtifacts(result)
const orderedByCodeRefDest = codeRefArtifacts.sort((a, b) => {
const aCodeRef = getFaceCodeRef(a)
const bCodeRef = getFaceCodeRef(b)
if (!aCodeRef || !bCodeRef) {
return 0
}
return bCodeRef.range[0] - aCodeRef.range[0]
})
return orderedByCodeRefDest
}
/** Returns the last declared in code, relevant child */
export function getLastVariable(
orderedDescArtifacts: Artifact[],
ast: Node<Program>
) {
for (const artifact of orderedDescArtifacts) {
const codeRef = getFaceCodeRef(artifact)
if (codeRef) {
const pathToNode = getNodePathFromSourceRange(ast, codeRef.range)
const varDec = getNodeFromPath<VariableDeclaration>(
ast,
pathToNode,
'VariableDeclaration'
)
if (!err(varDec)) {
return {
variableDeclaration: varDec,
pathToNode: pathToNode,
artifact,
}
}
}
}
return null
}
export function booleanSubtractAstMod({
ast,
targets,
tools,
}: {
ast: Node<Program>
targets: VariableDeclaration[]
tools: VariableDeclaration[]
}): Node<Program> {
const newAst = structuredClone(ast)
const newVarName = findUniqueName(newAst, 'solid')
const createArrExpr = (varDecs: VariableDeclaration[]) =>
createArrayExpression(
varDecs.map((varDec) => createLocalName(varDec.declaration.id.name))
)
const targetsArrayExpression = createArrExpr(targets)
const toolsArrayExpression = createArrExpr(tools)
const newVarDec = createVariableDeclaration(
newVarName,
createCallExpressionStdLibKw('subtract', targetsArrayExpression, [
createLabeledArg('tools', toolsArrayExpression),
])
)
newAst.body.push(newVarDec)
return newAst
}
export function booleanUnionAstMod({
ast,
solids,
}: {
ast: Node<Program>
solids: VariableDeclaration[]
}): Node<Program> {
const newAst = structuredClone(ast)
const newVarName = findUniqueName(newAst, 'solid')
const createArrExpr = (varDecs: VariableDeclaration[]) =>
createArrayExpression(
varDecs.map((varDec) => createLocalName(varDec.declaration.id.name))
)
const solidsArrayExpression = createArrExpr(solids)
const newVarDec = createVariableDeclaration(
newVarName,
createCallExpressionStdLibKw('union', solidsArrayExpression, [])
)
newAst.body.push(newVarDec)
return newAst
}
export function booleanIntersectAstMod({
ast,
solids,
}: {
ast: Node<Program>
solids: VariableDeclaration[]
}): Node<Program> {
const newAst = structuredClone(ast)
const newVarName = findUniqueName(newAst, 'solid')
const createArrExpr = (varDecs: VariableDeclaration[]) =>
createArrayExpression(
varDecs.map((varDec) => createLocalName(varDec.declaration.id.name))
)
const solidsArrayExpression = createArrExpr(solids)
const newVarDec = createVariableDeclaration(
newVarName,
createCallExpressionStdLibKw('intersect', solidsArrayExpression, [])
)
newAst.body.push(newVarDec)
return newAst
}

View File

@ -23,6 +23,8 @@ import {
import { getVariableDeclaration } from 'lang/queryAst/getVariableDeclaration'
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
import { getNodeFromPath } from 'lang/queryAst'
import { IS_NIGHTLY_OR_DEBUG } from 'routes/Settings'
import { DEV } from 'env'
type OutputFormat = Models['OutputFormat3d_type']
type OutputTypeKey = OutputFormat['type']
@ -153,6 +155,16 @@ export type ModelingCommandSchema = {
nodeToEdit?: PathToNode
color: string
}
'Boolean Subtract': {
target: Selections
tool: Selections
}
'Boolean Union': {
solids: Selections
}
'Boolean Intersect': {
solids: Selections
}
}
export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
@ -328,7 +340,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
defaultValue: (commandBarContext) => {
return Object.values(
commandBarContext.machineManager.machines || []
)[0] as components['schemas']['MachineInfoResponse']
)[0]
},
},
},
@ -507,6 +519,67 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
},
},
},
'Boolean Subtract': {
hide: DEV || IS_NIGHTLY_OR_DEBUG ? undefined : 'both',
description: 'Subtract one solid from another.',
icon: 'booleanSubtract',
needsReview: true,
args: {
target: {
inputType: 'selection',
selectionTypes: ['path'],
selectionFilter: ['object'],
multiple: false,
required: true,
skip: true,
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
},
tool: {
clearSelectionFirst: true,
inputType: 'selection',
selectionTypes: ['path'],
selectionFilter: ['object'],
multiple: false,
required: true,
skip: false,
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
},
},
},
'Boolean Union': {
hide: DEV || IS_NIGHTLY_OR_DEBUG ? undefined : 'both',
description: 'Union multiple solids into a single solid.',
icon: 'booleanUnion',
needsReview: true,
args: {
solids: {
inputType: 'selection',
selectionTypes: ['path'],
selectionFilter: ['object'],
multiple: true,
required: true,
skip: false,
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
},
},
},
'Boolean Intersect': {
hide: DEV || IS_NIGHTLY_OR_DEBUG ? undefined : 'both',
description: 'Subtract one solid from another.',
icon: 'booleanIntersect',
needsReview: true,
args: {
solids: {
inputType: 'selectionMixed',
selectionTypes: ['path'],
selectionFilter: ['object'],
multiple: true,
required: true,
skip: false,
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
},
},
},
'Offset plane': {
description: 'Offset a plane.',
icon: 'plane',
@ -608,9 +681,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
inputType: 'kcl',
defaultValue: KCL_DEFAULT_LENGTH,
required: (commandContext) =>
!['Cylinder'].includes(
commandContext.argumentsToSubmit.mode as string
),
['Axis'].includes(commandContext.argumentsToSubmit.mode as string),
},
ccw: {
inputType: 'options',
@ -940,3 +1011,5 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
},
},
}
modelingMachineCommandConfig

View File

@ -74,8 +74,8 @@ export const projectsCommandBarConfig: StateMachineCommandSetConfig<
required: true,
options: (_, context) =>
context?.projects.map((p) => ({
name: p.name!,
value: p.name!,
name: p.name,
value: p.name,
})) || [],
},
},
@ -91,8 +91,8 @@ export const projectsCommandBarConfig: StateMachineCommandSetConfig<
required: true,
options: (_, context) =>
context?.projects.map((p) => ({
name: p.name!,
value: p.name!,
name: p.name,
value: p.name,
})) || [],
},
newName: {
@ -136,8 +136,8 @@ export const projectsCommandBarConfig: StateMachineCommandSetConfig<
skip: true,
options: (_, context) =>
context?.projects.map((p) => ({
name: p.name!,
value: p.name!,
name: p.name,
value: p.name,
})) || [],
},
name: {

View File

@ -1,14 +1,14 @@
import { CustomIconName } from 'components/CustomIcon'
import { AllMachines } from 'hooks/useStateMachineCommands'
import { Actor, AnyStateMachine, ContextFrom, EventFrom } from 'xstate'
import { Expr, VariableDeclaration } from 'lang/wasm'
import { Expr, Name, VariableDeclaration } from 'lang/wasm'
import { commandBarMachine } from 'machines/commandBarMachine'
import { ReactNode } from 'react'
import { MachineManager } from 'components/MachineManagerProvider'
import { Node } from '@rust/kcl-lib/bindings/Node'
import { Artifact } from 'lang/std/artifactGraph'
import { CommandBarContext } from 'machines/commandBarMachine'
import { Name } from '@rust/kcl-lib/bindings/Name'
import { EntityType_type } from '@kittycad/lib/dist/types/src/models'
type Icon = CustomIconName
const _PLATFORMS = ['both', 'web', 'desktop'] as const
@ -160,6 +160,8 @@ export type CommandArgumentConfig<
| {
inputType: 'selection'
selectionTypes: Artifact['type'][]
clearSelectionFirst?: boolean
selectionFilter?: EntityType_type[]
multiple: boolean
validation?: ({
data,
@ -172,6 +174,7 @@ export type CommandArgumentConfig<
| {
inputType: 'selectionMixed'
selectionTypes: Artifact['type'][]
selectionFilter?: EntityType_type[]
multiple: boolean
allowNoSelection?: boolean
validation?: ({
@ -281,6 +284,8 @@ export type CommandArgument<
| {
inputType: 'selection'
selectionTypes: Artifact['type'][]
clearSelectionFirst?: boolean
selectionFilter?: EntityType_type[]
multiple: boolean
validation?: ({
data,
@ -293,6 +298,7 @@ export type CommandArgument<
| {
inputType: 'selectionMixed'
selectionTypes: Artifact['type'][]
selectionFilter?: EntityType_type[]
multiple: boolean
allowNoSelection?: boolean
validation?: ({

View File

@ -28,7 +28,7 @@ export const FILE_EXT = '.kcl'
/** Default file to open when a project is opened */
export const PROJECT_ENTRYPOINT = `main${FILE_EXT}` as const
/** Thumbnail file name */
export const PROJECT_IMAGE_NAME = `thumbnail.png` as const
export const PROJECT_IMAGE_NAME = `thumbnail.png`
/** The localStorage key for last-opened projects */
export const FILE_PERSIST_KEY = `${PROJECT_FOLDER}-last-opened` as const
/** The default name given to new kcl files in a project */
@ -169,11 +169,11 @@ export const ZOO_STUDIO_PROTOCOL = 'zoo-studio'
export const ASK_TO_OPEN_QUERY_PARAM = 'ask-open-desktop'
/** Real execution. */
export const EXECUTION_TYPE_REAL = 'real' as const
export const EXECUTION_TYPE_REAL = 'real'
/** Mock execution. */
export const EXECUTION_TYPE_MOCK = 'mock' as const
export const EXECUTION_TYPE_MOCK = 'mock'
/** No execution. */
export const EXECUTION_TYPE_NONE = 'none' as const
export const EXECUTION_TYPE_NONE = 'none'
/**
* Enum of engine execution kinds.
*/

View File

@ -188,6 +188,8 @@ export function buildCommandArgument<
multiple: arg.multiple,
selectionTypes: arg.selectionTypes,
validation: arg.validation,
clearSelectionFirst: arg.clearSelectionFirst,
selectionFilter: arg.selectionFilter,
} satisfies CommandArgument<O, T> & { inputType: 'selection' }
} else if (arg.inputType === 'selectionMixed') {
return {
@ -198,6 +200,7 @@ export function buildCommandArgument<
validation: arg.validation,
allowNoSelection: arg.allowNoSelection,
selectionSource: arg.selectionSource,
selectionFilter: arg.selectionFilter,
} satisfies CommandArgument<O, T> & { inputType: 'selectionMixed' }
} else if (arg.inputType === 'kcl') {
return {

View File

@ -757,7 +757,9 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => {
} else {
return { reason: "Couldn't find radius argument" }
}
}
if (mode === 'Axis') {
if ('length' in operation.labeledArgs && operation.labeledArgs.length) {
const r = await stringToKclExpression(
codeManager.code.slice(
@ -847,6 +849,10 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
label: 'Import',
icon: 'import',
},
intersect: {
label: 'Intersect',
icon: 'booleanIntersect',
},
loft: {
label: 'Loft',
icon: 'loft',
@ -903,12 +909,20 @@ export const stdLibMap: Record<string, StdLibCallInfo> = {
}
},
},
subtract: {
label: 'Subtract',
icon: 'booleanSubtract',
},
sweep: {
label: 'Sweep',
icon: 'sweep',
prepareToEdit: prepareToEditSweep,
supportsAppearance: true,
},
union: {
label: 'Union',
icon: 'booleanUnion',
},
}
/**

View File

@ -23,7 +23,7 @@ type OnboardingPaths = {
[K in keyof typeof onboardingPaths]: `/onboarding${(typeof onboardingPaths)[K]}`
}
const SETTINGS = '/settings' as const
const SETTINGS = '/settings'
export type ProjectRoute = {
projectName: string | null

View File

@ -12,6 +12,7 @@ import {
defaultSourceRange,
topLevelRange,
ArtifactGraph,
CallExpressionKw,
} from 'lang/wasm'
import { ModelingMachineEvent } from 'machines/modelingMachine'
import { isNonNullable, uuidv4 } from 'lib/utils'
@ -337,7 +338,7 @@ function updateSceneObjectColors(codeBasedSelections: Selection[]) {
Object.values(sceneEntitiesManager.activeSegments).forEach((segmentGroup) => {
if (!SEGMENT_BODIES_PLUS_PROFILE_START.includes(segmentGroup?.name)) return
const nodeMeta = getNodeFromPath<Node<CallExpression | CallExpression>>(
const nodeMeta = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
updated,
segmentGroup.userData.pathToNode,
['CallExpression', 'CallExpressionKw']
@ -716,7 +717,7 @@ export function updateSelections(
},
}
})
.filter((x?: Selection) => x !== undefined) as Selection[]
.filter((x?: Selection) => x !== undefined)
// for when there is no artifact (sketch mode since mock execute does not update artifactGraph)
const pathToNodeBasedSelections: Selections['graphSelections'] = []

View File

@ -302,7 +302,7 @@ export function createSettings() {
defaultUnit: new Setting<BaseUnit>({
defaultValue: 'mm',
description: 'The default unit to use in modeling dimensions',
validate: (v) => baseUnitsUnion.includes(v as BaseUnit),
validate: (v) => baseUnitsUnion.includes(v),
commandConfig: {
inputType: 'options',
defaultValueFromContext: (context) =>
@ -332,7 +332,7 @@ export function createSettings() {
mouseControls: new Setting<CameraSystem>({
defaultValue: 'Zoo',
description: 'The controls for how to navigate the 3D view',
validate: (v) => cameraSystems.includes(v as CameraSystem),
validate: (v) => cameraSystems.includes(v),
hideOnLevel: 'project',
commandConfig: {
inputType: 'options',

View File

@ -101,27 +101,6 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
description: 'Pull a sketch into 3D along its normal or perpendicular.',
links: [{ label: 'KCL docs', url: 'https://zoo.dev/docs/kcl/extrude' }],
},
{
id: 'revolve',
onClick: () =>
commandBarActor.send({
type: 'Find and select command',
data: { name: 'Revolve', groupId: 'modeling' },
}),
icon: 'revolve',
status: 'available',
title: 'Revolve',
hotkey: 'R',
description:
'Create a 3D body by rotating a sketch region about an axis.',
links: [
{ label: 'KCL docs', url: 'https://zoo.dev/docs/kcl/revolve' },
{
label: 'KCL example',
url: 'https://zoo.dev/docs/kcl-samples/ball-bearing',
},
],
},
{
id: 'sweep',
onClick: () =>
@ -162,6 +141,27 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
},
],
},
{
id: 'revolve',
onClick: () =>
commandBarActor.send({
type: 'Find and select command',
data: { name: 'Revolve', groupId: 'modeling' },
}),
icon: 'revolve',
status: 'available',
title: 'Revolve',
hotkey: 'R',
description:
'Create a 3D body by rotating a sketch region about an axis.',
links: [
{ label: 'KCL docs', url: 'https://zoo.dev/docs/kcl/revolve' },
{
label: 'KCL example',
url: 'https://zoo.dev/docs/kcl-samples/ball-bearing',
},
],
},
'break',
{
id: 'fillet3d',
@ -209,9 +209,13 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
[
{
id: 'boolean-union',
onClick: () => console.error('Boolean union not yet implemented'),
onClick: () =>
commandBarActor.send({
type: 'Find and select command',
data: { name: 'Boolean Union', groupId: 'modeling' },
}),
icon: 'booleanUnion',
status: 'unavailable',
status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'unavailable',
title: 'Union',
hotkey: 'Shift + B U',
description: 'Combine two or more solids into a single solid.',
@ -224,9 +228,13 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
},
{
id: 'boolean-subtract',
onClick: () => console.error('Boolean subtract not yet implemented'),
onClick: () =>
commandBarActor.send({
type: 'Find and select command',
data: { name: 'Boolean Subtract', groupId: 'modeling' },
}),
icon: 'booleanSubtract',
status: 'unavailable',
status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'unavailable',
title: 'Subtract',
hotkey: 'Shift + B S',
description: 'Subtract one solid from another.',
@ -239,9 +247,13 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
},
{
id: 'boolean-intersect',
onClick: () => console.error('Boolean intersect not yet implemented'),
onClick: () =>
commandBarActor.send({
type: 'Find and select command',
data: { name: 'Boolean Intersect', groupId: 'modeling' },
}),
icon: 'booleanIntersect',
status: 'unavailable',
status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'unavailable',
title: 'Intersect',
hotkey: 'Shift + B I',
description: 'Create a solid from the intersection of two solids.',
@ -295,7 +307,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
},
hotkey: 'H',
icon: 'helix',
status: DEV || IS_NIGHTLY_OR_DEBUG ? 'available' : 'kcl-only',
status: 'available',
title: 'Helix',
description: 'Create a helix or spiral in 3D about an axis.',
links: [{ label: 'KCL docs', url: 'https://zoo.dev/docs/kcl/helix' }],

View File

@ -17,7 +17,7 @@ export function usePreviousVarMentions(context: CompletionContext) {
return null
}
return {
from: word?.from!,
from: word?.from,
options: [...data],
}
}

View File

@ -17,7 +17,7 @@ export function varMentions(data: Completion[] = []): Extension {
return null
}
return {
from: word?.from!,
from: word?.from,
options: [...data],
}
},

File diff suppressed because one or more lines are too long

View File

@ -146,7 +146,7 @@ export const settingsMachine = setup({
actor: input.actor,
})
)
.filter((c) => c !== null) as Command[]
.filter((c) => c !== null)
const addCommands = () =>
commandBarActor.send({
type: 'Add commands',