Compare commits

..

1 Commits

Author SHA1 Message Date
441e18e916 Update generated test output 2025-04-23 19:36:02 -04:00
355 changed files with 41247 additions and 31839 deletions

View File

@ -4,7 +4,6 @@ on:
branches:
- main
- all-e2e # this bypasses `fixme()` using `orRunWhenFullSuiteEnabled()`
- pierremtb/adhoc/quick-eval-stream-offset-impact-on-e2e
pull_request:
schedule:
- cron: 0 * * * * # hourly

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ Get the next adjacent edge to the edge given.
```js
getNextAdjacentEdge(edge: TagIdentifier): Uuid
getNextAdjacentEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getNextAdjacentEdge(edge: TagIdentifier): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the next adjacent edge of. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
### Returns

View File

@ -9,7 +9,7 @@ Get the opposite edge to the edge given.
```js
getOppositeEdge(edge: TagIdentifier): Uuid
getOppositeEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getOppositeEdge(edge: TagIdentifier): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the opposite edge of. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
### Returns

View File

@ -9,7 +9,7 @@ Get the previous adjacent edge to the edge given.
```js
getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
```
@ -17,7 +17,7 @@ getPreviousAdjacentEdge(edge: TagIdentifier): Uuid
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `edge` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The tag of the edge you want to find the previous adjacent edge of. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
### Returns

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,8 @@ layout: manual
* [`Z`](kcl/consts/std-Z)
* [`abs`](kcl/abs)
* [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
* [`angledLine`](kcl/angledLine)
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`appearance`](kcl/appearance)
@ -45,7 +47,6 @@ layout: manual
* [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`clone`](kcl/clone)
* [`close`](kcl/close)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
@ -73,7 +74,7 @@ layout: manual
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`offsetPlane`](kcl/std-offsetPlane)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d)

View File

@ -22,5 +22,6 @@ once fixed in engine will just start working here with no language changes.
chamfer cases work currently.
- **Appearance**: Changing the appearance on a loft does not work.
Changing the appearance on an imported model does not work.
- **CSG Booleans**: Coplanar (bodies that share a plane) unions, subtractions, and intersections are not currently supported.

View File

