Compare commits
3 Commits
kcl-0.2.39
...
pierremtb/
Author | SHA1 | Date | |
---|---|---|---|
2a415012d7 | |||
d39dd5697c | |||
c9f7275bc4 |
36
.github/workflows/build-apps.yml
vendored
@ -7,11 +7,14 @@ on:
|
|||||||
- main
|
- main
|
||||||
tags:
|
tags:
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
- 'nightly-v[0-9]+.[0-9]+.[0-9]+'
|
schedule:
|
||||||
|
- cron: '0 4 * * *'
|
||||||
|
# Daily at 04:00 AM UTC
|
||||||
|
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
|
IS_RELEASE: ${{ github.ref_type == 'tag' }}
|
||||||
IS_NIGHTLY: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'nightly-v') }}
|
IS_NIGHTLY: ${{ github.event_name == 'schedule' }}
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
@ -29,7 +32,6 @@ jobs:
|
|||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
cache: 'yarn'
|
|
||||||
|
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
|
|
||||||
@ -50,10 +52,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set nightly version, product name, release notes, and icons
|
- name: Set nightly version, product name, release notes, and icons
|
||||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
run: |
|
run: yarn files:flip-to-nightly
|
||||||
export VERSION=${GITHUB_REF_NAME#nightly-v}
|
|
||||||
yarn files:set-version
|
|
||||||
yarn files:flip-to-nightly
|
|
||||||
|
|
||||||
- name: Set release version
|
- name: Set release version
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.IS_RELEASE == 'true' }}
|
||||||
@ -124,11 +123,9 @@ jobs:
|
|||||||
cp prepared-files/assets/icon.ico assets/icon.ico
|
cp prepared-files/assets/icon.ico assets/icon.ico
|
||||||
cp prepared-files/assets/icon.png assets/icon.png
|
cp prepared-files/assets/icon.png assets/icon.png
|
||||||
|
|
||||||
- name: Sync node version and setup cache
|
- uses: actions/setup-node@v4
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
cache: 'yarn' # Set this to npm, yarn or pnpm.
|
|
||||||
|
|
||||||
- name: yarn install
|
- name: yarn install
|
||||||
# Windows is picky sometimes and fails on fetch. Step takes about ~30s
|
# Windows is picky sometimes and fails on fetch. Step takes about ~30s
|
||||||
@ -273,7 +270,7 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
if: ${{ github.ref_type == 'tag' }}
|
if: ${{ github.ref_type == 'tag' || github.event_name == 'schedule' }}
|
||||||
env:
|
env:
|
||||||
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
||||||
VERSION: ${{ format('v{0}', needs.prepare-files.outputs.version) }}
|
VERSION: ${{ format('v{0}', needs.prepare-files.outputs.version) }}
|
||||||
@ -330,8 +327,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
||||||
PUB_DATE: ${{ github.event.repository.updated_at }}
|
PUB_DATE: ${{ github.event.repository.updated_at }}
|
||||||
WEBSITE_DIR: ${{ env.IS_NIGHTLY == 'true' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
||||||
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
||||||
run: |
|
run: |
|
||||||
RELEASE_DIR=https://${WEBSITE_DIR}
|
RELEASE_DIR=https://${WEBSITE_DIR}
|
||||||
jq --null-input \
|
jq --null-input \
|
||||||
@ -414,3 +411,14 @@ jobs:
|
|||||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
run: yarn files:invalidate-bucket:nightly
|
run: yarn files:invalidate-bucket:nightly
|
||||||
|
|
||||||
|
- name: Tag nightly commit
|
||||||
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { VERSION } = process.env
|
||||||
|
const { owner, repo } = context.repo
|
||||||
|
const { sha } = context
|
||||||
|
const ref = `refs/tags/nightly-${VERSION}`
|
||||||
|
github.rest.git.createRef({ owner, repo, sha, ref })
|
||||||
|
39
.github/workflows/tag-nightly.yml
vendored
@ -1,39 +0,0 @@
|
|||||||
name: tag-nightly
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 4 * * *'
|
|
||||||
# Daily at 04:00 AM UTC
|
|
||||||
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tag-nightly:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/create-github-app-token@v1
|
|
||||||
id: app-token
|
|
||||||
with:
|
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
|
||||||
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
|
|
||||||
owner: ${{ github.repository_owner }}
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
|
|
||||||
- run: yarn install
|
|
||||||
|
|
||||||
- name: Push tag
|
|
||||||
run: |
|
|
||||||
VERSION_NO_V=$(date +'%-y.%-m.%-d')
|
|
||||||
TAG="nightly-v$VERSION_NO_V"
|
|
||||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git config --local user.name "github-actions[bot]"
|
|
||||||
git tag $TAG
|
|
||||||
git push origin tag $TAG
|
|
2
.gitignore
vendored
@ -24,7 +24,7 @@ yarn-debug.log*
|
|||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
# .vscode
|
||||||
.helix
|
.helix
|
||||||
src/wasm-lib/.idea
|
src/wasm-lib/.idea
|
||||||
src/wasm-lib/.vscode
|
src/wasm-lib/.vscode
|
||||||
|
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"rust-analyzer.linkedProjects": [
|
||||||
|
"src/wasm-lib/Cargo.toml"
|
||||||
|
]
|
||||||
|
}
|
@ -171,22 +171,4 @@ export class EditorFixture {
|
|||||||
{ text, placeCursor }
|
{ text, placeCursor }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
async selectText(text: string) {
|
|
||||||
// First make sure the code pane is open
|
|
||||||
const wasPaneOpen = await this.checkIfPaneIsOpen()
|
|
||||||
if (!wasPaneOpen) {
|
|
||||||
await this.openPane()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use Playwright's built-in text selection on the code content
|
|
||||||
// it seems to only select whole divs, which works out to align with syntax highlighting
|
|
||||||
// for code mirror, so you can probably select "sketch002 = startSketchOn('XZ')"
|
|
||||||
// but less so for exactly "sketch002 = startS"
|
|
||||||
await this.codeContent.getByText(text).first().selectText()
|
|
||||||
|
|
||||||
// Reset pane state if needed
|
|
||||||
if (!wasPaneOpen) {
|
|
||||||
await this.closePane()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ extrude003 = extrude(sketch003, length = 20)
|
|||||||
`
|
`
|
||||||
|
|
||||||
test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
||||||
test.describe('Check the happy path, for basic changing color', () => {
|
test.fixme('Check the happy path, for basic changing color', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
{
|
{
|
||||||
desc: 'User accepts change',
|
desc: 'User accepts change',
|
||||||
@ -70,7 +70,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
body1CapCoords.y
|
body1CapCoords.y
|
||||||
)
|
)
|
||||||
const yellow: [number, number, number] = [179, 179, 131]
|
const yellow: [number, number, number] = [179, 179, 131]
|
||||||
const green: [number, number, number] = [128, 194, 88]
|
const green: [number, number, number] = [108, 152, 75]
|
||||||
const notGreen: [number, number, number] = [132, 132, 132]
|
const notGreen: [number, number, number] = [132, 132, 132]
|
||||||
const body2NotGreen: [number, number, number] = [88, 88, 88]
|
const body2NotGreen: [number, number, number] = [88, 88, 88]
|
||||||
const submittingToast = page.getByText(
|
const submittingToast = page.getByText(
|
||||||
@ -109,7 +109,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await test.step('verify initial change', async () => {
|
await test.step('verify initial change', async () => {
|
||||||
await scene.expectPixelColor(green, greenCheckCoords, 20)
|
await scene.expectPixelColor(green, greenCheckCoords, 15)
|
||||||
await scene.expectPixelColor(body2NotGreen, body2WallCoords, 15)
|
await scene.expectPixelColor(body2NotGreen, body2WallCoords, 15)
|
||||||
await editor.expectEditor.toContain('appearance(')
|
await editor.expectEditor.toContain('appearance(')
|
||||||
})
|
})
|
||||||
@ -142,7 +142,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
test('bad edit prompt', async ({
|
test(`bad edit prompt`, async ({
|
||||||
context,
|
context,
|
||||||
homePage,
|
homePage,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
@ -195,150 +195,4 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
await expect(failToast).toBeVisible()
|
await expect(failToast).toBeVisible()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test(`manual code selection rename`, async ({
|
|
||||||
context,
|
|
||||||
homePage,
|
|
||||||
cmdBar,
|
|
||||||
editor,
|
|
||||||
page,
|
|
||||||
scene,
|
|
||||||
}) => {
|
|
||||||
const body1CapCoords = { x: 571, y: 351 }
|
|
||||||
|
|
||||||
await context.addInitScript((file) => {
|
|
||||||
localStorage.setItem('persistCode', file)
|
|
||||||
}, file)
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.waitForExecutionDone()
|
|
||||||
|
|
||||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
|
||||||
const successToast = page.getByText('Prompt to edit successful')
|
|
||||||
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
|
|
||||||
|
|
||||||
await test.step('wait for scene to load and select code in editor', async () => {
|
|
||||||
// Find and select the text "sketch002" in the editor
|
|
||||||
await editor.selectText('sketch002')
|
|
||||||
|
|
||||||
// Verify the selection was made
|
|
||||||
await editor.expectState({
|
|
||||||
highlightedCode: '',
|
|
||||||
activeLines: ["sketch002 = startSketchOn('XZ')"],
|
|
||||||
diagnostics: [],
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('fire off edit prompt', async () => {
|
|
||||||
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
|
|
||||||
await cmdBar.openCmdBar('promptToEdit')
|
|
||||||
await page
|
|
||||||
.getByTestId('cmd-bar-arg-value')
|
|
||||||
.fill('Please rename to mySketch')
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await expect(submittingToast).toBeVisible()
|
|
||||||
await expect(submittingToast).not.toBeVisible({
|
|
||||||
timeout: 2 * 60_000,
|
|
||||||
})
|
|
||||||
await expect(successToast).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('verify rename change and accept it', async () => {
|
|
||||||
await editor.expectEditor.toContain('mySketch = startSketchOn')
|
|
||||||
await editor.expectEditor.not.toContain('sketch002 = startSketchOn')
|
|
||||||
await editor.expectEditor.toContain(
|
|
||||||
'extrude002 = extrude(mySketch, length = 50)'
|
|
||||||
)
|
|
||||||
|
|
||||||
await acceptBtn.click()
|
|
||||||
await expect(successToast).not.toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('multiple body selections', async ({
|
|
||||||
context,
|
|
||||||
homePage,
|
|
||||||
cmdBar,
|
|
||||||
editor,
|
|
||||||
page,
|
|
||||||
scene,
|
|
||||||
}) => {
|
|
||||||
const body1CapCoords = { x: 571, y: 351 }
|
|
||||||
const body2WallCoords = { x: 620, y: 152 }
|
|
||||||
const [clickBody1Cap] = scene.makeMouseHelpers(
|
|
||||||
body1CapCoords.x,
|
|
||||||
body1CapCoords.y
|
|
||||||
)
|
|
||||||
const [clickBody2Cap] = scene.makeMouseHelpers(
|
|
||||||
body2WallCoords.x,
|
|
||||||
body2WallCoords.y
|
|
||||||
)
|
|
||||||
const grey: [number, number, number] = [132, 132, 132]
|
|
||||||
|
|
||||||
await context.addInitScript((file) => {
|
|
||||||
localStorage.setItem('persistCode', file)
|
|
||||||
}, file)
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.waitForExecutionDone()
|
|
||||||
|
|
||||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
|
||||||
const successToast = page.getByText('Prompt to edit successful')
|
|
||||||
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
|
|
||||||
|
|
||||||
await test.step('select multiple bodies and fire prompt', async () => {
|
|
||||||
// Initial color check
|
|
||||||
await scene.expectPixelColor(grey, body1CapCoords, 15)
|
|
||||||
|
|
||||||
// Open command bar first (without selection)
|
|
||||||
await cmdBar.openCmdBar('promptToEdit')
|
|
||||||
|
|
||||||
// Select first body
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await clickBody1Cap()
|
|
||||||
|
|
||||||
// Hold shift and select second body
|
|
||||||
await editor.expectState({
|
|
||||||
highlightedCode: '',
|
|
||||||
activeLines: ['|>startProfileAt([-73.64,-42.89],%)'],
|
|
||||||
diagnostics: [],
|
|
||||||
})
|
|
||||||
await page.keyboard.down('Shift')
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await clickBody2Cap()
|
|
||||||
await editor.expectState({
|
|
||||||
highlightedCode:
|
|
||||||
'line(end=[121.13,56.63],tag=$seg02)extrude(profile001,length=200)',
|
|
||||||
activeLines: [
|
|
||||||
'|>line(end=[121.13,56.63],tag=$seg02)',
|
|
||||||
'|>startProfileAt([-73.64,-42.89],%)',
|
|
||||||
],
|
|
||||||
diagnostics: [],
|
|
||||||
})
|
|
||||||
await page.keyboard.up('Shift')
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
|
|
||||||
// Enter prompt and submit
|
|
||||||
await page
|
|
||||||
.getByTestId('cmd-bar-arg-value')
|
|
||||||
.fill('make these neon green please, use #39FF14')
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
|
|
||||||
// Wait for API response
|
|
||||||
await expect(submittingToast).toBeVisible()
|
|
||||||
await expect(submittingToast).not.toBeVisible({
|
|
||||||
timeout: 2 * 60_000,
|
|
||||||
})
|
|
||||||
await expect(successToast).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('verify code changed', async () => {
|
|
||||||
await editor.expectEditor.toContain('appearance(')
|
|
||||||
|
|
||||||
// Accept changes
|
|
||||||
await acceptBtn.click()
|
|
||||||
await expect(successToast).not.toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
1
exp
Normal file
@ -0,0 +1 @@
|
|||||||
|
sketch001=startSketchOn('XZ')|>startProfileAt([75.8,317.2],%)//[$startCapTag,$EndCapTag]|>angledLine([0,268.43],%,$rectangleSegmentA001)|>angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)|>angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)|>line(endAbsolute=[profileStartX(%),profileStartY(%)],tag=$seg02)|>close()extrude001=extrude(sketch001,length=100)|>chamfer(length=30,tags=[getOppositeEdge(seg01)],tag=$seg03)|>chamfer(length=30,tags=[seg01],tag=$seg04)|>chamfer(length=30,tags=[getNextAdjacentEdge(seg02)],tag=$seg05)|>chamfer(length=30,tags=[getNextAdjacentEdge(yo)],tag=$seg06)sketch004=startSketchOn(extrude001,seg05)profile003=startProfileAt([82.57,322.96],sketch004)|>angledLine([0,11.16],%,$rectangleSegmentA004)|>angledLine([segAng(rectangleSegmentA004)-90,103.07],%)|>angledLine([segAng(rectangleSegmentA004),-segLen(rectangleSegmentA004)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch003=startSketchOn(extrude001,seg04)profile002=startProfileAt([-209.64,255.28],sketch003)|>angledLine([0,11.56],%,$rectangleSegmentA003)|>angledLine([segAng(rectangleSegmentA003)-90,106.84],%)|>angledLine([segAng(rectangleSegmentA003),-segLen(rectangleSegmentA003)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch002=startSketchOn(extrude001,seg03)profile001=startProfileAt([205.96,254.59],sketch002)|>angledLine([0,11.39],%,$rectangleSegmentA002)|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()
|
1
got
Normal file
@ -0,0 +1 @@
|
|||||||
|
sketch001=startSketchOn('XZ')|>startProfileAt([75.8,317.2],%)//[$startCapTag,$EndCapTag]|>angledLine([0,268.43],%,$rectangleSegmentA001)|>angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)|>angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)|>line(endAbsolute=[profileStartX(%),profileStartY(%)],tag=$seg02)|>close()extrude001=extrude(sketch001,length=100)|>chamfer(length=30,tags=[getOppositeEdge(seg01)],tag=$seg03)|>chamfer(length=30,tags=[seg01],tag=$seg04)|>chamfer(length=30,tags=[getNextAdjacentEdge(seg02)],tag=$seg05)|>chamfer(length=30,tags=[getNextAdjacentEdge(yo)],tag=$seg06)sketch005=startSketchOn(extrude001,seg06)profile004=startProfileAt([-23.43,19.69],sketch005)|>angledLine([0,9.1],%,$rectangleSegmentA005)|>angledLine([segAng(rectangleSegmentA005)-90,84.07],%)|>angledLine([segAng(rectangleSegmentA005),-segLen(rectangleSegmentA005)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch004=startSketchOn(extrude001,seg05)profile003=startProfileAt([82.57,322.96],sketch004)|>angledLine([0,11.16],%,$rectangleSegmentA004)|>angledLine([segAng(rectangleSegmentA004)-90,103.07],%)|>angledLine([segAng(rectangleSegmentA004),-segLen(rectangleSegmentA004)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch003=startSketchOn(extrude001,seg04)profile002=startProfileAt([-209.64,255.28],sketch003)|>angledLine([0,11.56],%,$rectangleSegmentA003)|>angledLine([segAng(rectangleSegmentA003)-90,106.84],%)|>angledLine([segAng(rectangleSegmentA003),-segLen(rectangleSegmentA003)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()sketch002=startSketchOn(extrude001,seg03)profile001=startProfileAt([205.96,254.59],sketch002)|>angledLine([0,11.39],%,$rectangleSegmentA002)|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)|>line(endAbsolute=[profileStartX(%),profileStartY(%)])|>close()
|
@ -91,11 +91,11 @@
|
|||||||
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages",
|
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages",
|
||||||
"fetch:wasm": "./scripts/get-latest-wasm-bundle.sh",
|
"fetch:wasm": "./scripts/get-latest-wasm-bundle.sh",
|
||||||
"fetch:wasm:windows": "./scripts/get-latest-wasm-bundle.ps1",
|
"fetch:wasm:windows": "./scripts/get-latest-wasm-bundle.ps1",
|
||||||
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/next/manifest.json",
|
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/next/manifest.json",
|
||||||
"build:wasm-dev": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt",
|
"build:wasm-dev": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt",
|
||||||
"build:wasm:nocopy": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings",
|
"build:wasm:nocopy": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings",
|
||||||
"build:wasm": "yarn build:wasm:nocopy && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn fmt",
|
"build:wasm": "yarn build:wasm:nocopy && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn fmt",
|
||||||
"build:wasm:windows": "yarn install:wasm-pack:cargo && yarn build:wasm:nocopy && ./scripts/copy-wasm.ps1 && yarn fmt",
|
"build:wasm:windows": "yarn install:wasm-pack:cargo && yarn build:wasm:nocopy && copy src\\wasm-lib\\pkg\\wasm_lib_bg.wasm public && yarn fmt",
|
||||||
"remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\" || echo \"sed for both mac and linux\"",
|
"remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./src/wasm-lib/pkg/wasm_lib.js\" || echo \"sed for both mac and linux\"",
|
||||||
"wasm-prep": "rimraf src/wasm-lib/pkg && mkdirp src/wasm-lib/pkg && rimraf src/wasm-lib/kcl/bindings",
|
"wasm-prep": "rimraf src/wasm-lib/pkg && mkdirp src/wasm-lib/pkg && rimraf src/wasm-lib/kcl/bindings",
|
||||||
"lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src",
|
"lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src",
|
||||||
|
@ -1 +0,0 @@
|
|||||||
copy src\wasm-lib\pkg\wasm_lib_bg.wasm public
|
|
@ -1,8 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
export VERSION=$(date +'%-y.%-m.%-d')
|
||||||
export COMMIT=$(git rev-parse --short HEAD)
|
export COMMIT=$(git rev-parse --short HEAD)
|
||||||
|
|
||||||
# package.json
|
# package.json
|
||||||
|
yarn files:set-version
|
||||||
PACKAGE=$(jq '.productName="Zoo Modeling App (Nightly)" | .name="zoo-modeling-app-nightly"' package.json --indent 2)
|
PACKAGE=$(jq '.productName="Zoo Modeling App (Nightly)" | .name="zoo-modeling-app-nightly"' package.json --indent 2)
|
||||||
echo "$PACKAGE" > package.json
|
echo "$PACKAGE" > package.json
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ yq -i '.appId = "dev.zoo.modeling-app-nightly"' electron-builder.yml
|
|||||||
yq -i '.nsis.include = "./scripts/installer-nightly.nsh"' electron-builder.yml
|
yq -i '.nsis.include = "./scripts/installer-nightly.nsh"' electron-builder.yml
|
||||||
|
|
||||||
# Release notes
|
# Release notes
|
||||||
echo "Nightly build (commit $COMMIT)" > release-notes.md
|
echo "Nightly build $VERSION (commit $COMMIT)" > release-notes.md
|
||||||
|
|
||||||
# icons
|
# icons
|
||||||
cp assets/icon-nightly.png assets/icon.png
|
cp assets/icon-nightly.png assets/icon.png
|
||||||
|
@ -24,7 +24,12 @@ import ModelingMachineProvider from 'components/ModelingMachineProvider'
|
|||||||
import FileMachineProvider from 'components/FileMachineProvider'
|
import FileMachineProvider from 'components/FileMachineProvider'
|
||||||
import { MachineManagerProvider } from 'components/MachineManagerProvider'
|
import { MachineManagerProvider } from 'components/MachineManagerProvider'
|
||||||
import { PATHS } from 'lib/paths'
|
import { PATHS } from 'lib/paths'
|
||||||
import { fileLoader, homeLoader, telemetryLoader } from 'lib/routeLoaders'
|
import {
|
||||||
|
fileLoader,
|
||||||
|
homeLoader,
|
||||||
|
onboardingRedirectLoader,
|
||||||
|
telemetryLoader,
|
||||||
|
} from 'lib/routeLoaders'
|
||||||
import LspProvider from 'components/LspProvider'
|
import LspProvider from 'components/LspProvider'
|
||||||
import { KclContextProvider } from 'lang/KclProvider'
|
import { KclContextProvider } from 'lang/KclProvider'
|
||||||
import { ASK_TO_OPEN_QUERY_PARAM, BROWSER_PROJECT_NAME } from 'lib/constants'
|
import { ASK_TO_OPEN_QUERY_PARAM, BROWSER_PROJECT_NAME } from 'lib/constants'
|
||||||
@ -108,6 +113,11 @@ const router = createRouter([
|
|||||||
{
|
{
|
||||||
id: PATHS.FILE + 'SETTINGS',
|
id: PATHS.FILE + 'SETTINGS',
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
loader: onboardingRedirectLoader,
|
||||||
|
index: true,
|
||||||
|
element: <></>,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: makeUrlPathRelative(PATHS.SETTINGS),
|
path: makeUrlPathRelative(PATHS.SETTINGS),
|
||||||
element: <Settings />,
|
element: <Settings />,
|
||||||
|
@ -17,9 +17,7 @@ export const CommandBar = () => {
|
|||||||
const {
|
const {
|
||||||
context: { selectedCommand, currentArgument, commands },
|
context: { selectedCommand, currentArgument, commands },
|
||||||
} = commandBarState
|
} = commandBarState
|
||||||
const isSelectionArgument =
|
const isSelectionArgument = currentArgument?.inputType === 'selection'
|
||||||
currentArgument?.inputType === 'selection' ||
|
|
||||||
currentArgument?.inputType === 'selectionMixed'
|
|
||||||
const WrapperComponent = isSelectionArgument ? Popover : Dialog
|
const WrapperComponent = isSelectionArgument ? Popover : Dialog
|
||||||
|
|
||||||
// Close the command bar when navigating
|
// Close the command bar when navigating
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import CommandArgOptionInput from './CommandArgOptionInput'
|
import CommandArgOptionInput from './CommandArgOptionInput'
|
||||||
import CommandBarBasicInput from './CommandBarBasicInput'
|
import CommandBarBasicInput from './CommandBarBasicInput'
|
||||||
import CommandBarSelectionInput from './CommandBarSelectionInput'
|
import CommandBarSelectionInput from './CommandBarSelectionInput'
|
||||||
import CommandBarSelectionMixedInput from './CommandBarSelectionMixedInput'
|
|
||||||
import { CommandArgument } from 'lib/commandTypes'
|
import { CommandArgument } from 'lib/commandTypes'
|
||||||
import CommandBarHeader from './CommandBarHeader'
|
import CommandBarHeader from './CommandBarHeader'
|
||||||
import CommandBarKclInput from './CommandBarKclInput'
|
import CommandBarKclInput from './CommandBarKclInput'
|
||||||
@ -85,14 +84,6 @@ function ArgumentInput({
|
|||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case 'selectionMixed':
|
|
||||||
return (
|
|
||||||
<CommandBarSelectionMixedInput
|
|
||||||
arg={arg}
|
|
||||||
stepBack={stepBack}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
case 'kcl':
|
case 'kcl':
|
||||||
return (
|
return (
|
||||||
<CommandBarKclInput arg={arg} stepBack={stepBack} onSubmit={onSubmit} />
|
<CommandBarKclInput arg={arg} stepBack={stepBack} onSubmit={onSubmit} />
|
||||||
|
@ -124,8 +124,7 @@ function CommandBarHeader({ children }: React.PropsWithChildren<{}>) {
|
|||||||
<span className="sr-only">: </span>
|
<span className="sr-only">: </span>
|
||||||
<span data-testid="header-arg-value">
|
<span data-testid="header-arg-value">
|
||||||
{argValue ? (
|
{argValue ? (
|
||||||
arg.inputType === 'selection' ||
|
arg.inputType === 'selection' ? (
|
||||||
arg.inputType === 'selectionMixed' ? (
|
|
||||||
getSelectionTypeDisplayText(argValue as Selections)
|
getSelectionTypeDisplayText(argValue as Selections)
|
||||||
) : arg.inputType === 'kcl' ? (
|
) : arg.inputType === 'kcl' ? (
|
||||||
roundOff(
|
roundOff(
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
|
||||||
import { CommandArgument } from 'lib/commandTypes'
|
|
||||||
import {
|
|
||||||
Selections,
|
|
||||||
canSubmitSelectionArg,
|
|
||||||
getSelectionCountByType,
|
|
||||||
getSelectionTypeDisplayText,
|
|
||||||
} from 'lib/selections'
|
|
||||||
import { useSelector } from '@xstate/react'
|
|
||||||
import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine'
|
|
||||||
|
|
||||||
const selectionSelector = (snapshot: any) => snapshot?.context.selectionRanges
|
|
||||||
|
|
||||||
export default function CommandBarSelectionMixedInput({
|
|
||||||
arg,
|
|
||||||
stepBack,
|
|
||||||
onSubmit,
|
|
||||||
}: {
|
|
||||||
arg: CommandArgument<unknown> & { inputType: 'selectionMixed'; name: string }
|
|
||||||
stepBack: () => void
|
|
||||||
onSubmit: (data: unknown) => void
|
|
||||||
}) {
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
|
||||||
const commandBarState = useCommandBarState()
|
|
||||||
const [hasSubmitted, setHasSubmitted] = useState(false)
|
|
||||||
const [hasAutoSkipped, setHasAutoSkipped] = useState(false)
|
|
||||||
const selection: Selections = useSelector(arg.machineActor, selectionSelector)
|
|
||||||
|
|
||||||
const selectionsByType = useMemo(() => {
|
|
||||||
return getSelectionCountByType(selection)
|
|
||||||
}, [selection])
|
|
||||||
|
|
||||||
const canSubmitSelection = useMemo<boolean>(() => {
|
|
||||||
if (!selection) return false
|
|
||||||
const isNonZeroRange = selection.graphSelections.some((sel) => {
|
|
||||||
const range = sel.codeRef.range
|
|
||||||
return range[1] - range[0] !== 0 // Non-zero range is always valid
|
|
||||||
})
|
|
||||||
if (isNonZeroRange) return true
|
|
||||||
return canSubmitSelectionArg(selectionsByType, arg)
|
|
||||||
}, [selectionsByType, selection])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
inputRef.current?.focus()
|
|
||||||
}, [selection, inputRef])
|
|
||||||
|
|
||||||
// Only auto-skip on initial mount if we have a valid selection
|
|
||||||
// different from the component CommandBarSelectionInput in the the dependency array
|
|
||||||
// is empty
|
|
||||||
useEffect(() => {
|
|
||||||
if (!hasAutoSkipped && canSubmitSelection && arg.skip) {
|
|
||||||
const argValue = commandBarState.context.argumentsToSubmit[arg.name]
|
|
||||||
if (argValue === undefined) {
|
|
||||||
handleSubmit()
|
|
||||||
setHasAutoSkipped(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
function handleChange() {
|
|
||||||
inputRef.current?.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSubmit(e?: React.FormEvent<HTMLFormElement>) {
|
|
||||||
e?.preventDefault()
|
|
||||||
|
|
||||||
if (!canSubmitSelection) {
|
|
||||||
setHasSubmitted(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(selection)
|
|
||||||
}
|
|
||||||
|
|
||||||
const isMixedSelection = arg.inputType === 'selectionMixed'
|
|
||||||
const allowNoSelection = isMixedSelection && arg.allowNoSelection
|
|
||||||
const showSceneSelection =
|
|
||||||
isMixedSelection && arg.selectionSource?.allowSceneSelection
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form id="arg-form" onSubmit={handleSubmit}>
|
|
||||||
<label
|
|
||||||
className={
|
|
||||||
'relative flex flex-col mx-4 my-4 ' +
|
|
||||||
(!hasSubmitted || canSubmitSelection || 'text-destroy-50')
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{canSubmitSelection
|
|
||||||
? 'Select objects in the scene'
|
|
||||||
: 'Select code or objects in the scene'}
|
|
||||||
|
|
||||||
{showSceneSelection && (
|
|
||||||
<div className="scene-selection mt-2">
|
|
||||||
<p className="text-sm text-chalkboard-60">
|
|
||||||
Select objects in the scene
|
|
||||||
</p>
|
|
||||||
{/* Scene selection UI will be handled by the parent component */}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{allowNoSelection && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => onSubmit(null)}
|
|
||||||
className="mt-2 px-4 py-2 rounded border border-chalkboard-30 text-chalkboard-90 dark:text-chalkboard-10 hover:bg-chalkboard-10 dark:hover:bg-chalkboard-90 transition-colors"
|
|
||||||
>
|
|
||||||
Continue without selection
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<span data-testid="cmd-bar-arg-name" className="sr-only">
|
|
||||||
{arg.name}
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
id="selection"
|
|
||||||
name="selection"
|
|
||||||
ref={inputRef}
|
|
||||||
required
|
|
||||||
data-testid="cmd-bar-arg-value"
|
|
||||||
placeholder="Select an entity with your mouse"
|
|
||||||
className="absolute inset-0 w-full h-full opacity-0 cursor-default"
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (event.key === 'Backspace') {
|
|
||||||
stepBack()
|
|
||||||
} else if (event.key === 'Escape') {
|
|
||||||
commandBarActor.send({ type: 'Close' })
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={handleChange}
|
|
||||||
value={JSON.stringify(selection || {})}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</form>
|
|
||||||
)
|
|
||||||
}
|
|
@ -130,8 +130,6 @@ export const FileMachineProvider = ({
|
|||||||
navigateToFile: ({ context, event }) => {
|
navigateToFile: ({ context, event }) => {
|
||||||
if (event.type !== 'xstate.done.actor.create-and-open-file') return
|
if (event.type !== 'xstate.done.actor.create-and-open-file') return
|
||||||
if (event.output && 'name' in event.output) {
|
if (event.output && 'name' in event.output) {
|
||||||
// TODO: Technically this is not the same as the FileTree Onclick even if they are in the same page
|
|
||||||
// What is "Open file?"
|
|
||||||
commandBarActor.send({ type: 'Close' })
|
commandBarActor.send({ type: 'Close' })
|
||||||
navigate(
|
navigate(
|
||||||
`..${PATHS.FILE}/${encodeURIComponent(
|
`..${PATHS.FILE}/${encodeURIComponent(
|
||||||
|
@ -23,8 +23,6 @@ import { FileEntry } from 'lib/project'
|
|||||||
import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher'
|
import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher'
|
||||||
import { normalizeLineEndings } from 'lib/codeEditor'
|
import { normalizeLineEndings } from 'lib/codeEditor'
|
||||||
import { reportRejection } from 'lib/trap'
|
import { reportRejection } from 'lib/trap'
|
||||||
import { useKclContext } from 'lang/KclProvider'
|
|
||||||
import { kclErrorsByFilename, KCLError } from 'lang/errors'
|
|
||||||
|
|
||||||
function getIndentationCSS(level: number) {
|
function getIndentationCSS(level: number) {
|
||||||
return `calc(1rem * ${level + 1})`
|
return `calc(1rem * ${level + 1})`
|
||||||
@ -160,7 +158,6 @@ const FileTreeItem = ({
|
|||||||
level = 0,
|
level = 0,
|
||||||
treeSelection,
|
treeSelection,
|
||||||
setTreeSelection,
|
setTreeSelection,
|
||||||
runtimeErrors,
|
|
||||||
}: {
|
}: {
|
||||||
parentDir: FileEntry | undefined
|
parentDir: FileEntry | undefined
|
||||||
project?: IndexLoaderData['project']
|
project?: IndexLoaderData['project']
|
||||||
@ -180,7 +177,6 @@ const FileTreeItem = ({
|
|||||||
level?: number
|
level?: number
|
||||||
treeSelection: FileEntry | undefined
|
treeSelection: FileEntry | undefined
|
||||||
setTreeSelection: Dispatch<React.SetStateAction<FileEntry | undefined>>
|
setTreeSelection: Dispatch<React.SetStateAction<FileEntry | undefined>>
|
||||||
runtimeErrors: Map<string, KCLError[]>
|
|
||||||
}) => {
|
}) => {
|
||||||
const { send: fileSend, context: fileContext } = useFileContext()
|
const { send: fileSend, context: fileContext } = useFileContext()
|
||||||
const { onFileOpen, onFileClose } = useLspContext()
|
const { onFileOpen, onFileClose } = useLspContext()
|
||||||
@ -190,8 +186,6 @@ const FileTreeItem = ({
|
|||||||
const isFileOrDirHighlighted = treeSelection?.path === fileOrDir?.path
|
const isFileOrDirHighlighted = treeSelection?.path === fileOrDir?.path
|
||||||
const itemRef = useRef(null)
|
const itemRef = useRef(null)
|
||||||
|
|
||||||
const hasRuntimeError = runtimeErrors.has(fileOrDir.path)
|
|
||||||
|
|
||||||
// Since every file or directory gets its own FileTreeItem, we can do this.
|
// Since every file or directory gets its own FileTreeItem, we can do this.
|
||||||
// Because subtrees only render when they are opened, that means this
|
// Because subtrees only render when they are opened, that means this
|
||||||
// only listens when they open. Because this acts like a useEffect, when
|
// only listens when they open. Because this acts like a useEffect, when
|
||||||
@ -298,7 +292,7 @@ const FileTreeItem = ({
|
|||||||
>
|
>
|
||||||
{!isRenaming ? (
|
{!isRenaming ? (
|
||||||
<button
|
<button
|
||||||
className="relative flex gap-1 items-center py-0.5 rounded-none border-none p-0 m-0 text-sm w-full hover:!bg-transparent text-left !text-inherit"
|
className="flex gap-1 items-center py-0.5 rounded-none border-none p-0 m-0 text-sm w-full hover:!bg-transparent text-left !text-inherit"
|
||||||
style={{ paddingInlineStart: getIndentationCSS(level) }}
|
style={{ paddingInlineStart: getIndentationCSS(level) }}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.currentTarget.focus()
|
e.currentTarget.focus()
|
||||||
@ -306,21 +300,11 @@ const FileTreeItem = ({
|
|||||||
}}
|
}}
|
||||||
onKeyUp={handleKeyUp}
|
onKeyUp={handleKeyUp}
|
||||||
>
|
>
|
||||||
{hasRuntimeError && (
|
|
||||||
<p
|
|
||||||
className={
|
|
||||||
'absolute m-0 p-0 bottom-3 left-6 w-3 h-3 flex items-center justify-center text-[9px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200'
|
|
||||||
}
|
|
||||||
title={`Click to view notifications`}
|
|
||||||
>
|
|
||||||
<span>x</span>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<CustomIcon
|
<CustomIcon
|
||||||
name={fileOrDir.name?.endsWith(FILE_EXT) ? 'kcl' : 'file'}
|
name={fileOrDir.name?.endsWith(FILE_EXT) ? 'kcl' : 'file'}
|
||||||
className="inline-block w-3 text-current"
|
className="inline-block w-3 text-current"
|
||||||
/>
|
/>
|
||||||
<span className="pl-1">{fileOrDir.name}</span>
|
{fileOrDir.name}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<RenameForm
|
<RenameForm
|
||||||
@ -430,7 +414,6 @@ const FileTreeItem = ({
|
|||||||
key={level + '-' + child.path}
|
key={level + '-' + child.path}
|
||||||
treeSelection={treeSelection}
|
treeSelection={treeSelection}
|
||||||
setTreeSelection={setTreeSelection}
|
setTreeSelection={setTreeSelection}
|
||||||
runtimeErrors={runtimeErrors}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
@ -677,8 +660,6 @@ export const FileTreeInner = ({
|
|||||||
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
|
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
|
||||||
const { send: fileSend, context: fileContext } = useFileContext()
|
const { send: fileSend, context: fileContext } = useFileContext()
|
||||||
const { send: modelingSend } = useModelingContext()
|
const { send: modelingSend } = useModelingContext()
|
||||||
const { errors } = useKclContext()
|
|
||||||
const runtimeErrors = kclErrorsByFilename(errors)
|
|
||||||
|
|
||||||
const [lastDirectoryClicked, setLastDirectoryClicked] = useState<
|
const [lastDirectoryClicked, setLastDirectoryClicked] = useState<
|
||||||
FileEntry | undefined
|
FileEntry | undefined
|
||||||
@ -788,7 +769,6 @@ export const FileTreeInner = ({
|
|||||||
key={fileOrDir.path}
|
key={fileOrDir.path}
|
||||||
treeSelection={treeSelection}
|
treeSelection={treeSelection}
|
||||||
setTreeSelection={setTreeSelection}
|
setTreeSelection={setTreeSelection}
|
||||||
runtimeErrors={runtimeErrors}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
@ -18,7 +18,6 @@ import { editorManager } from 'lib/singletons'
|
|||||||
import { ContextFrom } from 'xstate'
|
import { ContextFrom } from 'xstate'
|
||||||
import { settingsMachine } from 'machines/settingsMachine'
|
import { settingsMachine } from 'machines/settingsMachine'
|
||||||
import { FeatureTreePane } from './FeatureTreePane'
|
import { FeatureTreePane } from './FeatureTreePane'
|
||||||
import { kclErrorsByFilename } from 'lang/errors'
|
|
||||||
|
|
||||||
export type SidebarType =
|
export type SidebarType =
|
||||||
| 'code'
|
| 'code'
|
||||||
@ -31,10 +30,8 @@ export type SidebarType =
|
|||||||
| 'variables'
|
| 'variables'
|
||||||
|
|
||||||
export interface BadgeInfo {
|
export interface BadgeInfo {
|
||||||
value: (props: PaneCallbackProps) => boolean | number | string
|
value: (props: PaneCallbackProps) => boolean | number
|
||||||
onClick?: MouseEventHandler<any>
|
onClick?: MouseEventHandler<any>
|
||||||
className?: string
|
|
||||||
title?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,25 +152,6 @@ export const sidebarPanes: SidebarPane[] = [
|
|||||||
},
|
},
|
||||||
keybinding: 'Shift + F',
|
keybinding: 'Shift + F',
|
||||||
hide: ({ platform }) => platform === 'web',
|
hide: ({ platform }) => platform === 'web',
|
||||||
showBadge: {
|
|
||||||
value: (context) => {
|
|
||||||
// Only compute runtime errors! Compilation errors are not tracked here.
|
|
||||||
const errors = kclErrorsByFilename(context.kclContext.errors)
|
|
||||||
return errors.size > 0 ? 'x' : ''
|
|
||||||
},
|
|
||||||
onClick: (e) => {
|
|
||||||
e.preventDefault()
|
|
||||||
// TODO: When we have generic file open
|
|
||||||
// If badge is pressed
|
|
||||||
// Open the first error in the array of errors
|
|
||||||
// Then scroll to error
|
|
||||||
// Do you automatically open the project files
|
|
||||||
// editorManager.scrollToFirstErrorDiagnosticIfExists()
|
|
||||||
},
|
|
||||||
className:
|
|
||||||
'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[9px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200',
|
|
||||||
title: 'Project files have runtime errors',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'variables',
|
id: 'variables',
|
||||||
|
@ -27,10 +27,8 @@ interface ModelingSidebarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface BadgeInfoComputed {
|
interface BadgeInfoComputed {
|
||||||
value: number | boolean | string
|
value: number | boolean
|
||||||
onClick?: MouseEventHandler<any>
|
onClick?: MouseEventHandler<any>
|
||||||
className?: string
|
|
||||||
title?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlatformString(): 'web' | 'desktop' {
|
function getPlatformString(): 'web' | 'desktop' {
|
||||||
@ -118,8 +116,6 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
|||||||
acc[pane.id] = {
|
acc[pane.id] = {
|
||||||
value: pane.showBadge.value(paneCallbackProps),
|
value: pane.showBadge.value(paneCallbackProps),
|
||||||
onClick: pane.showBadge.onClick,
|
onClick: pane.showBadge.onClick,
|
||||||
className: pane.showBadge.className,
|
|
||||||
title: pane.showBadge.title,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
@ -129,7 +125,6 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
|||||||
// Clear any hidden panes from the `openPanes` array
|
// Clear any hidden panes from the `openPanes` array
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const panesToReset: SidebarType[] = []
|
const panesToReset: SidebarType[] = []
|
||||||
|
|
||||||
sidebarPanes.forEach((pane) => {
|
sidebarPanes.forEach((pane) => {
|
||||||
if (
|
if (
|
||||||
pane.hide === true ||
|
pane.hide === true ||
|
||||||
@ -344,31 +339,22 @@ function ModelingPaneButton({
|
|||||||
<p
|
<p
|
||||||
id={`${paneConfig.id}-badge`}
|
id={`${paneConfig.id}-badge`}
|
||||||
className={
|
className={
|
||||||
showBadge.className
|
'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[10px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200'
|
||||||
? showBadge.className
|
|
||||||
: 'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[10px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200'
|
|
||||||
}
|
}
|
||||||
onClick={showBadge.onClick}
|
onClick={showBadge.onClick}
|
||||||
title={
|
title={`Click to view ${showBadge.value} notification${
|
||||||
showBadge.title
|
Number(showBadge.value) > 1 ? 's' : ''
|
||||||
? showBadge.title
|
}`}
|
||||||
: `Click to view ${showBadge.value} notification${
|
|
||||||
Number(showBadge.value) > 1 ? 's' : ''
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className="sr-only"> has </span>
|
<span className="sr-only"> has </span>
|
||||||
{typeof showBadge.value === 'number' ||
|
{typeof showBadge.value === 'number' ? (
|
||||||
typeof showBadge.value === 'string' ? (
|
|
||||||
<span>{showBadge.value}</span>
|
<span>{showBadge.value}</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="sr-only">a</span>
|
<span className="sr-only">a</span>
|
||||||
)}
|
)}
|
||||||
{typeof showBadge.value === 'number' && (
|
<span className="sr-only">
|
||||||
<span className="sr-only">
|
notification{Number(showBadge.value) > 1 ? 's' : ''}
|
||||||
notification{Number(showBadge.value) > 1 ? 's' : ''}
|
</span>
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,12 +4,11 @@ import {
|
|||||||
useLocation,
|
useLocation,
|
||||||
useNavigate,
|
useNavigate,
|
||||||
useRouteLoaderData,
|
useRouteLoaderData,
|
||||||
redirect,
|
|
||||||
} from 'react-router-dom'
|
} from 'react-router-dom'
|
||||||
import { PATHS } from 'lib/paths'
|
import { PATHS } from 'lib/paths'
|
||||||
import { markOnce } from 'lib/performance'
|
import { markOnce } from 'lib/performance'
|
||||||
import { useAuthNavigation } from 'hooks/useAuthNavigation'
|
import { useAuthNavigation } from 'hooks/useAuthNavigation'
|
||||||
import { useAuthState, useSettings } from 'machines/appMachine'
|
import { useAuthState } from 'machines/appMachine'
|
||||||
import { IndexLoaderData } from 'lib/types'
|
import { IndexLoaderData } from 'lib/types'
|
||||||
import { getAppSettingsFilePath } from 'lib/desktop'
|
import { getAppSettingsFilePath } from 'lib/desktop'
|
||||||
import { isDesktop } from 'lib/isDesktop'
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
@ -17,9 +16,6 @@ import { trap } from 'lib/trap'
|
|||||||
import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher'
|
import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher'
|
||||||
import { loadAndValidateSettings } from 'lib/settings/settingsUtils'
|
import { loadAndValidateSettings } from 'lib/settings/settingsUtils'
|
||||||
import { settingsActor } from 'machines/appMachine'
|
import { settingsActor } from 'machines/appMachine'
|
||||||
import makeUrlPathRelative from 'lib/makeUrlPathRelative'
|
|
||||||
import { OnboardingStatus } from 'wasm-lib/kcl/bindings/OnboardingStatus'
|
|
||||||
import { SnapshotFrom } from 'xstate'
|
|
||||||
|
|
||||||
export const RouteProviderContext = createContext({})
|
export const RouteProviderContext = createContext({})
|
||||||
|
|
||||||
@ -33,7 +29,6 @@ export function RouteProvider({ children }: { children: ReactNode }) {
|
|||||||
const navigation = useNavigation()
|
const navigation = useNavigation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const settings = useSettings()
|
|
||||||
|
|
||||||
const authState = useAuthState()
|
const authState = useAuthState()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -48,32 +43,6 @@ export function RouteProvider({ children }: { children: ReactNode }) {
|
|||||||
markOnce('code/willLoadHome')
|
markOnce('code/willLoadHome')
|
||||||
} else if (isFile) {
|
} else if (isFile) {
|
||||||
markOnce('code/willLoadFile')
|
markOnce('code/willLoadFile')
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Move to XState. This block has been moved from routerLoaders
|
|
||||||
* and is borrowing the `isFile` logic from the rest of this
|
|
||||||
* telemetry-focused `useEffect`. Once `appMachine` knows about
|
|
||||||
* the current route and navigation, this can be moved into settingsMachine
|
|
||||||
* to fire as soon as the user settings have been read.
|
|
||||||
*/
|
|
||||||
const onboardingStatus: OnboardingStatus =
|
|
||||||
settings.app.onboardingStatus.current || ''
|
|
||||||
// '' is the initial state, 'completed' and 'dismissed' are the final states
|
|
||||||
const needsToOnboard =
|
|
||||||
onboardingStatus.length === 0 ||
|
|
||||||
!(onboardingStatus === 'completed' || onboardingStatus === 'dismissed')
|
|
||||||
const shouldRedirectToOnboarding = isFile && needsToOnboard
|
|
||||||
|
|
||||||
if (
|
|
||||||
shouldRedirectToOnboarding &&
|
|
||||||
settingsActor.getSnapshot().matches('idle')
|
|
||||||
) {
|
|
||||||
navigate(
|
|
||||||
(first ? location.pathname : navigation.location?.pathname) +
|
|
||||||
PATHS.ONBOARDING.INDEX +
|
|
||||||
onboardingStatus.slice(1)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setFirstState(false)
|
setFirstState(false)
|
||||||
}, [navigation])
|
}, [navigation])
|
||||||
|
@ -293,13 +293,6 @@ export class KclManager {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOTCHA:
|
|
||||||
// When we safeParse this is tied to execution because they clicked a new file to load
|
|
||||||
// Clear all previous errors and logs because they are old since they executed a new file
|
|
||||||
// If we decouple safeParse from execution we need to move this application logic.
|
|
||||||
this._kclErrorsCallBack([])
|
|
||||||
this._logsCallBack([])
|
|
||||||
|
|
||||||
this.addDiagnostics(complilationErrorsToDiagnostics(result.errors))
|
this.addDiagnostics(complilationErrorsToDiagnostics(result.errors))
|
||||||
this.addDiagnostics(complilationErrorsToDiagnostics(result.warnings))
|
this.addDiagnostics(complilationErrorsToDiagnostics(result.warnings))
|
||||||
if (result.errors.length > 0) {
|
if (result.errors.length > 0) {
|
||||||
|
@ -13,7 +13,6 @@ describe('test kclErrToDiagnostic', () => {
|
|||||||
operations: [],
|
operations: [],
|
||||||
artifactCommands: [],
|
artifactCommands: [],
|
||||||
artifactGraph: defaultArtifactGraph(),
|
artifactGraph: defaultArtifactGraph(),
|
||||||
filenames: {},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '',
|
name: '',
|
||||||
@ -24,7 +23,6 @@ describe('test kclErrToDiagnostic', () => {
|
|||||||
operations: [],
|
operations: [],
|
||||||
artifactCommands: [],
|
artifactCommands: [],
|
||||||
artifactGraph: defaultArtifactGraph(),
|
artifactGraph: defaultArtifactGraph(),
|
||||||
filenames: {},
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const diagnostics = kclErrorsToDiagnostics(errors)
|
const diagnostics = kclErrorsToDiagnostics(errors)
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import {
|
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||||
KclError,
|
|
||||||
KclError as RustKclError,
|
|
||||||
} from '../wasm-lib/kcl/bindings/KclError'
|
|
||||||
import { CompilationError } from 'wasm-lib/kcl/bindings/CompilationError'
|
import { CompilationError } from 'wasm-lib/kcl/bindings/CompilationError'
|
||||||
import { Diagnostic as CodeMirrorDiagnostic } from '@codemirror/lint'
|
import { Diagnostic as CodeMirrorDiagnostic } from '@codemirror/lint'
|
||||||
import { posToOffset } from '@kittycad/codemirror-lsp-client'
|
import { posToOffset } from '@kittycad/codemirror-lsp-client'
|
||||||
@ -16,7 +13,6 @@ import {
|
|||||||
SourceRange,
|
SourceRange,
|
||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import { Operation } from 'wasm-lib/kcl/bindings/Operation'
|
import { Operation } from 'wasm-lib/kcl/bindings/Operation'
|
||||||
import { ModulePath } from 'wasm-lib/kcl/bindings/ModulePath'
|
|
||||||
|
|
||||||
type ExtractKind<T> = T extends { kind: infer K } ? K : never
|
type ExtractKind<T> = T extends { kind: infer K } ? K : never
|
||||||
export class KCLError extends Error {
|
export class KCLError extends Error {
|
||||||
@ -26,7 +22,6 @@ export class KCLError extends Error {
|
|||||||
operations: Operation[]
|
operations: Operation[]
|
||||||
artifactCommands: ArtifactCommand[]
|
artifactCommands: ArtifactCommand[]
|
||||||
artifactGraph: ArtifactGraph
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
kind: ExtractKind<RustKclError> | 'name',
|
kind: ExtractKind<RustKclError> | 'name',
|
||||||
@ -34,8 +29,7 @@ export class KCLError extends Error {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
this.kind = kind
|
this.kind = kind
|
||||||
@ -44,7 +38,6 @@ export class KCLError extends Error {
|
|||||||
this.operations = operations
|
this.operations = operations
|
||||||
this.artifactCommands = artifactCommands
|
this.artifactCommands = artifactCommands
|
||||||
this.artifactGraph = artifactGraph
|
this.artifactGraph = artifactGraph
|
||||||
this.filenames = filenames
|
|
||||||
Object.setPrototypeOf(this, KCLError.prototype)
|
Object.setPrototypeOf(this, KCLError.prototype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,8 +48,7 @@ export class KCLLexicalError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'lexical',
|
'lexical',
|
||||||
@ -64,8 +56,7 @@ export class KCLLexicalError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
|
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
|
||||||
}
|
}
|
||||||
@ -77,8 +68,7 @@ export class KCLInternalError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'internal',
|
'internal',
|
||||||
@ -86,8 +76,7 @@ export class KCLInternalError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
|
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
|
||||||
}
|
}
|
||||||
@ -99,8 +88,7 @@ export class KCLSyntaxError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'syntax',
|
'syntax',
|
||||||
@ -108,8 +96,7 @@ export class KCLSyntaxError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
|
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
|
||||||
}
|
}
|
||||||
@ -121,8 +108,7 @@ export class KCLSemanticError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'semantic',
|
'semantic',
|
||||||
@ -130,8 +116,7 @@ export class KCLSemanticError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLSemanticError.prototype)
|
Object.setPrototypeOf(this, KCLSemanticError.prototype)
|
||||||
}
|
}
|
||||||
@ -143,18 +128,9 @@ export class KCLTypeError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super('type', msg, sourceRange, operations, artifactCommands, artifactGraph)
|
||||||
'type',
|
|
||||||
msg,
|
|
||||||
sourceRange,
|
|
||||||
operations,
|
|
||||||
artifactCommands,
|
|
||||||
artifactGraph,
|
|
||||||
filenames
|
|
||||||
)
|
|
||||||
Object.setPrototypeOf(this, KCLTypeError.prototype)
|
Object.setPrototypeOf(this, KCLTypeError.prototype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,8 +141,7 @@ export class KCLUnimplementedError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'unimplemented',
|
'unimplemented',
|
||||||
@ -174,8 +149,7 @@ export class KCLUnimplementedError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLUnimplementedError.prototype)
|
Object.setPrototypeOf(this, KCLUnimplementedError.prototype)
|
||||||
}
|
}
|
||||||
@ -187,8 +161,7 @@ export class KCLUnexpectedError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'unexpected',
|
'unexpected',
|
||||||
@ -196,8 +169,7 @@ export class KCLUnexpectedError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLUnexpectedError.prototype)
|
Object.setPrototypeOf(this, KCLUnexpectedError.prototype)
|
||||||
}
|
}
|
||||||
@ -209,8 +181,7 @@ export class KCLValueAlreadyDefined extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'name',
|
'name',
|
||||||
@ -218,8 +189,7 @@ export class KCLValueAlreadyDefined extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLValueAlreadyDefined.prototype)
|
Object.setPrototypeOf(this, KCLValueAlreadyDefined.prototype)
|
||||||
}
|
}
|
||||||
@ -231,8 +201,7 @@ export class KCLUndefinedValueError extends KCLError {
|
|||||||
sourceRange: SourceRange,
|
sourceRange: SourceRange,
|
||||||
operations: Operation[],
|
operations: Operation[],
|
||||||
artifactCommands: ArtifactCommand[],
|
artifactCommands: ArtifactCommand[],
|
||||||
artifactGraph: ArtifactGraph,
|
artifactGraph: ArtifactGraph
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
'name',
|
'name',
|
||||||
@ -240,8 +209,7 @@ export class KCLUndefinedValueError extends KCLError {
|
|||||||
sourceRange,
|
sourceRange,
|
||||||
operations,
|
operations,
|
||||||
artifactCommands,
|
artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph
|
||||||
filenames
|
|
||||||
)
|
)
|
||||||
Object.setPrototypeOf(this, KCLUndefinedValueError.prototype)
|
Object.setPrototypeOf(this, KCLUndefinedValueError.prototype)
|
||||||
}
|
}
|
||||||
@ -264,8 +232,7 @@ export function lspDiagnosticsToKclErrors(
|
|||||||
[posToOffset(doc, range.start)!, posToOffset(doc, range.end)!, 0],
|
[posToOffset(doc, range.start)!, posToOffset(doc, range.end)!, 0],
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph(),
|
defaultArtifactGraph()
|
||||||
{}
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
@ -337,34 +304,3 @@ export function complilationErrorsToDiagnostics(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an array of KCL Errors with a new formatting to
|
|
||||||
// easily map SourceRange of an error to the filename to display in the
|
|
||||||
// side bar UI. This is to indicate an error in an imported file, it isn't
|
|
||||||
// the specific code mirror error interface.
|
|
||||||
export function kclErrorsByFilename(
|
|
||||||
errors: KCLError[]
|
|
||||||
): Map<string, KCLError[]> {
|
|
||||||
const fileNameToError: Map<string, KCLError[]> = new Map()
|
|
||||||
errors.forEach((error: KCLError) => {
|
|
||||||
const filenames = error.filenames
|
|
||||||
const sourceRange: SourceRange = error.sourceRange
|
|
||||||
const fileIndex = sourceRange[2]
|
|
||||||
const modulePath: ModulePath | undefined = filenames[fileIndex]
|
|
||||||
if (modulePath) {
|
|
||||||
let stdOrLocalPath = modulePath.value
|
|
||||||
if (stdOrLocalPath) {
|
|
||||||
// Build up an array of errors per file name
|
|
||||||
const value = fileNameToError.get(stdOrLocalPath)
|
|
||||||
if (!value) {
|
|
||||||
fileNameToError.set(stdOrLocalPath, [error])
|
|
||||||
} else {
|
|
||||||
value.push(error)
|
|
||||||
fileNameToError.set(stdOrLocalPath, [error])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return fileNameToError
|
|
||||||
}
|
|
||||||
|
@ -511,8 +511,7 @@ const theExtrude = startSketchOn('XY')
|
|||||||
topLevelRange(129, 135),
|
topLevelRange(129, 135),
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph(),
|
defaultArtifactGraph()
|
||||||
{}
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -116,11 +116,7 @@ const runGetPathToExtrudeForSegmentSelectionTest = async (
|
|||||||
}
|
}
|
||||||
if (!extrudeInSketchPipe) {
|
if (!extrudeInSketchPipe) {
|
||||||
const init = expectedExtrudeNode.init
|
const init = expectedExtrudeNode.init
|
||||||
if (
|
if (init.type !== 'CallExpression' && init.type !== 'PipeExpression') {
|
||||||
init.type !== 'CallExpression' &&
|
|
||||||
init.type !== 'CallExpressionKw' &&
|
|
||||||
init.type !== 'PipeExpression'
|
|
||||||
) {
|
|
||||||
return new Error(
|
return new Error(
|
||||||
'Expected extrude expression is not a CallExpression or PipeExpression'
|
'Expected extrude expression is not a CallExpression or PipeExpression'
|
||||||
)
|
)
|
||||||
@ -133,33 +129,25 @@ const runGetPathToExtrudeForSegmentSelectionTest = async (
|
|||||||
// ast
|
// ast
|
||||||
const ast = assertParse(code)
|
const ast = assertParse(code)
|
||||||
|
|
||||||
// range
|
// selection
|
||||||
const segmentRange = topLevelRange(
|
const segmentRange = topLevelRange(
|
||||||
code.indexOf(selectedSegmentSnippet),
|
code.indexOf(selectedSegmentSnippet),
|
||||||
code.indexOf(selectedSegmentSnippet) + selectedSegmentSnippet.length
|
code.indexOf(selectedSegmentSnippet) + selectedSegmentSnippet.length
|
||||||
)
|
)
|
||||||
|
const selection: Selection = {
|
||||||
|
codeRef: codeRefFromRange(segmentRange, ast),
|
||||||
|
}
|
||||||
|
|
||||||
// executeAst and artifactGraph
|
// executeAst and artifactGraph
|
||||||
await kclManager.executeAst({ ast })
|
await kclManager.executeAst({ ast })
|
||||||
const artifactGraph = engineCommandManager.artifactGraph
|
const artifactGraph = engineCommandManager.artifactGraph
|
||||||
|
|
||||||
// find artifact
|
|
||||||
const maybeArtifact = [...artifactGraph].find(([, artifact]) => {
|
|
||||||
if (!('codeRef' in artifact && artifact.codeRef)) return false
|
|
||||||
return isOverlap(artifact.codeRef.range, segmentRange)
|
|
||||||
})
|
|
||||||
|
|
||||||
// build selection
|
|
||||||
const selection: Selection = {
|
|
||||||
codeRef: codeRefFromRange(segmentRange, ast),
|
|
||||||
artifact: maybeArtifact ? maybeArtifact[1] : undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
// get extrude expression
|
// get extrude expression
|
||||||
const pathResult = getPathToExtrudeForSegmentSelection(
|
const pathResult = getPathToExtrudeForSegmentSelection(
|
||||||
ast,
|
ast,
|
||||||
selection,
|
selection,
|
||||||
artifactGraph
|
artifactGraph,
|
||||||
|
dependencies
|
||||||
)
|
)
|
||||||
if (err(pathResult)) return pathResult
|
if (err(pathResult)) return pathResult
|
||||||
const { pathToExtrudeNode } = pathResult
|
const { pathToExtrudeNode } = pathResult
|
||||||
@ -246,56 +234,6 @@ extrude003 = extrude(sketch003, length = -15)`
|
|||||||
expectedExtrudeSnippet
|
expectedExtrudeSnippet
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
it('should return the correct paths for a (piped) extrude based on the other body (face)', async () => {
|
|
||||||
const code = `sketch001 = startSketchOn('XY')
|
|
||||||
|> startProfileAt([-25, -25], %)
|
|
||||||
|> yLine(50, %)
|
|
||||||
|> xLine(50, %)
|
|
||||||
|> yLine(-50, %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = 50)
|
|
||||||
sketch002 = startSketchOn(sketch001, 'END')
|
|
||||||
|> startProfileAt([-15, -15], %)
|
|
||||||
|> yLine(30, %)
|
|
||||||
|> xLine(30, %)
|
|
||||||
|> yLine(-30, %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
|> extrude(length = 30)`
|
|
||||||
const selectedSegmentSnippet = `xLine(30, %)`
|
|
||||||
const expectedExtrudeSnippet = `extrude(length = 30)`
|
|
||||||
await runGetPathToExtrudeForSegmentSelectionTest(
|
|
||||||
code,
|
|
||||||
selectedSegmentSnippet,
|
|
||||||
expectedExtrudeSnippet
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it('should return the correct paths for a (non-piped) extrude based on the other body (face)', async () => {
|
|
||||||
const code = `sketch001 = startSketchOn('XY')
|
|
||||||
|> startProfileAt([-25, -25], %)
|
|
||||||
|> yLine(50, %)
|
|
||||||
|> xLine(50, %)
|
|
||||||
|> yLine(-50, %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
extrude001 = extrude(sketch001, length = 50)
|
|
||||||
sketch002 = startSketchOn(extrude001, 'END')
|
|
||||||
|> startProfileAt([-15, -15], %)
|
|
||||||
|> yLine(30, %)
|
|
||||||
|> xLine(30, %)
|
|
||||||
|> yLine(-30, %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
extrude002 = extrude(sketch002, length = 30)`
|
|
||||||
const selectedSegmentSnippet = `xLine(30, %)`
|
|
||||||
const expectedExtrudeSnippet = `extrude002 = extrude(sketch002, length = 30)`
|
|
||||||
await runGetPathToExtrudeForSegmentSelectionTest(
|
|
||||||
code,
|
|
||||||
selectedSegmentSnippet,
|
|
||||||
expectedExtrudeSnippet
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it('should not return any path for missing extrusion', async () => {
|
it('should not return any path for missing extrusion', async () => {
|
||||||
const code = `sketch001 = startSketchOn('XY')
|
const code = `sketch001 = startSketchOn('XY')
|
||||||
|> startProfileAt([-30, 30], %)
|
|> startProfileAt([-30, 30], %)
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
Program,
|
Program,
|
||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
VariableDeclarator,
|
VariableDeclarator,
|
||||||
|
sketchFromKclValue,
|
||||||
} from '../wasm'
|
} from '../wasm'
|
||||||
import {
|
import {
|
||||||
createCallExpressionStdLib,
|
createCallExpressionStdLib,
|
||||||
@ -34,11 +35,11 @@ import {
|
|||||||
sketchLineHelperMap,
|
sketchLineHelperMap,
|
||||||
sketchLineHelperMapKw,
|
sketchLineHelperMapKw,
|
||||||
} from '../std/sketch'
|
} from '../std/sketch'
|
||||||
import { err } from 'lib/trap'
|
import { err, trap } from 'lib/trap'
|
||||||
import { Selection, Selections } from 'lib/selections'
|
import { Selection, Selections } from 'lib/selections'
|
||||||
import { KclCommandValue } from 'lib/commandTypes'
|
import { KclCommandValue } from 'lib/commandTypes'
|
||||||
import { isArray } from 'lib/utils'
|
import { isArray } from 'lib/utils'
|
||||||
import { Artifact, getSweepArtifactFromSelection } from 'lang/std/artifactGraph'
|
import { Artifact, getSweepFromSuspectedPath } from 'lang/std/artifactGraph'
|
||||||
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
||||||
import { findKwArg } from 'lang/util'
|
import { findKwArg } from 'lang/util'
|
||||||
import { KclManager } from 'lang/KclSingleton'
|
import { KclManager } from 'lang/KclSingleton'
|
||||||
@ -120,7 +121,8 @@ export function modifyAstWithEdgeTreatmentAndTag(
|
|||||||
const result = getPathToExtrudeForSegmentSelection(
|
const result = getPathToExtrudeForSegmentSelection(
|
||||||
clonedAstForGetExtrude,
|
clonedAstForGetExtrude,
|
||||||
selection,
|
selection,
|
||||||
artifactGraph
|
artifactGraph,
|
||||||
|
dependencies
|
||||||
)
|
)
|
||||||
if (err(result)) return result
|
if (err(result)) return result
|
||||||
const { pathToSegmentNode, pathToExtrudeNode } = result
|
const { pathToSegmentNode, pathToExtrudeNode } = result
|
||||||
@ -277,19 +279,39 @@ function insertParametersIntoAst(
|
|||||||
export function getPathToExtrudeForSegmentSelection(
|
export function getPathToExtrudeForSegmentSelection(
|
||||||
ast: Program,
|
ast: Program,
|
||||||
selection: Selection,
|
selection: Selection,
|
||||||
artifactGraph: ArtifactGraph
|
artifactGraph: ArtifactGraph,
|
||||||
|
dependencies: {
|
||||||
|
kclManager: KclManager
|
||||||
|
engineCommandManager: EngineCommandManager
|
||||||
|
editorManager: EditorManager
|
||||||
|
codeManager: CodeManager
|
||||||
|
}
|
||||||
): { pathToSegmentNode: PathToNode; pathToExtrudeNode: PathToNode } | Error {
|
): { pathToSegmentNode: PathToNode; pathToExtrudeNode: PathToNode } | Error {
|
||||||
const pathToSegmentNode = getNodePathFromSourceRange(
|
const pathToSegmentNode = getNodePathFromSourceRange(
|
||||||
ast,
|
ast,
|
||||||
selection.codeRef?.range
|
selection.codeRef?.range
|
||||||
)
|
)
|
||||||
|
|
||||||
const sweepArtifact = getSweepArtifactFromSelection(selection, artifactGraph)
|
const varDecNode = getNodeFromPath<VariableDeclaration>(
|
||||||
if (err(sweepArtifact)) return sweepArtifact
|
ast,
|
||||||
|
pathToSegmentNode,
|
||||||
|
'VariableDeclaration'
|
||||||
|
)
|
||||||
|
if (err(varDecNode)) return varDecNode
|
||||||
|
const sketchVar = varDecNode.node.declaration.id.name
|
||||||
|
|
||||||
|
const sketch = sketchFromKclValue(
|
||||||
|
dependencies.kclManager.variables[sketchVar],
|
||||||
|
sketchVar
|
||||||
|
)
|
||||||
|
if (trap(sketch)) return sketch
|
||||||
|
|
||||||
|
const extrusion = getSweepFromSuspectedPath(sketch.id, artifactGraph)
|
||||||
|
if (err(extrusion)) return extrusion
|
||||||
|
|
||||||
const pathToExtrudeNode = getNodePathFromSourceRange(
|
const pathToExtrudeNode = getNodePathFromSourceRange(
|
||||||
ast,
|
ast,
|
||||||
sweepArtifact.codeRef.range
|
extrusion.codeRef.range
|
||||||
)
|
)
|
||||||
if (err(pathToExtrudeNode)) return pathToExtrudeNode
|
if (err(pathToExtrudeNode)) return pathToExtrudeNode
|
||||||
|
|
||||||
|
@ -13,23 +13,36 @@ import {
|
|||||||
createLiteral,
|
createLiteral,
|
||||||
createIdentifier,
|
createIdentifier,
|
||||||
findUniqueName,
|
findUniqueName,
|
||||||
|
createCallExpressionStdLib,
|
||||||
|
createObjectExpression,
|
||||||
createArrayExpression,
|
createArrayExpression,
|
||||||
createVariableDeclaration,
|
createVariableDeclaration,
|
||||||
createCallExpressionStdLibKw,
|
createCallExpressionStdLibKw,
|
||||||
createLabeledArg,
|
createLabeledArg,
|
||||||
} from 'lang/modifyAst'
|
} from 'lang/modifyAst'
|
||||||
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
|
import { KCL_DEFAULT_CONSTANT_PREFIXES } from 'lib/constants'
|
||||||
|
import { KclManager } from 'lang/KclSingleton'
|
||||||
|
import { EngineCommandManager } from 'lang/std/engineConnection'
|
||||||
|
import EditorManager from 'editor/manager'
|
||||||
|
import CodeManager from 'lang/codeManager'
|
||||||
|
|
||||||
export function addShell({
|
export function addShell({
|
||||||
node,
|
node,
|
||||||
selection,
|
selection,
|
||||||
artifactGraph,
|
artifactGraph,
|
||||||
thickness,
|
thickness,
|
||||||
|
dependencies,
|
||||||
}: {
|
}: {
|
||||||
node: Node<Program>
|
node: Node<Program>
|
||||||
selection: Selections
|
selection: Selections
|
||||||
artifactGraph: ArtifactGraph
|
artifactGraph: ArtifactGraph
|
||||||
thickness: Expr
|
thickness: Expr
|
||||||
|
dependencies: {
|
||||||
|
kclManager: KclManager
|
||||||
|
engineCommandManager: EngineCommandManager
|
||||||
|
editorManager: EditorManager
|
||||||
|
codeManager: CodeManager
|
||||||
|
}
|
||||||
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
||||||
const modifiedAst = structuredClone(node)
|
const modifiedAst = structuredClone(node)
|
||||||
|
|
||||||
@ -42,7 +55,8 @@ export function addShell({
|
|||||||
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
const extrudeLookupResult = getPathToExtrudeForSegmentSelection(
|
||||||
clonedAstForGetExtrude,
|
clonedAstForGetExtrude,
|
||||||
graphSelection,
|
graphSelection,
|
||||||
artifactGraph
|
artifactGraph,
|
||||||
|
dependencies
|
||||||
)
|
)
|
||||||
if (err(extrudeLookupResult)) {
|
if (err(extrudeLookupResult)) {
|
||||||
return new Error("Couldn't find extrude")
|
return new Error("Couldn't find extrude")
|
||||||
|
@ -18,7 +18,6 @@ import {
|
|||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import { Models } from '@kittycad/lib'
|
import { Models } from '@kittycad/lib'
|
||||||
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
||||||
import { Selection } from 'lib/selections'
|
|
||||||
import { err } from 'lib/trap'
|
import { err } from 'lib/trap'
|
||||||
import { Cap, Plane, Wall } from 'wasm-lib/kcl/bindings/Artifact'
|
import { Cap, Plane, Wall } from 'wasm-lib/kcl/bindings/Artifact'
|
||||||
import { CapSubType } from 'wasm-lib/kcl/bindings/Artifact'
|
import { CapSubType } from 'wasm-lib/kcl/bindings/Artifact'
|
||||||
@ -80,7 +79,7 @@ interface SegmentArtifactRich extends BaseArtifact {
|
|||||||
|
|
||||||
interface SweepArtifactRich extends BaseArtifact {
|
interface SweepArtifactRich extends BaseArtifact {
|
||||||
type: 'sweep'
|
type: 'sweep'
|
||||||
subType: 'extrusion' | 'revolve' | 'revolveAboutEdge' | 'loft' | 'sweep'
|
subType: 'extrusion' | 'revolve' | 'loft' | 'sweep'
|
||||||
path: PathArtifact
|
path: PathArtifact
|
||||||
surfaces: Array<WallArtifact | CapArtifact>
|
surfaces: Array<WallArtifact | CapArtifact>
|
||||||
edges: Array<SweepEdge>
|
edges: Array<SweepEdge>
|
||||||
@ -456,47 +455,6 @@ export function getSweepFromSuspectedPath(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSweepArtifactFromSelection(
|
|
||||||
selection: Selection,
|
|
||||||
artifactGraph: ArtifactGraph
|
|
||||||
): SweepArtifact | Error {
|
|
||||||
let sweepArtifact: Artifact | null = null
|
|
||||||
if (selection.artifact?.type === 'sweepEdge') {
|
|
||||||
const _artifact = getArtifactOfTypes(
|
|
||||||
{ key: selection.artifact.sweepId, types: ['sweep'] },
|
|
||||||
artifactGraph
|
|
||||||
)
|
|
||||||
if (err(_artifact)) return _artifact
|
|
||||||
sweepArtifact = _artifact
|
|
||||||
} else if (selection.artifact?.type === 'segment') {
|
|
||||||
const _pathArtifact = getArtifactOfTypes(
|
|
||||||
{ key: selection.artifact.pathId, types: ['path'] },
|
|
||||||
artifactGraph
|
|
||||||
)
|
|
||||||
if (err(_pathArtifact)) return _pathArtifact
|
|
||||||
if (!_pathArtifact.sweepId) return new Error('Path does not have a sweepId')
|
|
||||||
const _artifact = getArtifactOfTypes(
|
|
||||||
{ key: _pathArtifact.sweepId, types: ['sweep'] },
|
|
||||||
artifactGraph
|
|
||||||
)
|
|
||||||
if (err(_artifact)) return _artifact
|
|
||||||
sweepArtifact = _artifact
|
|
||||||
} else if (
|
|
||||||
selection.artifact?.type === 'cap' ||
|
|
||||||
selection.artifact?.type === 'wall'
|
|
||||||
) {
|
|
||||||
const _artifact = getArtifactOfTypes(
|
|
||||||
{ key: selection.artifact.sweepId, types: ['sweep'] },
|
|
||||||
artifactGraph
|
|
||||||
)
|
|
||||||
if (err(_artifact)) return _artifact
|
|
||||||
sweepArtifact = _artifact
|
|
||||||
}
|
|
||||||
if (!sweepArtifact) return new Error('No sweep artifact found')
|
|
||||||
|
|
||||||
return sweepArtifact
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCodeRefsByArtifactId(
|
export function getCodeRefsByArtifactId(
|
||||||
id: string,
|
id: string,
|
||||||
artifactGraph: ArtifactGraph
|
artifactGraph: ArtifactGraph
|
||||||
|
@ -60,7 +60,6 @@ import { MetaSettings } from 'wasm-lib/kcl/bindings/MetaSettings'
|
|||||||
import { UnitAngle, UnitLength } from 'wasm-lib/kcl/bindings/ModelingCmd'
|
import { UnitAngle, UnitLength } from 'wasm-lib/kcl/bindings/ModelingCmd'
|
||||||
import { UnitLen } from 'wasm-lib/kcl/bindings/UnitLen'
|
import { UnitLen } from 'wasm-lib/kcl/bindings/UnitLen'
|
||||||
import { UnitAngle as UnitAng } from 'wasm-lib/kcl/bindings/UnitAngle'
|
import { UnitAngle as UnitAng } from 'wasm-lib/kcl/bindings/UnitAngle'
|
||||||
import { ModulePath } from 'wasm-lib/kcl/bindings/ModulePath'
|
|
||||||
|
|
||||||
export type { Artifact } from 'wasm-lib/kcl/bindings/Artifact'
|
export type { Artifact } from 'wasm-lib/kcl/bindings/Artifact'
|
||||||
export type { ArtifactCommand } from 'wasm-lib/kcl/bindings/Artifact'
|
export type { ArtifactCommand } from 'wasm-lib/kcl/bindings/Artifact'
|
||||||
@ -267,8 +266,7 @@ export const parse = (code: string | Error): ParseResult | Error => {
|
|||||||
firstSourceRange(parsed),
|
firstSourceRange(parsed),
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph(),
|
defaultArtifactGraph()
|
||||||
{}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,7 +296,6 @@ export interface ExecState {
|
|||||||
artifactCommands: ArtifactCommand[]
|
artifactCommands: ArtifactCommand[]
|
||||||
artifactGraph: ArtifactGraph
|
artifactGraph: ArtifactGraph
|
||||||
errors: CompilationError[]
|
errors: CompilationError[]
|
||||||
filenames: { [x: number]: ModulePath | undefined }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,7 +310,6 @@ export function emptyExecState(): ExecState {
|
|||||||
artifactCommands: [],
|
artifactCommands: [],
|
||||||
artifactGraph: defaultArtifactGraph(),
|
artifactGraph: defaultArtifactGraph(),
|
||||||
errors: [],
|
errors: [],
|
||||||
filenames: [],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +336,6 @@ function execStateFromRust(
|
|||||||
artifactCommands: execOutcome.artifactCommands,
|
artifactCommands: execOutcome.artifactCommands,
|
||||||
artifactGraph,
|
artifactGraph,
|
||||||
errors: execOutcome.errors,
|
errors: execOutcome.errors,
|
||||||
filenames: execOutcome.filenames,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +347,6 @@ function mockExecStateFromRust(execOutcome: RustExecOutcome): ExecState {
|
|||||||
artifactCommands: execOutcome.artifactCommands,
|
artifactCommands: execOutcome.artifactCommands,
|
||||||
artifactGraph: new Map<ArtifactId, Artifact>(),
|
artifactGraph: new Map<ArtifactId, Artifact>(),
|
||||||
errors: execOutcome.errors,
|
errors: execOutcome.errors,
|
||||||
filenames: execOutcome.filenames,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,7 +474,7 @@ const jsAppSettings = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const errFromErrWithOutputs = (e: any): KCLError => {
|
const errFromErrWithOutputs = (e: any): KCLError => {
|
||||||
console.log(e)
|
console.log('execute error', e)
|
||||||
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
|
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.error.kind,
|
parsed.error.kind,
|
||||||
@ -488,8 +482,7 @@ const errFromErrWithOutputs = (e: any): KCLError => {
|
|||||||
firstSourceRange(parsed.error),
|
firstSourceRange(parsed.error),
|
||||||
parsed.operations,
|
parsed.operations,
|
||||||
parsed.artifactCommands,
|
parsed.artifactCommands,
|
||||||
rustArtifactGraphToMap(parsed.artifactGraph),
|
rustArtifactGraphToMap(parsed.artifactGraph)
|
||||||
parsed.filenames
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,8 +548,7 @@ export const modifyAstForSketch = async (
|
|||||||
firstSourceRange(parsed),
|
firstSourceRange(parsed),
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
defaultArtifactGraph(),
|
defaultArtifactGraph()
|
||||||
{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return Promise.reject(kclError)
|
return Promise.reject(kclError)
|
||||||
|
@ -666,7 +666,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
|||||||
icon: 'chat',
|
icon: 'chat',
|
||||||
args: {
|
args: {
|
||||||
selection: {
|
selection: {
|
||||||
inputType: 'selectionMixed',
|
inputType: 'selection',
|
||||||
selectionTypes: [
|
selectionTypes: [
|
||||||
'solid2d',
|
'solid2d',
|
||||||
'segment',
|
'segment',
|
||||||
@ -678,10 +678,6 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
|||||||
],
|
],
|
||||||
multiple: true,
|
multiple: true,
|
||||||
required: true,
|
required: true,
|
||||||
selectionSource: {
|
|
||||||
allowSceneSelection: true,
|
|
||||||
allowCodeSelection: true,
|
|
||||||
},
|
|
||||||
skip: true,
|
skip: true,
|
||||||
},
|
},
|
||||||
prompt: {
|
prompt: {
|
||||||
|
@ -16,7 +16,6 @@ const INPUT_TYPES = [
|
|||||||
'text',
|
'text',
|
||||||
'kcl',
|
'kcl',
|
||||||
'selection',
|
'selection',
|
||||||
'selectionMixed',
|
|
||||||
'boolean',
|
'boolean',
|
||||||
] as const
|
] as const
|
||||||
export interface KclExpression {
|
export interface KclExpression {
|
||||||
@ -157,23 +156,6 @@ export type CommandArgumentConfig<
|
|||||||
context: CommandBarContext
|
context: CommandBarContext
|
||||||
}) => Promise<boolean | string>
|
}) => Promise<boolean | string>
|
||||||
}
|
}
|
||||||
| {
|
|
||||||
inputType: 'selectionMixed'
|
|
||||||
selectionTypes: Artifact['type'][]
|
|
||||||
multiple: boolean
|
|
||||||
allowNoSelection?: boolean
|
|
||||||
validation?: ({
|
|
||||||
data,
|
|
||||||
context,
|
|
||||||
}: {
|
|
||||||
data: any
|
|
||||||
context: CommandBarContext
|
|
||||||
}) => Promise<boolean | string>
|
|
||||||
selectionSource?: {
|
|
||||||
allowSceneSelection?: boolean
|
|
||||||
allowCodeSelection?: boolean
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| {
|
| {
|
||||||
inputType: 'kcl'
|
inputType: 'kcl'
|
||||||
createVariableByDefault?: boolean
|
createVariableByDefault?: boolean
|
||||||
@ -270,23 +252,6 @@ export type CommandArgument<
|
|||||||
context: CommandBarContext
|
context: CommandBarContext
|
||||||
}) => Promise<boolean | string>
|
}) => Promise<boolean | string>
|
||||||
}
|
}
|
||||||
| {
|
|
||||||
inputType: 'selectionMixed'
|
|
||||||
selectionTypes: Artifact['type'][]
|
|
||||||
multiple: boolean
|
|
||||||
allowNoSelection?: boolean
|
|
||||||
validation?: ({
|
|
||||||
data,
|
|
||||||
context,
|
|
||||||
}: {
|
|
||||||
data: any
|
|
||||||
context: CommandBarContext
|
|
||||||
}) => Promise<boolean | string>
|
|
||||||
selectionSource?: {
|
|
||||||
allowSceneSelection?: boolean
|
|
||||||
allowCodeSelection?: boolean
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| {
|
| {
|
||||||
inputType: 'kcl'
|
inputType: 'kcl'
|
||||||
createVariableByDefault?: boolean
|
createVariableByDefault?: boolean
|
||||||
|
@ -187,16 +187,6 @@ export function buildCommandArgument<
|
|||||||
selectionTypes: arg.selectionTypes,
|
selectionTypes: arg.selectionTypes,
|
||||||
validation: arg.validation,
|
validation: arg.validation,
|
||||||
} satisfies CommandArgument<O, T> & { inputType: 'selection' }
|
} satisfies CommandArgument<O, T> & { inputType: 'selection' }
|
||||||
} else if (arg.inputType === 'selectionMixed') {
|
|
||||||
return {
|
|
||||||
inputType: arg.inputType,
|
|
||||||
...baseCommandArgument,
|
|
||||||
multiple: arg.multiple,
|
|
||||||
selectionTypes: arg.selectionTypes,
|
|
||||||
validation: arg.validation,
|
|
||||||
allowNoSelection: arg.allowNoSelection,
|
|
||||||
selectionSource: arg.selectionSource,
|
|
||||||
} satisfies CommandArgument<O, T> & { inputType: 'selectionMixed' }
|
|
||||||
} else if (arg.inputType === 'kcl') {
|
} else if (arg.inputType === 'kcl') {
|
||||||
return {
|
return {
|
||||||
inputType: arg.inputType,
|
inputType: arg.inputType,
|
||||||
|
@ -43,33 +43,15 @@ export async function submitPromptToEditToQueue({
|
|||||||
projectName,
|
projectName,
|
||||||
}: {
|
}: {
|
||||||
prompt: string
|
prompt: string
|
||||||
selections: Selections | null
|
selections: Selections
|
||||||
code: string
|
code: string
|
||||||
projectName: string
|
projectName: string
|
||||||
token?: string
|
token?: string
|
||||||
artifactGraph: ArtifactGraph
|
artifactGraph: ArtifactGraph
|
||||||
}): Promise<Models['TextToCadIteration_type'] | Error> {
|
}): Promise<Models['TextToCadIteration_type'] | Error> {
|
||||||
// If no selection, use whole file
|
|
||||||
if (selections === null) {
|
|
||||||
const body: Models['TextToCadIterationBody_type'] = {
|
|
||||||
original_source_code: code,
|
|
||||||
prompt,
|
|
||||||
source_ranges: [], // Empty ranges indicates whole file
|
|
||||||
project_name:
|
|
||||||
projectName !== '' && projectName !== 'browser'
|
|
||||||
? projectName
|
|
||||||
: undefined,
|
|
||||||
kcl_version: kclManager.kclVersion,
|
|
||||||
}
|
|
||||||
return submitToApi(body, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle manual code selections and artifact selections differently
|
|
||||||
const ranges: Models['TextToCadIterationBody_type']['source_ranges'] =
|
const ranges: Models['TextToCadIterationBody_type']['source_ranges'] =
|
||||||
selections.graphSelections.flatMap((selection) => {
|
selections.graphSelections.flatMap((selection) => {
|
||||||
const artifact = selection.artifact
|
const artifact = selection.artifact
|
||||||
|
|
||||||
// For artifact selections, add context
|
|
||||||
const prompts: Models['TextToCadIterationBody_type']['source_ranges'] = []
|
const prompts: Models['TextToCadIterationBody_type']['source_ranges'] = []
|
||||||
|
|
||||||
if (artifact?.type === 'cap') {
|
if (artifact?.type === 'cap') {
|
||||||
@ -171,17 +153,8 @@ See later source ranges for more context. about the sweep`,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!artifact) {
|
|
||||||
// manually selected code is more likely to not have an artifact
|
|
||||||
// an example might be highlighting the variable name only in a variable declaration
|
|
||||||
prompts.push({
|
|
||||||
prompt: '',
|
|
||||||
range: convertAppRangeToApiRange(selection.codeRef.range, code),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return prompts
|
return prompts
|
||||||
})
|
})
|
||||||
|
|
||||||
const body: Models['TextToCadIterationBody_type'] = {
|
const body: Models['TextToCadIterationBody_type'] = {
|
||||||
original_source_code: code,
|
original_source_code: code,
|
||||||
prompt,
|
prompt,
|
||||||
@ -190,15 +163,6 @@ See later source ranges for more context. about the sweep`,
|
|||||||
projectName !== '' && projectName !== 'browser' ? projectName : undefined,
|
projectName !== '' && projectName !== 'browser' ? projectName : undefined,
|
||||||
kcl_version: kclManager.kclVersion,
|
kcl_version: kclManager.kclVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
return submitToApi(body, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to handle API submission
|
|
||||||
async function submitToApi(
|
|
||||||
body: Models['TextToCadIterationBody_type'],
|
|
||||||
token?: string
|
|
||||||
): Promise<Models['TextToCadIteration_type'] | Error> {
|
|
||||||
const url = VITE_KC_API_BASE_URL + '/ml/text-to-cad/iteration'
|
const url = VITE_KC_API_BASE_URL + '/ml/text-to-cad/iteration'
|
||||||
const data: Models['TextToCadIteration_type'] | Error =
|
const data: Models['TextToCadIteration_type'] | Error =
|
||||||
await crossPlatformFetch(
|
await crossPlatformFetch(
|
||||||
|
@ -23,6 +23,30 @@ export const telemetryLoader: LoaderFunction = async ({
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redirect users to the appropriate onboarding page if they haven't completed it
|
||||||
|
export const onboardingRedirectLoader: ActionFunction = async (args) => {
|
||||||
|
const settings = getSettings()
|
||||||
|
const onboardingStatus: OnboardingStatus =
|
||||||
|
settings.app.onboardingStatus.current || ''
|
||||||
|
const notEnRouteToOnboarding = !args.request.url.includes(
|
||||||
|
PATHS.ONBOARDING.INDEX
|
||||||
|
)
|
||||||
|
// '' is the initial state, 'completed' and 'dismissed' are the final states
|
||||||
|
const hasValidOnboardingStatus =
|
||||||
|
onboardingStatus.length === 0 ||
|
||||||
|
!(onboardingStatus === 'completed' || onboardingStatus === 'dismissed')
|
||||||
|
const shouldRedirectToOnboarding =
|
||||||
|
notEnRouteToOnboarding && hasValidOnboardingStatus
|
||||||
|
|
||||||
|
if (shouldRedirectToOnboarding) {
|
||||||
|
return redirect(
|
||||||
|
makeUrlPathRelative(PATHS.ONBOARDING.INDEX) + onboardingStatus.slice(1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
export const fileLoader: LoaderFunction = async (
|
export const fileLoader: LoaderFunction = async (
|
||||||
routerData
|
routerData
|
||||||
): Promise<FileLoaderData | Response> => {
|
): Promise<FileLoaderData | Response> => {
|
||||||
|
@ -481,9 +481,7 @@ export function getSelectionTypeDisplayText(
|
|||||||
|
|
||||||
export function canSubmitSelectionArg(
|
export function canSubmitSelectionArg(
|
||||||
selectionsByType: 'none' | Map<ResolvedSelectionType, number>,
|
selectionsByType: 'none' | Map<ResolvedSelectionType, number>,
|
||||||
argument: CommandArgument<unknown> & {
|
argument: CommandArgument<unknown> & { inputType: 'selection' }
|
||||||
inputType: 'selection' | 'selectionMixed'
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
selectionsByType !== 'none' &&
|
selectionsByType !== 'none' &&
|
||||||
|
@ -295,8 +295,7 @@ export const commandBarMachine = setup({
|
|||||||
if (
|
if (
|
||||||
context.currentArgument &&
|
context.currentArgument &&
|
||||||
context.selectedCommand &&
|
context.selectedCommand &&
|
||||||
(argConfig?.inputType === 'selection' ||
|
argConfig?.inputType === 'selection' &&
|
||||||
argConfig?.inputType === 'selectionMixed') &&
|
|
||||||
argConfig?.validation
|
argConfig?.validation
|
||||||
) {
|
) {
|
||||||
argConfig
|
argConfig
|
||||||
|
@ -1995,6 +1995,12 @@ export const modelingMachine = setup({
|
|||||||
// Extract inputs
|
// Extract inputs
|
||||||
const ast = kclManager.ast
|
const ast = kclManager.ast
|
||||||
const { selection, thickness } = input
|
const { selection, thickness } = input
|
||||||
|
const dependencies = {
|
||||||
|
kclManager,
|
||||||
|
engineCommandManager,
|
||||||
|
editorManager,
|
||||||
|
codeManager,
|
||||||
|
}
|
||||||
|
|
||||||
// Insert the thickness variable if it exists
|
// Insert the thickness variable if it exists
|
||||||
if (
|
if (
|
||||||
@ -2020,6 +2026,7 @@ export const modelingMachine = setup({
|
|||||||
'variableName' in thickness
|
'variableName' in thickness
|
||||||
? thickness.variableIdentifierAst
|
? thickness.variableIdentifierAst
|
||||||
: thickness.valueAst,
|
: thickness.valueAst,
|
||||||
|
dependencies,
|
||||||
})
|
})
|
||||||
if (err(shellResult)) {
|
if (err(shellResult)) {
|
||||||
return err(shellResult)
|
return err(shellResult)
|
||||||
|
6
src/wasm-lib/Cargo.lock
generated
@ -730,7 +730,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive-docs"
|
name = "derive-docs"
|
||||||
version = "0.1.39"
|
version = "0.1.38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -1724,7 +1724,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.2.39"
|
version = "0.2.38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx 0.5.1",
|
"approx 0.5.1",
|
||||||
@ -1791,7 +1791,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
version = "0.1.39"
|
version = "0.1.38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hyper 0.14.32",
|
"hyper 0.14.32",
|
||||||
|
@ -103,7 +103,3 @@ path = "tests/modify/main.rs"
|
|||||||
#[patch.crates-io]
|
#[patch.crates-io]
|
||||||
#kittycad-modeling-cmds = { path = "../../../modeling-api/modeling-cmds" }
|
#kittycad-modeling-cmds = { path = "../../../modeling-api/modeling-cmds" }
|
||||||
#kittycad-modeling-session = { path = "../../../modeling-api/modeling-session" }
|
#kittycad-modeling-session = { path = "../../../modeling-api/modeling-session" }
|
||||||
|
|
||||||
# Local development only. Placeholder to speed up development cycle
|
|
||||||
#[package.metadata.wasm-pack.profile.release]
|
|
||||||
#wasm-opt = false
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "derive-docs"
|
name = "derive-docs"
|
||||||
description = "A tool for generating documentation from Rust derive macros"
|
description = "A tool for generating documentation from Rust derive macros"
|
||||||
version = "0.1.39"
|
version = "0.1.38"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
description = "A test server for KCL"
|
description = "A test server for KCL"
|
||||||
version = "0.1.39"
|
version = "0.1.38"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language implementation and tools"
|
description = "KittyCAD Language implementation and tools"
|
||||||
version = "0.2.39"
|
version = "0.2.38"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -2,12 +2,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
execution::{ArtifactCommand, ArtifactGraph, Operation},
|
execution::{ArtifactCommand, ArtifactGraph, Operation},
|
||||||
lsp::IntoDiagnostic,
|
lsp::IntoDiagnostic,
|
||||||
modules::ModulePath,
|
|
||||||
source_range::SourceRange,
|
source_range::SourceRange,
|
||||||
ModuleId,
|
ModuleId,
|
||||||
};
|
};
|
||||||
@ -119,7 +116,6 @@ pub struct KclErrorWithOutputs {
|
|||||||
pub operations: Vec<Operation>,
|
pub operations: Vec<Operation>,
|
||||||
pub artifact_commands: Vec<ArtifactCommand>,
|
pub artifact_commands: Vec<ArtifactCommand>,
|
||||||
pub artifact_graph: ArtifactGraph,
|
pub artifact_graph: ArtifactGraph,
|
||||||
pub filenames: IndexMap<ModuleId, ModulePath>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KclErrorWithOutputs {
|
impl KclErrorWithOutputs {
|
||||||
@ -128,14 +124,12 @@ impl KclErrorWithOutputs {
|
|||||||
operations: Vec<Operation>,
|
operations: Vec<Operation>,
|
||||||
artifact_commands: Vec<ArtifactCommand>,
|
artifact_commands: Vec<ArtifactCommand>,
|
||||||
artifact_graph: ArtifactGraph,
|
artifact_graph: ArtifactGraph,
|
||||||
filenames: IndexMap<ModuleId, ModulePath>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
error,
|
error,
|
||||||
operations,
|
operations,
|
||||||
artifact_commands,
|
artifact_commands,
|
||||||
artifact_graph,
|
artifact_graph,
|
||||||
filenames,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn no_outputs(error: KclError) -> Self {
|
pub fn no_outputs(error: KclError) -> Self {
|
||||||
@ -144,7 +138,6 @@ impl KclErrorWithOutputs {
|
|||||||
operations: Default::default(),
|
operations: Default::default(),
|
||||||
artifact_commands: Default::default(),
|
artifact_commands: Default::default(),
|
||||||
artifact_graph: Default::default(),
|
artifact_graph: Default::default(),
|
||||||
filenames: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,6 @@ pub struct Sweep {
|
|||||||
pub enum SweepSubType {
|
pub enum SweepSubType {
|
||||||
Extrusion,
|
Extrusion,
|
||||||
Revolve,
|
Revolve,
|
||||||
RevolveAboutEdge,
|
|
||||||
Loft,
|
Loft,
|
||||||
Sweep,
|
Sweep,
|
||||||
}
|
}
|
||||||
@ -752,12 +751,10 @@ fn artifacts_to_update(
|
|||||||
}
|
}
|
||||||
ModelingCmd::Extrude(kcmc::Extrude { target, .. })
|
ModelingCmd::Extrude(kcmc::Extrude { target, .. })
|
||||||
| ModelingCmd::Revolve(kcmc::Revolve { target, .. })
|
| ModelingCmd::Revolve(kcmc::Revolve { target, .. })
|
||||||
| ModelingCmd::RevolveAboutEdge(kcmc::RevolveAboutEdge { target, .. })
|
|
||||||
| ModelingCmd::Sweep(kcmc::Sweep { target, .. }) => {
|
| ModelingCmd::Sweep(kcmc::Sweep { target, .. }) => {
|
||||||
let sub_type = match cmd {
|
let sub_type = match cmd {
|
||||||
ModelingCmd::Extrude(_) => SweepSubType::Extrusion,
|
ModelingCmd::Extrude(_) => SweepSubType::Extrusion,
|
||||||
ModelingCmd::Revolve(_) => SweepSubType::Revolve,
|
ModelingCmd::Revolve(_) => SweepSubType::Revolve,
|
||||||
ModelingCmd::RevolveAboutEdge(_) => SweepSubType::RevolveAboutEdge,
|
|
||||||
ModelingCmd::Sweep(_) => SweepSubType::Sweep,
|
ModelingCmd::Sweep(_) => SweepSubType::Sweep,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -888,7 +885,7 @@ fn artifacts_to_update(
|
|||||||
let path_sweep_id = path.sweep_id.ok_or_else(|| {
|
let path_sweep_id = path.sweep_id.ok_or_else(|| {
|
||||||
KclError::Internal(KclErrorDetails {
|
KclError::Internal(KclErrorDetails {
|
||||||
message:format!(
|
message:format!(
|
||||||
"Expected a sweep ID on the path when processing last path's Solid3dGetExtrusionFaceInfo command, but we have none: {id:?}, {path:?}"
|
"Expected a sweep ID on the path when processing Solid3dGetExtrusionFaceInfo command, but we have none: {id:?}, {path:?}"
|
||||||
),
|
),
|
||||||
source_ranges: vec![range],
|
source_ranges: vec![range],
|
||||||
})
|
})
|
||||||
|
@ -329,8 +329,6 @@ impl ExecutorContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let id = exec_state.next_module_id();
|
let id = exec_state.next_module_id();
|
||||||
// Add file path string to global state even if it fails to import
|
|
||||||
exec_state.add_path_to_source_id(resolved_path.clone(), id);
|
|
||||||
let source = resolved_path.source(&self.fs, source_range).await?;
|
let source = resolved_path.source(&self.fs, source_range).await?;
|
||||||
// TODO handle parsing errors properly
|
// TODO handle parsing errors properly
|
||||||
let parsed = crate::parsing::parse_str(&source, id).parse_errs_as_err()?;
|
let parsed = crate::parsing::parse_str(&source, id).parse_errs_as_err()?;
|
||||||
@ -345,8 +343,6 @@ impl ExecutorContext {
|
|||||||
|
|
||||||
let id = exec_state.next_module_id();
|
let id = exec_state.next_module_id();
|
||||||
let path = resolved_path.expect_path();
|
let path = resolved_path.expect_path();
|
||||||
// Add file path string to global state even if it fails to import
|
|
||||||
exec_state.add_path_to_source_id(resolved_path.clone(), id);
|
|
||||||
let format = super::import::format_from_annotations(attrs, path, source_range)?;
|
let format = super::import::format_from_annotations(attrs, path, source_range)?;
|
||||||
let geom = super::import::import_foreign(path, format, exec_state, self, source_range).await?;
|
let geom = super::import::import_foreign(path, format, exec_state, self, source_range).await?;
|
||||||
exec_state.add_module(id, resolved_path, ModuleRepr::Foreign(geom));
|
exec_state.add_module(id, resolved_path, ModuleRepr::Foreign(geom));
|
||||||
@ -358,8 +354,6 @@ impl ExecutorContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let id = exec_state.next_module_id();
|
let id = exec_state.next_module_id();
|
||||||
// Add file path string to global state even if it fails to import
|
|
||||||
exec_state.add_path_to_source_id(resolved_path.clone(), id);
|
|
||||||
let source = resolved_path.source(&self.fs, source_range).await?;
|
let source = resolved_path.source(&self.fs, source_range).await?;
|
||||||
let parsed = crate::parsing::parse_str(&source, id).parse_errs_as_err().unwrap();
|
let parsed = crate::parsing::parse_str(&source, id).parse_errs_as_err().unwrap();
|
||||||
exec_state.add_module(id, resolved_path, ModuleRepr::Kcl(parsed, None));
|
exec_state.add_module(id, resolved_path, ModuleRepr::Kcl(parsed, None));
|
||||||
|
@ -23,7 +23,6 @@ use crate::{
|
|||||||
cache::{CacheInformation, CacheResult},
|
cache::{CacheInformation, CacheResult},
|
||||||
},
|
},
|
||||||
fs::FileManager,
|
fs::FileManager,
|
||||||
modules::{ModuleId, ModulePath},
|
|
||||||
parsing::ast::types::{Expr, ImportPath, Node, NodeRef, Program},
|
parsing::ast::types::{Expr, ImportPath, Node, NodeRef, Program},
|
||||||
settings::types::UnitLength,
|
settings::types::UnitLength,
|
||||||
source_range::SourceRange,
|
source_range::SourceRange,
|
||||||
@ -71,8 +70,6 @@ pub struct ExecOutcome {
|
|||||||
pub artifact_graph: ArtifactGraph,
|
pub artifact_graph: ArtifactGraph,
|
||||||
/// Non-fatal errors and warnings.
|
/// Non-fatal errors and warnings.
|
||||||
pub errors: Vec<CompilationError>,
|
pub errors: Vec<CompilationError>,
|
||||||
/// File Names in module Id array index order
|
|
||||||
pub filenames: IndexMap<ModuleId, ModulePath>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
@ -715,19 +712,11 @@ impl ExecutorContext {
|
|||||||
.execute_and_build_graph(program, exec_state, preserve_mem)
|
.execute_and_build_graph(program, exec_state, preserve_mem)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let module_id_to_module_path: IndexMap<ModuleId, ModulePath> = exec_state
|
|
||||||
.global
|
|
||||||
.path_to_source_id
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| ((*v), k.clone()))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
KclErrorWithOutputs::new(
|
KclErrorWithOutputs::new(
|
||||||
e,
|
e,
|
||||||
exec_state.mod_local.operations.clone(),
|
exec_state.mod_local.operations.clone(),
|
||||||
exec_state.global.artifact_commands.clone(),
|
exec_state.global.artifact_commands.clone(),
|
||||||
exec_state.global.artifact_graph.clone(),
|
exec_state.global.artifact_graph.clone(),
|
||||||
module_id_to_module_path,
|
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -124,12 +124,6 @@ impl ExecState {
|
|||||||
artifact_commands: self.global.artifact_commands,
|
artifact_commands: self.global.artifact_commands,
|
||||||
artifact_graph: self.global.artifact_graph,
|
artifact_graph: self.global.artifact_graph,
|
||||||
errors: self.global.errors,
|
errors: self.global.errors,
|
||||||
filenames: self
|
|
||||||
.global
|
|
||||||
.path_to_source_id
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| ((*v), k.clone()))
|
|
||||||
.collect(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +141,6 @@ impl ExecState {
|
|||||||
artifact_commands: Default::default(),
|
artifact_commands: Default::default(),
|
||||||
artifact_graph: Default::default(),
|
artifact_graph: Default::default(),
|
||||||
errors: self.global.errors,
|
errors: self.global.errors,
|
||||||
filenames: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,13 +169,11 @@ impl ExecState {
|
|||||||
self.global.path_to_source_id.get(path).cloned()
|
self.global.path_to_source_id.get(path).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn add_path_to_source_id(&mut self, path: ModulePath, id: ModuleId) {
|
|
||||||
debug_assert!(!self.global.path_to_source_id.contains_key(&path));
|
|
||||||
self.global.path_to_source_id.insert(path.clone(), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn add_module(&mut self, id: ModuleId, path: ModulePath, repr: ModuleRepr) {
|
pub(super) fn add_module(&mut self, id: ModuleId, path: ModulePath, repr: ModuleRepr) {
|
||||||
debug_assert!(self.global.path_to_source_id.contains_key(&path));
|
debug_assert!(!self.global.path_to_source_id.contains_key(&path));
|
||||||
|
|
||||||
|
self.global.path_to_source_id.insert(path.clone(), id);
|
||||||
|
|
||||||
let module_info = ModuleInfo { id, repr, path };
|
let module_info = ModuleInfo { id, repr, path };
|
||||||
self.global.module_infos.insert(id, module_info);
|
self.global.module_infos.insert(id, module_info);
|
||||||
}
|
}
|
||||||
@ -234,15 +225,11 @@ impl GlobalState {
|
|||||||
root_id,
|
root_id,
|
||||||
ModuleInfo {
|
ModuleInfo {
|
||||||
id: root_id,
|
id: root_id,
|
||||||
path: ModulePath::Local {
|
path: ModulePath::Local(root_path.clone()),
|
||||||
value: root_path.clone(),
|
|
||||||
},
|
|
||||||
repr: ModuleRepr::Root,
|
repr: ModuleRepr::Root,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
global
|
global.path_to_source_id.insert(ModulePath::Local(root_path), root_id);
|
||||||
.path_to_source_id
|
|
||||||
.insert(ModulePath::Local { value: root_path }, root_id);
|
|
||||||
global
|
global
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,13 @@ impl ModuleLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enter_module(&mut self, path: &ModulePath) {
|
pub(crate) fn enter_module(&mut self, path: &ModulePath) {
|
||||||
if let ModulePath::Local { value: ref path } = path {
|
if let ModulePath::Local(ref path) = path {
|
||||||
self.import_stack.push(path.clone());
|
self.import_stack.push(path.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn leave_module(&mut self, path: &ModulePath) {
|
pub(crate) fn leave_module(&mut self, path: &ModulePath) {
|
||||||
if let ModulePath::Local { value: ref path } = path {
|
if let ModulePath::Local(ref path) = path {
|
||||||
let popped = self.import_stack.pop().unwrap();
|
let popped = self.import_stack.pop().unwrap();
|
||||||
assert_eq!(path, &popped);
|
assert_eq!(path, &popped);
|
||||||
}
|
}
|
||||||
@ -119,32 +119,31 @@ pub enum ModuleRepr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash, ts_rs::TS)]
|
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash)]
|
||||||
#[serde(tag = "type")]
|
|
||||||
pub enum ModulePath {
|
pub enum ModulePath {
|
||||||
Local { value: PathBuf },
|
Local(PathBuf),
|
||||||
Std { value: String },
|
Std(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModulePath {
|
impl ModulePath {
|
||||||
pub(crate) fn expect_path(&self) -> &PathBuf {
|
pub(crate) fn expect_path(&self) -> &PathBuf {
|
||||||
match self {
|
match self {
|
||||||
ModulePath::Local { value: p } => p,
|
ModulePath::Local(p) => p,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn std_path(&self) -> Option<String> {
|
pub(crate) fn std_path(&self) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
ModulePath::Local { value: _ } => None,
|
ModulePath::Local(_) => None,
|
||||||
ModulePath::Std { value: p } => Some(p.clone()),
|
ModulePath::Std(p) => Some(p.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn source(&self, fs: &FileManager, source_range: SourceRange) -> Result<String, KclError> {
|
pub(crate) async fn source(&self, fs: &FileManager, source_range: SourceRange) -> Result<String, KclError> {
|
||||||
match self {
|
match self {
|
||||||
ModulePath::Local { value: p } => fs.read_to_string(p, source_range).await,
|
ModulePath::Local(p) => fs.read_to_string(p, source_range).await,
|
||||||
ModulePath::Std { value: name } => read_std(name)
|
ModulePath::Std(name) => read_std(name)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
KclError::Semantic(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("Cannot find standard library module to import: std::{name}."),
|
message: format!("Cannot find standard library module to import: std::{name}."),
|
||||||
@ -163,14 +162,14 @@ impl ModulePath {
|
|||||||
} else {
|
} else {
|
||||||
std::path::PathBuf::from(path)
|
std::path::PathBuf::from(path)
|
||||||
};
|
};
|
||||||
ModulePath::Local { value: resolved_path }
|
ModulePath::Local(resolved_path)
|
||||||
}
|
}
|
||||||
ImportPath::Std { path } => {
|
ImportPath::Std { path } => {
|
||||||
// For now we only support importing from singly-nested modules inside std.
|
// For now we only support importing from singly-nested modules inside std.
|
||||||
assert_eq!(path.len(), 2);
|
assert_eq!(path.len(), 2);
|
||||||
assert_eq!(&path[0], "std");
|
assert_eq!(&path[0], "std");
|
||||||
|
|
||||||
ModulePath::Std { value: path[1].clone() }
|
ModulePath::Std(path[1].clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,8 +178,8 @@ impl ModulePath {
|
|||||||
impl fmt::Display for ModulePath {
|
impl fmt::Display for ModulePath {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ModulePath::Local { value: path } => path.display().fmt(f),
|
ModulePath::Local(path) => path.display().fmt(f),
|
||||||
ModulePath::Std { value: s } => write!(f, "std::{s}"),
|
ModulePath::Std(s) => write!(f, "std::{s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1018,27 +1018,6 @@ mod sketch_on_face {
|
|||||||
super::execute(TEST_NAME, true).await
|
super::execute(TEST_NAME, true).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod revolve_about_edge {
|
|
||||||
const TEST_NAME: &str = "revolve_about_edge";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[test]
|
|
||||||
fn unparse() {
|
|
||||||
super::unparse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, true).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mod poop_chute {
|
mod poop_chute {
|
||||||
const TEST_NAME: &str = "poop_chute";
|
const TEST_NAME: &str = "poop_chute";
|
||||||
|
|
||||||
@ -2011,29 +1990,7 @@ mod helix_simple {
|
|||||||
/// Test parsing KCL.
|
/// Test parsing KCL.
|
||||||
#[test]
|
#[test]
|
||||||
fn parse() {
|
fn parse() {
|
||||||
super::parse(TEST_NAME);
|
super::parse(TEST_NAME)
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[test]
|
|
||||||
fn unparse() {
|
|
||||||
super::unparse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, true).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod import_file_parse_error {
|
|
||||||
const TEST_NAME: &str = "import_file_parse_error";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||||
|
@ -1,284 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Artifact commands import_file_parse_error.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "plane_set_color",
|
|
||||||
"plane_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.7,
|
|
||||||
"g": 0.28,
|
|
||||||
"b": 0.28,
|
|
||||||
"a": 0.4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "plane_set_color",
|
|
||||||
"plane_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.28,
|
|
||||||
"g": 0.7,
|
|
||||||
"b": 0.28,
|
|
||||||
"a": 0.4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
},
|
|
||||||
"size": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "plane_set_color",
|
|
||||||
"plane_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.28,
|
|
||||||
"g": 0.28,
|
|
||||||
"b": 0.7,
|
|
||||||
"a": 0.4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
},
|
|
||||||
"size": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "edge_lines_visible",
|
|
||||||
"hidden": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart import_file_parse_error.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
@ -1,3 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
```
|
|
@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Result of parsing import_file_parse_error.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"Ok": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"end": 38,
|
|
||||||
"path": {
|
|
||||||
"type": "Kcl",
|
|
||||||
"filename": "parse-failure.kcl"
|
|
||||||
},
|
|
||||||
"selector": {
|
|
||||||
"type": "List",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"alias": null,
|
|
||||||
"end": 13,
|
|
||||||
"name": {
|
|
||||||
"end": 13,
|
|
||||||
"name": "hotdog",
|
|
||||||
"start": 7,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"start": 7,
|
|
||||||
"type": "ImportItem"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ImportStatement",
|
|
||||||
"type": "ImportStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 39,
|
|
||||||
"start": 0
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Error from executing import_file_parse_error.kcl
|
|
||||||
---
|
|
||||||
KCL Syntax error
|
|
||||||
|
|
||||||
× syntax: Unexpected token: }
|
|
||||||
╭────
|
|
||||||
1 │ import hotdog from "parse-failure.kcl"
|
|
||||||
· ─
|
|
||||||
╰────
|
|
@ -1 +0,0 @@
|
|||||||
import hotdog from "parse-failure.kcl"
|
|
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Operations executed import_file_parse_error.kcl
|
|
||||||
---
|
|
||||||
[]
|
|
@ -1,3 +0,0 @@
|
|||||||
export fn hotdog () {
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,571 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Artifact commands revolve_about_edge.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "plane_set_color",
|
|
||||||
"plane_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.7,
|
|
||||||
"g": 0.28,
|
|
||||||
"b": 0.28,
|
|
||||||
"a": 0.4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "plane_set_color",
|
|
||||||
"plane_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.28,
|
|
||||||
"g": 0.7,
|
|
||||||
"b": 0.28,
|
|
||||||
"a": 0.4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
},
|
|
||||||
"size": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "plane_set_color",
|
|
||||||
"plane_id": "[uuid]",
|
|
||||||
"color": {
|
|
||||||
"r": 0.28,
|
|
||||||
"g": 0.28,
|
|
||||||
"b": 0.7,
|
|
||||||
"a": 0.4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
},
|
|
||||||
"size": 100.0,
|
|
||||||
"clobber": false,
|
|
||||||
"hide": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "edge_lines_visible",
|
|
||||||
"hidden": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "set_scene_units",
|
|
||||||
"unit": "mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
12,
|
|
||||||
31,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": [
|
|
||||||
37,
|
|
||||||
65,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": [
|
|
||||||
37,
|
|
||||||
65,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "start_path"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
37,
|
|
||||||
65,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "move_path_pen",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"to": {
|
|
||||||
"x": -25.0,
|
|
||||||
"y": 25.0,
|
|
||||||
"z": 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
71,
|
|
||||||
107,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "extend_path",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"segment": {
|
|
||||||
"type": "line",
|
|
||||||
"end": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": -50.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"relative": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
120,
|
|
||||||
139,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"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": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "start_path"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "move_path_pen",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"to": {
|
|
||||||
"x": -40.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "extend_path",
|
|
||||||
"path": "[uuid]",
|
|
||||||
"segment": {
|
|
||||||
"type": "arc",
|
|
||||||
"center": {
|
|
||||||
"x": -50.0,
|
|
||||||
"y": 0.0
|
|
||||||
},
|
|
||||||
"radius": 10.0,
|
|
||||||
"start": {
|
|
||||||
"unit": "degrees",
|
|
||||||
"value": 0.0
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"unit": "degrees",
|
|
||||||
"value": 360.0
|
|
||||||
},
|
|
||||||
"relative": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "close_path",
|
|
||||||
"path_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
196,
|
|
||||||
270,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "revolve_about_edge",
|
|
||||||
"target": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"angle": {
|
|
||||||
"unit": "degrees",
|
|
||||||
"value": 90.0
|
|
||||||
},
|
|
||||||
"tolerance": 0.0000001
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
196,
|
|
||||||
270,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "object_bring_to_front",
|
|
||||||
"object_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
196,
|
|
||||||
270,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_extrusion_face_info",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
196,
|
|
||||||
270,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_opposite_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [
|
|
||||||
196,
|
|
||||||
270,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"command": {
|
|
||||||
"type": "solid3d_get_next_adjacent_edge",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"edge_id": "[uuid]",
|
|
||||||
"face_id": "[uuid]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart revolve_about_edge.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
@ -1,34 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
subgraph path2 [Path]
|
|
||||||
2["Path<br>[37, 65, 0]"]
|
|
||||||
3["Segment<br>[71, 107, 0]"]
|
|
||||||
end
|
|
||||||
subgraph path5 [Path]
|
|
||||||
5["Path<br>[145, 190, 0]"]
|
|
||||||
6["Segment<br>[145, 190, 0]"]
|
|
||||||
7[Solid2d]
|
|
||||||
end
|
|
||||||
1["Plane<br>[12, 31, 0]"]
|
|
||||||
4["Plane<br>[120, 139, 0]"]
|
|
||||||
8["Sweep RevolveAboutEdge<br>[196, 270, 0]"]
|
|
||||||
9[Wall]
|
|
||||||
10["Cap Start"]
|
|
||||||
11["Cap End"]
|
|
||||||
12["SweepEdge Opposite"]
|
|
||||||
13["SweepEdge Adjacent"]
|
|
||||||
1 --- 2
|
|
||||||
2 --- 3
|
|
||||||
4 --- 5
|
|
||||||
5 --- 6
|
|
||||||
5 ---- 8
|
|
||||||
5 --- 7
|
|
||||||
6 --- 9
|
|
||||||
6 --- 12
|
|
||||||
6 --- 13
|
|
||||||
8 --- 9
|
|
||||||
8 --- 10
|
|
||||||
8 --- 11
|
|
||||||
8 --- 12
|
|
||||||
8 --- 13
|
|
||||||
```
|
|
@ -1,376 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Result of parsing revolve_about_edge.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"Ok": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"declaration": {
|
|
||||||
"end": 107,
|
|
||||||
"id": {
|
|
||||||
"end": 9,
|
|
||||||
"name": "sketch001",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"end": 30,
|
|
||||||
"raw": "'XY'",
|
|
||||||
"start": 26,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": "XY"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"end": 25,
|
|
||||||
"name": "startSketchOn",
|
|
||||||
"start": 12,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"end": 31,
|
|
||||||
"start": 12,
|
|
||||||
"type": "CallExpression",
|
|
||||||
"type": "CallExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"end": 56,
|
|
||||||
"raw": "25",
|
|
||||||
"start": 54,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 25.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"end": 56,
|
|
||||||
"operator": "-",
|
|
||||||
"start": 53,
|
|
||||||
"type": "UnaryExpression",
|
|
||||||
"type": "UnaryExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 60,
|
|
||||||
"raw": "25",
|
|
||||||
"start": 58,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 25.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 61,
|
|
||||||
"start": 52,
|
|
||||||
"type": "ArrayExpression",
|
|
||||||
"type": "ArrayExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 64,
|
|
||||||
"start": 63,
|
|
||||||
"type": "PipeSubstitution",
|
|
||||||
"type": "PipeSubstitution"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"end": 51,
|
|
||||||
"name": "startProfileAt",
|
|
||||||
"start": 37,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"end": 65,
|
|
||||||
"start": 37,
|
|
||||||
"type": "CallExpression",
|
|
||||||
"type": "CallExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"end": 80,
|
|
||||||
"raw": "50",
|
|
||||||
"start": 78,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 50.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"end": 80,
|
|
||||||
"operator": "-",
|
|
||||||
"start": 77,
|
|
||||||
"type": "UnaryExpression",
|
|
||||||
"type": "UnaryExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 83,
|
|
||||||
"start": 82,
|
|
||||||
"type": "PipeSubstitution",
|
|
||||||
"type": "PipeSubstitution"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 106,
|
|
||||||
"start": 85,
|
|
||||||
"type": "TagDeclarator",
|
|
||||||
"type": "TagDeclarator",
|
|
||||||
"value": "rectangleSegmentB001"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"end": 76,
|
|
||||||
"name": "yLine",
|
|
||||||
"start": 71,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"end": 107,
|
|
||||||
"start": 71,
|
|
||||||
"type": "CallExpression",
|
|
||||||
"type": "CallExpression"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 107,
|
|
||||||
"start": 12,
|
|
||||||
"type": "PipeExpression",
|
|
||||||
"type": "PipeExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 107,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"declaration": {
|
|
||||||
"end": 270,
|
|
||||||
"id": {
|
|
||||||
"end": 117,
|
|
||||||
"name": "sketch002",
|
|
||||||
"start": 108,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"end": 138,
|
|
||||||
"raw": "'XY'",
|
|
||||||
"start": 134,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": "XY"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"end": 133,
|
|
||||||
"name": "startSketchOn",
|
|
||||||
"start": 120,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"end": 139,
|
|
||||||
"start": 120,
|
|
||||||
"type": "CallExpression",
|
|
||||||
"type": "CallExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"end": 186,
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"end": 171,
|
|
||||||
"key": {
|
|
||||||
"end": 160,
|
|
||||||
"name": "center",
|
|
||||||
"start": 154,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"start": 154,
|
|
||||||
"type": "ObjectProperty",
|
|
||||||
"value": {
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"end": 167,
|
|
||||||
"raw": "50",
|
|
||||||
"start": 165,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 50.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"end": 167,
|
|
||||||
"operator": "-",
|
|
||||||
"start": 164,
|
|
||||||
"type": "UnaryExpression",
|
|
||||||
"type": "UnaryExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 170,
|
|
||||||
"raw": "0",
|
|
||||||
"start": 169,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 0.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 171,
|
|
||||||
"start": 163,
|
|
||||||
"type": "ArrayExpression",
|
|
||||||
"type": "ArrayExpression"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 184,
|
|
||||||
"key": {
|
|
||||||
"end": 179,
|
|
||||||
"name": "radius",
|
|
||||||
"start": 173,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"start": 173,
|
|
||||||
"type": "ObjectProperty",
|
|
||||||
"value": {
|
|
||||||
"end": 184,
|
|
||||||
"raw": "10",
|
|
||||||
"start": 182,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 10.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 152,
|
|
||||||
"type": "ObjectExpression",
|
|
||||||
"type": "ObjectExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 189,
|
|
||||||
"start": 188,
|
|
||||||
"type": "PipeSubstitution",
|
|
||||||
"type": "PipeSubstitution"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"end": 151,
|
|
||||||
"name": "circle",
|
|
||||||
"start": 145,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"end": 190,
|
|
||||||
"start": 145,
|
|
||||||
"type": "CallExpression",
|
|
||||||
"type": "CallExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"end": 266,
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"end": 223,
|
|
||||||
"key": {
|
|
||||||
"end": 218,
|
|
||||||
"name": "angle",
|
|
||||||
"start": 213,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"start": 213,
|
|
||||||
"type": "ObjectProperty",
|
|
||||||
"value": {
|
|
||||||
"end": 223,
|
|
||||||
"raw": "90",
|
|
||||||
"start": 221,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 90.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 259,
|
|
||||||
"key": {
|
|
||||||
"end": 236,
|
|
||||||
"name": "axis",
|
|
||||||
"start": 232,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"start": 232,
|
|
||||||
"type": "ObjectProperty",
|
|
||||||
"value": {
|
|
||||||
"end": 259,
|
|
||||||
"name": "rectangleSegmentB001",
|
|
||||||
"start": 239,
|
|
||||||
"type": "Identifier",
|
|
||||||
"type": "Identifier"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 204,
|
|
||||||
"type": "ObjectExpression",
|
|
||||||
"type": "ObjectExpression"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"end": 269,
|
|
||||||
"start": 268,
|
|
||||||
"type": "PipeSubstitution",
|
|
||||||
"type": "PipeSubstitution"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"end": 203,
|
|
||||||
"name": "revolve",
|
|
||||||
"start": 196,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"end": 270,
|
|
||||||
"start": 196,
|
|
||||||
"type": "CallExpression",
|
|
||||||
"type": "CallExpression"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 270,
|
|
||||||
"start": 120,
|
|
||||||
"type": "PipeExpression",
|
|
||||||
"type": "PipeExpression"
|
|
||||||
},
|
|
||||||
"start": 108,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 270,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 108,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 271,
|
|
||||||
"start": 0
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
sketch001 = startSketchOn('XY')
|
|
||||||
|> startProfileAt([-25, 25], %)
|
|
||||||
|> yLine(-50, %, $rectangleSegmentB001)
|
|
||||||
sketch002 = startSketchOn('XY')
|
|
||||||
|> circle({ center = [-50, 0], radius = 10 }, %)
|
|
||||||
|> revolve({
|
|
||||||
angle = 90,
|
|
||||||
axis = rectangleSegmentB001
|
|
||||||
}, %)
|
|
@ -1,107 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Operations executed revolve_about_edge.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"data": {
|
|
||||||
"value": {
|
|
||||||
"type": "String",
|
|
||||||
"value": "XY"
|
|
||||||
},
|
|
||||||
"sourceRange": [
|
|
||||||
26,
|
|
||||||
30,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "startSketchOn",
|
|
||||||
"sourceRange": [
|
|
||||||
12,
|
|
||||||
31,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"data": {
|
|
||||||
"value": {
|
|
||||||
"type": "String",
|
|
||||||
"value": "XY"
|
|
||||||
},
|
|
||||||
"sourceRange": [
|
|
||||||
134,
|
|
||||||
138,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "startSketchOn",
|
|
||||||
"sourceRange": [
|
|
||||||
120,
|
|
||||||
139,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"labeledArgs": {
|
|
||||||
"data": {
|
|
||||||
"value": {
|
|
||||||
"type": "Object",
|
|
||||||
"value": {
|
|
||||||
"angle": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 90.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"axis": {
|
|
||||||
"type": "TagIdentifier",
|
|
||||||
"value": "rectangleSegmentB001",
|
|
||||||
"artifact_id": "[uuid]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": [
|
|
||||||
204,
|
|
||||||
266,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"sketch": {
|
|
||||||
"value": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"value": {
|
|
||||||
"artifactId": "[uuid]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": [
|
|
||||||
268,
|
|
||||||
269,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name": "revolve",
|
|
||||||
"sourceRange": [
|
|
||||||
196,
|
|
||||||
270,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"type": "StdLibCall",
|
|
||||||
"unlabeledArg": null
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,343 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl/src/simulation_tests.rs
|
|
||||||
description: Variables in memory after executing revolve_about_edge.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"rectangleSegmentB001": {
|
|
||||||
"type": "TagIdentifier",
|
|
||||||
"type": "TagIdentifier",
|
|
||||||
"value": "rectangleSegmentB001",
|
|
||||||
"info": {
|
|
||||||
"type": "TagEngineInfo",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sketch": "[uuid]",
|
|
||||||
"path": {
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
71,
|
|
||||||
107,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-25.0,
|
|
||||||
25.0
|
|
||||||
],
|
|
||||||
"tag": {
|
|
||||||
"end": 106,
|
|
||||||
"start": 85,
|
|
||||||
"type": "TagDeclarator",
|
|
||||||
"value": "rectangleSegmentB001"
|
|
||||||
},
|
|
||||||
"to": [
|
|
||||||
-25.0,
|
|
||||||
-25.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"surface": null
|
|
||||||
},
|
|
||||||
"__meta": [
|
|
||||||
{
|
|
||||||
"sourceRange": [
|
|
||||||
85,
|
|
||||||
106,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"sketch001": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"value": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
71,
|
|
||||||
107,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-25.0,
|
|
||||||
25.0
|
|
||||||
],
|
|
||||||
"tag": {
|
|
||||||
"end": 106,
|
|
||||||
"start": 85,
|
|
||||||
"type": "TagDeclarator",
|
|
||||||
"value": "rectangleSegmentB001"
|
|
||||||
},
|
|
||||||
"to": [
|
|
||||||
-25.0,
|
|
||||||
-25.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "plane",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "XY",
|
|
||||||
"origin": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"__meta": []
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
-25.0,
|
|
||||||
25.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
-25.0,
|
|
||||||
25.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
37,
|
|
||||||
65,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": {
|
|
||||||
"rectangleSegmentB001": {
|
|
||||||
"type": "TagIdentifier",
|
|
||||||
"value": "rectangleSegmentB001",
|
|
||||||
"info": {
|
|
||||||
"type": "TagEngineInfo",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sketch": "[uuid]",
|
|
||||||
"path": {
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
71,
|
|
||||||
107,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"from": [
|
|
||||||
-25.0,
|
|
||||||
25.0
|
|
||||||
],
|
|
||||||
"tag": {
|
|
||||||
"end": 106,
|
|
||||||
"start": 85,
|
|
||||||
"type": "TagDeclarator",
|
|
||||||
"value": "rectangleSegmentB001"
|
|
||||||
},
|
|
||||||
"to": [
|
|
||||||
-25.0,
|
|
||||||
-25.0
|
|
||||||
],
|
|
||||||
"type": "ToPoint",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"surface": null
|
|
||||||
},
|
|
||||||
"__meta": [
|
|
||||||
{
|
|
||||||
"sourceRange": [
|
|
||||||
85,
|
|
||||||
106,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"__meta": [
|
|
||||||
{
|
|
||||||
"sourceRange": [
|
|
||||||
37,
|
|
||||||
65,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sketch002": {
|
|
||||||
"type": "Solid",
|
|
||||||
"value": {
|
|
||||||
"type": "Solid",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"faceId": "[uuid]",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"tag": null,
|
|
||||||
"type": "extrudeArc"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sketch": {
|
|
||||||
"type": "Sketch",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"paths": [
|
|
||||||
{
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ccw": true,
|
|
||||||
"center": [
|
|
||||||
-50.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"from": [
|
|
||||||
-40.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"radius": 10.0,
|
|
||||||
"tag": null,
|
|
||||||
"to": [
|
|
||||||
-40.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"type": "Circle",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"on": {
|
|
||||||
"type": "plane",
|
|
||||||
"id": "[uuid]",
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"value": "XY",
|
|
||||||
"origin": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"xAxis": {
|
|
||||||
"x": 1.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"yAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 1.0,
|
|
||||||
"z": 0.0
|
|
||||||
},
|
|
||||||
"zAxis": {
|
|
||||||
"x": 0.0,
|
|
||||||
"y": 0.0,
|
|
||||||
"z": 1.0
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"__meta": []
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"from": [
|
|
||||||
-40.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"to": [
|
|
||||||
-40.0,
|
|
||||||
0.0
|
|
||||||
],
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"tag": null,
|
|
||||||
"__geoMeta": {
|
|
||||||
"id": "[uuid]",
|
|
||||||
"sourceRange": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"artifactId": "[uuid]",
|
|
||||||
"originalId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"__meta": [
|
|
||||||
{
|
|
||||||
"sourceRange": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"height": 0.0,
|
|
||||||
"startCapId": "[uuid]",
|
|
||||||
"endCapId": "[uuid]",
|
|
||||||
"units": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"__meta": [
|
|
||||||
{
|
|
||||||
"sourceRange": [
|
|
||||||
145,
|
|
||||||
190,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 93 KiB |