Compare commits

...

57 Commits

Author SHA1 Message Date
de74c4eae0 Tweak format changes
Breaking line(endAbsolute) onto multiple lines changed a bunch of tests
2025-02-11 09:59:48 -06:00
8972ddb640 Merge branch 'nadro/adhoc/ubuntu-e2e-local-fixes' into achalmers/kw-pattern-with-kevin-merge 2025-02-11 09:10:35 -06:00
8a62869d1d fix: restoring this testing code 2025-02-11 08:38:57 -06:00
033687924a Update snapshots 2025-02-10 18:14:24 -06:00
92ed9e445d A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-10 23:37:31 +00:00
2c2974c082 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-10 23:19:57 +00:00
999897102c Update another example 2025-02-10 17:07:14 -06:00
ac69b1263f Format the helix_simple example 2025-02-10 16:56:28 -06:00
026e45895e Update kcl sim tests 2025-02-10 16:54:18 -06:00
220a49b52b Fix up executor tests 2025-02-10 16:54:17 -06:00
e9862e7677 Redo docs 2025-02-10 16:54:17 -06:00
99cb8d3eb0 Fix clippy 2025-02-10 16:54:17 -06:00
4e2a200bdf Fix unit tests 2025-02-10 16:54:17 -06:00
d95d4d7f66 Use newer branch of kcl-samples 2025-02-10 16:54:17 -06:00
5edfae961e Regn docs 2025-02-10 16:54:16 -06:00
6075aa1d07 Tweak format 2025-02-10 16:54:16 -06:00
75f996e0ef Update test code 2025-02-10 16:54:16 -06:00
d29d2d4a11 WIP: Move patterns to kwargs 2025-02-10 16:54:14 -06:00
33287d540d Merge branch 'main' into nadro/adhoc/ubuntu-e2e-local-fixes 2025-02-10 10:54:41 -06:00
66fe3c7892 fix: auto fix: 2025-02-10 10:21:31 -06:00
3085b0c2c7 chore: skipping one more local engine tests that fails 2025-02-10 10:18:28 -06:00
ff884153db fix: big if true 2025-02-07 16:46:07 -06:00
bcd52a43ca fix: codespell 2025-02-07 16:10:39 -06:00
83ee6511be fix: merging main? 2025-02-07 16:08:03 -06:00
c1ff258bf9 fix: fixing test when using local engine 2025-02-07 14:36:33 -06:00
1469c685c0 chore: adding a skipLocalEngine tag 2025-02-07 11:00:03 -06:00
b2fea24fc4 fix: trying to resolve more flakes when running with more workers 2025-02-06 20:33:43 -06:00
1829c1047a fix: last wait fix 2025-02-06 15:52:52 -06:00
d5c7a1cef3 fix: Fixed testing selections with wait 2025-02-06 15:49:09 -06:00
23ea59cf58 Merge branch 'nadro/adhoc/ubuntu-e2e-local-fixes' of github.com:KittyCAD/modeling-app into nadro/adhoc/ubuntu-e2e-local-fixes 2025-02-06 15:44:56 -06:00
3d6fb4e6e6 fix: bad prompt fix 2025-02-06 15:44:06 -06:00
157ee93032 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-06 20:46:06 +00:00
6c4c59ced9 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-06 20:38:33 +00:00
925cc892a7 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-06 20:30:09 +00:00
08ae896b65 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-06 20:23:17 +00:00
2073df8a3f A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-06 20:15:22 +00:00
743732ba15 A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) 2025-02-06 20:07:54 +00:00
b8525ccd61 fix: auto fixes 2025-02-06 14:00:42 -06:00
0188d6c065 fix: resolved main conflicts 2025-02-06 13:58:49 -06:00
ddc7d5b20a fix: restoring name 2025-02-06 13:01:40 -06:00
81c2be78bb fix: not waiting for scene, not waiting for command bar 2025-02-06 13:01:03 -06:00
0f85e85c57 fix: wait for execution done 2025-02-06 12:51:53 -06:00
55a302bd75 fix: wait for execution done 2025-02-06 11:36:48 -06:00
21e710ee41 fix: updating wait for execution 2025-02-06 11:32:10 -06:00
bb51c8d269 fix: adding a wait for execution 2025-02-06 11:27:26 -06:00
d9d970b436 fix: add 1250ms before every progresscmdbar, removed model loaded scene state that is flaky, added toast if someone presses the command bar too quickly 2025-02-06 09:52:09 -06:00
1e9a2e3a1a fix: only fixes the chamfer point and click delete 2025-02-06 09:01:59 -06:00
e9ca2469c5 fix: adding execution done wait 2025-02-06 08:50:48 -06:00
1248623922 fix: adding wait for execution done 2025-02-06 08:47:21 -06:00
49ba5d31c7 fix: removing testing code 2025-02-06 08:44:55 -06:00
af7d0e6b66 fix: added wait for execution done 2025-02-06 08:43:57 -06:00
004898e0c7 fix: saving off debugging... 2025-02-05 15:33:33 -06:00
e7457dac0d fix: adding comment to clarify the gotcha 2025-02-05 12:43:25 -06:00
a8d76950d0 fix: fixing react race condition on parsing numeric literals in command bar on open 2025-02-05 12:34:08 -06:00
2ac836c0b8 fix: bug that desyncs codeManager, executeCode, lspPlugin 2025-02-05 11:07:27 -06:00
25c73aae6c fix: again another wait for execution does not work 2025-02-04 15:05:30 -06:00
65682e755a fix: Needed to increase timeout for this test. waitForExecutionDone does not work since there are errors in the KCL code 2025-02-04 14:47:36 -06:00
75 changed files with 28588 additions and 3558 deletions

File diff suppressed because one or more lines are too long

View File

@ -33,7 +33,14 @@ helix(revolutions: number, angle_start: number, ccw?: bool, radius: number, axis
```js
// Create a helix around the Z axis.
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = 'Z')
helixPath = helix(
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = 'Z',
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('YZ')
@ -49,7 +56,14 @@ helper001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(end = [0, 10], tag = $edge001)
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = edge001)
helixPath = helix(
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = edge001,
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('XY')
@ -61,12 +75,19 @@ springSketch = startSketchOn('XY')
```js
// Create a helix around a custom axis.
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = {
helixPath = helix(
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = {
custom = {
axis = [0, 0, 1.0],
origin = [0, 0.25, 0]
}
})
},
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('XY')

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Repeat a 2-dimensional sketch some number of times along a partial or
complete circle some specified number of times. Each object may additionally be rotated along the circle, ensuring orentation of the solid with respect to the center of the circle is maintained.
```js
patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch]
patternCircular2d(sketch_set: SketchSet, instances: integer, center: [number], arc_degrees: number, rotate_duplicates: bool, use_original?: bool) -> [Sketch]
```
@ -17,8 +17,12 @@ patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`CircularPattern2dData`](/docs/kcl/types/CircularPattern2dData) | Data for a circular pattern on a 2D sketch. | Yes |
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | Which sketch(es) to pattern | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `center` | `[number]` | The center about which to make the pattern. This is a 2D vector. | Yes |
| `arc_degrees` | `number` | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes |
| `rotate_duplicates` | `bool` | Whether or not to rotate the duplicates as they are copied. | Yes |
| `use_original` | `bool` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
### Returns
@ -34,12 +38,12 @@ exampleSketch = startSketchOn('XZ')
|> line(end = [-1, 0])
|> line(end = [0, -5])
|> close()
|> patternCircular2d({
|> patternCircular2d(
center = [0, 0],
instances = 13,
arcDegrees = 360,
rotateDuplicates = true
}, %)
rotateDuplicates = true,
)
example = extrude(exampleSketch, length = 1)
```

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount
of distance between each repetition, some specified number of times.
```js
patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?: bool) -> [Sketch]
patternLinear2d(sketch_set: SketchSet, instances: integer, distance: number, axis: [number], use_original?: bool) -> [Sketch]
```
@ -17,9 +17,11 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?:
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`LinearPattern2dData`](/docs/kcl/types/LinearPattern2dData) | Data for a linear pattern on a 2D sketch. | Yes |
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `use_original` | `bool` | | No |
| `sketch_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch(es) to duplicate | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `distance` | `number` | Distance between each repetition. Also known as 'spacing'. | Yes |
| `axis` | `[number]` | The axis of the pattern. A 2D vector. | Yes |
| `use_original` | `bool` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
### Returns
@ -31,11 +33,7 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet, use_original?:
```js
exampleSketch = startSketchOn('XZ')
|> circle({ center = [0, 0], radius = 1 }, %)
|> patternLinear2d({
axis = [1, 0],
instances = 7,
distance = 4
}, %)
|> patternLinear2d(axis = [1, 0], instances = 7, distance = 4)
example = extrude(exampleSketch, length = 1)
```

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,14 @@ sweepSketch = startSketchOn('XY')
// Create a helix around the Z axis.
helixPath = helix(angleStart = 0, ccw = true, revolutions = 4, length = 10, radius = 5, axis = 'Z')
helixPath = helix(
angleStart = 0,
ccw = true,
revolutions = 4,
length = 10,
radius = 5,
axis = 'Z',
)
// Create a spring by sweeping around the helix path.
springSketch = startSketchOn('YZ')

View File

