Compare commits

...

3 Commits

Author SHA1 Message Date
87dfda28a9 Move axes to std constants; move helix, revolve, and mirror2d to be declated in KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-02 17:05:28 +13:00
42f44e11f5 Add Edge type to std
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-28 11:18:10 +08:00
16ad7ff77a Move turns to a submodule of std
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-28 11:10:51 +08:00
174 changed files with 17159 additions and 29825 deletions

View File

@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 5)
// Add color to a revolved solid. // Add color to a revolved solid.
sketch001 = startSketchOn(XY) sketch001 = startSketchOn(XY)
|> circle(center = [15, 0], radius = 5) |> circle(center = [15, 0], radius = 5)
|> revolve(angle = 360, axis = 'y') |> revolve(angle = 360, axis = Y)
|> appearance(color = '#ff0000', metalness = 90, roughness = 90) |> appearance(color = '#ff0000', metalness = 90, roughness = 90)
``` ```

View File

@ -9,13 +9,12 @@ layout: manual
### `std` ### `std`
- [`HALF_TURN`](/docs/kcl/consts/std-HALF_TURN) - [`X`](/docs/kcl/consts/std-X)
- [`QUARTER_TURN`](/docs/kcl/consts/std-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-THREE_QUARTER_TURN)
- [`XY`](/docs/kcl/consts/std-XY) - [`XY`](/docs/kcl/consts/std-XY)
- [`XZ`](/docs/kcl/consts/std-XZ) - [`XZ`](/docs/kcl/consts/std-XZ)
- [`Y`](/docs/kcl/consts/std-Y)
- [`YZ`](/docs/kcl/consts/std-YZ) - [`YZ`](/docs/kcl/consts/std-YZ)
- [`ZERO`](/docs/kcl/consts/std-ZERO) - [`Z`](/docs/kcl/consts/std-Z)
### `std::math` ### `std::math`
@ -23,3 +22,10 @@ layout: manual
- [`PI`](/docs/kcl/consts/std-math-PI) - [`PI`](/docs/kcl/consts/std-math-PI)
- [`TAU`](/docs/kcl/consts/std-math-TAU) - [`TAU`](/docs/kcl/consts/std-math-TAU)
### `std::turns`
- [`HALF_TURN`](/docs/kcl/consts/std-turns-HALF_TURN)
- [`QUARTER_TURN`](/docs/kcl/consts/std-turns-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-turns-THREE_QUARTER_TURN)
- [`ZERO`](/docs/kcl/consts/std-turns-ZERO)

View File

@ -1,15 +0,0 @@
---
title: "std::HALF_TURN"
excerpt: ""
layout: manual
---
```js
std::HALF_TURN: number(deg) = 180deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -1,5 +1,5 @@
--- ---
title: "std::ZERO" title: "std::X"
excerpt: "" excerpt: ""
layout: manual layout: manual
--- ---
@ -9,7 +9,7 @@ layout: manual
```js ```js
std::ZERO: number = 0 std::X
``` ```

15
docs/kcl/consts/std-Y.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "std::Y"
excerpt: ""
layout: manual
---
```js
std::Y
```

15
docs/kcl/consts/std-Z.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "std::Z"
excerpt: ""
layout: manual
---
```js
std::Z
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::HALF_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::HALF_TURN: number(deg) = 180deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::ZERO"
excerpt: ""
layout: manual
---
```js
std::turns::ZERO: number = 0
```

File diff suppressed because one or more lines are too long

View File

@ -22,20 +22,22 @@ layout: manual
* [`string`](kcl/types/string) * [`string`](kcl/types/string)
* [`tag`](kcl/types/tag) * [`tag`](kcl/types/tag)
* **std** * **std**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face) * [`Face`](kcl/types/Face)
* [`HALF_TURN`](kcl/consts/std-HALF_TURN)
* [`Helix`](kcl/types/Helix) * [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane) * [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d) * [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d) * [`Point3d`](kcl/types/Point3d)
* [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN)
* [`Sketch`](kcl/types/Sketch) * [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid) * [`Solid`](kcl/types/Solid)
* [`THREE_QUARTER_TURN`](kcl/consts/std-THREE_QUARTER_TURN) * [`X`](kcl/consts/std-X)
* [`XY`](kcl/consts/std-XY) * [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ) * [`XZ`](kcl/consts/std-XZ)
* [`Y`](kcl/consts/std-Y)
* [`YZ`](kcl/consts/std-YZ) * [`YZ`](kcl/consts/std-YZ)
* [`ZERO`](kcl/consts/std-ZERO) * [`Z`](kcl/consts/std-Z)
* [`abs`](kcl/abs) * [`abs`](kcl/abs)
* [`acos`](kcl/acos) * [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX) * [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
@ -72,7 +74,7 @@ layout: manual
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge) * [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge) * [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge) * [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix) * [`helix`](kcl/std-helix)
* [`hole`](kcl/hole) * [`hole`](kcl/hole)
* [`hollow`](kcl/hollow) * [`hollow`](kcl/hollow)
* [`inch`](kcl/inch) * [`inch`](kcl/inch)
@ -91,7 +93,6 @@ layout: manual
* [`map`](kcl/map) * [`map`](kcl/map)
* [`max`](kcl/max) * [`max`](kcl/max)
* [`min`](kcl/min) * [`min`](kcl/min)
* [`mirror2d`](kcl/mirror2d)
* [`mm`](kcl/mm) * [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane) * [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d) * [`patternCircular2d`](kcl/patternCircular2d)
@ -110,7 +111,7 @@ layout: manual
* [`push`](kcl/push) * [`push`](kcl/push)
* [`reduce`](kcl/reduce) * [`reduce`](kcl/reduce)
* [`rem`](kcl/rem) * [`rem`](kcl/rem)
* [`revolve`](kcl/revolve) * [`revolve`](kcl/std-revolve)
* [`rotate`](kcl/rotate) * [`rotate`](kcl/rotate)
* [`round`](kcl/round) * [`round`](kcl/round)
* [`scale`](kcl/scale) * [`scale`](kcl/scale)
@ -146,3 +147,9 @@ layout: manual
* [`tan`](kcl/std-math-tan) * [`tan`](kcl/std-math-tan)
* **std::sketch** * **std::sketch**
* [`circle`](kcl/std-sketch-circle) * [`circle`](kcl/std-sketch-circle)
* [`mirror2d`](kcl/std-sketch-mirror2d)
* **std::turns**
* [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN)
* [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN)
* [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN)
* [`turns::ZERO`](kcl/consts/std-turns-ZERO)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -146,7 +146,7 @@ exampleSketch = startSketchOn(XY)
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
example = revolve(exampleSketch, axis = 'y', angle = 180) example = revolve(exampleSketch, axis = Y, angle = 180)
exampleSketch002 = startSketchOn(example, 'end') exampleSketch002 = startSketchOn(example, 'end')
|> startProfileAt([4.5, -5], %) |> startProfileAt([4.5, -5], %)
@ -177,7 +177,7 @@ exampleSketch = startSketchOn(XY)
example = revolve( example = revolve(
exampleSketch, exampleSketch,
axis = 'y', axis = Y,
angle = 180, angle = 180,
tagEnd = $end01, tagEnd = $end01,
) )

116
docs/kcl/std-helix.md Normal file

File diff suppressed because one or more lines are too long

246
docs/kcl/std-revolve.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -74,7 +74,7 @@ helixPath = helix(
revolutions = 4, revolutions = 4,
length = 10, length = 10,
radius = 5, radius = 5,
axis = 'Z', axis = Z,
) )
// Create a spring by sweeping around the helix path. // Create a spring by sweeping around the helix path.

12
docs/kcl/types/Axis2d.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "std::Axis2d"
excerpt: "An infinte line in 2d space."
layout: manual
---
An infinte line in 2d space.

12
docs/kcl/types/Axis3d.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "std::Axis3d"
excerpt: "An infinte line in 3d space."
layout: manual
---
An infinte line in 3d space.

12
docs/kcl/types/Edge.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "std::Edge"
excerpt: "The edge of a solid."
layout: manual
---
The edge of a solid.

View File