@ -24,8 +24,8 @@ legAngX(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -35,7 +35,7 @@ legAngX(
### Examples
```js
legAngX(hypotenuse = 5, leg = 3)
legAngX(5, 3)
```

View File

@ -24,8 +24,8 @@ legAngY(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -35,7 +35,7 @@ legAngY(
### Examples
```js
legAngY(hypotenuse = 5, leg = 3)
legAngY(5, 3)
```

View File

@ -24,8 +24,8 @@ legLen(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes |
### Returns
@ -35,7 +35,7 @@ legLen(
### Examples
```js
legLen(hypotenuse = 5, leg = 3)
legLen(5, 3)
```

121
docs/kcl/offsetPlane.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 one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +0,0 @@
---
title: "GeometryWithImportedGeometry"
excerpt: "A geometry including an imported geometry."
layout: manual
---
A geometry including an imported geometry.
**This schema accepts exactly one of the following:**
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Sketch`](/docs/kcl/types/Sketch)| | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the sketch (this will change when the engine's reference to it changes). | No |
| `paths` |`[` [`Path`](/docs/kcl/types/Path) `]`| The paths in the sketch. | No |
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
| `artifactId` |[`string`](/docs/kcl/types/string)| The original id of the sketch. This stays the same even if the sketch is is sketched on face etc. | No |
| `originalId` |[`string`](/docs/kcl/types/string)| | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
----
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: [`Solid`](/docs/kcl/types/Solid)| | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the solid. | No |
| `artifactId` |[`string`](/docs/kcl/types/string)| The artifact ID of the solid. Unlike `id`, this doesn't change. | No |
| `value` |`[` [`ExtrudeSurface`](/docs/kcl/types/ExtrudeSurface) `]`| The extrude surfaces. | No |
| `sketch` |[`Sketch`](/docs/kcl/types/Sketch)| The sketch. | No |
| `height` |[`number`](/docs/kcl/types/number)| The height of the solid. | No |
| `startCapId` |[`string`](/docs/kcl/types/string)| The id of the extrusion start cap | No |
| `endCapId` |[`string`](/docs/kcl/types/string)| The id of the extrusion end cap | No |
| `edgeCuts` |`[` [`EdgeCut`](/docs/kcl/types/EdgeCut) `]`| Chamfers or fillets on this solid. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| The units of the solid. | No |
| `sectional` |`boolean`| Is this a sectional solid? | No |
----
Data for an imported geometry.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `ImportedGeometry`| | No |
| `id` |[`string`](/docs/kcl/types/string)| The ID of the imported geometry. | No |
| `value` |`[` [`string`](/docs/kcl/types/string) `]`| The original file paths. | No |
----

View File

@ -30,6 +30,7 @@ A sketch type.
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
----
@ -51,6 +52,7 @@ A face.
| `value` |[`string`](/docs/kcl/types/string)| The tag of the face. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |

View File

@ -21,7 +21,7 @@ test.describe(
clickCoords: { x: number; y: number }
) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1700, height: 500 })
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
const XYPlanRed: [number, number, number] = [98, 50, 51]

View File

@ -406,7 +406,6 @@ profile003 = startProfileAt([0, -4.93], sketch001)
await fsp.mkdir(testProject, { recursive: true })
await fsp.writeFile(join(testProject, 'main.kcl'), beforeKclCode, 'utf-8')
})
await page.setBodyDimensions({ width: 1500, height: 500 })
// One dumb hardcoded screen pixel value
const testPoint = { x: 650, y: 250 }
const sketchColor: [number, number, number] = [149, 149, 149]

View File

@ -488,7 +488,6 @@ test('Restarting onboarding on desktop takes one attempt', async ({
join(routerTemplateDir, 'main.kcl')
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
// Our constants
const u = await getUtils(page)

View File

@ -87,7 +87,7 @@ test.describe('Point-and-click assemblies tests', () => {
fsp.writeFile(path.join(bracketDir, 'main.kcl'), ''),
])
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.openProject(projectName)
await scene.settled(cmdBar)
await toolbar.closePane('code')
@ -225,7 +225,7 @@ test.describe('Point-and-click assemblies tests', () => {
fsp.writeFile(path.join(bracketDir, 'main.kcl'), ''),
])
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.openProject(projectName)
await scene.settled(cmdBar)
await toolbar.closePane('code')
@ -403,7 +403,7 @@ test.describe('Point-and-click assemblies tests', () => {
fsp.writeFile(path.join(bracketDir, 'main.kcl'), ''),
])
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.openProject(projectName)
await scene.settled(cmdBar)
await toolbar.closePane('code')

View File

@ -203,7 +203,7 @@ test.describe('Point-and-click tests', () => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -366,7 +366,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -689,7 +689,7 @@ openSketch = startSketchOn(XY)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// Wait for the scene and stream to load
@ -864,7 +864,7 @@ openSketch = startSketchOn(XY)
// Setup
await test.step(`Initial test setup`, async () => {
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// Wait for the scene and stream to load
@ -1215,7 +1215,7 @@ openSketch = startSketchOn(XY)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -1360,7 +1360,7 @@ extrude001 = extrude(profile001, length = 100)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -1496,7 +1496,7 @@ extrude001 = extrude(profile001, length = 100)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// One dumb hardcoded screen pixel value
@ -1587,7 +1587,7 @@ loft001 = loft([sketch001, sketch002])
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -1676,7 +1676,7 @@ sketch002 = startSketchOn(XZ)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -1818,7 +1818,7 @@ sketch002 = startSketchOn(XZ)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -1924,7 +1924,7 @@ extrude001 = extrude(sketch001, length = -12)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// verify modeling scene is loaded
@ -2199,7 +2199,7 @@ fillet001 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg01)])
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -2263,7 +2263,7 @@ fillet04 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg02)])
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// verify modeling scene is loaded
@ -2397,7 +2397,7 @@ extrude001 = extrude(profile001, length = 5)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
// verify modeling scene is loaded
@ -2520,7 +2520,7 @@ extrude001 = extrude(sketch001, length = -12)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
})
@ -2821,7 +2821,7 @@ chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -2946,7 +2946,7 @@ extrude001 = extrude(sketch001, length = 30)
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.connectionEstablished()
@ -3089,7 +3089,7 @@ extrude001 = extrude(sketch001, length = 40)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -3236,7 +3236,7 @@ extrude002 = extrude(sketch002, length = 50)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1700, height: 500 })
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -3325,7 +3325,7 @@ profile001 = startProfileAt([-20, 20], sketch001)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
await toolbar.openPane('feature-tree')
@ -3405,7 +3405,7 @@ sweep001 = sweep(sketch001, path = sketch002)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -3487,7 +3487,7 @@ tag=$rectangleSegmentC002,
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -3565,7 +3565,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.connectionEstablished()
await scene.settled(cmdBar)
@ -3656,7 +3656,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.connectionEstablished()
await scene.settled(cmdBar)
@ -3736,7 +3736,7 @@ extrude001 = extrude(profile001, length = 100)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -3867,7 +3867,7 @@ extrude001 = extrude(profile001, length = 100)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -4023,7 +4023,7 @@ extrude001 = extrude(profile001, length = 100)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -4152,7 +4152,7 @@ extrude001 = extrude(profile001, length = 1)
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
}, initialCode)
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)

View File

@ -1815,8 +1815,8 @@ test(
'basic_fillet_cube_next_adjacent.kcl',
'basic_fillet_cube_previous_adjacent.kcl',
'basic_fillet_cube_start.kcl',
'broken-code-test.kcl',
'circular_pattern3d_a_pattern.kcl',
'big_number_angle_to_match_length_x.kcl',
'big_number_angle_to_match_length_y.kcl',
'close_arc.kcl',
'computed_var.kcl',
'cube-embedded.gltf',

View File

@ -53,7 +53,6 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -149,7 +148,6 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -205,7 +203,6 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -275,7 +272,6 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)

View File

@ -343,7 +343,7 @@ extrude002 = extrude(profile002, length = 150)
)
const websocketPromise = page.waitForEvent('websocket')
await page.setBodyDimensions({ width: 1000, height: 500 })
await page.setBodyDimensions({ width: 500, height: 500 })
await homePage.goToModelingScene()
const websocket = await websocketPromise
@ -679,12 +679,10 @@ extrude002 = extrude(profile002, length = 150)
scene,
toolbar,
viewport,
page,
}) => {
await context.folderSetupFn(async (dir) => {
const legoDir = path.join(dir, 'lego')
await fsp.mkdir(legoDir, { recursive: true })
await page.setBodyDimensions({ width: 1500, height: 500 })
await fsp.copyFile(
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
path.join(legoDir, 'main.kcl')

View File

@ -115,7 +115,6 @@ sketch001 = startSketchOn(XZ)
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -1542,7 +1541,6 @@ profile003 = startProfileAt([206.63, -56.73], sketch001)
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
@ -2232,7 +2230,7 @@ profile003 = circle(sketch001, center = [6.92, -4.2], radius = 3.16)
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.settled(cmdBar)
await expect(
@ -2341,7 +2339,7 @@ extrude001 = extrude(profile003, length = 5)
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.connectionEstablished()
await scene.settled(cmdBar)
@ -2439,7 +2437,7 @@ profile002 = startProfileAt([85.81, 52.55], sketch002)
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
@ -2597,7 +2595,7 @@ extrude003 = extrude(profile011, length = 2.5)
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await scene.connectionEstablished()
await scene.settled(cmdBar)
@ -2712,7 +2710,7 @@ loft([profile001, profile002])
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
@ -2770,7 +2768,7 @@ loft([profile001, profile002])
)
})
await page.setBodyDimensions({ width: 1500, height: 500 })
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
@ -3262,7 +3260,6 @@ profile003 = startProfileAt([-201.08, 254.17], sketch002)
await context.addInitScript((file) => {
localStorage.setItem('persistCode', file)
}, file)
await page.setBodyDimensions({ width: 1500, height: 500 })
await homePage.goToModelingScene()
const [objClick] = scene.makeMouseHelpers(600, 250)

View File

@ -39,12 +39,12 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
})
const emptySpaceHover = () =>
test.step('Hover over empty space', async () => {
await page.mouse.move(1000, 143, { steps: 5 })
await page.mouse.move(700, 143, { steps: 5 })
await expect(page.locator('.hover-highlight')).not.toBeVisible()
})
const emptySpaceClick = () =>
test.step(`Click in empty space`, async () => {
await page.mouse.click(1000, 143)
await page.mouse.click(700, 143)
await expect(page.locator('.cm-line').last()).toHaveClass(
/cm-activeLine/
)

View File

@ -30,68 +30,21 @@ declare module '@playwright/test' {
// *for one worker*.
const electronZooInstance = new ElectronZoo()
// Track whether this is the first run for this worker process
// Mac needs more time for the first window creation
let isFirstRun = true
// Our custom decorated Zoo test object. Makes it easier to add fixtures, and
// switch between web and electron if needed.
const playwrightTestFnWithFixtures_ = playwrightTestFn.extend<{
tronApp?: ElectronZoo
}>({
tronApp: [
async ({}, use, testInfo) => {
if (process.env.PLATFORM === 'web') {
await use(undefined)
return
}
tronApp: async ({}, use, testInfo) => {
if (process.env.PLATFORM === 'web') {
await use(undefined)
return
}
// Create a single timeout for the entire tronApp setup process
// This will ensure tests fail faster if there's an issue with setup
// instead of waiting for the full global timeout (120s)
// First runs need more time especially on Mac for window creation
const setupTimeout = isFirstRun ? 120_000 : 30_000
let timeoutId: NodeJS.Timeout | undefined
const setupPromise = new Promise<void>((resolve, reject) => {
timeoutId = setTimeout(() => {
reject(
new Error(
`tronApp setup timed out after ${setupTimeout}ms${isFirstRun ? ' (first run)' : ' (subsequent run)'}`
)
)
}, setupTimeout)
// Execute the async setup in a separate function
const doSetup = async () => {
try {
await electronZooInstance.createInstanceIfMissing(testInfo)
resolve()
} catch (error) {
reject(error)
}
}
// Start the setup process
void doSetup()
})
try {
await setupPromise
if (timeoutId) clearTimeout(timeoutId)
// First run is complete at this point
isFirstRun = false
await use(electronZooInstance)
await electronZooInstance.makeAvailableAgain()
} catch (error) {
if (timeoutId) clearTimeout(timeoutId)
throw error
}
},
{ timeout: 120_000 }, // Keep the global timeout as fallback
],
await electronZooInstance.createInstanceIfMissing(testInfo)
await use(electronZooInstance)
await electronZooInstance.makeAvailableAgain()
},
})
const test = playwrightTestFnWithFixtures_.extend<Fixtures>(

View File

@ -3,13 +3,14 @@
> dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx
• Circular Dependencies
1) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts
2) src/lang/std/sketch.ts -> src/lang/modifyAst.ts
3) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts
4) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts
5) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts
6) src/lib/singletons.ts -> src/lang/codeManager.ts
7) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts
8) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts
9) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts
10) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx
01) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts
02) src/lang/std/sketch.ts -> src/lang/modifyAst.ts
03) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts
04) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts
05) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts -> src/machines/appMachine.ts -> src/machines/engineStreamMachine.ts
06) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts
07) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts
08) src/lib/singletons.ts -> src/lang/codeManager.ts
09) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts
10) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts
11) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx

View File

@ -114,7 +114,6 @@
"circular-deps": "dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx",
"circular-deps:overwrite": "npm run circular-deps | sed '$d' | grep -v '^npm run' > known-circular.txt",
"circular-deps:diff": "./scripts/diff-circular-deps.sh",
"circular-deps:diff:nodejs": "npm run circular-deps:diff || node ./scripts/diff.js",
"files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
"files:set-notes": "./scripts/set-files-notes.sh",
"files:flip-to-nightly": "./scripts/flip-files-to-nightly.sh",

View File

@ -126,7 +126,7 @@ fn armRestProfile(plane, offset) {
export fn armRest(plane, offset) {
path = armRestPath( offsetPlane(plane, offset = offset))
profile = armRestProfile( offsetPlane(-XZ, offset = 20), -offset)
profile = armRestProfile( offsetPlane(-XZ, offset = 20), offset)
sweep(profile, path = path)
return 0
}

View File

@ -17,8 +17,8 @@ import armRest from "bench-parts.kcl"
// Create the dividers, these hold the seat and back slats
divider(YZ)
divider(offsetPlane(-YZ, offset = benchLength / 2))
divider(offsetPlane(YZ, offset = benchLength / 2))
divider(offsetPlane(YZ, offset = -benchLength / 2))
// Create the connectors to join the dividers
connector(offsetPlane(YZ, offset = -benchLength / 2), benchLength)
@ -30,5 +30,5 @@ seatSlats(offsetPlane(YZ, offset = -benchLength / 2 - (dividerThickness / 2)), b
backSlats(offsetPlane(YZ, offset = -benchLength / 2 - (dividerThickness / 2)), benchLength + dividerThickness)
// Create the arm rests
armRest(YZ, benchLength / 2)
armRest(YZ, -benchLength / 2)
armRest(-YZ, benchLength / 2)
armRest(-YZ, -benchLength / 2)

View File

@ -1,79 +1,88 @@
// Dodecahedron
// A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the a dodecahedron with a series of intersects.
// Hollow Dodecahedron
// A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the individual faces of the dodecahedron and extruding inwards.
// Set units
@settings(defaultLengthUnit = in)
// Define the dihedral angle for a regular dodecahedron
dihedral = 116.565
// Input parameters
// circumscribed radius
circR = 25
// Create a face template function that makes a large thin cube
fn createFaceTemplate(dither) {
baseSketch = startSketchOn(XY)
|> startProfileAt([-1000 - dither, -1000 - dither], %)
|> line(endAbsolute = [1000 + dither, -1000 - dither])
|> line(endAbsolute = [1000 + dither, 1000 + dither])
|> line(endAbsolute = [-1000 - dither, 1000 + dither])
|> close()
extruded = extrude(baseSketch, length = 1000 + dither + 1000)
return extruded
|> translate(x = 0, y = 0, z = -260 - dither)
// Calculated parameters
// Thickness of the dodecahedron
wallThickness = circR * 0.2
// Angle between faces in radians
dihedral = acos(-(sqrt(5) / 5))
// Inscribed radius
inscR = circR / 15 * sqrt(75 + 30 * sqrt(5))
// Pentagon edge length
edgeL = 4 * circR / (sqrt(3) * (1 + sqrt(5)))
// Pentagon radius
pentR = edgeL / 2 / sin(toRadians(36))
// Define a plane for the bottom angled face
plane = {
origin = [
-inscR * cos(toRadians(toDegrees(dihedral) - 90)),
0,
inscR - (inscR * sin(toRadians(toDegrees(dihedral) - 90)))
],
xAxis = [cos(dihedral), 0.0, sin(dihedral)],
yAxis = [0, 1, 0],
zAxis = [sin(dihedral), 0, -cos(dihedral)]
}
// Define the rotations array with [pitch, roll, yaw, dither] for each face
faceRotations = [
[0, 0, 0, 0],
// face1 - reference face
[dihedral, 0, 0, 0.1],
// face2
[dihedral, 0, 72, 0.2],
// face3
[dihedral, 0, 144, 0.3],
// face4
[dihedral, 0, 216, 0.4],
// face5
[dihedral, 0, 288, 0.5],
// face6
[180, 0, 0, 0.6],
// face7
[180 - dihedral, 0, 36, 0.7],
// face8
[180 - dihedral, 0, 108, 0.8],
// face9
[180 - dihedral, 0, 180, 0.9],
// face10
[180 - dihedral, 0, 252, 0.11],
// face11
[180 - dihedral, 0, 324, 0.12],
// face12
]
// Create a regular pentagon inscribed in a circle of radius pentR
bottomFace = startSketchOn(XY)
|> polygon(
radius = pentR,
numSides = 5,
center = [0, 0],
inscribed = true,
)
// Create faces by mapping over the rotations array
dodecFaces = map(faceRotations, fn(rotation) {
return createFaceTemplate(rotation[3])
|> rotate(
pitch = rotation[0],
roll = rotation[1],
yaw = rotation[2],
global = true,
)
})
bottomSideFace = startSketchOn(plane)
|> polygon(
radius = pentR,
numSides = 5,
center = [0, 0],
inscribed = true,
)
fn calculateArrayLength(arr) {
return reduce(arr, 0, fn(item, accumulator) {
return accumulator + 1
})
}
// Extrude the faces in each plane
bottom = extrude(bottomFace, length = wallThickness)
bottomSide = extrude(bottomSideFace, length = wallThickness)
fn createIntersection(solids) {
fn reduceIntersect(previous, current) {
return intersect([previous, current])
}
lastIndex = calculateArrayLength(solids) - 1
lastSolid = solids[lastIndex]
remainingSolids = pop(solids)
return reduce(remainingSolids, lastSolid, reduceIntersect)
}
// Pattern the sides so we have a full dodecahedron
bottomBowl = patternCircular3d(
bottomSide,
instances = 5,
axis = [0, 0, 1],
center = [0, 0, 0],
arcDegrees = 360,
rotateDuplicates = true,
)
// Apply intersection to all faces
createIntersection(dodecFaces)
// Pattern the bottom to create the top face
patternCircular3d(
bottom,
instances = 2,
axis = [0, 1, 0],
center = [0, 0, inscR],
arcDegrees = 360,
rotateDuplicates = true,
)
// Pattern the bottom angled faces to create the top
patternCircular3d(
bottomBowl,
instances = 2,
axis = [0, 1, 0],
center = [0, 0, inscR],
arcDegrees = 360,
rotateDuplicates = true,
)

View File

@ -202,17 +202,19 @@ plane000 = {
height + binHeight * countBinHeight
],
xAxis = [0.0, 1.0, 0.0],
yAxis = [0.0, 0.0, 1.0]
yAxis = [0.0, 0.0, 1.0],
zAxis = [1.0, 0.0, 0.0]
}
plane001 = {
origin = [
0.0,
countBinLength * (binLength + 2 * binTol) - cornerRadius,
cornerRadius,
height + binHeight * countBinHeight
],
xAxis = [1.0, 0.0, 0.0],
yAxis = [0.0, 0.0, 1.0]
yAxis = [0.0, 0.0, 1.0],
zAxis = [0.0, 1.0, 0.0]
}
plane002 = {
@ -222,7 +224,8 @@ plane002 = {
height + binHeight * countBinHeight
],
xAxis = [0.0, 1.0, 0.0],
yAxis = [0.0, 0.0, 1.0]
yAxis = [0.0, 0.0, 1.0],
zAxis = [1.0, 0.0, 0.0]
}
// Extrude a single side of the lip of the bin

View File

@ -66,8 +66,8 @@
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "dodecahedron/main.kcl",
"multipleFiles": false,
"title": "Dodecahedron",
"description": "A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the a dodecahedron with a series of intersects."
"title": "Hollow Dodecahedron",
"description": "A regular dodecahedron or pentagonal dodecahedron is a dodecahedron composed of regular pentagonal faces, three meeting at each vertex. This example shows constructing the individual faces of the dodecahedron and extruding inwards."
},
{
"file": "main.kcl",

View File

@ -4,10 +4,10 @@
@settings(defaultLengthUnit = in)
// Axis Angles
export axisJ4 = 25deg
export axisJ3 = 60deg
export axisJ2 = 110deg
export axisJ1 = 80deg
export axisJ4 = 25
export axisJ3 = 60
export axisJ2 = 110
export axisJ1 = 80
// Robot Arm Base
export basePlateRadius = 5
@ -30,26 +30,29 @@ export axisJ3CArmThickness = 2.5
export plane001 = {
origin = [0.0, 0.0, baseHeight - 1.5 + 0.1],
xAxis = [1.0, 0.0, 0.0],
yAxis = [0.0, 1.0, 0.0]
yAxis = [0.0, 1.0, 0.0],
zAxis = [0.0, 0.0, 1.0]
}
export plane002 = {
origin = [0.0, 0.0, 0.0],
xAxis = [
sin(axisJ1): number(in),
cos(axisJ1): number(in),
sin(toRadians(axisJ1)),
cos(toRadians(axisJ1)),
0.0
],
yAxis = [0.0, 0.0, 1.0]
yAxis = [0.0, 0.0, 1.0],
zAxis = [1.0, 0.0, 0.0]
}
// Define Plane to Move J2 Axis Robot Arm
export plane003 = {
origin = [-0.1, 0.0, 0.0],
xAxis = [
sin(axisJ1): number(in),
cos(axisJ1): number(in),
sin(toRadians(axisJ1)),
cos(toRadians(axisJ1)),
0.0
],
yAxis = [0.0, 0.0, 1.0]
yAxis = [0.0, 0.0, 1.0],
zAxis = [1.0, 0.0, 0.0]
}

View File

@ -62,7 +62,8 @@ customPlane = {
z = 0
},
xAxis = { x = 1, y = 0, z = 0 },
yAxis = { x = 0, y = 0, z = 1 }
yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 0, y = -1, z = 0 }
}
sketch003 = startSketchOn(customPlane)
|> startProfileAt([0, 0], %)
@ -97,18 +98,19 @@ customPlane2 = {
y = 0,
z = 0
},
xAxis = { x = 0, y = 1, z = 0 },
yAxis = { x = 0, y = 0, z = 1 }
xAxis = { x = 0, y = -1, z = 0 },
yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 1, y = 0, z = 0 }
}
sketch005 = startSketchOn(customPlane2)
|> startProfileAt([0, 0], %)
|> yLine(endAbsolute = height)
|> xLine(endAbsolute = -wallsWidth)
|> xLine(endAbsolute = wallsWidth)
|> tangentialArc(endAbsolute = [
-1 * ((frontLength - wallsWidth) / 2 + wallsWidth),
(frontLength - wallsWidth) / 2 + wallsWidth,
height - ((height - exitHeight) / 2)
])
|> tangentialArc(endAbsolute = [-frontLength, exitHeight])
|> tangentialArc(endAbsolute = [frontLength, exitHeight])
|> yLine(endAbsolute = 0, tag = $seg03)
|> close()
|> extrude(length = wallThickness)
@ -136,7 +138,8 @@ customPlane3 = {
z = wallThickness
},
xAxis = { x = 0, y = -1, z = 0 },
yAxis = { x = 1, y = 0, z = 0 }
yAxis = { x = 1, y = 0, z = 0 },
zAxis = { x = 0, y = 0, z = 1 }
}
sketch008 = startSketchOn(customPlane3)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -6,7 +6,7 @@ uses-engine = { max-threads = 4 }
after-engine = { max-threads = 12 }
[profile.default]
slow-timeout = { period = "180s", terminate-after = 1 }
slow-timeout = { period = "90s", terminate-after = 1 }
[profile.ci]
slow-timeout = { period = "50s", terminate-after = 5 }

View File

@ -6,12 +6,11 @@
mod tests;
mod unbox;
use std::{collections::HashMap, fs};
use std::collections::HashMap;
use convert_case::Casing;
use inflector::{cases::camelcase::to_camel_case, Inflector};
use once_cell::sync::Lazy;
use proc_macro2::Span;
use quote::{format_ident, quote, quote_spanned, ToTokens};
use regex::Regex;
use serde::Deserialize;
@ -22,16 +21,6 @@ use syn::{
};
use unbox::unbox;
#[proc_macro_attribute]
pub fn stdlib(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
do_output(do_stdlib(attr.into(), item.into()))
}
#[proc_macro_attribute]
pub fn for_each_std_mod(_attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
do_for_each_std_mod(item.into()).into()
}
/// Describes an argument of a stdlib function.
#[derive(Deserialize, Debug)]
struct ArgMetadata {
@ -84,6 +73,11 @@ struct StdlibMetadata {
args: HashMap<String, ArgMetadata>,
}
#[proc_macro_attribute]
pub fn stdlib(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
do_output(do_stdlib(attr.into(), item.into()))
}
fn do_stdlib(
attr: proc_macro2::TokenStream,
item: proc_macro2::TokenStream,
@ -92,31 +86,6 @@ fn do_stdlib(
do_stdlib_inner(metadata, attr, item)
}
fn do_for_each_std_mod(item: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let item: syn::ItemFn = syn::parse2(item.clone()).unwrap();
let mut result = proc_macro2::TokenStream::new();
for name in fs::read_dir("kcl-lib/std").unwrap().filter_map(|e| {
let e = e.unwrap();
let filename = e.file_name();
filename.to_str().unwrap().strip_suffix(".kcl").map(str::to_owned)
}) {
let mut item = item.clone();
item.sig.ident = syn::Ident::new(&format!("{}_{}", item.sig.ident, name), Span::call_site());
let stmts = &item.block.stmts;
//let name = format!("\"{name}\"");
let block = quote! {
{
const STD_MOD_NAME: &str = #name;
#(#stmts)*
}
};
item.block = Box::new(syn::parse2(block).unwrap());
result.extend(Some(item.into_token_stream()));
}
result
}
fn do_output(res: Result<(proc_macro2::TokenStream, Vec<Error>), Error>) -> proc_macro::TokenStream {
match res {
Err(err) => err.to_compile_error().into(),
@ -702,7 +671,6 @@ fn normalize_comment_string(s: String) -> Vec<String> {
/// Represent an item without concern for its body which may (or may not)
/// contain syntax errors.
#[derive(Clone)]
struct ItemFnForSignature {
pub attrs: Vec<Attribute>,
pub vis: Visibility,

View File

@ -0,0 +1,9 @@
const part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [1, 3.82], tag = $seg01)
|> angled(
angle = -angleToMatchLengthX(seg01, 3, %),
endAbsoluteX = 3,
)
|> close()
|> extrude(length = 10)

View File

@ -0,0 +1,9 @@
const part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [1, 3.82], tag = $seg01)
|> angledLine(
angle = -angleToMatchLengthY(seg01, 3, %),
endAbsoluteX = 3,
)
|> close()
|> extrude(length = 10)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -61,10 +61,8 @@ impl CollectionVisitor {
format!("std::{}::", self.name)
};
let mut dd = match var.kind {
VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name, preferred_prefix, name)),
VariableKind::Const => {
DocData::Const(ConstData::from_ast(var, qual_name, preferred_prefix, name))
}
VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name, preferred_prefix)),
VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name, preferred_prefix)),
};
dd.with_meta(&var.outer_attrs);
@ -81,7 +79,7 @@ impl CollectionVisitor {
} else {
format!("std::{}::", self.name)
};
let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name, preferred_prefix, name));
let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name, preferred_prefix));
dd.with_meta(&ty.outer_attrs);
for a in &ty.outer_attrs {
@ -116,16 +114,6 @@ impl DocData {
}
}
/// The name of the module in which the item is declared, e.g., `sketch`
#[allow(dead_code)]
pub fn module_name(&self) -> &str {
match self {
DocData::Fn(f) => &f.module_name,
DocData::Const(c) => &c.module_name,
DocData::Ty(t) => &t.module_name,
}
}
#[allow(dead_code)]
pub fn file_name(&self) -> String {
match self {
@ -144,7 +132,6 @@ impl DocData {
}
}
/// The path to the module through which the item is accessed, e.g., `std::sketch`
#[allow(dead_code)]
pub fn mod_name(&self) -> String {
let q = match self {
@ -230,8 +217,6 @@ pub struct ConstData {
/// Code examples.
/// These are tested and we know they compile and execute.
pub examples: Vec<(String, ExampleProperties)>,
pub module_name: String,
}
impl ConstData {
@ -239,7 +224,6 @@ impl ConstData {
var: &crate::parsing::ast::types::VariableDeclaration,
mut qual_name: String,
preferred_prefix: &str,
module_name: &str,
) -> Self {
assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Const);
@ -279,7 +263,6 @@ impl ConstData {
summary: None,
description: None,
examples: Vec::new(),
module_name: module_name.to_owned(),
}
}
@ -351,8 +334,6 @@ pub struct FnData {
pub examples: Vec<(String, ExampleProperties)>,
#[allow(dead_code)]
pub referenced_types: Vec<String>,
pub module_name: String,
}
impl FnData {
@ -360,7 +341,6 @@ impl FnData {
var: &crate::parsing::ast::types::VariableDeclaration,
mut qual_name: String,
preferred_prefix: &str,
module_name: &str,
) -> Self {
assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Fn);
let crate::parsing::ast::types::Expr::FunctionExpression(expr) = &var.declaration.init else {
@ -395,7 +375,6 @@ impl FnData {
description: None,
examples: Vec::new(),
referenced_types: referenced_types.into_iter().collect(),
module_name: module_name.to_owned(),
}
}
@ -675,8 +654,6 @@ pub struct TyData {
pub examples: Vec<(String, ExampleProperties)>,
#[allow(dead_code)]
pub referenced_types: Vec<String>,
pub module_name: String,
}
impl TyData {
@ -684,7 +661,6 @@ impl TyData {
ty: &crate::parsing::ast::types::TypeDeclaration,
mut qual_name: String,
preferred_prefix: &str,
module_name: &str,
) -> Self {
let name = ty.name.name.clone();
qual_name.push_str(&name);
@ -708,7 +684,6 @@ impl TyData {
description: None,
examples: Vec::new(),
referenced_types: referenced_types.into_iter().collect(),
module_name: module_name.to_owned(),
}
}
@ -1034,8 +1009,6 @@ fn collect_type_names_from_primitive(ty: &PrimitiveType) -> String {
#[cfg(test)]
mod test {
use kcl_derive_docs::for_each_std_mod;
use super::*;
#[test]
@ -1074,28 +1047,18 @@ mod test {
);
}
#[for_each_std_mod]
#[tokio::test(flavor = "multi_thread")]
async fn test_examples() {
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
async fn test_examples() -> miette::Result<()> {
let std = walk_prelude();
let mut errs = Vec::new();
for d in std {
if d.module_name() != STD_MOD_NAME {
continue;
}
for (i, eg) in d.examples().enumerate() {
let result = match crate::test_server::execute_and_snapshot(eg, None).await {
Err(crate::errors::ExecError::Kcl(e)) => {
errs.push(
miette::Report::new(crate::errors::Report {
error: e.error,
filename: format!("{}{i}", d.name()),
kcl_source: eg.to_string(),
})
.to_string(),
);
continue;
return Err(miette::Report::new(crate::errors::Report {
error: e.error,
filename: format!("{}{i}", d.name()),
kcl_source: eg.to_string(),
}));
}
Err(other_err) => panic!("{}", other_err),
Ok(img) => img,
@ -1108,8 +1071,6 @@ mod test {
}
}
if !errs.is_empty() {
panic!("{}", errs.join("\n\n"));
}
Ok(())
}
}

View File

@ -129,8 +129,6 @@ impl StdLibFnArg {
};
if (self.type_ == "Sketch"
|| self.type_ == "[Sketch]"
|| self.type_ == "Geometry"
|| self.type_ == "GeometryWithImportedGeometry"
|| self.type_ == "Solid"
|| self.type_ == "[Solid]"
|| self.type_ == "SketchSurface"
@ -504,8 +502,6 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
fn to_autocomplete_snippet(&self) -> Result<String> {
if self.name() == "loft" {
return Ok("loft([${0:sketch000}, ${1:sketch001}])".to_string());
} else if self.name() == "clone" {
return Ok("clone(${0:part001})".to_string());
} else if self.name() == "union" {
return Ok("union([${0:extrude001}, ${1:extrude002}])".to_string());
} else if self.name() == "subtract" {
@ -1093,14 +1089,6 @@ mod tests {
);
}
#[test]
#[allow(clippy::literal_string_with_formatting_args)]
fn get_autocomplete_snippet_clone() {
let clone_fn: Box<dyn StdLibFn> = Box::new(crate::std::clone::Clone);
let snippet = clone_fn.to_autocomplete_snippet().unwrap();
assert_eq!(snippet, r#"clone(${0:part001})"#);
}
// We want to test the snippets we compile at lsp start.
#[test]
fn get_all_stdlib_autocomplete_snippets() {

View File

@ -1142,15 +1142,9 @@ impl Node<UnaryExpression> {
}
KclValue::Plane { value } => {
let mut plane = value.clone();
if plane.x_axis.x != 0.0 {
plane.x_axis.x *= -1.0;
}
if plane.x_axis.y != 0.0 {
plane.x_axis.y *= -1.0;
}
if plane.x_axis.z != 0.0 {
plane.x_axis.z *= -1.0;
}
plane.z_axis.x *= -1.0;
plane.z_axis.y *= -1.0;
plane.z_axis.z *= -1.0;
plane.value = PlaneType::Uninit;
plane.id = exec_state.next_uuid();
@ -2643,6 +2637,7 @@ p = {
origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 1, y = 0, z = 0 },
yAxis = { x = 0, y = 1, z = 0 },
zAxis = { x = 0, y = 0, z = 1 }
}: Plane
p2 = -p
"#;
@ -2654,11 +2649,7 @@ p2 = -p
.get_from("p2", result.mem_env, SourceRange::default(), 0)
.unwrap()
{
KclValue::Plane { value } => {
assert_eq!(value.x_axis.x, -1.0);
assert_eq!(value.x_axis.y, 0.0);
assert_eq!(value.x_axis.z, 0.0);
}
KclValue::Plane { value } => assert_eq!(value.z_axis.z, -1.0),
_ => unreachable!(),
}
}

View File

@ -47,29 +47,6 @@ impl Geometry {
}
}
/// A geometry including an imported geometry.
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub enum GeometryWithImportedGeometry {
Sketch(Sketch),
Solid(Solid),
ImportedGeometry(Box<ImportedGeometry>),
}
impl GeometryWithImportedGeometry {
pub async fn id(&mut self, ctx: &ExecutorContext) -> Result<uuid::Uuid, KclError> {
match self {
GeometryWithImportedGeometry::Sketch(s) => Ok(s.id),
GeometryWithImportedGeometry::Solid(e) => Ok(e.id),
GeometryWithImportedGeometry::ImportedGeometry(i) => {
let id = i.id(ctx).await?;
Ok(id)
}
}
}
}
/// A set of geometry.
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
@ -285,6 +262,8 @@ pub struct Plane {
pub x_axis: Point3d,
/// What should the plane's Y axis be?
pub y_axis: Point3d,
/// The z-axis (normal).
pub z_axis: Point3d,
#[serde(skip)]
pub meta: Vec<Metadata>,
}
@ -317,6 +296,13 @@ impl Plane {
z: 0.0,
units: UnitLen::Mm,
},
z_axis:
Point3d {
x: 0.0,
y: 0.0,
z: 1.0,
units: UnitLen::Mm,
},
..
} => return PlaneData::XY,
Self {
@ -329,7 +315,7 @@ impl Plane {
},
x_axis:
Point3d {
x: -1.0,
x: 1.0,
y: 0.0,
z: 0.0,
units: UnitLen::Mm,
@ -341,6 +327,13 @@ impl Plane {
z: 0.0,
units: UnitLen::Mm,
},
z_axis:
Point3d {
x: 0.0,
y: 0.0,
z: -1.0,
units: UnitLen::Mm,
},
..
} => return PlaneData::NegXY,
Self {
@ -365,6 +358,13 @@ impl Plane {
z: 1.0,
units: UnitLen::Mm,
},
z_axis:
Point3d {
x: 0.0,
y: -1.0,
z: 0.0,
units: UnitLen::Mm,
},
..
} => return PlaneData::XZ,
Self {
@ -377,7 +377,7 @@ impl Plane {
},
x_axis:
Point3d {
x: -1.0,
x: 1.0,
y: 0.0,
z: 0.0,
units: UnitLen::Mm,
@ -389,6 +389,13 @@ impl Plane {
z: 1.0,
units: UnitLen::Mm,
},
z_axis:
Point3d {
x: 0.0,
y: 1.0,
z: 0.0,
units: UnitLen::Mm,
},
..
} => return PlaneData::NegXZ,
Self {
@ -413,6 +420,13 @@ impl Plane {
z: 1.0,
units: UnitLen::Mm,
},
z_axis:
Point3d {
x: 1.0,
y: 0.0,
z: 0.0,
units: UnitLen::Mm,
},
..
} => return PlaneData::YZ,
Self {
@ -426,7 +440,7 @@ impl Plane {
x_axis:
Point3d {
x: 0.0,
y: -1.0,
y: 1.0,
z: 0.0,
units: UnitLen::Mm,
},
@ -437,6 +451,13 @@ impl Plane {
z: 1.0,
units: UnitLen::Mm,
},
z_axis:
Point3d {
x: -1.0,
y: 0.0,
z: 0.0,
units: UnitLen::Mm,
},
..
} => return PlaneData::NegYZ,
_ => {}
@ -447,6 +468,7 @@ impl Plane {
origin: self.origin,
x_axis: self.x_axis,
y_axis: self.y_axis,
z_axis: self.z_axis,
}
}
@ -459,6 +481,7 @@ impl Plane {
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
value: PlaneType::XY,
meta: vec![],
},
@ -466,8 +489,9 @@ impl Plane {
id,
artifact_id: id.into(),
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, 0.0, -1.0, UnitLen::Mm),
value: PlaneType::XY,
meta: vec![],
},
@ -477,6 +501,7 @@ impl Plane {
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
value: PlaneType::XZ,
meta: vec![],
},
@ -486,6 +511,7 @@ impl Plane {
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
value: PlaneType::XZ,
meta: vec![],
},
@ -495,6 +521,7 @@ impl Plane {
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
value: PlaneType::YZ,
meta: vec![],
},
@ -502,12 +529,18 @@ impl Plane {
id,
artifact_id: id.into(),
origin: Point3d::new(0.0, 0.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
x_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
value: PlaneType::YZ,
meta: vec![],
},
PlaneData::Plane { origin, x_axis, y_axis } => {
PlaneData::Plane {
origin,
x_axis,
y_axis,
z_axis,
} => {
let id = exec_state.next_uuid();
Plane {
id,
@ -515,6 +548,7 @@ impl Plane {
origin,
x_axis,
y_axis,
z_axis,
value: PlaneType::Custom,
meta: vec![],
}
@ -543,6 +577,8 @@ pub struct Face {
pub x_axis: Point3d,
/// What should the face's Y axis be?
pub y_axis: Point3d,
/// The z-axis (normal).
pub z_axis: Point3d,
/// The solid the face is on.
pub solid: Box<Solid>,
pub units: UnitLen,
@ -620,8 +656,7 @@ impl Sketch {
adjust_camera: false,
planar_normal: if let SketchSurface::Plane(plane) = &self.on {
// We pass in the normal for the plane here.
let normal = plane.x_axis.cross(&plane.y_axis);
Some(normal.into())
Some(plane.z_axis.into())
} else {
None
},
@ -665,6 +700,12 @@ impl SketchSurface {
SketchSurface::Face(face) => face.y_axis,
}
}
pub(crate) fn z_axis(&self) -> Point3d {
match self {
SketchSurface::Plane(plane) => plane.z_axis,
SketchSurface::Face(face) => face.z_axis,
}
}
}
#[derive(Debug, Clone)]
@ -766,10 +807,7 @@ pub struct Solid {
/// Chamfers or fillets on this solid.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub edge_cuts: Vec<EdgeCut>,
/// The units of the solid.
pub units: UnitLen,
/// Is this a sectional solid?
pub sectional: bool,
/// Metadata.
#[serde(skip)]
pub meta: Vec<Metadata>,
@ -820,13 +858,6 @@ impl EdgeCut {
}
}
pub fn set_id(&mut self, id: uuid::Uuid) {
match self {
EdgeCut::Fillet { id: ref mut i, .. } => *i = id,
EdgeCut::Chamfer { id: ref mut i, .. } => *i = id,
}
}
pub fn edge_id(&self) -> uuid::Uuid {
match self {
EdgeCut::Fillet { edge_id, .. } => *edge_id,
@ -834,13 +865,6 @@ impl EdgeCut {
}
}
pub fn set_edge_id(&mut self, id: uuid::Uuid) {
match self {
EdgeCut::Fillet { edge_id: ref mut i, .. } => *i = id,
EdgeCut::Chamfer { edge_id: ref mut i, .. } => *i = id,
}
}
pub fn tag(&self) -> Option<TagNode> {
match self {
EdgeCut::Fillet { tag, .. } => *tag.clone(),
@ -905,27 +929,6 @@ impl Point3d {
pub const fn is_zero(&self) -> bool {
self.x == 0.0 && self.y == 0.0 && self.z == 0.0
}
/// Calculate the cross product of this vector with another
pub fn cross(&self, other: &Self) -> Self {
let other = if other.units == self.units {
other
} else {
&Point3d {
x: self.units.adjust_to(other.x, self.units).0,
y: self.units.adjust_to(other.y, self.units).0,
z: self.units.adjust_to(other.z, self.units).0,
units: self.units,
}
};
Self {
x: self.y * other.z - self.z * other.y,
y: self.z * other.x - self.x * other.z,
z: self.x * other.y - self.y * other.x,
units: self.units,
}
}
}
impl From<[TyF64; 3]> for Point3d {
@ -1181,21 +1184,6 @@ impl Path {
}
}
pub fn set_id(&mut self, id: uuid::Uuid) {
match self {
Path::ToPoint { base } => base.geo_meta.id = id,
Path::Horizontal { base, .. } => base.geo_meta.id = id,
Path::AngledLineTo { base, .. } => base.geo_meta.id = id,
Path::Base { base } => base.geo_meta.id = id,
Path::TangentialArcTo { base, .. } => base.geo_meta.id = id,
Path::TangentialArc { base, .. } => base.geo_meta.id = id,
Path::Circle { base, .. } => base.geo_meta.id = id,
Path::CircleThreePoint { base, .. } => base.geo_meta.id = id,
Path::Arc { base, .. } => base.geo_meta.id = id,
Path::ArcThreePoint { base, .. } => base.geo_meta.id = id,
}
}
pub fn get_tag(&self) -> Option<TagNode> {
match self {
Path::ToPoint { base } => base.tag.clone(),

View File

@ -9,8 +9,8 @@ use crate::{
execution::{
annotations::{SETTINGS, SETTINGS_UNIT_LENGTH},
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
EnvironmentRef, ExecState, Face, Geometry, GeometryWithImportedGeometry, Helix, ImportedGeometry, MetaSettings,
Metadata, Plane, Sketch, Solid, TagIdentifier,
EnvironmentRef, ExecState, Face, Helix, ImportedGeometry, MetaSettings, Metadata, Plane, Sketch, Solid,
TagIdentifier,
},
parsing::ast::types::{
DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode,
@ -611,22 +611,3 @@ impl KclValue {
}
}
}
impl From<Geometry> for KclValue {
fn from(value: Geometry) -> Self {
match value {
Geometry::Sketch(x) => Self::Sketch { value: Box::new(x) },
Geometry::Solid(x) => Self::Solid { value: Box::new(x) },
}
}
}
impl From<GeometryWithImportedGeometry> for KclValue {
fn from(value: GeometryWithImportedGeometry) -> Self {
match value {
GeometryWithImportedGeometry::Sketch(x) => Self::Sketch { value: Box::new(x) },
GeometryWithImportedGeometry::Solid(x) => Self::Solid { value: Box::new(x) },
GeometryWithImportedGeometry::ImportedGeometry(x) => Self::ImportedGeometry(*x),
}
}
}

View File

@ -1277,7 +1277,7 @@ const part001 = startSketchOn(XY)
|> line(end = [3, 4], tag = $seg01)
|> line(end = [
min(segLen(seg01), myVar),
-legLen(hypotenuse = segLen(seg01), leg = myVar)
-legLen(segLen(seg01), myVar)
])
"#;
@ -1292,7 +1292,7 @@ const part001 = startSketchOn(XY)
|> line(end = [3, 4], tag = $seg01)
|> line(end = [
min(segLen(seg01), myVar),
legLen(hypotenuse = segLen(seg01), leg = myVar)
legLen(segLen(seg01), myVar)
])
"#;
@ -1684,7 +1684,7 @@ let shape = layer() |> patternTransform(instances = 10, transform = transform)
#[tokio::test(flavor = "multi_thread")]
async fn test_math_execute_with_functions() {
let ast = r#"const myVar = 2 + min(100, -1 + legLen(hypotenuse = 5, leg = 3))"#;
let ast = r#"const myVar = 2 + min(100, -1 + legLen(5, 3))"#;
let result = parse_execute(ast).await.unwrap();
assert_eq!(
5.0,

View File

@ -28,10 +28,6 @@ pub enum RuntimeType {
}
impl RuntimeType {
pub fn edge() -> Self {
RuntimeType::Primitive(PrimitiveType::Edge)
}
pub fn sketch() -> Self {
RuntimeType::Primitive(PrimitiveType::Sketch)
}
@ -1047,6 +1043,10 @@ impl KclValue {
.get("yAxis")
.and_then(Point3d::from_kcl_val)
.ok_or(CoercionError::from(self))?;
let z_axis = value
.get("zAxis")
.and_then(Point3d::from_kcl_val)
.ok_or(CoercionError::from(self))?;
let id = exec_state.mod_local.id_generator.next_uuid();
let plane = Plane {
@ -1055,6 +1055,7 @@ impl KclValue {
origin,
x_axis,
y_axis,
z_axis,
value: super::PlaneType::Uninit,
meta: meta.clone(),
};

View File

@ -43,5 +43,5 @@ async fn main() {
.await
.unwrap();
let mut exec_state = ExecState::new(&ctx);
ctx.run(&program, &mut exec_state).await.map_err(|e| e.error).unwrap();
ctx.run(&program, &mut exec_state).await.unwrap();
}

View File

@ -1354,6 +1354,48 @@ mod tangential_arc {
super::execute(TEST_NAME, true).await
}
}
mod big_number_angle_to_match_length_x {
const TEST_NAME: &str = "big_number_angle_to_match_length_x";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[tokio::test(flavor = "multi_thread")]
async fn unparse() {
super::unparse(TEST_NAME).await
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await
}
}
mod big_number_angle_to_match_length_y {
const TEST_NAME: &str = "big_number_angle_to_match_length_y";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[tokio::test(flavor = "multi_thread")]
async fn unparse() {
super::unparse(TEST_NAME).await
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await
}
}
mod sketch_on_face_circle_tagged {
const TEST_NAME: &str = "sketch_on_face_circle_tagged";

View File

@ -277,11 +277,11 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// import "tests/inputs/cube.sldprt" as cube
///
/// cube
/// |> appearance(
/// color = "#ff0000",
/// metalness = 50,
/// roughness = 50
/// )
/// // |> appearance(
/// // color = "#ff0000",
/// // metalness = 50,
/// // roughness = 50
/// // )
/// ```
#[stdlib {
name = "appearance",

View File

@ -615,6 +615,22 @@ impl Args {
Ok(numbers)
}
pub(crate) fn get_hypotenuse_leg(&self) -> Result<(f64, f64, NumericType), KclError> {
let numbers = self.get_number_array_with_types()?;
if numbers.len() != 2 {
return Err(KclError::Type(KclErrorDetails {
message: format!("Expected a number array of length 2, found `{:?}`", numbers),
source_ranges: vec![self.source_range],
}));
}
let mut numbers = numbers.into_iter();
let a = numbers.next().unwrap();
let b = numbers.next().unwrap();
Ok(NumericType::combine_eq_coerce(a, b))
}
pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> {
let Some(arg0) = self.args.first() else {
return Err(KclError::Semantic(KclErrorDetails {
@ -659,10 +675,21 @@ impl Args {
Ok((sketches, sketch))
}
pub(crate) fn get_data<'a, T>(&'a self) -> Result<T, KclError>
where
T: FromArgs<'a>,
{
FromArgs::from_args(self, 0)
}
pub(crate) fn get_data_and_sketch_surface(&self) -> Result<([TyF64; 2], SketchSurface, Option<TagNode>), KclError> {
FromArgs::from_args(self, 0)
}
pub(crate) fn get_tag_to_number_sketch(&self) -> Result<(TagIdentifier, TyF64, Sketch), KclError> {
FromArgs::from_args(self, 0)
}
pub(crate) async fn get_adjacent_face_to_tag(
&self,
exec_state: &mut ExecState,
@ -1001,27 +1028,6 @@ impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::Direction {
}
}
impl<'a> FromKclValue<'a> for crate::execution::Geometry {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
match arg {
KclValue::Sketch { value } => Some(Self::Sketch(*value.to_owned())),
KclValue::Solid { value } => Some(Self::Solid(*value.to_owned())),
_ => None,
}
}
}
impl<'a> FromKclValue<'a> for crate::execution::GeometryWithImportedGeometry {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
match arg {
KclValue::Sketch { value } => Some(Self::Sketch(*value.to_owned())),
KclValue::Solid { value } => Some(Self::Solid(*value.to_owned())),
KclValue::ImportedGeometry(value) => Some(Self::ImportedGeometry(Box::new(value.clone()))),
_ => None,
}
}
}
impl<'a> FromKclValue<'a> for FaceTag {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = || match arg.as_str() {
@ -1081,6 +1087,7 @@ impl<'a> FromKclValue<'a> for super::sketch::PlaneData {
origin: value.origin,
x_axis: value.x_axis,
y_axis: value.y_axis,
z_axis: value.z_axis,
});
}
// Case 1: predefined plane
@ -1101,7 +1108,13 @@ impl<'a> FromKclValue<'a> for super::sketch::PlaneData {
let origin = plane.get("origin").and_then(FromKclValue::from_kcl_val)?;
let x_axis = plane.get("xAxis").and_then(FromKclValue::from_kcl_val)?;
let y_axis = plane.get("yAxis").and_then(FromKclValue::from_kcl_val)?;
Some(Self::Plane { origin, x_axis, y_axis })
let z_axis = plane.get("zAxis").and_then(FromKclValue::from_kcl_val)?;
Some(Self::Plane {
origin,
x_axis,
y_axis,
z_axis,
})
}
}

View File

@ -1,909 +0,0 @@
//! Standard library clone.
use std::collections::HashMap;
use anyhow::Result;
use kcl_derive_docs::stdlib;
use kcmc::{
each_cmd as mcmd,
ok_response::{output::EntityGetAllChildUuids, OkModelingCmdResponse},
websocket::OkWebSocketResponseData,
ModelingCmd,
};
use kittycad_modeling_cmds::{self as kcmc};
use super::extrude::do_post_extrude;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
types::{NumericType, PrimitiveType, RuntimeType},
ExecState, GeometryWithImportedGeometry, KclValue, Sketch, Solid,
},
parsing::ast::types::TagNode,
std::{extrude::NamedCapTags, Args},
};
/// Clone a sketch or solid.
///
/// This works essentially like a copy-paste operation.
pub async fn clone(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let geometry = args.get_unlabeled_kw_arg_typed(
"geometry",
&RuntimeType::Union(vec![
RuntimeType::Primitive(PrimitiveType::Sketch),
RuntimeType::Primitive(PrimitiveType::Solid),
RuntimeType::imported(),
]),
exec_state,
)?;
let cloned = inner_clone(geometry, exec_state, args).await?;
Ok(cloned.into())
}
/// Clone a sketch or solid.
///
/// This works essentially like a copy-paste operation.
///
/// This doesn't really have much utility unless you need the equivalent of a double
/// instance pattern with zero transformations.
///
/// Really only use this function if YOU ARE SURE you need it. In most cases you
/// do not need clone and using a pattern with `instance = 2` is more appropriate.
///
/// ```no_run
/// // Clone a basic sketch and move it and extrude it.
/// exampleSketch = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [10, 0])
/// |> line(end = [0, 10])
/// |> line(end = [-10, 0])
/// |> close()
///
/// clonedSketch = clone(exampleSketch)
/// |> scale(
/// x = 1.0,
/// y = 1.0,
/// z = 2.5,
/// )
/// |> translate(
/// x = 15.0,
/// y = 0,
/// z = 0,
/// )
/// |> extrude(length = 5)
/// ```
///
/// ```no_run
/// // Clone a basic solid and move it.
///
/// exampleSketch = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [10, 0])
/// |> line(end = [0, 10])
/// |> line(end = [-10, 0])
/// |> close()
///
/// myPart = extrude(exampleSketch, length = 5)
/// clonedPart = clone(myPart)
/// |> translate(
/// x = 25.0,
/// )
/// ```
///
/// ```no_run
/// // Translate and rotate a cloned sketch to create a loft.
///
/// sketch001 = startSketchOn(XY)
/// |> startProfileAt([-10, 10], %)
/// |> xLine(length = 20)
/// |> yLine(length = -20)
/// |> xLine(length = -20)
/// |> close()
///
/// sketch002 = clone(sketch001)
/// |> translate(x = 0, y = 0, z = 20)
/// |> rotate(axis = [0, 0, 1.0], angle = 45)
///
/// loft([sketch001, sketch002])
/// ```
///
/// ```no_run
/// // Translate a cloned solid. Fillet only the clone.
///
/// sketch001 = startSketchOn(XY)
/// |> startProfileAt([-10, 10], %)
/// |> xLine(length = 20)
/// |> yLine(length = -20)
/// |> xLine(length = -20, tag = $filletTag)
/// |> close()
/// |> extrude(length = 5)
///
///
/// sketch002 = clone(sketch001)
/// |> translate(x = 0, y = 0, z = 20)
/// |> fillet(
/// radius = 2,
/// tags = [getNextAdjacentEdge(filletTag)],
/// )
/// ```
///
/// ```no_run
/// // You can reuse the tags from the original geometry with the cloned geometry.
///
/// sketch001 = startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> line(end = [10, 0])
/// |> line(end = [0, 10], tag = $sketchingFace)
/// |> line(end = [-10, 0])
/// |> close()
///
/// sketch002 = clone(sketch001)
/// |> translate(x = 10, y = 20, z = 0)
/// |> extrude(length = 5)
///
/// startSketchOn(sketch002, face = sketchingFace)
/// |> startProfileAt([1, 1], %)
/// |> line(end = [8, 0])
/// |> line(end = [0, 8])
/// |> line(end = [-8, 0])
/// |> close(tag = $sketchingFace002)
/// |> extrude(length = 10)
/// ```
///
/// ```no_run
/// // You can also use the tags from the original geometry to fillet the cloned geometry.
///
/// width = 20
/// length = 10
/// thickness = 1
/// filletRadius = 2
///
/// mountingPlateSketch = startSketchOn(XY)
/// |> startProfileAt([-width/2, -length/2], %)
/// |> line(endAbsolute = [width/2, -length/2], tag = $edge1)
/// |> line(endAbsolute = [width/2, length/2], tag = $edge2)
/// |> line(endAbsolute = [-width/2, length/2], tag = $edge3)
/// |> close(tag = $edge4)
///
/// mountingPlate = extrude(mountingPlateSketch, length = thickness)
///
/// clonedMountingPlate = clone(mountingPlate)
/// |> fillet(
/// radius = filletRadius,
/// tags = [
/// getNextAdjacentEdge(edge1),
/// getNextAdjacentEdge(edge2),
/// getNextAdjacentEdge(edge3),
/// getNextAdjacentEdge(edge4)
/// ],
/// )
/// |> translate(x = 0, y = 50, z = 0)
/// ```
///
/// ```no_run
/// // Create a spring by sweeping around a helix path from a cloned sketch.
///
/// // Create a helix around the Z axis.
/// helixPath = helix(
/// angleStart = 0,
/// ccw = true,
/// revolutions = 4,
/// length = 10,
/// radius = 5,
/// axis = Z,
/// )
///
///
/// springSketch = startSketchOn(YZ)
/// |> circle( center = [0, 0], radius = 1)
///
/// // Create a spring by sweeping around the helix path.
/// sweepedSpring = clone(springSketch)
/// |> translate(x=100)
/// |> sweep(path = helixPath)
/// ```
///
/// ```
/// // A donut shape from a cloned sketch.
/// sketch001 = startSketchOn(XY)
/// |> circle( center = [15, 0], radius = 5 )
///
/// sketch002 = clone(sketch001)
/// |> translate( z = 30)
/// |> revolve(
/// angle = 360,
/// axis = Y,
/// )
/// ```
///
/// ```no_run
/// // Sketch on the end of a revolved face by tagging the end face.
/// // This shows the cloned geometry will have the same tags as the original geometry.
///
/// exampleSketch = 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()
///
/// example001 = revolve(exampleSketch, axis = Y, angle = 180, tagEnd = $end01)
///
/// // example002 = clone(example001)
/// // |> translate(x = 0, y = 20, z = 0)
///
/// // Sketch on the cloned face.
/// // exampleSketch002 = startSketchOn(example002, face = end01)
/// // |> startProfileAt([4.5, -5], %)
/// // |> line(end = [0, 5])
/// // |> line(end = [5, 0])
/// // |> line(end = [0, -5])
/// // |> close()
///
/// // example003 = extrude(exampleSketch002, length = 5)
/// ```
///
/// ```no_run
/// // Clone an imported model.
///
/// import "tests/inputs/cube.sldprt" as cube
///
/// myCube = cube
///
/// clonedCube = clone(myCube)
/// |> translate(
/// x = 1020,
/// )
/// |> appearance(
/// color = "#ff0000",
/// metalness = 50,
/// roughness = 50
/// )
/// ```
#[stdlib {
name = "clone",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
geometry = { docs = "The sketch, solid, or imported geometry to be cloned" },
}
}]
async fn inner_clone(
geometry: GeometryWithImportedGeometry,
exec_state: &mut ExecState,
args: Args,
) -> Result<GeometryWithImportedGeometry, KclError> {
let new_id = exec_state.next_uuid();
let mut geometry = geometry.clone();
let old_id = geometry.id(&args.ctx).await?;
let mut new_geometry = match &geometry {
GeometryWithImportedGeometry::ImportedGeometry(imported) => {
let mut new_imported = imported.clone();
new_imported.id = new_id;
GeometryWithImportedGeometry::ImportedGeometry(new_imported)
}
GeometryWithImportedGeometry::Sketch(sketch) => {
let mut new_sketch = sketch.clone();
new_sketch.id = new_id;
new_sketch.original_id = new_id;
new_sketch.artifact_id = new_id.into();
GeometryWithImportedGeometry::Sketch(new_sketch)
}
GeometryWithImportedGeometry::Solid(solid) => {
let mut new_solid = solid.clone();
new_solid.id = new_id;
new_solid.sketch.original_id = new_id;
new_solid.artifact_id = new_id.into();
GeometryWithImportedGeometry::Solid(new_solid)
}
};
if args.ctx.no_engine_commands().await {
return Ok(new_geometry);
}
args.batch_modeling_cmd(new_id, ModelingCmd::from(mcmd::EntityClone { entity_id: old_id }))
.await?;
fix_tags_and_references(&mut new_geometry, old_id, exec_state, &args)
.await
.map_err(|e| {
KclError::Internal(KclErrorDetails {
message: format!("failed to fix tags and references: {:?}", e),
source_ranges: vec![args.source_range],
})
})?;
Ok(new_geometry)
}
/// Fix the tags and references of the cloned geometry.
async fn fix_tags_and_references(
new_geometry: &mut GeometryWithImportedGeometry,
old_geometry_id: uuid::Uuid,
exec_state: &mut ExecState,
args: &Args,
) -> Result<()> {
let new_geometry_id = new_geometry.id(&args.ctx).await?;
let entity_id_map = get_old_new_child_map(new_geometry_id, old_geometry_id, exec_state, args).await?;
// Fix the path references in the new geometry.
match new_geometry {
GeometryWithImportedGeometry::ImportedGeometry(_) => {}
GeometryWithImportedGeometry::Sketch(sketch) => {
fix_sketch_tags_and_references(sketch, &entity_id_map, exec_state).await?;
}
GeometryWithImportedGeometry::Solid(solid) => {
// Make the sketch id the new geometry id.
solid.sketch.id = new_geometry_id;
solid.sketch.original_id = new_geometry_id;
solid.sketch.artifact_id = new_geometry_id.into();
fix_sketch_tags_and_references(&mut solid.sketch, &entity_id_map, exec_state).await?;
let (start_tag, end_tag) = get_named_cap_tags(solid);
// Fix the edge cuts.
for edge_cut in solid.edge_cuts.iter_mut() {
let Some(new_edge_id) = entity_id_map.get(&edge_cut.edge_id()) else {
anyhow::bail!("Failed to find new edge id for old edge id: {:?}", edge_cut.edge_id());
};
edge_cut.set_edge_id(*new_edge_id);
let Some(id) = entity_id_map.get(&edge_cut.id()) else {
anyhow::bail!(
"Failed to find new edge cut id for old edge cut id: {:?}",
edge_cut.id()
);
};
edge_cut.set_id(*id);
}
// Do the after extrude things to update those ids, based on the new sketch
// information.
let new_solid = do_post_extrude(
&solid.sketch,
new_geometry_id.into(),
crate::std::args::TyF64::new(
solid.height,
NumericType::Known(crate::execution::types::UnitType::Length(solid.units)),
),
solid.sectional,
&NamedCapTags {
start: start_tag.as_ref(),
end: end_tag.as_ref(),
},
exec_state,
args,
)
.await?;
*solid = new_solid;
}
}
Ok(())
}
async fn get_old_new_child_map(
new_geometry_id: uuid::Uuid,
old_geometry_id: uuid::Uuid,
exec_state: &mut ExecState,
args: &Args,
) -> Result<HashMap<uuid::Uuid, uuid::Uuid>> {
// Get the new geometries entity ids.
let response = args
.send_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityGetAllChildUuids {
entity_id: new_geometry_id,
}),
)
.await?;
let OkWebSocketResponseData::Modeling {
modeling_response:
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids {
entity_ids: new_entity_ids,
}),
} = response
else {
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
};
// Get the old geometries entity ids.
let response = args
.send_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::EntityGetAllChildUuids {
entity_id: old_geometry_id,
}),
)
.await?;
let OkWebSocketResponseData::Modeling {
modeling_response:
OkModelingCmdResponse::EntityGetAllChildUuids(EntityGetAllChildUuids {
entity_ids: old_entity_ids,
}),
} = response
else {
anyhow::bail!("Expected EntityGetAllChildUuids response, got: {:?}", response);
};
// Create a map of old entity ids to new entity ids.
Ok(HashMap::from_iter(
old_entity_ids
.iter()
.zip(new_entity_ids.iter())
.map(|(old_id, new_id)| (*old_id, *new_id)),
))
}
/// Fix the tags and references of a sketch.
async fn fix_sketch_tags_and_references(
new_sketch: &mut Sketch,
entity_id_map: &HashMap<uuid::Uuid, uuid::Uuid>,
exec_state: &mut ExecState,
) -> Result<()> {
// Fix the path references in the sketch.
for path in new_sketch.paths.as_mut_slice() {
let Some(new_path_id) = entity_id_map.get(&path.get_id()) else {
anyhow::bail!("Failed to find new path id for old path id: {:?}", path.get_id());
};
path.set_id(*new_path_id);
}
// Fix the tags
// This is annoying, in order to fix the tags we need to iterate over the paths again, but not
// mutable borrow the paths.
for path in new_sketch.paths.clone() {
// Check if this path has a tag.
if let Some(tag) = path.get_tag() {
new_sketch.add_tag(&tag, &path, exec_state);
}
}
// Fix the base path.
// TODO: Right now this one does not work, ignore for now and see if we really need it.
/* let Some(new_base_path) = entity_id_map.get(&new_sketch.start.geo_meta.id) else {
anyhow::bail!(
"Failed to find new base path id for old base path id: {:?}",
new_sketch.start.geo_meta.id
);
};
new_sketch.start.geo_meta.id = *new_base_path;*/
Ok(())
}
// Return the named cap tags for the original solid.
fn get_named_cap_tags(solid: &Solid) -> (Option<TagNode>, Option<TagNode>) {
let mut start_tag = None;
let mut end_tag = None;
// Check the start cap.
if let Some(start_cap_id) = solid.start_cap_id {
// Check if we had a value for that cap.
for value in &solid.value {
if value.get_id() == start_cap_id {
start_tag = value.get_tag().clone();
break;
}
}
}
// Check the end cap.
if let Some(end_cap_id) = solid.end_cap_id {
// Check if we had a value for that cap.
for value in &solid.value {
if value.get_id() == end_cap_id {
end_tag = value.get_tag().clone();
break;
}
}
}
(start_tag, end_tag)
}
#[cfg(test)]
mod tests {
use pretty_assertions::{assert_eq, assert_ne};
use crate::exec::KclValue;
// Ensure the clone function returns a sketch with different ids for all the internal paths and
// the resulting sketch.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_clone_sketch() {
let code = r#"cube = startSketchOn(XY)
|> startProfileAt([0,0], %)
|> line(end = [0, 10])
|> line(end = [10, 0])
|> line(end = [0, -10])
|> close()
clonedCube = clone(cube)
"#;
let ctx = crate::test_server::new_context(true, None).await.unwrap();
let program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
let result = ctx.run_with_caching(program.clone()).await.unwrap();
let cube = result.variables.get("cube").unwrap();
let cloned_cube = result.variables.get("clonedCube").unwrap();
assert_ne!(cube, cloned_cube);
let KclValue::Sketch { value: cube } = cube else {
panic!("Expected a sketch, got: {:?}", cube);
};
let KclValue::Sketch { value: cloned_cube } = cloned_cube else {
panic!("Expected a sketch, got: {:?}", cloned_cube);
};
assert_ne!(cube.id, cloned_cube.id);
assert_ne!(cube.original_id, cloned_cube.original_id);
assert_ne!(cube.artifact_id, cloned_cube.artifact_id);
assert_eq!(cloned_cube.artifact_id, cloned_cube.id.into());
assert_eq!(cloned_cube.original_id, cloned_cube.id);
for (path, cloned_path) in cube.paths.iter().zip(cloned_cube.paths.iter()) {
assert_ne!(path.get_id(), cloned_path.get_id());
assert_eq!(path.get_tag(), cloned_path.get_tag());
}
assert_eq!(cube.tags.len(), 0);
assert_eq!(cloned_cube.tags.len(), 0);
}
// Ensure the clone function returns a solid with different ids for all the internal paths and
// references.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_clone_solid() {
let code = r#"cube = startSketchOn(XY)
|> startProfileAt([0,0], %)
|> line(end = [0, 10])
|> line(end = [10, 0])
|> line(end = [0, -10])
|> close()
|> extrude(length = 5)
clonedCube = clone(cube)
"#;
let ctx = crate::test_server::new_context(true, None).await.unwrap();
let program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
let result = ctx.run_with_caching(program.clone()).await.unwrap();
let cube = result.variables.get("cube").unwrap();
let cloned_cube = result.variables.get("clonedCube").unwrap();
assert_ne!(cube, cloned_cube);
let KclValue::Solid { value: cube } = cube else {
panic!("Expected a solid, got: {:?}", cube);
};
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
panic!("Expected a solid, got: {:?}", cloned_cube);
};
assert_ne!(cube.id, cloned_cube.id);
assert_ne!(cube.sketch.id, cloned_cube.sketch.id);
assert_ne!(cube.sketch.original_id, cloned_cube.sketch.original_id);
assert_ne!(cube.artifact_id, cloned_cube.artifact_id);
assert_ne!(cube.sketch.artifact_id, cloned_cube.sketch.artifact_id);
assert_eq!(cloned_cube.artifact_id, cloned_cube.id.into());
for (path, cloned_path) in cube.sketch.paths.iter().zip(cloned_cube.sketch.paths.iter()) {
assert_ne!(path.get_id(), cloned_path.get_id());
assert_eq!(path.get_tag(), cloned_path.get_tag());
}
for (value, cloned_value) in cube.value.iter().zip(cloned_cube.value.iter()) {
assert_ne!(value.get_id(), cloned_value.get_id());
assert_eq!(value.get_tag(), cloned_value.get_tag());
}
assert_eq!(cube.sketch.tags.len(), 0);
assert_eq!(cloned_cube.sketch.tags.len(), 0);
assert_eq!(cube.edge_cuts.len(), 0);
assert_eq!(cloned_cube.edge_cuts.len(), 0);
}
// Ensure the clone function returns a sketch with different ids for all the internal paths and
// the resulting sketch.
// AND TAGS.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_clone_sketch_with_tags() {
let code = r#"cube = startSketchOn(XY)
|> startProfileAt([0,0], %) // tag this one
|> line(end = [0, 10], tag = $tag02)
|> line(end = [10, 0], tag = $tag03)
|> line(end = [0, -10], tag = $tag04)
|> close(tag = $tag05)
clonedCube = clone(cube)
"#;
let ctx = crate::test_server::new_context(true, None).await.unwrap();
let program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
let result = ctx.run_with_caching(program.clone()).await.unwrap();
let cube = result.variables.get("cube").unwrap();
let cloned_cube = result.variables.get("clonedCube").unwrap();
assert_ne!(cube, cloned_cube);
let KclValue::Sketch { value: cube } = cube else {
panic!("Expected a sketch, got: {:?}", cube);
};
let KclValue::Sketch { value: cloned_cube } = cloned_cube else {
panic!("Expected a sketch, got: {:?}", cloned_cube);
};
assert_ne!(cube.id, cloned_cube.id);
assert_ne!(cube.original_id, cloned_cube.original_id);
for (path, cloned_path) in cube.paths.iter().zip(cloned_cube.paths.iter()) {
assert_ne!(path.get_id(), cloned_path.get_id());
assert_eq!(path.get_tag(), cloned_path.get_tag());
}
for (tag_name, tag) in &cube.tags {
let cloned_tag = cloned_cube.tags.get(tag_name).unwrap();
let tag_info = tag.get_cur_info().unwrap();
let cloned_tag_info = cloned_tag.get_cur_info().unwrap();
assert_ne!(tag_info.id, cloned_tag_info.id);
assert_ne!(tag_info.sketch, cloned_tag_info.sketch);
assert_ne!(tag_info.path, cloned_tag_info.path);
assert_eq!(tag_info.surface, None);
assert_eq!(cloned_tag_info.surface, None);
}
}
// Ensure the clone function returns a solid with different ids for all the internal paths and
// references.
// WITH TAGS.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_clone_solid_with_tags() {
let code = r#"cube = startSketchOn(XY)
|> startProfileAt([0,0], %) // tag this one
|> line(end = [0, 10], tag = $tag02)
|> line(end = [10, 0], tag = $tag03)
|> line(end = [0, -10], tag = $tag04)
|> close(tag = $tag05)
|> extrude(length = 5) // TODO: Tag these
clonedCube = clone(cube)
"#;
let ctx = crate::test_server::new_context(true, None).await.unwrap();
let program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
let result = ctx.run_with_caching(program.clone()).await.unwrap();
let cube = result.variables.get("cube").unwrap();
let cloned_cube = result.variables.get("clonedCube").unwrap();
assert_ne!(cube, cloned_cube);
let KclValue::Solid { value: cube } = cube else {
panic!("Expected a solid, got: {:?}", cube);
};
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
panic!("Expected a solid, got: {:?}", cloned_cube);
};
assert_ne!(cube.id, cloned_cube.id);
assert_ne!(cube.sketch.id, cloned_cube.sketch.id);
assert_ne!(cube.sketch.original_id, cloned_cube.sketch.original_id);
assert_ne!(cube.artifact_id, cloned_cube.artifact_id);
assert_ne!(cube.sketch.artifact_id, cloned_cube.sketch.artifact_id);
assert_eq!(cloned_cube.artifact_id, cloned_cube.id.into());
for (path, cloned_path) in cube.sketch.paths.iter().zip(cloned_cube.sketch.paths.iter()) {
assert_ne!(path.get_id(), cloned_path.get_id());
assert_eq!(path.get_tag(), cloned_path.get_tag());
}
for (value, cloned_value) in cube.value.iter().zip(cloned_cube.value.iter()) {
assert_ne!(value.get_id(), cloned_value.get_id());
assert_eq!(value.get_tag(), cloned_value.get_tag());
}
for (tag_name, tag) in &cube.sketch.tags {
let cloned_tag = cloned_cube.sketch.tags.get(tag_name).unwrap();
let tag_info = tag.get_cur_info().unwrap();
let cloned_tag_info = cloned_tag.get_cur_info().unwrap();
assert_ne!(tag_info.id, cloned_tag_info.id);
assert_ne!(tag_info.sketch, cloned_tag_info.sketch);
assert_ne!(tag_info.path, cloned_tag_info.path);
assert_ne!(tag_info.surface, cloned_tag_info.surface);
}
assert_eq!(cube.edge_cuts.len(), 0);
assert_eq!(cloned_cube.edge_cuts.len(), 0);
}
// Ensure we can get all paths even on a sketch where we closed it and it was already closed.
#[tokio::test(flavor = "multi_thread")]
#[ignore = "this test is not working yet, need to fix the getting of ids if sketch already closed"]
async fn kcl_test_clone_cube_already_closed_sketch() {
let code = r#"// Clone a basic solid and move it.
exampleSketch = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> line(end = [0, 10])
|> line(end = [-10, 0])
|> line(end = [0, -10])
|> close()
cube = extrude(exampleSketch, length = 5)
clonedCube = clone(cube)
|> translate(
x = 25.0,
)"#;
let ctx = crate::test_server::new_context(true, None).await.unwrap();
let program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
let result = ctx.run_with_caching(program.clone()).await.unwrap();
let cube = result.variables.get("cube").unwrap();
let cloned_cube = result.variables.get("clonedCube").unwrap();
assert_ne!(cube, cloned_cube);
let KclValue::Solid { value: cube } = cube else {
panic!("Expected a solid, got: {:?}", cube);
};
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
panic!("Expected a solid, got: {:?}", cloned_cube);
};
assert_ne!(cube.id, cloned_cube.id);
assert_ne!(cube.sketch.id, cloned_cube.sketch.id);
assert_ne!(cube.sketch.original_id, cloned_cube.sketch.original_id);
assert_ne!(cube.artifact_id, cloned_cube.artifact_id);
assert_ne!(cube.sketch.artifact_id, cloned_cube.sketch.artifact_id);
assert_eq!(cloned_cube.artifact_id, cloned_cube.id.into());
for (path, cloned_path) in cube.sketch.paths.iter().zip(cloned_cube.sketch.paths.iter()) {
assert_ne!(path.get_id(), cloned_path.get_id());
assert_eq!(path.get_tag(), cloned_path.get_tag());
}
for (value, cloned_value) in cube.value.iter().zip(cloned_cube.value.iter()) {
assert_ne!(value.get_id(), cloned_value.get_id());
assert_eq!(value.get_tag(), cloned_value.get_tag());
}
for (tag_name, tag) in &cube.sketch.tags {
let cloned_tag = cloned_cube.sketch.tags.get(tag_name).unwrap();
let tag_info = tag.get_cur_info().unwrap();
let cloned_tag_info = cloned_tag.get_cur_info().unwrap();
assert_ne!(tag_info.id, cloned_tag_info.id);
assert_ne!(tag_info.sketch, cloned_tag_info.sketch);
assert_ne!(tag_info.path, cloned_tag_info.path);
assert_ne!(tag_info.surface, cloned_tag_info.surface);
}
for (edge_cut, cloned_edge_cut) in cube.edge_cuts.iter().zip(cloned_cube.edge_cuts.iter()) {
assert_ne!(edge_cut.id(), cloned_edge_cut.id());
assert_ne!(edge_cut.edge_id(), cloned_edge_cut.edge_id());
assert_eq!(edge_cut.tag(), cloned_edge_cut.tag());
}
}
// Ensure the clone function returns a solid with different ids for all the internal paths and
// references.
// WITH TAGS AND EDGE CUTS.
#[tokio::test(flavor = "multi_thread")]
#[ignore = "this test is not working yet, need to fix the edge cut ids"]
async fn kcl_test_clone_solid_with_edge_cuts() {
let code = r#"cube = startSketchOn(XY)
|> startProfileAt([0,0], %) // tag this one
|> line(end = [0, 10], tag = $tag02)
|> line(end = [10, 0], tag = $tag03)
|> line(end = [0, -10], tag = $tag04)
|> close(tag = $tag05)
|> extrude(length = 5) // TODO: Tag these
|> fillet(
radius = 2,
tags = [
getNextAdjacentEdge(tag02),
],
tag = $fillet01,
)
|> fillet(
radius = 2,
tags = [
getNextAdjacentEdge(tag04),
],
tag = $fillet02,
)
|> chamfer(
length = 2,
tags = [
getNextAdjacentEdge(tag03),
],
tag = $chamfer01,
)
|> chamfer(
length = 2,
tags = [
getNextAdjacentEdge(tag05),
],
tag = $chamfer02,
)
clonedCube = clone(cube)
"#;
let ctx = crate::test_server::new_context(true, None).await.unwrap();
let program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
let result = ctx.run_with_caching(program.clone()).await.unwrap();
let cube = result.variables.get("cube").unwrap();
let cloned_cube = result.variables.get("clonedCube").unwrap();
assert_ne!(cube, cloned_cube);
let KclValue::Solid { value: cube } = cube else {
panic!("Expected a solid, got: {:?}", cube);
};
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
panic!("Expected a solid, got: {:?}", cloned_cube);
};
assert_ne!(cube.id, cloned_cube.id);
assert_ne!(cube.sketch.id, cloned_cube.sketch.id);
assert_ne!(cube.sketch.original_id, cloned_cube.sketch.original_id);
assert_ne!(cube.artifact_id, cloned_cube.artifact_id);
assert_ne!(cube.sketch.artifact_id, cloned_cube.sketch.artifact_id);
assert_eq!(cloned_cube.artifact_id, cloned_cube.id.into());
for (path, cloned_path) in cube.sketch.paths.iter().zip(cloned_cube.sketch.paths.iter()) {
assert_ne!(path.get_id(), cloned_path.get_id());
assert_eq!(path.get_tag(), cloned_path.get_tag());
}
for (value, cloned_value) in cube.value.iter().zip(cloned_cube.value.iter()) {
assert_ne!(value.get_id(), cloned_value.get_id());
assert_eq!(value.get_tag(), cloned_value.get_tag());
}
for (tag_name, tag) in &cube.sketch.tags {
let cloned_tag = cloned_cube.sketch.tags.get(tag_name).unwrap();
let tag_info = tag.get_cur_info().unwrap();
let cloned_tag_info = cloned_tag.get_cur_info().unwrap();
assert_ne!(tag_info.id, cloned_tag_info.id);
assert_ne!(tag_info.sketch, cloned_tag_info.sketch);
assert_ne!(tag_info.path, cloned_tag_info.path);
assert_ne!(tag_info.surface, cloned_tag_info.surface);
}
for (edge_cut, cloned_edge_cut) in cube.edge_cuts.iter().zip(cloned_cube.edge_cuts.iter()) {
assert_ne!(edge_cut.id(), cloned_edge_cut.id());
assert_ne!(edge_cut.edge_id(), cloned_edge_cut.edge_id());
assert_eq!(edge_cut.tag(), cloned_edge_cut.tag());
}
}
}

