Compare commits

...

17 Commits

Author SHA1 Message Date
cac7aa2bee Optionally chain error_code
Something in the Chamfer E2E tests is complaining about an uncaught
error with `error_code` trying to be referenced on something that is
`undefined`. That means that an API request is coming back as not
successful but does not have an actual error in the body of the
response.
2025-05-20 19:24:55 -04:00
0753987b5a [Fix]: Allow importing assemblies into exsiting projects and handling the collision (#7108)
* fix: saving off code

* fix: saving off progress

* chore: implemented kcl sample assembly unique sub dir creation

* fix: removing testing console logs

* fix: cleaning up old comment

* fix: add to file always does subdir/main.kcl now for single files

* fix: auto fmt

* fix: delete project and folder from ttc

* fix: fixed deleting projects and subdirs

* fix: if statement logic fixed for deleting project or subdir

* fix: TTC isProjectNew makes main.kcl not a subdir.

* fix: fixing e2e test

* fix: this should pass now
2025-05-20 19:03:54 -04:00
815ff7dc2b more subtract regression tests (#7123)
* more regression tests

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

* snaps

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

* iupdates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-05-20 16:02:44 -07:00
46684d420d Test nested imports on all platforms (#7126) 2025-05-20 18:45:04 -04:00
eca09984a3 Fix: Follow up Text-to-CAD Edit to fix in browser (#7124)
* fix: web vs desktop who wins

* fix: fixed logic round two :(
2025-05-20 21:11:31 +00:00
ce63c6423e Impove naming in point-and-click Revolve to convey that axis are relative (#7122)
* Better axis options in point-and-click Revolve to convey the axis are relative
Fixes #7121

* Less changes
2025-05-20 16:57:55 -04:00
09699afe82 Fix: Can't go back to Profiles arg in Extrude, Revolve, Loft (#7106)
* Revert "Update failing E2E tests with new behavior, which allows skip with preselection"

This reverts commit d72bee8637.

* Fix: Can't go back to Profiles step in sweep commands
Fixes #7080

* Make it better but still not quite there

* I think I got it: this was likely the real bug making submit fire twice

* Bring timemouts back
2025-05-20 20:07:56 +00:00
36c8ad439d KCL: Add diameter arg to circle (#7116)
Paul's been requesting this for a long time. Now that we're fully using keyword args, this is easy to do.

We should probably add a similar `diameter` arg to `arc`, `tangentialArc`, `polygon` etc. And _maybe_ to `fillet`, but that might not be as helpful.
2025-05-20 19:44:35 +00:00
5dc77ceed5 Only start saving camera after scene is ready (#7120) 2025-05-20 15:12:08 -04:00
c7baa26b2d idiomatic kcl for hip sample (#7095)
* idiomatic kcl for hip sample

* Update kcl-samples simulation test output

* updates

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
2025-05-20 11:36:08 -07:00
4d0454abcd Remove old ZMA logos, rip out JS theme state from open-in-desktop view (#7119)
* Remove old ZMA logos, rip out JS theme state from open-in-desktop view

Make this page dumber so that it doesn't break

* Lint and remove kcma refs

---------

Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2025-05-20 18:13:58 +00:00
1dafbf105e Identify distinct test suites (#7109) 2025-05-20 12:56:55 -04:00
773f013115 [Fix]: When loading the modeling page the user's settings for camera projection was ignored (#7111)
* fix: initialization of user camera projection is now used again, ope

* fix: removing comment
2025-05-20 12:46:53 -04:00
c5cd460595 Show error when trying to export at non-top-level (#7110) 2025-05-20 12:43:11 -04:00
845352046b Modeling machine unit tests (#7098)
* successfully transition to sketch idle

* get constraint to mod code

* clean up

* remove .only

* Fixed tsc

---------

Co-authored-by: lee-at-zoo-corp <lee@zoo.dev>
2025-05-20 12:22:52 -04:00
597f1087f9 Fix enter key loop in sweep commands (#7112)
* use effect for focus of command palette submit button, not autoFocus

autoFocus is being overridden by the Headless UI Dialog component's
focus management here
https://headlessui.com/v1/react/dialog#focus-management (we do not have
access to pass back initialFocus in this case). So we can use an effect
to imperatively focus the button when this component is mounted.

* Update sweep tests to submit the command with Enter
2025-05-20 16:04:56 +00:00
511334683a test: Add regression test for importing only at the top level (#7104)
Add regression test for importing only at the top level
2025-05-20 11:43:48 -04:00
86 changed files with 10209 additions and 3838 deletions

View File

@ -6,6 +6,7 @@ if [ -z "${TAB_API_URL:-}" ] || [ -z "${TAB_API_KEY:-}" ]; then
fi fi
project="https://github.com/KittyCAD/modeling-app" project="https://github.com/KittyCAD/modeling-app"
suite="${CI_SUITE:-unit}"
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}" branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}" commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
@ -13,6 +14,7 @@ echo "Uploading batch results"
curl --silent --request POST \ curl --silent --request POST \
--header "X-API-Key: ${TAB_API_KEY}" \ --header "X-API-Key: ${TAB_API_KEY}" \
--form "project=${project}" \ --form "project=${project}" \
--form "suite=${suite}" \
--form "branch=${branch}" \ --form "branch=${branch}" \
--form "commit=${commit}" \ --form "commit=${commit}" \
--form "tests=@test-results/junit.xml" \ --form "tests=@test-results/junit.xml" \

View File

@ -193,6 +193,7 @@ jobs:
TAB_API_KEY: ${{ secrets.TAB_API_KEY }} TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }} CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: unit:kcl
run-internal-kcl-samples: run-internal-kcl-samples:
name: cargo test (internal-kcl-samples) name: cargo test (internal-kcl-samples)
runs-on: runs-on:

View File

@ -156,6 +156,7 @@ jobs:
TAB_API_KEY: ${{ secrets.TAB_API_KEY }} TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }} CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: snapshots
TARGET: web TARGET: web
- name: Update snapshots - name: Update snapshots
@ -167,6 +168,7 @@ jobs:
TAB_API_KEY: ${{ secrets.TAB_API_KEY }} TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CI_PR_NUMBER: ${{ github.event.pull_request.number }} CI_PR_NUMBER: ${{ github.event.pull_request.number }}
CI_SUITE: snapshots
TARGET: web TARGET: web
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4

View File

@ -11,7 +11,8 @@ layout: manual
circle( circle(
@sketch_or_surface: Sketch | Plane | Face, @sketch_or_surface: Sketch | Plane | Face,
center: Point2d, center: Point2d,
radius: number(Length), radius?: number(Length),
diameter?: number(Length),
tag?: tag, tag?: tag,
): Sketch ): Sketch
``` ```
@ -25,7 +26,8 @@ the provided (x, y) origin point.
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `sketch_or_surface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes | | `sketch_or_surface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the circle. | Yes | | `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the circle. | Yes |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the circle. | Yes | | `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the circle. Incompatible with `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The diameter of the circle. Incompatible with `radius`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this circle. | No | | [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this circle. | No |
### Returns ### Returns
@ -51,7 +53,7 @@ exampleSketch = startSketchOn(XZ)
|> line(end = [0, 30]) |> line(end = [0, 30])
|> line(end = [-30, 0]) |> line(end = [-30, 0])
|> close() |> close()
|> subtract2d(tool = circle(center = [0, 15], radius = 5)) |> subtract2d(tool = circle(center = [0, 15], diameter = 10))
example = extrude(exampleSketch, length = 5) example = extrude(exampleSketch, length = 5)
``` ```

View File

@ -45,15 +45,16 @@ test.describe('Command bar tests', () => {
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
commandName: 'Extrude', commandName: 'Extrude',
currentArgKey: 'length', currentArgKey: 'sketches',
currentArgValue: '5', currentArgValue: '',
headerArguments: { headerArguments: {
Profiles: '1 profile', Profiles: '',
Length: '', Length: '',
}, },
highlightedHeaderArg: 'length', highlightedHeaderArg: 'Profiles',
}) })
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'review', stage: 'review',
commandName: 'Extrude', commandName: 'Extrude',

View File

@ -1134,6 +1134,7 @@ sketch001 = startSketchOn(XZ)
// Wait for the selection to register (TODO: we need a definitive way to wait for this) // Wait for the selection to register (TODO: we need a definitive way to wait for this)
await page.waitForTimeout(200) await page.waitForTimeout(200)
await toolbar.extrudeButton.click() await toolbar.extrudeButton.click()
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
currentArgKey: 'length', currentArgKey: 'length',
@ -1355,9 +1356,7 @@ sketch001 = startSketchOn(XZ)
const u = await getUtils(page) const u = await getUtils(page)
const projectLink = page.getByRole('link', { name: 'cube' }) const projectLink = page.getByRole('link', { name: 'cube' })
const gizmo = page.locator('[aria-label*=gizmo]') const gizmo = page.locator('[aria-label*=gizmo]')
const resetCameraButton = page.getByRole('button', { const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
name: 'Reset view',
})
const locationToHaveColor = async ( const locationToHaveColor = async (
position: { x: number; y: number }, position: { x: number; y: number },
color: [number, number, number] color: [number, number, number]

View File

@ -105,14 +105,19 @@ export class CmdBarFixture {
expectState = async (expected: CmdBarSerialised) => { expectState = async (expected: CmdBarSerialised) => {
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected) return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
} }
/** The method will use buttons OR press enter randomly to progress the cmdbar, /**
* this could have unexpected results depending on what's focused * This method is used to progress the command bar to the next step, defaulting to clicking the next button.
* * Optionally, with the `shouldUseKeyboard` parameter, it will hit `Enter` to progress.
* TODO: This method assumes the user has a valid input to the current stage, * * TODO: This method assumes the user has a valid input to the current stage,
* and assumes we are past the `pickCommand` step. * and assumes we are past the `pickCommand` step.
*/ */
progressCmdBar = async (shouldFuzzProgressMethod = true) => { progressCmdBar = async (shouldUseKeyboard = false) => {
await this.page.waitForTimeout(2000) await this.page.waitForTimeout(2000)
if (shouldUseKeyboard) {
await this.page.keyboard.press('Enter')
return
}
const arrowButton = this.page.getByRole('button', { const arrowButton = this.page.getByRole('button', {
name: 'arrow right Continue', name: 'arrow right Continue',
}) })

View File

@ -61,6 +61,7 @@ class MyAPIReporter implements Reporter {
const payload = { const payload = {
// Required information // Required information
project: 'https://github.com/KittyCAD/modeling-app', project: 'https://github.com/KittyCAD/modeling-app',
suite: process.env.CI_SUITE || 'e2e',
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '', branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '', commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
test: test.titlePath().slice(2).join(' '), test: test.titlePath().slice(2).join(' '),

View File

@ -74,6 +74,15 @@ test.describe('Point-and-click tests', () => {
await test.step('do extrude flow and check extrude code is added to editor', async () => { await test.step('do extrude flow and check extrude code is added to editor', async () => {
await toolbar.extrudeButton.click() await toolbar.extrudeButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'sketches',
currentArgValue: '',
headerArguments: { Profiles: '', Length: '' },
highlightedHeaderArg: 'Profiles',
commandName: 'Extrude',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
currentArgKey: 'length', currentArgKey: 'length',
@ -1645,6 +1654,15 @@ sketch002 = startSketchOn(plane001)
await test.step(`Go through the command bar flow with preselected sketches`, async () => { await test.step(`Go through the command bar flow with preselected sketches`, async () => {
await toolbar.loftButton.click() await toolbar.loftButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'sketches',
currentArgValue: '',
headerArguments: { Profiles: '' },
highlightedHeaderArg: 'Profiles',
commandName: 'Loft',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'review', stage: 'review',
headerArguments: { Profiles: '2 profiles' }, headerArguments: { Profiles: '2 profiles' },
@ -1855,7 +1873,11 @@ sketch002 = startSketchOn(XZ)
}, },
stage: 'review', stage: 'review',
}) })
await cmdBar.progressCmdBar() // Confirm we can submit from the review step with just `Enter`
await cmdBar.progressCmdBar(true)
await cmdBar.expectState({
stage: 'commandBarClosed',
})
}) })
await test.step(`Confirm code is added to the editor, scene has changed`, async () => { await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
@ -1995,7 +2017,7 @@ profile001 = ${circleCode}`
}, },
stage: 'review', stage: 'review',
}) })
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar(true)
await editor.expectEditor.toContain(sweepDeclaration) await editor.expectEditor.toContain(sweepDeclaration)
}) })
@ -2088,6 +2110,18 @@ extrude001 = extrude(sketch001, length = -12)
await test.step(`Apply fillet to the preselected edge`, async () => { await test.step(`Apply fillet to the preselected edge`, async () => {
await page.waitForTimeout(100) await page.waitForTimeout(100)
await toolbar.filletButton.click() await toolbar.filletButton.click()
await cmdBar.expectState({
commandName: 'Fillet',
highlightedHeaderArg: 'selection',
currentArgKey: 'selection',
currentArgValue: '',
headerArguments: {
Selection: '',
Radius: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
commandName: 'Fillet', commandName: 'Fillet',
highlightedHeaderArg: 'radius', highlightedHeaderArg: 'radius',
@ -2617,6 +2651,18 @@ extrude001 = extrude(profile001, length = 5)
await test.step(`Apply fillet`, async () => { await test.step(`Apply fillet`, async () => {
await page.waitForTimeout(100) await page.waitForTimeout(100)
await toolbar.filletButton.click() await toolbar.filletButton.click()
await cmdBar.expectState({
commandName: 'Fillet',
highlightedHeaderArg: 'selection',
currentArgKey: 'selection',
currentArgValue: '',
headerArguments: {
Selection: '',
Radius: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
commandName: 'Fillet', commandName: 'Fillet',
highlightedHeaderArg: 'radius', highlightedHeaderArg: 'radius',
@ -2722,6 +2768,19 @@ extrude001 = extrude(sketch001, length = -12)
await test.step(`Apply chamfer to the preselected edge`, async () => { await test.step(`Apply chamfer to the preselected edge`, async () => {
await page.waitForTimeout(100) await page.waitForTimeout(100)
await toolbar.chamferButton.click() await toolbar.chamferButton.click()
await cmdBar.expectState({
commandName: 'Chamfer',
highlightedHeaderArg: 'selection',
currentArgKey: 'selection',
currentArgValue: '',
headerArguments: {
Selection: '',
Length: '',
},
stage: 'arguments',
})
await cmdBar.progressCmdBar()
await page.waitForTimeout(1000)
await cmdBar.expectState({ await cmdBar.expectState({
commandName: 'Chamfer', commandName: 'Chamfer',
highlightedHeaderArg: 'length', highlightedHeaderArg: 'length',
@ -3205,6 +3264,8 @@ extrude001 = extrude(sketch001, length = 30)
await test.step(`Go through the command bar flow with a preselected face (cap)`, async () => { await test.step(`Go through the command bar flow with a preselected face (cap)`, async () => {
await toolbar.shellButton.click() await toolbar.shellButton.click()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await page.waitForTimeout(500)
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'review', stage: 'review',
headerArguments: { headerArguments: {
@ -3638,13 +3699,12 @@ tag=$rectangleSegmentC002,
// revolve // revolve
await editor.scrollToText(codeToSelection) await editor.scrollToText(codeToSelection)
await page.getByText(codeToSelection).click() await page.getByText(codeToSelection).click()
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
await page.waitForTimeout(200)
await toolbar.revolveButton.click() await toolbar.revolveButton.click()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)` const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy() expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
@ -4573,6 +4633,18 @@ path001 = startProfile(sketch001, at = [0, 0])
await test.step('Go through command bar flow', async () => { await test.step('Go through command bar flow', async () => {
await toolbar.extrudeButton.click() await toolbar.extrudeButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'sketches',
currentArgValue: '',
headerArguments: {
Profiles: '',
Length: '',
},
highlightedHeaderArg: 'Profiles',
commandName: 'Extrude',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
currentArgKey: 'length', currentArgKey: 'length',
@ -4655,6 +4727,19 @@ path001 = startProfile(sketch001, at = [0, 0])
await test.step('Go through command bar flow', async () => { await test.step('Go through command bar flow', async () => {
await toolbar.sweepButton.click() await toolbar.sweepButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'sketches',
currentArgValue: '',
headerArguments: {
Profiles: '',
Path: '',
Sectional: '',
},
highlightedHeaderArg: 'Profiles',
commandName: 'Sweep',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
currentArgKey: 'path', currentArgKey: 'path',
@ -4739,6 +4824,19 @@ path001 = startProfile(sketch001, at = [0, 0])
await test.step('Go through command bar flow', async () => { await test.step('Go through command bar flow', async () => {
await toolbar.closePane('code') await toolbar.closePane('code')
await toolbar.revolveButton.click() await toolbar.revolveButton.click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'sketches',
currentArgValue: '',
headerArguments: {
Profiles: '',
AxisOrEdge: '',
Angle: '',
},
highlightedHeaderArg: 'Profiles',
commandName: 'Revolve',
})
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
currentArgKey: 'axisOrEdge', currentArgKey: 'axisOrEdge',

View File

@ -11,6 +11,7 @@ import {
getPlaywrightDownloadDir, getPlaywrightDownloadDir,
getUtils, getUtils,
isOutOfViewInScrollContainer, isOutOfViewInScrollContainer,
runningOnWindows,
} from '@e2e/playwright/test-utils' } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test' import { expect, test } from '@e2e/playwright/zoo-test'
@ -1979,7 +1980,6 @@ test(
} }
) )
// Flaky
test( test(
'Original project name persist after onboarding', 'Original project name persist after onboarding',
{ tag: '@electron' }, { tag: '@electron' },
@ -2066,13 +2066,9 @@ test(
) )
test( test(
'nested dir import works on windows', 'import from nested directory',
{ tag: ['@electron', '@windows'] }, { tag: ['@electron', '@windows', '@macos'] },
async ({ scene, cmdBar, context, page }, testInfo) => { async ({ scene, cmdBar, context, page }) => {
// Skip if on non-windows
if (process.platform !== 'win32') {
test.skip()
}
await context.folderSetupFn(async (dir) => { await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket') const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true }) await fsp.mkdir(bracketDir, { recursive: true })
@ -2085,9 +2081,9 @@ test(
) )
await fsp.writeFile( await fsp.writeFile(
path.join(bracketDir, 'main.kcl'), path.join(bracketDir, 'main.kcl'),
`import 'nested\\main.kcl' as thing runningOnWindows()
? `import 'nested\\main.kcl' as thing\n\nthing`
thing` : `import 'nested/main.kcl' as thing\n\nthing`
) )
}) })

View File

@ -1016,6 +1016,7 @@ profile001 = startProfile(sketch001, at = [${roundOff(scale * 69.6)}, ${roundOff
// sketch selection should already have been made. // sketch selection should already have been made.
// otherwise the cmdbar would be waiting for a selection. // otherwise the cmdbar would be waiting for a selection.
await cmdBar.progressCmdBar()
await cmdBar.expectState({ await cmdBar.expectState({
stage: 'arguments', stage: 'arguments',
currentArgKey: 'length', currentArgKey: 'length',

View File

@ -103,6 +103,8 @@ test.describe('Testing loading external models', () => {
file: 'ball-bearing' + FILE_EXT, file: 'ball-bearing' + FILE_EXT,
title: 'Ball Bearing', title: 'Ball Bearing',
file1: 'ball-bearing-1' + FILE_EXT, file1: 'ball-bearing-1' + FILE_EXT,
folderName: 'ball-bearing',
folderName1: 'ball-bearing-1',
} }
const projectCard = page.getByRole('link', { name: 'bracket' }) const projectCard = page.getByRole('link', { name: 'bracket' })
const overwriteWarning = page.getByText( const overwriteWarning = page.getByText(
@ -154,8 +156,10 @@ test.describe('Testing loading external models', () => {
await test.step(`Ensure we made and opened a new file`, async () => { await test.step(`Ensure we made and opened a new file`, async () => {
await editor.expectEditor.toContain('// ' + sampleOne.title) await editor.expectEditor.toContain('// ' + sampleOne.title)
await expect(newlyCreatedFile(sampleOne.file)).toBeVisible() await expect(
await expect(projectMenuButton).toContainText(sampleOne.file) page.getByTestId('file-tree-item').getByText(sampleOne.folderName)
).toBeVisible()
await expect(projectMenuButton).toContainText('main.kcl')
}) })
await test.step(`Load a KCL sample with the command palette`, async () => { await test.step(`Load a KCL sample with the command palette`, async () => {
@ -169,8 +173,10 @@ test.describe('Testing loading external models', () => {
await test.step(`Ensure we made and opened a new file with a unique name`, async () => { await test.step(`Ensure we made and opened a new file with a unique name`, async () => {
await editor.expectEditor.toContain('// ' + sampleOne.title) await editor.expectEditor.toContain('// ' + sampleOne.title)
await expect(newlyCreatedFile(sampleOne.file1)).toBeVisible() await expect(
await expect(projectMenuButton).toContainText(sampleOne.file1) page.getByTestId('file-tree-item').getByText(sampleOne.folderName1)
).toBeVisible()
await expect(projectMenuButton).toContainText('main.kcl')
}) })
} }
) )

View File

@ -984,12 +984,12 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
) )
await expect(page.getByTestId('app-header-file-name')).toBeVisible() await expect(page.getByTestId('app-header-file-name')).toBeVisible()
await expect(page.getByTestId('app-header-file-name')).toContainText( await expect(page.getByTestId('app-header-file-name')).toContainText(
'2x2x2-cube.kcl' 'main.kcl'
) )
await u.openFilePanel() await u.openFilePanel()
await expect( await expect(
page.getByTestId('file-tree-item').getByText('2x2x2-cube.kcl') page.getByTestId('file-tree-item').getByText('2x2x2-cube')
).toBeVisible() ).toBeVisible()
} }
) )
@ -1184,13 +1184,13 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
) )
await expect(page.getByTestId('app-header-file-name')).toBeVisible() await expect(page.getByTestId('app-header-file-name')).toBeVisible()
await expect(page.getByTestId('app-header-file-name')).toContainText( await expect(page.getByTestId('app-header-file-name')).toContainText(
'2x2x2-cube.kcl' 'main.kcl'
) )
// Check file is created // Check file is created
await u.openFilePanel() await u.openFilePanel()
await expect( await expect(
page.getByTestId('file-tree-item').getByText('2x2x2-cube.kcl') page.getByTestId('file-tree-item').getByText('2x2x2-cube')
).toBeVisible() ).toBeVisible()
} }
) )
@ -1476,13 +1476,13 @@ test.describe('Mocked Text-to-CAD API tests', { tag: ['@skipWin'] }, () => {
) )
await expect(page.getByTestId('app-header-file-name')).toBeVisible() await expect(page.getByTestId('app-header-file-name')).toBeVisible()
await expect(page.getByTestId('app-header-file-name')).toContainText( await expect(page.getByTestId('app-header-file-name')).toContainText(
'2x2x2-cube.kcl' 'main.kcl'
) )
// Check file is created // Check file is created
await u.openFilePanel() await u.openFilePanel()
await expect( await expect(
page.getByTestId('file-tree-item').getByText('2x2x2-cube.kcl') page.getByTestId('file-tree-item').getByText('2x2x2-cube')
).toBeVisible() ).toBeVisible()
await expect( await expect(
page.getByTestId('file-tree-item').getByText('main.kcl') page.getByTestId('file-tree-item').getByText('main.kcl')

View File

@ -573,6 +573,7 @@ profile001 = startProfile(sketch002, at = [-12.34, 12.34])
await expect(page.getByTestId('command-bar')).toBeVisible() await expect(page.getByTestId('command-bar')).toBeVisible()
await page.waitForTimeout(100) await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await expect(page.getByText('Confirm Extrude')).toBeVisible() await expect(page.getByText('Confirm Extrude')).toBeVisible()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()

View File

@ -33,14 +33,9 @@ stemLoftProfile2 = startSketchOn(offsetPlane(XY, offset = 75))
// Draw the third profile for the lofted femur // Draw the third profile for the lofted femur
p3Z = 110 p3Z = 110
p3A = 25 p3A = 25
plane003 = {
origin = [0, 0.0, p3Z],
xAxis = [cos(p3A), 0, sin(p3A)],
yAxis = [0.0, 1.0, 0.0]
}
l3 = 32 l3 = 32
r3 = 4 r3 = 4
stemLoftProfile3 = startSketchOn(plane003) stemLoftProfile3 = startSketchOn(XY)
|> startProfile(at = [-15.5, -l3 / 2]) |> startProfile(at = [-15.5, -l3 / 2])
|> yLine(length = l3, tag = $seg03) |> yLine(length = l3, tag = $seg03)
|> tangentialArc(angle = -120, radius = r3) |> tangentialArc(angle = -120, radius = r3)
@ -49,18 +44,14 @@ stemLoftProfile3 = startSketchOn(plane003)
|> angledLine(angle = 30, length = -segLen(seg03)) |> angledLine(angle = 30, length = -segLen(seg03))
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)]) |> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> translate(z = p3Z)
|> rotate(pitch = -p3A)
// Draw the fourth profile for the lofted femur // Draw the fourth profile for the lofted femur
p4Z = 130 p4Z = 130
p4A = 36.5 p4A = 36.5
plane004 = {
origin = [0, 0.0, p4Z],
xAxis = [cos(p4A), 0, sin(p4A)],
yAxis = [0.0, 1.0, 0.0]
}
l4 = 16 l4 = 16
r4 = 5 r4 = 5
stemLoftProfile4 = startSketchOn(plane004) stemLoftProfile4 = startSketchOn(XY)
|> startProfile(at = [-23, -l4 / 2]) |> startProfile(at = [-23, -l4 / 2])
|> yLine(length = l4, tag = $seg04) |> yLine(length = l4, tag = $seg04)
|> tangentialArc(angle = -120, radius = r4) |> tangentialArc(angle = -120, radius = r4)
@ -69,18 +60,14 @@ stemLoftProfile4 = startSketchOn(plane004)
|> angledLine(angle = 30, length = -segLen(seg04)) |> angledLine(angle = 30, length = -segLen(seg04))
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)]) |> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> translate(z = p4Z)
|> rotate(pitch = -p4A)
// Draw the first profile for the femoral stem // Draw the first profile for the femoral stem
p5Z = 140 p5Z = 140
p5A = 36.5 p5A = 36.5
plane005 = {
origin = [0, 0.0, p5Z],
xAxis = [cos(p5A), 0, sin(p5A)],
yAxis = [0.0, 1.0, 0.0]
}
l5 = 1.6 l5 = 1.6
r5 = 1.6 r5 = 1.6
stemLoftProfile5 = startSketchOn(plane005) stemLoftProfile5 = startSketchOn(XY)
|> startProfile(at = [-19.5, -l5 / 2]) |> startProfile(at = [-19.5, -l5 / 2])
|> yLine(length = l5, tag = $seg05) |> yLine(length = l5, tag = $seg05)
|> tangentialArc(angle = -120, radius = r5) |> tangentialArc(angle = -120, radius = r5)
@ -89,18 +76,14 @@ stemLoftProfile5 = startSketchOn(plane005)
|> angledLine(angle = 30, length = -segLen(seg05)) |> angledLine(angle = 30, length = -segLen(seg05))
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)]) |> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> translate(z = p5Z)
|> rotate(pitch = -p5A)
// Draw the second profile for the femoral stem // Draw the second profile for the femoral stem
p6Z = 145 p6Z = 145
p6A = 36.5 p6A = 36.5
plane006 = {
origin = [0, 0.0, p6Z],
xAxis = [cos(p6A), 0, sin(p6A)],
yAxis = [0.0, 1.0, 0.0]
}
l6 = 1 l6 = 1
r6 = 3 r6 = 3
stemLoftProfile6 = startSketchOn(plane006) stemLoftProfile6 = startSketchOn(XY)
|> startProfile(at = [-23.4, -l6 / 2]) |> startProfile(at = [-23.4, -l6 / 2])
|> yLine(length = l6, tag = $seg06) |> yLine(length = l6, tag = $seg06)
|> tangentialArc(angle = -120, radius = r6) |> tangentialArc(angle = -120, radius = r6)
@ -109,27 +92,24 @@ stemLoftProfile6 = startSketchOn(plane006)
|> angledLine(angle = 30, length = -segLen(seg06)) |> angledLine(angle = 30, length = -segLen(seg06))
|> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)]) |> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> translate(z = p6Z)
// Draw the third profile for the femoral stem |> rotate(pitch = -p6A)
stemTab = clone(stemLoftProfile6)
|> extrude(%, length = 6)
// Loft the femur using all profiles in sequence // Loft the femur using all profiles in sequence
femur = loft([ femur = loft([
stemLoftProfile1, stemLoftProfile1,
stemLoftProfile2, stemLoftProfile2,
stemLoftProfile3, stemLoftProfile3,
stemLoftProfile4 stemLoftProfile4
]) ])
// Loft the femoral stem // Loft the femoral stem
femoralStem = loft([ femoralStem = loft([
clone(stemLoftProfile4), clone(stemLoftProfile4),
stemLoftProfile5, stemLoftProfile5,
stemLoftProfile6 clone(stemLoftProfile6)
]) ])
// Draw the third profile for the femoral stem
stemTab = stemLoftProfile6
|> extrude(length = 6)
// Revolve a hollow socket to represent the femoral head // Revolve a hollow socket to represent the femoral head
femoralHead = startSketchOn(XZ) femoralHead = startSketchOn(XZ)
|> startProfile(at = [4, 0]) |> startProfile(at = [4, 0])

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -631,6 +631,8 @@ impl FnData {
return "clone(${0:part001})".to_owned(); return "clone(${0:part001})".to_owned();
} else if self.name == "hole" { } else if self.name == "hole" {
return "hole(${0:holeSketch}, ${1:%})".to_owned(); return "hole(${0:holeSketch}, ${1:%})".to_owned();
} else if self.name == "circle" {
return "circle(center = [${0:3.14}, ${1:3.14}], diameter = ${2:3.14})".to_owned();
} }
let mut args = Vec::new(); let mut args = Vec::new();
let mut index = 0; let mut index = 0;

View File

@ -1018,7 +1018,7 @@ mod tests {
let snippet = circle_fn.to_autocomplete_snippet(); let snippet = circle_fn.to_autocomplete_snippet();
assert_eq!( assert_eq!(
snippet, snippet,
r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})"# r#"circle(center = [${0:3.14}, ${1:3.14}], diameter = ${2:3.14})"#
); );
} }

View File

@ -281,7 +281,14 @@ impl ExecutorContext {
// Track exports. // Track exports.
if let ItemVisibility::Export = variable_declaration.visibility { if let ItemVisibility::Export = variable_declaration.visibility {
if matches!(body_type, BodyType::Root) {
exec_state.mod_local.module_exports.push(var_name); exec_state.mod_local.module_exports.push(var_name);
} else {
exec_state.err(CompilationError::err(
variable_declaration.as_source_range(),
"Exports are only supported at the top-level of a file. Remove `export` or move it to the top-level.",
));
}
} }
// Variable declaration can be the return value of a module. // Variable declaration can be the return value of a module.
last_expr = matches!(body_type, BodyType::Root).then_some(value); last_expr = matches!(body_type, BodyType::Root).then_some(value);

View File

@ -996,6 +996,27 @@ mod import_cycle1 {
super::execute(TEST_NAME, false).await super::execute(TEST_NAME, false).await
} }
} }
mod import_only_at_top_level {
const TEST_NAME: &str = "import_only_at_top_level";
/// 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, false).await
}
}
mod import_function_not_sketch { mod import_function_not_sketch {
const TEST_NAME: &str = "import_function_not_sketch"; const TEST_NAME: &str = "import_function_not_sketch";
@ -1164,6 +1185,27 @@ mod import_foreign {
super::execute(TEST_NAME, false).await super::execute(TEST_NAME, false).await
} }
} }
mod export_var_only_at_top_level {
const TEST_NAME: &str = "export_var_only_at_top_level";
/// 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, false).await
}
}
mod assembly_non_default_units { mod assembly_non_default_units {
const TEST_NAME: &str = "assembly_non_default_units"; const TEST_NAME: &str = "assembly_non_default_units";
@ -3318,3 +3360,45 @@ mod nested_windows_main_kcl {
super::execute(TEST_NAME, true).await super::execute(TEST_NAME, true).await
} }
} }
mod subtract_regression11 {
const TEST_NAME: &str = "subtract_regression11";
/// 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_regression12 {
const TEST_NAME: &str = "subtract_regression12";
/// 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

@ -44,10 +44,11 @@ pub enum SketchOrSurface {
pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_or_surface = args.get_unlabeled_kw_arg("sketchOrSurface")?; let sketch_or_surface = args.get_unlabeled_kw_arg("sketchOrSurface")?;
let center = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?; let center = args.get_kw_arg_typed("center", &RuntimeType::point2d(), exec_state)?;
let radius: TyF64 = args.get_kw_arg_typed("radius", &RuntimeType::length(), exec_state)?; let radius: Option<TyF64> = args.get_kw_arg_opt_typed("radius", &RuntimeType::length(), exec_state)?;
let diameter: Option<TyF64> = args.get_kw_arg_opt_typed("diameter", &RuntimeType::length(), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?; let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let sketch = inner_circle(sketch_or_surface, center, radius, tag, exec_state, args).await?; let sketch = inner_circle(sketch_or_surface, center, radius, diameter, tag, exec_state, args).await?;
Ok(KclValue::Sketch { Ok(KclValue::Sketch {
value: Box::new(sketch), value: Box::new(sketch),
}) })
@ -56,7 +57,8 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
async fn inner_circle( async fn inner_circle(
sketch_or_surface: SketchOrSurface, sketch_or_surface: SketchOrSurface,
center: [TyF64; 2], center: [TyF64; 2],
radius: TyF64, radius: Option<TyF64>,
diameter: Option<TyF64>,
tag: Option<TagNode>, tag: Option<TagNode>,
exec_state: &mut ExecState, exec_state: &mut ExecState,
args: Args, args: Args,
@ -68,6 +70,25 @@ async fn inner_circle(
let (center_u, ty) = untype_point(center.clone()); let (center_u, ty) = untype_point(center.clone());
let units = ty.expect_length(); let units = ty.expect_length();
let radius = match (radius, diameter) {
(Some(radius), None) => radius,
(None, Some(mut diameter)) => {
diameter.n /= 2.0;
diameter
}
(None, None) => {
return Err(KclError::Type(KclErrorDetails::new(
"This function needs either `diameter` or `radius`".to_string(),
vec![args.source_range],
)))
}
(Some(_), Some(_)) => {
return Err(KclError::Type(KclErrorDetails::new(
"You cannot specify both `diameter` and `radius`, please remove one".to_string(),
vec![args.source_range],
)))
}
};
let from = [center_u[0] + radius.to_length_units(units), center_u[1]]; let from = [center_u[0] + radius.to_length_units(units), center_u[1]];
let from_t = [TyF64::new(from[0], ty.clone()), TyF64::new(from[1], ty)]; let from_t = [TyF64::new(from[0], ty.clone()), TyF64::new(from[1], ty)];

View File

@ -24,7 +24,7 @@
/// |> line(end = [0, 30]) /// |> line(end = [0, 30])
/// |> line(end = [-30, 0]) /// |> line(end = [-30, 0])
/// |> close() /// |> close()
/// |> subtract2d(tool = circle(center = [0, 15], radius = 5)) /// |> subtract2d(tool = circle(center = [0, 15], diameter = 10))
/// ///
/// example = extrude(exampleSketch, length = 5) /// example = extrude(exampleSketch, length = 5)
/// ``` /// ```
@ -34,8 +34,10 @@ export fn circle(
@sketch_or_surface: Sketch | Plane | Face, @sketch_or_surface: Sketch | Plane | Face,
/// The center of the circle. /// The center of the circle.
center: Point2d, center: Point2d,
/// The radius of the circle. /// The radius of the circle. Incompatible with `diameter`.
radius: number(Length), radius?: number(Length),
/// The diameter of the circle. Incompatible with `radius`.
diameter?: number(Length),
/// Create a new tag which refers to this circle. /// Create a new tag which refers to this circle.
tag?: tag, tag?: tag,
): Sketch {} ): Sketch {}

View File

@ -0,0 +1,5 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands export_only_at_top_level.kcl
---
[]

View File

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

View File

@ -0,0 +1,3 @@
```mermaid
flowchart LR
```

View File

@ -0,0 +1,148 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of parsing export_only_at_top_level.kcl
---
{
"Ok": {
"body": [
{
"commentStart": 0,
"declaration": {
"commentStart": 0,
"end": 0,
"id": {
"commentStart": 0,
"end": 0,
"name": "main",
"start": 0,
"type": "Identifier"
},
"init": {
"body": {
"body": [
{
"commentStart": 0,
"declaration": {
"commentStart": 0,
"end": 0,
"id": {
"commentStart": 0,
"end": 0,
"name": "x",
"start": 0,
"type": "Identifier"
},
"init": {
"commentStart": 0,
"end": 0,
"raw": "2",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 0,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"visibility": "export"
},
{
"argument": {
"commentStart": 0,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"commentStart": 0,
"end": 0,
"start": 0
},
"commentStart": 0,
"end": 0,
"params": [],
"start": 0,
"type": "FunctionExpression",
"type": "FunctionExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 0,
"kind": "fn",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"commentStart": 0,
"end": 0,
"expression": {
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "main",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
"start": 0,
"type": "ExpressionStatement",
"type": "ExpressionStatement"
}
],
"commentStart": 0,
"end": 0,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "NonCodeNode",
"value": {
"type": "newLine"
}
}
]
},
"startNodes": []
},
"start": 0
}
}

View File

@ -0,0 +1,15 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Error from executing export_only_at_top_level.kcl
---
KCL Semantic error
× semantic: Exports are only supported at the top-level of a file. Remove
│ `export` or move it to the top-level.
╭─[2:3]
1 │ fn main() {
2 │ export x = 2
· ──────┬─────
· ╰── main
3 │ return 0
╰────

View File

@ -0,0 +1,6 @@
fn main() {
export x = 2
return 0
}
main()

View File

@ -0,0 +1,5 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed export_only_at_top_level.kcl
---
[]

View File

@ -0,0 +1,10 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing export_only_at_top_level.kcl
---
fn main() {
export x = 2
return 0
}
main()

View File

@ -0,0 +1,32 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands import_only_at_top_level.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
}
]

View File

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

View File

@ -0,0 +1,3 @@
```mermaid
flowchart LR
```

View File

@ -0,0 +1,129 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of parsing import_only_at_top_level.kcl
---
{
"Ok": {
"body": [
{
"commentStart": 0,
"declaration": {
"commentStart": 0,
"end": 0,
"id": {
"commentStart": 0,
"end": 0,
"name": "main",
"start": 0,
"type": "Identifier"
},
"init": {
"body": {
"body": [
{
"commentStart": 0,
"end": 0,
"path": {
"type": "Kcl",
"filename": "empty.kcl"
},
"selector": {
"type": "None",
"alias": null
},
"start": 0,
"type": "ImportStatement",
"type": "ImportStatement"
},
{
"argument": {
"commentStart": 0,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"commentStart": 0,
"end": 0,
"start": 0
},
"commentStart": 0,
"end": 0,
"params": [],
"start": 0,
"type": "FunctionExpression",
"type": "FunctionExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 0,
"kind": "fn",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
},
{
"commentStart": 0,
"end": 0,
"expression": {
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "main",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
"start": 0,
"type": "ExpressionStatement",
"type": "ExpressionStatement"
}
],
"commentStart": 0,
"end": 0,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "NonCodeNode",
"value": {
"type": "newLine"
}
}
]
},
"startNodes": []
},
"start": 0
}
}

View File

@ -0,0 +1,30 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Error from executing import_only_at_top_level.kcl
---
KCL Semantic error
× semantic: Imports are only supported at the top-level of a file.
╭─[2:3]
1 │ fn main() {
2 │ import "empty.kcl"
· ─────────┬────────
· ╰── tests/import_only_at_top_level/input.kcl
3 │ return 0
╰────
╭─[6:1]
5 │
6 │ main()
· ───┬──
· ╰── tests/import_only_at_top_level/input.kcl
╰────
╰─▶ KCL Semantic error
× semantic: Imports are only supported at the top-level of a file.
╭─[2:3]
1 │ fn main() {
2 │ import "empty.kcl"
· ─────────┬────────
· ╰── tests/import_only_at_top_level/input.kcl
3 │ return 0
╰────

View File

@ -0,0 +1,6 @@
fn main() {
import "empty.kcl"
return 0
}
main()

View File

@ -0,0 +1,32 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed import_only_at_top_level.kcl
---
[
{
"type": "GroupBegin",
"group": {
"type": "ModuleInstance",
"name": "empty.kcl",
"moduleId": 0
},
"sourceRange": []
},
{
"type": "GroupBegin",
"group": {
"type": "FunctionCall",
"name": "main",
"functionSourceRange": [],
"unlabeledArg": null,
"labeledArgs": {}
},
"sourceRange": []
},
{
"type": "GroupEnd"
},
{
"type": "GroupEnd"
}
]

View File

@ -0,0 +1,10 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing import_only_at_top_level.kcl
---
fn main() {
import "empty.kcl"
return 0
}
main()

View File

@ -0,0 +1,5 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing tests/import_only_at_top_level/empty.kcl
---

View File

@ -185,21 +185,20 @@ flowchart LR
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
86["Cap Start"] 86["Cap Start"]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
87["Cap Start"] 87["Cap End"]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
88["Cap End"] 88["Cap End"]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
89["Cap End"] 89["Cap End"]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
90["Cap End"] 90["SweepEdge Opposite"]
%% face_code_ref=Missing NodePath
91["SweepEdge Opposite"] 91["SweepEdge Opposite"]
92["SweepEdge Opposite"] 92["SweepEdge Opposite"]
93["SweepEdge Opposite"] 93["SweepEdge Opposite"]
94["SweepEdge Opposite"] 94["SweepEdge Opposite"]
95["SweepEdge Opposite"] 95["SweepEdge Opposite"]
96["SweepEdge Opposite"] 96["SweepEdge Opposite"]
97["SweepEdge Opposite"] 97["SweepEdge Adjacent"]
98["SweepEdge Adjacent"] 98["SweepEdge Adjacent"]
99["SweepEdge Adjacent"] 99["SweepEdge Adjacent"]
100["SweepEdge Adjacent"] 100["SweepEdge Adjacent"]
@ -214,15 +213,14 @@ flowchart LR
109["SweepEdge Adjacent"] 109["SweepEdge Adjacent"]
110["SweepEdge Adjacent"] 110["SweepEdge Adjacent"]
111["SweepEdge Adjacent"] 111["SweepEdge Adjacent"]
112["SweepEdge Adjacent"] 112["EdgeCut Fillet<br>[2999, 3289, 0]"]
%% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
113["EdgeCut Fillet<br>[2999, 3289, 0]"] 113["EdgeCut Fillet<br>[2999, 3289, 0]"]
%% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
114["EdgeCut Fillet<br>[2999, 3289, 0]"] 114["EdgeCut Fillet<br>[2999, 3289, 0]"]
%% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
115["EdgeCut Fillet<br>[2999, 3289, 0]"] 115["EdgeCut Fillet<br>[2999, 3289, 0]"]
%% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
116["EdgeCut Fillet<br>[2999, 3289, 0]"]
%% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
1 --- 8 1 --- 8
1 --- 9 1 --- 9
1 --- 13 1 --- 13
@ -283,84 +281,84 @@ flowchart LR
20 ---- 64 20 ---- 64
82 --- 20 82 --- 20
27 --- 83 27 --- 83
27 x--> 87 27 x--> 86
27 --- 97 27 --- 96
27 --- 112 27 --- 111
28 --- 68 28 --- 68
28 x--> 85 28 x--> 85
28 --- 91 28 --- 90
28 --- 98 28 --- 97
31 --- 70 31 --- 70
31 x--> 84 31 x--> 84
31 --- 95 31 --- 94
31 --- 102 31 --- 101
32 --- 71 32 --- 71
32 x--> 84 32 x--> 84
32 --- 94 32 --- 93
32 --- 101 32 --- 100
33 --- 69 33 --- 69
33 x--> 84 33 x--> 84
33 --- 93 33 --- 92
33 --- 100 33 --- 99
34 --- 72 34 --- 72
34 x--> 84 34 x--> 84
34 --- 92 34 --- 91
34 --- 99 34 --- 98
62 <--x 36 62 <--x 36
36 --- 78 36 --- 78
36 x--> 104 36 x--> 103
62 <--x 37 62 <--x 37
37 --- 77 37 --- 77
37 --- 104 37 --- 103
62 <--x 38 62 <--x 38
38 --- 82 38 --- 82
38 --- 105 38 --- 104
62 <--x 39 62 <--x 39
39 --- 79 39 --- 79
39 --- 106 39 --- 105
62 <--x 40 62 <--x 40
40 --- 74 40 --- 74
40 --- 107 40 --- 106
62 <--x 41 62 <--x 41
41 --- 81 41 --- 81
41 --- 108 41 --- 107
62 <--x 42 62 <--x 42
42 --- 76 42 --- 76
42 --- 109 42 --- 108
62 <--x 43 62 <--x 43
43 --- 75 43 --- 75
43 --- 110 43 --- 109
62 <--x 44 62 <--x 44
44 --- 80 44 --- 80
44 --- 111 44 --- 110
45 --- 73 45 --- 73
45 x--> 82 45 x--> 82
45 --- 96 45 --- 95
45 --- 103 45 --- 102
59 --- 68 59 --- 68
59 --- 85 59 --- 85
59 --- 89 59 --- 88
59 --- 91 59 --- 90
59 --- 98 59 --- 97
60 --- 83 60 --- 83
60 --- 87 60 --- 86
60 --- 90 60 --- 89
60 --- 97 60 --- 96
60 --- 112 60 --- 111
61 --- 69 61 --- 69
61 --- 70 61 --- 70
61 --- 71 61 --- 71
61 --- 72 61 --- 72
61 --- 84 61 --- 84
61 --- 88 61 --- 87
61 --- 91
61 --- 92 61 --- 92
61 --- 93 61 --- 93
61 --- 94 61 --- 94
61 --- 95 61 --- 98
61 --- 99 61 --- 99
61 --- 100 61 --- 100
61 --- 101 61 --- 101
61 --- 102
62 --- 74 62 --- 74
62 --- 75 62 --- 75
62 --- 76 62 --- 76
@ -370,6 +368,7 @@ flowchart LR
62 --- 80 62 --- 80
62 --- 81 62 --- 81
62 --- 82 62 --- 82
62 --- 103
62 --- 104 62 --- 104
62 --- 105 62 --- 105
62 --- 106 62 --- 106
@ -377,54 +376,52 @@ flowchart LR
62 --- 108 62 --- 108
62 --- 109 62 --- 109
62 --- 110 62 --- 110
62 --- 111
64 --- 73 64 --- 73
64 --- 86 64 --- 95
64 --- 96 64 --- 102
64 --- 103 68 --- 90
68 --- 91 68 --- 97
68 --- 98 69 --- 92
69 --- 93 69 --- 99
69 --- 100 100 <--x 69
101 <--x 69 70 --- 94
70 --- 95 98 <--x 70
99 <--x 70 70 --- 101
70 --- 102 71 --- 93
71 --- 94 71 --- 100
71 --- 101 101 <--x 71
102 <--x 71 72 --- 91
72 --- 92 72 --- 98
72 --- 99 99 <--x 72
100 <--x 72 73 --- 95
73 --- 96 73 --- 102
73 --- 103 95 <--x 74
106 <--x 74 105 <--x 74
74 --- 107 74 --- 106
109 <--x 75 108 <--x 75
75 --- 110 75 --- 109
108 <--x 76 107 <--x 76
76 --- 109 76 --- 108
77 --- 104 77 --- 103
78 --- 104 78 --- 103
111 <--x 78 110 <--x 78
105 <--x 79 104 <--x 79
79 --- 106 79 --- 105
110 <--x 80 109 <--x 80
80 --- 111 80 --- 110
107 <--x 81 106 <--x 81
81 --- 108 81 --- 107
82 --- 105 82 --- 104
83 --- 97 83 --- 96
83 --- 112 83 --- 111
96 <--x 86 91 <--x 87
92 <--x 88 92 <--x 87
93 <--x 88 93 <--x 87
94 <--x 88 94 <--x 87
95 <--x 88 90 <--x 88
91 <--x 89 96 <--x 89
97 <--x 90 98 <--x 113
99 <--x 114 99 <--x 112
100 <--x 113 100 <--x 115
101 <--x 116 101 <--x 114
102 <--x 115
``` ```

View File

@ -1172,7 +1172,7 @@ description: Variables in memory after executing brake-rotor.kcl
} }
}, },
"height": -7.0, "height": -7.0,
"startCapId": "[uuid]", "startCapId": null,
"endCapId": null, "endCapId": null,
"units": { "units": {
"type": "Mm" "type": "Mm"
@ -1606,7 +1606,7 @@ description: Variables in memory after executing brake-rotor.kcl
} }
}, },
"height": -7.0, "height": -7.0,
"startCapId": "[uuid]", "startCapId": null,
"endCapId": null, "endCapId": null,
"units": { "units": {
"type": "Mm" "type": "Mm"
@ -2040,7 +2040,7 @@ description: Variables in memory after executing brake-rotor.kcl
} }
}, },
"height": -7.0, "height": -7.0,
"startCapId": "[uuid]", "startCapId": null,
"endCapId": null, "endCapId": null,
"units": { "units": {
"type": "Mm" "type": "Mm"
@ -2474,7 +2474,7 @@ description: Variables in memory after executing brake-rotor.kcl
} }
}, },
"height": -7.0, "height": -7.0,
"startCapId": "[uuid]", "startCapId": null,
"endCapId": null, "endCapId": null,
"units": { "units": {
"type": "Mm" "type": "Mm"
@ -2908,7 +2908,7 @@ description: Variables in memory after executing brake-rotor.kcl
} }
}, },
"height": -7.0, "height": -7.0,
"startCapId": "[uuid]", "startCapId": null,
"endCapId": null, "endCapId": null,
"units": { "units": {
"type": "Mm" "type": "Mm"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -412,12 +412,12 @@ description: Artifact commands prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 110.0 "z": 0.0
}, },
"x_axis": { "x_axis": {
"x": 0.9063, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.4226 "z": 0.0
}, },
"y_axis": { "y_axis": {
"x": 0.0, "x": 0.0,
@ -439,9 +439,9 @@ description: Artifact commands prosthetic-hip.kcl
"animated": false, "animated": false,
"adjust_camera": false, "adjust_camera": false,
"planar_normal": { "planar_normal": {
"x": -0.4226, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 0.9063 "z": 1.0
} }
} }
}, },
@ -458,15 +458,6 @@ description: Artifact commands prosthetic-hip.kcl
} }
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -589,6 +580,54 @@ description: Artifact commands prosthetic-hip.kcl
"path_id": "[uuid]" "path_id": "[uuid]"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": {
"property": {
"x": 0.0,
"y": 0.0,
"z": 110.0
},
"set": false,
"is_local": true
},
"rotate_rpy": null,
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": null,
"rotate_rpy": {
"property": {
"x": 0.0,
"y": -25.0,
"z": 0.0
},
"set": false,
"is_local": true
},
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -597,12 +636,12 @@ description: Artifact commands prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 130.0 "z": 0.0
}, },
"x_axis": { "x_axis": {
"x": 0.8039, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948 "z": 0.0
}, },
"y_axis": { "y_axis": {
"x": 0.0, "x": 0.0,
@ -624,9 +663,9 @@ description: Artifact commands prosthetic-hip.kcl
"animated": false, "animated": false,
"adjust_camera": false, "adjust_camera": false,
"planar_normal": { "planar_normal": {
"x": -0.5948, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 0.8039 "z": 1.0
} }
} }
}, },
@ -643,15 +682,6 @@ description: Artifact commands prosthetic-hip.kcl
} }
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -774,6 +804,54 @@ description: Artifact commands prosthetic-hip.kcl
"path_id": "[uuid]" "path_id": "[uuid]"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": {
"property": {
"x": 0.0,
"y": 0.0,
"z": 130.0
},
"set": false,
"is_local": true
},
"rotate_rpy": null,
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": null,
"rotate_rpy": {
"property": {
"x": 0.0,
"y": -36.5,
"z": 0.0
},
"set": false,
"is_local": true
},
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -782,12 +860,12 @@ description: Artifact commands prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 140.0 "z": 0.0
}, },
"x_axis": { "x_axis": {
"x": 0.8039, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948 "z": 0.0
}, },
"y_axis": { "y_axis": {
"x": 0.0, "x": 0.0,
@ -809,9 +887,9 @@ description: Artifact commands prosthetic-hip.kcl
"animated": false, "animated": false,
"adjust_camera": false, "adjust_camera": false,
"planar_normal": { "planar_normal": {
"x": -0.5948, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 0.8039 "z": 1.0
} }
} }
}, },
@ -828,15 +906,6 @@ description: Artifact commands prosthetic-hip.kcl
} }
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -959,6 +1028,54 @@ description: Artifact commands prosthetic-hip.kcl
"path_id": "[uuid]" "path_id": "[uuid]"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": {
"property": {
"x": 0.0,
"y": 0.0,
"z": 140.0
},
"set": false,
"is_local": true
},
"rotate_rpy": null,
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": null,
"rotate_rpy": {
"property": {
"x": 0.0,
"y": -36.5,
"z": 0.0
},
"set": false,
"is_local": true
},
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -967,12 +1084,12 @@ description: Artifact commands prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 145.0 "z": 0.0
}, },
"x_axis": { "x_axis": {
"x": 0.8039, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948 "z": 0.0
}, },
"y_axis": { "y_axis": {
"x": 0.0, "x": 0.0,
@ -994,9 +1111,9 @@ description: Artifact commands prosthetic-hip.kcl
"animated": false, "animated": false,
"adjust_camera": false, "adjust_camera": false,
"planar_normal": { "planar_normal": {
"x": -0.5948, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 0.8039 "z": 1.0
} }
} }
}, },
@ -1013,15 +1130,6 @@ description: Artifact commands prosthetic-hip.kcl
} }
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_visible",
"object_id": "[uuid]",
"hidden": true
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -1144,6 +1252,163 @@ description: Artifact commands prosthetic-hip.kcl
"path_id": "[uuid]" "path_id": "[uuid]"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": {
"property": {
"x": 0.0,
"y": 0.0,
"z": 145.0
},
"set": false,
"is_local": true
},
"rotate_rpy": null,
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_object_transform",
"object_id": "[uuid]",
"transforms": [
{
"translate": null,
"rotate_rpy": {
"property": {
"x": 0.0,
"y": -36.5,
"z": 0.0
},
"set": false,
"is_local": true
},
"rotate_angle_axis": null,
"scale": null
}
]
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "loft",
"section_ids": [
"[uuid]",
"[uuid]",
"[uuid]",
"[uuid]"
],
"v_degree": 2,
"bez_approximate_rational": false,
"base_curve_index": null,
"tolerance": 0.0000001
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "loft",
"section_ids": [
"[uuid]",
"[uuid]",
"[uuid]"
],
"v_degree": 2,
"bez_approximate_rational": false,
"base_curve_index": null,
"tolerance": 0.0000001
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_clone",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],
@ -1178,9 +1443,9 @@ description: Artifact commands prosthetic-hip.kcl
"animated": false, "animated": false,
"adjust_camera": false, "adjust_camera": false,
"planar_normal": { "planar_normal": {
"x": -0.5948, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 0.8039 "z": 1.0
} }
} }
}, },
@ -1228,115 +1493,6 @@ description: Artifact commands prosthetic-hip.kcl
"edge_id": "[uuid]" "edge_id": "[uuid]"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "loft",
"section_ids": [
"[uuid]",
"[uuid]",
"[uuid]",
"[uuid]"
],
"v_degree": 2,
"bez_approximate_rational": false,
"base_curve_index": null,
"tolerance": 0.0000001
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "loft",
"section_ids": [
"[uuid]",
"[uuid]",
"[uuid]"
],
"v_degree": 2,
"bez_approximate_rational": false,
"base_curve_index": null,
"tolerance": 0.0000001
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_clone",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "entity_get_all_child_uuids",
"entity_id": "[uuid]"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -17,7 +17,7 @@ flowchart LR
%% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }] %% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
26["Segment<br>[676, 683, 0]"] 26["Segment<br>[676, 683, 0]"]
%% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }] %% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
80[Solid2d] 79[Solid2d]
end end
subgraph path12 [Path] subgraph path12 [Path]
12["Path<br>[816, 848, 0]"] 12["Path<br>[816, 848, 0]"]
@ -36,161 +36,161 @@ flowchart LR
%% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }] %% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
33["Segment<br>[1161, 1168, 0]"] 33["Segment<br>[1161, 1168, 0]"]
%% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }] %% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
84[Solid2d]
end
subgraph path13 [Path]
13["Path<br>[1401, 1436, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
34["Segment<br>[1442, 1474, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
35["Segment<br>[1480, 1520, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
36["Segment<br>[1526, 1573, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
37["Segment<br>[1579, 1619, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
38["Segment<br>[1625, 1672, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
39["Segment<br>[1678, 1743, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
40["Segment<br>[1749, 1756, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
77[Solid2d]
end
subgraph path14 [Path]
14["Path<br>[1992, 2025, 0]"]
%% [ProgramBodyItem { index: 17 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
41["Segment<br>[2338, 2345, 0]"]
%% [ProgramBodyItem { index: 17 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
85[Solid2d] 85[Solid2d]
end end
subgraph path15 [Path] subgraph path13 [Path]
15["Path<br>[2583, 2618, 0]"] 13["Path<br>[1293, 1328, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
42["Segment<br>[2624, 2656, 0]"] 34["Segment<br>[1334, 1366, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
43["Segment<br>[2662, 2702, 0]"] 35["Segment<br>[1372, 1412, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
44["Segment<br>[2708, 2755, 0]"] 36["Segment<br>[1418, 1465, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
45["Segment<br>[2761, 2801, 0]"] 37["Segment<br>[1471, 1511, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
46["Segment<br>[2807, 2854, 0]"] 38["Segment<br>[1517, 1564, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
47["Segment<br>[2860, 2925, 0]"] 39["Segment<br>[1570, 1635, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
48["Segment<br>[2931, 2938, 0]"] 40["Segment<br>[1641, 1648, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
79[Solid2d]
end
subgraph path16 [Path]
16["Path<br>[3173, 3208, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
49["Segment<br>[3214, 3246, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
50["Segment<br>[3252, 3292, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
51["Segment<br>[3298, 3345, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
52["Segment<br>[3351, 3391, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
53["Segment<br>[3397, 3444, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
54["Segment<br>[3450, 3515, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
55["Segment<br>[3521, 3528, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
78[Solid2d] 78[Solid2d]
end end
subgraph path14 [Path]
14["Path<br>[1825, 1858, 0]"]
%% [ProgramBodyItem { index: 15 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
41["Segment<br>[2171, 2178, 0]"]
%% [ProgramBodyItem { index: 15 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
80[Solid2d]
end
subgraph path15 [Path]
15["Path<br>[2357, 2392, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
42["Segment<br>[2398, 2430, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
43["Segment<br>[2436, 2476, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
44["Segment<br>[2482, 2529, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
45["Segment<br>[2535, 2575, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
46["Segment<br>[2581, 2628, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
47["Segment<br>[2634, 2699, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
48["Segment<br>[2705, 2712, 0]"]
%% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
84[Solid2d]
end
subgraph path16 [Path]
16["Path<br>[2888, 2923, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
49["Segment<br>[2929, 2961, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
50["Segment<br>[2967, 3007, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
51["Segment<br>[3013, 3060, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
52["Segment<br>[3066, 3106, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
53["Segment<br>[3112, 3159, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
54["Segment<br>[3165, 3230, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
55["Segment<br>[3236, 3243, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
77[Solid2d]
end
subgraph path17 [Path] subgraph path17 [Path]
17["Path<br>[3998, 4023, 0]"] 17["Path<br>[3755, 3780, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
56["Segment<br>[4029, 4048, 0]"] 56["Segment<br>[3786, 3805, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
57["Segment<br>[4054, 4091, 0]"] 57["Segment<br>[3811, 3848, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
58["Segment<br>[4097, 4134, 0]"] 58["Segment<br>[3854, 3891, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
59["Segment<br>[4140, 4158, 0]"] 59["Segment<br>[3897, 3915, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
60["Segment<br>[4164, 4202, 0]"] 60["Segment<br>[3921, 3959, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
61["Segment<br>[4208, 4273, 0]"] 61["Segment<br>[3965, 4030, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
62["Segment<br>[4279, 4286, 0]"] 62["Segment<br>[4036, 4043, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
81[Solid2d] 81[Solid2d]
end end
subgraph path18 [Path] subgraph path18 [Path]
18["Path<br>[4515, 4543, 0]"] 18["Path<br>[4272, 4300, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
63["Segment<br>[4549, 4568, 0]"] 63["Segment<br>[4306, 4325, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
64["Segment<br>[4574, 4592, 0]"] 64["Segment<br>[4331, 4349, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
65["Segment<br>[4598, 4639, 0]"] 65["Segment<br>[4355, 4396, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
66["Segment<br>[4645, 4666, 0]"] 66["Segment<br>[4402, 4423, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
67["Segment<br>[4672, 4692, 0]"] 67["Segment<br>[4429, 4449, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
68["Segment<br>[4698, 4763, 0]"] 68["Segment<br>[4455, 4520, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
69["Segment<br>[4769, 4776, 0]"] 69["Segment<br>[4526, 4533, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
82[Solid2d] 82[Solid2d]
end end
subgraph path19 [Path] subgraph path19 [Path]
19["Path<br>[4999, 5029, 0]"] 19["Path<br>[4756, 4786, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
70["Segment<br>[5035, 5052, 0]"] 70["Segment<br>[4792, 4809, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
71["Segment<br>[5058, 5076, 0]"] 71["Segment<br>[4815, 4833, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
72["Segment<br>[5082, 5120, 0]"] 72["Segment<br>[4839, 4877, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
73["Segment<br>[5126, 5152, 0]"] 73["Segment<br>[4883, 4909, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
74["Segment<br>[5158, 5177, 0]"] 74["Segment<br>[4915, 4934, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
75["Segment<br>[5183, 5248, 0]"] 75["Segment<br>[4940, 5005, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
76["Segment<br>[5254, 5261, 0]"] 76["Segment<br>[5011, 5018, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 8 }]
83[Solid2d] 83[Solid2d]
end end
1["Plane<br>[308, 325, 0]"] 1["Plane<br>[308, 325, 0]"]
%% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
2["Plane<br>[781, 809, 0]"] 2["Plane<br>[781, 809, 0]"]
%% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }, CallKwUnlabeledArg] %% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }, CallKwUnlabeledArg]
3["Plane<br>[1372, 1395, 0]"] 3["Plane<br>[1270, 1287, 0]"]
%% [ProgramBodyItem { index: 11 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 10 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
4["Plane<br>[1963, 1986, 0]"] 4["Plane<br>[1802, 1819, 0]"]
%% [ProgramBodyItem { index: 17 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 15 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
5["Plane<br>[2554, 2577, 0]"] 5["Plane<br>[2334, 2351, 0]"]
%% [ProgramBodyItem { index: 23 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 20 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
6["Plane<br>[3144, 3167, 0]"] 6["Plane<br>[2865, 2882, 0]"]
%% [ProgramBodyItem { index: 25 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
7["Plane<br>[3732, 3749, 0]"]
%% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
7["Plane<br>[3975, 3992, 0]"] 8["Plane<br>[4249, 4266, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
8["Plane<br>[4492, 4509, 0]"] 9["Plane<br>[4733, 4750, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
9["Plane<br>[4976, 4993, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
10["StartSketchOnPlane<br>[767, 810, 0]"] 10["StartSketchOnPlane<br>[767, 810, 0]"]
%% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }] %% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
86["Sweep Extrusion<br>[3616, 3638, 0]"] 86["Sweep Loft<br>[3351, 3439, 0]"]
%% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }] %% [ProgramBodyItem { index: 26 }, VariableDeclarationDeclaration, VariableDeclarationInit]
87["Sweep Loft<br>[3698, 3786, 0]"] 87["Sweep Loft<br>[3479, 3561, 0]"]
%% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit] %% [ProgramBodyItem { index: 27 }, VariableDeclarationDeclaration, VariableDeclarationInit]
88["Sweep Loft<br>[3827, 3902, 0]"] 88["Sweep Extrusion<br>[3641, 3660, 0]"]
%% [ProgramBodyItem { index: 32 }, VariableDeclarationDeclaration, VariableDeclarationInit] %% [ProgramBodyItem { index: 28 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
89["Sweep Revolve<br>[4292, 4322, 0]"] 89["Sweep Revolve<br>[4049, 4079, 0]"]
%% [ProgramBodyItem { index: 33 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 9 }] %% [ProgramBodyItem { index: 29 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 9 }]
90["Sweep Revolve<br>[4782, 4812, 0]"] 90["Sweep Revolve<br>[4539, 4569, 0]"]
%% [ProgramBodyItem { index: 34 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 9 }] %% [ProgramBodyItem { index: 30 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 9 }]
91["Sweep Revolve<br>[5267, 5297, 0]"] 91["Sweep Revolve<br>[5024, 5054, 0]"]
%% [ProgramBodyItem { index: 35 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 9 }] %% [ProgramBodyItem { index: 31 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 9 }]
92[Wall] 92[Wall]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
93[Wall] 93[Wall]
@ -239,30 +239,38 @@ flowchart LR
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
115[Wall] 115[Wall]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
116["Cap Start"] 116[Wall]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
117["Cap End"] 117[Wall]
%% face_code_ref=Missing NodePath %% face_code_ref=Missing NodePath
118["SweepEdge Opposite"] 118[Wall]
119["SweepEdge Opposite"] %% face_code_ref=Missing NodePath
120["SweepEdge Opposite"] 119[Wall]
121["SweepEdge Opposite"] %% face_code_ref=Missing NodePath
122["SweepEdge Opposite"] 120[Wall]
123["SweepEdge Opposite"] %% face_code_ref=Missing NodePath
124["SweepEdge Adjacent"] 121[Wall]
125["SweepEdge Adjacent"] %% face_code_ref=Missing NodePath
126["SweepEdge Adjacent"] 122["Cap Start"]
127["SweepEdge Adjacent"] %% face_code_ref=Missing NodePath
128["SweepEdge Adjacent"] 123["Cap Start"]
129["SweepEdge Adjacent"] %% face_code_ref=Missing NodePath
130["SweepEdge Adjacent"] 124["Cap End"]
131["SweepEdge Adjacent"] %% face_code_ref=Missing NodePath
132["SweepEdge Adjacent"] 125["Cap End"]
133["SweepEdge Adjacent"] %% face_code_ref=Missing NodePath
134["SweepEdge Adjacent"] 126["SweepEdge Opposite"]
135["SweepEdge Adjacent"] 127["SweepEdge Opposite"]
136["SweepEdge Adjacent"] 128["SweepEdge Opposite"]
137["SweepEdge Adjacent"] 129["SweepEdge Opposite"]
130["SweepEdge Opposite"]
131["SweepEdge Opposite"]
132["SweepEdge Opposite"]
133["SweepEdge Opposite"]
134["SweepEdge Opposite"]
135["SweepEdge Opposite"]
136["SweepEdge Opposite"]
137["SweepEdge Opposite"]
138["SweepEdge Adjacent"] 138["SweepEdge Adjacent"]
139["SweepEdge Adjacent"] 139["SweepEdge Adjacent"]
140["SweepEdge Adjacent"] 140["SweepEdge Adjacent"]
@ -272,6 +280,26 @@ flowchart LR
144["SweepEdge Adjacent"] 144["SweepEdge Adjacent"]
145["SweepEdge Adjacent"] 145["SweepEdge Adjacent"]
146["SweepEdge Adjacent"] 146["SweepEdge Adjacent"]
147["SweepEdge Adjacent"]
148["SweepEdge Adjacent"]
149["SweepEdge Adjacent"]
150["SweepEdge Adjacent"]
151["SweepEdge Adjacent"]
152["SweepEdge Adjacent"]
153["SweepEdge Adjacent"]
154["SweepEdge Adjacent"]
155["SweepEdge Adjacent"]
156["SweepEdge Adjacent"]
157["SweepEdge Adjacent"]
158["SweepEdge Adjacent"]
159["SweepEdge Adjacent"]
160["SweepEdge Adjacent"]
161["SweepEdge Adjacent"]
162["SweepEdge Adjacent"]
163["SweepEdge Adjacent"]
164["SweepEdge Adjacent"]
165["SweepEdge Adjacent"]
166["SweepEdge Adjacent"]
1 --- 11 1 --- 11
2 <--x 10 2 <--x 10
2 --- 12 2 --- 12
@ -289,8 +317,8 @@ flowchart LR
11 --- 24 11 --- 24
11 --- 25 11 --- 25
11 --- 26 11 --- 26
11 --- 80 11 --- 79
11 ---- 87 11 ---- 86
12 --- 27 12 --- 27
12 --- 28 12 --- 28
12 --- 29 12 --- 29
@ -298,8 +326,8 @@ flowchart LR
12 --- 31 12 --- 31
12 --- 32 12 --- 32
12 --- 33 12 --- 33
12 --- 84 12 --- 85
12 x---> 87 12 x---> 86
13 --- 34 13 --- 34
13 --- 35 13 --- 35
13 --- 36 13 --- 36
@ -307,17 +335,17 @@ flowchart LR
13 --- 38 13 --- 38
13 --- 39 13 --- 39
13 --- 40 13 --- 40
13 --- 77 13 --- 78
13 x---> 87 13 x---> 86
14 --- 41 14 --- 41
14 --- 85 14 --- 80
14 x---> 87 14 x---> 86
14 x--> 118 14 x--> 132
14 x--> 119 14 x--> 133
14 x--> 120 14 x--> 134
14 x--> 121 14 x--> 135
14 x--> 122 14 x--> 136
14 x--> 123 14 x--> 137
15 --- 42 15 --- 42
15 --- 43 15 --- 43
15 --- 44 15 --- 44
@ -325,8 +353,8 @@ flowchart LR
15 --- 46 15 --- 46
15 --- 47 15 --- 47
15 --- 48 15 --- 48
15 --- 79 15 --- 84
15 x---> 88 15 x---> 87
16 --- 49 16 --- 49
16 --- 50 16 --- 50
16 --- 51 16 --- 51
@ -334,8 +362,8 @@ flowchart LR
16 --- 53 16 --- 53
16 --- 54 16 --- 54
16 --- 55 16 --- 55
16 --- 78 16 --- 77
16 x---> 88 16 ---- 88
17 --- 56 17 --- 56
17 --- 57 17 --- 57
17 --- 58 17 --- 58
@ -363,195 +391,263 @@ flowchart LR
19 --- 76 19 --- 76
19 --- 83 19 --- 83
19 ---- 91 19 ---- 91
20 --- 103 20 --- 109
20 x--> 116 20 x--> 122
20 --- 118 20 --- 132
20 --- 130 20 --- 150
21 --- 101 21 --- 107
21 x--> 116 21 x--> 122
21 --- 119 21 --- 133
21 --- 131 21 --- 151
22 --- 100 22 --- 106
22 x--> 116 22 x--> 122
22 --- 120 22 --- 134
22 --- 132 22 --- 152
23 --- 102 23 --- 108
23 x--> 116 23 x--> 122
23 --- 121 23 --- 135
23 --- 133 23 --- 153
24 --- 99 24 --- 105
24 x--> 116 24 x--> 122
24 --- 122 24 --- 136
24 --- 134 24 --- 154
25 --- 98 25 --- 104
25 x--> 116 25 x--> 122
25 --- 123 25 --- 137
25 --- 135 25 --- 155
49 --- 94
49 x--> 123
49 --- 131
49 --- 143
50 --- 95
50 x--> 123
50 --- 130
50 --- 142
51 --- 96
51 x--> 123
51 --- 129
51 --- 141
52 --- 97
52 x--> 123
52 --- 128
52 --- 140
53 --- 92
53 x--> 123
53 --- 127
53 --- 139
54 --- 93
54 x--> 123
54 --- 126
54 --- 138
89 <--x 56 89 <--x 56
56 --- 109 56 --- 115
56 x--> 136 56 x--> 156
89 <--x 57 89 <--x 57
57 --- 108 57 --- 114
57 --- 136 57 --- 156
89 <--x 58 89 <--x 58
58 --- 104 58 --- 110
58 --- 137 58 --- 157
89 <--x 59 89 <--x 59
59 --- 107 59 --- 113
59 --- 138 59 --- 158
89 <--x 60 89 <--x 60
60 --- 106 60 --- 112
60 --- 139 60 --- 159
89 <--x 61 89 <--x 61
61 --- 105 61 --- 111
61 --- 140 61 --- 160
90 <--x 63 90 <--x 63
63 --- 96 63 --- 102
63 --- 124 63 --- 144
90 <--x 64 90 <--x 64
64 --- 92 64 --- 98
64 --- 125 64 --- 145
90 <--x 65 90 <--x 65
65 --- 93 65 --- 99
65 --- 126 65 --- 146
90 <--x 66 90 <--x 66
66 --- 97 66 --- 103
66 --- 127 66 --- 147
90 <--x 67 90 <--x 67
67 --- 95 67 --- 101
67 --- 128 67 --- 148
90 <--x 68 90 <--x 68
68 --- 94 68 --- 100
68 --- 129 68 --- 149
91 <--x 70 91 <--x 70
70 --- 112 70 --- 118
70 --- 141 70 --- 161
91 <--x 71 91 <--x 71
71 --- 115 71 --- 121
71 --- 142 71 --- 162
91 <--x 72 91 <--x 72
72 --- 114 72 --- 120
72 --- 143 72 --- 163
91 <--x 73 91 <--x 73
73 --- 110 73 --- 116
73 --- 144 73 --- 164
91 <--x 74 91 <--x 74
74 --- 113 74 --- 119
74 --- 145 74 --- 165
91 <--x 75 91 <--x 75
75 --- 111 75 --- 117
75 --- 146 75 --- 166
87 --- 98 86 --- 104
87 --- 99 86 --- 105
87 --- 100 86 --- 106
87 --- 101 86 --- 107
87 --- 102 86 --- 108
87 --- 103 86 --- 109
87 --- 116 86 --- 122
87 --- 117 86 --- 124
87 --- 118 86 --- 132
87 --- 119 86 --- 133
87 --- 120 86 --- 134
87 --- 121 86 --- 135
87 --- 122 86 --- 136
87 --- 123 86 --- 137
87 --- 130 86 --- 150
87 --- 131 86 --- 151
87 --- 132 86 --- 152
87 --- 133 86 --- 153
87 --- 134 86 --- 154
87 --- 135 86 --- 155
89 --- 104 88 --- 92
89 --- 105 88 --- 93
89 --- 106 88 --- 94
89 --- 107 88 --- 95
89 --- 108 88 --- 96
89 --- 109 88 --- 97
89 --- 136 88 --- 123
89 --- 137 88 --- 125
89 --- 138 88 --- 126
89 --- 139 88 --- 127
89 --- 140 88 --- 128
90 --- 92 88 --- 129
90 --- 93 88 --- 130
90 --- 94 88 --- 131
90 --- 95 88 --- 138
90 --- 96 88 --- 139
90 --- 97 88 --- 140
90 --- 124 88 --- 141
90 --- 125 88 --- 142
90 --- 126 88 --- 143
90 --- 127 89 --- 110
90 --- 128 89 --- 111
90 --- 129 89 --- 112
91 --- 110 89 --- 113
91 --- 111 89 --- 114
91 --- 112 89 --- 115
91 --- 113 89 --- 156
91 --- 114 89 --- 157
91 --- 115 89 --- 158
91 --- 141 89 --- 159
91 --- 142 89 --- 160
91 --- 143 90 --- 98
91 --- 144 90 --- 99
91 --- 145 90 --- 100
91 --- 146 90 --- 101
124 <--x 92 90 --- 102
92 --- 125 90 --- 103
125 <--x 93 90 --- 144
90 --- 145
90 --- 146
90 --- 147
90 --- 148
90 --- 149
91 --- 116
91 --- 117
91 --- 118
91 --- 119
91 --- 120
91 --- 121
91 --- 161
91 --- 162
91 --- 163
91 --- 164
91 --- 165
91 --- 166
92 --- 127
92 --- 139
140 <--x 92
93 --- 126 93 --- 126
128 <--x 94 93 --- 138
94 --- 129 139 <--x 93
127 <--x 95 94 --- 131
95 --- 128 138 <--x 94
96 --- 124 94 --- 143
129 <--x 96 95 --- 130
126 <--x 97 95 --- 142
97 --- 127 143 <--x 95
98 --- 123 96 --- 129
130 <--x 98 96 --- 141
98 --- 135 142 <--x 96
99 --- 122 97 --- 128
99 --- 134 97 --- 140
135 <--x 99 141 <--x 97
100 --- 120 144 <--x 98
100 --- 132 98 --- 145
133 <--x 100 145 <--x 99
101 --- 119 99 --- 146
101 --- 131 148 <--x 100
132 <--x 101 100 --- 149
102 --- 121 147 <--x 101
102 --- 133 101 --- 148
134 <--x 102 102 --- 144
103 --- 118 149 <--x 102
103 --- 130 146 <--x 103
131 <--x 103 103 --- 147
104 --- 137 104 --- 137
139 <--x 105 150 <--x 104
105 --- 140 104 --- 155
138 <--x 106 105 --- 136
106 --- 139 105 --- 154
137 <--x 107 155 <--x 105
107 --- 138 106 --- 134
108 --- 136 106 --- 152
109 --- 136 153 <--x 106
140 <--x 109 107 --- 133
143 <--x 110 107 --- 151
110 --- 144 152 <--x 107
145 <--x 111 108 --- 135
111 --- 146 108 --- 153
112 --- 141 154 <--x 108
146 <--x 112 109 --- 132
144 <--x 113 109 --- 150
113 --- 145 151 <--x 109
142 <--x 114 110 --- 157
114 --- 143 159 <--x 111
141 <--x 115 111 --- 160
115 --- 142 158 <--x 112
118 <--x 117 112 --- 159
119 <--x 117 157 <--x 113
120 <--x 117 113 --- 158
121 <--x 117 114 --- 156
122 <--x 117 115 --- 156
123 <--x 117 160 <--x 115
163 <--x 116
116 --- 164
165 <--x 117
117 --- 166
118 --- 161
166 <--x 118
164 <--x 119
119 --- 165
162 <--x 120
120 --- 163
161 <--x 121
121 --- 162
132 <--x 124
133 <--x 124
134 <--x 124
135 <--x 124
136 <--x 124
137 <--x 124
126 <--x 125
127 <--x 125
128 <--x 125
129 <--x 125
130 <--x 125
131 <--x 125
``` ```

File diff suppressed because it is too large Load Diff

View File

@ -64,131 +64,8 @@ description: Operations executed prosthetic-hip.kcl
"name": "startSketchOn", "name": "startSketchOn",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Object", "type": "Plane",
"value": { "artifact_id": "[uuid]"
"origin": {
"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"
}
}
},
{
"type": "Number",
"value": 110.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.9063077870366499,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.42261826174069944,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.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": [] "sourceRange": []
}, },
@ -200,131 +77,8 @@ description: Operations executed prosthetic-hip.kcl
"name": "startSketchOn", "name": "startSketchOn",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Object", "type": "Plane",
"value": { "artifact_id": "[uuid]"
"origin": {
"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"
}
}
},
{
"type": "Number",
"value": 130.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.8038568606172173,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.5948227867513413,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.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": [] "sourceRange": []
}, },
@ -336,131 +90,8 @@ description: Operations executed prosthetic-hip.kcl
"name": "startSketchOn", "name": "startSketchOn",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Object", "type": "Plane",
"value": { "artifact_id": "[uuid]"
"origin": {
"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"
}
}
},
{
"type": "Number",
"value": 140.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.8038568606172173,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.5948227867513413,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.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": [] "sourceRange": []
}, },
@ -472,130 +103,92 @@ description: Operations executed prosthetic-hip.kcl
"name": "startSketchOn", "name": "startSketchOn",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Object", "type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "loft",
"unlabeledArg": {
"value": { "value": {
"origin": {
"type": "Array", "type": "Array",
"value": [ "value": [
{ {
"type": "Number", "type": "Sketch",
"value": 0.0, "value": {
"ty": { "artifactId": "[uuid]"
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
} }
}, },
{ {
"type": "Number", "type": "Sketch",
"value": 0.0, "value": {
"ty": { "artifactId": "[uuid]"
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
} }
}, },
{ {
"type": "Number", "type": "Sketch",
"value": 145.0, "value": {
"ty": { "artifactId": "[uuid]"
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
} }
},
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
} }
} }
] ]
}, },
"xAxis": { "sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "loft",
"unlabeledArg": {
"value": {
"type": "Array", "type": "Array",
"value": [ "value": [
{ {
"type": "Number", "type": "Sketch",
"value": 0.8038568606172173, "value": {
"ty": { "artifactId": "[uuid]"
"type": "Known",
"type": "Count"
} }
}, },
{ {
"type": "Number", "type": "Sketch",
"value": 0.0, "value": {
"ty": { "artifactId": "[uuid]"
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
} }
}, },
{ {
"type": "Number", "type": "Sketch",
"value": 0.5948227867513413, "value": {
"ty": { "artifactId": "[uuid]"
"type": "Known",
"type": "Count"
} }
} }
] ]
}, },
"yAxis": { "sourceRange": []
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
}, },
"angle": { "labeledArgs": {},
"type": "Degrees" "sourceRange": []
}
}
}, },
{ {
"type": "Number", "type": "StdLibCall",
"value": 1.0, "name": "clone",
"ty": { "unlabeledArg": {
"type": "Default", "value": {
"len": { "type": "Sketch",
"type": "Mm" "value": {
}, "artifactId": "[uuid]"
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
} }
}, },
"sourceRange": [] "sourceRange": []
@ -650,91 +243,6 @@ description: Operations executed prosthetic-hip.kcl
}, },
"sourceRange": [] "sourceRange": []
}, },
{
"type": "StdLibCall",
"name": "loft",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "loft",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "clone",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{ {
"type": "StdLibCall", "type": "StdLibCall",
"name": "startSketchOn", "name": "startSketchOn",

View File

@ -556,9 +556,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
-8.0 -8.0
], ],
"tag": { "tag": {
"commentStart": 2056, "commentStart": 1889,
"end": 2062, "end": 1895,
"start": 2056, "start": 1889,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg04" "value": "seg04"
}, },
@ -707,17 +707,17 @@ description: Variables in memory after executing prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 130.0, "z": 0.0,
"units": { "units": {
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane", "type": "plane",
"value": "Custom", "value": "XY",
"xAxis": { "xAxis": {
"x": 0.8038568606172174, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948227867513414, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Unknown"
} }
@ -1236,514 +1236,6 @@ description: Variables in memory after executing prosthetic-hip.kcl
} }
} }
}, },
"plane003": {
"type": "Object",
"value": {
"origin": {
"type": "HomArray",
"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"
}
}
},
{
"type": "Number",
"value": 110.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.9063,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.4226,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"plane004": {
"type": "Object",
"value": {
"origin": {
"type": "HomArray",
"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"
}
}
},
{
"type": "Number",
"value": 130.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.8039,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.5948,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"plane005": {
"type": "Object",
"value": {
"origin": {
"type": "HomArray",
"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"
}
}
},
{
"type": "Number",
"value": 140.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.8039,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.5948,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"plane006": {
"type": "Object",
"value": {
"origin": {
"type": "HomArray",
"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"
}
}
},
{
"type": "Number",
"value": 145.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"xAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.8039,
"ty": {
"type": "Known",
"type": "Count"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.5948,
"ty": {
"type": "Known",
"type": "Count"
}
}
]
},
"yAxis": {
"type": "HomArray",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"polyethyleneInsert": { "polyethyleneInsert": {
"type": "Solid", "type": "Solid",
"value": { "value": {
@ -2573,9 +2065,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
-16.0 -16.0
], ],
"tag": { "tag": {
"commentStart": 1467, "commentStart": 1359,
"end": 1473, "end": 1365,
"start": 1467, "start": 1359,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg03" "value": "seg03"
}, },
@ -2724,17 +2216,17 @@ description: Variables in memory after executing prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 110.0, "z": 0.0,
"units": { "units": {
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane", "type": "plane",
"value": "Custom", "value": "XY",
"xAxis": { "xAxis": {
"x": 0.9063077870366499, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.42261826174069944, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Unknown"
} }
@ -2795,9 +2287,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
-8.0 -8.0
], ],
"tag": { "tag": {
"commentStart": 2056, "commentStart": 1889,
"end": 2062, "end": 1895,
"start": 2056, "start": 1889,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg04" "value": "seg04"
}, },
@ -2946,17 +2438,17 @@ description: Variables in memory after executing prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 130.0, "z": 0.0,
"units": { "units": {
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane", "type": "plane",
"value": "Custom", "value": "XY",
"xAxis": { "xAxis": {
"x": 0.8038568606172174, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948227867513414, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Unknown"
} }
@ -3017,9 +2509,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
-0.8 -0.8
], ],
"tag": { "tag": {
"commentStart": 2649, "commentStart": 2423,
"end": 2655, "end": 2429,
"start": 2649, "start": 2423,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg05" "value": "seg05"
}, },
@ -3168,17 +2660,17 @@ description: Variables in memory after executing prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 140.0, "z": 0.0,
"units": { "units": {
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane", "type": "plane",
"value": "Custom", "value": "XY",
"xAxis": { "xAxis": {
"x": 0.8038568606172174, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948227867513414, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Unknown"
} }
@ -3239,9 +2731,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
-0.5 -0.5
], ],
"tag": { "tag": {
"commentStart": 3239, "commentStart": 2954,
"end": 3245, "end": 2960,
"start": 3239, "start": 2954,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg06" "value": "seg06"
}, },
@ -3390,17 +2882,17 @@ description: Variables in memory after executing prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 145.0, "z": 0.0,
"units": { "units": {
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane", "type": "plane",
"value": "Custom", "value": "XY",
"xAxis": { "xAxis": {
"x": 0.8038568606172174, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948227867513414, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Unknown"
} }
@ -3457,9 +2949,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
"id": "[uuid]", "id": "[uuid]",
"sourceRange": [], "sourceRange": [],
"tag": { "tag": {
"commentStart": 3239, "commentStart": 2954,
"end": 3245, "end": 2960,
"start": 3239, "start": 2954,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg06" "value": "seg06"
}, },
@ -3515,9 +3007,9 @@ description: Variables in memory after executing prosthetic-hip.kcl
-0.5 -0.5
], ],
"tag": { "tag": {
"commentStart": 3239, "commentStart": 2954,
"end": 3245, "end": 2960,
"start": 3239, "start": 2954,
"type": "TagDeclarator", "type": "TagDeclarator",
"value": "seg06" "value": "seg06"
}, },
@ -3666,17 +3158,17 @@ description: Variables in memory after executing prosthetic-hip.kcl
"origin": { "origin": {
"x": 0.0, "x": 0.0,
"y": 0.0, "y": 0.0,
"z": 145.0, "z": 0.0,
"units": { "units": {
"type": "Mm" "type": "Mm"
} }
}, },
"type": "plane", "type": "plane",
"value": "Custom", "value": "XY",
"xAxis": { "xAxis": {
"x": 0.8038568606172174, "x": 1.0,
"y": 0.0, "y": 0.0,
"z": 0.5948227867513414, "z": 0.0,
"units": { "units": {
"type": "Unknown" "type": "Unknown"
} }

View File

@ -0,0 +1,481 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands subtract_regression11.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"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": 0.0,
"y": 1.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 0.0,
"z": 1.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": 1.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 0.0,
"y": 20.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 2.25,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.75,
"y": -0.75,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -38.5,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -0.75,
"y": -0.75,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -2.25,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": 40.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "revolve",
"target": "[uuid]",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"axis_is_2d": true,
"angle": {
"unit": "degrees",
"value": 360.0
},
"tolerance": 0.0000001,
"opposite": "None"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 0.0,
"z": 1.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": 1.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 0.65,
"y": 20.1,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -1.5,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -1.1,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": 1.5,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 1.1,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"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": 1.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 10.0,
"faces": null,
"opposite": {
"Other": 10.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "boolean_subtract",
"target_ids": [
"[uuid]"
],
"tool_ids": [
"[uuid]"
],
"tolerance": 0.0000001
}
}
]

View File

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

View File

@ -0,0 +1,178 @@
```mermaid
flowchart LR
subgraph path3 [Path]
3["Path<br>[88, 127, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
5["Segment<br>[133, 153, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
6["Segment<br>[159, 184, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
7["Segment<br>[190, 211, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
8["Segment<br>[217, 243, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
9["Segment<br>[249, 270, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
10["Segment<br>[276, 294, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
11["Segment<br>[300, 307, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
18[Solid2d]
end
subgraph path4 [Path]
4["Path<br>[428, 470, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
12["Segment<br>[476, 496, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
13["Segment<br>[502, 522, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
14["Segment<br>[528, 547, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
15["Segment<br>[553, 572, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
16["Segment<br>[578, 585, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
17[Solid2d]
end
1["Plane<br>[47, 64, 0]"]
%% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit]
2["Plane<br>[387, 404, 0]"]
%% [ProgramBodyItem { index: 3 }, VariableDeclarationDeclaration, VariableDeclarationInit]
19["Sweep Revolve<br>[322, 373, 0]"]
%% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit]
20["Sweep Extrusion<br>[603, 672, 0]"]
%% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit]
21["CompositeSolid Subtract<br>[683, 726, 0]"]
%% [ProgramBodyItem { index: 6 }, VariableDeclarationDeclaration, VariableDeclarationInit]
22[Wall]
%% face_code_ref=Missing NodePath
23[Wall]
%% face_code_ref=Missing NodePath
24[Wall]
%% face_code_ref=Missing NodePath
25[Wall]
%% face_code_ref=Missing NodePath
26[Wall]
%% face_code_ref=Missing NodePath
27[Wall]
%% face_code_ref=Missing NodePath
28[Wall]
%% face_code_ref=Missing NodePath
29[Wall]
%% face_code_ref=Missing NodePath
30[Wall]
%% face_code_ref=Missing NodePath
31["Cap Start"]
%% face_code_ref=Missing NodePath
32["Cap End"]
%% face_code_ref=Missing NodePath
33["SweepEdge Opposite"]
34["SweepEdge Opposite"]
35["SweepEdge Opposite"]
36["SweepEdge Opposite"]
37["SweepEdge Adjacent"]
38["SweepEdge Adjacent"]
39["SweepEdge Adjacent"]
40["SweepEdge Adjacent"]
41["SweepEdge Adjacent"]
42["SweepEdge Adjacent"]
43["SweepEdge Adjacent"]
44["SweepEdge Adjacent"]
1 --- 3
2 --- 4
3 --- 5
3 --- 6
3 --- 7
3 --- 8
3 --- 9
3 --- 10
3 --- 11
3 --- 18
3 ---- 19
3 --- 21
4 --- 12
4 --- 13
4 --- 14
4 --- 15
4 --- 16
4 --- 17
4 ---- 20
4 --- 21
19 <--x 5
5 --- 30
5 --- 41
19 <--x 6
6 --- 28
6 --- 42
19 <--x 7
7 --- 27
7 --- 43
19 <--x 8
8 --- 29
8 --- 44
19 <--x 9
9 --- 26
12 --- 23
12 x--> 31
12 --- 36
12 --- 40
13 --- 25
13 x--> 31
13 --- 35
13 --- 39
14 --- 22
14 x--> 31
14 --- 34
14 --- 38
15 --- 24
15 x--> 31
15 --- 33
15 --- 37
19 --- 26
19 --- 27
19 --- 28
19 --- 29
19 --- 30
19 --- 41
19 --- 42
19 --- 43
19 --- 44
20 --- 22
20 --- 23
20 --- 24
20 --- 25
20 --- 31
20 --- 32
20 --- 33
20 --- 34
20 --- 35
20 --- 36
20 --- 37
20 --- 38
20 --- 39
20 --- 40
22 --- 34
37 <--x 22
22 --- 38
23 --- 36
39 <--x 23
23 --- 40
24 --- 33
24 --- 37
40 <--x 24
25 --- 35
38 <--x 25
25 --- 39
44 <--x 26
42 <--x 27
27 --- 43
41 <--x 28
28 --- 42
43 <--x 29
29 --- 44
30 --- 41
33 <--x 32
34 <--x 32
35 <--x 32
36 <--x 32
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
@settings(defaultLengthUnit = mm)
sketch001 = startSketchOn(YZ)
sketch001Profile000 = startProfile(sketch001, at = [0.0, 20])
|> xLine(length = 2.25)
|> line(end = [0.75, -0.75])
|> yLine(length = -38.5)
|> line(end = [-0.75, -0.75])
|> xLine(length = -2.25)
|> yLine(length = 40)
|> close()
revolve000 = revolve(sketch001Profile000, axis = Y, angle = 360)
sketch003 = startSketchOn(YZ)
sketch003Profile000 = startProfile(sketch003, at = [0.65, 20.1])
|> yLine(length = -1.5)
|> xLine(length = -1.1)
|> yLine(length = 1.5)
|> xLine(length = 1.1)
|> close()
cut000Extrude = extrude([sketch003Profile000], length = 10, bidirectionalLength = 10)
cut000 = subtract(revolve000, tools = cut000Extrude)

View File

@ -0,0 +1,217 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed subtract_regression11.kcl
---
[
{
"type": "StdLibCall",
"name": "startSketchOn",
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "revolve",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {
"angle": {
"value": {
"type": "Number",
"value": 360.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"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": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "startSketchOn",
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "extrude",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {
"bidirectionalLength": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "subtract",
"unlabeledArg": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"tools": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
"sourceRange": []
}
]

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,31 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing subtract_regression11.kcl
---
@settings(defaultLengthUnit = mm)
sketch001 = startSketchOn(YZ)
sketch001Profile000 = startProfile(sketch001, at = [0.0, 20])
|> xLine(length = 2.25)
|> line(end = [0.75, -0.75])
|> yLine(length = -38.5)
|> line(end = [-0.75, -0.75])
|> xLine(length = -2.25)
|> yLine(length = 40)
|> close()
revolve000 = revolve(sketch001Profile000, axis = Y, angle = 360)
sketch003 = startSketchOn(YZ)
sketch003Profile000 = startProfile(sketch003, at = [0.65, 20.1])
|> yLine(length = -1.5)
|> xLine(length = -1.1)
|> yLine(length = 1.5)
|> xLine(length = 1.1)
|> close()
cut000Extrude = extrude([sketch003Profile000], length = 10, bidirectionalLength = 10)
cut000 = subtract(revolve000, tools = cut000Extrude)

View File

@ -0,0 +1,481 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Artifact commands subtract_regression12.kcl
---
[
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "edge_lines_visible",
"hidden": false
}
},
{
"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": "move_path_pen",
"path": "[uuid]",
"to": {
"x": 5.588,
"y": 12.7,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -5.588,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -25.4,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 2.54,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.635,
"y": 2.54,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": 20.0406,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 2.413,
"y": 2.8194,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "close_path",
"path_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "revolve",
"target": "[uuid]",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"axis_is_2d": true,
"angle": {
"unit": "degrees",
"value": 360.0
},
"tolerance": 0.0000001,
"opposite": "None"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "make_plane",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"x_axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"y_axis": {
"x": 0.0,
"y": 0.0,
"z": 1.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": 1.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "move_path_pen",
"path": "[uuid]",
"to": {
"x": -15.24,
"y": 0.508,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "start_path"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": -1.016,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 22.86,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": 0.0,
"y": 1.016,
"z": 0.0
},
"relative": true
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extend_path",
"path": "[uuid]",
"segment": {
"type": "line",
"end": {
"x": -22.86,
"y": 0.0,
"z": 0.0
},
"relative": true
}
}
},
{
"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": 1.0,
"y": 0.0,
"z": 0.0
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "extrude",
"target": "[uuid]",
"distance": 5.08,
"faces": null,
"opposite": {
"Other": 5.08
}
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "object_bring_to_front",
"object_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "sketch_mode_disable"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_adjacency_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "solid3d_get_extrusion_face_info",
"object_id": "[uuid]",
"edge_id": "[uuid]"
}
},
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "boolean_subtract",
"target_ids": [
"[uuid]"
],
"tool_ids": [
"[uuid]"
],
"tolerance": 0.0000001
}
}
]

View File

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

View File

@ -0,0 +1,180 @@
```mermaid
flowchart LR
subgraph path3 [Path]
3["Path<br>[88, 129, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
5["Segment<br>[135, 156, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
6["Segment<br>[162, 180, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
7["Segment<br>[186, 205, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
8["Segment<br>[211, 235, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
9["Segment<br>[241, 262, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
10["Segment<br>[268, 294, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 6 }]
11["Segment<br>[300, 307, 0]"]
%% [ProgramBodyItem { index: 1 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 7 }]
18[Solid2d]
end
subgraph path4 [Path]
4["Path<br>[428, 470, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
12["Segment<br>[476, 497, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
13["Segment<br>[503, 522, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
14["Segment<br>[528, 548, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 3 }]
15["Segment<br>[554, 574, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 4 }]
16["Segment<br>[580, 587, 0]"]
%% [ProgramBodyItem { index: 4 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 5 }]
17[Solid2d]
end
1["Plane<br>[47, 64, 0]"]
%% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit]
2["Plane<br>[387, 404, 0]"]
%% [ProgramBodyItem { index: 3 }, VariableDeclarationDeclaration, VariableDeclarationInit]
19["Sweep Revolve<br>[322, 373, 0]"]
%% [ProgramBodyItem { index: 2 }, VariableDeclarationDeclaration, VariableDeclarationInit]
20["Sweep Extrusion<br>[605, 676, 0]"]
%% [ProgramBodyItem { index: 5 }, VariableDeclarationDeclaration, VariableDeclarationInit]
21["CompositeSolid Subtract<br>[687, 730, 0]"]
%% [ProgramBodyItem { index: 6 }, VariableDeclarationDeclaration, VariableDeclarationInit]
22[Wall]
%% face_code_ref=Missing NodePath
23[Wall]
%% face_code_ref=Missing NodePath
24[Wall]
%% face_code_ref=Missing NodePath
25[Wall]
%% face_code_ref=Missing NodePath
26[Wall]
%% face_code_ref=Missing NodePath
27[Wall]
%% face_code_ref=Missing NodePath
28[Wall]
%% face_code_ref=Missing NodePath
29[Wall]
%% face_code_ref=Missing NodePath
30[Wall]
%% face_code_ref=Missing NodePath
31["Cap Start"]
%% face_code_ref=Missing NodePath
32["Cap End"]
%% face_code_ref=Missing NodePath
33["SweepEdge Opposite"]
34["SweepEdge Opposite"]
35["SweepEdge Opposite"]
36["SweepEdge Opposite"]
37["SweepEdge Adjacent"]
38["SweepEdge Adjacent"]
39["SweepEdge Adjacent"]
40["SweepEdge Adjacent"]
41["SweepEdge Adjacent"]
42["SweepEdge Adjacent"]
43["SweepEdge Adjacent"]
44["SweepEdge Adjacent"]
1 --- 3
2 --- 4
3 --- 5
3 --- 6
3 --- 7
3 --- 8
3 --- 9
3 --- 10
3 --- 11
3 --- 18
3 ---- 19
3 --- 21
4 --- 12
4 --- 13
4 --- 14
4 --- 15
4 --- 16
4 --- 17
4 ---- 20
4 --- 21
19 <--x 5
5 --- 30
19 <--x 7
7 --- 28
7 --- 41
19 <--x 8
8 --- 29
8 --- 42
19 <--x 9
9 --- 27
9 --- 43
19 <--x 10
10 --- 26
10 --- 44
12 --- 23
12 x--> 31
12 --- 33
12 --- 37
13 --- 25
13 x--> 31
13 --- 34
13 --- 38
14 --- 22
14 x--> 31
14 --- 35
14 --- 39
15 --- 24
15 x--> 31
15 --- 36
15 --- 40
19 --- 26
19 --- 27
19 --- 28
19 --- 29
19 --- 30
19 --- 41
19 --- 42
19 --- 43
19 --- 44
20 --- 22
20 --- 23
20 --- 24
20 --- 25
20 --- 31
20 --- 32
20 --- 33
20 --- 34
20 --- 35
20 --- 36
20 --- 37
20 --- 38
20 --- 39
20 --- 40
22 --- 35
38 <--x 22
22 --- 39
23 --- 33
23 --- 37
40 <--x 23
24 --- 36
39 <--x 24
24 --- 40
25 --- 34
37 <--x 25
25 --- 38
42 <--x 26
43 <--x 26
26 x--> 44
41 <--x 27
42 <--x 27
27 x--> 43
28 x--> 41
41 <--x 29
29 x--> 42
43 <--x 30
33 <--x 32
34 <--x 32
35 <--x 32
36 <--x 32
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
@settings(defaultLengthUnit = in)
sketch000 = startSketchOn(XY)
sketch000Profile000 = startProfile(sketch000, at = [0.22, 0.5])
|> xLine(length = -0.22)
|> yLine(length = -1)
|> xLine(length = 0.1)
|> line(end = [0.025, 0.1])
|> yLine(length = 0.789)
|> line(end = [0.095, 0.111])
|> close()
revolve000 = revolve(sketch000Profile000, axis = Y, angle = 360)
sketch002 = startSketchOn(YZ)
sketch002Profile000 = startProfile(sketch002, at = [-0.6, 0.02])
|> yLine(length = -0.04)
|> xLine(length = 0.9)
|> yLine(length = 0.04)
|> xLine(length = -0.9)
|> close()
cut000Extrude = extrude([sketch002Profile000], length = 0.2, bidirectionalLength = 0.2)
cut000 = subtract(revolve000, tools = cut000Extrude)

View File

@ -0,0 +1,217 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed subtract_regression12.kcl
---
[
{
"type": "StdLibCall",
"name": "startSketchOn",
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "revolve",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {
"angle": {
"value": {
"type": "Number",
"value": 360.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"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": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "startSketchOn",
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "extrude",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {
"bidirectionalLength": {
"value": {
"type": "Number",
"value": 0.2,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"length": {
"value": {
"type": "Number",
"value": 0.2,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "StdLibCall",
"name": "subtract",
"unlabeledArg": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": {
"tools": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
"sourceRange": []
}
]

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,31 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing subtract_regression12.kcl
---
@settings(defaultLengthUnit = in)
sketch000 = startSketchOn(XY)
sketch000Profile000 = startProfile(sketch000, at = [0.22, 0.5])
|> xLine(length = -0.22)
|> yLine(length = -1)
|> xLine(length = 0.1)
|> line(end = [0.025, 0.1])
|> yLine(length = 0.789)
|> line(end = [0.095, 0.111])
|> close()
revolve000 = revolve(sketch000Profile000, axis = Y, angle = 360)
sketch002 = startSketchOn(YZ)
sketch002Profile000 = startProfile(sketch002, at = [-0.6, 0.02])
|> yLine(length = -0.04)
|> xLine(length = 0.9)
|> yLine(length = 0.04)
|> xLine(length = -0.9)
|> close()
cut000Extrude = extrude([sketch002Profile000], length = 0.2, bidirectionalLength = 0.2)
cut000 = subtract(revolve000, tools = cut000Extrude)

View File

@ -1,4 +1,5 @@
import React, { useMemo, useState } from 'react' import type React from 'react'
import { useMemo, useEffect, useRef, useState } from 'react'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import { ActionButton } from '@src/components/ActionButton' import { ActionButton } from '@src/components/ActionButton'
@ -121,6 +122,7 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
data-is-current-arg={ data-is-current-arg={
argName === currentArgument?.name ? 'true' : 'false' argName === currentArgument?.name ? 'true' : 'false'
} }
type="button"
disabled={!isReviewing && currentArgument?.name === argName} disabled={!isReviewing && currentArgument?.name === argName}
onClick={() => { onClick={() => {
commandBarActor.send({ commandBarActor.send({
@ -244,13 +246,20 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
type ButtonProps = { bgClassName?: string; iconClassName?: string } type ButtonProps = { bgClassName?: string; iconClassName?: string }
function ReviewingButton({ bgClassName, iconClassName }: ButtonProps) { function ReviewingButton({ bgClassName, iconClassName }: ButtonProps) {
const buttonRef = useRef<HTMLButtonElement>(null)
useEffect(() => {
if (buttonRef.current) {
buttonRef.current.focus()
}
}, [])
return ( return (
<ActionButton <ActionButton
Element="button" Element="button"
autoFocus ref={buttonRef}
type="submit" type="submit"
form="review-form" form="review-form"
className="w-fit !p-0 rounded-sm hover:shadow" className="w-fit !p-0 rounded-sm hover:shadow focus:outline-current"
tabIndex={0}
data-testid="command-bar-submit" data-testid="command-bar-submit"
iconStart={{ iconStart={{
icon: 'checkmark', icon: 'checkmark',
@ -269,7 +278,8 @@ function GatheringArgsButton({ bgClassName, iconClassName }: ButtonProps) {
Element="button" Element="button"
type="submit" type="submit"
form="arg-form" form="arg-form"
className="w-fit !p-0 rounded-sm hover:shadow" className="w-fit !p-0 rounded-sm hover:shadow focus:outline-current"
tabIndex={0}
data-testid="command-bar-continue" data-testid="command-bar-continue"
iconStart={{ iconStart={{
icon: 'arrowRight', icon: 'arrowRight',

View File

@ -139,7 +139,7 @@ function CommandBarSelectionInput({
data: { data: {
selectionType: 'singleCodeCursor', selectionType: 'singleCodeCursor',
}, },
}) }) &&
setHasClearedSelection(true) setHasClearedSelection(true)
}, [arg]) }, [arg])

View File

@ -406,11 +406,17 @@ export const EngineStream = (props: {
// On various inputs save the camera state, in case we get disconnected. // On various inputs save the camera state, in case we get disconnected.
useEffect(() => { useEffect(() => {
// Only start saving after we are playing the stream (which means
// the scene is ready.)
// Also prevents us from stepping on the toes of the camera restoration.
if (engineStreamState.value !== EngineStreamState.Playing) return
const onInput = () => { const onInput = () => {
// Save the remote camera state to restore on stream restore. // Save the remote camera state to restore on stream restore.
// Fire-and-forget because we don't know when a camera movement is // Fire-and-forget because we don't know when a camera movement is
// completed on the engine side (there are no responses to data channel // completed on the engine side (there are no responses to data channel
// mouse movements.) // mouse movements.)
sceneInfra.camControls.saveRemoteCameraState().catch(trap) sceneInfra.camControls.saveRemoteCameraState().catch(trap)
} }
@ -426,7 +432,7 @@ export const EngineStream = (props: {
window.document.removeEventListener('scroll', onInput) window.document.removeEventListener('scroll', onInput)
window.document.removeEventListener('touchend', onInput) window.document.removeEventListener('touchend', onInput)
} }
}, []) }, [engineStreamState.value])
const isNetworkOkay = const isNetworkOkay =
overallState === NetworkHealthState.Ok || overallState === NetworkHealthState.Ok ||

View File

@ -12,12 +12,8 @@ import { useLoaderData } from 'react-router-dom'
import type { Actor, ContextFrom, Prop, SnapshotFrom, StateFrom } from 'xstate' import type { Actor, ContextFrom, Prop, SnapshotFrom, StateFrom } from 'xstate'
import { assign, fromPromise } from 'xstate' import { assign, fromPromise } from 'xstate'
import type { import type { OutputFormat3d } from '@rust/kcl-lib/bindings/ModelingCmd'
OutputFormat3d,
Point3d,
} from '@rust/kcl-lib/bindings/ModelingCmd'
import type { Node } from '@rust/kcl-lib/bindings/Node' import type { Node } from '@rust/kcl-lib/bindings/Node'
import type { Plane } from '@rust/kcl-lib/bindings/Plane'
import { useAppState } from '@src/AppState' import { useAppState } from '@src/AppState'
import { letEngineAnimateAndSyncCamAfter } from '@src/clientSideScene/CameraControls' import { letEngineAnimateAndSyncCamAfter } from '@src/clientSideScene/CameraControls'
@ -38,26 +34,16 @@ import useModelingMachineCommands from '@src/hooks/useStateMachineCommands'
import { useKclContext } from '@src/lang/KclProvider' import { useKclContext } from '@src/lang/KclProvider'
import { updateModelingState } from '@src/lang/modelingWorkflows' import { updateModelingState } from '@src/lang/modelingWorkflows'
import { import {
insertNamedConstant,
replaceValueAtNodePath,
sketchOnExtrudedFace, sketchOnExtrudedFace,
sketchOnOffsetPlane, sketchOnOffsetPlane,
splitPipedProfile, splitPipedProfile,
startSketchOnDefault, startSketchOnDefault,
} from '@src/lang/modifyAst' } from '@src/lang/modifyAst'
import { import {
artifactIsPlaneWithPaths,
doesSketchPipeNeedSplitting, doesSketchPipeNeedSplitting,
getNodeFromPath, getNodeFromPath,
isCursorInFunctionDefinition,
traverse, traverse,
} from '@src/lang/queryAst' } from '@src/lang/queryAst'
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
import {
getFaceCodeRef,
getPathsFromArtifact,
getPlaneFromArtifact,
} from '@src/lang/std/artifactGraph'
import { import {
EngineConnectionStateType, EngineConnectionStateType,
EngineConnectionEvents, EngineConnectionEvents,
@ -66,7 +52,6 @@ import { err, reportRejection, trap, reject } from '@src/lib/trap'
import { isNonNullable, platform, uuidv4 } from '@src/lib/utils' import { isNonNullable, platform, uuidv4 } from '@src/lib/utils'
import { promptToEditFlow } from '@src/lib/promptToEdit' import { promptToEditFlow } from '@src/lib/promptToEdit'
import type { FileMeta } from '@src/lib/types' import type { FileMeta } from '@src/lib/types'
import { kclEditorActor } from '@src/machines/kclEditorMachine'
import { commandBarActor } from '@src/lib/singletons' import { commandBarActor } from '@src/lib/singletons'
import { useToken, useSettings } from '@src/lib/singletons' import { useToken, useSettings } from '@src/lib/singletons'
import type { IndexLoaderData } from '@src/lib/types' import type { IndexLoaderData } from '@src/lib/types'
@ -98,23 +83,13 @@ import {
} from '@src/lib/singletons' } from '@src/lib/singletons'
import type { MachineManager } from '@src/components/MachineManagerProvider' import type { MachineManager } from '@src/components/MachineManagerProvider'
import { MachineManagerContext } from '@src/components/MachineManagerProvider' import { MachineManagerContext } from '@src/components/MachineManagerProvider'
import { import { updateSelections } from '@src/lib/selections'
handleSelectionBatch, import { updateSketchDetailsNodePaths } from '@src/lang/util'
updateSelections,
type Selections,
} from '@src/lib/selections'
import {
crossProduct,
isCursorInSketchCommandRange,
updateSketchDetailsNodePaths,
} from '@src/lang/util'
import { import {
modelingMachineCommandConfig, modelingMachineCommandConfig,
type ModelingCommandSchema, type ModelingCommandSchema,
} from '@src/lib/commandBarConfigs/modelingCommandConfig' } from '@src/lib/commandBarConfigs/modelingCommandConfig'
import type { import type {
KclValue,
PathToNode,
PipeExpression, PipeExpression,
Program, Program,
VariableDeclaration, VariableDeclaration,
@ -320,229 +295,6 @@ export const ModelingMachineProvider = ({
}, },
} }
}), }),
'Set selection': assign(
({ context: { selectionRanges, sketchDetails }, event }) => {
// this was needed for ts after adding 'Set selection' action to on done modal events
const setSelections =
('data' in event &&
event.data &&
'selectionType' in event.data &&
event.data) ||
('output' in event &&
event.output &&
'selectionType' in event.output &&
event.output) ||
null
if (!setSelections) return {}
let selections: Selections = {
graphSelections: [],
otherSelections: [],
}
if (setSelections.selectionType === 'singleCodeCursor') {
if (!setSelections.selection && editorManager.isShiftDown) {
// if the user is holding shift, but they didn't select anything
// don't nuke their other selections (frustrating to have one bad click ruin your
// whole selection)
selections = {
graphSelections: selectionRanges.graphSelections,
otherSelections: selectionRanges.otherSelections,
}
} else if (
!setSelections.selection &&
!editorManager.isShiftDown
) {
selections = {
graphSelections: [],
otherSelections: [],
}
} else if (
setSelections.selection &&
!editorManager.isShiftDown
) {
selections = {
graphSelections: [setSelections.selection],
otherSelections: [],
}
} else if (setSelections.selection && editorManager.isShiftDown) {
// selecting and deselecting multiple objects
/**
* There are two scenarios:
* 1. General case:
* When selecting and deselecting edges,
* faces or segment (during sketch edit)
* we use its artifact ID to identify the selection
* 2. Initial sketch setup:
* The artifact is not yet created
* so we use the codeRef.range
*/
let updatedSelections: typeof selectionRanges.graphSelections
// 1. General case: Artifact exists, use its ID
if (setSelections.selection.artifact?.id) {
// check if already selected
const alreadySelected = selectionRanges.graphSelections.some(
(selection) =>
selection.artifact?.id ===
setSelections.selection?.artifact?.id
)
if (
alreadySelected &&
setSelections.selection?.artifact?.id
) {
// remove it
updatedSelections = selectionRanges.graphSelections.filter(
(selection) =>
selection.artifact?.id !==
setSelections.selection?.artifact?.id
)
} else {
// add it
updatedSelections = [
...selectionRanges.graphSelections,
setSelections.selection,
]
}
} else {
// 2. Initial sketch setup: Artifact not yet created use codeRef.range
const selectionRange = JSON.stringify(
setSelections.selection?.codeRef?.range
)
// check if already selected
const alreadySelected = selectionRanges.graphSelections.some(
(selection) => {
const existingRange = JSON.stringify(
selection.codeRef?.range
)
return existingRange === selectionRange
}
)
if (
alreadySelected &&
setSelections.selection?.codeRef?.range
) {
// remove it
updatedSelections = selectionRanges.graphSelections.filter(
(selection) =>
JSON.stringify(selection.codeRef?.range) !==
selectionRange
)
} else {
// add it
updatedSelections = [
...selectionRanges.graphSelections,
setSelections.selection,
]
}
}
selections = {
graphSelections: updatedSelections,
otherSelections: selectionRanges.otherSelections,
}
}
const {
engineEvents,
codeMirrorSelection,
updateSceneObjectColors,
} = handleSelectionBatch({
selections,
})
if (codeMirrorSelection) {
kclEditorActor.send({
type: 'setLastSelectionEvent',
data: {
codeMirrorSelection,
scrollIntoView: setSelections.scrollIntoView ?? false,
},
})
}
// If there are engine commands that need sent off, send them
// TODO: This should be handled outside of an action as its own
// actor, so that the system state is more controlled.
engineEvents &&
engineEvents.forEach((event) => {
engineCommandManager
.sendSceneCommand(event)
.catch(reportRejection)
})
updateSceneObjectColors()
return {
selectionRanges: selections,
}
}
if (setSelections.selectionType === 'mirrorCodeMirrorSelections') {
return {
selectionRanges: setSelections.selection,
}
}
if (
setSelections.selectionType === 'axisSelection' ||
setSelections.selectionType === 'defaultPlaneSelection'
) {
if (editorManager.isShiftDown) {
selections = {
graphSelections: selectionRanges.graphSelections,
otherSelections: [setSelections.selection],
}
} else {
selections = {
graphSelections: [],
otherSelections: [setSelections.selection],
}
}
return {
selectionRanges: selections,
}
}
if (setSelections.selectionType === 'completeSelection') {
const codeMirrorSelection = editorManager.createEditorSelection(
setSelections.selection
)
kclEditorActor.send({
type: 'setLastSelectionEvent',
data: {
codeMirrorSelection,
scrollIntoView: false,
},
})
if (!sketchDetails)
return {
selectionRanges: setSelections.selection,
}
return {
selectionRanges: setSelections.selection,
sketchDetails: {
...sketchDetails,
sketchEntryNodePath:
setSelections.updatedSketchEntryNodePath ||
sketchDetails?.sketchEntryNodePath ||
[],
sketchNodePaths:
setSelections.updatedSketchNodePaths ||
sketchDetails?.sketchNodePaths ||
[],
planeNodePath:
setSelections.updatedPlaneNodePath ||
sketchDetails?.planeNodePath ||
[],
},
}
}
return {}
}
),
}, },
guards: { guards: {
'has valid selection for deletion': ({ 'has valid selection for deletion': ({
@ -552,35 +304,6 @@ export const ModelingMachineProvider = ({
if (selectionRanges.graphSelections.length <= 0) return false if (selectionRanges.graphSelections.length <= 0) return false
return true return true
}, },
'is-error-free': () => {
return kclManager.errors.length === 0 && !kclManager.hasErrors()
},
'Selection is on face': ({ context: { selectionRanges }, event }) => {
if (event.type !== 'Enter sketch') return false
if (event.data?.forceNewSketch) return false
if (artifactIsPlaneWithPaths(selectionRanges)) {
return true
} else if (selectionRanges.graphSelections[0]?.artifact) {
// See if the selection is "close enough" to be coerced to the plane later
const maybePlane = getPlaneFromArtifact(
selectionRanges.graphSelections[0].artifact,
kclManager.artifactGraph
)
return !err(maybePlane)
}
if (
isCursorInFunctionDefinition(
kclManager.ast,
selectionRanges.graphSelections[0]
)
) {
return false
}
return !!isCursorInSketchCommandRange(
kclManager.artifactGraph,
selectionRanges
)
},
'Has exportable geometry': () => 'Has exportable geometry': () =>
!kclManager.hasErrors() && kclManager.ast.body.length > 0, !kclManager.hasErrors() && kclManager.ast.body.length > 0,
}, },
@ -850,123 +573,6 @@ export const ModelingMachineProvider = ({
animateTargetId: input.planeId, animateTargetId: input.planeId,
} }
}), }),
'animate-to-sketch': fromPromise(
async ({ input: { selectionRanges } }) => {
const artifact = selectionRanges.graphSelections[0].artifact
const plane = getPlaneFromArtifact(
artifact,
kclManager.artifactGraph
)
if (err(plane)) return Promise.reject(plane)
// if the user selected a segment, make sure we enter the right sketch as there can be multiple on a plane
// but still works if the user selected a plane/face by defaulting to the first path
const mainPath =
artifact?.type === 'segment' || artifact?.type === 'solid2d'
? artifact?.pathId
: plane?.pathIds[0]
let sketch: KclValue | null = null
let planeVar: Plane | null = null
for (const variable of Object.values(
kclManager.execState.variables
)) {
// find programMemory that matches path artifact
if (
variable?.type === 'Sketch' &&
variable.value.artifactId === mainPath
) {
sketch = variable
break
}
if (
// if the variable is an sweep, check if the underlying sketch matches the artifact
variable?.type === 'Solid' &&
variable.value.sketch.on.type === 'plane' &&
variable.value.sketch.artifactId === mainPath
) {
sketch = {
type: 'Sketch',
value: variable.value.sketch,
}
break
}
if (
variable?.type === 'Plane' &&
plane.id === variable.value.id
) {
planeVar = variable.value
}
}
if (!sketch || sketch.type !== 'Sketch') {
if (artifact?.type !== 'plane')
return Promise.reject(new Error('No sketch'))
const planeCodeRef = getFaceCodeRef(artifact)
if (planeVar && planeCodeRef) {
const toTuple = (point: Point3d): [number, number, number] => [
point.x,
point.y,
point.z,
]
const planPath = getNodePathFromSourceRange(
kclManager.ast,
planeCodeRef.range
)
await letEngineAnimateAndSyncCamAfter(
engineCommandManager,
artifact.id
)
const normal = crossProduct(planeVar.xAxis, planeVar.yAxis)
return {
sketchEntryNodePath: [],
planeNodePath: planPath,
sketchNodePaths: [],
zAxis: toTuple(normal),
yAxis: toTuple(planeVar.yAxis),
origin: toTuple(planeVar.origin),
}
}
return Promise.reject(new Error('No sketch'))
}
const info = await sceneEntitiesManager.getSketchOrientationDetails(
sketch.value
)
await letEngineAnimateAndSyncCamAfter(
engineCommandManager,
info?.sketchDetails?.faceId || ''
)
const sketchArtifact = kclManager.artifactGraph.get(mainPath)
if (sketchArtifact?.type !== 'path')
return Promise.reject(new Error('No sketch artifact'))
const sketchPaths = getPathsFromArtifact({
artifact: kclManager.artifactGraph.get(plane.id),
sketchPathToNode: sketchArtifact?.codeRef?.pathToNode,
artifactGraph: kclManager.artifactGraph,
ast: kclManager.ast,
})
if (err(sketchPaths)) return Promise.reject(sketchPaths)
let codeRef = getFaceCodeRef(plane)
if (!codeRef) return Promise.reject(new Error('No plane codeRef'))
// codeRef.pathToNode is not always populated correctly
const planeNodePath = getNodePathFromSourceRange(
kclManager.ast,
codeRef.range
)
return {
sketchEntryNodePath: sketchArtifact.codeRef.pathToNode || [],
sketchNodePaths: sketchPaths,
planeNodePath,
zAxis: info.sketchDetails.zAxis || null,
yAxis: info.sketchDetails.yAxis || null,
origin: info.sketchDetails.origin.map(
(a) => a / sceneInfra._baseUnitMultiplier
) as [number, number, number],
animateTargetId: info?.sketchDetails?.faceId || '',
}
}
),
'Get horizontal info': fromPromise( 'Get horizontal info': fromPromise(
async ({ input: { selectionRanges, sketchDetails } }) => { async ({ input: { selectionRanges, sketchDetails } }) => {
const { modifiedAst, pathToNodeMap, exprInsertIndex } = const { modifiedAst, pathToNodeMap, exprInsertIndex } =
@ -1371,130 +977,6 @@ export const ModelingMachineProvider = ({
} }
} }
), ),
'Apply named value constraint': fromPromise(
async ({ input: { selectionRanges, sketchDetails, data } }) => {
if (!sketchDetails) {
return Promise.reject(new Error('No sketch details'))
}
if (!data) {
return Promise.reject(new Error('No data from command flow'))
}
let pResult = parse(recast(kclManager.ast))
if (trap(pResult) || !resultIsOk(pResult))
return Promise.reject(new Error('Unexpected compilation error'))
let parsed = pResult.program
let result: {
modifiedAst: Node<Program>
pathToReplaced: PathToNode | null
exprInsertIndex: number
} = {
modifiedAst: parsed,
pathToReplaced: null,
exprInsertIndex: -1,
}
// If the user provided a constant name,
// we need to insert the named constant
// and then replace the node with the constant's name.
if ('variableName' in data.namedValue) {
const astAfterReplacement = replaceValueAtNodePath({
ast: parsed,
pathToNode: data.currentValue.pathToNode,
newExpressionString: data.namedValue.variableName,
})
if (trap(astAfterReplacement)) {
return Promise.reject(astAfterReplacement)
}
const parseResultAfterInsertion = parse(
recast(
insertNamedConstant({
node: astAfterReplacement.modifiedAst,
newExpression: data.namedValue,
})
)
)
result.exprInsertIndex = data.namedValue.insertIndex
if (
trap(parseResultAfterInsertion) ||
!resultIsOk(parseResultAfterInsertion)
)
return Promise.reject(parseResultAfterInsertion)
result = {
modifiedAst: parseResultAfterInsertion.program,
pathToReplaced: astAfterReplacement.pathToReplaced,
exprInsertIndex: result.exprInsertIndex,
}
} else if ('valueText' in data.namedValue) {
// If they didn't provide a constant name,
// just replace the node with the value.
const astAfterReplacement = replaceValueAtNodePath({
ast: parsed,
pathToNode: data.currentValue.pathToNode,
newExpressionString: data.namedValue.valueText,
})
if (trap(astAfterReplacement)) {
return Promise.reject(astAfterReplacement)
}
// The `replacer` function returns a pathToNode that assumes
// an identifier is also being inserted into the AST, creating an off-by-one error.
// This corrects that error, but TODO we should fix this upstream
// to avoid this kind of error in the future.
astAfterReplacement.pathToReplaced[1][0] =
(astAfterReplacement.pathToReplaced[1][0] as number) - 1
result = astAfterReplacement
}
pResult = parse(recast(result.modifiedAst))
if (trap(pResult) || !resultIsOk(pResult))
return Promise.reject(new Error('Unexpected compilation error'))
parsed = pResult.program
if (trap(parsed)) return Promise.reject(parsed)
if (!result.pathToReplaced)
return Promise.reject(new Error('No path to replaced node'))
const {
updatedSketchEntryNodePath,
updatedSketchNodePaths,
updatedPlaneNodePath,
} = updateSketchDetailsNodePaths({
sketchEntryNodePath: sketchDetails.sketchEntryNodePath,
sketchNodePaths: sketchDetails.sketchNodePaths,
planeNodePath: sketchDetails.planeNodePath,
exprInsertIndex: result.exprInsertIndex,
})
const updatedAst =
await sceneEntitiesManager.updateAstAndRejigSketch(
updatedSketchEntryNodePath,
updatedSketchNodePaths,
updatedPlaneNodePath,
parsed,
sketchDetails.zAxis,
sketchDetails.yAxis,
sketchDetails.origin
)
if (err(updatedAst)) return Promise.reject(updatedAst)
await codeManager.updateEditorWithAstAndWriteToFile(
updatedAst.newAst
)
const selection = updateSelections(
{ 0: result.pathToReplaced },
selectionRanges,
updatedAst.newAst
)
if (err(selection)) return Promise.reject(selection)
return {
selectionType: 'completeSelection',
selection,
updatedSketchEntryNodePath,
updatedSketchNodePaths,
updatedPlaneNodePath,
}
}
),
'set-up-draft-circle': fromPromise( 'set-up-draft-circle': fromPromise(
async ({ input: { sketchDetails, data } }) => { async ({ input: { sketchDetails, data } }) => {
if (!sketchDetails || !data) if (!sketchDetails || !data)
@ -1608,38 +1090,6 @@ export const ModelingMachineProvider = ({
return result return result
} }
), ),
'setup-client-side-sketch-segments': fromPromise(
async ({ input: { sketchDetails, selectionRanges } }) => {
if (!sketchDetails) return
if (!sketchDetails.sketchEntryNodePath?.length) return
sceneInfra.resetMouseListeners()
await sceneEntitiesManager.setupSketch({
sketchEntryNodePath: sketchDetails?.sketchEntryNodePath || [],
sketchNodePaths: sketchDetails.sketchNodePaths,
forward: sketchDetails.zAxis,
up: sketchDetails.yAxis,
position: sketchDetails.origin,
maybeModdedAst: kclManager.ast,
selectionRanges,
})
sceneInfra.resetMouseListeners()
sceneEntitiesManager.setupSketchIdleCallbacks({
sketchEntryNodePath: sketchDetails?.sketchEntryNodePath || [],
forward: sketchDetails.zAxis,
up: sketchDetails.yAxis,
position: sketchDetails.origin,
sketchNodePaths: sketchDetails.sketchNodePaths,
planeNodePath: sketchDetails.planeNodePath,
// We will want to pass sketchTools here
// to add their interactions
})
// We will want to update the context with sketchTools.
// They'll be used for their .destroy() in tearDownSketch
return undefined
}
),
'split-sketch-pipe-if-needed': fromPromise( 'split-sketch-pipe-if-needed': fromPromise(
async ({ input: { sketchDetails } }) => { async ({ input: { sketchDetails } }) => {
if (!sketchDetails) return reject('No sketch details') if (!sketchDetails) return reject('No sketch details')
@ -1828,12 +1278,12 @@ export const ModelingMachineProvider = ({
) )
} }
} }
let filePath = file?.path // route to main.kcl by default for web and desktop
let filePath: string = PROJECT_ENTRYPOINT
const possibleFileName = file?.path
if (possibleFileName && isDesktop()) {
// When prompt to edit finishes, try to route to the file they were in otherwise go to main.kcl // When prompt to edit finishes, try to route to the file they were in otherwise go to main.kcl
if (filePath) { filePath = window.electron.path.relative(basePath, possibleFileName)
filePath = window.electron.path.relative(basePath, filePath)
} else {
filePath = PROJECT_ENTRYPOINT
} }
return await promptToEditFlow({ return await promptToEditFlow({
projectFiles, projectFiles,

View File

@ -9,9 +9,11 @@ import {
ZOO_STUDIO_PROTOCOL, ZOO_STUDIO_PROTOCOL,
} from '@src/lib/constants' } from '@src/lib/constants'
import { isDesktop } from '@src/lib/isDesktop' import { isDesktop } from '@src/lib/isDesktop'
import { Themes, getSystemTheme } from '@src/lib/theme' import { Themes, darkModeMatcher, setThemeClass } from '@src/lib/theme'
import toast from 'react-hot-toast' import toast from 'react-hot-toast'
import { platform } from '@src/lib/utils' import { platform } from '@src/lib/utils'
import { Logo } from '@src/components/Logo'
import { useEffect } from 'react'
/** /**
* This component is a handler that checks if a certain query parameter * This component is a handler that checks if a certain query parameter
@ -19,17 +21,23 @@ import { platform } from '@src/lib/utils'
* want to open the current page in the desktop app. * want to open the current page in the desktop app.
*/ */
export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => { export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
const theme = getSystemTheme()
const buttonClasses = const buttonClasses =
'bg-transparent flex-0 hover:bg-primary/10 dark:hover:bg-primary/10' 'bg-transparent flex-0 hover:bg-primary/10 dark:hover:bg-primary/10'
const pathLogomarkSvg = `${isDesktop() ? '.' : ''}/zma-logomark${
theme === Themes.Light ? '-dark' : ''
}.svg`
const [searchParams, setSearchParams] = useSearchParams() const [searchParams, setSearchParams] = useSearchParams()
// We also ignore this param on desktop, as it is redundant // We also ignore this param on desktop, as it is redundant
const hasAskToOpenParam = const hasAskToOpenParam =
!isDesktop() && searchParams.has(ASK_TO_OPEN_QUERY_PARAM) !isDesktop() && searchParams.has(ASK_TO_OPEN_QUERY_PARAM)
// Watch the system theme for changes
useEffect(() => {
const listener = (e: MediaQueryListEvent) => {
setThemeClass(e.matches ? Themes.Dark : Themes.Light)
}
darkModeMatcher?.addEventListener('change', listener)
return () => darkModeMatcher?.removeEventListener('change', listener)
}, [])
/** /**
* This function removes the query param to ask to open in desktop app * This function removes the query param to ask to open in desktop app
* and then navigates to the same route but with our custom protocol * and then navigates to the same route but with our custom protocol
@ -73,17 +81,12 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
appear appear
show={true} show={true}
as="div" as="div"
className={ className="fixed inset-0 grid p-4 place-content-center bg-chalkboard-10 dark:bg-chalkboard-110"
theme +
` fixed inset-0 grid p-4 place-content-center ${
theme === Themes.Dark ? '!bg-chalkboard-110 text-chalkboard-20' : ''
}`
}
> >
<Transition.Child <Transition.Child
as="div" as="div"
className={`max-w-3xl py-6 px-10 flex flex-col items-center gap-8 className={`max-w-3xl py-6 px-10 flex flex-col items-center gap-12
mx-auto border rounded-lg shadow-lg dark:bg-chalkboard-100`} mx-auto border rounded-lg shadow-lg bg-chalkboard-10 dark:bg-chalkboard-100`}
enter="ease-out duration-300" enter="ease-out duration-300"
enterFrom="opacity-0 scale-95" enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100" enterTo="opacity-100 scale-100"
@ -92,19 +95,15 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
leaveTo="opacity-0 scale-95" leaveTo="opacity-0 scale-95"
style={{ zIndex: 10 }} style={{ zIndex: 10 }}
> >
<div> <h1 className="text-2xl text-center ">
<h1 className="text-2xl"> <div className="mb-4">Launching </div>
Launching{' '} <div className="flex items-center gap-4 flex-wrap text-4xl">
<img <Logo className="w-40" aria-label="Zoo" />
src={pathLogomarkSvg} <span>Design Studio</span>
className="w-48"
alt="Zoo Design Studio"
/>
</h1>
</div> </div>
<p className="text-primary flex items-center gap-2"> </h1>
Choose where to open this link... <div className="flex flex-col gap-4 items-center">
</p> <p className="text-primary">Choose where to open this link...</p>
<div className="flex flex-col md:flex-row items-start justify-between gap-4 xl:gap-8"> <div className="flex flex-col md:flex-row items-start justify-between gap-4 xl:gap-8">
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<ActionButton <ActionButton
@ -137,6 +136,7 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
Continue to web app Continue to web app
</ActionButton> </ActionButton>
</div> </div>
</div>
</Transition.Child> </Transition.Child>
</Transition> </Transition>
) : ( ) : (

View File

@ -159,6 +159,7 @@ export function ToastTextToCadSuccess({
projectName, projectName,
fileName, fileName,
isProjectNew, isProjectNew,
rootProjectName,
}: { }: {
toastId: string toastId: string
data: TextToCad_type & { fileName: string } data: TextToCad_type & { fileName: string }
@ -170,6 +171,7 @@ export function ToastTextToCadSuccess({
projectName: string projectName: string
fileName: string fileName: string
isProjectNew: boolean isProjectNew: boolean
rootProjectName: string
}) { }) {
const wrapperRef = useRef<HTMLDivElement | null>(null) const wrapperRef = useRef<HTMLDivElement | null>(null)
const canvasRef = useRef<HTMLCanvasElement | null>(null) const canvasRef = useRef<HTMLCanvasElement | null>(null)
@ -361,26 +363,23 @@ export function ToastTextToCadSuccess({
if (isDesktop()) { if (isDesktop()) {
// Delete the file from the project // Delete the file from the project
if (projectName && fileName) {
// You are in the new workflow for text to cad at the global application level
if (isProjectNew) { if (isProjectNew) {
// Delete the entire project if it was newly created from text to CAD // Delete the entire project if it was newly created from text to CAD
systemIOActor.send({
type: SystemIOMachineEvents.deleteProject,
data: {
requestedProjectName: rootProjectName,
},
})
} else if (projectName && fileName) {
// deletes the folder when inside the modeling page
// The TTC Create will make a subdir, delete that dir with the main.kcl as well
systemIOActor.send({ systemIOActor.send({
type: SystemIOMachineEvents.deleteProject, type: SystemIOMachineEvents.deleteProject,
data: { data: {
requestedProjectName: projectName, requestedProjectName: projectName,
}, },
}) })
} else {
// Only delete the file if the project was preexisting
systemIOActor.send({
type: SystemIOMachineEvents.deleteKCLFile,
data: {
requestedProjectName: projectName,
requestedFileName: fileName,
},
})
}
} }
} }

View File

@ -924,7 +924,7 @@ class EngineConnection extends EventTarget {
}, },
} }
// This is required for when KCMA is running stand-alone / within desktop app. // This is required for when the app is running stand-alone / within desktop app.
// Otherwise when run in a browser, the token is sent implicitly via // Otherwise when run in a browser, the token is sent implicitly via
// the Cookie header. // the Cookie header.
if (this.token) { if (this.token) {
@ -998,7 +998,7 @@ class EngineConnection extends EventTarget {
if (!message.success) { if (!message.success) {
const errorsString = message?.errors const errorsString = message?.errors
?.map((error) => { ?.map((error) => {
return ` - ${error.error_code}: ${error.message}` return ` - ${error?.error_code || 'Unknown error'}: ${error?.message || 'Unknown message'}`
}) })
.join('\n') .join('\n')
if (message.request_id) { if (message.request_id) {
@ -1016,7 +1016,7 @@ class EngineConnection extends EventTarget {
} }
const firstError = message?.errors[0] const firstError = message?.errors[0]
if (firstError.error_code === 'auth_token_invalid') { if (firstError?.error_code === 'auth_token_invalid') {
this.state = { this.state = {
type: EngineConnectionStateType.Disconnecting, type: EngineConnectionStateType.Disconnecting,
value: { value: {
@ -1030,7 +1030,7 @@ class EngineConnection extends EventTarget {
this.disconnectAll() this.disconnectAll()
} }
if (firstError.error_code === 'internal_api') { if (firstError?.error_code === 'internal_api') {
this.state = { this.state = {
type: EngineConnectionStateType.Disconnecting, type: EngineConnectionStateType.Disconnecting,
value: { value: {

View File

@ -10,12 +10,16 @@ import {
kclSamplesManifestWithNoMultipleFiles, kclSamplesManifestWithNoMultipleFiles,
} from '@src/lib/kclSamples' } from '@src/lib/kclSamples'
import { getUniqueProjectName } from '@src/lib/desktopFS' import { getUniqueProjectName } from '@src/lib/desktopFS'
import { IS_ML_EXPERIMENTAL, PROJECT_ENTRYPOINT } from '@src/lib/constants' import { IS_ML_EXPERIMENTAL } from '@src/lib/constants'
import toast from 'react-hot-toast' import toast from 'react-hot-toast'
import { reportRejection } from '@src/lib/trap' import { reportRejection } from '@src/lib/trap'
import { relevantFileExtensions } from '@src/lang/wasmUtils' import { relevantFileExtensions } from '@src/lang/wasmUtils'
import { getStringAfterLastSeparator, webSafePathSplit } from '@src/lib/paths' import {
import { FILE_EXT } from '@src/lib/constants' getStringAfterLastSeparator,
joinOSPaths,
webSafePathSplit,
} from '@src/lib/paths'
import { getAllSubDirectoriesAtProjectRoot } from '@src/machines/systemIO/snapshotContext'
function onSubmitKCLSampleCreation({ function onSubmitKCLSampleCreation({
sample, sample,
@ -69,20 +73,32 @@ function onSubmitKCLSampleCreation({
}) })
} }
if (requestedFiles.length === 1) {
/** /**
* Navigates to the single file that could be renamed on disk for duplicates * When adding assemblies to an existing project create the assembly into a unique sub directory
*/ */
const folderNameBecomesKCLFileName = projectPathPart + FILE_EXT if (!isProjectNew) {
// If the project is new create the single file as main.kcl requestedFiles.forEach((requestedFile) => {
const requestedFileNameWithExtension = isProjectNew const subDirectoryName = projectPathPart
? PROJECT_ENTRYPOINT const firstLevelDirectories = getAllSubDirectoriesAtProjectRoot({
: folderNameBecomesKCLFileName projectFolderName: requestedFile.requestedProjectName,
})
const uniqueSubDirectoryName = getUniqueProjectName(
subDirectoryName,
firstLevelDirectories
)
requestedFile.requestedProjectName = joinOSPaths(
requestedFile.requestedProjectName,
uniqueSubDirectoryName
)
})
}
if (requestedFiles.length === 1) {
systemIOActor.send({ systemIOActor.send({
type: SystemIOMachineEvents.importFileFromURL, type: SystemIOMachineEvents.importFileFromURL,
data: { data: {
requestedProjectName: requestedFiles[0].requestedProjectName, requestedProjectName: requestedFiles[0].requestedProjectName,
requestedFileNameWithExtension: requestedFileNameWithExtension, requestedFileNameWithExtension: requestedFiles[0].requestedFileName,
requestedCode: requestedFiles[0].requestedCode, requestedCode: requestedFiles[0].requestedCode,
}, },
}) })
@ -278,8 +294,7 @@ export function createApplicationCommands({
return value return value
}, },
options: ({ argumentsToSubmit }) => { options: ({ argumentsToSubmit }) => {
const samples = const samples = isDesktop()
isDesktop() && argumentsToSubmit.method !== 'existingProject'
? everyKclSample ? everyKclSample
: kclSamplesManifestWithNoMultipleFiles : kclSamplesManifestWithNoMultipleFiles
return samples.map((sample) => { return samples.map((sample) => {
@ -296,17 +311,10 @@ export function createApplicationCommands({
skip: true, skip: true,
options: ({ argumentsToSubmit }, _) => { options: ({ argumentsToSubmit }, _) => {
if (isDesktop() && typeof argumentsToSubmit.sample === 'string') { if (isDesktop() && typeof argumentsToSubmit.sample === 'string') {
const kclSample = findKclSample(argumentsToSubmit.sample)
if (kclSample && kclSample.files.length > 1) {
return [
{ name: 'New project', value: 'newProject', isCurrent: true },
]
} else {
return [ return [
{ name: 'New project', value: 'newProject', isCurrent: true }, { name: 'New project', value: 'newProject', isCurrent: true },
{ name: 'Existing project', value: 'existingProject' }, { name: 'Existing project', value: 'existingProject' },
] ]
}
} else { } else {
return [{ name: 'Overwrite', value: 'existingProject' }] return [{ name: 'Overwrite', value: 'existingProject' }]
} }

View File

@ -478,7 +478,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
required: true, required: true,
defaultValue: 'Axis', defaultValue: 'Axis',
options: [ options: [
{ name: 'Axis', isCurrent: true, value: 'Axis' }, { name: 'Sketch Axis', isCurrent: true, value: 'Axis' },
{ name: 'Edge', isCurrent: false, value: 'Edge' }, { name: 'Edge', isCurrent: false, value: 'Edge' },
], ],
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit), hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
@ -489,6 +489,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
commandContext.argumentsToSubmit.axisOrEdge as string commandContext.argumentsToSubmit.axisOrEdge as string
), ),
inputType: 'options', inputType: 'options',
displayName: 'Sketch Axis',
options: [ options: [
{ name: 'X Axis', isCurrent: true, value: 'X' }, { name: 'X Axis', isCurrent: true, value: 'X' },
{ name: 'Y Axis', isCurrent: false, value: 'Y' }, { name: 'Y Axis', isCurrent: false, value: 'Y' },

View File

@ -1,6 +1,11 @@
import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants' import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants'
import { isPlaywright } from '@src/lib/isPlaywright' import { isPlaywright } from '@src/lib/isPlaywright'
import { engineCommandManager, kclManager } from '@src/lib/singletons' import {
engineCommandManager,
kclManager,
sceneInfra,
settingsActor,
} from '@src/lib/singletons'
import { import {
engineStreamZoomToFit, engineStreamZoomToFit,
engineViewIsometricWithoutGeometryPresent, engineViewIsometricWithoutGeometryPresent,
@ -22,6 +27,15 @@ export async function resetCameraPosition() {
if (isPlaywright()) { if (isPlaywright()) {
await engineStreamZoomToFit({ engineCommandManager, padding }) await engineStreamZoomToFit({ engineCommandManager, padding })
} else { } else {
// Get user camera projection
const cameraProjection =
settingsActor.getSnapshot().context.modeling.cameraProjection.current
// We need to keep the users projection setting when resetting their camera
if (cameraProjection === 'perspective') {
await sceneInfra.camControls.usePerspectiveCamera()
}
// If the scene is empty you cannot use view_isometric, it will not move the camera // If the scene is empty you cannot use view_isometric, it will not move the camera
if (kclManager.isAstBodyEmpty(kclManager.ast)) { if (kclManager.isAstBodyEmpty(kclManager.ast)) {
await engineViewIsometricWithoutGeometryPresent({ await engineViewIsometricWithoutGeometryPresent({
@ -29,6 +43,7 @@ export async function resetCameraPosition() {
unit: unit:
kclManager.fileSettings.defaultLengthUnit || kclManager.fileSettings.defaultLengthUnit ||
DEFAULT_DEFAULT_LENGTH_UNIT, DEFAULT_DEFAULT_LENGTH_UNIT,
cameraProjection,
}) })
} else { } else {
await engineViewIsometricWithGeometryPresent({ await engineViewIsometricWithGeometryPresent({

View File

@ -6,9 +6,9 @@ import {
ToastTextToCadError, ToastTextToCadError,
ToastTextToCadSuccess, ToastTextToCadSuccess,
} from '@src/components/ToastTextToCad' } from '@src/components/ToastTextToCad'
import { FILE_EXT, PROJECT_ENTRYPOINT } from '@src/lib/constants' import { PROJECT_ENTRYPOINT } from '@src/lib/constants'
import crossPlatformFetch from '@src/lib/crossPlatformFetch' import crossPlatformFetch from '@src/lib/crossPlatformFetch'
import { getNextFileName } from '@src/lib/desktopFS' import { getUniqueProjectName } from '@src/lib/desktopFS'
import { isDesktop } from '@src/lib/isDesktop' import { isDesktop } from '@src/lib/isDesktop'
import { kclManager, systemIOActor } from '@src/lib/singletons' import { kclManager, systemIOActor } from '@src/lib/singletons'
import { import {
@ -17,6 +17,8 @@ import {
} from '@src/machines/systemIO/utils' } from '@src/machines/systemIO/utils'
import { reportRejection } from '@src/lib/trap' import { reportRejection } from '@src/lib/trap'
import { toSync } from '@src/lib/utils' import { toSync } from '@src/lib/utils'
import { getAllSubDirectoriesAtProjectRoot } from '@src/machines/systemIO/snapshotContext'
import { joinOSPaths } from '@src/lib/paths'
export async function submitTextToCadPrompt( export async function submitTextToCadPrompt(
prompt: string, prompt: string,
@ -173,7 +175,8 @@ export async function submitAndAwaitTextToKclSystemIO({
} }
) )
let newFileName = '' let newFileName = PROJECT_ENTRYPOINT
let uniqueProjectName = projectName
const textToCadOutputCreated = await textToCadComplete const textToCadOutputCreated = await textToCadComplete
.catch((e) => { .catch((e) => {
@ -197,30 +200,28 @@ export async function submitAndAwaitTextToKclSystemIO({
const TRUNCATED_PROMPT_LENGTH = 24 const TRUNCATED_PROMPT_LENGTH = 24
// Only add the prompt name if it is a preexisting project // Only add the prompt name if it is a preexisting project
newFileName = `${value.prompt const subDirectoryAsPromptName = `${value.prompt
.slice(0, TRUNCATED_PROMPT_LENGTH) .slice(0, TRUNCATED_PROMPT_LENGTH)
.replace(/\s/gi, '-') .replace(/\s/gi, '-')
.replace(/\W/gi, '-') .replace(/\W/gi, '-')
.toLowerCase()}${FILE_EXT}` .toLowerCase()}`
// If the project is new generate a main.kcl
if (isProjectNew) {
newFileName = PROJECT_ENTRYPOINT
}
if (isDesktop()) { if (isDesktop()) {
// We have to preemptively run our unique file name logic, if (!isProjectNew) {
// so that we can pass the unique file name to the toast, // If the project is new, use a sub dir
// and by extension the file-deletion-on-reject logic. const firstLevelDirectories = getAllSubDirectoriesAtProjectRoot({
newFileName = getNextFileName({ projectFolderName: projectName,
entryName: newFileName, })
baseDir: projectName, const uniqueSubDirectoryName = getUniqueProjectName(
}).name subDirectoryAsPromptName,
firstLevelDirectories
)
uniqueProjectName = joinOSPaths(projectName, uniqueSubDirectoryName)
}
systemIOActor.send({ systemIOActor.send({
type: SystemIOMachineEvents.createKCLFile, type: SystemIOMachineEvents.createKCLFile,
data: { data: {
requestedProjectName: projectName, requestedProjectName: uniqueProjectName,
requestedCode: value.code, requestedCode: value.code,
requestedFileNameWithExtension: newFileName, requestedFileNameWithExtension: newFileName,
}, },
@ -251,11 +252,14 @@ export async function submitAndAwaitTextToKclSystemIO({
toastId, toastId,
data: textToCadOutputCreated, data: textToCadOutputCreated,
token, token,
projectName: projectName, // This can be a subdir within the rootProjectName
projectName: uniqueProjectName,
fileName: newFileName, fileName: newFileName,
navigate, navigate,
isProjectNew, isProjectNew,
settings, settings,
// This is always the root project name, no subdir
rootProjectName: projectName,
}), }),
{ {
id: toastId, id: toastId,

View File

@ -12,6 +12,7 @@ import type {
CameraViewState_type, CameraViewState_type,
UnitLength_type, UnitLength_type,
} from '@kittycad/lib/dist/types/src/models' } from '@kittycad/lib/dist/types/src/models'
import type { CameraProjectionType } from '@rust/kcl-lib/bindings/CameraProjectionType'
export const uuidv4 = v4 export const uuidv4 = v4
@ -622,9 +623,11 @@ export async function engineViewIsometricWithGeometryPresent({
export async function engineViewIsometricWithoutGeometryPresent({ export async function engineViewIsometricWithoutGeometryPresent({
engineCommandManager, engineCommandManager,
unit, unit,
cameraProjection,
}: { }: {
engineCommandManager: EngineCommandManager engineCommandManager: EngineCommandManager
unit?: UnitLength_type unit?: UnitLength_type
cameraProjection: CameraProjectionType
}) { }) {
// If you load an empty scene with any file unit it will have an eye offset of this // If you load an empty scene with any file unit it will have an eye offset of this
const MAGIC_ENGINE_EYE_OFFSET = 1378.0057 const MAGIC_ENGINE_EYE_OFFSET = 1378.0057
@ -644,8 +647,8 @@ export async function engineViewIsometricWithoutGeometryPresent({
eye_offset: MAGIC_ENGINE_EYE_OFFSET, eye_offset: MAGIC_ENGINE_EYE_OFFSET,
fov_y: 45, fov_y: 45,
ortho_scale_factor: 1.4063792, ortho_scale_factor: 1.4063792,
is_ortho: true, is_ortho: cameraProjection !== 'perspective',
ortho_scale_enabled: true, ortho_scale_enabled: cameraProjection !== 'perspective',
world_coord_system: 'right_handed_up_z', world_coord_system: 'right_handed_up_z',
} }
await engineCommandManager.sendSceneCommand({ await engineCommandManager.sendSceneCommand({

View File

@ -0,0 +1,245 @@
import {
modelingMachine,
modelingMachineDefaultContext,
} from '@src/machines/modelingMachine'
import { createActor } from 'xstate'
import { vi } from 'vitest'
import { assertParse, type CallExpressionKw } from '@src/lang/wasm'
import { initPromise } from '@src/lang/wasmUtils'
import {
codeManager,
engineCommandManager,
kclManager,
} from '@src/lib/singletons'
import { VITE_KC_DEV_TOKEN } from '@src/env'
import { line } from '@src/lang/std/sketch'
import { getNodeFromPath } from '@src/lang/queryAst'
import type { Node } from '@rust/kcl-lib/bindings/Node'
import { err } from '@src/lib/trap'
import {
createIdentifier,
createLiteral,
createVariableDeclaration,
} from '@src/lang/create'
// Store original method to restore in afterAll
beforeAll(async () => {
await initPromise
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
await new Promise((resolve) => {
engineCommandManager.start({
token: VITE_KC_DEV_TOKEN,
width: 256,
height: 256,
setMediaStream: () => {},
setIsStreamReady: () => {},
callbackOnEngineLiteConnect: () => {
resolve(true)
},
})
})
}, 30_000)
afterAll(() => {
// Restore the original method
engineCommandManager.tearDown()
})
// Define mock implementations that will be referenced in vi.mock calls
vi.mock('@src/components/SetHorVertDistanceModal', () => ({
createInfoModal: vi.fn(() => ({
open: vi.fn().mockResolvedValue({
value: '10',
segName: 'test',
valueNode: {},
newVariableInsertIndex: 0,
sign: 1,
}),
})),
GetInfoModal: vi.fn(),
}))
vi.mock('@src/components/SetAngleLengthModal', () => ({
createSetAngleLengthModal: vi.fn(() => ({
open: vi.fn().mockResolvedValue({
value: '45',
segName: 'test',
valueNode: {},
newVariableInsertIndex: 0,
sign: 1,
}),
})),
SetAngleLengthModal: vi.fn(),
}))
// Add this function before the test cases
// Utility function to wait for a condition to be met
const waitForCondition = async (
condition: () => boolean,
timeout = 5000,
interval = 100
) => {
const startTime = Date.now()
while (Date.now() - startTime < timeout) {
try {
if (condition()) {
return true
}
} catch {
// Ignore errors, keep polling
}
// Wait for the next interval
await new Promise((resolve) => setTimeout(resolve, interval))
}
// Last attempt before failing
return condition()
}
describe('modelingMachine - XState', () => {
describe('when initialized', () => {
it('should start in the idle state', () => {
const actor = createActor(modelingMachine, {
input: modelingMachineDefaultContext,
}).start()
const state = actor.getSnapshot().value
// The machine should start in the idle state
expect(state).toEqual({ idle: 'hidePlanes' })
})
})
describe('when in sketch mode', () => {
it('should transition to sketch state when entering sketch mode', async () => {
const code = `sketch001 = startSketchOn(XZ)
profile001 = startProfile(sketch001, at = [2263.04, -2721.2])
|> line(end = [16.27, 73.81])
|> line(end = [75.72, 18.41])
`
const ast = assertParse(code)
await kclManager.executeAst({ ast })
expect(kclManager.errors).toEqual([])
const indexOfInterest = code.indexOf('[16.27, 73.81]')
// segment artifact with that source range
const artifact = [...kclManager.artifactGraph].find(
([_, artifact]) =>
artifact?.type === 'segment' &&
artifact.codeRef.range[0] <= indexOfInterest &&
indexOfInterest <= artifact.codeRef.range[1]
)?.[1]
if (!artifact || !('codeRef' in artifact)) {
throw new Error('Artifact not found or invalid artifact structure')
}
const actor = createActor(modelingMachine, {
input: modelingMachineDefaultContext,
}).start()
// Send event to transition to sketch mode
actor.send({
type: 'Set selection',
data: {
selectionType: 'mirrorCodeMirrorSelections',
selection: {
graphSelections: [
{
artifact: artifact,
codeRef: artifact.codeRef,
},
],
otherSelections: [],
},
},
})
actor.send({ type: 'Enter sketch' })
// Check that we're in the sketch state
let state = actor.getSnapshot()
expect(state.value).toBe('animating to existing sketch')
// wait for it to transition
await waitForCondition(() => {
const snapshot = actor.getSnapshot()
return snapshot.value !== 'animating to existing sketch'
}, 5000)
// After the condition is met, do the actual assertion
expect(actor.getSnapshot().value).toEqual({
Sketch: { SketchIdle: 'scene drawn' },
})
const getConstraintInfo = line.getConstraintInfo
const callExp = getNodeFromPath<Node<CallExpressionKw>>(
kclManager.ast,
artifact.codeRef.pathToNode,
'CallExpressionKw'
)
if (err(callExp)) {
throw new Error('Failed to get CallExpressionKw node')
}
const constraintInfo = getConstraintInfo(
callExp.node,
codeManager.code,
artifact.codeRef.pathToNode
)
const first = constraintInfo[0]
// Now that we're in sketchIdle state, test the "Constrain with named value" event
actor.send({
type: 'Constrain with named value',
data: {
currentValue: {
valueText: first.value,
pathToNode: first.pathToNode,
variableName: 'test_variable',
},
// Use type assertion to mock the complex type
namedValue: {
valueText: '20',
variableName: 'test_variable',
insertIndex: 0,
valueCalculated: '20',
variableDeclarationAst: createVariableDeclaration(
'test_variable',
createLiteral('20')
),
variableIdentifierAst: createIdentifier('test_variable') as any,
valueAst: createLiteral('20'),
},
},
})
// Wait for the state to change in response to the constraint
await waitForCondition(() => {
const snapshot = actor.getSnapshot()
// Check if we've transitioned to a different state
return (
JSON.stringify(snapshot.value) !==
JSON.stringify({
Sketch: { SketchIdle: 'set up segments' },
})
)
}, 5000)
await waitForCondition(() => {
const snapshot = actor.getSnapshot()
// Check if we've transitioned to a different state
return (
JSON.stringify(snapshot.value) !==
JSON.stringify({ Sketch: 'Converting to named value' })
)
}, 5000)
expect(codeManager.code).toContain('line(end = [test_variable,')
}, 10_000)
})
})

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,6 @@
import type { FileEntry } from '@src/lib/project'
import { systemIOActor } from '@src/lib/singletons' import { systemIOActor } from '@src/lib/singletons'
import { isArray } from '@src/lib/utils'
export const folderSnapshot = () => { export const folderSnapshot = () => {
const { folders } = systemIOActor.getSnapshot().context const { folders } = systemIOActor.getSnapshot().context
@ -9,3 +11,48 @@ export const defaultProjectFolderNameSnapshot = () => {
const { defaultProjectFolderName } = systemIOActor.getSnapshot().context const { defaultProjectFolderName } = systemIOActor.getSnapshot().context
return defaultProjectFolderName return defaultProjectFolderName
} }
/**
* From the application project directory go down to a project folder and list all the folders at that directory level
* application project directory: /home/documents/zoo-modeling-app-projects/
*
* /home/documents/zoo-modeling-app-projects/car-door/
* ├── handle
* ├── main.kcl
* └── window
*
* The two folders are handle and window
*
* @param {Object} params
* @param {string} params.projectFolderName - The name with no path information.
* @returns {FileEntry[]} An array of subdirectory names found at the root level of the specified project folder.
*/
export const getAllSubDirectoriesAtProjectRoot = ({
projectFolderName,
}: { projectFolderName: string }): FileEntry[] => {
const subDirectories: FileEntry[] = []
const { folders } = systemIOActor.getSnapshot().context
const projectFolder = folders.find((folder) => {
return folder.name === projectFolderName
})
// Find the subdirectories
if (projectFolder) {
// 1st level
const children = projectFolder.children
if (children) {
children.forEach((childFileOrDirectory) => {
// 2nd level
const secondLevelChild = childFileOrDirectory.children
// if secondLevelChild is null then it is a file
if (secondLevelChild && isArray(secondLevelChild)) {
// this is a directory!
subDirectories.push(childFileOrDirectory)
}
})
}
}
return subDirectories
}