@ -21,7 +21,7 @@ sketch001 = startSketchOn(XZ)
|> angledLine([-45, length001], %) |> angledLine([-45, length001], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
revolve001 = revolve(sketch001, axis = "X") revolve001 = revolve(sketch001, axis = X)
triangle() triangle()
|> extrude(length = 30) |> extrude(length = 30)
plane001 = offsetPlane(XY, offset = 10) plane001 = offsetPlane(XY, offset = 10)
@ -126,7 +126,7 @@ test.describe('Feature Tree pane', () => {
await testViewSource({ await testViewSource({
operationName: 'Revolve', operationName: 'Revolve',
operationIndex: 0, operationIndex: 0,
expectedActiveLine: 'revolve001 = revolve(sketch001, axis = "X")', expectedActiveLine: 'revolve001 = revolve(sketch001, axis = X)',
}) })
await testViewSource({ await testViewSource({
operationName: 'Triangle', operationName: 'Triangle',

View File

@ -3469,7 +3469,7 @@ segAng(rectangleSegmentA002),
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar() await cmdBar.progressCmdBar()
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = 'X')` const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy() expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
}) })
test('revolve surface around edge from an extruded solid2d', async ({ test('revolve surface around edge from an extruded solid2d', async ({

View File

@ -674,7 +674,7 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> line(end = [12.73, -0.09]) |> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -5.38], %) |> tangentialArcTo([24.95, -5.38], %)
|> close() |> close()
|> revolve(axis = "X")` |> revolve(axis = X)`
) )
}) })
@ -761,7 +761,7 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> tangentialArcTo([24.95, -5.38], %) |> tangentialArcTo([24.95, -5.38], %)
|> line(end = [1.97, 2.06]) |> line(end = [1.97, 2.06])
|> close() |> close()
|> revolve(axis = "X")`) |> revolve(axis = X)`)
}) })
test('Can add multiple sketches', async ({ page, homePage }) => { test('Can add multiple sketches', async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
@ -1209,7 +1209,7 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
|> xLine(endAbsolute = 0 + .001) |> xLine(endAbsolute = 0 + .001)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()
|> revolve(axis = "Y") |> revolve(axis = Y)
return lugSketch return lugSketch
} }

View File

@ -76,11 +76,11 @@ part001 = startSketchOn(-XZ)
|> xLine(endAbsolute = totalLen, tag = $seg03) |> xLine(endAbsolute = totalLen, tag = $seg03)
|> yLine(length = -armThick, tag = $seg01) |> yLine(length = -armThick, tag = $seg01)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle = HALF_TURN, angle = turns::HALF_TURN,
offset = -armThick, offset = -armThick,
intersectTag = seg04 intersectTag = seg04
}, %) }, %)
|> angledLineToY([segAng(seg04, %) + 180, ZERO], %) |> angledLineToY([segAng(seg04, %) + 180, turns::ZERO], %)
|> angledLineToY({ |> angledLineToY({
angle = -bottomAng, angle = -bottomAng,
to = -totalHeightHalf - armThick, to = -totalHeightHalf - armThick,
@ -88,12 +88,12 @@ part001 = startSketchOn(-XZ)
|> xLine(length = endAbsolute = segEndX(seg03) + 0) |> xLine(length = endAbsolute = segEndX(seg03) + 0)
|> yLine(length = -segLen(seg01, %)) |> yLine(length = -segLen(seg01, %))
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle = HALF_TURN, angle = turns::HALF_TURN,
offset = -armThick, offset = -armThick,
intersectTag = seg02 intersectTag = seg02
}, %) }, %)
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %) |> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|> xLine(endAbsolute = ZERO) |> xLine(endAbsolute = turns::ZERO)
|> close() |> close()
|> extrude(length = 4)` |> extrude(length = 4)`
) )

View File

@ -486,13 +486,13 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
testName: 'Add variable, selecting axis', testName: 'Add variable, selecting axis',
addVariable: true, addVariable: true,
axisSelect: true, axisSelect: true,
value: 'QUARTER_TURN - angle001', value: 'turns::QUARTER_TURN - angle001',
}, },
{ {
testName: 'No variable, selecting axis', testName: 'No variable, selecting axis',
addVariable: false, addVariable: false,
axisSelect: true, axisSelect: true,
value: 'QUARTER_TURN - 7', value: 'turns::QUARTER_TURN - 7',
}, },
] as const ] as const
for (const { testName, addVariable, value, axisSelect } of cases) { for (const { testName, addVariable, value, axisSelect } of cases) {
@ -935,12 +935,12 @@ part002 = startSketchOn(XZ)
test.describe('Axis & segment - no modal constraints', () => { test.describe('Axis & segment - no modal constraints', () => {
const cases = [ const cases = [
{ {
codeAfter: `|> line(endAbsolute = [154.9, ZERO])`, codeAfter: `|> line(endAbsolute = [154.9, turns::ZERO])`,
axisClick: { x: 950, y: 250 }, axisClick: { x: 950, y: 250 },
constraintName: 'Snap To X', constraintName: 'Snap To X',
}, },
{ {
codeAfter: `|> line(endAbsolute = [ZERO, 61.34])`, codeAfter: `|> line(endAbsolute = [turns::ZERO, 61.34])`,
axisClick: { x: 600, y: 150 }, axisClick: { x: 600, y: 150 },
constraintName: 'Snap To Y', constraintName: 'Snap To Y',
}, },

View File

@ -319,7 +319,7 @@ part009 = startSketchOn(XY)
|> line(end = [0, pipeLength]) |> line(end = [0, pipeLength])
|> angledLineToX({ angle = 60, to = pipeLargeDia }, %) |> angledLineToX({ angle = 60, to = pipeLargeDia }, %)
|> close() |> close()
rev = revolve(part009, axis = 'y') rev = revolve(part009, axis = Y)
sketch006 = startSketchOn(XY) sketch006 = startSketchOn(XY)
profile001 = circle( profile001 = circle(
sketch006, sketch006,
@ -376,7 +376,7 @@ profile003 = startProfileAt([40.16, -120.48], sketch006)
await page.waitForTimeout(200) await page.waitForTimeout(200)
await expect(u.codeLocator).not.toContainText( await expect(u.codeLocator).not.toContainText(
`rev = revolve(part009, axis: 'y')` `rev = revolve(part009, axis: Y)`
) )
// FIXME (commented section below), this test would select a wall that had a sketch on it, and delete the underlying extrude // FIXME (commented section below), this test would select a wall that had a sketch on it, and delete the underlying extrude

View File

@ -67,11 +67,11 @@ part001 = startSketchOn(-XZ)
|> xLine(endAbsolute = totalLen, tag = $seg03) |> xLine(endAbsolute = totalLen, tag = $seg03)
|> yLine(length = -armThick, tag = $seg01) |> yLine(length = -armThick, tag = $seg01)
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle = HALF_TURN, angle = turns::HALF_TURN,
offset = -armThick, offset = -armThick,
intersectTag = seg04 intersectTag = seg04
}, %) }, %)
|> angledLineToY([segAng(seg04) + 180, ZERO], %) |> angledLineToY([segAng(seg04) + 180, turns::ZERO], %)
|> angledLineToY({ |> angledLineToY({
angle = -bottomAng, angle = -bottomAng,
to = -totalHeightHalf - armThick, to = -totalHeightHalf - armThick,
@ -79,12 +79,12 @@ part001 = startSketchOn(-XZ)
|> xLine(endAbsolute = segEndX(seg03) + 0) |> xLine(endAbsolute = segEndX(seg03) + 0)
|> yLine(length = -segLen(seg01)) |> yLine(length = -segLen(seg01))
|> angledLineThatIntersects({ |> angledLineThatIntersects({
angle = HALF_TURN, angle = turns::HALF_TURN,
offset = -armThick, offset = -armThick,
intersectTag = seg02 intersectTag = seg02
}, %) }, %)
|> angledLineToY([segAng(seg02) + 180, -baseHeight], %) |> angledLineToY([segAng(seg02) + 180, -baseHeight], %)
|> xLine(endAbsolute = ZERO) |> xLine(endAbsolute = turns::ZERO)
|> close() |> close()
|> extrude(length = 4)` |> extrude(length = 4)`
) )

View File

@ -35,7 +35,7 @@ ballsSketch = startSketchOn(XY)
|> close() |> close()
// Revolve the ball to make a sphere and pattern around the inside wall // Revolve the ball to make a sphere and pattern around the inside wall
balls = revolve(ballsSketch, axis = "X") balls = revolve(ballsSketch, axis = X)
|> patternCircular3d( |> patternCircular3d(
arcDegrees = 360, arcDegrees = 360,
axis = [0, 0, 1], axis = [0, 0, 1],
@ -60,7 +60,7 @@ chainSketch = startSketchOn(XY)
|> close() |> close()
// Revolve the chain sketch // Revolve the chain sketch
chainHead = revolve(chainSketch, axis = "X") chainHead = revolve(chainSketch, axis = X)
|> patternCircular3d( |> patternCircular3d(
arcDegrees = 360, arcDegrees = 360,
axis = [0, 0, 1], axis = [0, 0, 1],
@ -80,7 +80,7 @@ linkSketch = startSketchOn(XZ)
) )
// Revolve the link sketch // Revolve the link sketch
linkRevolve = revolve(linkSketch, axis = 'Y', angle = 360 / nBalls) linkRevolve = revolve(linkSketch, axis = Y, angle = 360 / nBalls)
|> patternCircular3d( |> patternCircular3d(
arcDegrees = 360, arcDegrees = 360,
axis = [0, 0, 1], axis = [0, 0, 1],

View File

@ -80,5 +80,5 @@ brakeCaliperSketch = startSketchOn(XY)
|> close() |> close()
// Revolve the brake caliper sketch // Revolve the brake caliper sketch
revolve(brakeCaliperSketch, axis = "Y", angle = -70) revolve(brakeCaliperSketch, axis = Y, angle = -70)
|> appearance(color = "#c82d2d", metalness = 90, roughness = 90) |> appearance(color = "#c82d2d", metalness = 90, roughness = 90)

View File

@ -41,5 +41,5 @@ tireSketch = startSketchOn(XY)
|> close() |> close()
// Revolve the sketch to create the tire // Revolve the sketch to create the tire
revolve(tireSketch, axis = "Y") revolve(tireSketch, axis = Y)
|> appearance(color = "#0f0f0f", roughness = 80) |> appearance(color = "#0f0f0f", roughness = 80)

View File

@ -54,7 +54,7 @@ wheelCenterInner = startSketchOn(XY)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
|> appearance(color = "#ffffff", metalness = 0, roughness = 0) |> appearance(color = "#ffffff", metalness = 0, roughness = 0)
wheelCenterOuter = startSketchOn(XY) wheelCenterOuter = startSketchOn(XY)
@ -68,7 +68,7 @@ wheelCenterOuter = startSketchOn(XY)
|> yLine(endAbsolute = -wheelWidth / 20) |> yLine(endAbsolute = -wheelWidth / 20)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
|> appearance(color = "#ffffff", metalness = 0, roughness = 0) |> appearance(color = "#ffffff", metalness = 0, roughness = 0)
// Write a function that defines the spoke geometry, patterns and extrudes it // Write a function that defines the spoke geometry, patterns and extrudes it
@ -173,5 +173,5 @@ startSketchOn(XY)
|> xLine(length = wheelWidth * 0.03) |> xLine(length = wheelWidth * 0.03)
|> yLine(length = wheelWidth * 0.05) |> yLine(length = wheelWidth * 0.05)
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
|> appearance(color = "#ffffff", metalness = 0, roughness = 0) |> appearance(color = "#ffffff", metalness = 0, roughness = 0)

View File

@ -32,7 +32,7 @@ fn lug(plane, length, diameter) {
|> xLine(endAbsolute = lugThreadDiameter) |> xLine(endAbsolute = lugThreadDiameter)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> close() |> close()
|> revolve(axis = "Y") |> revolve(axis = Y)
|> appearance(color = "#dbcd70", roughness = 90, metalness = 90) |> appearance(color = "#dbcd70", roughness = 90, metalness = 90)
return lugSketch return lugSketch
} }

View File

@ -23,7 +23,7 @@ sketch001 = startSketchOn(XZ)
], %, $rectangleSegmentC001) ], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> revolve(angle = 360, axis = 'Y') |> revolve(angle = 360, axis = Y)
// Create an angled plane to sketch the supports // Create an angled plane to sketch the supports
plane001 = { plane001 = {
@ -132,7 +132,7 @@ sketch005 = startSketchOn(XZ)
|> xLine(endAbsolute = 0.15) |> xLine(endAbsolute = 0.15)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
// Plunger and stem // Plunger and stem
sketch006 = startSketchOn(XZ) sketch006 = startSketchOn(XZ)
@ -145,7 +145,7 @@ sketch006 = startSketchOn(XZ)
|> tangentialArc({ radius = 0.6, offset = -90 }, %) |> tangentialArc({ radius = 0.6, offset = -90 }, %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
// Spiral plate // Spiral plate
sketch007 = startSketchOn(offsetPlane(XY, offset = 1.12)) sketch007 = startSketchOn(offsetPlane(XY, offset = 1.12))
@ -201,7 +201,7 @@ sketch011 = startSketchOn(XZ)
}, %) }, %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
// Draw and extrude handle // Draw and extrude handle
sketch012 = startSketchOn(offsetPlane(XZ, offset = handleThickness / 2)) sketch012 = startSketchOn(offsetPlane(XZ, offset = handleThickness / 2))

View File

@ -48,10 +48,8 @@ sides = patternCircular3d(
// define an axis axis000 // define an axis axis000
axis000 = { axis000 = {
custom = { direction = [0.0, 1.0],
axis = [0.0, 1.0],
origin = [cornerRadius, cornerRadius] origin = [cornerRadius, cornerRadius]
}
} }
// create a single corner of the bin // create a single corner of the bin

View File

@ -45,10 +45,8 @@ sides = patternCircular3d(
// define an axis axis000 // define an axis axis000
axis000 = { axis000 = {
custom = { direction = [0.0, 1.0],
axis = [0.0, 1.0],
origin = [cornerRadius, cornerRadius] origin = [cornerRadius, cornerRadius]
}
} }
// create a single corner of the bin // create a single corner of the bin

View File

@ -65,13 +65,11 @@ sides = patternCircular3d(
// define an axis axis000 // define an axis axis000
axis000 = { axis000 = {
custom = { direction = [0.0, 1.0],
axis = [0.0, 1.0],
origin = [ origin = [
cornerRadius + binTol, cornerRadius + binTol,
cornerRadius + binTol cornerRadius + binTol
] ]
}
} }
// create a single corner of the bin // create a single corner of the bin
@ -272,10 +270,8 @@ lipWidths = patternCircular3d(
// define an axis axis000 // define an axis axis000
axis001 = { axis001 = {
custom = { direction = [0.0, 1.0],
axis = [0.0, 1.0],
origin = [cornerRadius, cornerRadius] origin = [cornerRadius, cornerRadius]
}
} }
// create a single corner of the bin // create a single corner of the bin

View File

@ -58,13 +58,11 @@ sides = patternCircular3d(
// define an axis axis000 // define an axis axis000
axis000 = { axis000 = {
custom = { direction = [0.0, 1.0],
axis = [0.0, 1.0],
origin = [ origin = [
cornerRadius + binTol, cornerRadius + binTol,
cornerRadius + binTol cornerRadius + binTol
] ]
}
} }
// create a single corner of the bin // create a single corner of the bin

View File

@ -20,6 +20,6 @@ sketch001 = startSketchOn(-XZ)
|> xLine(endAbsolute = webThickness / 2 + rootRadius) |> xLine(endAbsolute = webThickness / 2 + rootRadius)
|> tangentialArc({ radius = rootRadius, offset = 90 }, %) |> tangentialArc({ radius = rootRadius, offset = 90 }, %)
|> yLine(endAbsolute = 0) |> yLine(endAbsolute = 0)
|> mirror2d({ axis = 'X' }, %) |> mirror2d(axis = X)
|> mirror2d({ axis = 'Y' }, %) |> mirror2d(axis = Y)
|> extrude(length = beamLength) |> extrude(length = beamLength)

View File

@ -24,4 +24,4 @@ pipeProfile = outerProfile
|> hole(innerProfile, %) |> hole(innerProfile, %)
// revolve the pipe profile at the desired angle // revolve the pipe profile at the desired angle
pipe = revolve(pipeProfile, axis = 'Y', angle = bendAngle) pipe = revolve(pipeProfile, axis = Y, angle = bendAngle)

View File

@ -33,4 +33,4 @@ pipeSketch = startSketchOn(XY)
|> close() |> close()
// Revolve the sketch to create the pipe // Revolve the sketch to create the pipe
pipe = revolve(pipeSketch, axis = 'y') pipe = revolve(pipeSketch, axis = Y)

View File

@ -34,10 +34,8 @@ part001 = revolve(
sketch001, sketch001,
angle = 90, angle = 90,
axis = { axis = {
custom = { direction = [1.0, 0.0],
axis = [1.0, 0.0],
origin = [0.0, height + .0001] origin = [0.0, height + .0001]
}
}, },
) )

View File

@ -14,7 +14,7 @@ radius = 10
depth = 30 depth = 30
distanceToInsideEdge = slateWidthHalf + templateThickness + templateGap distanceToInsideEdge = slateWidthHalf + templateThickness + templateGap
sketch001 = startSketchOn(XZ) sketch001 = startSketchOn(XZ)
|> startProfileAt([ZERO, depth + templateGap], %) |> startProfileAt([turns::ZERO, depth + templateGap], %)
|> xLine(length = slateWidthHalf - radius, tag = $seg01) |> xLine(length = slateWidthHalf - radius, tag = $seg01)
|> arc({ |> arc({
angleEnd = 0, angleEnd = 0,
@ -28,7 +28,7 @@ sketch001 = startSketchOn(XZ)
|> yLine(length = templateThickness * 2, tag = $seg08) |> yLine(length = templateThickness * 2, tag = $seg08)
|> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05) |> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05)
|> yLine(endAbsolute = segEndY(seg01) + templateThickness, tag = $seg10) |> yLine(endAbsolute = segEndY(seg01) + templateThickness, tag = $seg10)
|> xLine(endAbsolute = ZERO, tag = $seg04) |> xLine(endAbsolute = turns::ZERO, tag = $seg04)
|> xLine(length = -segLen(seg04)) |> xLine(length = -segLen(seg04))
|> yLine(length = -segLen(seg10)) |> yLine(length = -segLen(seg10))
|> xLine(length = -segLen(seg05)) |> xLine(length = -segLen(seg05))

View File

@ -28,7 +28,7 @@ sketch001 = startSketchOn(XZ)
|> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05) |> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05)
|> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04) |> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04)
|> yLine(length = -length002, tag = $seg03) |> yLine(length = -length002, tag = $seg03)
|> xLine(endAbsolute = ZERO, tag = $seg02) |> xLine(endAbsolute = turns::ZERO, tag = $seg02)
// |> line(end = [7.78, 11.16]) // |> line(end = [7.78, 11.16])
|> xLine(length = -segLen(seg02)) |> xLine(length = -segLen(seg02))
|> yLine(length = segLen(seg03)) |> yLine(length = segLen(seg03))

View File

@ -21,7 +21,7 @@ export fn knob() {
}, %) }, %)
|> xLine(endAbsolute = 0.0001) |> xLine(endAbsolute = 0.0001)
|> close() |> close()
|> revolve(axis = "Y") |> revolve(axis = Y)
|> appearance(color = '#D0FF01', metalness = 90, roughness = 50) |> appearance(color = '#D0FF01', metalness = 90, roughness = 50)
return knob return knob

View File

@ -876,7 +876,7 @@ async fn kcl_test_simple_revolve() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y') |> revolve(axis = Y)
"#; "#;
@ -896,7 +896,7 @@ async fn kcl_test_simple_revolve_uppercase() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'Y') |> revolve(axis = Y)
"#; "#;
@ -916,7 +916,7 @@ async fn kcl_test_simple_revolve_negative() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = '-Y', angle = 180) |> revolve(axis = -Y, angle = 180)
"#; "#;
@ -936,7 +936,7 @@ async fn kcl_test_revolve_bad_angle_low() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y', angle = -455) |> revolve(axis = Y, angle = -455)
"#; "#;
@ -962,7 +962,7 @@ async fn kcl_test_revolve_bad_angle_high() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y', angle = 455) |> revolve(axis = Y, angle = 455)
"#; "#;
@ -988,7 +988,7 @@ async fn kcl_test_simple_revolve_custom_angle() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y', angle = 180) |> revolve(axis = Y, angle = 180)
"#; "#;
@ -1008,7 +1008,7 @@ async fn kcl_test_simple_revolve_custom_axis() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = {custom: {axis: [0, -1], origin: [0,0]}}, angle = 180) |> revolve(axis = { direction = [0, -1], origin: [0,0] }, angle = 180)
"#; "#;
@ -1106,7 +1106,7 @@ sketch001 = startSketchOn(box, "END")
|> circle(center = [10,10], radius= 4 ) |> circle(center = [10,10], radius= 4 )
|> revolve( |> revolve(
angle = -90, angle = -90,
axis = 'y' axis = Y
) )
"#; "#;
@ -1131,7 +1131,7 @@ sketch001 = startSketchOn(box, "end")
|> line(end = [0, 10]) |> line(end = [0, 10])
|> close() |> close()
|> revolve( |> revolve(
axis = 'y', axis = Y,
angle = -90, angle = -90,
) )
"#; "#;
@ -1146,7 +1146,7 @@ async fn kcl_test_basic_revolve_circle() {
|> circle(center = [15, 0], radius= 5) |> circle(center = [15, 0], radius= 5)
|> revolve( |> revolve(
angle = 360, angle = 360,
axis = 'y' axis = Y
) )
"#; "#;
@ -1166,7 +1166,7 @@ async fn kcl_test_simple_revolve_sketch_on_edge() {
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y', angle = 180) |> revolve(axis = Y, angle = 180)
part002 = startSketchOn(part001, 'end') part002 = startSketchOn(part001, 'end')
|> startProfileAt([4.5, -5], %) |> startProfileAt([4.5, -5], %)

View File

@ -23,8 +23,9 @@ use crate::{
const TYPES_DIR: &str = "../../docs/kcl/types"; const TYPES_DIR: &str = "../../docs/kcl/types";
const LANG_TOPICS: [&str; 5] = ["Types", "Modules", "Settings", "Known Issues", "Constants"]; const LANG_TOPICS: [&str; 5] = ["Types", "Modules", "Settings", "Known Issues", "Constants"];
// These types are declared in std. // These types are declared in std.
const DECLARED_TYPES: [&str; 11] = [ const DECLARED_TYPES: [&str; 14] = [
"number", "string", "tag", "bool", "Sketch", "Solid", "Plane", "Helix", "Face", "Point2d", "Point3d", "number", "string", "tag", "bool", "Sketch", "Solid", "Plane", "Helix", "Face", "Edge", "Point2d", "Point3d",
"Axis2d", "Axis3d",
]; ];
fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { fn init_handlebars() -> Result<handlebars::Handlebars<'static>> {
@ -339,9 +340,9 @@ fn generate_index(combined: &IndexMap<String, Box<dyn StdLibFn>>, kcl_lib: &[Doc
} }
functions.entry(d.mod_name()).or_default().push(match d { functions.entry(d.mod_name()).or_default().push(match d {
DocData::Fn(f) => (f.name.clone(), d.file_name()), DocData::Fn(f) => (f.preferred_name.clone(), d.file_name()),
DocData::Const(c) => (c.name.clone(), d.file_name()), DocData::Const(c) => (c.preferred_name.clone(), d.file_name()),
DocData::Ty(t) => (t.name.clone(), d.file_name()), DocData::Ty(t) => (t.preferred_name.clone(), d.file_name()),
}); });
if let DocData::Const(c) = d { if let DocData::Const(c) = d {

View File

@ -9,7 +9,7 @@ use tower_lsp::lsp_types::{
use crate::{ use crate::{
execution::annotations, execution::annotations,
parsing::{ parsing::{
ast::types::{Annotation, Node, PrimitiveType, Type, VariableKind}, ast::types::{Annotation, ImportSelector, Node, PrimitiveType, Type, VariableKind},
token::NumericSuffix, token::NumericSuffix,
}, },
ModuleId, ModuleId,
@ -17,7 +17,7 @@ use crate::{
pub fn walk_prelude() -> Vec<DocData> { pub fn walk_prelude() -> Vec<DocData> {
let mut visitor = CollectionVisitor::default(); let mut visitor = CollectionVisitor::default();
visitor.visit_module("prelude").unwrap(); visitor.visit_module("prelude", "").unwrap();
visitor.result visitor.result
} }
@ -29,7 +29,7 @@ struct CollectionVisitor {
} }
impl CollectionVisitor { impl CollectionVisitor {
fn visit_module(&mut self, name: &str) -> Result<(), String> { fn visit_module(&mut self, name: &str, preferred_prefix: &str) -> Result<(), String> {
let old_name = std::mem::replace(&mut self.name, name.to_owned()); let old_name = std::mem::replace(&mut self.name, name.to_owned());
let source = crate::modules::read_std(name).unwrap(); let source = crate::modules::read_std(name).unwrap();
let parsed = crate::parsing::parse_str(source, ModuleId::from_usize(self.id)) let parsed = crate::parsing::parse_str(source, ModuleId::from_usize(self.id))
@ -40,14 +40,16 @@ impl CollectionVisitor {
for n in &parsed.body { for n in &parsed.body {
match n { match n {
crate::parsing::ast::types::BodyItem::ImportStatement(import) if !import.visibility.is_default() => { crate::parsing::ast::types::BodyItem::ImportStatement(import) if !import.visibility.is_default() => {
// Only supports glob imports for now.
assert!(matches!(
import.selector,
crate::parsing::ast::types::ImportSelector::Glob(..)
));
match &import.path { match &import.path {
crate::parsing::ast::types::ImportPath::Std { path } => { crate::parsing::ast::types::ImportPath::Std { path } => {
self.visit_module(&path[1])?; match import.selector {
ImportSelector::Glob(..) => self.visit_module(&path[1], "")?,
ImportSelector::None { .. } => {
self.visit_module(&path[1], &format!("{}::", import.module_name().unwrap()))?
}
// Only supports glob or whole-module imports for now.
_ => unimplemented!(),
}
} }
p => return Err(format!("Unexpected import: `{p}`")), p => return Err(format!("Unexpected import: `{p}`")),
} }
@ -59,8 +61,8 @@ impl CollectionVisitor {
format!("std::{}::", self.name) format!("std::{}::", self.name)
}; };
let mut dd = match var.kind { let mut dd = match var.kind {
VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)), VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name, preferred_prefix)),
VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)), VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name, preferred_prefix)),
}; };
dd.with_meta(&var.outer_attrs); dd.with_meta(&var.outer_attrs);
@ -77,7 +79,7 @@ impl CollectionVisitor {
} else { } else {
format!("std::{}::", self.name) format!("std::{}::", self.name)
}; };
let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name)); let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name, preferred_prefix));
dd.with_meta(&ty.outer_attrs); dd.with_meta(&ty.outer_attrs);
for a in &ty.outer_attrs { for a in &ty.outer_attrs {
@ -200,6 +202,8 @@ impl DocData {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ConstData { pub struct ConstData {
pub name: String, pub name: String,
/// How the const is indexed, etc.
pub preferred_name: String,
/// The fully qualified name. /// The fully qualified name.
pub qual_name: String, pub qual_name: String,
pub value: Option<String>, pub value: Option<String>,
@ -216,7 +220,11 @@ pub struct ConstData {
} }
impl ConstData { impl ConstData {
fn from_ast(var: &crate::parsing::ast::types::VariableDeclaration, mut qual_name: String) -> Self { fn from_ast(
var: &crate::parsing::ast::types::VariableDeclaration,
mut qual_name: String,
preferred_prefix: &str,
) -> Self {
assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Const); assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Const);
let (value, ty) = match &var.declaration.init { let (value, ty) = match &var.declaration.init {
@ -240,6 +248,7 @@ impl ConstData {
let name = var.declaration.id.name.clone(); let name = var.declaration.id.name.clone();
qual_name.push_str(&name); qual_name.push_str(&name);
ConstData { ConstData {
preferred_name: format!("{preferred_prefix}{name}"),
name, name,
qual_name, qual_name,
value, value,
@ -272,7 +281,7 @@ impl ConstData {
detail.push_str(ty); detail.push_str(ty);
} }
CompletionItem { CompletionItem {
label: self.name.clone(), label: self.preferred_name.clone(),
label_details: Some(CompletionItemLabelDetails { label_details: Some(CompletionItemLabelDetails {
detail: self.value.clone(), detail: self.value.clone(),
description: None, description: None,
@ -306,6 +315,8 @@ impl ConstData {
pub struct FnData { pub struct FnData {
/// The name of the function. /// The name of the function.
pub name: String, pub name: String,
/// How the function is indexed, etc.
pub preferred_name: String,
/// The fully qualified name. /// The fully qualified name.
pub qual_name: String, pub qual_name: String,
/// The args of the function. /// The args of the function.
@ -326,7 +337,11 @@ pub struct FnData {
} }
impl FnData { impl FnData {
fn from_ast(var: &crate::parsing::ast::types::VariableDeclaration, mut qual_name: String) -> Self { fn from_ast(
var: &crate::parsing::ast::types::VariableDeclaration,
mut qual_name: String,
preferred_prefix: &str,
) -> Self {
assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Fn); assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Fn);
let crate::parsing::ast::types::Expr::FunctionExpression(expr) = &var.declaration.init else { let crate::parsing::ast::types::Expr::FunctionExpression(expr) = &var.declaration.init else {
unreachable!(); unreachable!();
@ -345,6 +360,7 @@ impl FnData {
} }
FnData { FnData {
preferred_name: format!("{preferred_prefix}{name}"),
name, name,
qual_name, qual_name,
args: expr.params.iter().map(ArgData::from_ast).collect(), args: expr.params.iter().map(ArgData::from_ast).collect(),
@ -443,7 +459,7 @@ impl FnData {
} }
// We end with ${} so you can jump to the end of the snippet. // We end with ${} so you can jump to the end of the snippet.
// After the last argument. // After the last argument.
format!("{}({})${{}}", self.name, args.join(", ")) format!("{}({})${{}}", self.preferred_name, args.join(", "))
} }
fn to_signature_help(&self) -> SignatureHelp { fn to_signature_help(&self) -> SignatureHelp {
@ -452,7 +468,7 @@ impl FnData {
SignatureHelp { SignatureHelp {
signatures: vec![SignatureInformation { signatures: vec![SignatureInformation {
label: self.name.clone(), label: self.preferred_name.clone(),
documentation: self.short_docs().map(|s| { documentation: self.short_docs().map(|s| {
Documentation::MarkupContent(MarkupContent { Documentation::MarkupContent(MarkupContent {
kind: MarkupKind::Markdown, kind: MarkupKind::Markdown,
@ -492,6 +508,7 @@ pub struct ArgData {
pub ty: Option<String>, pub ty: Option<String>,
/// If the argument is required. /// If the argument is required.
pub kind: ArgKind, pub kind: ArgKind,
pub override_in_snippet: Option<bool>,
/// Additional information that could be used instead of the type's description. /// Additional information that could be used instead of the type's description.
/// This is helpful if the type is really basic, like "number" -- that won't tell the user much about /// This is helpful if the type is really basic, like "number" -- that won't tell the user much about
/// how this argument is meant to be used. /// how this argument is meant to be used.
@ -512,6 +529,7 @@ impl ArgData {
name: arg.identifier.name.clone(), name: arg.identifier.name.clone(),
ty: arg.type_.as_ref().map(|t| t.to_string()), ty: arg.type_.as_ref().map(|t| t.to_string()),
docs: None, docs: None,
override_in_snippet: None,
kind: if arg.labeled { kind: if arg.labeled {
ArgKind::Labelled(arg.optional()) ArgKind::Labelled(arg.optional())
} else { } else {
@ -519,26 +537,54 @@ impl ArgData {
}, },
}; };
for attr in &arg.identifier.outer_attrs {
if let Annotation {
name: None,
properties: Some(props),
..
} = &attr.inner
{
for p in props {
match &*p.key.name {
"include_in_snippet" => {
if let Some(b) = p.value.literal_bool() {
result.override_in_snippet = Some(b);
} else {
panic!(
"Invalid value for `include_in_snippet`, expected bool literal, found {:?}",
p.value
);
}
}
_ => {}
}
}
}
}
result.with_comments(&arg.identifier.pre_comments); result.with_comments(&arg.identifier.pre_comments);
result result
} }
pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> { pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> {
match self.override_in_snippet {
Some(false) => return None,
None if !self.kind.required() => return None,
_ => {}
}
let label = if self.kind == ArgKind::Special { let label = if self.kind == ArgKind::Special {
String::new() String::new()
} else { } else {
format!("{} = ", self.name) format!("{} = ", self.name)
}; };
match self.ty.as_deref() { match self.ty.as_deref() {
Some(s) if ["Sketch", "Solid", "Plane | Face", "Sketch | Plane | Face"].contains(&s) => { Some(s) if s.starts_with("number") => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))),
Some((index, format!("{label}${{{}:{}}}", index, "%"))) Some("Point2d") => Some((
}
Some("number") if self.kind.required() => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))),
Some("Point2d") if self.kind.required() => Some((
index + 1, index + 1,
format!(r#"{label}[${{{}:3.14}}, ${{{}:3.14}}]"#, index, index + 1), format!(r#"{label}[${{{}:3.14}}, ${{{}:3.14}}]"#, index, index + 1),
)), )),
Some("Point3d") if self.kind.required() => Some(( Some("Point3d") => Some((
index + 2, index + 2,
format!( format!(
r#"{label}[${{{}:3.14}}, ${{{}:3.14}}, ${{{}:3.14}}]"#, r#"{label}[${{{}:3.14}}, ${{{}:3.14}}, ${{{}:3.14}}]"#,
@ -547,8 +593,10 @@ impl ArgData {
index + 2 index + 2
), ),
)), )),
Some("string") if self.kind.required() => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))), Some("Axis2d | Edge") | Some("Axis3d | Edge") => Some((index, format!(r#"{label}${{{}:X}}"#, index))),
Some("bool") if self.kind.required() => Some((index, format!(r#"{label}${{{}:false}}"#, index))),
Some("string") => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))),
Some("bool") => Some((index, format!(r#"{label}${{{}:false}}"#, index))),
_ => None, _ => None,
} }
} }
@ -580,6 +628,8 @@ impl ArgKind {
pub struct TyData { pub struct TyData {
/// The name of the function. /// The name of the function.
pub name: String, pub name: String,
/// How the type is indexed, etc.
pub preferred_name: String,
/// The fully qualified name. /// The fully qualified name.
pub qual_name: String, pub qual_name: String,
pub properties: Properties, pub properties: Properties,
@ -597,7 +647,11 @@ pub struct TyData {
} }
impl TyData { impl TyData {
fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self { fn from_ast(
ty: &crate::parsing::ast::types::TypeDeclaration,
mut qual_name: String,
preferred_prefix: &str,
) -> Self {
let name = ty.name.name.clone(); let name = ty.name.name.clone();
qual_name.push_str(&name); qual_name.push_str(&name);
let mut referenced_types = HashSet::new(); let mut referenced_types = HashSet::new();
@ -606,6 +660,7 @@ impl TyData {
} }
TyData { TyData {
preferred_name: format!("{preferred_prefix}{name}"),
name, name,
qual_name, qual_name,
properties: Properties { properties: Properties {
@ -641,7 +696,7 @@ impl TyData {
fn to_completion_item(&self) -> CompletionItem { fn to_completion_item(&self) -> CompletionItem {
CompletionItem { CompletionItem {
label: self.name.clone(), label: self.preferred_name.clone(),
label_details: self.alias.as_ref().map(|t| CompletionItemLabelDetails { label_details: self.alias.as_ref().map(|t| CompletionItemLabelDetails {
detail: Some(format!("type {} = {t}", self.name)), detail: Some(format!("type {} = {t}", self.name)),
description: None, description: None,
@ -658,7 +713,7 @@ impl TyData {
preselect: None, preselect: None,
sort_text: None, sort_text: None,
filter_text: None, filter_text: None,
insert_text: Some(self.name.clone()), insert_text: Some(self.preferred_name.clone()),
insert_text_format: Some(InsertTextFormat::SNIPPET), insert_text_format: Some(InsertTextFormat::SNIPPET),
insert_text_mode: None, insert_text_mode: None,
text_edit: None, text_edit: None,

View File

@ -1000,9 +1000,12 @@ mod tests {
#[test] #[test]
fn get_autocomplete_snippet_revolve() { fn get_autocomplete_snippet_revolve() {
let revolve_fn: Box<dyn StdLibFn> = Box::new(crate::std::revolve::Revolve); let data = kcl_doc::walk_prelude();
let snippet = revolve_fn.to_autocomplete_snippet().unwrap(); let DocData::Fn(revolve_fn) = data.into_iter().find(|d| d.name() == "revolve").unwrap() else {
assert_eq!(snippet, r#"revolve(${0:%}, axis = ${1:"X"})${}"#); panic!();
};
let snippet = revolve_fn.to_autocomplete_snippet();
assert_eq!(snippet, r#"revolve(axis = ${0:X})${}"#);
} }
#[test] #[test]
@ -1015,7 +1018,7 @@ mod tests {
let snippet = circle_fn.to_autocomplete_snippet(); let snippet = circle_fn.to_autocomplete_snippet();
assert_eq!( assert_eq!(
snippet, snippet,
r#"circle(${0:%}, center = [${1:3.14}, ${2:3.14}], radius = ${3:3.14})${}"# r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})${}"#
); );
} }
@ -1089,11 +1092,14 @@ mod tests {
#[test] #[test]
#[allow(clippy::literal_string_with_formatting_args)] #[allow(clippy::literal_string_with_formatting_args)]
fn get_autocomplete_snippet_helix() { fn get_autocomplete_snippet_helix() {
let helix_fn: Box<dyn StdLibFn> = Box::new(crate::std::helix::Helix); let data = kcl_doc::walk_prelude();
let snippet = helix_fn.to_autocomplete_snippet().unwrap(); let DocData::Fn(helix_fn) = data.into_iter().find(|d| d.name() == "helix").unwrap() else {
panic!();
};
let snippet = helix_fn.to_autocomplete_snippet();
assert_eq!( assert_eq!(
snippet, snippet,
r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:"X"}, length = ${4:3.14})${}"# r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:X}, length = ${4:3.14})${}"#
); );
} }

View File

@ -27,6 +27,19 @@ pub enum Operation {
is_error: bool, is_error: bool,
}, },
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
KclStdLibCall {
name: String,
/// The unlabeled argument to the function.
unlabeled_arg: Option<OpArg>,
/// The labeled keyword arguments to the function.
labeled_args: IndexMap<String, OpArg>,
/// The source range of the operation in the source code.
source_range: SourceRange,
/// True if the operation resulted in an error.
#[serde(default, skip_serializing_if = "is_false")]
is_error: bool,
},
#[serde(rename_all = "camelCase")]
UserDefinedFunctionCall { UserDefinedFunctionCall {
/// The name of the user-defined function being called. Anonymous /// The name of the user-defined function being called. Anonymous
/// functions have no name. /// functions have no name.
@ -49,6 +62,7 @@ impl Operation {
pub(crate) fn set_std_lib_call_is_error(&mut self, is_err: bool) { pub(crate) fn set_std_lib_call_is_error(&mut self, is_err: bool) {
match self { match self {
Self::StdLibCall { ref mut is_error, .. } => *is_error = is_err, Self::StdLibCall { ref mut is_error, .. } => *is_error = is_err,
Self::KclStdLibCall { ref mut is_error, .. } => *is_error = is_err,
Self::UserDefinedFunctionCall { .. } | Self::UserDefinedFunctionReturn => {} Self::UserDefinedFunctionCall { .. } | Self::UserDefinedFunctionReturn => {}
} }
} }

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use async_recursion::async_recursion; use async_recursion::async_recursion;
use indexmap::IndexMap; use indexmap::IndexMap;
use super::kcl_value::TypeDef; use super::{kcl_value::TypeDef, types::PrimitiveType};
use crate::{ use crate::{
engine::ExecutionKind, engine::ExecutionKind,
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
@ -1031,6 +1031,15 @@ impl Node<UnaryExpression> {
} }
let value = &self.argument.get_result(exec_state, ctx).await?; let value = &self.argument.get_result(exec_state, ctx).await?;
let err = || {
KclError::Semantic(KclErrorDetails {
message: format!(
"You can only negate numbers, planes, or lines, but this is a {}",
value.human_friendly_type()
),
source_ranges: vec![self.into()],
})
};
match value { match value {
KclValue::Number { value, ty, .. } => { KclValue::Number { value, ty, .. } => {
let meta = vec![Metadata { let meta = vec![Metadata {
@ -1052,13 +1061,63 @@ impl Node<UnaryExpression> {
plane.id = exec_state.next_uuid(); plane.id = exec_state.next_uuid();
Ok(KclValue::Plane { value: plane }) Ok(KclValue::Plane { value: plane })
} }
_ => Err(KclError::Semantic(KclErrorDetails { KclValue::Object { value: values, meta } => {
message: format!( // Special-case for negating line-like objects.
"You can only negate numbers or planes, but this is a {}", let Some(direction) = values.get("direction") else {
value.human_friendly_type() return Err(err());
), };
source_ranges: vec![self.into()],
})), let direction = match direction {
KclValue::MixedArray { value: values, meta } => {
let values = values
.iter()
.map(|v| match v {
KclValue::Number { value, ty, meta } => Ok(KclValue::Number {
value: *value * -1.0,
ty: ty.clone(),
meta: meta.clone(),
}),
_ => Err(err()),
})
.collect::<Result<Vec<_>, _>>()?;
KclValue::MixedArray {
value: values,
meta: meta.clone(),
}
}
KclValue::HomArray {
value: values,
ty: ty @ RuntimeType::Primitive(PrimitiveType::Number(_)),
} => {
let values = values
.iter()
.map(|v| match v {
KclValue::Number { value, ty, meta } => Ok(KclValue::Number {
value: *value * -1.0,
ty: ty.clone(),
meta: meta.clone(),
}),
_ => Err(err()),
})
.collect::<Result<Vec<_>, _>>()?;
KclValue::HomArray {
value: values,
ty: ty.clone(),
}
}
_ => return Err(err()),
};
let mut value = values.clone();
value.insert("direction".to_owned(), direction);
Ok(KclValue::Object {
value,
meta: meta.clone(),
})
}
_ => Err(err()),
} }
} }
} }
@ -2145,6 +2204,27 @@ impl FunctionSource {
} }
} }
let op = if props.include_in_feature_tree {
let op_labeled_args = args
.kw_args
.labeled
.iter()
.map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range)))
.collect();
Some(Operation::KclStdLibCall {
// TODO
name: String::new(),
unlabeled_arg: args
.unlabeled_kw_arg_unconverted()
.map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
labeled_args: op_labeled_args,
source_range: callsite,
is_error: false,
})
} else {
None
};
// Attempt to call the function. // Attempt to call the function.
exec_state.mut_stack().push_new_env_for_rust_call(); exec_state.mut_stack().push_new_env_for_rust_call();
let mut result = { let mut result = {
@ -2152,7 +2232,15 @@ impl FunctionSource {
let result = func(exec_state, args).await; let result = func(exec_state, args).await;
exec_state.mut_stack().pop_env(); exec_state.mut_stack().pop_env();
// TODO support recording op into the feature tree if let Some(mut op) = op {
op.set_std_lib_call_is_error(result.is_err());
// Track call operation. We do this after the call
// since things like patternTransform may call user code
// before running, and we will likely want to use the
// return value. The call takes ownership of the args,
// so we need to build the op before the call.
exec_state.global.operations.push(op);
}
result result
}?; }?;

View File

@ -56,6 +56,20 @@ impl RuntimeType {
RuntimeType::Primitive(PrimitiveType::ImportedGeometry) RuntimeType::Primitive(PrimitiveType::ImportedGeometry)
} }
/// `[number; 2]`
pub fn point2d() -> Self {
RuntimeType::Array(Box::new(RuntimeType::number_any()), ArrayLen::Known(2))
}
/// `[number; 3]`
pub fn point3d() -> Self {
RuntimeType::Array(Box::new(RuntimeType::number_any()), ArrayLen::Known(3))
}
pub fn number_any() -> Self {
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any))
}
pub fn from_parsed( pub fn from_parsed(
value: Type, value: Type,
exec_state: &mut ExecState, exec_state: &mut ExecState,
@ -93,21 +107,27 @@ impl RuntimeType {
AstPrimitiveType::Number(suffix) => RuntimeType::Primitive(PrimitiveType::Number( AstPrimitiveType::Number(suffix) => RuntimeType::Primitive(PrimitiveType::Number(
NumericType::from_parsed(suffix, &exec_state.mod_local.settings), NumericType::from_parsed(suffix, &exec_state.mod_local.settings),
)), )),
AstPrimitiveType::Named(name) => { AstPrimitiveType::Named(name) => Self::from_alias(&name.name, exec_state, source_range)?,
AstPrimitiveType::Tag => RuntimeType::Primitive(PrimitiveType::Tag),
})
}
pub fn from_alias(
alias: &str,
exec_state: &mut ExecState,
source_range: SourceRange,
) -> Result<Self, CompilationError> {
let ty_val = exec_state let ty_val = exec_state
.stack() .stack()
.get(&format!("{}{}", memory::TYPE_PREFIX, name.name), source_range) .get(&format!("{}{}", memory::TYPE_PREFIX, alias), source_range)
.map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", name.name)))?; .map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", alias)))?;
match ty_val { Ok(match ty_val {
KclValue::Type { value, .. } => match value { KclValue::Type { value, .. } => match value {
TypeDef::RustRepr(ty, _) => RuntimeType::Primitive(ty.clone()), TypeDef::RustRepr(ty, _) => RuntimeType::Primitive(ty.clone()),
TypeDef::Alias(ty) => ty.clone(), TypeDef::Alias(ty) => ty.clone(),
}, },
_ => unreachable!(), _ => unreachable!(),
}
}
AstPrimitiveType::Tag => RuntimeType::Primitive(PrimitiveType::Tag),
}) })
} }
@ -143,6 +163,35 @@ impl RuntimeType {
(Object(t1), Object(t2)) => t2 (Object(t1), Object(t2)) => t2
.iter() .iter()
.all(|(f, t)| t1.iter().any(|(ff, tt)| f == ff && tt.subtype(t))), .all(|(f, t)| t1.iter().any(|(ff, tt)| f == ff && tt.subtype(t))),
// Equality between Axis types and there object representation.
(Object(t1), Primitive(PrimitiveType::Axis2d)) => {
t1.iter()
.any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point2d()))
&& t1
.iter()
.any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point2d()))
}
(Object(t1), Primitive(PrimitiveType::Axis3d)) => {
t1.iter()
.any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point3d()))
&& t1
.iter()
.any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point3d()))
}
(Primitive(PrimitiveType::Axis2d), Object(t2)) => {
t2.iter()
.any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point2d()))
&& t2
.iter()
.any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point2d()))
}
(Primitive(PrimitiveType::Axis3d), Object(t2)) => {
t2.iter()
.any(|(n, t)| n == "origin" && t.subtype(&RuntimeType::point3d()))
&& t2
.iter()
.any(|(n, t)| n == "direction" && t.subtype(&RuntimeType::point3d()))
}
_ => false, _ => false,
} }
} }
@ -213,11 +262,11 @@ impl ArrayLen {
} }
/// True if the length constraint is satisfied by the supplied length. /// True if the length constraint is satisfied by the supplied length.
fn satisfied(self, len: usize) -> bool { fn satisfied(self, len: usize, allow_shrink: bool) -> Option<usize> {
match self { match self {
ArrayLen::None => true, ArrayLen::None => Some(len),
ArrayLen::NonEmpty => len > 0, ArrayLen::NonEmpty => (len > 0).then_some(len),
ArrayLen::Known(s) => len == s, ArrayLen::Known(s) => (if allow_shrink { len >= s } else { len == s }).then_some(s),
} }
} }
} }
@ -233,6 +282,9 @@ pub enum PrimitiveType {
Plane, Plane,
Helix, Helix,
Face, Face,
Edge,
Axis2d,
Axis3d,
ImportedGeometry, ImportedGeometry,
} }
@ -248,6 +300,9 @@ impl PrimitiveType {
PrimitiveType::Plane => "Planes".to_owned(), PrimitiveType::Plane => "Planes".to_owned(),
PrimitiveType::Helix => "Helices".to_owned(), PrimitiveType::Helix => "Helices".to_owned(),
PrimitiveType::Face => "Faces".to_owned(), PrimitiveType::Face => "Faces".to_owned(),
PrimitiveType::Edge => "Edges".to_owned(),
PrimitiveType::Axis2d => "2d axes".to_owned(),
PrimitiveType::Axis3d => "3d axes".to_owned(),
PrimitiveType::ImportedGeometry => "imported geometries".to_owned(), PrimitiveType::ImportedGeometry => "imported geometries".to_owned(),
PrimitiveType::Tag => "tags".to_owned(), PrimitiveType::Tag => "tags".to_owned(),
} }
@ -273,6 +328,9 @@ impl fmt::Display for PrimitiveType {
PrimitiveType::Solid => write!(f, "Solid"), PrimitiveType::Solid => write!(f, "Solid"),
PrimitiveType::Plane => write!(f, "Plane"), PrimitiveType::Plane => write!(f, "Plane"),
PrimitiveType::Face => write!(f, "Face"), PrimitiveType::Face => write!(f, "Face"),
PrimitiveType::Edge => write!(f, "Edge"),
PrimitiveType::Axis2d => write!(f, "Axis2d"),
PrimitiveType::Axis3d => write!(f, "Axis3d"),
PrimitiveType::Helix => write!(f, "Helix"), PrimitiveType::Helix => write!(f, "Helix"),
PrimitiveType::ImportedGeometry => write!(f, "imported geometry"), PrimitiveType::ImportedGeometry => write!(f, "imported geometry"),
} }
@ -298,6 +356,10 @@ impl NumericType {
NumericType::Known(UnitType::Count) NumericType::Known(UnitType::Count)
} }
pub fn mm() -> Self {
NumericType::Known(UnitType::Length(UnitLen::Mm))
}
/// Combine two types when we expect them to be equal. /// Combine two types when we expect them to be equal.
pub fn combine_eq(self, other: &NumericType) -> NumericType { pub fn combine_eq(self, other: &NumericType) -> NumericType {
if &self == other { if &self == other {
@ -541,7 +603,7 @@ impl KclValue {
pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> { pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> {
match ty { match ty {
RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state), RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state),
RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state), RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state, false),
RuntimeType::Tuple(tys) => self.coerce_to_tuple_type(tys, exec_state), RuntimeType::Tuple(tys) => self.coerce_to_tuple_type(tys, exec_state),
RuntimeType::Union(tys) => self.coerce_to_union_type(tys, exec_state), RuntimeType::Union(tys) => self.coerce_to_union_type(tys, exec_state),
RuntimeType::Object(tys) => self.coerce_to_object_type(tys, exec_state), RuntimeType::Object(tys) => self.coerce_to_object_type(tys, exec_state),
@ -609,6 +671,55 @@ impl KclValue {
KclValue::Helix { .. } => Some(value.clone()), KclValue::Helix { .. } => Some(value.clone()),
_ => None, _ => None,
}, },
PrimitiveType::Edge => match value {
KclValue::Uuid { .. } => Some(value.clone()),
KclValue::TagIdentifier { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Axis2d => match value {
KclValue::Object { value: values, meta } => {
if values.get("origin")?.has_type(&RuntimeType::point2d())
&& values.get("direction")?.has_type(&RuntimeType::point2d())
{
return Some(value.clone());
}
let origin = values.get("origin").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true)
})?;
let direction = values.get("direction").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(2), exec_state, true)
})?;
Some(KclValue::Object {
value: [("origin".to_owned(), origin), ("direction".to_owned(), direction)].into(),
meta: meta.clone(),
})
}
_ => None,
},
PrimitiveType::Axis3d => match value {
KclValue::Object { value: values, meta } => {
if values.get("origin")?.has_type(&RuntimeType::point3d())
&& values.get("direction")?.has_type(&RuntimeType::point3d())
{
return Some(value.clone());
}
let origin = values.get("origin").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true)
})?;
let direction = values.get("direction").and_then(|p| {
p.coerce_to_array_type(&RuntimeType::number_any(), ArrayLen::Known(3), exec_state, true)
})?;
Some(KclValue::Object {
value: [("origin".to_owned(), origin), ("direction".to_owned(), direction)].into(),
meta: meta.clone(),
})
}
_ => None,
},
PrimitiveType::ImportedGeometry => match value { PrimitiveType::ImportedGeometry => match value {
KclValue::ImportedGeometry { .. } => Some(value.clone()), KclValue::ImportedGeometry { .. } => Some(value.clone()),
_ => None, _ => None,
@ -621,60 +732,35 @@ impl KclValue {
} }
} }
fn coerce_to_array_type(&self, ty: &RuntimeType, len: ArrayLen, exec_state: &mut ExecState) -> Option<KclValue> { fn coerce_to_array_type(
&self,
ty: &RuntimeType,
len: ArrayLen,
exec_state: &mut ExecState,
allow_shrink: bool,
) -> Option<KclValue> {
match self { match self {
KclValue::HomArray { value, ty: aty } if aty == ty => { KclValue::HomArray { value, ty: aty } if aty.subtype(ty) => {
let value = match len { len.satisfied(value.len(), allow_shrink).map(|len| KclValue::HomArray {
ArrayLen::None => value.clone(), value: value[..len].to_vec(),
ArrayLen::NonEmpty => { ty: aty.clone(),
if value.is_empty() { })
return None;
} }
value if len.satisfied(1, false).is_some() && value.has_type(ty) => Some(KclValue::HomArray {
value.clone()
}
ArrayLen::Known(n) => {
if n != value.len() {
return None;
}
value[..n].to_vec()
}
};
Some(KclValue::HomArray { value, ty: ty.clone() })
}
value if len.satisfied(1) && value.has_type(ty) => Some(KclValue::HomArray {
value: vec![value.clone()], value: vec![value.clone()],
ty: ty.clone(), ty: ty.clone(),
}), }),
KclValue::MixedArray { value, .. } => { KclValue::MixedArray { value, .. } => {
let value = match len { let len = len.satisfied(value.len(), allow_shrink)?;
ArrayLen::None => value.clone(),
ArrayLen::NonEmpty => {
if value.is_empty() {
return None;
}
value.clone() let value = value[..len]
}
ArrayLen::Known(n) => {
if n != value.len() {
return None;
}
value[..n].to_vec()
}
};
let value = value
.iter() .iter()
.map(|v| v.coerce(ty, exec_state)) .map(|v| v.coerce(ty, exec_state))
.collect::<Option<Vec<_>>>()?; .collect::<Option<Vec<_>>>()?;
Some(KclValue::HomArray { value, ty: ty.clone() }) Some(KclValue::HomArray { value, ty: ty.clone() })
} }
KclValue::KclNone { .. } if len.satisfied(0) => Some(KclValue::HomArray { KclValue::KclNone { .. } if len.satisfied(0, false).is_some() => Some(KclValue::HomArray {
value: Vec::new(), value: Vec::new(),
ty: ty.clone(), ty: ty.clone(),
}), }),
@ -1251,4 +1337,119 @@ mod test {
assert!(count.coerce(&tyb, &mut exec_state).is_none()); assert!(count.coerce(&tyb, &mut exec_state).is_none());
assert!(count.coerce(&tyb2, &mut exec_state).is_none()); assert!(count.coerce(&tyb2, &mut exec_state).is_none());
} }
#[tokio::test(flavor = "multi_thread")]
async fn coerce_axes() {
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
// Subtyping
assert!(RuntimeType::Primitive(PrimitiveType::Axis2d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis2d)));
assert!(RuntimeType::Primitive(PrimitiveType::Axis3d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis3d)));
assert!(!RuntimeType::Primitive(PrimitiveType::Axis3d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis2d)));
assert!(!RuntimeType::Primitive(PrimitiveType::Axis2d).subtype(&RuntimeType::Primitive(PrimitiveType::Axis3d)));
// Coercion
let a2d = KclValue::Object {
value: [
(
"origin".to_owned(),
KclValue::HomArray {
value: vec![
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
],
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())),
},
),
(
"direction".to_owned(),
KclValue::HomArray {
value: vec![
KclValue::Number {
value: 1.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
],
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())),
},
),
]
.into(),
meta: Vec::new(),
};
let a3d = KclValue::Object {
value: [
(
"origin".to_owned(),
KclValue::HomArray {
value: vec![
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
],
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())),
},
),
(
"direction".to_owned(),
KclValue::HomArray {
value: vec![
KclValue::Number {
value: 1.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
KclValue::Number {
value: 0.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
KclValue::Number {
value: 1.0,
ty: NumericType::mm(),
meta: Vec::new(),
},
],
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())),
},
),
]
.into(),
meta: Vec::new(),
};
let ty2d = RuntimeType::Primitive(PrimitiveType::Axis2d);
let ty3d = RuntimeType::Primitive(PrimitiveType::Axis3d);
assert_coerce_results(&a2d, &ty2d, &a2d, &mut exec_state);
assert_coerce_results(&a3d, &ty3d, &a3d, &mut exec_state);
assert_coerce_results(&a3d, &ty2d, &a2d, &mut exec_state);
assert!(a2d.coerce(&ty3d, &mut exec_state).is_none());
}
} }

View File

@ -120,7 +120,7 @@ const Part001 = startSketchOn('XY')
|> line([0, pipeLength], %) |> line([0, pipeLength], %)
|> angledLineToX({ angle: 60, to: pipeLargeDia }, %) |> angledLineToX({ angle: 60, to: pipeLargeDia }, %)
|> close() |> close()
|> revolve({ axis: 'y' }, %) |> revolve({ axis = Y }, %)
" "
); );
@ -156,7 +156,7 @@ const part001 = startSketchOn('XY')
|> line([0, pipeLength], %) |> line([0, pipeLength], %)
|> angledLineToX({ angle: 60, to: pipeLargeDia }, %) |> angledLineToX({ angle: 60, to: pipeLargeDia }, %)
|> close() |> close()
|> revolve({ axis: 'y' }, %) |> revolve({ axis = Y }, %)
" "
); );

View File

@ -1632,7 +1632,7 @@ insideRevolve = startSketchOn(XZ)
|> line(end = [0, -thickness]) |> line(end = [0, -thickness])
|> line(end = [-overHangLength, 0]) |> line(end = [-overHangLength, 0])
|> close() |> close()
|> revolve({ axis: 'y' }, %) |> revolve({ axis = Y }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn(XZ) sphere = startSketchOn(XZ)
@ -1647,7 +1647,7 @@ sphere = startSketchOn(XZ)
radius: sphereDia / 2 - 0.05 radius: sphereDia / 2 - 0.05
}, %) }, %)
|> close() |> close()
|> revolve({ axis: 'x' }, %) |> revolve({ axis = X }, %)
|> patternCircular3d( |> patternCircular3d(
axis = [0, 0, 1], axis = [0, 0, 1],
center = [0, 0, 0], center = [0, 0, 0],
@ -1671,7 +1671,7 @@ outsideRevolve = startSketchOn(XZ)
|> line(end = [0, thickness]) |> line(end = [0, thickness])
|> line(end = [overHangLength - thickness, 0]) |> line(end = [overHangLength - thickness, 0])
|> close() |> close()
|> revolve({ axis: 'y' }, %)"# |> revolve({ axis = Y }, %)"#
.to_string(), .to_string(),
}, },
}) })
@ -1705,7 +1705,7 @@ outsideRevolve = startSketchOn(XZ)
start: tower_lsp::lsp_types::Position { line: 0, character: 0 }, start: tower_lsp::lsp_types::Position { line: 0, character: 0 },
end: tower_lsp::lsp_types::Position { end: tower_lsp::lsp_types::Position {
line: 60, line: 60,
character: 30 character: 29
} }
} }
); );
@ -1732,7 +1732,7 @@ insideRevolve = startSketchOn(XZ)
|> line(end = [0, -thickness]) |> line(end = [0, -thickness])
|> line(end = [-overHangLength, 0]) |> line(end = [-overHangLength, 0])
|> close() |> close()
|> revolve({ axis = 'y' }, %) |> revolve({ axis = Y }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn(XZ) sphere = startSketchOn(XZ)
@ -1747,7 +1747,7 @@ sphere = startSketchOn(XZ)
radius = sphereDia / 2 - 0.05 radius = sphereDia / 2 - 0.05
}, %) }, %)
|> close() |> close()
|> revolve({ axis = 'x' }, %) |> revolve({ axis = X }, %)
|> patternCircular3d( |> patternCircular3d(
axis = [0, 0, 1], axis = [0, 0, 1],
center = [0, 0, 0], center = [0, 0, 0],
@ -1771,7 +1771,7 @@ outsideRevolve = startSketchOn(XZ)
|> line(end = [0, thickness]) |> line(end = [0, thickness])
|> line(end = [overHangLength - thickness, 0]) |> line(end = [overHangLength - thickness, 0])
|> close() |> close()
|> revolve({ axis = 'y' }, %)"# |> revolve({ axis = Y }, %)"#
); );
} }

View File

@ -88,6 +88,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
"prelude" => Some(include_str!("../std/prelude.kcl")), "prelude" => Some(include_str!("../std/prelude.kcl")),
"math" => Some(include_str!("../std/math.kcl")), "math" => Some(include_str!("../std/math.kcl")),
"sketch" => Some(include_str!("../std/sketch.kcl")), "sketch" => Some(include_str!("../std/sketch.kcl")),
"turns" => Some(include_str!("../std/turns.kcl")),
_ => None, _ => None,
} }
} }

View File

@ -1609,10 +1609,9 @@ impl ImportStatement {
return Some(alias.name.clone()); return Some(alias.name.clone());
} }
let mut parts = match &self.path { match &self.path {
ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => s.split('.'), ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => {
_ => return None, let mut parts = s.split('.');
};
let path = parts.next()?; let path = parts.next()?;
let _ext = parts.next()?; let _ext = parts.next()?;
let rest = parts.next(); let rest = parts.next();
@ -1623,6 +1622,9 @@ impl ImportStatement {
path.rsplit(&['/', '\\']).next().map(str::to_owned) path.rsplit(&['/', '\\']).next().map(str::to_owned)
} }
ImportPath::Std { path } => path.last().cloned(),
}
}
} }
impl From<&ImportStatement> for Vec<CompletionItem> { impl From<&ImportStatement> for Vec<CompletionItem> {

View File

@ -152,7 +152,12 @@ const STR_DEPRECATIONS: [(&str, &str); 6] = [
("-YZ", "-YZ"), ("-YZ", "-YZ"),
]; ];
const FN_DEPRECATIONS: [(&str, &str); 3] = [("pi", "PI"), ("e", "E"), ("tau", "TAU")]; const FN_DEPRECATIONS: [(&str, &str); 3] = [("pi", "PI"), ("e", "E"), ("tau", "TAU")];
const CONST_DEPRECATIONS: [(&str, &str); 0] = []; const CONST_DEPRECATIONS: [(&str, &str); 4] = [
("ZERO", "turns::ZERO"),
("QUARTER_TURN", "turns::QUARTER_TURN"),
("HALF_TURN", "turns::HALF_TURN"),
("THREE_QUARTER_TURN", "turns::THREE_QUARTER_TURN"),
];
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum DeprecationKind { pub enum DeprecationKind {

View File

@ -286,6 +286,11 @@ fn non_code_node(i: &mut TokenSlice) -> PResult<Node<NonCodeNode>> {
alt((non_code_node_leading_whitespace, non_code_node_no_leading_whitespace)).parse_next(i) alt((non_code_node_leading_whitespace, non_code_node_no_leading_whitespace)).parse_next(i)
} }
fn outer_annotation(i: &mut TokenSlice) -> PResult<Node<Annotation>> {
peek((at_sign, open_paren)).parse_next(i)?;
annotation(i)
}
fn annotation(i: &mut TokenSlice) -> PResult<Node<Annotation>> { fn annotation(i: &mut TokenSlice) -> PResult<Node<Annotation>> {
let at = at_sign.parse_next(i)?; let at = at_sign.parse_next(i)?;
let name = opt(binding_name).parse_next(i)?; let name = opt(binding_name).parse_next(i)?;
@ -1823,14 +1828,6 @@ fn import_stmt(i: &mut TokenSlice) -> PResult<BoxNode<ImportStatement>> {
) )
.into(), .into(),
)); ));
} else if matches!(path, ImportPath::Std { .. }) && matches!(selector, ImportSelector::None { .. }) {
return Err(ErrMode::Cut(
CompilationError::fatal(
SourceRange::new(start, end, module_id),
"the standard library cannot be imported as a part",
)
.into(),
));
} }
Ok(Node::boxed( Ok(Node::boxed(
@ -2910,13 +2907,17 @@ struct ParamDescription {
arg_name: Token, arg_name: Token,
type_: std::option::Option<Node<Type>>, type_: std::option::Option<Node<Type>>,
default_value: Option<DefaultParamVal>, default_value: Option<DefaultParamVal>,
attr: Option<Node<Annotation>>,
comments: Option<Node<Vec<String>>>, comments: Option<Node<Vec<String>>>,
} }
fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
let (_, comments, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = ( let (_, comments, _, attr, _, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = (
opt(whitespace), opt(whitespace),
opt(comments), opt(comments),
opt(whitespace),
opt(outer_annotation),
opt(whitespace),
opt(at_sign), opt(at_sign),
any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"), any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"),
opt(question_mark), opt(question_mark),
@ -2941,6 +2942,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
return Err(ErrMode::Backtrack(ContextError::from(e))); return Err(ErrMode::Backtrack(ContextError::from(e)));
} }
}, },
attr,
comments, comments,
}) })
} }
@ -2962,6 +2964,7 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> {
arg_name, arg_name,
type_, type_,
default_value, default_value,
attr,
comments, comments,
}| { }| {
let mut identifier = Node::<Identifier>::try_from(arg_name)?; let mut identifier = Node::<Identifier>::try_from(arg_name)?;
@ -2969,6 +2972,9 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> {
identifier.comment_start = comments.start; identifier.comment_start = comments.start;
identifier.pre_comments = comments.inner; identifier.pre_comments = comments.inner;
} }
if let Some(attr) = attr {
identifier.outer_attrs.push(attr);
}
Ok(Parameter { Ok(Parameter {
identifier, identifier,

View File

@ -75,7 +75,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// This will work on any solid, including extruded solids, revolved solids, and shelled solids. /// This will work on any solid, including extruded solids, revolved solids, and shelled solids.
/// ```no_run /// ```no_run
/// // Add color to an extruded solid. /// // Add color to an extruded solid.
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> line(endAbsolute = [10, 0]) /// |> line(endAbsolute = [10, 0])
/// |> line(endAbsolute = [0, 10]) /// |> line(endAbsolute = [0, 10])
@ -89,9 +89,9 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ///
/// ```no_run /// ```no_run
/// // Add color to a revolved solid. /// // Add color to a revolved solid.
/// sketch001 = startSketchOn('XY') /// sketch001 = startSketchOn(XY)
/// |> circle( center = [15, 0], radius = 5 ) /// |> circle( center = [15, 0], radius = 5 )
/// |> revolve( angle = 360, axis = 'y') /// |> revolve( angle = 360, axis = Y)
/// |> appearance( /// |> appearance(
/// color = '#ff0000', /// color = '#ff0000',
/// metalness = 90, /// metalness = 90,
@ -102,7 +102,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ```no_run /// ```no_run
/// // Add color to different solids. /// // Add color to different solids.
/// fn cube(center) { /// fn cube(center) {
/// return startSketchOn('XY') /// return startSketchOn(XY)
/// |> startProfileAt([center[0] - 10, center[1] - 10], %) /// |> startProfileAt([center[0] - 10, center[1] - 10], %)
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10]) /// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10]) /// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
@ -122,7 +122,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ```no_run /// ```no_run
/// // You can set the appearance before or after you shell it will yield the same result. /// // You can set the appearance before or after you shell it will yield the same result.
/// // This example shows setting the appearance _after_ the shell. /// // This example shows setting the appearance _after_ the shell.
/// firstSketch = startSketchOn('XY') /// firstSketch = startSketchOn(XY)
/// |> startProfileAt([-12, 12], %) /// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0]) /// |> line(end = [24, 0])
/// |> line(end = [0, -24]) /// |> line(end = [0, -24])
@ -145,7 +145,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ```no_run /// ```no_run
/// // You can set the appearance before or after you shell it will yield the same result. /// // You can set the appearance before or after you shell it will yield the same result.
/// // This example shows setting the appearance _before_ the shell. /// // This example shows setting the appearance _before_ the shell.
/// firstSketch = startSketchOn('XY') /// firstSketch = startSketchOn(XY)
/// |> startProfileAt([-12, 12], %) /// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0]) /// |> line(end = [24, 0])
/// |> line(end = [0, -24]) /// |> line(end = [0, -24])
@ -168,7 +168,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ```no_run /// ```no_run
/// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern. /// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
/// // This example shows _before_ the pattern. /// // This example shows _before_ the pattern.
/// exampleSketch = startSketchOn('XZ') /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 2]) /// |> line(end = [0, 2])
/// |> line(end = [3, 1]) /// |> line(end = [3, 1])
@ -191,7 +191,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ```no_run /// ```no_run
/// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern. /// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
/// // This example shows _after_ the pattern. /// // This example shows _after_ the pattern.
/// exampleSketch = startSketchOn('XZ') /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 2]) /// |> line(end = [0, 2])
/// |> line(end = [3, 1]) /// |> line(end = [3, 1])
@ -213,7 +213,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// ///
/// ```no_run /// ```no_run
/// // Color the result of a 2D pattern that was extruded. /// // Color the result of a 2D pattern that was extruded.
/// exampleSketch = startSketchOn('XZ') /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([.5, 25], %) /// |> startProfileAt([.5, 25], %)
/// |> line(end = [0, 5]) /// |> line(end = [0, 5])
/// |> line(end = [-1, 0]) /// |> line(end = [-1, 0])
@ -238,7 +238,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// // Color the result of a sweep. /// // Color the result of a sweep.
/// ///
/// // Create a path for the sweep. /// // Create a path for the sweep.
/// sweepPath = startSketchOn('XZ') /// sweepPath = startSketchOn(XZ)
/// |> startProfileAt([0.05, 0.05], %) /// |> startProfileAt([0.05, 0.05], %)
/// |> line(end = [0, 7]) /// |> line(end = [0, 7])
/// |> tangentialArc({ /// |> tangentialArc({
@ -252,13 +252,13 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// }, %) /// }, %)
/// |> line(end = [0, 7]) /// |> line(end = [0, 7])
/// ///
/// pipeHole = startSketchOn('XY') /// pipeHole = startSketchOn(XY)
/// |> circle( /// |> circle(
/// center = [0, 0], /// center = [0, 0],
/// radius = 1.5, /// radius = 1.5,
/// ) /// )
/// ///
/// sweepSketch = startSketchOn('XY') /// sweepSketch = startSketchOn(XY)
/// |> circle( /// |> circle(
/// center = [0, 0], /// center = [0, 0],
/// radius = 2, /// radius = 2,

View File

@ -154,6 +154,22 @@ impl Args {
}) })
} }
pub(crate) fn get_kw_arg_opt_typed<T>(
&self,
label: &str,
ty: &RuntimeType,
exec_state: &mut ExecState,
) -> Result<Option<T>, KclError>
where
T: for<'a> FromKclValue<'a>,
{
if self.kw_args.labeled.get(label).is_none() {
return Ok(None);
};
self.get_kw_arg_typed(label, ty, exec_state).map(Some)
}
/// Get a keyword argument. If not set, returns Err. /// Get a keyword argument. If not set, returns Err.
pub(crate) fn get_kw_arg<'a, T>(&'a self, label: &str) -> Result<T, KclError> pub(crate) fn get_kw_arg<'a, T>(&'a self, label: &str) -> Result<T, KclError>
where where
@ -675,37 +691,6 @@ impl Args {
FromArgs::from_args(self, 0) FromArgs::from_args(self, 0)
} }
pub(crate) fn get_data_and_sketches<'a, T>(
&'a self,
exec_state: &mut ExecState,
) -> Result<(T, Vec<Sketch>), KclError>
where
T: serde::de::DeserializeOwned + FromArgs<'a>,
{
let data: T = FromArgs::from_args(self, 0)?;
let Some(arg1) = self.args.get(1) else {
return Err(KclError::Semantic(KclErrorDetails {
message: "Expected one or more sketches for second argument".to_owned(),
source_ranges: vec![self.source_range],
}));
};
let sarg = arg1
.value
.coerce(&RuntimeType::sketches(), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected one or more sketches for second argument, found {}",
arg1.value.human_friendly_type()
),
source_ranges: vec![self.source_range],
}))?;
let sketches = match sarg {
KclValue::HomArray { value, .. } => value.iter().map(|v| v.as_sketch().unwrap().clone()).collect(),
_ => unreachable!(),
};
Ok((data, sketches))
}
pub(crate) fn get_data_and_sketch_and_tag<'a, T>( pub(crate) fn get_data_and_sketch_and_tag<'a, T>(
&'a self, &'a self,
exec_state: &mut ExecState, exec_state: &mut ExecState,
@ -1583,50 +1568,6 @@ impl<'a> FromKclValue<'a> for super::sketch::SketchData {
} }
} }
impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin2d {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
// Case 1: predefined planes.
if let Some(s) = arg.as_str() {
return match s {
"X" | "x" => Some(Self::X),
"Y" | "y" => Some(Self::Y),
"-X" | "-x" => Some(Self::NegX),
"-Y" | "-y" => Some(Self::NegY),
_ => None,
};
}
// Case 2: custom planes.
let obj = arg.as_object()?;
let_field_of!(obj, custom, &KclObjectFields);
let_field_of!(custom, origin);
let_field_of!(custom, axis);
Some(Self::Custom { axis, origin })
}
}
impl<'a> FromKclValue<'a> for super::axis_or_reference::AxisAndOrigin3d {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
// Case 1: predefined planes.
if let Some(s) = arg.as_str() {
return match s {
"X" | "x" => Some(Self::X),
"Y" | "y" => Some(Self::Y),
"Z" | "z" => Some(Self::Z),
"-X" | "-x" => Some(Self::NegX),
"-Y" | "-y" => Some(Self::NegY),
"-Z" | "-z" => Some(Self::NegZ),
_ => None,
};
}
// Case 2: custom planes.
let obj = arg.as_object()?;
let_field_of!(obj, custom, &KclObjectFields);
let_field_of!(custom, origin);
let_field_of!(custom, axis);
Some(Self::Custom { axis, origin })
}
}
impl<'a> FromKclValue<'a> for super::fillet::EdgeReference { impl<'a> FromKclValue<'a> for super::fillet::EdgeReference {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let id = arg.as_uuid().map(Self::Uuid); let id = arg.as_uuid().map(Self::Uuid);
@ -1637,25 +1578,27 @@ impl<'a> FromKclValue<'a> for super::fillet::EdgeReference {
impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis2dOrEdgeReference { impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis2dOrEdgeReference {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = super::axis_or_reference::AxisAndOrigin2d::from_kcl_val; let case1 = |arg: &KclValue| {
let obj = arg.as_object()?;
let_field_of!(obj, direction);
let_field_of!(obj, origin);
Some(Self::Axis { direction, origin })
};
let case2 = super::fillet::EdgeReference::from_kcl_val; let case2 = super::fillet::EdgeReference::from_kcl_val;
case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge)) case1(arg).or_else(|| case2(arg).map(Self::Edge))
} }
} }
impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis3dOrEdgeReference { impl<'a> FromKclValue<'a> for super::axis_or_reference::Axis3dOrEdgeReference {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = super::axis_or_reference::AxisAndOrigin3d::from_kcl_val; let case1 = |arg: &KclValue| {
let case2 = super::fillet::EdgeReference::from_kcl_val;
case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge))
}
}
impl<'a> FromKclValue<'a> for super::mirror::Mirror2dData {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let obj = arg.as_object()?; let obj = arg.as_object()?;
let_field_of!(obj, axis); let_field_of!(obj, direction);
Some(Self { axis }) let_field_of!(obj, origin);
Some(Self::Axis { direction, origin })
};
let case2 = super::fillet::EdgeReference::from_kcl_val;
case1(arg).or_else(|| case2(arg).map(Self::Edge))
} }
} }