View File

@ -8,15 +8,15 @@ use uuid::Uuid;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{types::RuntimeType, ExecState, ExtrudeSurface, KclValue, TagIdentifier},
execution::{ExecState, ExtrudeSurface, KclValue, TagIdentifier},
std::Args,
};
/// Get the opposite edge to the edge given.
pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?;
let tag: TagIdentifier = args.get_data()?;
let edge = inner_get_opposite_edge(input_edge, exec_state, args.clone()).await?;
let edge = inner_get_opposite_edge(tag, exec_state, args.clone()).await?;
Ok(KclValue::Uuid {
value: edge,
meta: vec![args.source_range.into()],
@ -53,24 +53,15 @@ pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result
/// ```
#[stdlib {
name = "getOppositeEdge",
keywords = true,
unlabeled_first = true,
args = {
edge = { docs = "The tag of the edge you want to find the opposite edge of." },
}
}]
async fn inner_get_opposite_edge(
edge: TagIdentifier,
exec_state: &mut ExecState,
args: Args,
) -> Result<Uuid, KclError> {
async fn inner_get_opposite_edge(tag: TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<Uuid, KclError> {
if args.ctx.no_engine_commands().await {
return Ok(exec_state.next_uuid());
}
let face_id = args.get_adjacent_face_to_tag(exec_state, &edge, false).await?;
let face_id = args.get_adjacent_face_to_tag(exec_state, &tag, false).await?;
let id = exec_state.next_uuid();
let tagged_path = args.get_tag_engine_info(exec_state, &edge)?;
let tagged_path = args.get_tag_engine_info(exec_state, &tag)?;
let resp = args
.send_modeling_cmd(
@ -97,9 +88,9 @@ async fn inner_get_opposite_edge(
/// Get the next adjacent edge to the edge given.
pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?;
let tag: TagIdentifier = args.get_data()?;
let edge = inner_get_next_adjacent_edge(input_edge, exec_state, args.clone()).await?;
let edge = inner_get_next_adjacent_edge(tag, exec_state, args.clone()).await?;
Ok(KclValue::Uuid {
value: edge,
meta: vec![args.source_range.into()],
@ -136,24 +127,19 @@ pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> R
/// ```
#[stdlib {
name = "getNextAdjacentEdge",
keywords = true,
unlabeled_first = true,
args = {
edge = { docs = "The tag of the edge you want to find the next adjacent edge of." },
}
}]
async fn inner_get_next_adjacent_edge(
edge: TagIdentifier,
tag: TagIdentifier,
exec_state: &mut ExecState,
args: Args,
) -> Result<Uuid, KclError> {
if args.ctx.no_engine_commands().await {
return Ok(exec_state.next_uuid());
}
let face_id = args.get_adjacent_face_to_tag(exec_state, &edge, false).await?;
let face_id = args.get_adjacent_face_to_tag(exec_state, &tag, false).await?;
let id = exec_state.next_uuid();
let tagged_path = args.get_tag_engine_info(exec_state, &edge)?;
let tagged_path = args.get_tag_engine_info(exec_state, &tag)?;
let resp = args
.send_modeling_cmd(
@ -181,7 +167,7 @@ async fn inner_get_next_adjacent_edge(
adjacent_edge.edge.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("No edge found next adjacent to tag: `{}`", edge.value),
message: format!("No edge found next adjacent to tag: `{}`", tag.value),
source_ranges: vec![args.source_range],
})
})
@ -189,9 +175,9 @@ async fn inner_get_next_adjacent_edge(
/// Get the previous adjacent edge to the edge given.
pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?;
let tag: TagIdentifier = args.get_data()?;
let edge = inner_get_previous_adjacent_edge(input_edge, exec_state, args.clone()).await?;
let edge = inner_get_previous_adjacent_edge(tag, exec_state, args.clone()).await?;
Ok(KclValue::Uuid {
value: edge,
meta: vec![args.source_range.into()],
@ -228,24 +214,19 @@ pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args)
/// ```
#[stdlib {
name = "getPreviousAdjacentEdge",
keywords = true,
unlabeled_first = true,
args = {
edge = { docs = "The tag of the edge you want to find the previous adjacent edge of." },
}
}]
async fn inner_get_previous_adjacent_edge(
edge: TagIdentifier,
tag: TagIdentifier,
exec_state: &mut ExecState,
args: Args,
) -> Result<Uuid, KclError> {
if args.ctx.no_engine_commands().await {
return Ok(exec_state.next_uuid());
}
let face_id = args.get_adjacent_face_to_tag(exec_state, &edge, false).await?;
let face_id = args.get_adjacent_face_to_tag(exec_state, &tag, false).await?;
let id = exec_state.next_uuid();
let tagged_path = args.get_tag_engine_info(exec_state, &edge)?;
let tagged_path = args.get_tag_engine_info(exec_state, &tag)?;
let resp = args
.send_modeling_cmd(
@ -272,7 +253,7 @@ async fn inner_get_previous_adjacent_edge(
adjacent_edge.edge.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("No edge found previous adjacent to tag: `{}`", edge.value),
message: format!("No edge found previous adjacent to tag: `{}`", tag.value),
source_ranges: vec![args.source_range],
})
})

View File

@ -471,7 +471,6 @@ pub(crate) async fn do_post_extrude<'a>(
meta: sketch.meta.clone(),
units: sketch.units,
height: length.to_length_units(sketch.units),
sectional,
sketch,
start_cap_id,
end_cap_id,

View File

@ -6,7 +6,6 @@ pub mod array;
pub mod assert;
pub mod axis_or_reference;
pub mod chamfer;
pub mod clone;
pub mod convert;
pub mod csg;
pub mod edge;
@ -30,7 +29,6 @@ pub mod utils;
use anyhow::Result;
pub use args::Args;
use args::TyF64;
use indexmap::IndexMap;
use kcl_derive_docs::stdlib;
use lazy_static::lazy_static;
@ -41,10 +39,7 @@ use serde::{Deserialize, Serialize};
use crate::{
docs::StdLibFn,
errors::KclError,
execution::{
types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitType},
ExecState, KclValue,
},
execution::{types::PrimitiveType, ExecState, KclValue},
parsing::ast::types::Name,
};
@ -72,6 +67,8 @@ lazy_static! {
Box::new(crate::std::segment::SegLen),
Box::new(crate::std::segment::SegAng),
Box::new(crate::std::segment::TangentToEnd),
Box::new(crate::std::segment::AngleToMatchLengthX),
Box::new(crate::std::segment::AngleToMatchLengthY),
Box::new(crate::std::shapes::CircleThreePoint),
Box::new(crate::std::shapes::Polygon),
Box::new(crate::std::sketch::InvoluteCircular),
@ -90,7 +87,6 @@ lazy_static! {
Box::new(crate::std::sketch::TangentialArc),
Box::new(crate::std::sketch::BezierCurve),
Box::new(crate::std::sketch::Hole),
Box::new(crate::std::clone::Clone),
Box::new(crate::std::patterns::PatternLinear2D),
Box::new(crate::std::patterns::PatternLinear3D),
Box::new(crate::std::patterns::PatternCircular2D),
@ -111,6 +107,7 @@ lazy_static! {
Box::new(crate::std::shell::Hollow),
Box::new(crate::std::sweep::Sweep),
Box::new(crate::std::loft::Loft),
Box::new(crate::std::planes::OffsetPlane),
Box::new(crate::std::math::Acos),
Box::new(crate::std::math::Asin),
Box::new(crate::std::math::Atan),
@ -208,10 +205,6 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
|e, a| Box::pin(crate::std::revolve::revolve(e, a)),
StdFnProps::default("std::revolve").include_in_feature_tree(),
),
("prelude", "offsetPlane") => (
|e, a| Box::pin(crate::std::planes::offset_plane(e, a)),
StdFnProps::default("std::offsetPlane").include_in_feature_tree(),
),
_ => unreachable!(),
}
}
@ -291,10 +284,8 @@ pub enum FunctionKind {
const DEFAULT_TOLERANCE: f64 = 0.0000001;
/// Compute the length of the given leg.
pub async fn leg_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
pub async fn leg_length(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?;
let result = inner_leg_length(hypotenuse, leg);
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()]))
}
@ -302,16 +293,10 @@ pub async fn leg_length(exec_state: &mut ExecState, args: Args) -> Result<KclVal
/// Compute the length of the given leg.
///
/// ```no_run
/// legLen(hypotenuse = 5, leg = 3)
/// legLen(5, 3)
/// ```
#[stdlib {
name = "legLen",
keywords = true,
unlabeled_first = false,
args = {
hypotenuse = { docs = "The length of the triangle's hypotenuse" },
leg = { docs = "The length of one of the triangle's legs (i.e. non-hypotenuse side)" },
},
tags = ["utilities"],
}]
fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 {
@ -319,31 +304,19 @@ fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 {
}
/// Compute the angle of the given leg for x.
pub async fn leg_angle_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, _ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
pub async fn leg_angle_x(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?;
let result = inner_leg_angle_x(hypotenuse, leg);
Ok(KclValue::from_number_with_type(
result,
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)),
vec![args.into()],
))
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()]))
}
/// Compute the angle of the given leg for x.
///
/// ```no_run
/// legAngX(hypotenuse = 5, leg = 3)
/// legAngX(5, 3)
/// ```
#[stdlib {
name = "legAngX",
keywords = true,
unlabeled_first = false,
args = {
hypotenuse = { docs = "The length of the triangle's hypotenuse" },
leg = { docs = "The length of one of the triangle's legs (i.e. non-hypotenuse side)" },
},
tags = ["utilities"],
}]
fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 {
@ -351,31 +324,19 @@ fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 {
}
/// Compute the angle of the given leg for y.
pub async fn leg_angle_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, _ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
pub async fn leg_angle_y(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?;
let result = inner_leg_angle_y(hypotenuse, leg);
Ok(KclValue::from_number_with_type(
result,
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)),
vec![args.into()],
))
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()]))
}
/// Compute the angle of the given leg for y.
///
/// ```no_run
/// legAngY(hypotenuse = 5, leg = 3)
/// legAngY(5, 3)
/// ```
#[stdlib {
name = "legAngY",
keywords = true,
unlabeled_first = false,
args = {
hypotenuse = { docs = "The length of the triangle's hypotenuse" },
leg = { docs = "The length of one of the triangle's legs (i.e. non-hypotenuse side)" },
},
tags = ["utilities"],
}]
fn inner_leg_angle_y(hypotenuse: f64, leg: f64) -> f64 {

View File

@ -1,5 +1,6 @@
//! Standard library plane helpers.
use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Color, ModelingCmd};
use kittycad_modeling_cmds as kcmc;
@ -18,6 +19,98 @@ pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclV
Ok(KclValue::Plane { value: Box::new(plane) })
}
/// Offset a plane by a distance along its normal.
///
/// For example, if you offset the 'XZ' plane by 10, the new plane will be parallel to the 'XZ'
/// plane and 10 units away from it.
///
/// ```no_run
/// // Loft a square and a circle on the `XY` plane using offset.
/// squareSketch = startSketchOn('XY')
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane('XY', offset = 150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```no_run
/// // Loft a square and a circle on the `XZ` plane using offset.
/// squareSketch = startSketchOn('XZ')
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane('XZ', offset = 150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```no_run
/// // Loft a square and a circle on the `YZ` plane using offset.
/// squareSketch = startSketchOn('YZ')
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane('YZ', offset = 150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```no_run
/// // Loft a square and a circle on the `-XZ` plane using offset.
/// squareSketch = startSketchOn('-XZ')
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane('-XZ', offset = -150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
/// ```no_run
/// // A circle on the XY plane
/// startSketchOn("XY")
/// |> startProfileAt([0, 0], %)
/// |> circle( radius = 10, center = [0, 0] )
///
/// // Triangle on the plane 4 units above
/// startSketchOn(offsetPlane("XY", offset = 4))
/// |> startProfileAt([0, 0], %)
/// |> line(end = [10, 0])
/// |> line(end = [0, 10])
/// |> close()
/// ```
#[stdlib {
name = "offsetPlane",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
plane = { docs = "The plane (e.g. XY) which this new plane is created from." },
offset = { docs = "Distance from the standard plane this new plane will be created at." },
}
}]
async fn inner_offset_plane(
plane: PlaneData,
offset: TyF64,
@ -29,8 +122,7 @@ async fn inner_offset_plane(
// standard planes themselves.
plane.value = PlaneType::Custom;
let normal = plane.x_axis.cross(&plane.y_axis);
plane.origin += normal * offset.to_length_units(plane.origin.units);
plane.origin += plane.z_axis * offset.to_length_units(plane.origin.units);
make_offset_plane_in_engine(&plane, exec_state, args).await?;
Ok(plane)

View File

@ -4,7 +4,6 @@ use anyhow::Result;
use kcl_derive_docs::stdlib;
use kittycad_modeling_cmds::shared::Angle;
use super::utils::untype_point;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
@ -14,6 +13,8 @@ use crate::{
std::{args::TyF64, utils::between, Args},
};
use super::utils::untype_point;
/// Returns the point at the end of the given segment.
pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
@ -579,3 +580,130 @@ async fn inner_tangent_to_end(tag: &TagIdentifier, exec_state: &mut ExecState, a
Ok(previous_end_tangent.to_degrees())
}
/// Returns the angle to match the given length for x.
pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
let result = inner_angle_to_match_length_x(&tag, to, sketch, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
}
/// Returns the angle to match the given length for x.
///
/// ```no_run
/// sketch001 = startSketchOn('XZ')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [2, 5], tag = $seg01)
/// |> angledLine(
/// angle = -angleToMatchLengthX(seg01, 7, %),
/// endAbsoluteX = 10,
/// )
/// |> close()
///
/// extrusion = extrude(sketch001, length = 5)
/// ```
#[stdlib {
name = "angleToMatchLengthX",
}]
fn inner_angle_to_match_length_x(
tag: &TagIdentifier,
to: TyF64,
sketch: Sketch,
exec_state: &mut ExecState,
args: Args,
) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
let path = line.path.clone().ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a line segment with a path, found `{:?}`", line),
source_ranges: vec![args.source_range],
})
})?;
let length = path.length().n;
let last_line = sketch
.paths
.last()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a Sketch with at least one segment, found `{:?}`", sketch),
source_ranges: vec![args.source_range],
})
})?
.get_base();
let diff = (to.to_length_units(sketch.units) - last_line.to[0]).abs();
let angle_r = (diff / length).acos();
if diff > length {
Ok(0.0)
} else {
Ok(angle_r.to_degrees())
}
}
/// Returns the angle to match the given length for y.
pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
let result = inner_angle_to_match_length_y(&tag, to, sketch, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, NumericType::degrees())))
}
/// Returns the angle to match the given length for y.
///
/// ```no_run
/// sketch001 = startSketchOn('XZ')
/// |> startProfileAt([0, 0], %)
/// |> line(end = [1, 2], tag = $seg01)
/// |> angledLine(
/// angle = angleToMatchLengthY(seg01, 15, %),
/// length = 5,
/// )
/// |> yLine(endAbsolute = 0)
/// |> close()
///
/// extrusion = extrude(sketch001, length = 5)
/// ```
#[stdlib {
name = "angleToMatchLengthY",
}]
fn inner_angle_to_match_length_y(
tag: &TagIdentifier,
to: TyF64,
sketch: Sketch,
exec_state: &mut ExecState,
args: Args,
) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
let path = line.path.clone().ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a line segment with a path, found `{:?}`", line),
source_ranges: vec![args.source_range],
})
})?;
let length = path.length().n;
let last_line = sketch
.paths
.last()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a Sketch with at least one segment, found `{:?}`", sketch),
source_ranges: vec![args.source_range],
})
})?
.get_base();
let diff = (to.to_length_units(sketch.units) - last_line.to[1]).abs();
let angle_r = (diff / length).asin();
if diff > length {
Ok(0.0)
} else {
Ok(angle_r.to_degrees())
}
}