@ -19,6 +19,8 @@ test.describe(
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// FIXME: Cannot use scene.waitForExecutionDone() since there is no KCL code
await page.waitForTimeout(10000)
await u.openDebugPanel()
const coord =

View File

@ -10,6 +10,7 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
test('Typing KCL errors induces a badge on the code pane button', async ({
page,
homePage,
scene,
}) => {
const u = await getUtils(page)
@ -30,11 +31,7 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await scene.waitForExecutionDone()
// Ensure no badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
@ -175,7 +172,9 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.waitForTimeout(1000)
// FIXME: await scene.waitForExecutionDone() does not work. It still fails.
// I needed to increase this timeout to get this to pass.
await page.waitForTimeout(10000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
@ -187,7 +186,7 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
// click in the editor to focus it
await page.locator('.cm-content').click()
await page.waitForTimeout(500)
await page.waitForTimeout(2000)
// go to the start of the editor and enter more text which will trigger
// a lint error.
@ -204,8 +203,9 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('ArrowUp')
await page.keyboard.press('Home')
await page.keyboard.type('foo_bar = 1')
await page.waitForTimeout(500)
await page.waitForTimeout(2000)
await page.keyboard.press('Enter')
await page.waitForTimeout(2000)
// ensure we have a lint error
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()

View File

@ -174,6 +174,9 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// FIXME: No KCL code, unable to wait for engine execution
await page.waitForTimeout(10000)
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()

View File

@ -9,8 +9,8 @@ import fsp from 'fs/promises'
test(
'export works on the first try',
{ tag: '@electron' },
async ({ page, context }, testInfo) => {
{ tag: ['@electron', '@skipLocalEngine'] },
async ({ page, context, scene }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
@ -118,8 +118,9 @@ test(
// Close the file pane
await u.closeFilePanel()
// wait for it to finish executing (todo: make this more robust)
await page.waitForTimeout(1000)
// FIXME: await scene.waitForExecutionDone() does not work. The modeling indicator stays in -receive-reliable and not execution done
await page.waitForTimeout(10000)
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()

View File

@ -490,6 +490,11 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('ArrowLeft')
await page.keyboard.press('ArrowRight')
// FIXME: lsp errors do not propagate to the frontend until engine is connected and code is executed
// This timeout is to wait for engine connection. LSP and code execution errors should be handled differently
// LSP can emit errors as fast as it waits and show them in the editor
await page.waitForTimeout(10000)
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
@ -641,7 +646,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
width = 0.500
height = 0.500
dia = 4
fn squareHole = (l, w) => {
squareHoleSketch = startSketchOn('XY')
|> startProfileAt([-width / 2, -length / 2], %)
@ -714,7 +719,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
|> line(end = [0, -10], tag = $revolveAxis)
|> close()
|> extrude(length = 10)
sketch001 = startSketchOn(box, revolveAxis)
|> startProfileAt([5, 10], %)
|> line(end = [0, -10])

View File

@ -112,6 +112,9 @@ export class CmdBarFixture {
* and assumes we are past the `pickCommand` step.
*/
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
// FIXME: Progressing the command bar is a race condition. We have an async useEffect that reports the final state via useCalculateKclExpression. If this does not run quickly enough, it will not "fail" the continue because you can press continue if the state is not ready. E2E tests do not know this.
// Wait 1250ms to assume the await executeAst of the KCL input field is finished
await this.page.waitForTimeout(1250)
if (shouldFuzzProgressMethod || Math.random() > 0.5) {
const arrowButton = this.page.getByRole('button', {
name: 'arrow right Continue',
@ -128,6 +131,23 @@ export class CmdBarFixture {
}
}
// Added data-testid to the command bar buttons
// command-bar-continue are the buttons to go to the next step
// does not include the submit which is the final button press
// aka the right arrow button
continue = async () => {
const continueButton = this.page.getByTestId('command-bar-continue')
await continueButton.click()
}
// Added data-testid to the command bar buttons
// command-bar-submit is the button for the final step to submit
// the command bar flow aka the checkmark button.
submit = async () => {
const submitButton = this.page.getByTestId('command-bar-submit')
await submitButton.click()
}
openCmdBar = async (selectCmd?: 'promptToEdit') => {
// TODO why does this button not work in electron tests?
// await this.cmdBarOpenBtn.click()

View File

@ -29,11 +29,13 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
const [clickCircle, moveToCircle] = scene.makeMouseHelpers(582, 217)
await test.step('because there is sweepable geometry, verify extrude is enable when nothing is selected', async () => {
await scene.clickNoWhere()
// FIXME: Do not click, clicking removes the activeLines in future checks
// await scene.clickNoWhere()
await expect(toolbar.extrudeButton).toBeEnabled()
})
@ -199,6 +201,7 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
}, file)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
@ -422,6 +425,7 @@ test.describe('Point-and-click tests', { tag: ['@skipWin'] }, () => {
}, file)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
@ -727,6 +731,9 @@ openSketch = startSketchOn('XY')
const expectedOutput = `plane001 = offsetPlane('XZ', 5)`
await homePage.goToModelingScene()
// FIXME: Since there is no KCL code loaded. We need to wait for the scene to load before we continue.
// The engine may not be connected
await page.waitForTimeout(15000)
await test.step(`Look for the blue of the XZ plane`, async () => {
await scene.expectPixelColor([50, 51, 96], testPoint, 15)
@ -952,6 +959,7 @@ loft001 = loft([sketch001, sketch002])
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
// One dumb hardcoded screen pixel value
const testPoint = { x: 575, y: 200 }
@ -1594,16 +1602,7 @@ extrude001 = extrude(sketch001, length = -12)
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// verify modeling scene is loaded
await scene.expectPixelColor(
backgroundColor,
secondEdgeLocation,
lowTolerance
)
// wait for stream to load
await scene.expectPixelColor(bodyColor, bodyLocation, highTolerance)
await scene.waitForExecutionDone()
})
// Test 1: Command bar flow with preselected edges
@ -1828,6 +1827,7 @@ chamfer04 = chamfer({ length = 5, tags = [getOppositeEdge(seg02)]}, extrude001
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
// verify modeling scene is loaded
await scene.expectPixelColor(
@ -1950,6 +1950,7 @@ chamfer04 = chamfer({ length = 5, tags = [getOppositeEdge(seg02)]}, extrude001
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
// One dumb hardcoded screen pixel value
const testPoint = { x: 575, y: 200 }
@ -2048,6 +2049,7 @@ extrude001 = extrude(sketch001, length = 40)
}, initialCode)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
// One dumb hardcoded screen pixel value
const testPoint = { x: 580, y: 180 }

View File

@ -455,7 +455,7 @@ test.describe('Can export from electron app', () => {
for (const method of exportMethods) {
test(
`Can export using ${method}`,
{ tag: '@electron' },
{ tag: ['@electron', '@skipLocalEngine'] },
async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket')

View File

@ -60,6 +60,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
const body1CapCoords = { x: 571, y: 351 }
const greenCheckCoords = { x: 565, y: 345 }
@ -76,7 +77,9 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
'Submitting to Text-to-CAD API...'
)
const successToast = page.getByText('Prompt to edit successful')
const acceptBtn = page.getByRole('button', { name: 'checkmark Accept' })
const acceptBtn = page.getByRole('button', {
name: 'checkmark Accept',
})
const rejectBtn = page.getByRole('button', { name: 'close Reject' })
await test.step('wait for scene to load select body and check selection came through', async () => {
@ -99,7 +102,9 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(submittingToast).toBeVisible()
await expect(submittingToast).not.toBeVisible({ timeout: 2 * 60_000 }) // can take a while
await expect(submittingToast).not.toBeVisible({
timeout: 2 * 60_000,
}) // can take a while
await expect(successToast).toBeVisible()
})
@ -150,6 +155,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
localStorage.setItem('persistCode', file)
}, file)
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
const body1CapCoords = { x: 571, y: 351 }
const [clickBody1Cap] = scene.makeMouseHelpers(

View File

@ -192,11 +192,11 @@ extrude001 = extrude(sketch001, length = 50)
|> line(end = [0, -1])
|> close()
|> extrude(length = 1)
|> patternLinear3d({
axis: [1, 0, 1],
repetitions: 3,
distance: 6
}, %)`
|> patternLinear3d(
axis = [1, 0, 1],
repetitions = 3,
distance = 6,
)`
)
})
await page.setBodyDimensions({ width: 1000, height: 500 })
@ -251,7 +251,7 @@ extrude001 = extrude(sketch001, length = 50)
|> yLineTo(0, %)
|> close()
|>
example = extrude(exampleSketch, length = 5)
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
)
@ -306,113 +306,113 @@ extrude001 = extrude(sketch001, length = 50)
|> angledLine({ angle: 50, length: 45 }, %)
|> yLineTo(0, %)
|> close()
thing: "blah"`)
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
}
)
test('when engine fails export we handle the failure and alert the user', async ({
scene,
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(
async ({ code }) => {
localStorage.setItem('persistCode', code)
;(window as any).playwrightSkipFilePicker = true
},
{ code: TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR }
)
test(
'when engine fails export we handle the failure and alert the user',
{ tag: '@skipLocalEngine' },
async ({ scene, page, homePage }) => {
const u = await getUtils(page)
await page.addInitScript(
async ({ code }) => {
localStorage.setItem('persistCode', code)
;(window as any).playwrightSkipFilePicker = true
},
{ code: TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR }
)
await page.setBodyDimensions({ width: 1000, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await u.waitForPageLoad()
await homePage.goToModelingScene()
await u.waitForPageLoad()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
// Click the export button
await exportButton.click()
// Click the export button
await exportButton.click()
// Click the stl.
const stlOption = page.getByText('glTF')
await expect(stlOption).toBeVisible()
// Click the stl.
const stlOption = page.getByText('glTF')
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
await expect(engineErrorToastMessage).toBeVisible()
const engineErrorToastMessage = page.getByText(`Nothing to export`)
await expect(engineErrorToastMessage).toBeVisible()
// Make sure the exporting toast is gone
await expect(exportingToastMessage).not.toBeVisible()
// Make sure the exporting toast is gone
await expect(exportingToastMessage).not.toBeVisible()
// Click the code editor
await page.locator('.cm-content').click()
// Click the code editor
await page.locator('.cm-content').click()
await page.waitForTimeout(2000)
await page.waitForTimeout(2000)
// Expect the toast to be gone
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
// Expect the toast to be gone
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
// Now add in code that works.
await page.locator('.cm-content').fill(bracket)
await page.keyboard.press('End')
await page.keyboard.press('Enter')
// Now add in code that works.
await page.locator('.cm-content').fill(bracket)
await page.keyboard.press('End')
await page.keyboard.press('Enter')
await scene.waitForExecutionDone()
await scene.waitForExecutionDone()
// Now try exporting
// Now try exporting
// Click the export button
await exportButton.click()
// Click the export button
await exportButton.click()
// Click the stl.
await expect(stlOption).toBeVisible()
// Click the stl.
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
await page.keyboard.press('Enter')
// Click the checkbox
await expect(submitButton).toBeVisible()
// Click the checkbox
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
// Expect it to succeed.
await expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 })
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
// Expect it to succeed.
await expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 })
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
})
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
}
)
test(
'ensure you can not export while an export is already going',
{ tag: ['@skipLinux', '@skipWin'] },

View File

@ -9,6 +9,7 @@ import {
PERSIST_MODELING_CONTEXT,
} from './test-utils'
import { uuidv4, roundOff } from 'lib/utils'
import { SceneFixture } from './fixtures/sceneFixture'
test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
test('multi-sketch file shows multiple Edit Sketch buttons', async ({
@ -184,7 +185,8 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
const doEditSegmentsByDraggingHandle = async (
page: Page,
homePage: HomePageFixture,
openPanes: string[]
openPanes: string[],
scene: SceneFixture
) => {
// Load the app with the code panes
await page.addInitScript(async () => {
@ -200,6 +202,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
const u = await getUtils(page)
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
@ -317,7 +320,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
test(
'code pane open at start-handles',
{ tag: ['@skipWin'] },
async ({ page, homePage }) => {
async ({ page, homePage, scene }) => {
// Load the app with the code panes
await page.addInitScript(async () => {
localStorage.setItem(
@ -330,14 +333,14 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
})
)
})
await doEditSegmentsByDraggingHandle(page, homePage, ['code'])
await doEditSegmentsByDraggingHandle(page, homePage, ['code'], scene)
}
)
test(
'code pane closed at start-handles',
{ tag: ['@skipWin'] },
async ({ page, homePage }) => {
async ({ page, homePage, scene }) => {
// Load the app with the code panes
await page.addInitScript(async (persistModelingContext) => {
localStorage.setItem(
@ -345,7 +348,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
JSON.stringify({ openPanes: [] })
)
}, PERSIST_MODELING_CONTEXT)
await doEditSegmentsByDraggingHandle(page, homePage, [])
await doEditSegmentsByDraggingHandle(page, homePage, [], scene)
}
)
})
@ -547,6 +550,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
test('Can edit a sketch that has been revolved in the same pipe', async ({
page,
homePage,
scene,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
@ -562,6 +566,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
})
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
await expect(
page.getByRole('button', { name: 'Start Sketch' })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -3,199 +3,200 @@ import { test, expect } from './zoo-test'
import { commonPoints, getUtils } from './test-utils'
test.describe('Test network and connection issues', () => {
test('simulate network down and network little widget', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
test(
'simulate network down and network little widget',
{ tag: '@skipLocalEngine' },
async ({ page, homePage }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await homePage.goToModelingScene()
const networkToggle = page.getByTestId('network-toggle')
const networkToggle = page.getByTestId('network-toggle')
// This is how we wait until the stream is online
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled({ timeout: 15000 })
// This is how we wait until the stream is online
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled({ timeout: 15000 })
const networkWidget = page.locator('[data-testid="network-toggle"]')
await expect(networkWidget).toBeVisible()
await networkWidget.hover()
const networkWidget = page.locator('[data-testid="network-toggle"]')
await expect(networkWidget).toBeVisible()
await networkWidget.hover()
const networkPopover = page.locator('[data-testid="network-popover"]')
await expect(networkPopover).not.toBeVisible()
const networkPopover = page.locator('[data-testid="network-popover"]')
await expect(networkPopover).not.toBeVisible()
// (First check) Expect the network to be up
await expect(networkToggle).toContainText('Connected')
// (First check) Expect the network to be up
await expect(networkToggle).toContainText('Connected')
// Click the network widget
await networkWidget.click()
// Click the network widget
await networkWidget.click()
// Check the modal opened.
await expect(networkPopover).toBeVisible()
// Check the modal opened.
await expect(networkPopover).toBeVisible()
// Click off the modal.
await page.mouse.click(100, 100)
await expect(networkPopover).not.toBeVisible()
// Click off the modal.
await page.mouse.click(100, 100)
await expect(networkPopover).not.toBeVisible()
// Turn off the network
await u.emulateNetworkConditions({
offline: true,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// Turn off the network
await u.emulateNetworkConditions({
offline: true,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// Expect the network to be down
await expect(networkToggle).toContainText('Problem')
// Expect the network to be down
await expect(networkToggle).toContainText('Problem')
// Click the network widget
await networkWidget.click()
// Click the network widget
await networkWidget.click()
// Check the modal opened.
await expect(networkPopover).toBeVisible()
// Check the modal opened.
await expect(networkPopover).toBeVisible()
// Click off the modal.
await page.mouse.click(0, 0)
await expect(networkPopover).not.toBeVisible()
// Click off the modal.
await page.mouse.click(0, 0)
await expect(networkPopover).not.toBeVisible()
// Turn back on the network
await u.emulateNetworkConditions({
offline: false,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// Turn back on the network
await u.emulateNetworkConditions({
offline: false,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled({ timeout: 15000 })
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled({ timeout: 15000 })
// (Second check) expect the network to be up
await expect(networkToggle).toContainText('Connected')
})
// (Second check) expect the network to be up
await expect(networkToggle).toContainText('Connected')
}
)
test('Engine disconnect & reconnect in sketch mode', async ({
page,
homePage,
}) => {
// TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit
const networkToggle = page.getByTestId('network-toggle')
test(
'Engine disconnect & reconnect in sketch mode',
{ tag: '@skipLocalEngine' },
async ({ page, homePage }) => {
// TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit
const networkToggle = page.getByTestId('network-toggle')
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
await homePage.goToModelingScene()
await u.waitForPageLoad()
await homePage.goToModelingScene()
await u.waitForPageLoad()
await u.openDebugPanel()
// click on "Start Sketch" button
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(100)
await u.openDebugPanel()
// click on "Start Sketch" button
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(100)
// select a plane
await page.mouse.click(700, 200)
// select a plane
await page.mouse.click(700, 200)
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')`
)
await u.closeDebugPanel()
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn('XZ')`
)
await u.closeDebugPanel()
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
|> startProfileAt(${commonPoints.startAt}, %)`)
await page.waitForTimeout(100)
await page.waitForTimeout(100)
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
await page.waitForTimeout(100)
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
await page.waitForTimeout(100)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
|> startProfileAt(${commonPoints.startAt}, %)
|> xLine(${commonPoints.num1}, %)`)
// Expect the network to be up
await expect(networkToggle).toContainText('Connected')
// Expect the network to be up
await expect(networkToggle).toContainText('Connected')
// simulate network down
await u.emulateNetworkConditions({
offline: true,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// simulate network down
await u.emulateNetworkConditions({
offline: true,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// Expect the network to be down
await expect(networkToggle).toContainText('Problem')
// Expect the network to be down
await expect(networkToggle).toContainText('Problem')
// Ensure we are not in sketch mode
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).not.toBeVisible()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).toBeVisible()
// Ensure we are not in sketch mode
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).not.toBeVisible()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).toBeVisible()
// simulate network up
await u.emulateNetworkConditions({
offline: false,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// simulate network up
await u.emulateNetworkConditions({
offline: false,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// Wait for the app to be ready for use
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled({ timeout: 15000 })
// Wait for the app to be ready for use
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled({ timeout: 15000 })
// Expect the network to be up
await expect(networkToggle).toContainText('Connected')
await expect(page.getByTestId('loading-stream')).not.toBeAttached()
// Expect the network to be up
await expect(networkToggle).toContainText('Connected')
await expect(page.getByTestId('loading-stream')).not.toBeAttached()
// Click off the code pane.
await page.mouse.click(100, 100)
// Click off the code pane.
await page.mouse.click(100, 100)
// select a line
await page.getByText(`startProfileAt(${commonPoints.startAt}, %)`).click()
// select a line
await page.getByText(`startProfileAt(${commonPoints.startAt}, %)`).click()
// enter sketch again
await u.doAndWaitForCmd(
() => page.getByRole('button', { name: 'Edit Sketch' }).click(),
'default_camera_get_settings'
)
await page.waitForTimeout(150)
// enter sketch again
await u.doAndWaitForCmd(
() => page.getByRole('button', { name: 'Edit Sketch' }).click(),
'default_camera_get_settings'
)
await page.waitForTimeout(150)
// Click the line tool
await page.getByRole('button', { name: 'line Line', exact: true }).click()
// Click the line tool
await page.getByRole('button', { name: 'line Line', exact: true }).click()
await page.waitForTimeout(150)
await page.waitForTimeout(150)
// Ensure we can continue sketching
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
await expect.poll(u.normalisedEditorCode)
.toBe(`sketch001 = startSketchOn('XZ')
// Ensure we can continue sketching
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
await expect.poll(u.normalisedEditorCode)
.toBe(`sketch001 = startSketchOn('XZ')
|> startProfileAt([12.34, -12.34], %)
|> xLine(12.34, %)
|> line(end = [-12.34, 12.34])
`)
await page.waitForTimeout(100)
await page.mouse.click(startXPx, 500 - PUR * 20)
await page.waitForTimeout(100)
await page.mouse.click(startXPx, 500 - PUR * 20)
await expect.poll(u.normalisedEditorCode)
.toBe(`sketch001 = startSketchOn('XZ')
await expect.poll(u.normalisedEditorCode)
.toBe(`sketch001 = startSketchOn('XZ')
|> startProfileAt([12.34, -12.34], %)
|> xLine(12.34, %)
|> line(end = [-12.34, 12.34])
@ -203,20 +204,21 @@ test.describe('Test network and connection issues', () => {
`)
// Unequip line tool
await page.keyboard.press('Escape')
// Make sure we didn't pop out of sketch mode.
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).toBeVisible()
await expect(
page.getByRole('button', { name: 'line Line', exact: true })
).not.toHaveAttribute('aria-pressed', 'true')
// Unequip line tool
await page.keyboard.press('Escape')
// Make sure we didn't pop out of sketch mode.
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).toBeVisible()
await expect(
page.getByRole('button', { name: 'line Line', exact: true })
).not.toHaveAttribute('aria-pressed', 'true')
// Exit sketch
await page.keyboard.press('Escape')
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).not.toBeVisible()
})
// Exit sketch
await page.keyboard.press('Escape')
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).not.toBeVisible()
}
)
})

View File

@ -109,7 +109,8 @@ test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => {
await page.keyboard.down('Shift')
await page.mouse.move(600, 200)
await page.mouse.down({ button: 'right' })
await page.mouse.move(700, 200, { steps: 2 })
// Gotcha: remove steps:2 from this 700,200 mouse move. This bricked the test on local host engine.
await page.mouse.move(700, 200)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Shift')
}, [-19, -85, -85])

View File

@ -248,7 +248,11 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
})
})
test('Solids should be select and deletable', async ({ page, homePage }) => {
test('Solids should be select and deletable', async ({
page,
homePage,
scene,
}) => {
test.setTimeout(90_000)
const u = await getUtils(page)
await page.addInitScript(async () => {
@ -320,10 +324,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await scene.waitForExecutionDone()
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
@ -902,6 +903,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
test('Testing selections (and hovers) work on sketches when NOT in sketch mode', async ({
page,
homePage,
scene,
}) => {
const cases = [
{
@ -937,6 +939,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
@ -970,6 +973,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
test("Hovering and selection of extruded faces works, and is not overridden shortly after user's click", async ({
page,
homePage,
scene,
}) => {
await page.addInitScript(async () => {
localStorage.setItem(
@ -988,6 +992,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await scene.waitForExecutionDone()
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
@ -1021,19 +1026,19 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
.poll(() => u.getGreatestPixDiff(extrudeWall, noHoverColor))
.toBeLessThan(15)
await page.mouse.move(nothing.x, nothing.y)
await page.waitForTimeout(100)
await page.waitForTimeout(1000)
await page.mouse.move(extrudeWall.x, extrudeWall.y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible()
await expect(page.getByTestId('hover-highlight').first()).toContainText(
removeAfterFirstParenthesis(extrudeText)
)
await page.waitForTimeout(200)
await page.waitForTimeout(1000)
await expect(
await u.getGreatestPixDiff(extrudeWall, hoverColor)
).toBeLessThan(15)
await page.mouse.click(extrudeWall.x, extrudeWall.y)
await expect(page.locator('.cm-activeLine')).toHaveText(`|> ${extrudeText}`)
await page.waitForTimeout(200)
await page.waitForTimeout(1000)
await expect(
await u.getGreatestPixDiff(extrudeWall, selectColor)
).toBeLessThan(15)
@ -1044,7 +1049,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
).toBeLessThan(15)
await page.mouse.move(nothing.x, nothing.y)
await page.waitForTimeout(300)
await page.waitForTimeout(1000)
await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
// because of shading, color is not exact everywhere on the face
@ -1058,11 +1063,11 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
await expect(page.getByTestId('hover-highlight').first()).toContainText(
removeAfterFirstParenthesis(capText)
)
await page.waitForTimeout(200)
await page.waitForTimeout(1000)
await expect(await u.getGreatestPixDiff(cap, hoverColor)).toBeLessThan(15)
await page.mouse.click(cap.x, cap.y)
await expect(page.locator('.cm-activeLine')).toHaveText(`|> ${capText}`)
await page.waitForTimeout(200)
await page.waitForTimeout(1000)
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(15)
await page.waitForTimeout(1000)
// check color stays there, i.e. not overridden (this was a bug previously)
@ -1109,7 +1114,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|> line(end = [4.95, -8])
|> line(end = [-20.38, -10.12])
|> line(end = [-15.79, 17.08])
fn yohey = (pos) => {
sketch004 = startSketchOn('XZ')
${extrudeAndEditBlockedInFunction}
@ -1119,7 +1124,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|> line(end = [-15.79, 17.08])
return ''
}
yohey([15.79, -34.6])
`
)

View File

@ -32,15 +32,18 @@ test.fixme('Units menu', async ({ page, homePage }) => {
await expect(unitsMenuButton).toContainText('mm')
})
test('Successful export shows a success toast', async ({ page, homePage }) => {
// FYI this test doesn't work with only engine running locally
// And you will need to have the KittyCAD CLI installed
const u = await getUtils(page)
await page.addInitScript(async () => {
;(window as any).playwrightSkipFilePicker = true
localStorage.setItem(
'persistCode',
`topAng = 25
test(
'Successful export shows a success toast',
{ tag: '@skipLocalEngine' },
async ({ page, homePage }) => {
// FYI this test doesn't work with only engine running locally
// And you will need to have the KittyCAD CLI installed
const u = await getUtils(page)
await page.addInitScript(async () => {
;(window as any).playwrightSkipFilePicker = true
localStorage.setItem(
'persistCode',
`topAng = 25
bottomAng = 35
baseLen = 3.5
baseHeight = 1
@ -78,26 +81,27 @@ part001 = startSketchOn('-XZ')
|> xLineTo(ZERO, %)
|> close()
|> extrude(length = 4)`
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.waitForCmdReceive('extrude')
await page.waitForTimeout(1000)
await u.clearAndCloseDebugPanel()
await doExport(
{
type: 'gltf',
storage: 'embedded',
presentation: 'pretty',
},
page
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.waitForCmdReceive('extrude')
await page.waitForTimeout(1000)
await u.clearAndCloseDebugPanel()
await doExport(
{
type: 'gltf',
storage: 'embedded',
presentation: 'pretty',
},
page
)
})
}
)
test('Paste should not work unless an input is focused', async ({
page,
@ -444,7 +448,7 @@ test('Delete key does not navigate back', async ({ page, homePage }) => {
await expect.poll(() => page.url()).not.toContain('/settings')
})
test('Sketch on face', async ({ page, homePage }) => {
test('Sketch on face', async ({ page, homePage, scene, cmdBar }) => {
test.setTimeout(90_000)
const u = await getUtils(page)
await page.addInitScript(async () => {
@ -470,11 +474,7 @@ extrude001 = extrude(sketch001, length = 5 + 7)`
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await scene.waitForExecutionDone()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
@ -579,10 +579,9 @@ extrude001 = extrude(sketch001, length = 5 + 7)`
await expect(page.getByTestId('command-bar')).toBeVisible()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'arrow right Continue' }).click()
await page.waitForTimeout(100)
await cmdBar.progressCmdBar()
await expect(page.getByText('Confirm Extrude')).toBeVisible()
await page.getByRole('button', { name: 'checkmark Submit command' }).click()
await cmdBar.progressCmdBar()
const result2 = result.genNext`
const sketch002 = extrude(sketch002, length = ${[5, 5]} + 7)`

View File

@ -85,7 +85,7 @@
"fmt": "prettier --write ./src *.ts *.json *.js ./e2e ./packages",
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages",
"fetch:wasm": "./get-latest-wasm-bundle.sh",
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/achalmers/kw-appearance/manifest.json",
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/achalmers/kw-pattern/manifest.json",
"isomorphic-copy-wasm": "(copy src/wasm-lib/pkg/wasm_lib_bg.wasm public || cp src/wasm-lib/pkg/wasm_lib_bg.wasm public)",
"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": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings && cd ../.. && yarn isomorphic-copy-wasm && yarn fmt",
@ -120,6 +120,7 @@
"test:playwright:electron:windows:local": "yarn tronb:vite:dev && set NODE_ENV='development' && playwright test --config=playwright.electron.config.ts --grep-invert=\"@skipWin|@snapshot\"",
"test:playwright:electron:macos:local": "yarn tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@skipMacos|@snapshot'",
"test:playwright:electron:ubuntu:local": "yarn tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@skipLinux|@snapshot'",
"test:playwright:electron:ubuntu:engine:local": "yarn tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@skipLinux|@snapshot|@skipLocalEngine'",
"test:unit:local": "yarn simpleserver:bg && yarn test:unit; kill-port 3000",
"test:unit:kcl-samples:local": "yarn simpleserver:bg && yarn test:unit:kcl-samples; kill-port 3000"
},

View File

@ -196,6 +196,7 @@ function ReviewingButton() {
type="submit"
form="review-form"
className="w-fit !p-0 rounded-sm hover:shadow"
data-testid="command-bar-submit"
iconStart={{
icon: 'checkmark',
bgClassName: 'p-1 rounded-sm !bg-primary hover:brightness-110',
@ -214,6 +215,7 @@ function GatheringArgsButton() {
type="submit"
form="arg-form"
className="w-fit !p-0 rounded-sm hover:shadow"
data-testid="command-bar-continue"
iconStart={{
icon: 'arrowRight',
bgClassName: 'p-1 rounded-sm !bg-primary hover:brightness-110',

View File

@ -20,6 +20,7 @@ import { createIdentifier, createVariableDeclaration } from 'lang/modifyAst'
import { useCodeMirror } from 'components/ModelingSidebar/ModelingPanes/CodeEditor'
import { useSelector } from '@xstate/react'
import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine'
import toast from 'react-hot-toast'
const machineContextSelector = (snapshot?: {
context: Record<string, unknown>
@ -97,6 +98,7 @@ function CommandBarKclInput({
value,
initialVariableName,
})
const varMentionData: Completion[] = prevVariables.map((v) => ({
label: v.key,
detail: String(roundOff(v.value as number)),
@ -170,7 +172,15 @@ function CommandBarKclInput({
function handleSubmit(e?: React.FormEvent<HTMLFormElement>) {
e?.preventDefault()
if (!canSubmit || valueNode === null) return
if (!canSubmit || valueNode === null) {
// Gotcha: Our application can attempt to submit a command value before the command bar kcl input is ready. Notify the scene and user.
if (!canSubmit) {
toast.error('Unable to submit command')
} else if (valueNode === null) {
toast.error('Unable to submit undefined command value')
}
return
}
onSubmit(
createNewVariable

View File

@ -25,6 +25,18 @@ export class KclPlugin implements PluginValue {
constructor(client: LanguageServerClient) {
this.client = client
// Gotcha: Code can be written into the CodeMirror editor but not propagated to codeManager.code
// because the update function has not run. We need to initialize the codeManager.code when lsp initializes
// because new code could have been written into the editor before the update callback is initialized.
// There appears to be limited ways to safely get the current doc content. This appears to be sync and safe.
const kclLspPlugin = this.client.plugins.find((plugin) => {
return plugin.client.name === 'kcl'
})
if (kclLspPlugin) {
// @ts-ignore Ignoring this private dereference of .view on the plugin. I do not have another helper method that can give me doc string
codeManager.code = kclLspPlugin.view.state.doc.toString()
}
}
// When a doc update needs to be sent to the server, this holds the

View File

@ -32,7 +32,7 @@ child_process.spawnSync('git', [
'clone',
'--single-branch',
'--branch',
'achalmers/kw-appearance',
'achalmers/kw-pattern',
URL_GIT_KCL_SAMPLES,
DIR_KCL_SAMPLES,
])

View File

@ -289,7 +289,10 @@ describe('testing addTagForSketchOnFace', () => {
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|> line(
endAbsolute = [profileStartX(%), profileStartY(%)],
tag = $seg02,
)
|> close()
extrude001 = extrude(sketch001, length = 100)
${insertCode}

View File

@ -51,16 +51,16 @@ sketch002 = startSketchOn(sketch001, seg03)
center = [-1.25, 1],
radius = mountingHoleDiameter / 2,
}, %)
|> patternLinear2d({
|> patternLinear2d(
instances = 2,
distance = 2.5,
axis = [-1, 0],
}, %)
|> patternLinear2d({
)
|> patternLinear2d(
instances = 2,
distance = 4,
axis = [0, 1],
}, %)
)
|> extrude(%, length = -thickness-.01)
sketch003 = startSketchOn(sketch001, seg04)
@ -68,11 +68,11 @@ sketch003 = startSketchOn(sketch001, seg04)
center = [1, -1],
radius = mountingHoleDiameter / 2,
}, %)
|> patternLinear2d({
|> patternLinear2d(
instances = 2,
distance = 4,
axis = [1, 0],
}, %)
)
|> extrude(%, length = -thickness-0.1)
`

View File

@ -9,6 +9,8 @@ import {
getCalculatedKclExpressionValue,
programMemoryFromVariables,
} from './kclHelpers'
import { parse, resultIsOk } from 'lang/wasm'
import { err } from 'lib/trap'
const isValidVariableName = (name: string) =>
/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)
@ -50,7 +52,20 @@ export function useCalculateKclExpression({
bodyPath: [],
})
const [valueNode, setValueNode] = useState<Expr | null>(null)
const [calcResult, setCalcResult] = useState('NAN')
// Gotcha: If we do not attempt to parse numeric literals instantly it means that there is an async action to verify
// the value is good. This means all E2E tests have a race condition on when they can hit "next" in the command bar.
// Most scenarios automatically pass a numeric literal. We can try to parse that first, otherwise make it go through the slow
// async method.
// If we pass in numeric literals, we should instantly parse them, they have nothing to do with application memory
const _code_value = `const __result__ = ${value}`
const codeValueParseResult = parse(_code_value)
let isValueParsable = true
if (err(codeValueParseResult) || !resultIsOk(codeValueParseResult)) {
isValueParsable = false
}
const initialCalcResult: number | string =
Number.isNaN(Number(value)) || !isValueParsable ? 'NAN' : value
const [calcResult, setCalcResult] = useState(initialCalcResult)
const [newVariableName, setNewVariableName] = useState('')
const [isNewVariableNameUnique, setIsNewVariableNameUnique] = useState(true)

View File

@ -36,5 +36,11 @@ run-sim-test test_name:
{{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
overwrite-sim-test test_name:
EXPECTORATE=overwrite {{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::parse
EXPECTORATE=overwrite {{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
{{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
test:
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1

View File

@ -944,13 +944,7 @@ mod tests {
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"patternCircular3d({
instances = ${0:10},
axis = [${1:3.14}, ${2:3.14}, ${3:3.14}],
center = [${4:3.14}, ${5:3.14}, ${6:3.14}],
arcDegrees = ${7:3.14},
rotateDuplicates = ${8:false},
}, ${9:%})${}"#
r#"patternCircular3d(${0:%}, instances = ${1:10}, axis = [${2:3.14}, ${3:3.14}, ${4:3.14}], center = [${5:3.14}, ${6:3.14}, ${7:3.14}], arc_degrees = ${8:3.14}, rotate_duplicates = ${9:false})${}"#
);
}
@ -1006,11 +1000,7 @@ mod tests {
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"patternLinear2d({
instances = ${0:10},
distance = ${1:3.14},
axis = [${2:3.14}, ${3:3.14}],
}, ${4:%})${}"#
r#"patternLinear2d(${0:%}, instances = ${1:10}, distance = ${2:3.14}, axis = [${3:3.14}, ${4:3.14}])${}"#
);
}

View File

@ -1543,13 +1543,13 @@ sphere = startSketchOn('XZ')
}, %)
|> close()
|> revolve({ axis: 'x' }, %)
|> patternCircular3d({
axis: [0, 0, 1],
center: [0, 0, 0],
repetitions: 10,
arcDegrees: 360,
rotateDuplicates: true
}, %)
|> patternCircular3d(
axis = [0, 0, 1],
center = [0, 0, 0],
repetitions = 10,
arcDegrees = 360,
rotateDuplicates = true,
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
@ -1644,13 +1644,13 @@ sphere = startSketchOn('XZ')
}, %)
|> close()
|> revolve({ axis = 'x' }, %)
|> patternCircular3d({
|> patternCircular3d(
axis = [0, 0, 1],
center = [0, 0, 0],
repetitions = 10,
arcDegrees = 360,
rotateDuplicates = true
}, %)
rotateDuplicates = true,
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')

View File

@ -180,12 +180,12 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// color = '#ff0000',
/// metalness = 90,
/// roughness = 90
/// )
/// |> patternLinear3d({
/// axis = [1, 0, 1],
/// instances = 7,
/// distance = 6
/// }, %)
/// )
/// |> patternLinear3d(
/// axis = [1, 0, 1],
/// instances = 7,
/// distance = 6
/// )
/// ```
///
/// ```no_run
@ -199,16 +199,16 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// |> close()
///
/// example = extrude(exampleSketch, length = 1)
/// |> patternLinear3d({
/// |> patternLinear3d(
/// axis = [1, 0, 1],
/// instances = 7,
/// distance = 6
/// }, %)
/// |> appearance(
/// color = '#ff0000',
/// metalness = 90,
/// roughness = 90
/// )
/// )
/// |> appearance(
/// color = '#ff0000',
/// metalness = 90,
/// roughness = 90
/// )
/// ```
///
/// ```no_run
@ -219,12 +219,12 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// |> line(end = [-1, 0])
/// |> line(end = [0, -5])
/// |> close()
/// |> patternCircular2d({
/// |> patternCircular2d(
/// center = [0, 0],
/// instances = 13,
/// arcDegrees = 360,
/// rotateDuplicates = true
/// }, %)
/// )
///
/// example = extrude(exampleSketch, length = 1)
/// |> appearance(

View File

@ -440,13 +440,6 @@ impl Args {
FromArgs::from_args(self, 0)
}
pub(crate) fn get_data_and_solid_set<'a, T>(&'a self) -> Result<(T, SolidSet), KclError>
where
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
{
FromArgs::from_args(self, 0)
}
pub(crate) fn get_data_and_solid<'a, T>(&'a self) -> Result<(T, Box<Solid>), KclError>
where
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
@ -943,72 +936,6 @@ impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::Direction {
}
}
impl<'a> FromKclValue<'a> for super::patterns::CircularPattern3dData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, instances);
let_field_of!(obj, arc_degrees "arcDegrees");
let_field_of!(obj, rotate_duplicates "rotateDuplicates");
let_field_of!(obj, axis);
let_field_of!(obj, center);
let_field_of!(obj, use_original? "useOriginal");
Some(Self {
instances,
axis,
center,
arc_degrees,
rotate_duplicates,
use_original,
})
}
}
impl<'a> FromKclValue<'a> for super::patterns::CircularPattern2dData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, instances);
let_field_of!(obj, arc_degrees "arcDegrees");
let_field_of!(obj, rotate_duplicates "rotateDuplicates");
let_field_of!(obj, center);
let_field_of!(obj, use_original? "useOriginal");
Some(Self {
instances,
center,
arc_degrees,
rotate_duplicates,
use_original,
})
}
}
impl<'a> FromKclValue<'a> for super::patterns::LinearPattern3dData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, distance);
let_field_of!(obj, instances);
let_field_of!(obj, axis);
Some(Self {
instances,
distance,
axis,
})
}
}
impl<'a> FromKclValue<'a> for super::patterns::LinearPattern2dData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;
let_field_of!(obj, distance);
let_field_of!(obj, instances);
let_field_of!(obj, axis);
Some(Self {
instances,
distance,
axis,
})
}
}
impl<'a> FromKclValue<'a> for super::sketch::BezierData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?;