View File

@ -1,233 +1,21 @@
//! Types for referencing an axis or edge. //! Types for referencing an axis or edge.
use anyhow::Result; use crate::std::fillet::EdgeReference;
use kcmc::length_unit::LengthUnit;
use kittycad_modeling_cmds::{self as kcmc};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{errors::KclError, std::fillet::EdgeReference};
/// A 2D axis or tagged edge. /// A 2D axis or tagged edge.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, PartialEq)]
#[ts(export)]
#[serde(untagged)]
pub enum Axis2dOrEdgeReference { pub enum Axis2dOrEdgeReference {
/// 2D axis and origin. /// 2D axis and origin.
Axis(AxisAndOrigin2d), Axis { direction: [f64; 2], origin: [f64; 2] },
/// Tagged edge. /// Tagged edge.
Edge(EdgeReference), Edge(EdgeReference),
} }
/// A 2D axis and origin.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum AxisAndOrigin2d {
/// X-axis.
#[serde(rename = "X", alias = "x")]
X,
/// Y-axis.
#[serde(rename = "Y", alias = "y")]
Y,
/// Flip the X-axis.
#[serde(rename = "-X", alias = "-x")]
NegX,
/// Flip the Y-axis.
#[serde(rename = "-Y", alias = "-y")]
NegY,
Custom {
/// The axis.
axis: [f64; 2],
/// The origin.
origin: [f64; 2],
},
}
impl AxisAndOrigin2d {
/// Get the axis and origin.
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
let (axis, origin) = match self {
AxisAndOrigin2d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin2d::Custom { axis, origin } => ([axis[0], axis[1], 0.0], [origin[0], origin[1], 0.0]),
};
Ok((
kcmc::shared::Point3d {
x: axis[0],
y: axis[1],
z: axis[2],
},
kcmc::shared::Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(origin[2]),
},
))
}
}
/// A 3D axis or tagged edge. /// A 3D axis or tagged edge.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, PartialEq)]
#[ts(export)]
#[serde(untagged)]
pub enum Axis3dOrEdgeReference { pub enum Axis3dOrEdgeReference {
/// 3D axis and origin. /// 3D axis and origin.
Axis(AxisAndOrigin3d), Axis { direction: [f64; 3], origin: [f64; 3] },
/// Tagged edge. /// Tagged edge.
Edge(EdgeReference), Edge(EdgeReference),
} }
/// A 3D axis and origin.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum AxisAndOrigin3d {
/// X-axis.
#[serde(rename = "X", alias = "x")]
X,
/// Y-axis.
#[serde(rename = "Y", alias = "y")]
Y,
/// Z-axis.
#[serde(rename = "Z", alias = "z")]
Z,
/// Flip the X-axis.
#[serde(rename = "-X", alias = "-x")]
NegX,
/// Flip the Y-axis.
#[serde(rename = "-Y", alias = "-y")]
NegY,
/// Flip the Z-axis.
#[serde(rename = "-Z", alias = "-z")]
NegZ,
Custom {
/// The axis.
axis: [f64; 3],
/// The origin.
origin: [f64; 3],
},
}
impl AxisAndOrigin3d {
/// Get the axis and origin.
pub fn axis_and_origin(&self) -> Result<(kcmc::shared::Point3d<f64>, kcmc::shared::Point3d<LengthUnit>), KclError> {
let (axis, origin) = match self {
AxisAndOrigin3d::X => ([1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::Y => ([0.0, 1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::Z => ([0.0, 0.0, 1.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::NegX => ([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::NegY => ([0.0, -1.0, 0.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::NegZ => ([0.0, 0.0, -1.0], [0.0, 0.0, 0.0]),
AxisAndOrigin3d::Custom { axis, origin } => {
([axis[0], axis[1], axis[2]], [origin[0], origin[1], origin[2]])
}
};
Ok((
kcmc::shared::Point3d {
x: axis[0],
y: axis[1],
z: axis[2],
},
kcmc::shared::Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(origin[2]),
},
))
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use crate::std::axis_or_reference::{
Axis2dOrEdgeReference, Axis3dOrEdgeReference, AxisAndOrigin2d, AxisAndOrigin3d,
};
#[test]
fn test_deserialize_revolve_axis_2d() {
let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::X);
let mut str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, "\"X\"");
str_json = "\"Y\"".to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Y));
str_json = "\"-Y\"".to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegY));
str_json = "\"-x\"".to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::NegX));
let data = Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom {
axis: [0.0, -1.0],
origin: [1.0, 0.0],
});
str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0],"origin":[1.0,0.0]}}"#);
str_json = r#"{"custom": {"axis": [0,-1], "origin": [1,2.0]}}"#.to_string();
let data: Axis2dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(
data,
Axis2dOrEdgeReference::Axis(AxisAndOrigin2d::Custom {
axis: [0.0, -1.0],
origin: [1.0, 2.0]
})
);
}
#[test]
fn test_deserialize_revolve_axis_3d() {
let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::X);
let mut str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, "\"X\"");
str_json = "\"Y\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Y));
str_json = "\"Z\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Z));
str_json = "\"-Y\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegY));
str_json = "\"-x\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegX));
str_json = "\"-z\"".to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::NegZ));
let data = Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom {
axis: [0.0, -1.0, 0.0],
origin: [1.0, 0.0, 0.0],
});
str_json = serde_json::to_string(&data).unwrap();
assert_eq!(str_json, r#"{"custom":{"axis":[0.0,-1.0,0.0],"origin":[1.0,0.0,0.0]}}"#);
str_json = r#"{"custom": {"axis": [0,-1,0], "origin": [1,2.0,0]}}"#.to_string();
let data: Axis3dOrEdgeReference = serde_json::from_str(&str_json).unwrap();
assert_eq!(
data,
Axis3dOrEdgeReference::Axis(AxisAndOrigin3d::Custom {
axis: [0.0, -1.0, 0.0],
origin: [1.0, 2.0, 0.0]
})
);
}
}