View File

@ -960,6 +960,9 @@ pub enum PlaneData {
/// What should the planes Y axis be?
#[serde(rename = "yAxis")]
y_axis: Point3d,
/// The z-axis (normal).
#[serde(rename = "zAxis")]
z_axis: Point3d,
},
}
@ -1226,6 +1229,7 @@ async fn start_sketch_on_face(
// TODO: get this from the extrude plane data.
x_axis: solid.sketch.on.x_axis(),
y_axis: solid.sketch.on.y_axis(),
z_axis: solid.sketch.on.z_axis(),
units: solid.units,
solid,
meta: vec![args.source_range.into()],
@ -1243,18 +1247,49 @@ async fn make_sketch_plane_from_orientation(
let clobber = false;
let size = LengthUnit(60.0);
let hide = Some(true);
args.batch_modeling_cmd(
plane.id,
ModelingCmd::from(mcmd::MakePlane {
clobber,
origin: plane.origin.into(),
size,
x_axis: plane.x_axis.into(),
y_axis: plane.y_axis.into(),
hide,
}),
)
.await?;
match data {
PlaneData::XY | PlaneData::NegXY | PlaneData::XZ | PlaneData::NegXZ | PlaneData::YZ | PlaneData::NegYZ => {
// TODO: ignoring the default planes here since we already created them, breaks the
// front end for the feature tree which is stupid and we should fix it.
let x_axis = match data {
PlaneData::NegXY => Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
PlaneData::NegXZ => Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
PlaneData::NegYZ => Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
_ => plane.x_axis,
};
args.batch_modeling_cmd(
plane.id,
ModelingCmd::from(mcmd::MakePlane {
clobber,
origin: plane.origin.into(),
size,
x_axis: x_axis.into(),
y_axis: plane.y_axis.into(),
hide,
}),
)
.await?;
}
PlaneData::Plane {
origin,
x_axis,
y_axis,
z_axis: _,
} => {
args.batch_modeling_cmd(
plane.id,
ModelingCmd::from(mcmd::MakePlane {
clobber,
origin: origin.into(),
size,
x_axis: x_axis.into(),
y_axis: y_axis.into(),
hide,
}),
)
.await?;
}
}
Ok(Box::new(plane))
}
@ -1349,8 +1384,7 @@ pub(crate) async fn inner_start_profile_at(
adjust_camera: false,
planar_normal: if let SketchSurface::Plane(plane) = &sketch_surface {
// We pass in the normal for the plane here.
let normal = plane.x_axis.cross(&plane.y_axis);
Some(normal.into())
Some(plane.z_axis.into())
} else {
None
},

View File

@ -2219,8 +2219,8 @@ myAng2 = 134
part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLine(angle = -foo(seg01, myVar, %), length = myVar) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLine(angle = -bar(seg01, myVar, %), length = myVar) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper"#;
|> angledLine(angle = -angleToMatchLengthX(seg01, myVar, %), length = myVar) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLine(angle = -angleToMatchLengthY(seg01, myVar, %), length = myVar) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let recasted = program.recast(&Default::default(), 0);
@ -2237,8 +2237,8 @@ myAng2 = 134
part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLine(angle = -foo(seg01, myVar, %), length = myVar) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLine(angle = -bar(seg01, myVar, %), length = myVar) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper
|> angledLine(angle = -angleToMatchLengthX(seg01, myVar, %), length = myVar) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLine(angle = -angleToMatchLengthY(seg01, myVar, %), length = myVar) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper
"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();

View File

@ -12,18 +12,21 @@ export XY = {
origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 1, y = 0, z = 0 },
yAxis = { x = 0, y = 1, z = 0 },
zAxis = { x = 0, y = 0, z = 1 },
}: Plane
export XZ = {
origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 1, y = 0, z = 0 },
yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 0, y = -1, z = 0 },
}: Plane
export YZ = {
origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 0, y = 1, z = 0 },
yAxis = { x = 0, y = 0, z = 1 },
zAxis = { x = 1, y = 0, z = 0 },
}: Plane
export X = {
@ -446,93 +449,3 @@ export fn toRadians(@num: number(rad)): number(rad) {
export fn toDegrees(@num: number(deg)): number(deg) {
return num
}
/// Offset a plane by a distance along its normal.
///
/// For example, if you offset the `XZ` plane by 10, the new plane will be parallel to the `XZ`
/// plane and 10 units away from it.
///
/// ```
/// // Loft a square and a circle on the `XY` plane using offset.
/// squareSketch = startSketchOn(XY)
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane(XY, offset = 150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```
/// // Loft a square and a circle on the `XZ` plane using offset.
/// squareSketch = startSketchOn(XZ)
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane(XZ, offset = 150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```
/// // Loft a square and a circle on the `YZ` plane using offset.
/// squareSketch = startSketchOn(YZ)
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane(YZ, offset = 150))
/// |> circle( center = [0, 100], radius = 50 )
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```
/// // Loft a square and a circle on the `-XZ` plane using offset.
/// squareSketch = startSketchOn(-XZ)
/// |> startProfileAt([-100, 200], %)
/// |> line(end = [200, 0])
/// |> line(end = [0, -200])
/// |> line(end = [-200, 0])
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
///
/// circleSketch = startSketchOn(offsetPlane(-XZ, offset = 150))
/// |> circle(center = [0, 100], radius = 50)
///
/// loft([squareSketch, circleSketch])
/// ```
///
/// ```
/// // A circle on the XY plane
/// startSketchOn(XY)
/// |> startProfileAt([0, 0], %)
/// |> circle( radius = 10, center = [0, 0] )
///
/// // Triangle on the plane 4 units above
/// startSketchOn(offsetPlane(XY, offset = 4))
/// |> startProfileAt([0, 0], %)
/// |> line(end = [10, 0])
/// |> line(end = [0, 10])
/// |> close()
/// ```
@(impl = std_rust)
export fn offsetPlane(
/// The plane (e.g. `XY`) which this new plane is created from.
@plane: Plane,
/// Distance from the standard plane this new plane will be created at.
offset: number(Length),
): Plane {}

View File

@ -212,6 +212,14 @@ description: Variables in memory after executing angled_line.kcl
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -249,8 +257,7 @@ description: Variables in memory after executing angled_line.kcl
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"seg01": {

View File

@ -191,6 +191,14 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -252,8 +260,7 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
],
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"extrude002": {
@ -387,6 +394,14 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -573,6 +588,14 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -634,8 +657,7 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
],
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -670,8 +692,7 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"seg01": {
@ -826,6 +847,14 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -967,6 +996,14 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -1153,6 +1190,14 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -1214,8 +1259,7 @@ description: Variables in memory after executing artifact_graph_example_code1.kc
],
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"

View File

@ -210,7 +210,7 @@ description: Artifact commands artifact_graph_example_code_no_3d.kcl
"planar_normal": {
"x": 0.0,
"y": 1.0,
"z": -0.0
"z": 0.0
}
}
},