View File

@ -29,22 +29,6 @@ use crate::{
const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry";
/// Data for a linear pattern on a 2D sketch.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct LinearPattern2dData {
/// The number of total instances. Must be greater than or equal to 1.
/// This includes the original entity. For example, if instances is 2,
/// there will be two copies -- the original, and one new copy.
/// If instances is 1, this has no effect.
pub instances: u32,
/// The distance between each repetition. This can also be referred to as spacing.
pub distance: f64,
/// The axis of the pattern. This is a 2D vector.
pub axis: [f64; 2],
}
/// Data for a linear pattern on a 3D model.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
@ -689,10 +673,13 @@ mod tests {
/// A linear pattern on a 2D sketch.
pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch_set, use_original): (LinearPattern2dData, SketchSet, Option<bool>) =
super::args::FromArgs::from_args(&args, 0)?;
let sketch_set: SketchSet = args.get_unlabeled_kw_arg("sketchSet")?;
let instances: u32 = args.get_kw_arg("instances")?;
let distance: f64 = args.get_kw_arg("distance")?;
let axis: [f64; 2] = args.get_kw_arg("axis")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
if data.axis == [0.0, 0.0] {
if axis == [0.0, 0.0] {
return Err(KclError::Semantic(KclErrorDetails {
message:
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
@ -701,7 +688,8 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
}));
}
let sketches = inner_pattern_linear_2d(data, sketch_set, use_original, exec_state, args).await?;
let sketches =
inner_pattern_linear_2d(sketch_set, instances, distance, axis, use_original, exec_state, args).await?;
Ok(sketches.into())
}
@ -711,31 +699,41 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
/// ```no_run
/// exampleSketch = startSketchOn('XZ')
/// |> circle({ center = [0, 0], radius = 1 }, %)
/// |> patternLinear2d({
/// |> patternLinear2d(
/// axis = [1, 0],
/// instances = 7,
/// distance = 4
/// }, %)
/// )
///
/// example = extrude(exampleSketch, length = 1)
/// ```
#[stdlib {
name = "patternLinear2d",
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "The sketch(es) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
distance = { docs = "Distance between each repetition. Also known as 'spacing'."},
axis = { docs = "The axis of the pattern. A 2D vector." },
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
}
}]
async fn inner_pattern_linear_2d(
data: LinearPattern2dData,
sketch_set: SketchSet,
instances: u32,
distance: f64,
axis: [f64; 2],
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
let axis = data.axis;
let [x, y] = axis;
let axis_len = f64::sqrt(x * x + y * y);
let normalized_axis = kcmc::shared::Point2d::from([x / axis_len, y / axis_len]);
let transforms: Vec<_> = (1..data.instances)
let transforms: Vec<_> = (1..instances)
.map(|i| {
let d = data.distance * (i as f64);
let d = distance * (i as f64);
let translate = (normalized_axis * d).with_z(0.0).map(LengthUnit);
vec![Transform {
translate,
@ -755,10 +753,13 @@ async fn inner_pattern_linear_2d(
/// A linear pattern on a 3D model.
pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid_set, use_original): (LinearPattern3dData, SolidSet, Option<bool>) =
super::args::FromArgs::from_args(&args, 0)?;
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
let instances: u32 = args.get_kw_arg("instances")?;
let distance: f64 = args.get_kw_arg("distance")?;
let axis: [f64; 3] = args.get_kw_arg("axis")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
if data.axis == [0.0, 0.0, 0.0] {
if axis == [0.0, 0.0, 0.0] {
return Err(KclError::Semantic(KclErrorDetails {
message:
"The axis of the linear pattern cannot be the zero vector. Otherwise they will just duplicate in place."
@ -767,7 +768,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
}));
}
let solids = inner_pattern_linear_3d(data, solid_set, use_original, exec_state, args).await?;
let solids = inner_pattern_linear_3d(solid_set, instances, distance, axis, use_original, exec_state, args).await?;
Ok(solids.into())
}
@ -783,30 +784,40 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
/// |> close()
///
/// example = extrude(exampleSketch, length = 1)
/// |> patternLinear3d({
/// |> patternLinear3d(
/// axis = [1, 0, 1],
/// instances = 7,
/// distance = 6
/// }, %)
/// )
/// ```
#[stdlib {
name = "patternLinear3d",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "The solid(s) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
distance = { docs = "Distance between each repetition. Also known as 'spacing'."},
axis = { docs = "The axis of the pattern. A 2D vector." },
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
}
}]
async fn inner_pattern_linear_3d(
data: LinearPattern3dData,
solid_set: SolidSet,
instances: u32,
distance: f64,
axis: [f64; 3],
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Solid>>, KclError> {
let axis = data.axis;
let [x, y, z] = axis;
let axis_len = f64::sqrt(x * x + y * y + z * z);
let normalized_axis = kcmc::shared::Point3d::from([x / axis_len, y / axis_len, z / axis_len]);
let transforms: Vec<_> = (1..data.instances)
let transforms: Vec<_> = (1..instances)
.map(|i| {
let d = data.distance * (i as f64);
let d = distance * (i as f64);
let translate = (normalized_axis * d).map(LengthUnit);
vec![Transform {
translate,
@ -828,7 +839,7 @@ async fn inner_pattern_linear_3d(
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct CircularPattern2dData {
struct CircularPattern2dData {
/// The number of total instances. Must be greater than or equal to 1.
/// This includes the original entity. For example, if instances is 2,
/// there will be two copies -- the original, and one new copy.
@ -870,7 +881,7 @@ pub struct CircularPattern3dData {
pub use_original: Option<bool>,
}
pub enum CircularPattern {
enum CircularPattern {
ThreeD(CircularPattern3dData),
TwoD(CircularPattern2dData),
}
@ -941,9 +952,24 @@ impl CircularPattern {
/// A circular pattern on a 2D sketch.
pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch_set): (CircularPattern2dData, SketchSet) = args.get_data_and_sketch_set()?;
let sketch_set: SketchSet = args.get_unlabeled_kw_arg("sketchSet")?;
let instances: u32 = args.get_kw_arg("instances")?;
let center: [f64; 2] = args.get_kw_arg("center")?;
let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?;
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let sketches = inner_pattern_circular_2d(data, sketch_set, exec_state, args).await?;
let sketches = inner_pattern_circular_2d(
sketch_set,
instances,
center,
arc_degrees,
rotate_duplicates,
use_original,
exec_state,
args,
)
.await?;
Ok(sketches.into())
}
@ -959,21 +985,36 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu
/// |> line(end = [-1, 0])
/// |> line(end = [0, -5])
/// |> close()
/// |> patternCircular2d({
/// |> patternCircular2d(
/// center = [0, 0],
/// instances = 13,
/// arcDegrees = 360,
/// rotateDuplicates = true
/// }, %)
/// )
///
/// example = extrude(exampleSketch, length = 1)
/// ```
#[stdlib {
name = "patternCircular2d",
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "Which sketch(es) to pattern" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect."},
center = { docs = "The center about which to make the pattern. This is a 2D vector."},
arc_degrees = { docs = "The arc angle (in degrees) to place the repetitions. Must be greater than 0."},
rotate_duplicates= { docs = "Whether or not to rotate the duplicates as they are copied."},
use_original= { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false."},
}
}]
#[allow(clippy::too_many_arguments)]
async fn inner_pattern_circular_2d(
data: CircularPattern2dData,
sketch_set: SketchSet,
instances: u32,
center: [f64; 2],
arc_degrees: f64,
rotate_duplicates: bool,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
@ -982,6 +1023,13 @@ async fn inner_pattern_circular_2d(
if args.ctx.context_type == crate::execution::ContextType::Mock {
return Ok(starting_sketches);
}
let data = CircularPattern2dData {
instances,
center,
arc_degrees,
rotate_duplicates,
use_original,
};
let mut sketches = Vec::new();
for sketch in starting_sketches.iter() {
@ -1008,9 +1056,36 @@ async fn inner_pattern_circular_2d(
/// A circular pattern on a 3D model.
pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid_set): (CircularPattern3dData, SolidSet) = args.get_data_and_solid_set()?;
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
// The number of total instances. Must be greater than or equal to 1.
// This includes the original entity. For example, if instances is 2,
// there will be two copies -- the original, and one new copy.
// If instances is 1, this has no effect.
let instances: u32 = args.get_kw_arg("instances")?;
// The axis around which to make the pattern. This is a 3D vector.
let axis: [f64; 3] = args.get_kw_arg("axis")?;
// The center about which to make the pattern. This is a 3D vector.
let center: [f64; 3] = args.get_kw_arg("center")?;
// The arc angle (in degrees) to place the repetitions. Must be greater than 0.
let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?;
// Whether or not to rotate the duplicates as they are copied.
let rotate_duplicates: bool = args.get_kw_arg("rotateDuplicates")?;
// If the target being patterned is itself a pattern, then, should you use the original solid,
// or the pattern?
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let solids = inner_pattern_circular_3d(data, solid_set, exec_state, args).await?;
let solids = inner_pattern_circular_3d(
solid_set,
instances,
axis,
center,
arc_degrees,
rotate_duplicates,
use_original,
exec_state,
args,
)
.await?;
Ok(solids.into())
}
@ -1024,21 +1099,38 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
/// |> circle({ center = [0, 0], radius = 1 }, %)
///
/// example = extrude(exampleSketch, length = -5)
/// |> patternCircular3d({
/// |> patternCircular3d(
/// axis = [1, -1, 0],
/// center = [10, -20, 0],
/// instances = 11,
/// arcDegrees = 360,
/// rotateDuplicates = true
/// }, %)
/// )
/// ```
#[stdlib {
name = "patternCircular3d",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "Which solid(s) to pattern" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect."},
axis = { docs = "The axis around which to make the pattern. This is a 3D vector"},
center = { docs = "The center about which to make the pattern. This is a 3D vector."},
arc_degrees = { docs = "The arc angle (in degrees) to place the repetitions. Must be greater than 0."},
rotate_duplicates= { docs = "Whether or not to rotate the duplicates as they are copied."},
use_original= { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false."},
}
}]
#[allow(clippy::too_many_arguments)]
async fn inner_pattern_circular_3d(
data: CircularPattern3dData,
solid_set: SolidSet,
instances: u32,
axis: [f64; 3],
center: [f64; 3],
arc_degrees: f64,
rotate_duplicates: bool,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Solid>>, KclError> {
@ -1055,6 +1147,14 @@ async fn inner_pattern_circular_3d(
}
let mut solids = Vec::new();
let data = CircularPattern3dData {
instances,
axis,
center,
arc_degrees,
rotate_duplicates,
use_original,
};
for solid in starting_solids.iter() {
let geometries = pattern_circular(
CircularPattern::ThreeD(data.clone()),

View File

@ -334,8 +334,25 @@ impl CallExpressionKw {
.iter()
.map(|arg| arg.recast(options, indentation_level, ctxt)),
);
let args = arg_list.join(", ");
format!("{indent}{name}({args})")
let args = arg_list.clone().join(", ");
if arg_list.len() >= 4 {
let inner_indentation = if ctxt == ExprContext::Pipe {
options.get_indentation_offset_pipe(indentation_level + 1)
} else {
options.get_indentation(indentation_level + 1)
};
let mut args = arg_list.join(&format!(",\n{inner_indentation}"));
args.push(',');
let args = args;
let end_indent = if ctxt == ExprContext::Pipe {
options.get_indentation_offset_pipe(indentation_level)
} else {
options.get_indentation(indentation_level)
};
format!("{indent}{name}(\n{inner_indentation}{args}\n{end_indent})")
} else {
format!("{indent}{name}({args})")
}
}
}
@ -1031,13 +1048,13 @@ sphere = startSketchOn('XZ')
}, %)
|> close()
|> revolve({ axis: 'x' }, %)
|> patternCircular3d({
|> patternCircular3d(
axis = [0, 0, 1],
center = [0, 0, 0],
repetitions = 10,
arcDegrees = 360,
rotateDuplicates = true
}, %)
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
@ -1098,13 +1115,13 @@ sphere = startSketchOn('XZ')
}, %)
|> close()
|> revolve({ axis = 'x' }, %)
|> patternCircular3d({
|> patternCircular3d(
axis = [0, 0, 1],
center = [0, 0, 0],
repetitions = 10,
arcDegrees = 360,
rotateDuplicates = true
}, %)
rotateDuplicates = true,
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
@ -1417,11 +1434,11 @@ tabs_r = startSketchOn({
radius = hole_diam / 2
}, %), %)
|> extrude(-thk, %)
|> patternLinear3d({
|> patternLinear3d(
axis = [0, -1, 0],
repetitions = 1,
distance = length - 10
}, %)
)
// build the tabs of the mounting bracket (left side)
tabs_l = startSketchOn({
plane: {
@ -1444,11 +1461,7 @@ tabs_l = startSketchOn({
radius = hole_diam / 2
}, %), %)
|> extrude(-thk, %)
|> patternLinear3d({
axis = [0, -1, 0],
repetitions = 1,
distance = length - 10
}, %)
|> patternLinear3d(axis = [0, -1, 0], repetitions = 1, distance = length - 10)
"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
@ -1542,11 +1555,7 @@ tabs_r = startSketchOn({
radius = hole_diam / 2
}, %), %)
|> extrude(-thk, %)
|> patternLinear3d({
axis = [0, -1, 0],
repetitions = 1,
distance = length - 10
}, %)
|> patternLinear3d(axis = [0, -1, 0], repetitions = 1, distance = length - 10)
// build the tabs of the mounting bracket (left side)
tabs_l = startSketchOn({
plane = {
@ -1569,11 +1578,7 @@ tabs_l = startSketchOn({
radius = hole_diam / 2
}, %), %)
|> extrude(-thk, %)
|> patternLinear3d({
axis = [0, -1, 0],
repetitions = 1,
distance = length - 10
}, %)
|> patternLinear3d(axis = [0, -1, 0], repetitions = 1, distance = length - 10)
"#
);
}

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing big_number_angle_to_match_length_x.kcl
snapshot_kind: text
---
{
"Ok": {

View File

@ -631,7 +631,7 @@ snapshot_kind: text
"cmdId": "[uuid]",
"range": [
189,
276,
277,
0
],
"command": {
@ -819,8 +819,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {
@ -844,8 +844,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {
@ -869,8 +869,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {
@ -894,8 +894,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {
@ -919,8 +919,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {
@ -944,8 +944,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {
@ -969,8 +969,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
430,
288,
432,
0
],
"command": {

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing circular_pattern3d_a_pattern.kcl
snapshot_kind: text
---
{
"Ok": {
@ -321,7 +322,7 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
},
{
"declaration": {
"end": 276,
"end": 277,
"id": {
"end": 186,
"name": "pattn1",
@ -331,115 +332,88 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
"init": {
"arguments": [
{
"end": 260,
"properties": [
{
"end": 225,
"key": {
"end": 213,
"name": "axis",
"start": 209,
"type": "Identifier"
},
"start": 209,
"type": "ObjectProperty",
"value": {
"elements": [
{
"end": 218,
"raw": "1",
"start": 217,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 221,
"raw": "0",
"start": 220,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 224,
"raw": "0",
"start": 223,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 225,
"start": 216,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 242,
"key": {
"end": 238,
"name": "instances",
"start": 229,
"type": "Identifier"
},
"start": 229,
"type": "ObjectProperty",
"value": {
"end": 242,
"raw": "7",
"start": 241,
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "axis"
},
"arg": {
"elements": [
{
"end": 234,
"raw": "1",
"start": 233,
"type": "Literal",
"type": "Literal",
"value": {
"value": 7.0,
"value": 1.0,
"suffix": "None"
}
}
},
{
"end": 258,
"key": {
"end": 254,
"name": "distance",
"start": 246,
"type": "Identifier"
},
"start": 246,
"type": "ObjectProperty",
"value": {
"end": 258,
"raw": "6",
"start": 257,
{
"end": 237,
"raw": "0",
"start": 236,
"type": "Literal",
"type": "Literal",
"value": {
"value": 6.0,
"value": 0.0,
"suffix": "None"
}
},
{
"end": 240,
"raw": "0",
"start": 239,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
}
],
"start": 205,
"type": "ObjectExpression",
"type": "ObjectExpression"
],
"end": 241,
"start": 232,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 275,
"name": "exampleSketch",
"start": 262,
"type": "Identifier",
"type": "Identifier"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "instances"
},
"arg": {
"end": 258,
"raw": "7",
"start": 257,
"type": "Literal",
"type": "Literal",
"value": {
"value": 7.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "distance"
},
"arg": {
"end": 274,
"raw": "6",
"start": 273,
"type": "Literal",
"type": "Literal",
"value": {
"value": 6.0,
"suffix": "None"
}
}
}
],
"callee": {
@ -448,15 +422,22 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
"start": 189,
"type": "Identifier"
},
"end": 276,
"end": 277,
"start": 189,
"type": "CallExpression",
"type": "CallExpression"
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"end": 221,
"name": "exampleSketch",
"start": 208,
"type": "Identifier",
"type": "Identifier"
}
},
"start": 180,
"type": "VariableDeclarator"
},
"end": 276,
"end": 277,
"kind": "const",
"start": 180,
"type": "VariableDeclaration",
@ -464,241 +445,213 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
},
{
"declaration": {
"end": 430,
"end": 432,
"id": {
"end": 284,
"end": 285,
"name": "pattn2",
"start": 278,
"start": 279,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 421,
"properties": [
{
"end": 325,
"key": {
"end": 313,
"name": "axis",
"start": 309,
"type": "Identifier"
},
"start": 309,
"type": "ObjectProperty",
"value": {
"elements": [
{
"end": 318,
"raw": "0",
"start": 317,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 321,
"raw": "0",
"start": 320,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 324,
"raw": "1",
"start": 323,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 325,
"start": 316,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 353,
"key": {
"end": 335,
"name": "center",
"start": 329,
"type": "Identifier"
},
"start": 329,
"type": "ObjectProperty",
"value": {
"elements": [
{
"argument": {
"end": 342,
"raw": "20",
"start": 340,
"type": "Literal",
"type": "Literal",
"value": {
"value": 20.0,
"suffix": "None"
}
},
"end": 342,
"operator": "-",
"start": 339,
"type": "UnaryExpression",
"type": "UnaryExpression"
},
{
"argument": {
"end": 347,
"raw": "20",
"start": 345,
"type": "Literal",
"type": "Literal",
"value": {
"value": 20.0,
"suffix": "None"
}
},
"end": 347,
"operator": "-",
"start": 344,
"type": "UnaryExpression",
"type": "UnaryExpression"
},
{
"argument": {
"end": 352,
"raw": "20",
"start": 350,
"type": "Literal",
"type": "Literal",
"value": {
"value": 20.0,
"suffix": "None"
}
},
"end": 352,
"operator": "-",
"start": 349,
"type": "UnaryExpression",
"type": "UnaryExpression"
}
],
"end": 353,
"start": 338,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 371,
"key": {
"end": 366,
"name": "instances",
"start": 357,
"type": "Identifier"
},
"start": 357,
"type": "ObjectProperty",
"value": {
"end": 371,
"raw": "41",
"start": 369,
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "axis"
},
"arg": {
"elements": [
{
"end": 328,
"raw": "0",
"start": 327,
"type": "Literal",
"type": "Literal",
"value": {
"value": 41.0,
"value": 0.0,
"suffix": "None"
}
}
},
{
"end": 391,
"key": {
"end": 385,
"name": "arcDegrees",
"start": 375,
"type": "Identifier"
},
"start": 375,
"type": "ObjectProperty",
"value": {
"end": 391,
"raw": "360",
"start": 388,
{
"end": 331,
"raw": "0",
"start": 330,
"type": "Literal",
"type": "Literal",
"value": {
"value": 360.0,
"value": 0.0,
"suffix": "None"
}
},
{
"end": 334,
"raw": "1",
"start": 333,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
"end": 419,
"key": {
"end": 411,
"name": "rotateDuplicates",
"start": 395,
"type": "Identifier"
},
"start": 395,
"type": "ObjectProperty",
"value": {
"end": 419,
"raw": "false",
"start": 414,
"type": "Literal",
"type": "Literal",
"value": false
}
}
],
"start": 305,
"type": "ObjectExpression",
"type": "ObjectExpression"
],
"end": 335,
"start": 326,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 429,
"name": "pattn1",
"start": 423,
"type": "Identifier",
"type": "Identifier"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "center"
},
"arg": {
"elements": [
{
"argument": {
"end": 352,
"raw": "20",
"start": 350,
"type": "Literal",
"type": "Literal",
"value": {
"value": 20.0,
"suffix": "None"
}
},
"end": 352,
"operator": "-",
"start": 349,
"type": "UnaryExpression",
"type": "UnaryExpression"
},
{
"argument": {
"end": 357,
"raw": "20",
"start": 355,
"type": "Literal",
"type": "Literal",
"value": {
"value": 20.0,
"suffix": "None"
}
},
"end": 357,
"operator": "-",
"start": 354,
"type": "UnaryExpression",
"type": "UnaryExpression"
},
{
"argument": {
"end": 362,
"raw": "20",
"start": 360,
"type": "Literal",
"type": "Literal",
"value": {
"value": 20.0,
"suffix": "None"
}
},
"end": 362,
"operator": "-",
"start": 359,
"type": "UnaryExpression",
"type": "UnaryExpression"
}
],
"end": 363,
"start": 348,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "instances"
},
"arg": {
"end": 381,
"raw": "41",
"start": 379,
"type": "Literal",
"type": "Literal",
"value": {
"value": 41.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "arcDegrees"
},
"arg": {
"end": 401,
"raw": "360",
"start": 398,
"type": "Literal",
"type": "Literal",
"value": {
"value": 360.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "rotateDuplicates"
},
"arg": {
"end": 429,
"raw": "false",
"start": 424,
"type": "Literal",
"type": "Literal",
"value": false
}
}
],
"callee": {
"end": 304,
"end": 305,
"name": "patternCircular3d",
"start": 287,
"start": 288,
"type": "Identifier"
},
"end": 430,
"start": 287,
"type": "CallExpression",
"type": "CallExpression"
"end": 432,
"start": 288,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"end": 315,
"name": "pattn1",
"start": 309,
"type": "Identifier",
"type": "Identifier"
}
},
"start": 278,
"start": 279,
"type": "VariableDeclarator"
},
"end": 430,
"end": 432,
"kind": "const",
"start": 278,
"start": 279,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 431,
"end": 433,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [
@ -713,8 +666,8 @@ description: Result of parsing circular_pattern3d_a_pattern.kcl
],
"1": [
{
"end": 278,
"start": 276,
"end": 279,
"start": 277,
"type": "NonCodeNode",
"value": {
"type": "newLine"

View File

@ -6,16 +6,18 @@ exampleSketch = startSketchOn('XZ')
|> close(%)
|> extrude(length = 1)
pattn1 = patternLinear3d({
pattn1 = patternLinear3d(
exampleSketch,
axis = [1, 0, 0],
instances = 7,
distance = 6
}, exampleSketch)
distance = 6,
)
pattn2 = patternCircular3d({
pattn2 = patternCircular3d(
pattn1,
axis = [0, 0, 1],
center = [-20, -20, -20],
instances = 41,
arcDegrees = 360,
rotateDuplicates = false
}, pattn1)
rotateDuplicates = false,
)

View File

@ -44,17 +44,24 @@ snapshot_kind: text
},
{
"labeledArgs": {
"data": {
"axis": {
"sourceRange": [
205,
260,
232,
241,
0
]
},
"solid_set": {
"distance": {
"sourceRange": [
262,
275,
273,
274,
0
]
},
"instances": {
"sourceRange": [
257,
258,
0
]
}
@ -62,24 +69,51 @@ snapshot_kind: text
"name": "patternLinear3d",
"sourceRange": [
189,
276,
277,
0
],
"type": "StdLibCall",
"unlabeledArg": null
"unlabeledArg": {
"sourceRange": [
208,
221,
0
]
}
},
{
"labeledArgs": {
"data": {
"arcDegrees": {
"sourceRange": [
305,
421,
398,
401,
0
]
},
"solid_set": {
"axis": {
"sourceRange": [
423,
326,
335,
0
]
},
"center": {
"sourceRange": [
348,
363,
0
]
},
"instances": {
"sourceRange": [
379,
381,
0
]
},
"rotateDuplicates": {
"sourceRange": [
424,
429,
0
]
@ -87,11 +121,17 @@ snapshot_kind: text
},
"name": "patternCircular3d",
"sourceRange": [
287,
430,
288,
432,
0
],
"type": "StdLibCall",
"unlabeledArg": null
"unlabeledArg": {
"sourceRange": [
309,
315,
0
]
}
}
]

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Artifact commands helix_simple.kcl
snapshot_kind: text
---
[
{
@ -383,7 +384,7 @@ description: Artifact commands helix_simple.kcl
"cmdId": "[uuid]",
"range": [
151,
242,
257,
0
],
"command": {

View File

@ -5,7 +5,7 @@ flowchart LR
3["Segment<br>[102, 137, 0]"]
end
1["Plane<br>[46, 65, 0]"]
4["Helix<br>[151, 242, 0]"]
4["Helix<br>[151, 257, 0]"]
1 --- 2
2 --- 3
3 <--x 4

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing helix_simple.kcl
snapshot_kind: text
---
{
"Ok": {
@ -171,7 +172,7 @@ description: Result of parsing helix_simple.kcl
},
{
"declaration": {
"end": 242,
"end": 257,
"id": {
"end": 148,
"name": "helixPath",
@ -187,9 +188,9 @@ description: Result of parsing helix_simple.kcl
"name": "angleStart"
},
"arg": {
"end": 171,
"end": 174,
"raw": "0",
"start": 170,
"start": 173,
"type": "Literal",
"type": "Literal",
"value": {
@ -205,9 +206,9 @@ description: Result of parsing helix_simple.kcl
"name": "ccw"
},
"arg": {
"end": 183,
"end": 188,
"raw": "true",
"start": 179,
"start": 184,
"type": "Literal",
"type": "Literal",
"value": true
@ -220,9 +221,9 @@ description: Result of parsing helix_simple.kcl
"name": "revolutions"
},
"arg": {
"end": 200,
"end": 207,
"raw": "5",
"start": 199,
"start": 206,
"type": "Literal",
"type": "Literal",
"value": {
@ -238,9 +239,9 @@ description: Result of parsing helix_simple.kcl
"name": "length"
},
"arg": {
"end": 213,
"end": 222,
"raw": "10",
"start": 211,
"start": 220,
"type": "Literal",
"type": "Literal",
"value": {
@ -256,9 +257,9 @@ description: Result of parsing helix_simple.kcl
"name": "radius"
},
"arg": {
"end": 225,
"end": 236,
"raw": "5",
"start": 224,
"start": 235,
"type": "Literal",
"type": "Literal",
"value": {
@ -274,9 +275,9 @@ description: Result of parsing helix_simple.kcl
"name": "axis"
},
"arg": {
"end": 241,
"end": 254,
"name": "edge001",
"start": 234,
"start": 247,
"type": "Identifier",
"type": "Identifier"
}
@ -288,7 +289,7 @@ description: Result of parsing helix_simple.kcl
"start": 151,
"type": "Identifier"
},
"end": 242,
"end": 257,
"start": 151,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
@ -297,14 +298,14 @@ description: Result of parsing helix_simple.kcl
"start": 139,
"type": "VariableDeclarator"
},
"end": 242,
"end": 257,
"kind": "const",
"start": 139,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 243,
"end": 258,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [

View File

@ -3,4 +3,11 @@ helper001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %)
|> line(end = [0, 10], tag = $edge001)
helixPath = helix(angleStart = 0, ccw = true, revolutions = 5, length = 10, radius = 5, axis = edge001)
helixPath = helix(
angleStart = 0,
ccw = true,
revolutions = 5,
length = 10,
radius = 5,
axis = edge001,
)

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Operations executed helix_simple.kcl
snapshot_kind: text
---
[
{
@ -26,43 +27,43 @@ description: Operations executed helix_simple.kcl
"labeledArgs": {
"angleStart": {
"sourceRange": [
170,
171,
173,
174,
0
]
},
"axis": {
"sourceRange": [
234,
241,
247,
254,
0
]
},
"ccw": {
"sourceRange": [
179,
183,
184,
188,
0
]
},
"length": {
"sourceRange": [
211,
213,
220,
222,
0
]
},
"radius": {
"sourceRange": [
224,
225,
235,
236,
0
]
},
"revolutions": {
"sourceRange": [
199,
200,
206,
207,
0
]
}
@ -70,7 +71,7 @@ description: Operations executed helix_simple.kcl
"name": "helix",
"sourceRange": [
151,
242,
257,
0
],
"type": "StdLibCall",

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing helix_simple.kcl
snapshot_kind: text
---
{
"environments": [
@ -86,7 +87,7 @@ description: Program memory after executing helix_simple.kcl
{
"sourceRange": [
151,
242,
257,
0
]
}

View File

@ -631,7 +631,7 @@ snapshot_kind: text
"cmdId": "[uuid]",
"range": [
189,
276,
277,
0
],
"command": {
@ -819,8 +819,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {
@ -1008,8 +1008,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {
@ -1197,8 +1197,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {
@ -1386,8 +1386,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {
@ -1575,8 +1575,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {
@ -1764,8 +1764,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {
@ -1953,8 +1953,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
287,
367,
288,
369,
0
],
"command": {

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing linear_pattern3d_a_pattern.kcl
snapshot_kind: text
---
{
"Ok": {
@ -321,7 +322,7 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
},
{
"declaration": {
"end": 276,
"end": 277,
"id": {
"end": 186,
"name": "pattn1",
@ -331,115 +332,88 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
"init": {
"arguments": [
{
"end": 260,
"properties": [
{
"end": 225,
"key": {
"end": 213,
"name": "axis",
"start": 209,
"type": "Identifier"
},
"start": 209,
"type": "ObjectProperty",
"value": {
"elements": [
{
"end": 218,
"raw": "1",
"start": 217,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 221,
"raw": "0",
"start": 220,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 224,
"raw": "0",
"start": 223,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 225,
"start": 216,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 242,
"key": {
"end": 238,
"name": "instances",
"start": 229,
"type": "Identifier"
},
"start": 229,
"type": "ObjectProperty",
"value": {
"end": 242,
"raw": "7",
"start": 241,
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "axis"
},
"arg": {
"elements": [
{
"end": 234,
"raw": "1",
"start": 233,
"type": "Literal",
"type": "Literal",
"value": {
"value": 7.0,
"value": 1.0,
"suffix": "None"
}
}
},
{
"end": 258,
"key": {
"end": 254,
"name": "distance",
"start": 246,
"type": "Identifier"
},
"start": 246,
"type": "ObjectProperty",
"value": {
"end": 258,
"raw": "6",
"start": 257,
{
"end": 237,
"raw": "0",
"start": 236,
"type": "Literal",
"type": "Literal",
"value": {
"value": 6.0,
"value": 0.0,
"suffix": "None"
}
},
{
"end": 240,
"raw": "0",
"start": 239,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
}
],
"start": 205,
"type": "ObjectExpression",
"type": "ObjectExpression"
],
"end": 241,
"start": 232,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 275,
"name": "exampleSketch",
"start": 262,
"type": "Identifier",
"type": "Identifier"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "instances"
},
"arg": {
"end": 258,
"raw": "7",
"start": 257,
"type": "Literal",
"type": "Literal",
"value": {
"value": 7.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "distance"
},
"arg": {
"end": 274,
"raw": "6",
"start": 273,
"type": "Literal",
"type": "Literal",
"value": {
"value": 6.0,
"suffix": "None"
}
}
}
],
"callee": {
@ -448,15 +422,22 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
"start": 189,
"type": "Identifier"
},
"end": 276,
"end": 277,
"start": 189,
"type": "CallExpression",
"type": "CallExpression"
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"end": 221,
"name": "exampleSketch",
"start": 208,
"type": "Identifier",
"type": "Identifier"
}
},
"start": 180,
"type": "VariableDeclarator"
},
"end": 276,
"end": 277,
"kind": "const",
"start": 180,
"type": "VariableDeclaration",
@ -464,84 +445,49 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
},
{
"declaration": {
"end": 367,
"end": 369,
"id": {
"end": 284,
"end": 285,
"name": "pattn2",
"start": 278,
"start": 279,
"type": "Identifier"
},
"init": {
"arguments": [
{
"end": 358,
"properties": [
{
"end": 323,
"key": {
"end": 311,
"name": "axis",
"start": 307,
"type": "Identifier"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "axis"
},
"arg": {
"elements": [
{
"end": 326,
"raw": "0",
"start": 325,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
"start": 307,
"type": "ObjectProperty",
"value": {
"elements": [
{
"end": 316,
"raw": "0",
"start": 315,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 319,
"raw": "0",
"start": 318,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 322,
"raw": "1",
"start": 321,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 323,
"start": 314,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 339,
"key": {
"end": 335,
"name": "distance",
"start": 327,
"type": "Identifier"
{
"end": 329,
"raw": "0",
"start": 328,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
"start": 327,
"type": "ObjectProperty",
"value": {
"end": 339,
{
"end": 332,
"raw": "1",
"start": 338,
"start": 331,
"type": "Literal",
"type": "Literal",
"value": {
@ -549,64 +495,79 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
"suffix": "None"
}
}
},
{
"end": 356,
"key": {
"end": 352,
"name": "instances",
"start": 343,
"type": "Identifier"
},
"start": 343,
"type": "ObjectProperty",
"value": {
"end": 356,
"raw": "7",
"start": 355,
"type": "Literal",
"type": "Literal",
"value": {
"value": 7.0,
"suffix": "None"
}
}
}
],
"start": 303,
"type": "ObjectExpression",
"type": "ObjectExpression"
],
"end": 333,
"start": 324,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"end": 366,
"name": "pattn1",
"start": 360,
"type": "Identifier",
"type": "Identifier"
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "distance"
},
"arg": {
"end": 349,
"raw": "1",
"start": 348,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
"type": "LabeledArg",
"label": {
"type": "Identifier",
"name": "instances"
},
"arg": {
"end": 366,
"raw": "7",
"start": 365,
"type": "Literal",
"type": "Literal",
"value": {
"value": 7.0,
"suffix": "None"
}
}
}
],
"callee": {
"end": 302,
"end": 303,
"name": "patternLinear3d",
"start": 287,
"start": 288,
"type": "Identifier"
},
"end": 367,
"start": 287,
"type": "CallExpression",
"type": "CallExpression"
"end": 369,
"start": 288,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"end": 313,
"name": "pattn1",
"start": 307,
"type": "Identifier",
"type": "Identifier"
}
},
"start": 278,
"start": 279,
"type": "VariableDeclarator"
},
"end": 367,
"end": 369,
"kind": "const",
"start": 278,
"start": 279,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"end": 368,
"end": 370,
"nonCodeMeta": {
"nonCodeNodes": {
"0": [
@ -621,8 +582,8 @@ description: Result of parsing linear_pattern3d_a_pattern.kcl
],
"1": [
{
"end": 278,
"start": 276,
"end": 279,
"start": 277,
"type": "NonCodeNode",
"value": {
"type": "newLine"

View File

@ -6,14 +6,16 @@ exampleSketch = startSketchOn('XZ')
|> close(%)
|> extrude(length = 1)
pattn1 = patternLinear3d({
pattn1 = patternLinear3d(
exampleSketch,
axis = [1, 0, 0],
instances = 7,
distance = 6
}, exampleSketch)
distance = 6,
)
pattn2 = patternLinear3d({
pattn2 = patternLinear3d(
pattn1,
axis = [0, 0, 1],
distance = 1,
instances = 7
}, pattn1)
instances = 7,
)

View File

@ -44,17 +44,24 @@ snapshot_kind: text
},
{
"labeledArgs": {
"data": {
"axis": {
"sourceRange": [
205,
260,
232,
241,
0
]
},
"solid_set": {
"distance": {
"sourceRange": [
262,
275,
273,
274,
0
]
},
"instances": {
"sourceRange": [
257,
258,
0
]
}
@ -62,24 +69,37 @@ snapshot_kind: text
"name": "patternLinear3d",
"sourceRange": [
189,
276,
277,
0
],
"type": "StdLibCall",
"unlabeledArg": null
"unlabeledArg": {
"sourceRange": [
208,
221,
0
]
}
},
{
"labeledArgs": {
"data": {
"axis": {
"sourceRange": [
303,
358,
324,
333,
0
]
},
"solid_set": {
"distance": {
"sourceRange": [
360,
348,
349,
0
]
},
"instances": {
"sourceRange": [
365,
366,
0
]
@ -87,11 +107,17 @@ snapshot_kind: text
},
"name": "patternLinear3d",
"sourceRange": [
287,
367,
288,
369,
0
],
"type": "StdLibCall",
"unlabeledArg": null
"unlabeledArg": {
"sourceRange": [
307,
313,
0
]
}
}
]

View File

@ -426,7 +426,7 @@ snapshot_kind: text
"cmdId": "[uuid]",
"range": [
356,
426,
448,
0
],
"command": {
@ -446,8 +446,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
432,
440,
454,
462,
0
],
"command": {
@ -458,8 +458,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
432,
440,
454,
462,
0
],
"command": {
@ -469,8 +469,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -489,8 +489,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -503,8 +503,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -514,8 +514,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -526,8 +526,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -539,8 +539,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -553,8 +553,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -567,8 +567,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -581,8 +581,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -595,8 +595,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -609,8 +609,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -623,8 +623,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -637,8 +637,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -651,8 +651,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
585,
607,
629,
0
],
"command": {
@ -665,8 +665,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
492,
534,
514,
556,
0
],
"command": {
@ -681,8 +681,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
540,
627,
562,
649,
0
],
"command": {
@ -697,8 +697,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
633,
684,
655,
706,
0
],
"command": {
@ -713,8 +713,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
736,
770,
758,
792,
0
],
"command": {
@ -729,8 +729,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
736,
770,
758,
792,
0
],
"command": {
@ -740,8 +740,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
736,
770,
758,
792,
0
],
"command": {
@ -757,8 +757,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
776,
824,
798,
846,
0
],
"command": {
@ -778,8 +778,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
830,
931,
852,
953,
0
],
"command": {
@ -799,8 +799,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
937,
1057,
959,
1079,
0
],
"command": {
@ -820,8 +820,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1063,
1119,
1085,
1141,
0
],
"command": {
@ -841,8 +841,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1125,
1133,
1147,
1155,
0
],
"command": {
@ -853,8 +853,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1184,
1219,
1206,
1241,
0
],
"command": {
@ -869,8 +869,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1184,
1219,
1206,
1241,
0
],
"command": {
@ -880,8 +880,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1184,
1219,
1206,
1241,
0
],
"command": {
@ -897,8 +897,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1225,
1273,
1247,
1295,
0
],
"command": {
@ -918,8 +918,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1279,
1381,
1301,
1403,
0
],
"command": {
@ -939,8 +939,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1387,
1507,
1409,
1529,
0
],
"command": {
@ -960,8 +960,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1513,
1569,
1535,
1591,
0
],
"command": {
@ -981,8 +981,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1575,
1583,
1597,
1605,
0
],
"command": {
@ -993,8 +993,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1009,8 +1009,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1023,8 +1023,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1034,8 +1034,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1046,8 +1046,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1059,8 +1059,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1073,8 +1073,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1087,8 +1087,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1101,8 +1101,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1115,8 +1115,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1129,8 +1129,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1143,8 +1143,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1157,8 +1157,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {

View File

@ -5,30 +5,30 @@ flowchart LR
3["Segment<br>[105, 154, 0]"]
4["Segment<br>[160, 247, 0]"]
5["Segment<br>[253, 350, 0]"]
6["Segment<br>[356, 426, 0]"]
7["Segment<br>[432, 440, 0]"]
6["Segment<br>[356, 448, 0]"]
7["Segment<br>[454, 462, 0]"]
8[Solid2d]
end
subgraph path27 [Path]
27["Path<br>[736, 770, 0]"]
28["Segment<br>[776, 824, 0]"]
29["Segment<br>[830, 931, 0]"]
30["Segment<br>[937, 1057, 0]"]
31["Segment<br>[1063, 1119, 0]"]
32["Segment<br>[1125, 1133, 0]"]
27["Path<br>[758, 792, 0]"]
28["Segment<br>[798, 846, 0]"]
29["Segment<br>[852, 953, 0]"]
30["Segment<br>[959, 1079, 0]"]
31["Segment<br>[1085, 1141, 0]"]
32["Segment<br>[1147, 1155, 0]"]
33[Solid2d]
end
subgraph path34 [Path]
34["Path<br>[1184, 1219, 0]"]
35["Segment<br>[1225, 1273, 0]"]
36["Segment<br>[1279, 1381, 0]"]
37["Segment<br>[1387, 1507, 0]"]
38["Segment<br>[1513, 1569, 0]"]
39["Segment<br>[1575, 1583, 0]"]
34["Path<br>[1206, 1241, 0]"]
35["Segment<br>[1247, 1295, 0]"]
36["Segment<br>[1301, 1403, 0]"]
37["Segment<br>[1409, 1529, 0]"]
38["Segment<br>[1535, 1591, 0]"]
39["Segment<br>[1597, 1605, 0]"]
40[Solid2d]
end
1["Plane<br>[12, 31, 0]"]
9["Sweep Extrusion<br>[454, 486, 0]"]
9["Sweep Extrusion<br>[476, 508, 0]"]
10[Wall]
11[Wall]
12[Wall]
@ -43,10 +43,10 @@ flowchart LR
21["SweepEdge Adjacent"]
22["SweepEdge Opposite"]
23["SweepEdge Adjacent"]
24["EdgeCut Fillet<br>[492, 534, 0]"]
25["Plane<br>[1184, 1219, 0]"]
26["Plane<br>[736, 770, 0]"]
41["Sweep Extrusion<br>[1597, 1628, 0]"]
24["EdgeCut Fillet<br>[514, 556, 0]"]
25["Plane<br>[1206, 1241, 0]"]
26["Plane<br>[758, 792, 0]"]
41["Sweep Extrusion<br>[1619, 1650, 0]"]
42[Wall]
43[Wall]
44[Wall]

View File

@ -27,23 +27,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
482,
485,
504,
507,
0
]
}
},
"name": "extrude",
"sourceRange": [
454,
486,
476,
508,
0
],
"type": "StdLibCall",
"unlabeledArg": {
"sourceRange": [
462,
471,
484,
493,
0
]
}
@ -52,23 +52,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
499,
530,
521,
552,
0
]
},
"solid": {
"sourceRange": [
532,
533,
554,
555,
0
]
}
},
"name": "fillet",
"sourceRange": [
492,
534,
514,
556,
0
],
"type": "StdLibCall",
@ -78,30 +78,30 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
548,
615,
570,
637,
0
]
},
"solid": {
"sourceRange": [
617,
618,
639,
640,
0
]
},
"tag": {
"sourceRange": [
620,
626,
642,
648,
0
]
}
},
"name": "chamfer",
"sourceRange": [
540,
627,
562,
649,
0
],
"type": "StdLibCall",
@ -111,30 +111,30 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
641,
672,
663,
694,
0
]
},
"solid": {
"sourceRange": [
674,
675,
696,
697,
0
]
},
"tag": {
"sourceRange": [
677,
683,
699,
705,
0
]
}
},
"name": "chamfer",
"sourceRange": [
633,
684,
655,
706,
0
],
"type": "StdLibCall",
@ -144,23 +144,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
712,
722,
734,
744,
0
]
},
"tag": {
"sourceRange": [
724,
729,
746,
751,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
698,
730,
720,
752,
0
],
"type": "StdLibCall",
@ -170,23 +170,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
1160,
1170,
1182,
1192,
0
]
},
"tag": {
"sourceRange": [
1172,
1177,
1194,
1199,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
1146,
1178,
1168,
1200,
0
],
"type": "StdLibCall",
@ -196,23 +196,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
1625,
1627,
1647,
1649,
0
]
}
},
"name": "extrude",
"sourceRange": [
1597,
1628,
1619,
1650,
0
],
"type": "StdLibCall",
"unlabeledArg": {
"sourceRange": [
1605,
1614,
1627,
1636,
0
]
}

View File

@ -426,7 +426,7 @@ snapshot_kind: text
"cmdId": "[uuid]",
"range": [
356,
426,
448,
0
],
"command": {
@ -446,8 +446,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
432,
440,
454,
462,
0
],
"command": {
@ -458,8 +458,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
432,
440,
454,
462,
0
],
"command": {
@ -469,8 +469,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -489,8 +489,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -503,8 +503,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -514,8 +514,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -526,8 +526,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -539,8 +539,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -553,8 +553,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -567,8 +567,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -581,8 +581,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -595,8 +595,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -609,8 +609,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -623,8 +623,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -637,8 +637,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
454,
486,
476,
508,
0
],
"command": {
@ -651,8 +651,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
642,
664,
686,
0
],
"command": {
@ -665,8 +665,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
492,
534,
514,
556,
0
],
"command": {
@ -681,8 +681,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
540,
591,
562,
613,
0
],
"command": {
@ -697,8 +697,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
597,
684,
619,
706,
0
],
"command": {
@ -713,8 +713,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
736,
770,
758,
792,
0
],
"command": {
@ -729,8 +729,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
736,
770,
758,
792,
0
],
"command": {
@ -740,8 +740,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
736,
770,
758,
792,
0
],
"command": {
@ -757,8 +757,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
776,
824,
798,
846,
0
],
"command": {
@ -778,8 +778,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
830,
931,
852,
953,
0
],
"command": {
@ -799,8 +799,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
937,
1057,
959,
1079,
0
],
"command": {
@ -820,8 +820,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1063,
1119,
1085,
1141,
0
],
"command": {
@ -841,8 +841,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1125,
1133,
1147,
1155,
0
],
"command": {
@ -853,8 +853,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1184,
1219,
1206,
1241,
0
],
"command": {
@ -869,8 +869,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1184,
1219,
1206,
1241,
0
],
"command": {
@ -880,8 +880,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1184,
1219,
1206,
1241,
0
],
"command": {
@ -897,8 +897,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1225,
1273,
1247,
1295,
0
],
"command": {
@ -918,8 +918,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1279,
1381,
1301,
1403,
0
],
"command": {
@ -939,8 +939,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1387,
1507,
1409,
1529,
0
],
"command": {
@ -960,8 +960,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1513,
1569,
1535,
1591,
0
],
"command": {
@ -981,8 +981,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1575,
1583,
1597,
1605,
0
],
"command": {
@ -993,8 +993,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1009,8 +1009,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1023,8 +1023,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1034,8 +1034,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1046,8 +1046,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1059,8 +1059,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1073,8 +1073,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1087,8 +1087,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1101,8 +1101,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1115,8 +1115,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1129,8 +1129,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1143,8 +1143,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {
@ -1157,8 +1157,8 @@ snapshot_kind: text
{
"cmdId": "[uuid]",
"range": [
1597,
1628,
1619,
1650,
0
],
"command": {

View File

@ -5,30 +5,30 @@ flowchart LR
3["Segment<br>[105, 154, 0]"]
4["Segment<br>[160, 247, 0]"]
5["Segment<br>[253, 350, 0]"]
6["Segment<br>[356, 426, 0]"]
7["Segment<br>[432, 440, 0]"]
6["Segment<br>[356, 448, 0]"]
7["Segment<br>[454, 462, 0]"]
8[Solid2d]
end
subgraph path27 [Path]
27["Path<br>[736, 770, 0]"]
28["Segment<br>[776, 824, 0]"]
29["Segment<br>[830, 931, 0]"]
30["Segment<br>[937, 1057, 0]"]
31["Segment<br>[1063, 1119, 0]"]
32["Segment<br>[1125, 1133, 0]"]
27["Path<br>[758, 792, 0]"]
28["Segment<br>[798, 846, 0]"]
29["Segment<br>[852, 953, 0]"]
30["Segment<br>[959, 1079, 0]"]
31["Segment<br>[1085, 1141, 0]"]
32["Segment<br>[1147, 1155, 0]"]
33[Solid2d]
end
subgraph path34 [Path]
34["Path<br>[1184, 1219, 0]"]
35["Segment<br>[1225, 1273, 0]"]
36["Segment<br>[1279, 1381, 0]"]
37["Segment<br>[1387, 1507, 0]"]
38["Segment<br>[1513, 1569, 0]"]
39["Segment<br>[1575, 1583, 0]"]
34["Path<br>[1206, 1241, 0]"]
35["Segment<br>[1247, 1295, 0]"]
36["Segment<br>[1301, 1403, 0]"]
37["Segment<br>[1409, 1529, 0]"]
38["Segment<br>[1535, 1591, 0]"]
39["Segment<br>[1597, 1605, 0]"]
40[Solid2d]
end
1["Plane<br>[12, 31, 0]"]
9["Sweep Extrusion<br>[454, 486, 0]"]
9["Sweep Extrusion<br>[476, 508, 0]"]
10[Wall]
11[Wall]
12[Wall]
@ -43,10 +43,10 @@ flowchart LR
21["SweepEdge Adjacent"]
22["SweepEdge Opposite"]
23["SweepEdge Adjacent"]
24["EdgeCut Fillet<br>[492, 534, 0]"]
25["Plane<br>[736, 770, 0]"]
26["Plane<br>[1184, 1219, 0]"]
41["Sweep Extrusion<br>[1597, 1628, 0]"]
24["EdgeCut Fillet<br>[514, 556, 0]"]
25["Plane<br>[758, 792, 0]"]
26["Plane<br>[1206, 1241, 0]"]
41["Sweep Extrusion<br>[1619, 1650, 0]"]
42[Wall]
43[Wall]
44[Wall]

File diff suppressed because it is too large Load Diff

View File

@ -27,23 +27,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
482,
485,
504,
507,
0
]
}
},
"name": "extrude",
"sourceRange": [
454,
486,
476,
508,
0
],
"type": "StdLibCall",
"unlabeledArg": {
"sourceRange": [
462,
471,
484,
493,
0
]
}
@ -52,23 +52,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
499,
530,
521,
552,
0
]
},
"solid": {
"sourceRange": [
532,
533,
554,
555,
0
]
}
},
"name": "fillet",
"sourceRange": [
492,
534,
514,
556,
0
],
"type": "StdLibCall",
@ -78,30 +78,30 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
548,
579,
570,
601,
0
]
},
"solid": {
"sourceRange": [
581,
582,
603,
604,
0
]
},
"tag": {
"sourceRange": [
584,
590,
606,
612,
0
]
}
},
"name": "chamfer",
"sourceRange": [
540,
591,
562,
613,
0
],
"type": "StdLibCall",
@ -111,30 +111,30 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
605,
672,
627,
694,
0
]
},
"solid": {
"sourceRange": [
674,
675,
696,
697,
0
]
},
"tag": {
"sourceRange": [
677,
683,
699,
705,
0
]
}
},
"name": "chamfer",
"sourceRange": [
597,
684,
619,
706,
0
],
"type": "StdLibCall",
@ -144,23 +144,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
712,
722,
734,
744,
0
]
},
"tag": {
"sourceRange": [
724,
729,
746,
751,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
698,
730,
720,
752,
0
],
"type": "StdLibCall",
@ -170,23 +170,23 @@ snapshot_kind: text
"labeledArgs": {
"data": {
"sourceRange": [
1160,
1170,
1182,
1192,
0
]
},
"tag": {
"sourceRange": [
1172,
1177,
1194,
1199,
0
]
}
},
"name": "startSketchOn",
"sourceRange": [
1146,
1178,
1168,
1200,
0
],
"type": "StdLibCall",
@ -196,23 +196,23 @@ snapshot_kind: text
"labeledArgs": {
"length": {
"sourceRange": [
1625,
1627,
1647,
1649,
0
]
}
},
"name": "extrude",
"sourceRange": [
1597,
1628,
1619,
1650,
0
],
"type": "StdLibCall",
"unlabeledArg": {
"sourceRange": [
1605,
1614,
1627,
1636,
0
]
}

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Result of parsing sketch_on_face_after_fillets_referencing_face.kcl
snapshot_kind: text
---
{
"Ok": {

View File

@ -6,10 +6,18 @@ exampleSketch = startSketchOn('XZ')
|> close()
|> extrude(length = 1)
pattn1 = patternLinear3d({
axis: [1, 0, 0],
instances: 7,
distance: 6
}, exampleSketch)
pattn1 = patternLinear3d(
exampleSketch,
axis = [1, 0, 0],
instances = 7,
distance = 6,
)
pattn2 = patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], instances: 41, arcDegrees: 360, rotateDuplicates: false}, pattn1)
pattn2 = patternCircular3d(
pattn1,
axis = [0,0, 1],
center = [-20, -20, -20],
instances = 41,
arcDegrees = 360,
rotateDuplicates = false,
)

View File

@ -95,11 +95,11 @@ const tabsR = startSketchOn(tabPlane)
getNextAdjacentEdge(edge13)
]
}, %)
|> patternLinear3d({
axis: [0, -1, 0],
instances: 2,
distance: length + 2 * thk - (tabLength * 4 / 3)
}, %)
|> patternLinear3d(
axis = [0, -1, 0],
instances = 2,
distance = length + 2 * thk - (tabLength * 4 / 3)
)
// build the tabs of the mounting bracket (left side)
const tabsL = startSketchOn(tabPlane)
@ -123,11 +123,11 @@ const tabsL = startSketchOn(tabPlane)
getNextAdjacentEdge(edge22)
]
}, %)
|> patternLinear3d({
axis: [0, -1, 0],
instances: 2,
distance: length + 2 * thk - (tabLength * 4 / 3)
}, %)
|> patternLinear3d(
axis = [0, -1, 0],
instances = 2,
distance = length + 2 * thk - (tabLength * 4 / 3)
)
// define a plane for retention bumps
const retPlane = {

View File

@ -95,11 +95,11 @@ const tabsR = startSketchOn(tabPlane)
getNextAdjacentEdge(edge11)
]
}, %)
|> patternLinear3d({
axis: [0, -1, 0],
instances: 2,
distance: length + 2 * thk - (tabLength * 4 / 3)
}, %)
|> patternLinear3d(
axis = [0, -1, 0],
instances = 2,
distance = length + 2 * thk - (tabLength * 4 / 3)
)
// build the tabs of the mounting bracket (left side)
const tabsL = startSketchOn(tabPlane)
@ -123,11 +123,11 @@ const tabsL = startSketchOn(tabPlane)
getNextAdjacentEdge(edge22)
]
}, %)
|> patternLinear3d({
axis: [0, -1, 0],
instances: 2,
distance: length + 2 * thk - (tabLength * 4 / 3)
}, %)
|> patternLinear3d(
axis = [0, -1, 0],
instances = 2,
distance = length + 2 * thk - (tabLength * 4 / 3)
)
// define a plane for retention bumps
const retPlane = {

View File

@ -43,14 +43,14 @@ const peg = startSketchOn(s, "end")
-(total_width / 2 - wSegments),
-(total_length / 2 - lSegments)
], radius: bumpDiam / 2 }, %)
|> patternLinear2d({
axis: [1, 0],
instances: 6,
distance: 7
}, %)
|> patternLinear2d({
axis: [0, 1],
instances: 10,
distance: 7
}, %)
|> patternLinear2d(
axis = [1, 0],
instances = 6,
distance = 7
)
|> patternLinear2d(
axis = [0, 1],
instances = 10,
distance = 7
)
|> extrude(length = bumpHeight)

View File

@ -6,14 +6,16 @@ exampleSketch = startSketchOn('XZ')
|> close()
|> extrude(length = 1)
pattn1 = patternLinear3d({
axis: [1, 0, 0],
instances: 7,
distance: 6
}, exampleSketch)
pattn1 = patternLinear3d(
exampleSketch,
axis = [1, 0, 0],
instances = 7,
distance = 6
)
pattn2 = patternLinear3d({
axis: [0, 0, 1],
distance: 1,
instances: 7
}, pattn1)
pattn2 = patternLinear3d(
pattn1,
axis = [0, 0, 1],
distance = 1,
instances = 7
)

View File

@ -710,11 +710,11 @@ const sketch004fl = startSketchOn(extrude002fl, 'START')
], %, $rectangleSegmentC003fl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude004fl = extrude(sketch004fl, length = -thickness)
// EIA-310-D standard hole pattern
@ -731,11 +731,11 @@ const sketch005fl = startSketchOn(extrude002fl, 'START')
], %, $rectangleSegmentC004fl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude005fl = extrude(sketch005fl, length = -thickness)
// EIA-310-D standard hole pattern
@ -755,11 +755,11 @@ const sketch006fl = startSketchOn(extrude002fl, 'START')
], %, $rectangleSegmentC005fl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude006fl = extrude(sketch006fl, length = -thickness)
// EIA-310-D standard hole pattern
@ -776,11 +776,11 @@ const sketch007fl = startSketchOn(extrude001fl, 'START')
], %, $rectangleSegmentC006fl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude007fl = extrude(sketch007fl, length = -thickness)
// EIA-310-D standard hole pattern
@ -797,11 +797,11 @@ const sketch008fl = startSketchOn(extrude001fl, 'START')
], %, $rectangleSegmentC007fl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude008fl = extrude(sketch008fl, length = -thickness)
// EIA-310-D standard hole pattern
@ -821,11 +821,11 @@ const sketch009fl = startSketchOn(extrude001fl, 'START')
], %, $rectangleSegmentC008fl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude009fl = extrude(sketch009fl, length = -thickness)
// define slots
@ -839,11 +839,11 @@ const sketch010fl = startSketchOn(extrude001fl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010fl = extrude(sketch010fl, length = -thickness)
// define slots
@ -877,11 +877,11 @@ const sketch012fl = startSketchOn(extrude001fl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012fl = extrude(sketch012fl, length = -thickness)
// FRONT RIGHT VERTICAL RAIL
@ -992,11 +992,11 @@ const sketch004fr = startSketchOn(extrude002fr, 'START')
], %, $rectangleSegmentC003fr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude004fr = extrude(sketch004fr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1016,11 +1016,11 @@ const sketch005fr = startSketchOn(extrude002fr, 'START')
], %, $rectangleSegmentC004fr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude005fr = extrude(sketch005fr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1040,11 +1040,11 @@ const sketch006fr = startSketchOn(extrude002fr, 'START')
], %, $rectangleSegmentC005fr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude006fr = extrude(sketch006fr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1064,11 +1064,11 @@ const sketch007fr = startSketchOn(extrude001fr, 'START')
], %, $rectangleSegmentC006fr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude007fr = extrude(sketch007fr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1088,11 +1088,11 @@ const sketch008fr = startSketchOn(extrude001fr, 'START')
], %, $rectangleSegmentC007fr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude008fr = extrude(sketch008fr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1112,11 +1112,11 @@ const sketch009fr = startSketchOn(extrude001fr, 'START')
], %, $rectangleSegmentC008fr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude009fr = extrude(sketch009fr, length = -thickness)
// define slots
@ -1133,11 +1133,11 @@ const sketch010fr = startSketchOn(extrude001fr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010fr = extrude(sketch010fr, length = -thickness)
// define slots
@ -1171,11 +1171,11 @@ const sketch012fr = startSketchOn(extrude001fr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012fr = extrude(sketch012fr, length = -thickness)
// RIGHT REAR VERTICAL RAIL
@ -1286,11 +1286,11 @@ const sketch004rr = startSketchOn(extrude002rr, 'START')
], %, $rectangleSegmentC003rr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude004rr = extrude(sketch004rr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1310,11 +1310,11 @@ const sketch005rr = startSketchOn(extrude002rr, 'START')
], %, $rectangleSegmentC004rr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude005rr = extrude(sketch005rr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1334,11 +1334,11 @@ const sketch006rr = startSketchOn(extrude002rr, 'START')
], %, $rectangleSegmentC005rr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude006rr = extrude(sketch006rr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1358,11 +1358,11 @@ const sketch007rr = startSketchOn(extrude001rr, 'START')
], %, $rectangleSegmentC006rr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude007rr = extrude(sketch007rr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1382,11 +1382,11 @@ const sketch008rr = startSketchOn(extrude001rr, 'START')
], %, $rectangleSegmentC007rr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude008rr = extrude(sketch008rr, length = -thickness)
// EIA-310-D standard hole pattern
@ -1406,11 +1406,11 @@ const sketch009rr = startSketchOn(extrude001rr, 'START')
], %, $rectangleSegmentC008rr)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude009rr = extrude(sketch009rr, length = -thickness)
// define slots
@ -1427,11 +1427,11 @@ const sketch010rr = startSketchOn(extrude001rr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010rr = extrude(sketch010rr, length = -thickness)
// define slots
@ -1465,11 +1465,11 @@ const sketch012rr = startSketchOn(extrude001rr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012rr = extrude(sketch012rr, length = -thickness)
// REAR LEFT VETCIAL RAIL
@ -1579,11 +1579,11 @@ const sketch004rl = startSketchOn(extrude002rl, 'START')
], %, $rectangleSegmentC003rl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude004rl = extrude(sketch004rl, length = -thickness)
// EIA-310-D standard hole pattern
@ -1603,11 +1603,11 @@ const sketch005rl = startSketchOn(extrude002rl, 'START')
], %, $rectangleSegmentC004rl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude005rl = extrude(sketch005rl, length = -thickness)
// EIA-310-D standard hole pattern
@ -1627,11 +1627,11 @@ const sketch006rl = startSketchOn(extrude002rl, 'START')
], %, $rectangleSegmentC005rl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude006rl = extrude(sketch006rl, length = -thickness)
// EIA-310-D standard hole pattern
@ -1651,11 +1651,11 @@ const sketch007rl = startSketchOn(extrude001rl, 'START')
], %, $rectangleSegmentC006rl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude007rl = extrude(sketch007rl, length = -thickness)
// EIA-310-D standard hole pattern
@ -1675,11 +1675,11 @@ const sketch008rl = startSketchOn(extrude001rl, 'START')
], %, $rectangleSegmentC007rl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude008rl = extrude(sketch008rl, length = -thickness)
// EIA-310-D standard hole pattern
@ -1699,11 +1699,11 @@ const sketch009rl = startSketchOn(extrude001rl, 'START')
], %, $rectangleSegmentC008rl)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: railHeight,
distance: 0.62 + 0.62 + 0.5
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = railHeight,
distance = 0.62 + 0.62 + 0.5
)
const extrude009rl = extrude(sketch009rl, length = -thickness)
// define slots
@ -1720,11 +1720,11 @@ const sketch010rl = startSketchOn(extrude001rl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010rl = extrude(sketch010rl, length = -thickness)
// define slots
@ -1758,11 +1758,11 @@ const sketch012rl = startSketchOn(extrude001rl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012rl = extrude(sketch012rl, length = -thickness)
// GENERATE SERVER MODELS

View File

@ -719,11 +719,11 @@ const sketch010fl = startSketchOn(extrude001fl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010fl = extrude(sketch010fl, length = -thickness)
// define slots
@ -757,11 +757,11 @@ const sketch012fl = startSketchOn(extrude001fl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012fl = extrude(sketch012fl, length = -thickness)
// FRONT RIGHT VERTICAL RAIL
@ -869,11 +869,11 @@ const sketch010fr = startSketchOn(extrude001fr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010fr = extrude(sketch010fr, length = -thickness)
// define slots
@ -907,11 +907,11 @@ const sketch012fr = startSketchOn(extrude001fr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012fr = extrude(sketch012fr, length = -thickness)
// RIGHT REAR VERTICAL RAIL
@ -1019,11 +1019,11 @@ const sketch010rr = startSketchOn(extrude001rr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010rr = extrude(sketch010rr, length = -thickness)
// define slots
@ -1057,11 +1057,11 @@ const sketch012rr = startSketchOn(extrude001rr, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012rr = extrude(sketch012rr, length = -thickness)
// REAR LEFT VETCIAL RAIL
@ -1168,11 +1168,11 @@ const sketch010rl = startSketchOn(extrude001rl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, 1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, 1],
instances = 2,
distance = 1.22
)
const extrude010rl = extrude(sketch010rl, length = -thickness)
// define slots
@ -1206,11 +1206,11 @@ const sketch012rl = startSketchOn(extrude001rl, 'START')
|> xLine(-0.75 + .438, %)
|> tangentialArcTo([profileStartX(%), profileStartY(%)], %)
|> close()
|> patternLinear2d({
axis: [0, -1],
instances: 2,
distance: 1.22
}, %)
|> patternLinear2d(
axis = [0, -1],
instances = 2,
distance = 1.22
)
const extrude012rl = extrude(sketch012rl, length = -thickness)
// Define planes so the server can be moved

View File

@ -66,16 +66,16 @@ const peg = startSketchOn(s, 'end')
-(pitch*(wbumps-1)/2),
-(pitch*(lbumps-1)/2)
], radius: bumpDiam / 2 }, %)
|> patternLinear2d({
axis: [1, 0],
instances: wbumps,
distance: pitch
}, %)
|> patternLinear2d({
axis: [0, 1],
instances: lbumps,
distance: pitch
}, %)
|> patternLinear2d(
axis = [1, 0],
instances = wbumps,
distance = pitch
)
|> patternLinear2d(
axis = [0, 1],
instances = lbumps,
distance = pitch
)
|> extrude(bumpHeight, %)
// |> patternTransform(int(totalBumps-1), tr, %)

View File

@ -348,7 +348,7 @@ async fn kcl_test_patterns_linear_basic_with_math() {
distance = 5
part = startSketchOn('XY')
|> circle({ center: [0,0], radius: 2 }, %)
|> patternLinear2d({axis: [0,1], instances: num, distance: distance - 1}, %)
|> patternLinear2d(axis = [0,1], instances = num, distance = distance - 1)
|> extrude(length = 1)
"#;
@ -360,7 +360,7 @@ part = startSketchOn('XY')
async fn kcl_test_patterns_linear_basic() {
let code = r#"part = startSketchOn('XY')
|> circle({ center: [0,0], radius: 2 }, %)
|> patternLinear2d({axis: [0,1], instances: 13, distance: 4}, %)
|> patternLinear2d(axis = [0,1], instances = 13, distance = 4)
|> extrude(length = 1)
"#;
@ -377,7 +377,7 @@ async fn kcl_test_patterns_linear_basic_3d() {
|> line(end = [0, -1])
|> close()
|> extrude(length = 1)
|> patternLinear3d({axis: [1, 0, 1], instances: 4, distance: 6}, %)
|> patternLinear3d(axis = [1, 0, 1], instances = 4, distance = 6)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -388,7 +388,7 @@ async fn kcl_test_patterns_linear_basic_3d() {
async fn kcl_test_patterns_linear_basic_negative_distance() {
let code = r#"part = startSketchOn('XY')
|> circle({ center: [0,0], radius: 2 }, %)
|> patternLinear2d({axis: [0,1], instances: 13, distance: -2}, %)
|> patternLinear2d(axis = [0,1], instances = 13, distance = -2)
|> extrude(length = 1)
"#;
@ -400,7 +400,7 @@ async fn kcl_test_patterns_linear_basic_negative_distance() {
async fn kcl_test_patterns_linear_basic_negative_axis() {
let code = r#"part = startSketchOn('XY')
|> circle({ center: [0,0], radius: 2 }, %)
|> patternLinear2d({axis: [0,-1], instances: 13, distance: 2}, %)
|> patternLinear2d(axis = [0,-1], instances = 13, distance = 2)
|> extrude(length = 1)
"#;
@ -412,7 +412,7 @@ async fn kcl_test_patterns_linear_basic_negative_axis() {
async fn kcl_test_patterns_linear_basic_holes() {
let code = r#"circles = startSketchOn('XY')
|> circle({ center: [5, 5], radius: 1 }, %)
|> patternLinear2d({axis: [1,1], instances: 13, distance: 3}, %)
|> patternLinear2d(axis = [1,1], instances = 13, distance = 3)
rectangle = startSketchOn('XY')
|> startProfileAt([0, 0], %)
@ -433,7 +433,7 @@ rectangle = startSketchOn('XY')
async fn kcl_test_patterns_circular_basic_2d() {
let code = r#"part = startSketchOn('XY')
|> circle({ center: [0,0], radius: 2 }, %)
|> patternCircular2d({center: [20, 20], instances: 13, arcDegrees: 210, rotateDuplicates: true}, %)
|> patternCircular2d(center = [20, 20], instances = 13, arcDegrees = 210, rotateDuplicates = true)
|> extrude(length = 1)
"#;
@ -450,7 +450,7 @@ async fn kcl_test_patterns_circular_basic_3d() {
|> line(end = [0, -1])
|> close()
|> extrude(length = 1)
|> patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], instances: 41, arcDegrees: 360, rotateDuplicates: false}, %)
|> patternCircular3d(axis = [0,0, 1], center = [-20, -20, -20], instances = 41, arcDegrees = 360, rotateDuplicates = false)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -466,7 +466,7 @@ async fn kcl_test_patterns_circular_3d_tilted_axis() {
|> line(end = [0, -1])
|> close()
|> extrude(length = 1)
|> patternCircular3d({axis: [1,1,0], center: [10, 0, 10], instances: 11, arcDegrees: 360, rotateDuplicates: true}, %)
|> patternCircular3d(axis = [1,1,0], center = [10, 0, 10], instances = 11, arcDegrees = 360, rotateDuplicates = true)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -1417,11 +1417,12 @@ sketch002 = plane001
let extrudes = [sketch001, sketch002]
pattn1 = patternLinear3d({
axis: [0, 1, 0],
instances: 3,
distance: 20
}, extrudes)
pattn1 = patternLinear3d(
extrudes,
axis = [0, 1, 0],
instances = 3,
distance = 20
)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -1558,17 +1559,17 @@ async fn kcl_test_linear_pattern3d_filleted_sketch() {
part001 = cube([0,0], 20)
|> close(tag = $line1)
|> extrude(length = 20)
|> fillet({
radius: 10,
tags: [getOppositeEdge(line1)]
}, %)
pattn1 = patternLinear3d({
axis: [1, 0, 0],
instances: 4,
distance: 40
}, part001)
|> fillet({
radius: 10,
tags: [getOppositeEdge(line1)]
}, %)
pattn1 = patternLinear3d(
part001,
axis = [1, 0, 0],
instances = 4,
distance = 40
)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -1594,7 +1595,7 @@ part001 = cube([0,0], 20)
tags: [getOppositeEdge(line1)]
}, %)
pattn2 = patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], instances: 5, arcDegrees: 360, rotateDuplicates: false}, part001)
pattn2 = patternCircular3d(part001, axis = [0,0, 1], center = [-20, -20, -20], instances = 5, arcDegrees = 360, rotateDuplicates = false)
"#;
@ -1621,8 +1622,7 @@ part001 = cube([0,0], 20)
tags: [getOppositeEdge(line1)]
}, %)
pattn2 = patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], instances: 5, arcDegrees: 360, rotateDuplicates: false}, part001)
pattn2 = patternCircular3d(part001, axis = [0,0, 1], center = [-20, -20, -20], instances = 5, arcDegrees = 360, rotateDuplicates = false)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap();
@ -1748,12 +1748,12 @@ async fn kcl_test_arc_error_same_start_end() {
radius: 1.5
}, %)
|> close()
|> patternCircular2d({
arcDegrees: 360,
center: [0, 0],
instances: 6,
rotateDuplicates: true
}, %)
|> patternCircular2d(
arcDegrees = 360,
center = [0, 0],
instances = 6,
rotateDuplicates = true
)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm, None).await;