View File

@ -1,13 +1,15 @@
//! Standard library helices. //! Standard library helices.
use anyhow::Result; use anyhow::Result;
use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
use kittycad_modeling_cmds as kcmc; use kittycad_modeling_cmds::{self as kcmc, shared::Point3d};
use crate::{ use crate::{
errors::KclError, errors::KclError,
execution::{ExecState, Helix as HelixValue, KclValue, Solid}, execution::{
types::{PrimitiveType, RuntimeType},
ExecState, Helix as HelixValue, KclValue, Solid,
},
std::{axis_or_reference::Axis3dOrEdgeReference, Args}, std::{axis_or_reference::Axis3dOrEdgeReference, Args},
}; };
@ -17,7 +19,14 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
let revolutions = args.get_kw_arg("revolutions")?; let revolutions = args.get_kw_arg("revolutions")?;
let ccw = args.get_kw_arg_opt("ccw")?; let ccw = args.get_kw_arg_opt("ccw")?;
let radius = args.get_kw_arg_opt("radius")?; let radius = args.get_kw_arg_opt("radius")?;
let axis = args.get_kw_arg_opt("axis")?; let axis: Option<Axis3dOrEdgeReference> = args.get_kw_arg_opt_typed(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Edge),
RuntimeType::Primitive(PrimitiveType::Axis3d),
]),
exec_state,
)?;
let length = args.get_kw_arg_opt("length")?; let length = args.get_kw_arg_opt("length")?;
let cylinder = args.get_kw_arg_opt("cylinder")?; let cylinder = args.get_kw_arg_opt("cylinder")?;
@ -84,100 +93,6 @@ pub async fn helix(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
Ok(KclValue::Helix { value }) Ok(KclValue::Helix { value })
} }
/// Create a helix.
///
/// ```no_run
/// // Create a helix around the Z axis.
/// 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')
/// |> circle( center = [0, 0], radius = 0.5)
/// |> sweep(path = helixPath)
/// ```
///
/// ```no_run
/// // Create a helix around an edge.
/// 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,
/// )
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('XY')
/// |> circle( center = [0, 0], radius = 0.5 )
/// |> sweep(path = helixPath)
/// ```
///
/// ```no_run
/// // Create a helix around a custom 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')
/// |> circle( center = [0, 0], radius = 1 )
/// |> sweep(path = helixPath)
/// ```
///
///
///
/// ```no_run
/// // Create a helix on a cylinder.
///
/// part001 = startSketchOn('XY')
/// |> circle( center= [5, 5], radius= 10 )
/// |> extrude(length = 10)
///
/// helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// cylinder = part001,
/// )
/// ```
#[stdlib {
name = "helix",
keywords = true,
unlabeled_first = false,
args = {
revolutions = { docs = "Number of revolutions."},
angle_start = { docs = "Start angle (in degrees)."},
ccw = { docs = "Is the helix rotation counter clockwise? The default is `false`.", include_in_snippet = false},
radius = { docs = "Radius of the helix.", include_in_snippet = true},
axis = { docs = "Axis to use for the helix.", include_in_snippet = true},
length = { docs = "Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used.", include_in_snippet = true},
cylinder = { docs = "Cylinder to create the helix on.", include_in_snippet = false},
},
feature_tree_operation = true,
}]
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
async fn inner_helix( async fn inner_helix(
revolutions: f64, revolutions: f64,
@ -221,9 +136,7 @@ async fn inner_helix(
.await?; .await?;
} else if let (Some(axis), Some(radius)) = (axis, radius) { } else if let (Some(axis), Some(radius)) = (axis, radius) {
match axis { match axis {
Axis3dOrEdgeReference::Axis(axis) => { Axis3dOrEdgeReference::Axis { direction, origin } => {
let (axis, origin) = axis.axis_and_origin()?;
// Make sure they gave us a length. // Make sure they gave us a length.
let Some(length) = length else { let Some(length) = length else {
return Err(KclError::Semantic(crate::errors::KclErrorDetails { return Err(KclError::Semantic(crate::errors::KclErrorDetails {
@ -240,8 +153,16 @@ async fn inner_helix(
length: LengthUnit(length), length: LengthUnit(length),
revolutions, revolutions,
start_angle: Angle::from_degrees(angle_start), start_angle: Angle::from_degrees(angle_start),
axis, axis: Point3d {
center: origin, x: direction[0],
y: direction[1],
z: direction[2],
},
center: Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(origin[2]),
},
}), }),
) )
.await?; .await?;

View File

@ -1,109 +1,39 @@
//! Standard library mirror. //! Standard library mirror.
use anyhow::Result; use anyhow::Result;
use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, ModelingCmd}; use kcmc::{each_cmd as mcmd, ModelingCmd};
use kittycad_modeling_cmds::{self as kcmc}; use kittycad_modeling_cmds::{self as kcmc, length_unit::LengthUnit, shared::Point3d};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::KclError, errors::KclError,
execution::{ExecState, KclValue, Sketch}, execution::{
types::{PrimitiveType, RuntimeType},
ExecState, KclValue, Sketch,
},
std::{axis_or_reference::Axis2dOrEdgeReference, Args}, std::{axis_or_reference::Axis2dOrEdgeReference, Args},
}; };
/// Data for a mirror.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Mirror2dData {
/// Axis to use as mirror.
pub axis: Axis2dOrEdgeReference,
}
/// Mirror a sketch. /// Mirror a sketch.
/// ///
/// Only works on unclosed sketches for now. /// Only works on unclosed sketches for now.
pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch_set): (Mirror2dData, Vec<Sketch>) = args.get_data_and_sketches(exec_state)?; let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let axis = args.get_kw_arg_typed(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Edge),
RuntimeType::Primitive(PrimitiveType::Axis2d),
]),
exec_state,
)?;
let sketches = inner_mirror_2d(data, sketch_set, exec_state, args).await?; let sketches = inner_mirror_2d(sketches, axis, exec_state, args).await?;
Ok(sketches.into()) Ok(sketches.into())
} }
/// Mirror a sketch.
///
/// Only works on unclosed sketches for now.
///
/// Mirror occurs around a local sketch axis rather than a global axis.
///
/// ```no_run
/// // Mirror an un-closed sketch across the Y axis.
/// sketch001 = startSketchOn('XZ')
/// |> startProfileAt([0, 10], %)
/// |> line(end = [15, 0])
/// |> line(end = [-7, -3])
/// |> line(end = [9, -1])
/// |> line(end = [-8, -5])
/// |> line(end = [9, -3])
/// |> line(end = [-8, -3])
/// |> line(end = [9, -1])
/// |> line(end = [-19, -0])
/// |> mirror2d({axis = 'Y'}, %)
///
/// example = extrude(sketch001, length = 10)
/// ```
///
/// ```no_run
/// // Mirror a un-closed sketch across the Y axis.
/// sketch001 = startSketchOn('XZ')
/// |> startProfileAt([0, 8.5], %)
/// |> line(end = [20, -8.5])
/// |> line(end = [-20, -8.5])
/// |> mirror2d({axis = 'Y'}, %)
///
/// example = extrude(sketch001, length = 10)
/// ```
///
/// ```no_run
/// // Mirror a un-closed sketch across an edge.
/// helper001 = startSketchOn('XZ')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 10], tag = $edge001)
///
/// sketch001 = startSketchOn('XZ')
/// |> startProfileAt([0, 8.5], %)
/// |> line(end = [20, -8.5])
/// |> line(end = [-20, -8.5])
/// |> mirror2d({axis = edge001}, %)
///
/// // example = extrude(sketch001, length = 10)
/// ```
///
/// ```no_run
/// // Mirror an un-closed sketch across a custom axis.
/// sketch001 = startSketchOn('XZ')
/// |> startProfileAt([0, 8.5], %)
/// |> line(end = [20, -8.5])
/// |> line(end = [-20, -8.5])
/// |> mirror2d({
/// axis = {
/// custom = {
/// axis = [0.0, 1.0],
/// origin = [0.0, 0.0]
/// }
/// }
/// }, %)
///
/// example = extrude(sketch001, length = 10)
/// ```
#[stdlib {
name = "mirror2d",
}]
async fn inner_mirror_2d( async fn inner_mirror_2d(
data: Mirror2dData,
sketches: Vec<Sketch>, sketches: Vec<Sketch>,
axis: Axis2dOrEdgeReference,
exec_state: &mut ExecState, exec_state: &mut ExecState,
args: Args, args: Args,
) -> Result<Vec<Sketch>, KclError> { ) -> Result<Vec<Sketch>, KclError> {
@ -113,16 +43,22 @@ async fn inner_mirror_2d(
return Ok(starting_sketches); return Ok(starting_sketches);
} }
match data.axis { match axis {
Axis2dOrEdgeReference::Axis(axis) => { Axis2dOrEdgeReference::Axis { direction, origin } => {
let (axis, origin) = axis.axis_and_origin()?;
args.batch_modeling_cmd( args.batch_modeling_cmd(
exec_state.next_uuid(), exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityMirror { ModelingCmd::from(mcmd::EntityMirror {
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(), ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
axis, axis: Point3d {
point: origin, x: direction[0],
y: direction[1],
z: 0.0,
},
point: Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(0.0),
},
}), }),
) )
.await?; .await?;

View File

@ -26,7 +26,6 @@ pub mod shell;
pub mod sketch; pub mod sketch;
pub mod sweep; pub mod sweep;
pub mod transform; pub mod transform;
pub mod types;
pub mod units; pub mod units;
pub mod utils; pub mod utils;
@ -96,7 +95,6 @@ lazy_static! {
Box::new(crate::std::sketch::TangentialArcToRelative), Box::new(crate::std::sketch::TangentialArcToRelative),
Box::new(crate::std::sketch::BezierCurve), Box::new(crate::std::sketch::BezierCurve),
Box::new(crate::std::sketch::Hole), Box::new(crate::std::sketch::Hole),
Box::new(crate::std::mirror::Mirror2D),
Box::new(crate::std::patterns::PatternLinear2D), Box::new(crate::std::patterns::PatternLinear2D),
Box::new(crate::std::patterns::PatternLinear3D), Box::new(crate::std::patterns::PatternLinear3D),
Box::new(crate::std::patterns::PatternCircular2D), Box::new(crate::std::patterns::PatternCircular2D),
@ -113,10 +111,8 @@ lazy_static! {
Box::new(crate::std::edge::GetNextAdjacentEdge), Box::new(crate::std::edge::GetNextAdjacentEdge),
Box::new(crate::std::edge::GetPreviousAdjacentEdge), Box::new(crate::std::edge::GetPreviousAdjacentEdge),
Box::new(crate::std::edge::GetCommonEdge), Box::new(crate::std::edge::GetCommonEdge),
Box::new(crate::std::helix::Helix),
Box::new(crate::std::shell::Shell), Box::new(crate::std::shell::Shell),
Box::new(crate::std::shell::Hollow), Box::new(crate::std::shell::Hollow),
Box::new(crate::std::revolve::Revolve),
Box::new(crate::std::sweep::Sweep), Box::new(crate::std::sweep::Sweep),
Box::new(crate::std::loft::Loft), Box::new(crate::std::loft::Loft),
Box::new(crate::std::planes::OffsetPlane), Box::new(crate::std::planes::OffsetPlane),
@ -177,6 +173,7 @@ pub fn get_stdlib_fn(name: &str) -> Option<Box<dyn StdLibFn>> {
pub struct StdFnProps { pub struct StdFnProps {
pub name: String, pub name: String,
pub deprecated: bool, pub deprecated: bool,
pub include_in_feature_tree: bool,
} }
impl StdFnProps { impl StdFnProps {
@ -184,8 +181,14 @@ impl StdFnProps {
Self { Self {
name: name.to_owned(), name: name.to_owned(),
deprecated: false, deprecated: false,
include_in_feature_tree: false,
} }
} }
fn include_in_feature_tree(mut self) -> Self {
self.include_in_feature_tree = true;
self
}
} }
pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProps) { pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProps) {
@ -206,6 +209,18 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
|e, a| Box::pin(crate::std::shapes::circle(e, a)), |e, a| Box::pin(crate::std::shapes::circle(e, a)),
StdFnProps::default("std::sketch::circle"), StdFnProps::default("std::sketch::circle"),
), ),
("prelude", "helix") => (
|e, a| Box::pin(crate::std::helix::helix(e, a)),
StdFnProps::default("std::helix").include_in_feature_tree(),
),
("sketch", "mirror2d") => (
|e, a| Box::pin(crate::std::mirror::mirror_2d(e, a)),
StdFnProps::default("std::sketch::mirror2d"),
),
("prelude", "revolve") => (
|e, a| Box::pin(crate::std::revolve::revolve(e, a)),
StdFnProps::default("std::revolve").include_in_feature_tree(),
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -217,6 +232,9 @@ pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) {
("prelude", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::Plane")), ("prelude", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::Plane")),
("prelude", "Face") => (PrimitiveType::Face, StdFnProps::default("std::Face")), ("prelude", "Face") => (PrimitiveType::Face, StdFnProps::default("std::Face")),
("prelude", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::Helix")), ("prelude", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::Helix")),
("prelude", "Edge") => (PrimitiveType::Edge, StdFnProps::default("std::Edge")),
("prelude", "Axis2d") => (PrimitiveType::Axis2d, StdFnProps::default("std::Axis2d")),
("prelude", "Axis3d") => (PrimitiveType::Axis3d, StdFnProps::default("std::Axis3d")),
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -1,13 +1,15 @@
//! Standard library revolution surfaces. //! Standard library revolution surfaces.
use anyhow::Result; use anyhow::Result;
use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
use kittycad_modeling_cmds::{self as kcmc}; use kittycad_modeling_cmds::{self as kcmc, shared::Point3d};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, execution::{
types::{PrimitiveType, RuntimeType},
ExecState, KclValue, Sketch, Solid,
},
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args}, std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args},
}; };
@ -15,7 +17,14 @@ use crate::{
/// Revolve a sketch or set of sketches around an axis. /// Revolve a sketch or set of sketches around an axis.
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
let axis: Axis2dOrEdgeReference = args.get_kw_arg("axis")?; let axis = args.get_kw_arg_typed(
"axis",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Edge),
RuntimeType::Primitive(PrimitiveType::Axis2d),
]),
exec_state,
)?;
let angle = args.get_kw_arg_opt("angle")?; let angle = args.get_kw_arg_opt("angle")?;
let tolerance = args.get_kw_arg_opt("tolerance")?; let tolerance = args.get_kw_arg_opt("tolerance")?;
let tag_start = args.get_kw_arg_opt("tagStart")?; let tag_start = args.get_kw_arg_opt("tagStart")?;
@ -25,215 +34,6 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
Ok(value.into()) Ok(value.into())
} }
/// Rotate a sketch around some provided axis, creating a solid from its extent.
///
/// This, like extrude, is able to create a 3-dimensional solid from a
/// 2-dimensional sketch. However, unlike extrude, this creates a solid
/// by using the extent of the sketch as its revolved around an axis rather
/// than using the extent of the sketch linearly translated through a third
/// dimension.
///
/// Revolve occurs around a local sketch axis rather than a global axis.
///
/// You can provide more than one sketch to revolve, and they will all be
/// revolved around the same axis.
///
/// ```no_run
/// part001 = startSketchOn('XY')
/// |> startProfileAt([4, 12], %)
/// |> line(end = [2, 0])
/// |> line(end = [0, -6])
/// |> line(end = [4, -6])
/// |> line(end = [0, -6])
/// |> line(end = [-3.75, -4.5])
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve(axis = 'y') // default angle is 360
/// ```
///
/// ```no_run
/// // A donut shape.
/// sketch001 = startSketchOn('XY')
/// |> circle( center = [15, 0], radius = 5 )
/// |> revolve(
/// angle = 360,
/// axis = 'y'
/// )
/// ```
///
/// ```no_run
/// part001 = startSketchOn('XY')
/// |> startProfileAt([4, 12], %)
/// |> line(end = [2, 0])
/// |> line(end = [0, -6])
/// |> line(end = [4, -6])
/// |> line(end = [0, -6])
/// |> line(end = [-3.75, -4.5])
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve(axis = 'y', angle = 180)
/// ```
///
/// ```no_run
/// part001 = startSketchOn('XY')
/// |> startProfileAt([4, 12], %)
/// |> line(end = [2, 0])
/// |> line(end = [0, -6])
/// |> line(end = [4, -6])
/// |> line(end = [0, -6])
/// |> line(end = [-3.75, -4.5])
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve(axis = 'y', angle = 180)
///
/// part002 = startSketchOn(part001, 'end')
/// |> startProfileAt([4.5, -5], %)
/// |> line(end = [0, 5])
/// |> line(end = [5, 0])
/// |> line(end = [0, -5])
/// |> close()
/// |> extrude(length = 5)
/// ```
///
/// ```no_run
/// box = startSketchOn('XY')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20])
/// |> line(end = [20, 0])
/// |> line(end = [0, -20])
/// |> close()
/// |> extrude(length = 20)
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve(
/// angle = -90,
/// axis = 'y'
/// )
/// ```
///
/// ```no_run
/// box = startSketchOn('XY')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20])
/// |> line(end = [20, 0])
/// |> line(end = [0, -20], tag = $revolveAxis)
/// |> close()
/// |> extrude(length = 20)
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve(
/// angle = 90,
/// axis = getOppositeEdge(revolveAxis)
/// )
/// ```
///
/// ```no_run
/// box = startSketchOn('XY')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20])
/// |> line(end = [20, 0])
/// |> line(end = [0, -20], tag = $revolveAxis)
/// |> close()
/// |> extrude(length = 20)
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve(
/// angle = 90,
/// axis = getOppositeEdge(revolveAxis),
/// tolerance = 0.0001
/// )
/// ```
///
/// ```no_run
/// sketch001 = startSketchOn('XY')
/// |> startProfileAt([10, 0], %)
/// |> line(end = [5, -5])
/// |> line(end = [5, 5])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// part001 = revolve(
/// sketch001,
/// axis = {
/// custom: {
/// axis = [0.0, 1.0],
/// origin: [0.0, 0.0]
/// }
/// }
/// )
/// ```
///
/// ```no_run
/// // Revolve two sketches around the same axis.
///
/// sketch001 = startSketchOn('XY')
/// profile001 = startProfileAt([4, 8], sketch001)
/// |> xLine(length = 3)
/// |> yLine(length = -3)
/// |> xLine(length = -3)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// profile002 = startProfileAt([-5, 8], sketch001)
/// |> xLine(length = 3)
/// |> yLine(length = -3)
/// |> xLine(length = -3)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// revolve(
/// [profile001, profile002],
/// axis = "X",
/// )
/// ```
///
/// ```no_run
/// // Revolve around a path that has not been extruded.
///
/// profile001 = startSketchOn('XY')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20], tag = $revolveAxis)
/// |> line(end = [20, 0])
/// |> line(end = [0, -20])
/// |> close(%)
///
/// sketch001 = startSketchOn('XY')
/// |> circle(center = [-10, 10], radius = 4)
/// |> revolve(angle = 90, axis = revolveAxis)
/// ```
///
/// ```no_run
/// // Revolve around a path that has not been extruded or closed.
///
/// profile001 = startSketchOn('XY')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20], tag = $revolveAxis)
/// |> line(end = [20, 0])
///
/// sketch001 = startSketchOn('XY')
/// |> circle(center = [-10, 10], radius = 4)
/// |> revolve(angle = 90, axis = revolveAxis)
/// ```
#[stdlib {
name = "revolve",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
sketches = { docs = "The sketch or set of sketches that should be revolved" },
axis = { docs = "Axis of revolution." },
angle = { docs = "Angle to revolve (in degrees). Default is 360." },
tolerance = { docs = "Tolerance for the revolve operation." },
tag_start = { docs = "A named tag for the face at the start of the revolve, i.e. the original sketch" },
tag_end = { docs = "A named tag for the face at the end of the revolve" },
}
}]
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
async fn inner_revolve( async fn inner_revolve(
sketches: Vec<Sketch>, sketches: Vec<Sketch>,
@ -264,15 +64,22 @@ async fn inner_revolve(
let id = exec_state.next_uuid(); let id = exec_state.next_uuid();
match &axis { match &axis {
Axis2dOrEdgeReference::Axis(axis) => { Axis2dOrEdgeReference::Axis { direction, origin } => {
let (axis, origin) = axis.axis_and_origin()?;
args.batch_modeling_cmd( args.batch_modeling_cmd(
id, id,
ModelingCmd::from(mcmd::Revolve { ModelingCmd::from(mcmd::Revolve {
angle, angle,
target: sketch.id.into(), target: sketch.id.into(),
axis, axis: Point3d {
origin, x: direction[0],
y: direction[1],
z: 0.0,
},
origin: Point3d {
x: LengthUnit(origin[0]),
y: LengthUnit(origin[1]),
z: LengthUnit(0.0),
},
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
axis_is_2d: true, axis_is_2d: true,
}), }),

View File

@ -1021,7 +1021,7 @@ pub async fn start_sketch_on(exec_state: &mut ExecState, args: Args) -> Result<K
/// |> line(end = [-2, 0]) /// |> line(end = [-2, 0])
/// |> close() /// |> close()
/// ///
/// example = revolve(exampleSketch, axis = 'y', angle = 180) /// example = revolve(exampleSketch, axis = Y, angle = 180)
/// ///
/// exampleSketch002 = startSketchOn(example, 'end') /// exampleSketch002 = startSketchOn(example, 'end')
/// |> startProfileAt([4.5, -5], %) /// |> startProfileAt([4.5, -5], %)
@ -1047,7 +1047,7 @@ pub async fn start_sketch_on(exec_state: &mut ExecState, args: Args) -> Result<K
/// |> line(end = [-2, 0]) /// |> line(end = [-2, 0])
/// |> close() /// |> close()
/// ///
/// example = revolve(exampleSketch, axis = 'y', angle = 180, tagEnd = $end01) /// example = revolve(exampleSketch, axis = Y, angle = 180, tagEnd = $end01)
/// ///
/// exampleSketch002 = startSketchOn(example, end01) /// exampleSketch002 = startSketchOn(example, end01)
/// |> startProfileAt([4.5, -5], %) /// |> startProfileAt([4.5, -5], %)

View File

@ -54,7 +54,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// // Create a pipe using a sweep. /// // Create a pipe using a sweep.
/// ///
/// // Create a path for the sweep. /// // Create a path for the sweep.
/// sweepPath = startSketchOn('XZ') /// sweepPath = startSketchOn(XZ)
/// |> startProfileAt([0.05, 0.05], %) /// |> startProfileAt([0.05, 0.05], %)
/// |> line(end = [0, 7]) /// |> line(end = [0, 7])
/// |> tangentialArc({ /// |> tangentialArc({
@ -69,13 +69,13 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// |> line(end = [0, 7]) /// |> line(end = [0, 7])
/// ///
/// // Create a hole for the pipe. /// // Create a hole for the pipe.
/// pipeHole = startSketchOn('XY') /// pipeHole = startSketchOn(XY)
/// |> circle( /// |> circle(
/// center = [0, 0], /// center = [0, 0],
/// radius = 1.5, /// radius = 1.5,
/// ) /// )
/// ///
/// sweepSketch = startSketchOn('XY') /// sweepSketch = startSketchOn(XY)
/// |> circle( /// |> circle(
/// center = [0, 0], /// center = [0, 0],
/// radius = 2, /// radius = 2,
@ -94,12 +94,12 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// revolutions = 4, /// revolutions = 4,
/// length = 10, /// length = 10,
/// radius = 5, /// radius = 5,
/// axis = 'Z', /// axis = Z,
/// ) /// )
/// ///
/// ///
/// // Create a spring by sweeping around the helix path. /// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn('YZ') /// springSketch = startSketchOn(YZ)
/// |> circle( center = [0, 0], radius = 1) /// |> circle( center = [0, 0], radius = 1)
/// |> sweep(path = helixPath) /// |> sweep(path = helixPath)
/// ``` /// ```
@ -107,7 +107,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// ``` /// ```
/// // Sweep two sketches along the same path. /// // Sweep two sketches along the same path.
/// ///
/// sketch001 = startSketchOn('XY') /// sketch001 = startSketchOn(XY)
/// rectangleSketch = startProfileAt([-200, 23.86], sketch001) /// rectangleSketch = startProfileAt([-200, 23.86], sketch001)
/// |> angledLine([0, 73.47], %, $rectangleSegmentA001) /// |> angledLine([0, 73.47], %, $rectangleSegmentA001)
/// |> angledLine([ /// |> angledLine([
@ -123,7 +123,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// ///
/// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) /// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
/// ///
/// sketch002 = startSketchOn('YZ') /// sketch002 = startSketchOn(YZ)
/// sweepPath = startProfileAt([0, 0], sketch002) /// sweepPath = startProfileAt([0, 0], sketch002)
/// |> yLine(length = 231.81) /// |> yLine(length = 231.81)
/// |> tangentialArc({ /// |> tangentialArc({
@ -137,7 +137,7 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// ``` /// ```
/// // Sectionally sweep one sketch along the path /// // Sectionally sweep one sketch along the path
/// ///
/// sketch001 = startSketchOn('XY') /// sketch001 = startSketchOn(XY)
/// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) /// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
/// ///
/// sketch002 = startSketchOn('YZ') /// sketch002 = startSketchOn('YZ')

View File

@ -1 +0,0 @@

View File

@ -1235,7 +1235,7 @@ insideRevolve = startSketchOn(XZ)
|> line([0, -thickness], %) |> line([0, -thickness], %)
|> line([-overHangLength, 0], %) |> line([-overHangLength, 0], %)
|> close() |> close()
|> revolve({ axis: 'y' }, %) |> revolve({ axis = Y }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn(XZ) sphere = startSketchOn(XZ)
@ -1250,7 +1250,7 @@ sphere = startSketchOn(XZ)
radius = sphereDia / 2 - 0.05 radius = sphereDia / 2 - 0.05
}, %) }, %)
|> close() |> close()
|> revolve({ axis: 'x' }, %) |> revolve({ axis = X }, %)
|> patternCircular3d( |> patternCircular3d(
axis = [0, 0, 1], axis = [0, 0, 1],
center = [0, 0, 0], center = [0, 0, 0],
@ -1274,7 +1274,7 @@ outsideRevolve = startSketchOn(XZ)
|> line([0, thickness], %) |> line([0, thickness], %)
|> line([overHangLength - thickness, 0], %) |> line([overHangLength - thickness, 0], %)
|> close() |> close()
|> revolve({ axis: 'y' }, %)"#; |> revolve({ axis = Y }, %)"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap(); let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let recasted = program.recast(&Default::default(), 0); let recasted = program.recast(&Default::default(), 0);
@ -1301,7 +1301,7 @@ insideRevolve = startSketchOn(XZ)
|> line([0, -thickness], %) |> line([0, -thickness], %)
|> line([-overHangLength, 0], %) |> line([-overHangLength, 0], %)
|> close() |> close()
|> revolve({ axis = 'y' }, %) |> revolve({ axis = Y }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis) // Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn(XZ) sphere = startSketchOn(XZ)
@ -1316,7 +1316,7 @@ sphere = startSketchOn(XZ)
radius = sphereDia / 2 - 0.05 radius = sphereDia / 2 - 0.05
}, %) }, %)
|> close() |> close()
|> revolve({ axis = 'x' }, %) |> revolve({ axis = X }, %)
|> patternCircular3d( |> patternCircular3d(
axis = [0, 0, 1], axis = [0, 0, 1],
center = [0, 0, 0], center = [0, 0, 0],
@ -1340,7 +1340,7 @@ outsideRevolve = startSketchOn(XZ)
|> line([0, thickness], %) |> line([0, thickness], %)
|> line([overHangLength - thickness, 0], %) |> line([overHangLength - thickness, 0], %)
|> close() |> close()
|> revolve({ axis = 'y' }, %) |> revolve({ axis = Y }, %)
"# "#
); );
} }
@ -1613,9 +1613,9 @@ fn bracketSketch = (w, d, t) => {
s = startSketchOn({ s = startSketchOn({
plane: { plane: {
origin: { x = 0, y = length / 2 + thk, z = 0 }, origin: { x = 0, y = length / 2 + thk, z = 0 },
x_axis: { x = 1, y = 0, z = 0 }, x_axis = { x = 1, y = 0, z = 0 },
y_axis: { x = 0, y = 0, z = 1 }, y_axis = { x = 0, y = 0, z = 1 },
z_axis: { x = 0, y = 1, z = 0 } z_axis = { x = 0, y = 1, z = 0 }
} }
}) })
|> startProfileAt([-w / 2 - t, d + t], %) |> startProfileAt([-w / 2 - t, d + t], %)
@ -1645,9 +1645,9 @@ bracket_body = bracketSketch(width, depth, thk)
tabs_r = startSketchOn({ tabs_r = startSketchOn({
plane: { plane: {
origin: { x = 0, y = 0, z = depth + thk }, origin: { x = 0, y = 0, z = depth + thk },
x_axis: { x = 1, y = 0, z = 0 }, x_axis = { x = 1, y = 0, z = 0 },
y_axis: { x = 0, y = 1, z = 0 }, y_axis = { x = 0, y = 1, z = 0 },
z_axis: { x = 0, y = 0, z = 1 } z_axis = { x = 0, y = 0, z = 1 }
} }
}) })
|> startProfileAt([width / 2 + thk, length / 2 + thk], %) |> startProfileAt([width / 2 + thk, length / 2 + thk], %)
@ -2528,9 +2528,9 @@ fn f() {
sketch002 = startSketchOn({ sketch002 = startSketchOn({
plane: { plane: {
origin: { x = 1, y = 2, z = 3 }, origin: { x = 1, y = 2, z = 3 },
x_axis: { x = 4, y = 5, z = 6 }, x_axis = { x = 4, y = 5, z = 6 },
y_axis: { x = 7, y = 8, z = 9 }, y_axis = { x = 7, y = 8, z = 9 },
z_axis: { x = 10, y = 11, z = 12 } z_axis = { x = 10, y = 11, z = 12 }
} }
}) })
"#; "#;

View File

@ -5,6 +5,7 @@
export import * from "std::math" export import * from "std::math"
export import * from "std::sketch" export import * from "std::sketch"
export import "std::turns"
/// A number /// A number
/// ///
@ -233,6 +234,10 @@ export type Face
@(impl = std_rust) @(impl = std_rust)
export type Helix export type Helix
/// The edge of a solid.
@(impl = std_rust)
export type Edge
/// A point in two dimensional space. /// A point in two dimensional space.
/// ///
/// `Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value /// `Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value
@ -245,11 +250,6 @@ export type Point2d = [number; 2]
/// with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`. /// with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`.
export type Point3d = [number; 3] export type Point3d = [number; 3]
export ZERO = 0
export QUARTER_TURN = 90deg
export HALF_TURN = 180deg
export THREE_QUARTER_TURN = 270deg
export XY = { export XY = {
origin = { x = 0, y = 0, z = 0 }, origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 1, y = 0, z = 0 }, xAxis = { x = 1, y = 0, z = 0 },
@ -270,3 +270,330 @@ export YZ = {
yAxis = { x = 0, y = 0, z = 1 }, yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 1, y = 0, z = 0 }, zAxis = { x = 1, y = 0, z = 0 },
}: Plane }: Plane
/// An infinte line in 2d space.
@(impl = std_rust)
export type Axis2d
/// An infinte line in 3d space.
@(impl = std_rust)
export type Axis3d
export X = {
origin = [0, 0, 0],
direction = [1, 0, 0],
}: Axis3d
export Y = {
origin = [0, 0, 0],
direction = [0, 1, 0],
}: Axis3d
export Z = {
origin = [0, 0, 0],
direction = [0, 0, 1],
}: Axis3d
/// Create a helix.
///
/// ```
/// // Create a helix around the Z axis.
/// 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)
/// |> circle( center = [0, 0], radius = 0.5)
/// |> sweep(path = helixPath)
/// ```
///
/// ```
/// // Create a helix around an edge.
/// 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,
/// )
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn(XY)
/// |> circle( center = [0, 0], radius = 0.5 )
/// |> sweep(path = helixPath)
/// ```
///
/// ```
/// // Create a helix around a custom axis.
/// helixPath = helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 5,
/// length = 10,
/// radius = 5,
/// axis = {
/// direction = [0, 0, 1.0],
/// origin = [0, 0.25, 0]
/// }
/// )
///
/// // Create a spring by sweeping around the helix path.
/// springSketch = startSketchOn(XY)
/// |> circle( center = [0, 0], radius = 1 )
/// |> sweep(path = helixPath)
/// ```
///
/// ```
/// // Create a helix on a cylinder.
///
/// part001 = startSketchOn(XY)
/// |> circle( center= [5, 5], radius= 10 )
/// |> extrude(length = 10)
///
/// helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 16,
/// cylinder = part001,
/// )
/// ```
@(impl = std_rust)
export fn helix(
/// Number of revolutions.
revolutions: number(_),
/// Start angle (in degrees).
angleStart: number(deg),
/// Is the helix rotation counter clockwise? The default is `false`.
ccw?: bool,
/// Radius of the helix.
@(include_in_snippet = true)
radius?: number(mm),
/// Axis to use for the helix.
@(include_in_snippet = true)
axis?: Axis3d | Edge,
/// Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used.
@(include_in_snippet = true)
length?: number(mm),
/// Cylinder to create the helix on.
cylinder?: Solid,
): Helix {}
/// Rotate a sketch around some provided axis, creating a solid from its extent.
///
/// This, like extrude, is able to create a 3-dimensional solid from a
/// 2-dimensional sketch. However, unlike extrude, this creates a solid
/// by using the extent of the sketch as its revolved around an axis rather
/// than using the extent of the sketch linearly translated through a third
/// dimension.
///
/// Revolve occurs around a local sketch axis rather than a global axis.
///
/// You can provide more than one sketch to revolve, and they will all be
/// revolved around the same axis.
///
/// ```
/// part001 = startSketchOn(XY)
/// |> startProfileAt([4, 12], %)
/// |> line(end = [2, 0])
/// |> line(end = [0, -6])
/// |> line(end = [4, -6])
/// |> line(end = [0, -6])
/// |> line(end = [-3.75, -4.5])
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve(axis = Y) // default angle is 360
/// ```
///
/// ```
/// // A donut shape.
/// sketch001 = startSketchOn(XY)
/// |> circle( center = [15, 0], radius = 5 )
/// |> revolve(
/// angle = 360,
/// axis = Y,
/// )
/// ```
///
/// ```
/// part001 = startSketchOn(XY)
/// |> startProfileAt([4, 12], %)
/// |> line(end = [2, 0])
/// |> line(end = [0, -6])
/// |> line(end = [4, -6])
/// |> line(end = [0, -6])
/// |> line(end = [-3.75, -4.5])
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve(axis = Y, angle = 180)
/// ```
///
/// ```
/// part001 = startSketchOn(XY)
/// |> startProfileAt([4, 12], %)
/// |> line(end = [2, 0])
/// |> line(end = [0, -6])
/// |> line(end = [4, -6])
/// |> line(end = [0, -6])
/// |> line(end = [-3.75, -4.5])
/// |> line(end = [0, -5.5])
/// |> line(end = [-2, 0])
/// |> close()
/// |> revolve(axis = Y, angle = 180)
///
/// part002 = startSketchOn(part001, 'end')
/// |> startProfileAt([4.5, -5], %)
/// |> line(end = [0, 5])
/// |> line(end = [5, 0])
/// |> line(end = [0, -5])
/// |> close()
/// |> extrude(length = 5)
/// ```
///
/// ```
/// box = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20])
/// |> line(end = [20, 0])
/// |> line(end = [0, -20])
/// |> close()
/// |> extrude(length = 20)
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve(
/// angle = -90,
/// axis = Y
/// )
/// ```
///
/// ```
/// box = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20])
/// |> line(end = [20, 0])
/// |> line(end = [0, -20], tag = $revolveAxis)
/// |> close()
/// |> extrude(length = 20)
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve(
/// angle = 90,
/// axis = getOppositeEdge(revolveAxis)
/// )
/// ```
///
/// ```
/// box = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20])
/// |> line(end = [20, 0])
/// |> line(end = [0, -20], tag = $revolveAxis)
/// |> close()
/// |> extrude(length = 20)
///
/// sketch001 = startSketchOn(box, "END")
/// |> circle( center = [10,10], radius = 4 )
/// |> revolve(
/// angle = 90,
/// axis = getOppositeEdge(revolveAxis),
/// tolerance = 0.0001
/// )
/// ```
///
/// ```
/// sketch001 = startSketchOn(XY)
/// |> startProfileAt([10, 0], %)
/// |> line(end = [5, -5])
/// |> line(end = [5, 5])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// part001 = revolve(
/// sketch001,
/// axis = {
/// direction = [0.0, 1.0],
/// origin: [0.0, 0.0]
/// }
/// )
/// ```
///
/// ```
/// // Revolve two sketches around the same axis.
///
/// sketch001 = startSketchOn(XY)
/// profile001 = startProfileAt([4, 8], sketch001)
/// |> xLine(length = 3)
/// |> yLine(length = -3)
/// |> xLine(length = -3)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// profile002 = startProfileAt([-5, 8], sketch001)
/// |> xLine(length = 3)
/// |> yLine(length = -3)
/// |> xLine(length = -3)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// revolve(
/// [profile001, profile002],
/// axis = X,
/// )
/// ```
///
/// ```
/// // Revolve around a path that has not been extruded.
///
/// profile001 = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20], tag = $revolveAxis)
/// |> line(end = [20, 0])
/// |> line(end = [0, -20])
/// |> close(%)
///
/// sketch001 = startSketchOn(XY)
/// |> circle(center = [-10, 10], radius = 4)
/// |> revolve(angle = 90, axis = revolveAxis)
/// ```
///
/// ```
/// // Revolve around a path that has not been extruded or closed.
///
/// profile001 = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 20], tag = $revolveAxis)
/// |> line(end = [20, 0])
///
/// sketch001 = startSketchOn(XY)
/// |> circle(center = [-10, 10], radius = 4)
/// |> revolve(angle = 90, axis = revolveAxis)
/// ```
@(impl = std_rust)
export fn revolve(
/// The sketch or set of sketches that should be revolved
@sketches: [Sketch; 1+],
/// Axis of revolution.
axis: Axis2d | Edge,
/// Angle to revolve (in degrees). Default is 360.
angle?: number(deg),
/// Tolerance for the revolve operation.
tolerance?: number(mm),
/// A named tag for the face at the start of the revolve, i.e. the original sketch.
tagStart?: tag,
/// A named tag for the face at the end of the revolve.
tagEnd?: tag,
): Solid {}

View File

@ -32,3 +32,74 @@ export fn circle(
/// Create a new tag which refers to this circle. /// Create a new tag which refers to this circle.
tag?: tag, tag?: tag,
): Sketch {} ): Sketch {}
/// Mirror a sketch.
///
/// Only works on unclosed sketches for now.
///
/// Mirror occurs around a local sketch axis rather than a global axis.
///
/// ```
/// // Mirror an un-closed sketch across the Y axis.
/// sketch001 = startSketchOn(XZ)
/// |> startProfileAt([0, 10], %)
/// |> line(end = [15, 0])
/// |> line(end = [-7, -3])
/// |> line(end = [9, -1])
/// |> line(end = [-8, -5])
/// |> line(end = [9, -3])
/// |> line(end = [-8, -3])
/// |> line(end = [9, -1])
/// |> line(end = [-19, -0])
/// |> mirror2d(axis = Y)
///
/// example = extrude(sketch001, length = 10)
/// ```
///
/// ```
/// // Mirror a un-closed sketch across the Y axis.
/// sketch001 = startSketchOn(XZ)
/// |> startProfileAt([0, 8.5], %)
/// |> line(end = [20, -8.5])
/// |> line(end = [-20, -8.5])
/// |> mirror2d(axis = Y)
///
/// example = extrude(sketch001, length = 10)
/// ```
///
/// ```
/// // Mirror a un-closed sketch across an edge.
/// helper001 = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [0, 10], tag = $edge001)
///
/// sketch001 = startSketchOn(XZ)
/// |> startProfileAt([0, 8.5], %)
/// |> line(end = [20, -8.5])
/// |> line(end = [-20, -8.5])
/// |> mirror2d(axis = edge001)
///
/// // example = extrude(sketch001, length = 10)
/// ```
///
/// ```
/// // Mirror an un-closed sketch across a custom axis.
/// sketch001 = startSketchOn(XZ)
/// |> startProfileAt([0, 8.5], %)
/// |> line(end = [20, -8.5])
/// |> line(end = [-20, -8.5])
/// |> mirror2d(
/// axis = {
/// direction = [0.0, 1.0],
/// origin = [0.0, 0.0]
/// })
///
/// example = extrude(sketch001, length = 10)
/// ```
@(impl = std_rust)
export fn mirror2d(
/// The sketch or sketches to be reflected.
@sketches: [Sketch; 1+],
/// The axis to refect around.
axis: Axis2d | Edge,
): Sketch {}

View File

@ -0,0 +1,6 @@
@no_std
export ZERO = 0
export QUARTER_TURN = 90deg
export HALF_TURN = 180deg
export THREE_QUARTER_TURN = 270deg

View File

@ -1,25 +1,25 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[76, 113, 4]"] 2["Path<br>[76, 113, 5]"]
3["Segment<br>[119, 136, 4]"] 3["Segment<br>[119, 136, 5]"]
4["Segment<br>[142, 160, 4]"] 4["Segment<br>[142, 160, 5]"]
5["Segment<br>[166, 184, 4]"] 5["Segment<br>[166, 184, 5]"]
6["Segment<br>[190, 246, 4]"] 6["Segment<br>[190, 246, 5]"]
7["Segment<br>[252, 259, 4]"] 7["Segment<br>[252, 259, 5]"]
8[Solid2d] 8[Solid2d]
end end
subgraph path25 [Path] subgraph path25 [Path]
25["Path<br>[76, 111, 5]"] 25["Path<br>[76, 111, 6]"]
26["Segment<br>[117, 134, 5]"] 26["Segment<br>[117, 134, 6]"]
27["Segment<br>[140, 158, 5]"] 27["Segment<br>[140, 158, 6]"]
28["Segment<br>[164, 182, 5]"] 28["Segment<br>[164, 182, 6]"]
29["Segment<br>[188, 244, 5]"] 29["Segment<br>[188, 244, 6]"]
30["Segment<br>[250, 257, 5]"] 30["Segment<br>[250, 257, 6]"]
31[Solid2d] 31[Solid2d]
end end
1["Plane<br>[47, 66, 4]"] 1["Plane<br>[47, 66, 5]"]
9["Sweep Extrusion<br>[265, 287, 4]"] 9["Sweep Extrusion<br>[265, 287, 5]"]
10[Wall] 10[Wall]
11[Wall] 11[Wall]
12[Wall] 12[Wall]
@ -34,8 +34,8 @@ flowchart LR
21["SweepEdge Adjacent"] 21["SweepEdge Adjacent"]
22["SweepEdge Opposite"] 22["SweepEdge Opposite"]
23["SweepEdge Adjacent"] 23["SweepEdge Adjacent"]
24["Plane<br>[47, 66, 5]"] 24["Plane<br>[47, 66, 6]"]
32["Sweep Extrusion<br>[263, 285, 5]"] 32["Sweep Extrusion<br>[263, 285, 6]"]
33[Wall] 33[Wall]
34[Wall] 34[Wall]
35[Wall] 35[Wall]

View File

@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_mixed_units_cubes.kcl
{ {
"cubeIn": { "cubeIn": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
}, },
"cubeMm": { "cubeMm": {
"type": "Module", "type": "Module",
"value": 5 "value": 6
} }
} }

View File

@ -1,17 +1,17 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[197, 232, 4]"] 2["Path<br>[197, 232, 5]"]
3["Segment<br>[197, 232, 4]"] 3["Segment<br>[197, 232, 5]"]
4[Solid2d] 4[Solid2d]
end end
subgraph path6 [Path] subgraph path6 [Path]
6["Path<br>[113, 148, 5]"] 6["Path<br>[113, 148, 6]"]
7["Segment<br>[113, 148, 5]"] 7["Segment<br>[113, 148, 6]"]
8[Solid2d] 8[Solid2d]
end end
1["Plane<br>[172, 191, 4]"] 1["Plane<br>[172, 191, 5]"]
5["Plane<br>[88, 107, 5]"] 5["Plane<br>[88, 107, 6]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 --- 4 2 --- 4

View File

@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_non_default_units.kcl
{ {
"other1": { "other1": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
}, },
"other2": { "other2": {
"type": "Module", "type": "Module",
"value": 5 "value": 6
} }
} }

View File

@ -148,6 +148,22 @@ description: Operations executed crazy_multi_profile.kcl
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "revolve",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": { "labeledArgs": {
"angle": { "angle": {
"value": { "value": {
@ -173,19 +189,55 @@ description: Operations executed crazy_multi_profile.kcl
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "revolve", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Array",
"value": [
{
"type": "Sketch", "type": "Sketch",
"value": { "value": {
"artifactId": "[uuid]" "artifactId": "[uuid]"
} }
}
]
},
"sourceRange": []
},
"labeledArgs": {
"angle": {
"value": {
"type": "Number",
"value": 45.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"axis": {
"value": {
"type": "Uuid",
"value": "[uuid]"
}, },
"sourceRange": [] "sourceRange": []
} }
}, },
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -338,6 +390,22 @@ description: Operations executed crazy_multi_profile.kcl
} }
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "revolve",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": { "labeledArgs": {
"angle": { "angle": {
"value": { "value": {
@ -364,17 +432,54 @@ description: Operations executed crazy_multi_profile.kcl
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "revolve", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Array",
"value": [
{
"type": "Sketch", "type": "Sketch",
"value": { "value": {
"artifactId": "[uuid]" "artifactId": "[uuid]"
} }
}
]
},
"sourceRange": []
},
"labeledArgs": {
"angle": {
"value": {
"type": "Number",
"value": 45.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"axis": {
"value": {
"type": "TagIdentifier",
"value": "seg02",
"artifact_id": "[uuid]"
}, },
"sourceRange": [] "sourceRange": []
} }
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
} }
] ]

View File

@ -117,6 +117,14 @@ description: Operations executed helix_ccw.kcl
} }
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "helix",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": { "labeledArgs": {
"angleStart": { "angleStart": {
"value": { "value": {
@ -167,9 +175,11 @@ description: Operations executed helix_ccw.kcl
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "helix", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Solid", "type": "Solid",
@ -178,6 +188,60 @@ description: Operations executed helix_ccw.kcl
} }
}, },
"sourceRange": [] "sourceRange": []
},
"labeledArgs": {
"angleStart": {
"value": {
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
} }
} }
},
"sourceRange": []
},
"ccw": {
"value": {
"type": "Bool",
"value": true
},
"sourceRange": []
},
"cylinder": {
"value": {
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"revolutions": {
"value": {
"type": "Number",
"value": 16.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
}
] ]

View File

@ -19,6 +19,14 @@ description: Operations executed helix_simple.kcl
"unlabeledArg": null "unlabeledArg": null
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "helix",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": { "labeledArgs": {
"angleStart": { "angleStart": {
"value": { "value": {
@ -100,9 +108,96 @@ description: Operations executed helix_simple.kcl
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "helix", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"unlabeledArg": null "type": "KclStdLibCall",
"name": "",
"unlabeledArg": null,
"labeledArgs": {
"angleStart": {
"value": {
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"axis": {
"value": {
"type": "TagIdentifier",
"value": "edge001",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"ccw": {
"value": {
"type": "Bool",
"value": true
},
"sourceRange": []
},
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
},
"revolutions": {
"value": {
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
} }
] ]

View File

@ -5,7 +5,7 @@ description: Variables in memory after executing import_foreign.kcl
{ {
"cube": { "cube": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
}, },
"model": { "model": {
"type": "ImportedGeometry", "type": "ImportedGeometry",

View File

@ -1,6 +1,6 @@
@settings(defaultLengthUnit = mm) @settings(defaultLengthUnit = mm)
export part001 = startSketchOn('XY') export part001 = startSketchOn(XY)
|> startProfileAt([4, 12], %) |> startProfileAt([4, 12], %)
|> line(end = [2, 0]) |> line(end = [2, 0])
|> line(end = [0, -6]) |> line(end = [0, -6])
@ -10,7 +10,7 @@ export part001 = startSketchOn('XY')
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y') // default angle is 360 |> revolve(axis = Y) // default angle is 360
export fn two() { export fn two() {
return 5 return 5

View File

@ -7,8 +7,8 @@ description: Operations executed import_function_not_sketch.kcl
"labeledArgs": { "labeledArgs": {
"data": { "data": {
"value": { "value": {
"type": "String", "type": "Plane",
"value": "XY" "artifact_id": "[uuid]"
}, },
"sourceRange": [] "sourceRange": []
} }
@ -19,18 +19,117 @@ description: Operations executed import_function_not_sketch.kcl
"unlabeledArg": null "unlabeledArg": null
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "revolve",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": { "labeledArgs": {
"axis": { "axis": {
"value": { "value": {
"type": "String", "type": "Object",
"value": "y" "value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
}, },
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "revolve", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Sketch", "type": "Sketch",
@ -39,6 +138,82 @@ description: Operations executed import_function_not_sketch.kcl
} }
}, },
"sourceRange": [] "sourceRange": []
},
"labeledArgs": {
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
} }
} }
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
}
] ]

View File

@ -14,7 +14,7 @@ export part001 = startSketchOn(XY)
|> line(end = [0, -5.5]) |> line(end = [0, -5.5])
|> line(end = [-2, 0]) |> line(end = [-2, 0])
|> close() |> close()
|> revolve(axis = 'y') // default angle is 360 |> revolve(axis = Y) // default angle is 360
export fn two() { export fn two() {
return 5 return 5

View File

@ -5,6 +5,6 @@ description: Variables in memory after executing import_transform.kcl
{ {
"screw": { "screw": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
} }
} }

View File

@ -1,12 +1,12 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[83, 119, 4]"] 2["Path<br>[83, 119, 5]"]
3["Segment<br>[83, 119, 4]"] 3["Segment<br>[83, 119, 5]"]
4[Solid2d] 4[Solid2d]
end end
1["Plane<br>[60, 77, 4]"] 1["Plane<br>[60, 77, 5]"]
5["Sweep Extrusion<br>[125, 145, 4]"] 5["Sweep Extrusion<br>[125, 145, 5]"]
6[Wall] 6[Wall]
7["Cap Start"] 7["Cap Start"]
8["Cap End"] 8["Cap End"]

View File

@ -111,6 +111,6 @@ description: Variables in memory after executing import_whole.kcl
}, },
"foo": { "foo": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
} }
} }

View File

@ -17,26 +17,26 @@ flowchart LR
18[Solid2d] 18[Solid2d]
end end
subgraph path24 [Path] subgraph path24 [Path]
24["Path<br>[1576, 1709, 0]"] 24["Path<br>[1574, 1707, 0]"]
25["Segment<br>[1715, 1808, 0]"] 25["Segment<br>[1713, 1806, 0]"]
26["Segment<br>[1814, 1845, 0]"] 26["Segment<br>[1812, 1843, 0]"]
27["Segment<br>[1851, 1879, 0]"] 27["Segment<br>[1849, 1877, 0]"]
28["Segment<br>[1885, 1892, 0]"] 28["Segment<br>[1883, 1890, 0]"]
29[Solid2d] 29[Solid2d]
end end
subgraph path40 [Path] subgraph path40 [Path]
40["Path<br>[2228, 2370, 0]"] 40["Path<br>[2224, 2366, 0]"]
41["Segment<br>[2228, 2370, 0]"] 41["Segment<br>[2224, 2366, 0]"]
42[Solid2d] 42[Solid2d]
end end
subgraph path50 [Path] subgraph path50 [Path]
50["Path<br>[2766, 2819, 0]"] 50["Path<br>[2760, 2813, 0]"]
51["Segment<br>[2766, 2819, 0]"] 51["Segment<br>[2760, 2813, 0]"]
52[Solid2d] 52[Solid2d]
end end
subgraph path53 [Path] subgraph path53 [Path]
53["Path<br>[2830, 2904, 0]"] 53["Path<br>[2824, 2898, 0]"]
54["Segment<br>[2830, 2904, 0]"] 54["Segment<br>[2824, 2898, 0]"]
55[Solid2d] 55[Solid2d]
end end
1["Plane<br>[677, 724, 0]"] 1["Plane<br>[677, 724, 0]"]
@ -47,12 +47,12 @@ flowchart LR
12["SweepEdge Opposite"] 12["SweepEdge Opposite"]
13["SweepEdge Adjacent"] 13["SweepEdge Adjacent"]
14["Plane<br>[1014, 1031, 0]"] 14["Plane<br>[1014, 1031, 0]"]
19["Sweep Revolve<br>[1286, 1318, 0]"] 19["Sweep Revolve<br>[1286, 1316, 0]"]
20[Wall] 20[Wall]
21[Wall] 21[Wall]
22["SweepEdge Adjacent"] 22["SweepEdge Adjacent"]
23["Plane<br>[1553, 1570, 0]"] 23["Plane<br>[1551, 1568, 0]"]
30["Sweep Revolve<br>[1934, 1966, 0]"] 30["Sweep Revolve<br>[1932, 1962, 0]"]
31[Wall] 31[Wall]
32[Wall] 32[Wall]
33[Wall] 33[Wall]
@ -61,22 +61,22 @@ flowchart LR
36["SweepEdge Adjacent"] 36["SweepEdge Adjacent"]
37["SweepEdge Adjacent"] 37["SweepEdge Adjacent"]
38["SweepEdge Adjacent"] 38["SweepEdge Adjacent"]
39["Plane<br>[2205, 2222, 0]"] 39["Plane<br>[2201, 2218, 0]"]
43["Sweep Revolve<br>[2413, 2466, 0]"] 43["Sweep Revolve<br>[2409, 2460, 0]"]
44[Wall] 44[Wall]
45["Cap Start"] 45["Cap Start"]
46["Cap End"] 46["Cap End"]
47["SweepEdge Opposite"] 47["SweepEdge Opposite"]
48["SweepEdge Adjacent"] 48["SweepEdge Adjacent"]
49["Plane<br>[2712, 2759, 0]"] 49["Plane<br>[2706, 2753, 0]"]
56["Sweep Extrusion<br>[2924, 2977, 0]"] 56["Sweep Extrusion<br>[2918, 2971, 0]"]
57[Wall] 57[Wall]
58["Cap Start"] 58["Cap Start"]
59["Cap End"] 59["Cap End"]
60["SweepEdge Opposite"] 60["SweepEdge Opposite"]
61["SweepEdge Adjacent"] 61["SweepEdge Adjacent"]
62["StartSketchOnPlane<br>[663, 725, 0]"] 62["StartSketchOnPlane<br>[663, 725, 0]"]
63["StartSketchOnPlane<br>[2698, 2760, 0]"] 63["StartSketchOnPlane<br>[2692, 2754, 0]"]
1 --- 2 1 --- 2
1 --- 5 1 --- 5
2 --- 3 2 --- 3

File diff suppressed because it is too large Load Diff

View File

@ -236,18 +236,13 @@ description: Operations executed ball-bearing.kcl
"unlabeledArg": null "unlabeledArg": null
}, },
{ {
"labeledArgs": { "type": "UserDefinedFunctionCall",
"axis": {
"value": {
"type": "String",
"value": "X"
},
"sourceRange": []
}
},
"name": "revolve", "name": "revolve",
"sourceRange": [], "functionSourceRange": [
"type": "StdLibCall", 0,
0,
0
],
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Sketch", "type": "Sketch",
@ -256,7 +251,200 @@ description: Operations executed ball-bearing.kcl
} }
}, },
"sourceRange": [] "sourceRange": []
},
"labeledArgs": {
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
} }
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
}, },
{ {
"labeledArgs": { "labeledArgs": {
@ -438,18 +626,13 @@ description: Operations executed ball-bearing.kcl
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{ {
"labeledArgs": { "type": "UserDefinedFunctionCall",
"axis": {
"value": {
"type": "String",
"value": "X"
},
"sourceRange": []
}
},
"name": "revolve", "name": "revolve",
"sourceRange": [], "functionSourceRange": [
"type": "StdLibCall", 0,
0,
0
],
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Sketch", "type": "Sketch",
@ -458,7 +641,200 @@ description: Operations executed ball-bearing.kcl
} }
}, },
"sourceRange": [] "sourceRange": []
},
"labeledArgs": {
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
} }
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": {
"value": {
"type": "Array",
"value": [
{
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
"sourceRange": []
},
"labeledArgs": {
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
}, },
{ {
"labeledArgs": { "labeledArgs": {
@ -679,6 +1055,22 @@ description: Operations executed ball-bearing.kcl
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "revolve",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"labeledArgs": { "labeledArgs": {
"angle": { "angle": {
"value": { "value": {
@ -692,25 +1084,207 @@ description: Operations executed ball-bearing.kcl
}, },
"axis": { "axis": {
"value": { "value": {
"type": "String", "type": "Object",
"value": "Y" "value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
}, },
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "revolve", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"type": "KclStdLibCall",
"name": "",
"unlabeledArg": { "unlabeledArg": {
"value": { "value": {
"type": "Array",
"value": [
{
"type": "Sketch", "type": "Sketch",
"value": { "value": {
"artifactId": "[uuid]" "artifactId": "[uuid]"
} }
}
]
},
"sourceRange": []
},
"labeledArgs": {
"angle": {
"value": {
"type": "Number",
"value": 36.0,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
},
"axis": {
"value": {
"type": "Object",
"value": {
"direction": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"origin": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
}
}
}, },
"sourceRange": [] "sourceRange": []
} }
}, },
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"arcDegrees": { "arcDegrees": {

View File

@ -1,239 +1,239 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[361, 394, 4]"] 2["Path<br>[361, 394, 5]"]
3["Segment<br>[402, 428, 4]"] 3["Segment<br>[402, 428, 5]"]
4["Segment<br>[436, 489, 4]"] 4["Segment<br>[436, 489, 5]"]
5["Segment<br>[497, 550, 4]"] 5["Segment<br>[497, 550, 5]"]
6["Segment<br>[558, 612, 4]"] 6["Segment<br>[558, 612, 5]"]
7["Segment<br>[620, 645, 4]"] 7["Segment<br>[620, 645, 5]"]
8["Segment<br>[653, 673, 4]"] 8["Segment<br>[653, 673, 5]"]
9["Segment<br>[681, 705, 4]"] 9["Segment<br>[681, 705, 5]"]
10["Segment<br>[713, 766, 4]"] 10["Segment<br>[713, 766, 5]"]
11["Segment<br>[774, 799, 4]"] 11["Segment<br>[774, 799, 5]"]
12["Segment<br>[807, 827, 4]"] 12["Segment<br>[807, 827, 5]"]
13["Segment<br>[835, 859, 4]"] 13["Segment<br>[835, 859, 5]"]
14["Segment<br>[867, 919, 4]"] 14["Segment<br>[867, 919, 5]"]
15["Segment<br>[927, 979, 4]"] 15["Segment<br>[927, 979, 5]"]
16["Segment<br>[987, 1012, 4]"] 16["Segment<br>[987, 1012, 5]"]
17["Segment<br>[1020, 1044, 4]"] 17["Segment<br>[1020, 1044, 5]"]
18["Segment<br>[1052, 1105, 4]"] 18["Segment<br>[1052, 1105, 5]"]
19["Segment<br>[1113, 1138, 4]"] 19["Segment<br>[1113, 1138, 5]"]
20["Segment<br>[1146, 1173, 4]"] 20["Segment<br>[1146, 1173, 5]"]
21["Segment<br>[1181, 1233, 4]"] 21["Segment<br>[1181, 1233, 5]"]
22["Segment<br>[1241, 1276, 4]"] 22["Segment<br>[1241, 1276, 5]"]
23["Segment<br>[1284, 1291, 4]"] 23["Segment<br>[1284, 1291, 5]"]
24[Solid2d] 24[Solid2d]
end end
subgraph path89 [Path] subgraph path89 [Path]
89["Path<br>[361, 394, 4]"] 89["Path<br>[361, 394, 5]"]
90["Segment<br>[402, 428, 4]"] 90["Segment<br>[402, 428, 5]"]
91["Segment<br>[436, 489, 4]"] 91["Segment<br>[436, 489, 5]"]
92["Segment<br>[497, 550, 4]"] 92["Segment<br>[497, 550, 5]"]
93["Segment<br>[558, 612, 4]"] 93["Segment<br>[558, 612, 5]"]
94["Segment<br>[620, 645, 4]"] 94["Segment<br>[620, 645, 5]"]
95["Segment<br>[653, 673, 4]"] 95["Segment<br>[653, 673, 5]"]
96["Segment<br>[681, 705, 4]"] 96["Segment<br>[681, 705, 5]"]
97["Segment<br>[713, 766, 4]"] 97["Segment<br>[713, 766, 5]"]
98["Segment<br>[774, 799, 4]"] 98["Segment<br>[774, 799, 5]"]
99["Segment<br>[807, 827, 4]"] 99["Segment<br>[807, 827, 5]"]
100["Segment<br>[835, 859, 4]"] 100["Segment<br>[835, 859, 5]"]
101["Segment<br>[867, 919, 4]"] 101["Segment<br>[867, 919, 5]"]
102["Segment<br>[927, 979, 4]"] 102["Segment<br>[927, 979, 5]"]
103["Segment<br>[987, 1012, 4]"] 103["Segment<br>[987, 1012, 5]"]
104["Segment<br>[1020, 1044, 4]"] 104["Segment<br>[1020, 1044, 5]"]
105["Segment<br>[1052, 1105, 4]"] 105["Segment<br>[1052, 1105, 5]"]
106["Segment<br>[1113, 1138, 4]"] 106["Segment<br>[1113, 1138, 5]"]
107["Segment<br>[1146, 1173, 4]"] 107["Segment<br>[1146, 1173, 5]"]
108["Segment<br>[1181, 1233, 4]"] 108["Segment<br>[1181, 1233, 5]"]
109["Segment<br>[1241, 1276, 4]"] 109["Segment<br>[1241, 1276, 5]"]
110["Segment<br>[1284, 1291, 4]"] 110["Segment<br>[1284, 1291, 5]"]
111[Solid2d] 111[Solid2d]
end end
subgraph path176 [Path] subgraph path176 [Path]
176["Path<br>[361, 394, 4]"] 176["Path<br>[361, 394, 5]"]
177["Segment<br>[402, 428, 4]"] 177["Segment<br>[402, 428, 5]"]
178["Segment<br>[436, 489, 4]"] 178["Segment<br>[436, 489, 5]"]
179["Segment<br>[497, 550, 4]"] 179["Segment<br>[497, 550, 5]"]
180["Segment<br>[558, 612, 4]"] 180["Segment<br>[558, 612, 5]"]
181["Segment<br>[620, 645, 4]"] 181["Segment<br>[620, 645, 5]"]
182["Segment<br>[653, 673, 4]"] 182["Segment<br>[653, 673, 5]"]
183["Segment<br>[681, 705, 4]"] 183["Segment<br>[681, 705, 5]"]
184["Segment<br>[713, 766, 4]"] 184["Segment<br>[713, 766, 5]"]
185["Segment<br>[774, 799, 4]"] 185["Segment<br>[774, 799, 5]"]
186["Segment<br>[807, 827, 4]"] 186["Segment<br>[807, 827, 5]"]
187["Segment<br>[835, 859, 4]"] 187["Segment<br>[835, 859, 5]"]
188["Segment<br>[867, 919, 4]"] 188["Segment<br>[867, 919, 5]"]
189["Segment<br>[927, 979, 4]"] 189["Segment<br>[927, 979, 5]"]
190["Segment<br>[987, 1012, 4]"] 190["Segment<br>[987, 1012, 5]"]
191["Segment<br>[1020, 1044, 4]"] 191["Segment<br>[1020, 1044, 5]"]
192["Segment<br>[1052, 1105, 4]"] 192["Segment<br>[1052, 1105, 5]"]
193["Segment<br>[1113, 1138, 4]"] 193["Segment<br>[1113, 1138, 5]"]
194["Segment<br>[1146, 1173, 4]"] 194["Segment<br>[1146, 1173, 5]"]
195["Segment<br>[1181, 1233, 4]"] 195["Segment<br>[1181, 1233, 5]"]
196["Segment<br>[1241, 1276, 4]"] 196["Segment<br>[1241, 1276, 5]"]
197["Segment<br>[1284, 1291, 4]"] 197["Segment<br>[1284, 1291, 5]"]
198[Solid2d] 198[Solid2d]
end end
subgraph path262 [Path] subgraph path262 [Path]
262["Path<br>[361, 394, 4]"] 262["Path<br>[361, 394, 5]"]
263["Segment<br>[402, 428, 4]"] 263["Segment<br>[402, 428, 5]"]
264["Segment<br>[436, 489, 4]"] 264["Segment<br>[436, 489, 5]"]
265["Segment<br>[497, 550, 4]"] 265["Segment<br>[497, 550, 5]"]
266["Segment<br>[558, 612, 4]"] 266["Segment<br>[558, 612, 5]"]
267["Segment<br>[620, 645, 4]"] 267["Segment<br>[620, 645, 5]"]
268["Segment<br>[653, 673, 4]"] 268["Segment<br>[653, 673, 5]"]
269["Segment<br>[681, 705, 4]"] 269["Segment<br>[681, 705, 5]"]
270["Segment<br>[713, 766, 4]"] 270["Segment<br>[713, 766, 5]"]
271["Segment<br>[774, 799, 4]"] 271["Segment<br>[774, 799, 5]"]
272["Segment<br>[807, 827, 4]"] 272["Segment<br>[807, 827, 5]"]
273["Segment<br>[835, 859, 4]"] 273["Segment<br>[835, 859, 5]"]
274["Segment<br>[867, 919, 4]"] 274["Segment<br>[867, 919, 5]"]
275["Segment<br>[927, 979, 4]"] 275["Segment<br>[927, 979, 5]"]
276["Segment<br>[987, 1012, 4]"] 276["Segment<br>[987, 1012, 5]"]
277["Segment<br>[1020, 1044, 4]"] 277["Segment<br>[1020, 1044, 5]"]
278["Segment<br>[1052, 1105, 4]"] 278["Segment<br>[1052, 1105, 5]"]
279["Segment<br>[1113, 1138, 4]"] 279["Segment<br>[1113, 1138, 5]"]
280["Segment<br>[1146, 1173, 4]"] 280["Segment<br>[1146, 1173, 5]"]
281["Segment<br>[1181, 1233, 4]"] 281["Segment<br>[1181, 1233, 5]"]
282["Segment<br>[1241, 1276, 4]"] 282["Segment<br>[1241, 1276, 5]"]
283["Segment<br>[1284, 1291, 4]"] 283["Segment<br>[1284, 1291, 5]"]
284[Solid2d] 284[Solid2d]
end end
subgraph path349 [Path] subgraph path349 [Path]
349["Path<br>[361, 394, 4]"] 349["Path<br>[361, 394, 5]"]
350["Segment<br>[402, 428, 4]"] 350["Segment<br>[402, 428, 5]"]
351["Segment<br>[436, 489, 4]"] 351["Segment<br>[436, 489, 5]"]
352["Segment<br>[497, 550, 4]"] 352["Segment<br>[497, 550, 5]"]
353["Segment<br>[558, 612, 4]"] 353["Segment<br>[558, 612, 5]"]
354["Segment<br>[620, 645, 4]"] 354["Segment<br>[620, 645, 5]"]
355["Segment<br>[653, 673, 4]"] 355["Segment<br>[653, 673, 5]"]
356["Segment<br>[681, 705, 4]"] 356["Segment<br>[681, 705, 5]"]
357["Segment<br>[713, 766, 4]"] 357["Segment<br>[713, 766, 5]"]
358["Segment<br>[774, 799, 4]"] 358["Segment<br>[774, 799, 5]"]
359["Segment<br>[807, 827, 4]"] 359["Segment<br>[807, 827, 5]"]
360["Segment<br>[835, 859, 4]"] 360["Segment<br>[835, 859, 5]"]
361["Segment<br>[867, 919, 4]"] 361["Segment<br>[867, 919, 5]"]
362["Segment<br>[927, 979, 4]"] 362["Segment<br>[927, 979, 5]"]
363["Segment<br>[987, 1012, 4]"] 363["Segment<br>[987, 1012, 5]"]
364["Segment<br>[1020, 1044, 4]"] 364["Segment<br>[1020, 1044, 5]"]
365["Segment<br>[1052, 1105, 4]"] 365["Segment<br>[1052, 1105, 5]"]
366["Segment<br>[1113, 1138, 4]"] 366["Segment<br>[1113, 1138, 5]"]
367["Segment<br>[1146, 1173, 4]"] 367["Segment<br>[1146, 1173, 5]"]
368["Segment<br>[1181, 1233, 4]"] 368["Segment<br>[1181, 1233, 5]"]
369["Segment<br>[1241, 1276, 4]"] 369["Segment<br>[1241, 1276, 5]"]
370["Segment<br>[1284, 1291, 4]"] 370["Segment<br>[1284, 1291, 5]"]
371[Solid2d] 371[Solid2d]
end end
subgraph path435 [Path] subgraph path435 [Path]
435["Path<br>[361, 394, 4]"] 435["Path<br>[361, 394, 5]"]
436["Segment<br>[402, 428, 4]"] 436["Segment<br>[402, 428, 5]"]
437["Segment<br>[436, 489, 4]"] 437["Segment<br>[436, 489, 5]"]
438["Segment<br>[497, 550, 4]"] 438["Segment<br>[497, 550, 5]"]
439["Segment<br>[558, 612, 4]"] 439["Segment<br>[558, 612, 5]"]
440["Segment<br>[620, 645, 4]"] 440["Segment<br>[620, 645, 5]"]
441["Segment<br>[653, 673, 4]"] 441["Segment<br>[653, 673, 5]"]
442["Segment<br>[681, 705, 4]"] 442["Segment<br>[681, 705, 5]"]
443["Segment<br>[713, 766, 4]"] 443["Segment<br>[713, 766, 5]"]
444["Segment<br>[774, 799, 4]"] 444["Segment<br>[774, 799, 5]"]
445["Segment<br>[807, 827, 4]"] 445["Segment<br>[807, 827, 5]"]
446["Segment<br>[835, 859, 4]"] 446["Segment<br>[835, 859, 5]"]
447["Segment<br>[867, 919, 4]"] 447["Segment<br>[867, 919, 5]"]
448["Segment<br>[927, 979, 4]"] 448["Segment<br>[927, 979, 5]"]
449["Segment<br>[987, 1012, 4]"] 449["Segment<br>[987, 1012, 5]"]
450["Segment<br>[1020, 1044, 4]"] 450["Segment<br>[1020, 1044, 5]"]
451["Segment<br>[1052, 1105, 4]"] 451["Segment<br>[1052, 1105, 5]"]
452["Segment<br>[1113, 1138, 4]"] 452["Segment<br>[1113, 1138, 5]"]
453["Segment<br>[1146, 1173, 4]"] 453["Segment<br>[1146, 1173, 5]"]
454["Segment<br>[1181, 1233, 4]"] 454["Segment<br>[1181, 1233, 5]"]
455["Segment<br>[1241, 1276, 4]"] 455["Segment<br>[1241, 1276, 5]"]
456["Segment<br>[1284, 1291, 4]"] 456["Segment<br>[1284, 1291, 5]"]
457[Solid2d] 457[Solid2d]
end end
subgraph path522 [Path] subgraph path522 [Path]
522["Path<br>[1685, 1709, 4]"] 522["Path<br>[1685, 1709, 5]"]
end end
subgraph path523 [Path] subgraph path523 [Path]
523["Path<br>[1717, 1847, 4]"] 523["Path<br>[1717, 1847, 5]"]
524["Segment<br>[1717, 1847, 4]"] 524["Segment<br>[1717, 1847, 5]"]
525["Segment<br>[1717, 1847, 4]"] 525["Segment<br>[1717, 1847, 5]"]
526["Segment<br>[1717, 1847, 4]"] 526["Segment<br>[1717, 1847, 5]"]
527["Segment<br>[1717, 1847, 4]"] 527["Segment<br>[1717, 1847, 5]"]
528["Segment<br>[1717, 1847, 4]"] 528["Segment<br>[1717, 1847, 5]"]
529["Segment<br>[1717, 1847, 4]"] 529["Segment<br>[1717, 1847, 5]"]
530["Segment<br>[1717, 1847, 4]"] 530["Segment<br>[1717, 1847, 5]"]
531[Solid2d] 531[Solid2d]
end end
subgraph path553 [Path] subgraph path553 [Path]
553["Path<br>[1685, 1709, 4]"] 553["Path<br>[1685, 1709, 5]"]
end end
subgraph path554 [Path] subgraph path554 [Path]
554["Path<br>[1717, 1847, 4]"] 554["Path<br>[1717, 1847, 5]"]
555["Segment<br>[1717, 1847, 4]"] 555["Segment<br>[1717, 1847, 5]"]
556["Segment<br>[1717, 1847, 4]"] 556["Segment<br>[1717, 1847, 5]"]
557["Segment<br>[1717, 1847, 4]"] 557["Segment<br>[1717, 1847, 5]"]
558["Segment<br>[1717, 1847, 4]"] 558["Segment<br>[1717, 1847, 5]"]
559["Segment<br>[1717, 1847, 4]"] 559["Segment<br>[1717, 1847, 5]"]
560["Segment<br>[1717, 1847, 4]"] 560["Segment<br>[1717, 1847, 5]"]
561["Segment<br>[1717, 1847, 4]"] 561["Segment<br>[1717, 1847, 5]"]
562[Solid2d] 562[Solid2d]
end end
subgraph path585 [Path] subgraph path585 [Path]
585["Path<br>[2123, 2150, 4]"] 585["Path<br>[2123, 2150, 5]"]
586["Segment<br>[2158, 2180, 4]"] 586["Segment<br>[2158, 2180, 5]"]
587["Segment<br>[2188, 2210, 4]"] 587["Segment<br>[2188, 2210, 5]"]
588["Segment<br>[2218, 2240, 4]"] 588["Segment<br>[2218, 2240, 5]"]
589["Segment<br>[2248, 2271, 4]"] 589["Segment<br>[2248, 2271, 5]"]
590["Segment<br>[2279, 2302, 4]"] 590["Segment<br>[2279, 2302, 5]"]
591["Segment<br>[2310, 2345, 4]"] 591["Segment<br>[2310, 2345, 5]"]
592["Segment<br>[2353, 2360, 4]"] 592["Segment<br>[2353, 2360, 5]"]
593[Solid2d] 593[Solid2d]
end end
subgraph path618 [Path] subgraph path618 [Path]
618["Path<br>[2632, 2661, 4]"] 618["Path<br>[2632, 2661, 5]"]
619["Segment<br>[2669, 2692, 4]"] 619["Segment<br>[2669, 2692, 5]"]
620["Segment<br>[2700, 2725, 4]"] 620["Segment<br>[2700, 2725, 5]"]
621["Segment<br>[2733, 2757, 4]"] 621["Segment<br>[2733, 2757, 5]"]
622["Segment<br>[2765, 2789, 4]"] 622["Segment<br>[2765, 2789, 5]"]
623["Segment<br>[2797, 2819, 4]"] 623["Segment<br>[2797, 2819, 5]"]
624["Segment<br>[2827, 2862, 4]"] 624["Segment<br>[2827, 2862, 5]"]
625["Segment<br>[2870, 2877, 4]"] 625["Segment<br>[2870, 2877, 5]"]
626[Solid2d] 626[Solid2d]
end end
subgraph path650 [Path] subgraph path650 [Path]
650["Path<br>[3152, 3179, 4]"] 650["Path<br>[3152, 3179, 5]"]
651["Segment<br>[3187, 3206, 4]"] 651["Segment<br>[3187, 3206, 5]"]
652["Segment<br>[3214, 3304, 4]"] 652["Segment<br>[3214, 3304, 5]"]
end end
subgraph path654 [Path] subgraph path654 [Path]
654["Path<br>[3404, 3437, 4]"] 654["Path<br>[3404, 3437, 5]"]
655["Segment<br>[3445, 3464, 4]"] 655["Segment<br>[3445, 3464, 5]"]
656["Segment<br>[3472, 3494, 4]"] 656["Segment<br>[3472, 3494, 5]"]
657["Segment<br>[3502, 3525, 4]"] 657["Segment<br>[3502, 3525, 5]"]
658["Segment<br>[3533, 3553, 4]"] 658["Segment<br>[3533, 3553, 5]"]
659["Segment<br>[3561, 3585, 4]"] 659["Segment<br>[3561, 3585, 5]"]
660["Segment<br>[3593, 3616, 4]"] 660["Segment<br>[3593, 3616, 5]"]
661["Segment<br>[3624, 3631, 4]"] 661["Segment<br>[3624, 3631, 5]"]
662[Solid2d] 662[Solid2d]
end end
subgraph path688 [Path] subgraph path688 [Path]
688["Path<br>[3152, 3179, 4]"] 688["Path<br>[3152, 3179, 5]"]
689["Segment<br>[3187, 3206, 4]"] 689["Segment<br>[3187, 3206, 5]"]
690["Segment<br>[3214, 3304, 4]"] 690["Segment<br>[3214, 3304, 5]"]
end end
subgraph path692 [Path] subgraph path692 [Path]
692["Path<br>[3404, 3437, 4]"] 692["Path<br>[3404, 3437, 5]"]
693["Segment<br>[3445, 3464, 4]"] 693["Segment<br>[3445, 3464, 5]"]
694["Segment<br>[3472, 3494, 4]"] 694["Segment<br>[3472, 3494, 5]"]
695["Segment<br>[3502, 3525, 4]"] 695["Segment<br>[3502, 3525, 5]"]
696["Segment<br>[3533, 3553, 4]"] 696["Segment<br>[3533, 3553, 5]"]
697["Segment<br>[3561, 3585, 4]"] 697["Segment<br>[3561, 3585, 5]"]
698["Segment<br>[3593, 3616, 4]"] 698["Segment<br>[3593, 3616, 5]"]
699["Segment<br>[3624, 3631, 4]"] 699["Segment<br>[3624, 3631, 5]"]
700[Solid2d] 700[Solid2d]
end end
1["Plane<br>[333, 353, 4]"] 1["Plane<br>[333, 353, 5]"]
25["Sweep Extrusion<br>[1379, 1417, 4]"] 25["Sweep Extrusion<br>[1379, 1417, 5]"]
26[Wall] 26[Wall]
27[Wall] 27[Wall]
28[Wall] 28[Wall]
@ -296,8 +296,8 @@ flowchart LR
85["SweepEdge Adjacent"] 85["SweepEdge Adjacent"]
86["SweepEdge Opposite"] 86["SweepEdge Opposite"]
87["SweepEdge Adjacent"] 87["SweepEdge Adjacent"]
88["Plane<br>[333, 353, 4]"] 88["Plane<br>[333, 353, 5]"]
112["Sweep Extrusion<br>[1455, 1494, 4]"] 112["Sweep Extrusion<br>[1455, 1494, 5]"]
113[Wall] 113[Wall]
114[Wall] 114[Wall]
115[Wall] 115[Wall]
@ -361,7 +361,7 @@ flowchart LR
173["SweepEdge Opposite"] 173["SweepEdge Opposite"]
174["SweepEdge Adjacent"] 174["SweepEdge Adjacent"]
175["Plane<br>[823, 865, 0]"] 175["Plane<br>[823, 865, 0]"]
199["Sweep Extrusion<br>[1379, 1417, 4]"] 199["Sweep Extrusion<br>[1379, 1417, 5]"]
200[Wall] 200[Wall]
201[Wall] 201[Wall]
202[Wall] 202[Wall]
@ -424,7 +424,7 @@ flowchart LR
259["SweepEdge Adjacent"] 259["SweepEdge Adjacent"]
260["SweepEdge Opposite"] 260["SweepEdge Opposite"]
261["SweepEdge Adjacent"] 261["SweepEdge Adjacent"]
285["Sweep Extrusion<br>[1455, 1494, 4]"] 285["Sweep Extrusion<br>[1455, 1494, 5]"]
286[Wall] 286[Wall]
287[Wall] 287[Wall]
288[Wall] 288[Wall]
@ -488,7 +488,7 @@ flowchart LR
346["SweepEdge Opposite"] 346["SweepEdge Opposite"]
347["SweepEdge Adjacent"] 347["SweepEdge Adjacent"]
348["Plane<br>[875, 916, 0]"] 348["Plane<br>[875, 916, 0]"]
372["Sweep Extrusion<br>[1379, 1417, 4]"] 372["Sweep Extrusion<br>[1379, 1417, 5]"]
373[Wall] 373[Wall]
374[Wall] 374[Wall]
375[Wall] 375[Wall]
@ -551,7 +551,7 @@ flowchart LR
432["SweepEdge Adjacent"] 432["SweepEdge Adjacent"]
433["SweepEdge Opposite"] 433["SweepEdge Opposite"]
434["SweepEdge Adjacent"] 434["SweepEdge Adjacent"]
458["Sweep Extrusion<br>[1455, 1494, 4]"] 458["Sweep Extrusion<br>[1455, 1494, 5]"]
459[Wall] 459[Wall]
460[Wall] 460[Wall]
461[Wall] 461[Wall]
@ -615,7 +615,7 @@ flowchart LR
519["SweepEdge Opposite"] 519["SweepEdge Opposite"]
520["SweepEdge Adjacent"] 520["SweepEdge Adjacent"]
521["Plane<br>[975, 1017, 0]"] 521["Plane<br>[975, 1017, 0]"]
532["Sweep Extrusion<br>[1949, 1973, 4]"] 532["Sweep Extrusion<br>[1949, 1973, 5]"]
533[Wall] 533[Wall]
534[Wall] 534[Wall]
535[Wall] 535[Wall]
@ -636,7 +636,7 @@ flowchart LR
550["SweepEdge Adjacent"] 550["SweepEdge Adjacent"]
551["SweepEdge Opposite"] 551["SweepEdge Opposite"]
552["SweepEdge Adjacent"] 552["SweepEdge Adjacent"]
563["Sweep Extrusion<br>[2015, 2039, 4]"] 563["Sweep Extrusion<br>[2015, 2039, 5]"]
564[Wall] 564[Wall]
565[Wall] 565[Wall]
566[Wall] 566[Wall]
@ -658,7 +658,7 @@ flowchart LR
582["SweepEdge Opposite"] 582["SweepEdge Opposite"]
583["SweepEdge Adjacent"] 583["SweepEdge Adjacent"]
584["Plane<br>[1068, 1135, 0]"] 584["Plane<br>[1068, 1135, 0]"]
594["Sweep Extrusion<br>[2523, 2547, 4]"] 594["Sweep Extrusion<br>[2523, 2547, 5]"]
595[Wall] 595[Wall]
596[Wall] 596[Wall]
597[Wall] 597[Wall]
@ -679,10 +679,10 @@ flowchart LR
612["SweepEdge Adjacent"] 612["SweepEdge Adjacent"]
613["SweepEdge Opposite"] 613["SweepEdge Opposite"]
614["SweepEdge Adjacent"] 614["SweepEdge Adjacent"]
615["Sweep Extrusion<br>[2523, 2547, 4]"] 615["Sweep Extrusion<br>[2523, 2547, 5]"]
616["Sweep Extrusion<br>[2523, 2547, 4]"] 616["Sweep Extrusion<br>[2523, 2547, 5]"]
617["Plane<br>[1205, 1272, 0]"] 617["Plane<br>[1205, 1272, 0]"]
627["Sweep Extrusion<br>[3047, 3071, 4]"] 627["Sweep Extrusion<br>[3047, 3071, 5]"]
628[Wall] 628[Wall]
629[Wall] 629[Wall]
630[Wall] 630[Wall]
@ -703,10 +703,10 @@ flowchart LR
645["SweepEdge Adjacent"] 645["SweepEdge Adjacent"]
646["SweepEdge Opposite"] 646["SweepEdge Opposite"]
647["SweepEdge Adjacent"] 647["SweepEdge Adjacent"]
648["Sweep Extrusion<br>[3047, 3071, 4]"] 648["Sweep Extrusion<br>[3047, 3071, 5]"]
649["Plane<br>[3712, 3747, 4]"] 649["Plane<br>[3712, 3747, 5]"]
653["Plane<br>[3778, 3807, 4]"] 653["Plane<br>[3778, 3807, 5]"]
663["Sweep Sweep<br>[3819, 3846, 4]"] 663["Sweep Sweep<br>[3819, 3846, 5]"]
664[Wall] 664[Wall]
665[Wall] 665[Wall]
666[Wall] 666[Wall]
@ -730,9 +730,9 @@ flowchart LR
684["SweepEdge Adjacent"] 684["SweepEdge Adjacent"]
685["SweepEdge Opposite"] 685["SweepEdge Opposite"]
686["SweepEdge Adjacent"] 686["SweepEdge Adjacent"]
687["Plane<br>[3712, 3747, 4]"] 687["Plane<br>[3712, 3747, 5]"]
691["Plane<br>[3778, 3807, 4]"] 691["Plane<br>[3778, 3807, 5]"]
701["Sweep Sweep<br>[3819, 3846, 4]"] 701["Sweep Sweep<br>[3819, 3846, 5]"]
702[Wall] 702[Wall]
703[Wall] 703[Wall]
704[Wall] 704[Wall]
@ -756,18 +756,18 @@ flowchart LR
722["SweepEdge Adjacent"] 722["SweepEdge Adjacent"]
723["SweepEdge Opposite"] 723["SweepEdge Opposite"]
724["SweepEdge Adjacent"] 724["SweepEdge Adjacent"]
725["StartSketchOnPlane<br>[333, 353, 4]"] 725["StartSketchOnPlane<br>[333, 353, 5]"]
726["StartSketchOnPlane<br>[333, 353, 4]"] 726["StartSketchOnPlane<br>[333, 353, 5]"]
727["StartSketchOnPlane<br>[333, 353, 4]"] 727["StartSketchOnPlane<br>[333, 353, 5]"]
728["StartSketchOnPlane<br>[333, 353, 4]"] 728["StartSketchOnPlane<br>[333, 353, 5]"]
729["StartSketchOnPlane<br>[1657, 1677, 4]"] 729["StartSketchOnPlane<br>[1657, 1677, 5]"]
730["StartSketchOnPlane<br>[1657, 1677, 4]"] 730["StartSketchOnPlane<br>[1657, 1677, 5]"]
731["StartSketchOnPlane<br>[2095, 2115, 4]"] 731["StartSketchOnPlane<br>[2095, 2115, 5]"]
732["StartSketchOnPlane<br>[2604, 2624, 4]"] 732["StartSketchOnPlane<br>[2604, 2624, 5]"]
733["StartSketchOnPlane<br>[3124, 3144, 4]"] 733["StartSketchOnPlane<br>[3124, 3144, 5]"]
734["StartSketchOnPlane<br>[3376, 3396, 4]"] 734["StartSketchOnPlane<br>[3376, 3396, 5]"]
735["StartSketchOnPlane<br>[3124, 3144, 4]"] 735["StartSketchOnPlane<br>[3124, 3144, 5]"]
736["StartSketchOnPlane<br>[3376, 3396, 4]"] 736["StartSketchOnPlane<br>[3376, 3396, 5]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 --- 4 2 --- 4

View File

@ -9,7 +9,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1331, 1331,
1606, 1606,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -21,7 +21,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -77,7 +77,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -248,7 +248,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1331, 1331,
1606, 1606,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -260,7 +260,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -316,7 +316,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -487,7 +487,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1331, 1331,
1606, 1606,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -499,7 +499,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -555,7 +555,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -726,7 +726,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1889, 1889,
2052, 2052,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -738,7 +738,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1626, 1626,
1868, 1868,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -800,7 +800,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1626, 1626,
1868, 1868,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -889,7 +889,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2474, 2474,
2560, 2560,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -901,7 +901,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2071, 2071,
2453, 2453,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1007,7 +1007,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2993, 2993,
3084, 3084,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1019,7 +1019,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2580, 2580,
2972, 2972,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1095,7 +1095,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3671, 3671,
3859, 3859,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1131,7 +1131,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3100, 3100,
3325, 3325,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1191,7 +1191,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3344, 3344,
3652, 3652,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1249,7 +1249,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3671, 3671,
3859, 3859,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1285,7 +1285,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3100, 3100,
3325, 3325,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1345,7 +1345,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3344, 3344,
3652, 3652,
4 5
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},

View File

@ -1,264 +1,264 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[567, 618, 5]"] 2["Path<br>[567, 618, 6]"]
3["Segment<br>[567, 618, 5]"] 3["Segment<br>[567, 618, 6]"]
4[Solid2d] 4[Solid2d]
end end
subgraph path11 [Path] subgraph path11 [Path]
11["Path<br>[803, 859, 5]"] 11["Path<br>[803, 859, 6]"]
12["Segment<br>[803, 859, 5]"] 12["Segment<br>[803, 859, 6]"]
13[Solid2d] 13[Solid2d]
end end
subgraph path19 [Path] subgraph path19 [Path]
19["Path<br>[984, 1037, 5]"] 19["Path<br>[984, 1037, 6]"]
20["Segment<br>[984, 1037, 5]"] 20["Segment<br>[984, 1037, 6]"]
21[Solid2d] 21[Solid2d]
end end
subgraph path30 [Path] subgraph path30 [Path]
30["Path<br>[1420, 1460, 5]"] 30["Path<br>[1420, 1460, 6]"]
31["Segment<br>[1420, 1460, 5]"] 31["Segment<br>[1420, 1460, 6]"]
32[Solid2d] 32[Solid2d]
end end
subgraph path38 [Path] subgraph path38 [Path]
38["Path<br>[1564, 1615, 5]"] 38["Path<br>[1564, 1615, 6]"]
39["Segment<br>[1564, 1615, 5]"] 39["Segment<br>[1564, 1615, 6]"]
40[Solid2d] 40[Solid2d]
end end
subgraph path47 [Path] subgraph path47 [Path]
47["Path<br>[1748, 1801, 5]"] 47["Path<br>[1748, 1801, 6]"]
48["Segment<br>[1748, 1801, 5]"] 48["Segment<br>[1748, 1801, 6]"]
49[Solid2d] 49[Solid2d]
end end
subgraph path58 [Path] subgraph path58 [Path]
58["Path<br>[2044, 2116, 5]"] 58["Path<br>[2044, 2116, 6]"]
59["Segment<br>[2044, 2116, 5]"] 59["Segment<br>[2044, 2116, 6]"]
60[Solid2d] 60[Solid2d]
end end
subgraph path81 [Path] subgraph path81 [Path]
81["Path<br>[2373, 2404, 5]"] 81["Path<br>[2373, 2404, 6]"]
82["Segment<br>[2410, 2430, 5]"] 82["Segment<br>[2410, 2430, 6]"]
83["Segment<br>[2436, 2456, 5]"] 83["Segment<br>[2436, 2456, 6]"]
84["Segment<br>[2462, 2483, 5]"] 84["Segment<br>[2462, 2483, 6]"]
85["Segment<br>[2489, 2545, 5]"] 85["Segment<br>[2489, 2545, 6]"]
86["Segment<br>[2551, 2558, 5]"] 86["Segment<br>[2551, 2558, 6]"]
87[Solid2d] 87[Solid2d]
end end
subgraph path106 [Path] subgraph path106 [Path]
106["Path<br>[2860, 2892, 5]"] 106["Path<br>[2860, 2892, 6]"]
107["Segment<br>[2898, 2919, 5]"] 107["Segment<br>[2898, 2919, 6]"]
108["Segment<br>[2925, 2945, 5]"] 108["Segment<br>[2925, 2945, 6]"]
109["Segment<br>[2951, 2971, 5]"] 109["Segment<br>[2951, 2971, 6]"]
110["Segment<br>[2977, 3033, 5]"] 110["Segment<br>[2977, 3033, 6]"]
111["Segment<br>[3039, 3046, 5]"] 111["Segment<br>[3039, 3046, 6]"]
112[Solid2d] 112[Solid2d]
end end
subgraph path132 [Path] subgraph path132 [Path]
132["Path<br>[350, 406, 4]"] 132["Path<br>[350, 406, 5]"]
133["Segment<br>[350, 406, 4]"] 133["Segment<br>[350, 406, 5]"]
134[Solid2d] 134[Solid2d]
end end
subgraph path135 [Path] subgraph path135 [Path]
135["Path<br>[417, 473, 4]"] 135["Path<br>[417, 473, 5]"]
136["Segment<br>[417, 473, 4]"] 136["Segment<br>[417, 473, 5]"]
137[Solid2d] 137[Solid2d]
end end
subgraph path144 [Path] subgraph path144 [Path]
144["Path<br>[638, 694, 4]"] 144["Path<br>[638, 694, 5]"]
145["Segment<br>[638, 694, 4]"] 145["Segment<br>[638, 694, 5]"]
146[Solid2d] 146[Solid2d]
end end
subgraph path147 [Path] subgraph path147 [Path]
147["Path<br>[705, 761, 4]"] 147["Path<br>[705, 761, 5]"]
148["Segment<br>[705, 761, 4]"] 148["Segment<br>[705, 761, 5]"]
149[Solid2d] 149[Solid2d]
end end
subgraph path156 [Path] subgraph path156 [Path]
156["Path<br>[905, 959, 4]"] 156["Path<br>[905, 959, 5]"]
157["Segment<br>[905, 959, 4]"] 157["Segment<br>[905, 959, 5]"]
158[Solid2d] 158[Solid2d]
end end
subgraph path167 [Path] subgraph path167 [Path]
167["Path<br>[1237, 1297, 4]"] 167["Path<br>[1237, 1297, 5]"]
168["Segment<br>[1237, 1297, 4]"] 168["Segment<br>[1237, 1297, 5]"]
169[Solid2d] 169[Solid2d]
end end
subgraph path179 [Path] subgraph path179 [Path]
179["Path<br>[1655, 1701, 4]"] 179["Path<br>[1655, 1701, 5]"]
180["Segment<br>[1707, 1759, 4]"] 180["Segment<br>[1707, 1759, 5]"]
181["Segment<br>[1765, 1870, 4]"] 181["Segment<br>[1765, 1870, 5]"]
182["Segment<br>[1876, 1898, 4]"] 182["Segment<br>[1876, 1898, 5]"]
183["Segment<br>[1904, 1960, 4]"] 183["Segment<br>[1904, 1960, 5]"]
184["Segment<br>[1966, 1973, 4]"] 184["Segment<br>[1966, 1973, 5]"]
185[Solid2d] 185[Solid2d]
end end
subgraph path195 [Path] subgraph path195 [Path]
195["Path<br>[2107, 2153, 4]"] 195["Path<br>[2105, 2151, 5]"]
196["Segment<br>[2159, 2211, 4]"] 196["Segment<br>[2157, 2209, 5]"]
197["Segment<br>[2217, 2324, 4]"] 197["Segment<br>[2215, 2322, 5]"]
198["Segment<br>[2330, 2367, 4]"] 198["Segment<br>[2328, 2365, 5]"]
199["Segment<br>[2373, 2429, 4]"] 199["Segment<br>[2371, 2427, 5]"]
200["Segment<br>[2435, 2442, 4]"] 200["Segment<br>[2433, 2440, 5]"]
201[Solid2d] 201[Solid2d]
end end
subgraph path212 [Path] subgraph path212 [Path]
212["Path<br>[2953, 3000, 4]"] 212["Path<br>[2949, 2996, 5]"]
213["Segment<br>[3008, 3348, 4]"] 213["Segment<br>[3004, 3344, 5]"]
214["Segment<br>[3356, 3388, 4]"] 214["Segment<br>[3352, 3384, 5]"]
215["Segment<br>[3396, 3740, 4]"] 215["Segment<br>[3392, 3736, 5]"]
216["Segment<br>[3748, 3804, 4]"] 216["Segment<br>[3744, 3800, 5]"]
217["Segment<br>[3812, 3819, 4]"] 217["Segment<br>[3808, 3815, 5]"]
218[Solid2d] 218[Solid2d]
end end
subgraph path235 [Path] subgraph path235 [Path]
235["Path<br>[2953, 3000, 4]"] 235["Path<br>[2949, 2996, 5]"]
236["Segment<br>[3008, 3348, 4]"] 236["Segment<br>[3004, 3344, 5]"]
237["Segment<br>[3356, 3388, 4]"] 237["Segment<br>[3352, 3384, 5]"]
238["Segment<br>[3396, 3740, 4]"] 238["Segment<br>[3392, 3736, 5]"]
239["Segment<br>[3748, 3804, 4]"] 239["Segment<br>[3744, 3800, 5]"]
240["Segment<br>[3812, 3819, 4]"] 240["Segment<br>[3808, 3815, 5]"]
241[Solid2d] 241[Solid2d]
end end
subgraph path258 [Path] subgraph path258 [Path]
258["Path<br>[4347, 4442, 4]"] 258["Path<br>[4343, 4438, 5]"]
259["Segment<br>[4448, 4481, 4]"] 259["Segment<br>[4444, 4477, 5]"]
260["Segment<br>[4487, 4538, 4]"] 260["Segment<br>[4483, 4534, 5]"]
261["Segment<br>[4544, 4577, 4]"] 261["Segment<br>[4540, 4573, 5]"]
262["Segment<br>[4583, 4633, 4]"] 262["Segment<br>[4579, 4629, 5]"]
263["Segment<br>[4639, 4680, 4]"] 263["Segment<br>[4635, 4676, 5]"]
264["Segment<br>[4686, 4735, 4]"] 264["Segment<br>[4682, 4731, 5]"]
265["Segment<br>[4741, 4774, 4]"] 265["Segment<br>[4737, 4770, 5]"]
266["Segment<br>[4780, 4814, 4]"] 266["Segment<br>[4776, 4810, 5]"]
267["Segment<br>[4820, 4854, 4]"] 267["Segment<br>[4816, 4850, 5]"]
268["Segment<br>[4860, 4912, 4]"] 268["Segment<br>[4856, 4908, 5]"]
269["Segment<br>[4918, 4952, 4]"] 269["Segment<br>[4914, 4948, 5]"]
270["Segment<br>[4958, 5034, 4]"] 270["Segment<br>[4954, 5030, 5]"]
271["Segment<br>[5040, 5073, 4]"] 271["Segment<br>[5036, 5069, 5]"]
272["Segment<br>[5079, 5155, 4]"] 272["Segment<br>[5075, 5151, 5]"]
273["Segment<br>[5161, 5195, 4]"] 273["Segment<br>[5157, 5191, 5]"]
274["Segment<br>[5201, 5275, 4]"] 274["Segment<br>[5197, 5271, 5]"]
275["Segment<br>[5281, 5315, 4]"] 275["Segment<br>[5277, 5311, 5]"]
276["Segment<br>[5321, 5372, 4]"] 276["Segment<br>[5317, 5368, 5]"]
277["Segment<br>[5378, 5440, 4]"] 277["Segment<br>[5374, 5436, 5]"]
278["Segment<br>[5446, 5497, 4]"] 278["Segment<br>[5442, 5493, 5]"]
279["Segment<br>[5503, 5537, 4]"] 279["Segment<br>[5499, 5533, 5]"]
280["Segment<br>[5543, 5576, 4]"] 280["Segment<br>[5539, 5572, 5]"]
281["Segment<br>[5582, 5615, 4]"] 281["Segment<br>[5578, 5611, 5]"]
282["Segment<br>[5621, 5628, 4]"] 282["Segment<br>[5617, 5624, 5]"]
283[Solid2d] 283[Solid2d]
end end
subgraph path334 [Path] subgraph path334 [Path]
334["Path<br>[740, 780, 7]"] 334["Path<br>[740, 780, 8]"]
335["Segment<br>[788, 850, 7]"] 335["Segment<br>[788, 850, 8]"]
336["Segment<br>[858, 894, 7]"] 336["Segment<br>[858, 894, 8]"]
337["Segment<br>[902, 932, 7]"] 337["Segment<br>[902, 932, 8]"]
338["Segment<br>[940, 992, 7]"] 338["Segment<br>[940, 992, 8]"]
339["Segment<br>[1000, 1040, 7]"] 339["Segment<br>[1000, 1040, 8]"]
340["Segment<br>[1048, 1083, 7]"] 340["Segment<br>[1048, 1083, 8]"]
341["Segment<br>[1091, 1129, 7]"] 341["Segment<br>[1091, 1129, 8]"]
342["Segment<br>[1137, 1159, 7]"] 342["Segment<br>[1137, 1159, 8]"]
343["Segment<br>[1167, 1174, 7]"] 343["Segment<br>[1167, 1174, 8]"]
344[Solid2d] 344[Solid2d]
end end
subgraph path365 [Path] subgraph path365 [Path]
365["Path<br>[507, 588, 6]"] 365["Path<br>[507, 588, 7]"]
366["Segment<br>[594, 695, 6]"] 366["Segment<br>[594, 695, 7]"]
367["Segment<br>[701, 786, 6]"] 367["Segment<br>[701, 786, 7]"]
368["Segment<br>[792, 876, 6]"] 368["Segment<br>[792, 876, 7]"]
369["Segment<br>[882, 968, 6]"] 369["Segment<br>[882, 968, 7]"]
370["Segment<br>[974, 1059, 6]"] 370["Segment<br>[974, 1059, 7]"]
371["Segment<br>[1065, 1151, 6]"] 371["Segment<br>[1065, 1151, 7]"]
372["Segment<br>[1157, 1280, 6]"] 372["Segment<br>[1157, 1280, 7]"]
373["Segment<br>[1286, 1372, 6]"] 373["Segment<br>[1286, 1372, 7]"]
374["Segment<br>[1378, 1513, 6]"] 374["Segment<br>[1378, 1513, 7]"]
375["Segment<br>[1519, 1605, 6]"] 375["Segment<br>[1519, 1605, 7]"]
376["Segment<br>[1611, 1735, 6]"] 376["Segment<br>[1611, 1735, 7]"]
377["Segment<br>[1741, 1827, 6]"] 377["Segment<br>[1741, 1827, 7]"]
378["Segment<br>[1833, 1918, 6]"] 378["Segment<br>[1833, 1918, 7]"]
379["Segment<br>[1924, 2010, 6]"] 379["Segment<br>[1924, 2010, 7]"]
380["Segment<br>[2016, 2101, 6]"] 380["Segment<br>[2016, 2101, 7]"]
381["Segment<br>[2107, 2192, 6]"] 381["Segment<br>[2107, 2192, 7]"]
382["Segment<br>[2198, 2205, 6]"] 382["Segment<br>[2198, 2205, 7]"]
383[Solid2d] 383[Solid2d]
end end
subgraph path439 [Path] subgraph path439 [Path]
439["Path<br>[483, 540, 8]"] 439["Path<br>[483, 540, 9]"]
440["Segment<br>[546, 680, 8]"] 440["Segment<br>[546, 680, 9]"]
441["Segment<br>[686, 741, 8]"] 441["Segment<br>[686, 741, 9]"]
442["Segment<br>[747, 844, 8]"] 442["Segment<br>[747, 844, 9]"]
443["Segment<br>[850, 882, 8]"] 443["Segment<br>[850, 882, 9]"]
444["Segment<br>[888, 920, 8]"] 444["Segment<br>[888, 920, 9]"]
445["Segment<br>[926, 957, 8]"] 445["Segment<br>[926, 957, 9]"]
446["Segment<br>[963, 1078, 8]"] 446["Segment<br>[963, 1078, 9]"]
447["Segment<br>[1084, 1116, 8]"] 447["Segment<br>[1084, 1116, 9]"]
448["Segment<br>[1122, 1154, 8]"] 448["Segment<br>[1122, 1154, 9]"]
449["Segment<br>[1160, 1191, 8]"] 449["Segment<br>[1160, 1191, 9]"]
450["Segment<br>[1197, 1290, 8]"] 450["Segment<br>[1197, 1290, 9]"]
451["Segment<br>[1296, 1351, 8]"] 451["Segment<br>[1296, 1351, 9]"]
452["Segment<br>[1357, 1430, 8]"] 452["Segment<br>[1357, 1430, 9]"]
453["Segment<br>[1436, 1443, 8]"] 453["Segment<br>[1436, 1443, 9]"]
454[Solid2d] 454[Solid2d]
end end
1["Plane<br>[544, 561, 5]"] 1["Plane<br>[544, 561, 6]"]
5["Sweep Extrusion<br>[627, 683, 5]"] 5["Sweep Extrusion<br>[627, 683, 6]"]
6[Wall] 6[Wall]
7["Cap Start"] 7["Cap Start"]
8["Cap End"] 8["Cap End"]
9["SweepEdge Opposite"] 9["SweepEdge Opposite"]
10["SweepEdge Adjacent"] 10["SweepEdge Adjacent"]
14["Sweep Extrusion<br>[872, 934, 5]"] 14["Sweep Extrusion<br>[872, 934, 6]"]
15[Wall] 15[Wall]
16["Cap End"] 16["Cap End"]
17["SweepEdge Opposite"] 17["SweepEdge Opposite"]
18["SweepEdge Adjacent"] 18["SweepEdge Adjacent"]
22["Sweep Extrusion<br>[1184, 1263, 5]"] 22["Sweep Extrusion<br>[1184, 1263, 6]"]
23[Wall] 23[Wall]
24["SweepEdge Opposite"] 24["SweepEdge Opposite"]
25["SweepEdge Adjacent"] 25["SweepEdge Adjacent"]
26["Sweep Extrusion<br>[1184, 1263, 5]"] 26["Sweep Extrusion<br>[1184, 1263, 6]"]
27["Sweep Extrusion<br>[1184, 1263, 5]"] 27["Sweep Extrusion<br>[1184, 1263, 6]"]
28["Sweep Extrusion<br>[1184, 1263, 5]"] 28["Sweep Extrusion<br>[1184, 1263, 6]"]
29["Sweep Extrusion<br>[1184, 1263, 5]"] 29["Sweep Extrusion<br>[1184, 1263, 6]"]
33["Sweep Extrusion<br>[1466, 1499, 5]"] 33["Sweep Extrusion<br>[1466, 1499, 6]"]
34[Wall] 34[Wall]
35["Cap End"] 35["Cap End"]
36["SweepEdge Opposite"] 36["SweepEdge Opposite"]
37["SweepEdge Adjacent"] 37["SweepEdge Adjacent"]
41["Sweep Extrusion<br>[1630, 1695, 5]"] 41["Sweep Extrusion<br>[1630, 1695, 6]"]
42[Wall] 42[Wall]
43["Cap Start"] 43["Cap Start"]
44["Cap End"] 44["Cap End"]
45["SweepEdge Opposite"] 45["SweepEdge Opposite"]
46["SweepEdge Adjacent"] 46["SweepEdge Adjacent"]
50["Sweep Extrusion<br>[1948, 1992, 5]"] 50["Sweep Extrusion<br>[1948, 1992, 6]"]
51[Wall] 51[Wall]
52["SweepEdge Opposite"] 52["SweepEdge Opposite"]
53["SweepEdge Adjacent"] 53["SweepEdge Adjacent"]
54["Sweep Extrusion<br>[1948, 1992, 5]"] 54["Sweep Extrusion<br>[1948, 1992, 6]"]
55["Sweep Extrusion<br>[1948, 1992, 5]"] 55["Sweep Extrusion<br>[1948, 1992, 6]"]
56["Sweep Extrusion<br>[1948, 1992, 5]"] 56["Sweep Extrusion<br>[1948, 1992, 6]"]
57["Sweep Extrusion<br>[1948, 1992, 5]"] 57["Sweep Extrusion<br>[1948, 1992, 6]"]
61["Sweep Extrusion<br>[2271, 2315, 5]"] 61["Sweep Extrusion<br>[2271, 2315, 6]"]
62[Wall] 62[Wall]
63["Cap End"] 63["Cap End"]
64["SweepEdge Opposite"] 64["SweepEdge Opposite"]
65["SweepEdge Adjacent"] 65["SweepEdge Adjacent"]
66["Sweep Extrusion<br>[2271, 2315, 5]"] 66["Sweep Extrusion<br>[2271, 2315, 6]"]
67["Sweep Extrusion<br>[2271, 2315, 5]"] 67["Sweep Extrusion<br>[2271, 2315, 6]"]
68["Sweep Extrusion<br>[2271, 2315, 5]"] 68["Sweep Extrusion<br>[2271, 2315, 6]"]
69["Sweep Extrusion<br>[2271, 2315, 5]"] 69["Sweep Extrusion<br>[2271, 2315, 6]"]
70["Sweep Extrusion<br>[2271, 2315, 5]"] 70["Sweep Extrusion<br>[2271, 2315, 6]"]
71["Sweep Extrusion<br>[2271, 2315, 5]"] 71["Sweep Extrusion<br>[2271, 2315, 6]"]
72["Sweep Extrusion<br>[2271, 2315, 5]"] 72["Sweep Extrusion<br>[2271, 2315, 6]"]
73["Sweep Extrusion<br>[2271, 2315, 5]"] 73["Sweep Extrusion<br>[2271, 2315, 6]"]
74["Sweep Extrusion<br>[2271, 2315, 5]"] 74["Sweep Extrusion<br>[2271, 2315, 6]"]
75["Sweep Extrusion<br>[2271, 2315, 5]"] 75["Sweep Extrusion<br>[2271, 2315, 6]"]
76["Sweep Extrusion<br>[2271, 2315, 5]"] 76["Sweep Extrusion<br>[2271, 2315, 6]"]
77["Sweep Extrusion<br>[2271, 2315, 5]"] 77["Sweep Extrusion<br>[2271, 2315, 6]"]
78["Sweep Extrusion<br>[2271, 2315, 5]"] 78["Sweep Extrusion<br>[2271, 2315, 6]"]
79["Sweep Extrusion<br>[2271, 2315, 5]"] 79["Sweep Extrusion<br>[2271, 2315, 6]"]
80["Sweep Extrusion<br>[2271, 2315, 5]"] 80["Sweep Extrusion<br>[2271, 2315, 6]"]
88["Sweep Extrusion<br>[2724, 2792, 5]"] 88["Sweep Extrusion<br>[2724, 2792, 6]"]
89[Wall] 89[Wall]
90[Wall] 90[Wall]
91[Wall] 91[Wall]
@ -272,11 +272,11 @@ flowchart LR
99["SweepEdge Adjacent"] 99["SweepEdge Adjacent"]
100["SweepEdge Opposite"] 100["SweepEdge Opposite"]
101["SweepEdge Adjacent"] 101["SweepEdge Adjacent"]
102["Sweep Extrusion<br>[2724, 2792, 5]"] 102["Sweep Extrusion<br>[2724, 2792, 6]"]
103["Sweep Extrusion<br>[2724, 2792, 5]"] 103["Sweep Extrusion<br>[2724, 2792, 6]"]
104["Sweep Extrusion<br>[2724, 2792, 5]"] 104["Sweep Extrusion<br>[2724, 2792, 6]"]
105["Sweep Extrusion<br>[2724, 2792, 5]"] 105["Sweep Extrusion<br>[2724, 2792, 6]"]
113["Sweep Extrusion<br>[3198, 3272, 5]"] 113["Sweep Extrusion<br>[3198, 3272, 6]"]
114[Wall] 114[Wall]
115[Wall] 115[Wall]
116[Wall] 116[Wall]
@ -290,41 +290,41 @@ flowchart LR
124["SweepEdge Adjacent"] 124["SweepEdge Adjacent"]
125["SweepEdge Opposite"] 125["SweepEdge Opposite"]
126["SweepEdge Adjacent"] 126["SweepEdge Adjacent"]
127["Sweep Extrusion<br>[3198, 3272, 5]"] 127["Sweep Extrusion<br>[3198, 3272, 6]"]
128["Sweep Extrusion<br>[3198, 3272, 5]"] 128["Sweep Extrusion<br>[3198, 3272, 6]"]
129["Sweep Extrusion<br>[3198, 3272, 5]"] 129["Sweep Extrusion<br>[3198, 3272, 6]"]
130["Sweep Extrusion<br>[3198, 3272, 5]"] 130["Sweep Extrusion<br>[3198, 3272, 6]"]
131["Plane<br>[327, 344, 4]"] 131["Plane<br>[327, 344, 5]"]
138["Sweep Extrusion<br>[483, 516, 4]"] 138["Sweep Extrusion<br>[483, 516, 5]"]
139[Wall] 139[Wall]
140["Cap Start"] 140["Cap Start"]
141["Cap End"] 141["Cap End"]
142["SweepEdge Opposite"] 142["SweepEdge Opposite"]
143["SweepEdge Adjacent"] 143["SweepEdge Adjacent"]
150["Sweep Extrusion<br>[771, 804, 4]"] 150["Sweep Extrusion<br>[771, 804, 5]"]
151[Wall] 151[Wall]
152["Cap Start"] 152["Cap Start"]
153["Cap End"] 153["Cap End"]
154["SweepEdge Opposite"] 154["SweepEdge Opposite"]
155["SweepEdge Adjacent"] 155["SweepEdge Adjacent"]
159["Sweep Extrusion<br>[1106, 1140, 4]"] 159["Sweep Extrusion<br>[1106, 1140, 5]"]
160[Wall] 160[Wall]
161["SweepEdge Opposite"] 161["SweepEdge Opposite"]
162["SweepEdge Adjacent"] 162["SweepEdge Adjacent"]
163["Sweep Extrusion<br>[1106, 1140, 4]"] 163["Sweep Extrusion<br>[1106, 1140, 5]"]
164["Sweep Extrusion<br>[1106, 1140, 4]"] 164["Sweep Extrusion<br>[1106, 1140, 5]"]
165["Sweep Extrusion<br>[1106, 1140, 4]"] 165["Sweep Extrusion<br>[1106, 1140, 5]"]
166["Sweep Extrusion<br>[1106, 1140, 4]"] 166["Sweep Extrusion<br>[1106, 1140, 5]"]
170["Sweep Extrusion<br>[1444, 1478, 4]"] 170["Sweep Extrusion<br>[1444, 1478, 5]"]
171[Wall] 171[Wall]
172["SweepEdge Opposite"] 172["SweepEdge Opposite"]
173["SweepEdge Adjacent"] 173["SweepEdge Adjacent"]
174["Sweep Extrusion<br>[1444, 1478, 4]"] 174["Sweep Extrusion<br>[1444, 1478, 5]"]
175["Sweep Extrusion<br>[1444, 1478, 4]"] 175["Sweep Extrusion<br>[1444, 1478, 5]"]
176["Sweep Extrusion<br>[1444, 1478, 4]"] 176["Sweep Extrusion<br>[1444, 1478, 5]"]
177["Sweep Extrusion<br>[1444, 1478, 4]"] 177["Sweep Extrusion<br>[1444, 1478, 5]"]
178["Plane<br>[1632, 1649, 4]"] 178["Plane<br>[1632, 1649, 5]"]
186["Sweep Revolve<br>[1979, 1998, 4]"] 186["Sweep Revolve<br>[1979, 1996, 5]"]
187[Wall] 187[Wall]
188[Wall] 188[Wall]
189[Wall] 189[Wall]
@ -332,8 +332,8 @@ flowchart LR
191["SweepEdge Adjacent"] 191["SweepEdge Adjacent"]
192["SweepEdge Adjacent"] 192["SweepEdge Adjacent"]
193["SweepEdge Adjacent"] 193["SweepEdge Adjacent"]
194["Plane<br>[2084, 2101, 4]"] 194["Plane<br>[2082, 2099, 5]"]
202["Sweep Revolve<br>[2448, 2467, 4]"] 202["Sweep Revolve<br>[2446, 2463, 5]"]
203[Wall] 203[Wall]
204[Wall] 204[Wall]
205[Wall] 205[Wall]
@ -342,8 +342,8 @@ flowchart LR
208["SweepEdge Adjacent"] 208["SweepEdge Adjacent"]
209["SweepEdge Adjacent"] 209["SweepEdge Adjacent"]
210["SweepEdge Adjacent"] 210["SweepEdge Adjacent"]
211["Plane<br>[2922, 2945, 4]"] 211["Plane<br>[2918, 2941, 5]"]
219["Sweep Extrusion<br>[3867, 3913, 4]"] 219["Sweep Extrusion<br>[3863, 3909, 5]"]
220[Wall] 220[Wall]
221[Wall] 221[Wall]
222[Wall] 222[Wall]
@ -358,8 +358,8 @@ flowchart LR
231["SweepEdge Adjacent"] 231["SweepEdge Adjacent"]
232["SweepEdge Opposite"] 232["SweepEdge Opposite"]
233["SweepEdge Adjacent"] 233["SweepEdge Adjacent"]
234["Plane<br>[2922, 2945, 4]"] 234["Plane<br>[2918, 2941, 5]"]
242["Sweep Extrusion<br>[3867, 3913, 4]"] 242["Sweep Extrusion<br>[3863, 3909, 5]"]
243[Wall] 243[Wall]
244[Wall] 244[Wall]
245[Wall] 245[Wall]
@ -374,8 +374,8 @@ flowchart LR
254["SweepEdge Adjacent"] 254["SweepEdge Adjacent"]
255["SweepEdge Opposite"] 255["SweepEdge Opposite"]
256["SweepEdge Adjacent"] 256["SweepEdge Adjacent"]
257["Plane<br>[4324, 4341, 4]"] 257["Plane<br>[4320, 4337, 5]"]
284["Sweep Revolve<br>[5634, 5653, 4]"] 284["Sweep Revolve<br>[5630, 5647, 5]"]
285[Wall] 285[Wall]
286[Wall] 286[Wall]
287[Wall] 287[Wall]
@ -424,8 +424,8 @@ flowchart LR
330["SweepEdge Adjacent"] 330["SweepEdge Adjacent"]
331["SweepEdge Adjacent"] 331["SweepEdge Adjacent"]
332["SweepEdge Adjacent"] 332["SweepEdge Adjacent"]
333["Plane<br>[706, 732, 7]"] 333["Plane<br>[706, 732, 8]"]
345["Sweep Revolve<br>[1182, 1201, 7]"] 345["Sweep Revolve<br>[1182, 1199, 8]"]
346[Wall] 346[Wall]
347[Wall] 347[Wall]
348[Wall] 348[Wall]
@ -444,8 +444,8 @@ flowchart LR
361["SweepEdge Adjacent"] 361["SweepEdge Adjacent"]
362["SweepEdge Adjacent"] 362["SweepEdge Adjacent"]
363["SweepEdge Adjacent"] 363["SweepEdge Adjacent"]
364["Plane<br>[484, 501, 6]"] 364["Plane<br>[484, 501, 7]"]
384["Sweep Revolve<br>[2243, 2295, 6]"] 384["Sweep Revolve<br>[2243, 2293, 7]"]
385[Wall] 385[Wall]
386[Wall] 386[Wall]
387[Wall] 387[Wall]
@ -499,8 +499,8 @@ flowchart LR
435["SweepEdge Adjacent"] 435["SweepEdge Adjacent"]
436["SweepEdge Opposite"] 436["SweepEdge Opposite"]
437["SweepEdge Adjacent"] 437["SweepEdge Adjacent"]
438["Plane<br>[460, 477, 8]"] 438["Plane<br>[460, 477, 9]"]
455["Sweep Revolve<br>[1486, 1517, 8]"] 455["Sweep Revolve<br>[1486, 1515, 9]"]
456[Wall] 456[Wall]
457[Wall] 457[Wall]
458[Wall] 458[Wall]
@ -529,17 +529,17 @@ flowchart LR
481["SweepEdge Adjacent"] 481["SweepEdge Adjacent"]
482["SweepEdge Adjacent"] 482["SweepEdge Adjacent"]
483["SweepEdge Adjacent"] 483["SweepEdge Adjacent"]
484["StartSketchOnFace<br>[770, 797, 5]"] 484["StartSketchOnFace<br>[770, 797, 6]"]
485["StartSketchOnFace<br>[947, 978, 5]"] 485["StartSketchOnFace<br>[947, 978, 6]"]
486["StartSketchOnFace<br>[1385, 1414, 5]"] 486["StartSketchOnFace<br>[1385, 1414, 6]"]
487["StartSketchOnFace<br>[1524, 1558, 5]"] 487["StartSketchOnFace<br>[1524, 1558, 6]"]
488["StartSketchOnFace<br>[1709, 1742, 5]"] 488["StartSketchOnFace<br>[1709, 1742, 6]"]
489["StartSketchOnFace<br>[2009, 2038, 5]"] 489["StartSketchOnFace<br>[2009, 2038, 6]"]
490["StartSketchOnFace<br>[2338, 2367, 5]"] 490["StartSketchOnFace<br>[2338, 2367, 6]"]
491["StartSketchOnFace<br>[2821, 2854, 5]"] 491["StartSketchOnFace<br>[2821, 2854, 6]"]
492["StartSketchOnFace<br>[603, 632, 4]"] 492["StartSketchOnFace<br>[603, 632, 5]"]
493["StartSketchOnFace<br>[865, 899, 4]"] 493["StartSketchOnFace<br>[865, 899, 5]"]
494["StartSketchOnFace<br>[1202, 1231, 4]"] 494["StartSketchOnFace<br>[1202, 1231, 5]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 ---- 5 2 ---- 5

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ description: Variables in memory after executing car-wheel-assembly.kcl
{ {
"brakeCaliper": { "brakeCaliper": {
"type": "Module", "type": "Module",
"value": 6 "value": 7
}, },
"c1": { "c1": {
"type": "TagIdentifier", "type": "TagIdentifier",
@ -14,15 +14,15 @@ description: Variables in memory after executing car-wheel-assembly.kcl
}, },
"carRotor": { "carRotor": {
"type": "Module", "type": "Module",
"value": 5 "value": 6
}, },
"carTire": { "carTire": {
"type": "Module", "type": "Module",
"value": 8 "value": 9
}, },
"carWheel": { "carWheel": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
}, },
"lugCount": { "lugCount": {
"type": "Number", "type": "Number",
@ -39,6 +39,6 @@ description: Variables in memory after executing car-wheel-assembly.kcl
}, },
"lugNut": { "lugNut": {
"type": "Module", "type": "Module",
"value": 7 "value": 8
} }
} }

View File

@ -10,118 +10,118 @@ flowchart LR
8[Solid2d] 8[Solid2d]
end end
subgraph path18 [Path] subgraph path18 [Path]
18["Path<br>[984, 1028, 0]"] 18["Path<br>[982, 1026, 0]"]
19["Segment<br>[1034, 1053, 0]"] 19["Segment<br>[1032, 1051, 0]"]
20["Segment<br>[1059, 1093, 0]"] 20["Segment<br>[1057, 1091, 0]"]
21["Segment<br>[1099, 1183, 0]"] 21["Segment<br>[1097, 1181, 0]"]
22["Segment<br>[1189, 1241, 0]"] 22["Segment<br>[1187, 1239, 0]"]
23["Segment<br>[1247, 1331, 0]"] 23["Segment<br>[1245, 1329, 0]"]
24["Segment<br>[1337, 1389, 0]"] 24["Segment<br>[1335, 1387, 0]"]
25["Segment<br>[1395, 1477, 0]"] 25["Segment<br>[1393, 1475, 0]"]
26["Segment<br>[1483, 1523, 0]"] 26["Segment<br>[1481, 1521, 0]"]
27["Segment<br>[1529, 1548, 0]"] 27["Segment<br>[1527, 1546, 0]"]
28["Segment<br>[1554, 1607, 0]"] 28["Segment<br>[1552, 1605, 0]"]
29["Segment<br>[1613, 1695, 0]"] 29["Segment<br>[1611, 1693, 0]"]
30["Segment<br>[1701, 1791, 0]"] 30["Segment<br>[1699, 1789, 0]"]
31["Segment<br>[1797, 1881, 0]"] 31["Segment<br>[1795, 1879, 0]"]
32["Segment<br>[1887, 1977, 0]"] 32["Segment<br>[1885, 1975, 0]"]
33["Segment<br>[1983, 2067, 0]"] 33["Segment<br>[1981, 2065, 0]"]
34["Segment<br>[2073, 2129, 0]"] 34["Segment<br>[2071, 2127, 0]"]
35["Segment<br>[2135, 2142, 0]"] 35["Segment<br>[2133, 2140, 0]"]
36[Solid2d] 36[Solid2d]
end end
subgraph path89 [Path] subgraph path89 [Path]
89["Path<br>[2409, 2468, 0]"] 89["Path<br>[2407, 2466, 0]"]
90["Segment<br>[2409, 2468, 0]"] 90["Segment<br>[2407, 2466, 0]"]
91[Solid2d] 91[Solid2d]
end end
subgraph path98 [Path] subgraph path98 [Path]
98["Path<br>[2569, 2599, 0]"] 98["Path<br>[2567, 2597, 0]"]
99["Segment<br>[2605, 2624, 0]"] 99["Segment<br>[2603, 2622, 0]"]
100["Segment<br>[2630, 2713, 0]"] 100["Segment<br>[2628, 2711, 0]"]
101["Segment<br>[2719, 2775, 0]"] 101["Segment<br>[2717, 2773, 0]"]
102["Segment<br>[2781, 2788, 0]"] 102["Segment<br>[2779, 2786, 0]"]
103[Solid2d] 103[Solid2d]
end end
subgraph path117 [Path] subgraph path117 [Path]
117["Path<br>[3026, 3057, 0]"] 117["Path<br>[3024, 3055, 0]"]
118["Segment<br>[3063, 3108, 0]"] 118["Segment<br>[3061, 3106, 0]"]
119["Segment<br>[3114, 3204, 0]"] 119["Segment<br>[3112, 3202, 0]"]
120["Segment<br>[3210, 3256, 0]"] 120["Segment<br>[3208, 3254, 0]"]
121["Segment<br>[3262, 3315, 0]"] 121["Segment<br>[3260, 3313, 0]"]
122["Segment<br>[3321, 3346, 0]"] 122["Segment<br>[3319, 3344, 0]"]
123["Segment<br>[3352, 3408, 0]"] 123["Segment<br>[3350, 3406, 0]"]
124["Segment<br>[3414, 3421, 0]"] 124["Segment<br>[3412, 3419, 0]"]
125[Solid2d] 125[Solid2d]
end end
subgraph path140 [Path] subgraph path140 [Path]
140["Path<br>[3503, 3530, 0]"] 140["Path<br>[3499, 3526, 0]"]
141["Segment<br>[3536, 3556, 0]"] 141["Segment<br>[3532, 3552, 0]"]
142["Segment<br>[3562, 3605, 0]"] 142["Segment<br>[3558, 3601, 0]"]
143["Segment<br>[3611, 3629, 0]"] 143["Segment<br>[3607, 3625, 0]"]
144["Segment<br>[3635, 3655, 0]"] 144["Segment<br>[3631, 3651, 0]"]
145["Segment<br>[3661, 3681, 0]"] 145["Segment<br>[3657, 3677, 0]"]
146["Segment<br>[3687, 3735, 0]"] 146["Segment<br>[3683, 3731, 0]"]
147["Segment<br>[3741, 3797, 0]"] 147["Segment<br>[3737, 3793, 0]"]
148["Segment<br>[3803, 3810, 0]"] 148["Segment<br>[3799, 3806, 0]"]
149[Solid2d] 149[Solid2d]
end end
subgraph path166 [Path] subgraph path166 [Path]
166["Path<br>[3916, 3975, 0]"] 166["Path<br>[3910, 3969, 0]"]
167["Segment<br>[3916, 3975, 0]"] 167["Segment<br>[3910, 3969, 0]"]
168[Solid2d] 168[Solid2d]
end end
subgraph path169 [Path] subgraph path169 [Path]
169["Path<br>[3986, 4023, 0]"] 169["Path<br>[3980, 4017, 0]"]
170["Segment<br>[3986, 4023, 0]"] 170["Segment<br>[3980, 4017, 0]"]
171[Solid2d] 171[Solid2d]
end end
subgraph path178 [Path] subgraph path178 [Path]
178["Path<br>[4165, 4203, 0]"] 178["Path<br>[4159, 4197, 0]"]
179["Segment<br>[4165, 4203, 0]"] 179["Segment<br>[4159, 4197, 0]"]
180[Solid2d] 180[Solid2d]
end end
subgraph path192 [Path] subgraph path192 [Path]
192["Path<br>[4476, 4514, 0]"] 192["Path<br>[4470, 4508, 0]"]
193["Segment<br>[4476, 4514, 0]"] 193["Segment<br>[4470, 4508, 0]"]
194[Solid2d] 194[Solid2d]
end end
subgraph path203 [Path] subgraph path203 [Path]
203["Path<br>[4766, 4818, 0]"] 203["Path<br>[4760, 4812, 0]"]
204["Segment<br>[4766, 4818, 0]"] 204["Segment<br>[4760, 4812, 0]"]
205[Solid2d] 205[Solid2d]
end end
subgraph path213 [Path] subgraph path213 [Path]
213["Path<br>[5065, 5109, 0]"] 213["Path<br>[5059, 5103, 0]"]
214["Segment<br>[5115, 5155, 0]"] 214["Segment<br>[5109, 5149, 0]"]
215["Segment<br>[5161, 5180, 0]"] 215["Segment<br>[5155, 5174, 0]"]
216["Segment<br>[5186, 5205, 0]"] 216["Segment<br>[5180, 5199, 0]"]
217["Segment<br>[5211, 5230, 0]"] 217["Segment<br>[5205, 5224, 0]"]
218["Segment<br>[5236, 5261, 0]"] 218["Segment<br>[5230, 5255, 0]"]
219["Segment<br>[5267, 5407, 0]"] 219["Segment<br>[5261, 5401, 0]"]
220["Segment<br>[5413, 5469, 0]"] 220["Segment<br>[5407, 5463, 0]"]
221["Segment<br>[5475, 5482, 0]"] 221["Segment<br>[5469, 5476, 0]"]
222[Solid2d] 222[Solid2d]
end end
subgraph path239 [Path] subgraph path239 [Path]
239["Path<br>[5614, 5643, 0]"] 239["Path<br>[5606, 5635, 0]"]
240["Segment<br>[5649, 5670, 0]"] 240["Segment<br>[5641, 5662, 0]"]
241["Segment<br>[5676, 5707, 0]"] 241["Segment<br>[5668, 5699, 0]"]
242["Segment<br>[5713, 5744, 0]"] 242["Segment<br>[5705, 5736, 0]"]
243["Segment<br>[5750, 5782, 0]"] 243["Segment<br>[5742, 5774, 0]"]
244["Segment<br>[5788, 5810, 0]"] 244["Segment<br>[5780, 5802, 0]"]
245["Segment<br>[5816, 5837, 0]"] 245["Segment<br>[5808, 5829, 0]"]
246["Segment<br>[5843, 5868, 0]"] 246["Segment<br>[5835, 5860, 0]"]
247["Segment<br>[5874, 5905, 0]"] 247["Segment<br>[5866, 5897, 0]"]
248["Segment<br>[5911, 5943, 0]"] 248["Segment<br>[5903, 5935, 0]"]
249["Segment<br>[5949, 5981, 0]"] 249["Segment<br>[5941, 5973, 0]"]
250["Segment<br>[5987, 6008, 0]"] 250["Segment<br>[5979, 6000, 0]"]
251["Segment<br>[6014, 6070, 0]"] 251["Segment<br>[6006, 6062, 0]"]
252["Segment<br>[6076, 6083, 0]"] 252["Segment<br>[6068, 6075, 0]"]
253[Solid2d] 253[Solid2d]
end end
1["Plane<br>[241, 258, 0]"] 1["Plane<br>[241, 258, 0]"]
9["Sweep Revolve<br>[674, 706, 0]"] 9["Sweep Revolve<br>[674, 704, 0]"]
10[Wall] 10[Wall]
11[Wall] 11[Wall]
12[Wall] 12[Wall]
@ -129,8 +129,8 @@ flowchart LR
14["SweepEdge Adjacent"] 14["SweepEdge Adjacent"]
15["SweepEdge Adjacent"] 15["SweepEdge Adjacent"]
16["SweepEdge Adjacent"] 16["SweepEdge Adjacent"]
17["Plane<br>[955, 978, 0]"] 17["Plane<br>[953, 976, 0]"]
37["Sweep Extrusion<br>[2148, 2170, 0]"] 37["Sweep Extrusion<br>[2146, 2168, 0]"]
38[Wall] 38[Wall]
39[Wall] 39[Wall]
40[Wall] 40[Wall]
@ -181,14 +181,14 @@ flowchart LR
85["SweepEdge Adjacent"] 85["SweepEdge Adjacent"]
86["SweepEdge Opposite"] 86["SweepEdge Opposite"]
87["SweepEdge Adjacent"] 87["SweepEdge Adjacent"]
88["Plane<br>[2375, 2402, 0]"] 88["Plane<br>[2373, 2400, 0]"]
92["Sweep Extrusion<br>[2483, 2517, 0]"] 92["Sweep Extrusion<br>[2481, 2515, 0]"]
93[Wall] 93[Wall]
94["Cap Start"] 94["Cap Start"]
95["Cap End"] 95["Cap End"]
96["SweepEdge Opposite"] 96["SweepEdge Opposite"]
97["SweepEdge Adjacent"] 97["SweepEdge Adjacent"]
104["Sweep Extrusion<br>[2937, 2972, 0]"] 104["Sweep Extrusion<br>[2935, 2970, 0]"]
105[Wall] 105[Wall]
106[Wall] 106[Wall]
107[Wall] 107[Wall]
@ -198,10 +198,10 @@ flowchart LR
111["SweepEdge Adjacent"] 111["SweepEdge Adjacent"]
112["SweepEdge Opposite"] 112["SweepEdge Opposite"]
113["SweepEdge Adjacent"] 113["SweepEdge Adjacent"]
114["Sweep Extrusion<br>[2937, 2972, 0]"] 114["Sweep Extrusion<br>[2935, 2970, 0]"]
115["Sweep Extrusion<br>[2937, 2972, 0]"] 115["Sweep Extrusion<br>[2935, 2970, 0]"]
116["Plane<br>[3003, 3020, 0]"] 116["Plane<br>[3001, 3018, 0]"]
126["Sweep Revolve<br>[3427, 3446, 0]"] 126["Sweep Revolve<br>[3425, 3442, 0]"]
127[Wall] 127[Wall]
128[Wall] 128[Wall]
129[Wall] 129[Wall]
@ -214,8 +214,8 @@ flowchart LR
136["SweepEdge Adjacent"] 136["SweepEdge Adjacent"]
137["SweepEdge Adjacent"] 137["SweepEdge Adjacent"]
138["SweepEdge Adjacent"] 138["SweepEdge Adjacent"]
139["Plane<br>[3480, 3497, 0]"] 139["Plane<br>[3476, 3493, 0]"]
150["Sweep Revolve<br>[3816, 3835, 0]"] 150["Sweep Revolve<br>[3812, 3829, 0]"]
151[Wall] 151[Wall]
152[Wall] 152[Wall]
153[Wall] 153[Wall]
@ -230,40 +230,40 @@ flowchart LR
162["SweepEdge Adjacent"] 162["SweepEdge Adjacent"]
163["SweepEdge Adjacent"] 163["SweepEdge Adjacent"]
164["SweepEdge Adjacent"] 164["SweepEdge Adjacent"]
165["Plane<br>[3879, 3909, 0]"] 165["Plane<br>[3873, 3903, 0]"]
172["Sweep Extrusion<br>[4042, 4076, 0]"] 172["Sweep Extrusion<br>[4036, 4070, 0]"]
173[Wall] 173[Wall]
174["Cap Start"] 174["Cap Start"]
175["Cap End"] 175["Cap End"]
176["SweepEdge Opposite"] 176["SweepEdge Opposite"]
177["SweepEdge Adjacent"] 177["SweepEdge Adjacent"]
181["Sweep Extrusion<br>[4352, 4387, 0]"] 181["Sweep Extrusion<br>[4346, 4381, 0]"]
182[Wall] 182[Wall]
183["SweepEdge Opposite"] 183["SweepEdge Opposite"]
184["SweepEdge Adjacent"] 184["SweepEdge Adjacent"]
185["Sweep Extrusion<br>[4352, 4387, 0]"] 185["Sweep Extrusion<br>[4346, 4381, 0]"]
186["Sweep Extrusion<br>[4352, 4387, 0]"] 186["Sweep Extrusion<br>[4346, 4381, 0]"]
187["Sweep Extrusion<br>[4352, 4387, 0]"] 187["Sweep Extrusion<br>[4346, 4381, 0]"]
188["Sweep Extrusion<br>[4352, 4387, 0]"] 188["Sweep Extrusion<br>[4346, 4381, 0]"]
189["Sweep Extrusion<br>[4352, 4387, 0]"] 189["Sweep Extrusion<br>[4346, 4381, 0]"]
190["Sweep Extrusion<br>[4352, 4387, 0]"] 190["Sweep Extrusion<br>[4346, 4381, 0]"]
191["Sweep Extrusion<br>[4352, 4387, 0]"] 191["Sweep Extrusion<br>[4346, 4381, 0]"]
195["Sweep Extrusion<br>[4663, 4698, 0]"] 195["Sweep Extrusion<br>[4657, 4692, 0]"]
196[Wall] 196[Wall]
197["SweepEdge Opposite"] 197["SweepEdge Opposite"]
198["SweepEdge Adjacent"] 198["SweepEdge Adjacent"]
199["Sweep Extrusion<br>[4663, 4698, 0]"] 199["Sweep Extrusion<br>[4657, 4692, 0]"]
200["Sweep Extrusion<br>[4663, 4698, 0]"] 200["Sweep Extrusion<br>[4657, 4692, 0]"]
201["Sweep Extrusion<br>[4663, 4698, 0]"] 201["Sweep Extrusion<br>[4657, 4692, 0]"]
202["Plane<br>[4743, 4760, 0]"] 202["Plane<br>[4737, 4754, 0]"]
206["Sweep Extrusion<br>[4914, 4955, 0]"] 206["Sweep Extrusion<br>[4908, 4949, 0]"]
207[Wall] 207[Wall]
208["Cap Start"] 208["Cap Start"]
209["Cap End"] 209["Cap End"]
210["SweepEdge Opposite"] 210["SweepEdge Opposite"]
211["SweepEdge Adjacent"] 211["SweepEdge Adjacent"]
212["Plane<br>[5042, 5059, 0]"] 212["Plane<br>[5036, 5053, 0]"]
223["Sweep Revolve<br>[5488, 5507, 0]"] 223["Sweep Revolve<br>[5482, 5499, 0]"]
224[Wall] 224[Wall]
225[Wall] 225[Wall]
226[Wall] 226[Wall]
@ -278,8 +278,8 @@ flowchart LR
235["SweepEdge Adjacent"] 235["SweepEdge Adjacent"]
236["SweepEdge Adjacent"] 236["SweepEdge Adjacent"]
237["SweepEdge Adjacent"] 237["SweepEdge Adjacent"]
238["Plane<br>[5562, 5607, 0]"] 238["Plane<br>[5554, 5599, 0]"]
254["Sweep Extrusion<br>[6097, 6142, 0]"] 254["Sweep Extrusion<br>[6089, 6134, 0]"]
255[Wall] 255[Wall]
256[Wall] 256[Wall]
257[Wall] 257[Wall]
@ -318,12 +318,12 @@ flowchart LR
290["SweepEdge Adjacent"] 290["SweepEdge Adjacent"]
291["SweepEdge Opposite"] 291["SweepEdge Opposite"]
292["SweepEdge Adjacent"] 292["SweepEdge Adjacent"]
293["StartSketchOnPlane<br>[2361, 2403, 0]"] 293["StartSketchOnPlane<br>[2359, 2401, 0]"]
294["StartSketchOnFace<br>[2531, 2563, 0]"] 294["StartSketchOnFace<br>[2529, 2561, 0]"]
295["StartSketchOnPlane<br>[3865, 3910, 0]"] 295["StartSketchOnPlane<br>[3859, 3904, 0]"]
296["StartSketchOnFace<br>[4127, 4159, 0]"] 296["StartSketchOnFace<br>[4121, 4153, 0]"]
297["StartSketchOnFace<br>[4438, 4470, 0]"] 297["StartSketchOnFace<br>[4432, 4464, 0]"]
298["StartSketchOnPlane<br>[5548, 5608, 0]"] 298["StartSketchOnPlane<br>[5540, 5600, 0]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 --- 4 2 --- 4

File diff suppressed because it is too large Load Diff

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