View File

@ -166,6 +166,14 @@ description: Variables in memory after executing artifact_graph_example_code_no_
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -309,6 +317,14 @@ description: Variables in memory after executing artifact_graph_example_code_no_
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {

View File

@ -4,15 +4,6 @@ description: Operations executed artifact_graph_example_code_offset_planes.kcl
---
[
{
"type": "KclStdLibCall",
"name": "offsetPlane",
"unlabeledArg": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
},
"labeledArgs": {
"offset": {
"value": {
@ -31,18 +22,18 @@ description: Operations executed artifact_graph_example_code_offset_planes.kcl
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "KclStdLibCall",
"name": "offsetPlane",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "String",
"value": "XZ"
"value": "XY"
},
"sourceRange": []
},
}
},
{
"labeledArgs": {
"offset": {
"value": {
@ -61,18 +52,18 @@ description: Operations executed artifact_graph_example_code_offset_planes.kcl
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "KclStdLibCall",
"name": "offsetPlane",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "String",
"value": "YZ"
"value": "XZ"
},
"sourceRange": []
},
}
},
{
"labeledArgs": {
"offset": {
"value": {
@ -91,7 +82,16 @@ description: Operations executed artifact_graph_example_code_offset_planes.kcl
"sourceRange": []
}
},
"sourceRange": []
"name": "offsetPlane",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "String",
"value": "YZ"
},
"sourceRange": []
}
},
{
"labeledArgs": {

View File

@ -32,6 +32,14 @@ description: Variables in memory after executing artifact_graph_example_code_off
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
}
},
@ -64,6 +72,14 @@ description: Variables in memory after executing artifact_graph_example_code_off
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
}
},
@ -96,6 +112,14 @@ description: Variables in memory after executing artifact_graph_example_code_off
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
}
},
@ -153,6 +177,14 @@ description: Variables in memory after executing artifact_graph_example_code_off
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {

View File

@ -153,6 +153,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -190,8 +198,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"extrude002": {
@ -325,6 +332,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -473,6 +488,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -510,8 +533,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -546,8 +568,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"extrude003": {
@ -693,6 +714,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -822,6 +851,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -970,6 +1007,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -1007,8 +1052,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -1043,8 +1087,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -1085,8 +1128,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"extrude004": {
@ -1220,6 +1262,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -1361,6 +1411,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -1490,6 +1548,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -1638,6 +1704,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -1675,8 +1749,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -1711,8 +1784,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -1753,8 +1825,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -1789,8 +1860,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"seg01": {
@ -1920,6 +1990,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -2057,6 +2135,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -2205,6 +2291,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -2242,8 +2336,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -2384,6 +2477,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -2513,6 +2614,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -2661,6 +2770,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -2698,8 +2815,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -2734,8 +2850,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -2876,6 +2991,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -3017,6 +3140,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -3146,6 +3277,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"solid": {
"type": "Solid",
"id": "[uuid]",
@ -3294,6 +3433,14 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": -1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -3331,8 +3478,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -3367,8 +3513,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"
@ -3409,8 +3554,7 @@ description: Variables in memory after executing artifact_graph_sketch_on_face_e
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
},
"units": {
"type": "Mm"

View File

@ -184,6 +184,14 @@ description: Variables in memory after executing basic_fillet_cube_close_opposit
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -267,8 +275,7 @@ description: Variables in memory after executing basic_fillet_cube_close_opposit
],
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"thing": {

View File

@ -172,6 +172,14 @@ description: Variables in memory after executing basic_fillet_cube_end.kcl
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -251,8 +259,7 @@ description: Variables in memory after executing basic_fillet_cube_end.kcl
],
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"thing": {

View File

@ -196,6 +196,14 @@ description: Variables in memory after executing basic_fillet_cube_next_adjacent
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -265,8 +273,7 @@ description: Variables in memory after executing basic_fillet_cube_next_adjacent
],
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"thing": {

View File

@ -196,6 +196,14 @@ description: Variables in memory after executing basic_fillet_cube_previous_adja
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -265,8 +273,7 @@ description: Variables in memory after executing basic_fillet_cube_previous_adja
],
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"thing": {

View File

@ -172,6 +172,14 @@ description: Variables in memory after executing basic_fillet_cube_start.kcl
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -251,8 +259,7 @@ description: Variables in memory after executing basic_fillet_cube_start.kcl
],
"units": {
"type": "Mm"
},
"sectional": false
}
}
},
"thing": {

View File

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

View File

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

View File

@ -0,0 +1,49 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[35, 60, 0]"]
3["Segment<br>[66, 101, 0]"]
4["Segment<br>[107, 178, 0]"]
5["Segment<br>[184, 192, 0]"]
6[Solid2d]
end
1["Plane<br>[10, 29, 0]"]
7["Sweep Extrusion<br>[198, 218, 0]"]
8[Wall]
9[Wall]
10[Wall]
11["Cap Start"]
12["Cap End"]
13["SweepEdge Opposite"]
14["SweepEdge Adjacent"]
15["SweepEdge Opposite"]
16["SweepEdge Adjacent"]
17["SweepEdge Opposite"]
18["SweepEdge Adjacent"]
1 --- 2
2 --- 3
2 --- 4
2 --- 5
2 ---- 7
2 --- 6
3 --- 10
3 --- 17
3 --- 18
4 --- 9
4 --- 15
4 --- 16
5 --- 8
5 --- 13
5 --- 14
7 --- 8
7 --- 9
7 --- 10
7 --- 11
7 --- 12
7 --- 13
7 --- 14
7 --- 15
7 --- 16
7 --- 17
7 --- 18
```

View File

@ -0,0 +1,428 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of parsing big_number_angle_to_match_length_x.kcl
---
{
"Ok": {
"body": [
{
"commentStart": 0,
"declaration": {
"commentStart": 0,
"end": 0,
"id": {
"commentStart": 0,
"end": 0,
"name": "part001",
"start": 0,
"type": "Identifier"
},
"init": {
"body": [
{
"arguments": [
{
"commentStart": 0,
"end": 0,
"raw": "'XY'",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": "XY"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"commentStart": 0,
"elements": [
{
"commentStart": 0,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"commentStart": 0,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 0,
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "end",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"elements": [
{
"commentStart": 0,
"end": 0,
"raw": "1",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"commentStart": 0,
"end": 0,
"raw": "3.82",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.82,
"suffix": "None"
}
}
],
"end": 0,
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "tag",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"end": 0,
"start": 0,
"type": "TagDeclarator",
"type": "TagDeclarator",
"value": "seg01"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "angle",
"start": 0,
"type": "Identifier"
},
"arg": {
"argument": {
"arguments": [
{
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "seg01",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name",
"type": "Name"
},
{
"commentStart": 0,
"end": 0,
"raw": "3",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.0,
"suffix": "None"
}
},
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "angleToMatchLengthX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
"commentStart": 0,
"end": 0,
"operator": "-",
"start": 0,
"type": "UnaryExpression",
"type": "UnaryExpression"
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "endAbsoluteX",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"end": 0,
"raw": "3",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.0,
"suffix": "None"
}
}
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "angledLine",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "length",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"end": 0,
"raw": "10",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 10.0,
"suffix": "None"
}
}
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
}
],
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeExpression",
"type": "PipeExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 0,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"commentStart": 0,
"end": 0,
"start": 0
}
}

View File

@ -0,0 +1,6 @@
part001 = startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> line(end = [1, 3.82], tag = $seg01)
|> angledLine(angle = -angleToMatchLengthX(seg01, 3, %), endAbsoluteX = 3)
|> close(%)
|> extrude(length = 10)

View File

@ -0,0 +1,53 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed big_number_angle_to_match_length_x.kcl
---
[
{
"labeledArgs": {
"planeOrSolid": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
}
]

View File

@ -0,0 +1,190 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing big_number_angle_to_match_length_x.kcl
---
{
"part001": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 94,
"end": 100,
"start": 94,
"type": "TagDeclarator",
"value": "seg01"
},
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
0.0,
0.0
],
"tag": {
"commentStart": 94,
"end": 100,
"start": 94,
"type": "TagDeclarator",
"value": "seg01"
},
"to": [
1.0,
3.82
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
1.0,
3.82
],
"tag": null,
"to": [
3.0,
0.4152
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
3.0,
0.4152
],
"tag": null,
"to": [
0.0,
0.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
"from": [
0.0,
0.0
],
"to": [
0.0,
0.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"tags": {
"seg01": {
"type": "TagIdentifier",
"value": "seg01"
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"seg01": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "seg01"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1,10 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing big_number_angle_to_match_length_x.kcl
---
part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [1, 3.82], tag = $seg01)
|> angledLine(angle = -angleToMatchLengthX(seg01, 3, %), endAbsoluteX = 3)
|> close(%)
|> extrude(length = 10)

View File

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

View File

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

View File

@ -0,0 +1,49 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[35, 60, 0]"]
3["Segment<br>[66, 101, 0]"]
4["Segment<br>[107, 178, 0]"]
5["Segment<br>[184, 192, 0]"]
6[Solid2d]
end
1["Plane<br>[10, 29, 0]"]
7["Sweep Extrusion<br>[198, 218, 0]"]
8[Wall]
9[Wall]
10[Wall]
11["Cap Start"]
12["Cap End"]
13["SweepEdge Opposite"]
14["SweepEdge Adjacent"]
15["SweepEdge Opposite"]
16["SweepEdge Adjacent"]
17["SweepEdge Opposite"]
18["SweepEdge Adjacent"]
1 --- 2
2 --- 3
2 --- 4
2 --- 5
2 ---- 7
2 --- 6
3 --- 10
3 --- 17
3 --- 18
4 --- 9
4 --- 15
4 --- 16
5 --- 8
5 --- 13
5 --- 14
7 --- 8
7 --- 9
7 --- 10
7 --- 11
7 --- 12
7 --- 13
7 --- 14
7 --- 15
7 --- 16
7 --- 17
7 --- 18
```

View File

@ -0,0 +1,428 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of parsing big_number_angle_to_match_length_y.kcl
---
{
"Ok": {
"body": [
{
"commentStart": 0,
"declaration": {
"commentStart": 0,
"end": 0,
"id": {
"commentStart": 0,
"end": 0,
"name": "part001",
"start": 0,
"type": "Identifier"
},
"init": {
"body": [
{
"arguments": [
{
"commentStart": 0,
"end": 0,
"raw": "'XY'",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": "XY"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"commentStart": 0,
"elements": [
{
"commentStart": 0,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"commentStart": 0,
"end": 0,
"raw": "0",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 0,
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
},
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "end",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"elements": [
{
"commentStart": 0,
"end": 0,
"raw": "1",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"commentStart": 0,
"end": 0,
"raw": "3.82",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.82,
"suffix": "None"
}
}
],
"end": 0,
"start": 0,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "tag",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"end": 0,
"start": 0,
"type": "TagDeclarator",
"type": "TagDeclarator",
"value": "seg01"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "angle",
"start": 0,
"type": "Identifier"
},
"arg": {
"argument": {
"arguments": [
{
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "seg01",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name",
"type": "Name"
},
{
"commentStart": 0,
"end": 0,
"raw": "3",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.0,
"suffix": "None"
}
},
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "angleToMatchLengthY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
"commentStart": 0,
"end": 0,
"operator": "-",
"start": 0,
"type": "UnaryExpression",
"type": "UnaryExpression"
}
},
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "endAbsoluteX",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"end": 0,
"raw": "3",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 3.0,
"suffix": "None"
}
}
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "angledLine",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
},
{
"arguments": [
{
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeSubstitution",
"type": "PipeSubstitution"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpression",
"type": "CallExpression"
},
{
"arguments": [
{
"type": "LabeledArg",
"label": {
"commentStart": 0,
"end": 0,
"name": "length",
"start": 0,
"type": "Identifier"
},
"arg": {
"commentStart": 0,
"end": 0,
"raw": "10",
"start": 0,
"type": "Literal",
"type": "Literal",
"value": {
"value": 10.0,
"suffix": "None"
}
}
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 0,
"name": {
"commentStart": 0,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Name"
},
"commentStart": 0,
"end": 0,
"start": 0,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
}
],
"commentStart": 0,
"end": 0,
"start": 0,
"type": "PipeExpression",
"type": "PipeExpression"
},
"start": 0,
"type": "VariableDeclarator"
},
"end": 0,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
"type": "VariableDeclaration"
}
],
"commentStart": 0,
"end": 0,
"start": 0
}
}

View File

@ -0,0 +1,6 @@
part001 = startSketchOn('XY')
|> startProfileAt([0, 0], %)
|> line(end = [1, 3.82], tag = $seg01)
|> angledLine(angle = -angleToMatchLengthY(seg01, 3, %), endAbsoluteX = 3)
|> close(%)
|> extrude(length = 10)

View File

@ -0,0 +1,53 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Operations executed big_number_angle_to_match_length_y.kcl
---
[
{
"labeledArgs": {
"planeOrSolid": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
}
]

View File

@ -0,0 +1,190 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Variables in memory after executing big_number_angle_to_match_length_y.kcl
---
{
"part001": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": {
"commentStart": 94,
"end": 100,
"start": 94,
"type": "TagDeclarator",
"value": "seg01"
},
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
0.0,
0.0
],
"tag": {
"commentStart": 94,
"end": 100,
"start": 94,
"type": "TagDeclarator",
"value": "seg01"
},
"to": [
1.0,
3.82
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
1.0,
3.82
],
"tag": null,
"to": [
3.0,
3.3954
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
},
"from": [
3.0,
3.3954
],
"tag": null,
"to": [
0.0,
0.0
],
"type": "ToPoint",
"units": {
"type": "Mm"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0,
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
"from": [
0.0,
0.0
],
"to": [
0.0,
0.0
],
"units": {
"type": "Mm"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": []
}
},
"tags": {
"seg01": {
"type": "TagIdentifier",
"value": "seg01"
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
}
},
"height": 10.0,
"startCapId": "[uuid]",
"endCapId": "[uuid]",
"units": {
"type": "Mm"
}
}
},
"seg01": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "seg01"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -0,0 +1,10 @@
---
source: kcl-lib/src/simulation_tests.rs
description: Result of unparsing big_number_angle_to_match_length_y.kcl
---
part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(end = [1, 3.82], tag = $seg01)
|> angledLine(angle = -angleToMatchLengthY(seg01, 3, %), endAbsoluteX = 3)
|> close(%)
|> extrude(length = 10)

View File

@ -82,6 +82,14 @@ description: Variables in memory after executing circle_three_point.kcl
"units": {
"type": "Mm"
}
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0,
"units": {
"type": "Mm"
}
}
},
"start": {
@ -113,8 +121,7 @@ description: Variables in memory after executing circle_three_point.kcl
"endCapId": "[uuid]",
"units": {
"type": "Mm"
},
"sectional": false
}
}
}
}

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