Use arrays for multiple geometry (#5770)

* Parse [T] instead of T[] for array types

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* homogenous arrays, type coercion, remove solid set and sketch set, etc

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-03-17 17:57:26 +13:00
committed by GitHub
parent 75a975b1e1
commit a8b0e1a771
97 changed files with 325236 additions and 323291 deletions

View File

@ -10,11 +10,11 @@ This will work on any solid, including extruded solids, revolved solids, and she
```js
appearance(
solidSet: SolidSet,
solids: [Solid],
color: String,
metalness?: number,
roughness?: number,
): SolidSet
): [Solid]
```
@ -22,14 +22,14 @@ appearance(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | The solid(s) whose appearance is being set | Yes |
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | The solid(s) whose appearance is being set | Yes |
| `color` | `String` | Color of the new material, a hex string like '#ff0000' | Yes |
| `metalness` | [`number`](/docs/kcl/types/number) | Metalness of the new material, a percentage like 95.7. | No |
| `roughness` | [`number`](/docs/kcl/types/number) | Roughness of the new material, a percentage like 95.7. | No |
### Returns
[`SolidSet`](/docs/kcl/types/SolidSet) - A solid or a group of solids.
[`[Solid]`](/docs/kcl/types/Solid)
### Examples

View File

@ -10,9 +10,9 @@ You can provide more than one sketch to extrude, and they will all be extruded i
```js
extrude(
sketchSet: SketchSet,
sketches: [Sketch],
length: number,
): SolidSet
): [Solid]
```
@ -20,12 +20,12 @@ extrude(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | Which sketch or set of sketches should be extruded | Yes |
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | Which sketch or sketches should be extruded | Yes |
| `length` | [`number`](/docs/kcl/types/number) | How far to extrude the given sketches | Yes |
### Returns
[`SolidSet`](/docs/kcl/types/SolidSet) - A solid or a group of solids.
[`[Solid]`](/docs/kcl/types/Solid)
### Examples

View File

@ -10,7 +10,7 @@ Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch.
```js
hole(
holeSketch: SketchSet,
holeSketch: [Sketch],
sketch: Sketch,
): Sketch
```
@ -20,7 +20,7 @@ hole(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `holeSketch` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `holeSketch` | [`[Sketch]`](/docs/kcl/types/Sketch) | | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
### Returns

View File

@ -13,7 +13,7 @@ Mirror occurs around a local sketch axis rather than a global axis.
```js
mirror2d(
data: Mirror2dData,
sketchSet: SketchSet,
sketches: [Sketch],
): [Sketch]
```
@ -23,7 +23,7 @@ mirror2d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`Mirror2dData`](/docs/kcl/types/Mirror2dData) | Data for a mirror. | Yes |
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | | Yes |
### Returns

View File

@ -10,7 +10,7 @@ Repeat a 2-dimensional sketch some number of times along a partial or complete c
```js
patternCircular2d(
sketchSet: SketchSet,
sketchSet: [Sketch],
instances: integer,
center: [number],
arcDegrees: number,
@ -24,7 +24,7 @@ patternCircular2d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | Which sketch(es) to pattern | Yes |
| `sketchSet` | [`[Sketch]`](/docs/kcl/types/Sketch) | Which sketch(es) to pattern | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center about which to make the pattern. This is a 2D vector. | Yes |
| `arcDegrees` | [`number`](/docs/kcl/types/number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes |

View File

@ -10,7 +10,7 @@ Repeat a 3-dimensional solid some number of times along a partial or complete ci
```js
patternCircular3d(
solidSet: SolidSet,
solids: [Solid],
instances: integer,
axis: [number],
center: [number],
@ -25,7 +25,7 @@ patternCircular3d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | Which solid(s) to pattern | Yes |
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | Which solid(s) to pattern | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `axis` | [`[number]`](/docs/kcl/types/number) | The axis around which to make the pattern. This is a 3D vector | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center about which to make the pattern. This is a 3D vector. | Yes |

View File

@ -10,7 +10,7 @@ Repeat a 2-dimensional sketch along some dimension, with a dynamic amount of dis
```js
patternLinear2d(
sketchSet: SketchSet,
sketches: [Sketch],
instances: integer,
distance: number,
axis: [number],
@ -23,7 +23,7 @@ patternLinear2d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch(es) to duplicate | Yes |
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | The sketch(es) to duplicate | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `distance` | [`number`](/docs/kcl/types/number) | Distance between each repetition. Also known as 'spacing'. | Yes |
| `axis` | [`[number]`](/docs/kcl/types/number) | The axis of the pattern. A 2D vector. | Yes |

View File

@ -10,7 +10,7 @@ Repeat a 3-dimensional solid along a linear path, with a dynamic amount of dista
```js
patternLinear3d(
solidSet: SolidSet,
solids: [Solid],
instances: integer,
distance: number,
axis: [number],
@ -23,7 +23,7 @@ patternLinear3d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | The solid(s) to duplicate | Yes |
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | The solid(s) to duplicate | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `distance` | [`number`](/docs/kcl/types/number) | Distance between each repetition. Also known as 'spacing'. | Yes |
| `axis` | [`[number]`](/docs/kcl/types/number) | The axis of the pattern. A 2D vector. | Yes |

View File

@ -36,7 +36,7 @@ The transform function returns a transform object. All properties of the object
```js
patternTransform(
solidSet: SolidSet,
solids: [Solid],
instances: integer,
transform: FunctionSource,
useOriginal?: bool,
@ -48,7 +48,7 @@ patternTransform(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | The solid(s) to duplicate | Yes |
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | The solid(s) to duplicate | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
| `useOriginal` | [`bool`](/docs/kcl/types/bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |

View File

@ -10,7 +10,7 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
```js
patternTransform2d(
sketchSet: SketchSet,
sketches: [Sketch],
instances: integer,
transform: FunctionSource,
useOriginal?: bool,
@ -22,7 +22,7 @@ patternTransform2d(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch(es) to duplicate | Yes |
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | The sketch(es) to duplicate | Yes |
| `instances` | `integer` | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
| `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
| `useOriginal` | [`bool`](/docs/kcl/types/bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |

View File

@ -15,8 +15,8 @@ You can provide more than one sketch to revolve, and they will all be revolved a
```js
revolve(
data: RevolveData,
sketchSet: SketchSet,
): SolidSet
sketches: [Sketch],
): [Solid]
```
@ -25,11 +25,11 @@ revolve(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`RevolveData`](/docs/kcl/types/RevolveData) | Data for revolution surfaces. | Yes |
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | | Yes |
### Returns
[`SolidSet`](/docs/kcl/types/SolidSet) - A solid or a group of solids.
[`[Solid]`](/docs/kcl/types/Solid)
### Examples

View File

@ -24,7 +24,7 @@ When rotating a part around an axis, you specify the axis of rotation and the an
```js
rotate(
solidSet: SolidOrImportedGeometry,
solids: SolidOrImportedGeometry,
roll?: number,
pitch?: number,
yaw?: number,
@ -39,7 +39,7 @@ rotate(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidOrImportedGeometry`](/docs/kcl/types/SolidOrImportedGeometry) | The solid or set of solids to rotate. | Yes |
| `solids` | [`SolidOrImportedGeometry`](/docs/kcl/types/SolidOrImportedGeometry) | The solid or set of solids to rotate. | Yes |
| `roll` | [`number`](/docs/kcl/types/number) | The roll angle in degrees. Must be used with `pitch` and `yaw`. Must be between -360 and 360. | No |
| `pitch` | [`number`](/docs/kcl/types/number) | The pitch angle in degrees. Must be used with `roll` and `yaw`. Must be between -360 and 360. | No |
| `yaw` | [`number`](/docs/kcl/types/number) | The yaw angle in degrees. Must be used with `roll` and `pitch`. Must be between -360 and 360. | No |

View File

@ -12,7 +12,7 @@ If you want to apply the transform in global space, set `global` to `true`. The
```js
scale(
solidSet: SolidOrImportedGeometry,
solids: SolidOrImportedGeometry,
scale: [number],
global?: bool,
): SolidOrImportedGeometry
@ -23,7 +23,7 @@ scale(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidOrImportedGeometry`](/docs/kcl/types/SolidOrImportedGeometry) | The solid or set of solids to scale. | Yes |
| `solids` | [`SolidOrImportedGeometry`](/docs/kcl/types/SolidOrImportedGeometry) | The solid or set of solids to scale. | Yes |
| `scale` | [`[number]`](/docs/kcl/types/number) | The scale factor for the x, y, and z axes. | Yes |
| `global` | [`bool`](/docs/kcl/types/bool) | If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move. | No |

View File

@ -10,10 +10,10 @@ Remove volume from a 3-dimensional shape such that a wall of the provided thickn
```js
shell(
solidSet: SolidSet,
solids: [Solid],
thickness: number,
faces: [FaceTag],
): SolidSet
): [Solid]
```
@ -21,13 +21,13 @@ shell(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidSet`](/docs/kcl/types/SolidSet) | Which solid (or solids) to shell out | Yes |
| `solids` | [`[Solid]`](/docs/kcl/types/Solid) | Which solid (or solids) to shell out | Yes |
| `thickness` | [`number`](/docs/kcl/types/number) | The thickness of the shell | Yes |
| `faces` | [`[FaceTag]`](/docs/kcl/types/FaceTag) | The faces you want removed | Yes |
### Returns
[`SolidSet`](/docs/kcl/types/SolidSet) - A solid or a group of solids.
[`[Solid]`](/docs/kcl/types/Solid)
### Examples

File diff suppressed because it is too large Load Diff

View File

@ -12,11 +12,11 @@ You can provide more than one sketch to sweep, and they will all be swept along
```js
sweep(
sketchSet: SketchSet,
sketches: [Sketch],
path: SweepPath,
sectional?: bool,
tolerance?: number,
): SolidSet
): [Solid]
```
@ -24,14 +24,14 @@ sweep(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSet` | [`SketchSet`](/docs/kcl/types/SketchSet) | The sketch or set of sketches that should be swept in space | Yes |
| `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) | The sketch or set of sketches that should be swept in space | Yes |
| `path` | [`SweepPath`](/docs/kcl/types/SweepPath) | The path to sweep the sketch along | Yes |
| `sectional` | [`bool`](/docs/kcl/types/bool) | If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. | No |
| `tolerance` | [`number`](/docs/kcl/types/number) | Tolerance for this operation | No |
### Returns
[`SolidSet`](/docs/kcl/types/SolidSet) - A solid or a group of solids.
[`[Solid]`](/docs/kcl/types/Solid)
### Examples

View File

@ -10,7 +10,7 @@ Move a solid.
```js
translate(
solidSet: SolidOrImportedGeometry,
solids: SolidOrImportedGeometry,
translate: [number],
global?: bool,
): SolidOrImportedGeometry
@ -21,7 +21,7 @@ translate(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `solidSet` | [`SolidOrImportedGeometry`](/docs/kcl/types/SolidOrImportedGeometry) | The solid or set of solids to move. | Yes |
| `solids` | [`SolidOrImportedGeometry`](/docs/kcl/types/SolidOrImportedGeometry) | The solid or set of solids to move. | Yes |
| `translate` | [`[number]`](/docs/kcl/types/number) | The amount to move the solid in all three axes. | Yes |
| `global` | [`bool`](/docs/kcl/types/bool) | If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move. | No |

View File

@ -100,6 +100,22 @@ Any KCL value.
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `HomArray`| | No |
| `value` |`[` [`KclValue`](/docs/kcl/types/KclValue) `]`| | No |
----
**Type:** `object`
## Properties
| Property | Type | Description | Required |
@ -199,22 +215,6 @@ Any KCL value.
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Sketches`| | No |
| `value` |`[` [`Sketch`](/docs/kcl/types/Sketch) `]`| | No |
----
**Type:** `object`
## Properties
| Property | Type | Description | Required |
@ -231,22 +231,6 @@ Any KCL value.
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Solids`| | No |
| `value` |`[` [`Solid`](/docs/kcl/types/Solid) `]`| | No |
----
**Type:** `object`
## Properties
| Property | Type | Description | Required |

View File

@ -1,56 +0,0 @@
---
title: "SketchSet"
excerpt: "A sketch or a group of sketches."
layout: manual
---
A sketch or a group of sketches.
**This schema accepts exactly one of the following:**
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `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` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| 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, array]`
`[` [`Sketch`](/docs/kcl/types/Sketch) `]`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `sketches`| | No |
----

View File

@ -12,30 +12,6 @@ Data for a solid or an imported geometry.
**This schema accepts exactly one of the following:**
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `solid`| | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the solid. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| 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)| A unit of length. | No |
----
Data for an imported geometry.
**Type:** `object`

View File

@ -1,57 +0,0 @@
---
title: "SolidSet"
excerpt: "A solid or a group of solids."
layout: manual
---
A solid or a group of solids.
**This schema accepts exactly one of the following:**
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `solid`| | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the solid. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| 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)| A unit of length. | No |
----
**Type:** `[object, array]`
`[` [`Solid`](/docs/kcl/types/Solid) `]`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `solids`| | No |
----

File diff suppressed because one or more lines are too long

View File

@ -3073,7 +3073,7 @@ DATA;
#3057 = CARTESIAN_POINT('NONE', (0.051104890518972546, -0.039940414856583686, -0.0635));
#3058 = CARTESIAN_POINT('NONE', (0.052242074077479335, -0.038876903045998674, -0.0635));
#3059 = CARTESIAN_POINT('NONE', (0.05224392753122875, -0.03887516966712757, -0.0635));
#3060 = CARTESIAN_POINT('NONE', (0.05311532463588208, -0.03767579444673182, -0.0635));
#3060 = CARTESIAN_POINT('NONE', (0.05311532463588208, -0.03767579444673181, -0.0635));
#3061 = CARTESIAN_POINT('NONE', (0.05311674489404425, -0.03767383962907501, -0.0635));
#3062 = CARTESIAN_POINT('NONE', (0.053776795686355607, -0.03626367057234418, -0.0635));
#3063 = CARTESIAN_POINT('NONE', (0.05377787147891932, -0.036261372189549286, -0.0635));
@ -3087,7 +3087,7 @@ DATA;
#3071 = CARTESIAN_POINT('NONE', (0.053252818350252196, -0.029748655756475863, -0.0635));
#3072 = CARTESIAN_POINT('NONE', (0.05233460363130192, -0.028414043632913145, -0.0635));
#3073 = CARTESIAN_POINT('NONE', (0.05233310706682834, -0.028411868397590818, -0.0635));
#3074 = CARTESIAN_POINT('NONE', (0.051232952266167, -0.02734405921816657, -0.0635));
#3074 = CARTESIAN_POINT('NONE', (0.05123295226616701, -0.02734405921816657, -0.0635));
#3075 = CARTESIAN_POINT('NONE', (0.05123115916423111, -0.027342318835171704, -0.0635));
#3076 = CARTESIAN_POINT('NONE', (0.0499865731843106, -0.02652506813979786, -0.0635));
#3077 = CARTESIAN_POINT('NONE', (0.049984544679296, -0.026523736132881105, -0.0635));
@ -3105,7 +3105,7 @@ DATA;
#3089 = CARTESIAN_POINT('NONE', (0.0407616757108459, -0.02775624333996861, -0.0635));
#3090 = CARTESIAN_POINT('NONE', (0.03976400232776854, -0.0288872140372878, -0.0635));
#3091 = CARTESIAN_POINT('NONE', (0.03976237625653429, -0.028889057364922765, -0.0635));
#3092 = B_SPLINE_CURVE_WITH_KNOTS('NONE', 2, (#3029, #3030, #3031, #3032, #3033, #3034, #3035, #3036, #3037, #3038, #3039, #3040, #3041, #3042, #3043, #3044, #3045, #3046, #3047, #3048, #3049, #3050, #3051, #3052, #3053, #3054, #3055, #3056, #3057, #3058, #3059, #3060, #3061, #3062, #3063, #3064, #3065, #3066, #3067, #3068, #3069, #3070, #3071, #3072, #3073, #3074, #3075, #3076, #3077, #3078, #3079, #3080, #3081, #3082, #3083, #3084, #3085, #3086, #3087, #3088, #3089, #3090, #3091), .UNSPECIFIED., .F., .F., (3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3), (0, 0.01639344262295082, 0.03278688524590164, 0.04918032786885246, 0.06557377049180328, 0.0819672131147541, 0.09836065573770492, 0.11475409836065574, 0.13114754098360656, 0.14754098360655737, 0.1639344262295082, 0.18032786885245902, 0.19672131147540983, 0.21311475409836067, 0.22950819672131148, 0.24590163934426232, 0.26229508196721313, 0.27868852459016397, 0.29508196721311475, 0.3114754098360656, 0.3278688524590164, 0.3442622950819672, 0.36065573770491804, 0.3770491803278689, 0.39344262295081966, 0.4098360655737705, 0.42622950819672134, 0.4426229508196722, 0.45901639344262296, 0.4754098360655738, 0.49180327868852464, 0.5081967213114753, 0.5245901639344261, 0.540983606557377, 0.5573770491803278, 0.5737704918032787, 0.5901639344262295, 0.6065573770491803, 0.6229508196721312, 0.639344262295082, 0.6557377049180328, 0.6721311475409836, 0.6885245901639344, 0.7049180327868853, 0.721311475409836, 0.7377049180327868, 0.7540983606557377, 0.7704918032786885, 0.7868852459016393, 0.8032786885245902, 0.819672131147541, 0.8360655737704918, 0.8524590163934427, 0.8688524590163934, 0.8852459016393442, 0.9016393442622951, 0.9180327868852459, 0.9344262295081968, 0.9508196721311475, 0.9672131147540983, 0.9836065573770492, 1), .UNSPECIFIED.);
#3092 = B_SPLINE_CURVE_WITH_KNOTS('NONE', 2, (#3029, #3030, #3031, #3032, #3033, #3034, #3035, #3036, #3037, #3038, #3039, #3040, #3041, #3042, #3043, #3044, #3045, #3046, #3047, #3048, #3049, #3050, #3051, #3052, #3053, #3054, #3055, #3056, #3057, #3058, #3059, #3060, #3061, #3062, #3063, #3064, #3065, #3066, #3067, #3068, #3069, #3070, #3071, #3072, #3073, #3074, #3075, #3076, #3077, #3078, #3079, #3080, #3081, #3082, #3083, #3084, #3085, #3086, #3087, #3088, #3089, #3090, #3091), .UNSPECIFIED., .F., .F., (3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3), (-1, -0.9836065573770492, -0.9672131147540983, -0.9508196721311475, -0.9344262295081968, -0.9180327868852459, -0.9016393442622951, -0.8852459016393442, -0.8688524590163934, -0.8524590163934427, -0.8360655737704918, -0.819672131147541, -0.8032786885245902, -0.7868852459016393, -0.7704918032786885, -0.7540983606557377, -0.7377049180327868, -0.721311475409836, -0.7049180327868853, -0.6885245901639344, -0.6721311475409836, -0.6557377049180328, -0.639344262295082, -0.6229508196721312, -0.6065573770491803, -0.5901639344262295, -0.5737704918032787, -0.5573770491803278, -0.540983606557377, -0.5245901639344261, -0.5081967213114753, -0.49180327868852464, -0.4754098360655738, -0.45901639344262296, -0.4426229508196722, -0.42622950819672134, -0.4098360655737705, -0.39344262295081966, -0.3770491803278689, -0.36065573770491804, -0.3442622950819672, -0.3278688524590164, -0.3114754098360656, -0.29508196721311475, -0.27868852459016397, -0.26229508196721313, -0.24590163934426232, -0.22950819672131148, -0.21311475409836067, -0.19672131147540983, -0.18032786885245902, -0.1639344262295082, -0.14754098360655737, -0.13114754098360656, -0.11475409836065574, -0.09836065573770492, -0.0819672131147541, -0.06557377049180328, -0.04918032786885246, -0.03278688524590164, -0.01639344262295082, -0), .UNSPECIFIED.);
#3093 = DIRECTION('NONE', (0, 0, 1));
#3094 = VECTOR('NONE', #3093, 1);
#3095 = CARTESIAN_POINT('NONE', (0.03976237625653429, -0.028889057364922765, -0.063501));

View File

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

View File

@ -2106,7 +2106,7 @@ async fn kcl_test_better_type_names() {
},
None => todo!(),
};
assert_eq!(err, "This function expected the input argument to be of type SolidSet but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`");
assert_eq!(err, "This function expected the input argument to be one or more Solids but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`");
}
#[tokio::test(flavor = "multi_thread")]

View File

@ -128,9 +128,9 @@ impl StdLibFnArg {
""
};
if self.type_ == "Sketch"
|| self.type_ == "SketchSet"
|| self.type_ == "[Sketch]"
|| self.type_ == "Solid"
|| self.type_ == "SolidSet"
|| self.type_ == "[Solid]"
|| self.type_ == "SketchSurface"
|| self.type_ == "SketchOrSurface"
|| self.type_ == "SolidOrImportedGeometry"

View File

@ -180,15 +180,9 @@ pub enum OpKclValue {
Sketch {
value: Box<OpSketch>,
},
Sketches {
value: Vec<OpSketch>,
},
Solid {
value: Box<OpSolid>,
},
Solids {
value: Vec<OpSolid>,
},
Helix {
value: Box<OpHelix>,
},
@ -234,7 +228,7 @@ impl From<&KclValue> for OpKclValue {
ty: ty.clone(),
},
KclValue::String { value, .. } => Self::String { value: value.clone() },
KclValue::MixedArray { value, .. } => {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => {
let value = value.iter().map(Self::from).collect();
Self::Array { value }
}
@ -260,29 +254,11 @@ impl From<&KclValue> for OpKclValue {
artifact_id: value.artifact_id,
}),
},
KclValue::Sketches { value } => {
let value = value
.iter()
.map(|sketch| OpSketch {
artifact_id: sketch.artifact_id,
})
.collect();
Self::Sketches { value }
}
KclValue::Solid { value } => Self::Solid {
value: Box::new(OpSolid {
artifact_id: value.artifact_id,
}),
},
KclValue::Solids { value } => {
let value = value
.iter()
.map(|solid| OpSolid {
artifact_id: solid.artifact_id,
})
.collect();
Self::Solids { value }
}
KclValue::Helix { value } => Self::Helix {
value: Box::new(OpHelix {
artifact_id: value.artifact_id,

View File

@ -8,11 +8,11 @@ use crate::{
execution::{
annotations,
cad_op::{OpArg, OpKclValue, Operation},
kcl_value::{FunctionSource, NumericType, PrimitiveType, RuntimeType},
kcl_value::{FunctionSource, NumericType, RuntimeType},
memory,
state::ModuleState,
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, Plane, PlaneType, Point3d,
TagEngineInfo, TagIdentifier,
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, PlaneType, TagEngineInfo,
TagIdentifier,
},
modules::{ModuleId, ModulePath, ModuleRepr},
parsing::ast::types::{
@ -23,7 +23,7 @@ use crate::{
},
source_range::SourceRange,
std::{
args::{Arg, FromKclValue, KwArgs},
args::{Arg, KwArgs},
FunctionKind,
},
CompilationError,
@ -647,11 +647,11 @@ impl ExecutorContext {
let result = self
.execute_expr(&expr.expr, exec_state, metadata, &[], statement_kind)
.await?;
coerce(result, &expr.ty, exec_state).map_err(|value| {
coerce(&result, &expr.ty, exec_state).ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"could not coerce {} value to type {}",
value.human_friendly_type(),
result.human_friendly_type(),
expr.ty
),
source_ranges: vec![expr.into()],
@ -663,72 +663,14 @@ impl ExecutorContext {
}
}
fn coerce(value: KclValue, ty: &Node<Type>, exec_state: &mut ExecState) -> Result<KclValue, KclValue> {
let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, (&value).into())
fn coerce(value: &KclValue, ty: &Node<Type>, exec_state: &mut ExecState) -> Option<KclValue> {
let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, value.into())
.map_err(|e| {
exec_state.err(e);
value.clone()
})?
.ok_or_else(|| value.clone())?;
if value.has_type(&ty) {
return Ok(value);
}
})
.ok()??;
// TODO coerce numeric types
if let KclValue::Object { value, meta } = value {
return match ty {
RuntimeType::Primitive(PrimitiveType::Plane) => {
let origin = value
.get("origin")
.and_then(Point3d::from_kcl_val)
.ok_or_else(|| KclValue::Object {
value: value.clone(),
meta: meta.clone(),
})?;
let x_axis = value
.get("xAxis")
.and_then(Point3d::from_kcl_val)
.ok_or_else(|| KclValue::Object {
value: value.clone(),
meta: meta.clone(),
})?;
let y_axis = value
.get("yAxis")
.and_then(Point3d::from_kcl_val)
.ok_or_else(|| KclValue::Object {
value: value.clone(),
meta: meta.clone(),
})?;
let z_axis = value
.get("zAxis")
.and_then(Point3d::from_kcl_val)
.ok_or_else(|| KclValue::Object {
value: value.clone(),
meta: meta.clone(),
})?;
let id = exec_state.next_uuid();
let plane = Plane {
id,
artifact_id: id.into(),
origin,
x_axis,
y_axis,
z_axis,
value: PlaneType::Uninit,
// TODO use length unit from origin
units: exec_state.length_unit(),
meta,
};
Ok(KclValue::Plane { value: Box::new(plane) })
}
_ => Err(KclValue::Object { value, meta }),
};
}
Err(value)
value.coerce(&ty, exec_state)
}
impl BinaryPart {
@ -1450,6 +1392,11 @@ fn update_memory_for_tags_of_geometry(result: &mut KclValue, exec_state: &mut Ex
}
}
}
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => {
for v in value {
update_memory_for_tags_of_geometry(v, exec_state)?;
}
}
_ => {}
}
Ok(())

View File

@ -23,8 +23,8 @@ type Point3D = kcmc::shared::Point3d<f64>;
#[ts(export)]
#[serde(tag = "type")]
pub enum Geometry {
Sketch(Box<Sketch>),
Solid(Box<Solid>),
Sketch(Sketch),
Solid(Solid),
}
impl Geometry {
@ -52,8 +52,8 @@ impl Geometry {
#[serde(tag = "type")]
#[allow(clippy::vec_box)]
pub enum Geometries {
Sketches(Vec<Box<Sketch>>),
Solids(Vec<Box<Solid>>),
Sketches(Vec<Sketch>),
Solids(Vec<Solid>),
}
impl From<Geometry> for Geometries {
@ -65,150 +65,6 @@ impl From<Geometry> for Geometries {
}
}
/// A sketch or a group of sketches.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type", rename_all = "camelCase")]
#[allow(clippy::vec_box)]
pub enum SketchSet {
Sketch(Box<Sketch>),
Sketches(Vec<Box<Sketch>>),
}
impl SketchSet {
pub fn meta(&self) -> Vec<Metadata> {
match self {
SketchSet::Sketch(sg) => sg.meta.clone(),
SketchSet::Sketches(sg) => sg.iter().flat_map(|sg| sg.meta.clone()).collect(),
}
}
}
impl From<SketchSet> for Vec<Sketch> {
fn from(value: SketchSet) -> Self {
match value {
SketchSet::Sketch(sg) => vec![*sg],
SketchSet::Sketches(sgs) => sgs.into_iter().map(|sg| *sg).collect(),
}
}
}
impl From<Sketch> for SketchSet {
fn from(sg: Sketch) -> Self {
SketchSet::Sketch(Box::new(sg))
}
}
impl From<Box<Sketch>> for SketchSet {
fn from(sg: Box<Sketch>) -> Self {
SketchSet::Sketch(sg)
}
}
impl From<Vec<Sketch>> for SketchSet {
fn from(sg: Vec<Sketch>) -> Self {
if sg.len() == 1 {
SketchSet::Sketch(Box::new(sg[0].clone()))
} else {
SketchSet::Sketches(sg.into_iter().map(Box::new).collect())
}
}
}
impl From<Vec<Box<Sketch>>> for SketchSet {
fn from(sg: Vec<Box<Sketch>>) -> Self {
if sg.len() == 1 {
SketchSet::Sketch(sg[0].clone())
} else {
SketchSet::Sketches(sg)
}
}
}
impl From<SketchSet> for Vec<Box<Sketch>> {
fn from(sg: SketchSet) -> Self {
match sg {
SketchSet::Sketch(sg) => vec![sg],
SketchSet::Sketches(sgs) => sgs,
}
}
}
impl From<&Sketch> for Vec<Box<Sketch>> {
fn from(sg: &Sketch) -> Self {
vec![Box::new(sg.clone())]
}
}
impl From<Box<Sketch>> for Vec<Box<Sketch>> {
fn from(sg: Box<Sketch>) -> Self {
vec![sg]
}
}
/// A solid or a group of solids.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type", rename_all = "camelCase")]
#[allow(clippy::vec_box)]
pub enum SolidSet {
Solid(Box<Solid>),
Solids(Vec<Box<Solid>>),
}
impl From<Solid> for SolidSet {
fn from(eg: Solid) -> Self {
SolidSet::Solid(Box::new(eg))
}
}
impl From<Box<Solid>> for SolidSet {
fn from(eg: Box<Solid>) -> Self {
SolidSet::Solid(eg)
}
}
impl From<Vec<Solid>> for SolidSet {
fn from(eg: Vec<Solid>) -> Self {
if eg.len() == 1 {
SolidSet::Solid(Box::new(eg[0].clone()))
} else {
SolidSet::Solids(eg.into_iter().map(Box::new).collect())
}
}
}
impl From<Vec<Box<Solid>>> for SolidSet {
fn from(eg: Vec<Box<Solid>>) -> Self {
if eg.len() == 1 {
SolidSet::Solid(eg[0].clone())
} else {
SolidSet::Solids(eg)
}
}
}
impl From<SolidSet> for Vec<Box<Solid>> {
fn from(eg: SolidSet) -> Self {
match eg {
SolidSet::Solid(eg) => vec![eg],
SolidSet::Solids(egs) => egs,
}
}
}
impl From<&Solid> for Vec<Box<Solid>> {
fn from(eg: &Solid) -> Self {
vec![Box::new(eg.clone())]
}
}
impl From<Box<Solid>> for Vec<Box<Solid>> {
fn from(eg: Box<Solid>) -> Self {
vec![eg]
}
}
/// Data for an imported geometry.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
@ -228,17 +84,29 @@ pub struct ImportedGeometry {
#[serde(tag = "type", rename_all = "camelCase")]
#[allow(clippy::vec_box)]
pub enum SolidOrImportedGeometry {
Solid(Box<Solid>),
ImportedGeometry(Box<ImportedGeometry>),
SolidSet(Vec<Box<Solid>>),
SolidSet(Vec<Solid>),
}
impl From<SolidOrImportedGeometry> for crate::execution::KclValue {
fn from(value: SolidOrImportedGeometry) -> Self {
match value {
SolidOrImportedGeometry::Solid(s) => crate::execution::KclValue::Solid { value: s },
SolidOrImportedGeometry::ImportedGeometry(s) => crate::execution::KclValue::ImportedGeometry(*s),
SolidOrImportedGeometry::SolidSet(s) => crate::execution::KclValue::Solids { value: s },
SolidOrImportedGeometry::SolidSet(mut s) => {
if s.len() == 1 {
crate::execution::KclValue::Solid {
value: Box::new(s.pop().unwrap()),
}
} else {
crate::execution::KclValue::HomArray {
value: s
.into_iter()
.map(|s| crate::execution::KclValue::Solid { value: Box::new(s) })
.collect(),
ty: crate::execution::PrimitiveType::Solid,
}
}
}
}
}
}
@ -246,7 +114,6 @@ impl From<SolidOrImportedGeometry> for crate::execution::KclValue {
impl SolidOrImportedGeometry {
pub(crate) fn ids(&self) -> Vec<uuid::Uuid> {
match self {
SolidOrImportedGeometry::Solid(s) => vec![s.id],
SolidOrImportedGeometry::ImportedGeometry(s) => vec![s.id],
SolidOrImportedGeometry::SolidSet(s) => s.iter().map(|s| s.id).collect(),
}

View File

@ -6,13 +6,12 @@ use serde::{Deserialize, Serialize};
use super::{
memory::{self, EnvironmentRef},
MetaSettings,
MetaSettings, Point3d,
};
use crate::{
errors::KclErrorDetails,
execution::{
ExecState, ExecutorContext, Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, SketchSet, Solid, SolidSet,
TagIdentifier,
ExecState, ExecutorContext, Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier,
},
parsing::{
ast::types::{
@ -21,7 +20,10 @@ use crate::{
},
token::NumericSuffix,
},
std::{args::Arg, StdFnProps},
std::{
args::{Arg, FromKclValue},
StdFnProps,
},
CompilationError, KclError, ModuleId, SourceRange,
};
@ -58,6 +60,13 @@ pub enum KclValue {
#[serde(skip)]
meta: Vec<Metadata>,
},
// An array where all values have a shared type (not necessarily the same principal type).
HomArray {
value: Vec<KclValue>,
// The type of values, not the array type.
#[serde(skip)]
ty: PrimitiveType,
},
Object {
value: KclObjectFields,
#[serde(skip)]
@ -74,15 +83,9 @@ pub enum KclValue {
Sketch {
value: Box<Sketch>,
},
Sketches {
value: Vec<Box<Sketch>>,
},
Solid {
value: Box<Solid>,
},
Solids {
value: Vec<Box<Solid>>,
},
Helix {
value: Box<Helix>,
},
@ -139,48 +142,46 @@ impl JsonSchema for FunctionSource {
}
}
impl From<SketchSet> for KclValue {
fn from(sg: SketchSet) -> Self {
match sg {
SketchSet::Sketch(value) => KclValue::Sketch { value },
SketchSet::Sketches(value) => KclValue::Sketches { value },
}
}
}
impl From<Vec<Box<Sketch>>> for KclValue {
fn from(sg: Vec<Box<Sketch>>) -> Self {
KclValue::Sketches { value: sg }
}
}
impl From<SolidSet> for KclValue {
fn from(eg: SolidSet) -> Self {
match eg {
SolidSet::Solid(eg) => KclValue::Solid { value: eg },
SolidSet::Solids(egs) => KclValue::Solids { value: egs },
}
}
}
impl From<Vec<Box<Solid>>> for KclValue {
fn from(eg: Vec<Box<Solid>>) -> Self {
impl From<Vec<Sketch>> for KclValue {
fn from(mut eg: Vec<Sketch>) -> Self {
if eg.len() == 1 {
KclValue::Solid { value: eg[0].clone() }
KclValue::Sketch {
value: Box::new(eg.pop().unwrap()),
}
} else {
KclValue::Solids { value: eg }
KclValue::HomArray {
value: eg
.into_iter()
.map(|s| KclValue::Sketch { value: Box::new(s) })
.collect(),
ty: crate::execution::PrimitiveType::Sketch,
}
}
}
}
impl From<Vec<Solid>> for KclValue {
fn from(mut eg: Vec<Solid>) -> Self {
if eg.len() == 1 {
KclValue::Solid {
value: Box::new(eg.pop().unwrap()),
}
} else {
KclValue::HomArray {
value: eg.into_iter().map(|s| KclValue::Solid { value: Box::new(s) }).collect(),
ty: crate::execution::PrimitiveType::Solid,
}
}
}
}
impl From<KclValue> for Vec<SourceRange> {
fn from(item: KclValue) -> Self {
match item {
KclValue::TagDeclarator(t) => vec![SourceRange::new(t.start, t.end, t.module_id)],
KclValue::TagIdentifier(t) => to_vec_sr(&t.meta),
KclValue::Solid { value } => to_vec_sr(&value.meta),
KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Sketch { value } => to_vec_sr(&value.meta),
KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Helix { value } => to_vec_sr(&value.meta),
KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta),
KclValue::Function { meta, .. } => to_vec_sr(&meta),
@ -190,6 +191,7 @@ impl From<KclValue> for Vec<SourceRange> {
KclValue::Number { meta, .. } => to_vec_sr(&meta),
KclValue::String { meta, .. } => to_vec_sr(&meta),
KclValue::MixedArray { meta, .. } => to_vec_sr(&meta),
KclValue::HomArray { value, .. } => value.iter().flat_map(Into::<Vec<SourceRange>>::into).collect(),
KclValue::Object { meta, .. } => to_vec_sr(&meta),
KclValue::Module { meta, .. } => to_vec_sr(&meta),
KclValue::Uuid { meta, .. } => to_vec_sr(&meta),
@ -209,9 +211,7 @@ impl From<&KclValue> for Vec<SourceRange> {
KclValue::TagDeclarator(t) => vec![SourceRange::new(t.start, t.end, t.module_id)],
KclValue::TagIdentifier(t) => to_vec_sr(&t.meta),
KclValue::Solid { value } => to_vec_sr(&value.meta),
KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Sketch { value } => to_vec_sr(&value.meta),
KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(),
KclValue::Helix { value } => to_vec_sr(&value.meta),
KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta),
KclValue::Function { meta, .. } => to_vec_sr(meta),
@ -222,6 +222,7 @@ impl From<&KclValue> for Vec<SourceRange> {
KclValue::String { meta, .. } => to_vec_sr(meta),
KclValue::Uuid { meta, .. } => to_vec_sr(meta),
KclValue::MixedArray { meta, .. } => to_vec_sr(meta),
KclValue::HomArray { value, .. } => value.iter().flat_map(Into::<Vec<SourceRange>>::into).collect(),
KclValue::Object { meta, .. } => to_vec_sr(meta),
KclValue::Module { meta, .. } => to_vec_sr(meta),
KclValue::KclNone { meta, .. } => to_vec_sr(meta),
@ -245,15 +246,14 @@ impl KclValue {
KclValue::Number { meta, .. } => meta.clone(),
KclValue::String { value: _, meta } => meta.clone(),
KclValue::MixedArray { value: _, meta } => meta.clone(),
KclValue::HomArray { value, .. } => value.iter().flat_map(|v| v.metadata()).collect(),
KclValue::Object { value: _, meta } => meta.clone(),
KclValue::TagIdentifier(x) => x.meta.clone(),
KclValue::TagDeclarator(x) => vec![x.metadata()],
KclValue::Plane { value } => value.meta.clone(),
KclValue::Face { value } => value.meta.clone(),
KclValue::Sketch { value } => value.meta.clone(),
KclValue::Sketches { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(),
KclValue::Solid { value } => value.meta.clone(),
KclValue::Solids { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(),
KclValue::Helix { value } => value.meta.clone(),
KclValue::ImportedGeometry(x) => x.meta.clone(),
KclValue::Function { meta, .. } => meta.clone(),
@ -276,29 +276,6 @@ impl KclValue {
Some(ast.as_source_range())
}
pub(crate) fn get_solid_set(&self) -> Result<SolidSet> {
match self {
KclValue::Solid { value } => Ok(SolidSet::Solid(value.clone())),
KclValue::Solids { value } => Ok(SolidSet::Solids(value.clone())),
KclValue::MixedArray { value, .. } => {
let solids: Vec<_> = value
.iter()
.enumerate()
.map(|(i, v)| {
v.as_solid().map(|v| v.to_owned()).map(Box::new).ok_or_else(|| {
anyhow::anyhow!(
"expected this array to only contain solids, but element {i} was actually {}",
v.human_friendly_type()
)
})
})
.collect::<Result<_, _>>()?;
Ok(SolidSet::Solids(solids))
}
_ => anyhow::bail!("Not a solid or solids: {:?}", self),
}
}
#[allow(unused)]
pub(crate) fn none() -> Self {
Self::KclNone {
@ -315,9 +292,7 @@ impl KclValue {
KclValue::TagDeclarator(_) => "TagDeclarator",
KclValue::TagIdentifier(_) => "TagIdentifier",
KclValue::Solid { .. } => "Solid",
KclValue::Solids { .. } => "Solids",
KclValue::Sketch { .. } => "Sketch",
KclValue::Sketches { .. } => "Sketches",
KclValue::Helix { .. } => "Helix",
KclValue::ImportedGeometry(_) => "ImportedGeometry",
KclValue::Function { .. } => "Function",
@ -327,6 +302,7 @@ impl KclValue {
KclValue::Number { .. } => "number",
KclValue::String { .. } => "string (text)",
KclValue::MixedArray { .. } => "array (list)",
KclValue::HomArray { .. } => "array (list)",
KclValue::Object { .. } => "object",
KclValue::Module { .. } => "module",
KclValue::Type { .. } => "type",
@ -481,6 +457,14 @@ impl KclValue {
}
}
pub fn as_sketch(&self) -> Option<&Sketch> {
if let KclValue::Sketch { value } = self {
Some(value)
} else {
None
}
}
pub fn as_mut_sketch(&mut self) -> Option<&mut Sketch> {
if let KclValue::Sketch { value } = self {
Some(value)
@ -578,6 +562,215 @@ impl KclValue {
self_ty.subtype(ty)
}
/// Coerce `self` to a new value which has `ty` as it's closest supertype.
///
/// If the result is Some, then:
/// - result.principal_type().unwrap().subtype(ty)
///
/// If self.principal_type() == ty then result == self
pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> {
match ty {
RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state),
RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state),
RuntimeType::Tuple(tys) => self.coerce_to_tuple_type(tys, exec_state),
RuntimeType::Union(tys) => self.coerce_to_union_type(tys, exec_state),
RuntimeType::Object(tys) => self.coerce_to_object_type(tys, exec_state),
}
}
fn coerce_to_primitive_type(&self, ty: &PrimitiveType, exec_state: &mut ExecState) -> Option<KclValue> {
let value = match self {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == 1 => &value[0],
_ => self,
};
match ty {
// TODO numeric type coercions
PrimitiveType::Number(_ty) => match value {
KclValue::Number { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::String => match value {
KclValue::String { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Boolean => match value {
KclValue::Bool { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Sketch => match value {
KclValue::Sketch { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Solid => match value {
KclValue::Solid { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Plane => match value {
KclValue::Plane { .. } => Some(value.clone()),
KclValue::Object { value, meta } => {
let origin = value.get("origin").and_then(Point3d::from_kcl_val)?;
let x_axis = value.get("xAxis").and_then(Point3d::from_kcl_val)?;
let y_axis = value.get("yAxis").and_then(Point3d::from_kcl_val)?;
let z_axis = value.get("zAxis").and_then(Point3d::from_kcl_val)?;
let id = exec_state.mod_local.id_generator.next_uuid();
let plane = Plane {
id,
artifact_id: id.into(),
origin,
x_axis,
y_axis,
z_axis,
value: super::PlaneType::Uninit,
// TODO use length unit from origin
units: exec_state.length_unit(),
meta: meta.clone(),
};
Some(KclValue::Plane { value: Box::new(plane) })
}
_ => None,
},
PrimitiveType::ImportedGeometry => match value {
KclValue::ImportedGeometry { .. } => Some(value.clone()),
_ => None,
},
}
}
fn coerce_to_array_type(&self, ty: &PrimitiveType, len: ArrayLen, exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::HomArray { value, ty: aty } => {
// TODO could check types of values individually
if aty != ty {
return None;
}
let value = match len {
ArrayLen::None => value.clone(),
ArrayLen::NonEmpty => {
if value.is_empty() {
return None;
}
value.clone()
}
ArrayLen::Known(n) => {
if n != value.len() {
return None;
}
value[..n].to_vec()
}
};
Some(KclValue::HomArray { value, ty: ty.clone() })
}
KclValue::MixedArray { value, .. } => {
let value = match len {
ArrayLen::None => value.clone(),
ArrayLen::NonEmpty => {
if value.is_empty() {
return None;
}
value.clone()
}
ArrayLen::Known(n) => {
if n != value.len() {
return None;
}
value[..n].to_vec()
}
};
let rt = RuntimeType::Primitive(ty.clone());
let value = value
.iter()
.map(|v| v.coerce(&rt, exec_state))
.collect::<Option<Vec<_>>>()?;
Some(KclValue::HomArray { value, ty: ty.clone() })
}
KclValue::KclNone { .. } if len.satisfied(0) => Some(KclValue::HomArray {
value: Vec::new(),
ty: ty.clone(),
}),
value if len.satisfied(1) => {
if value.has_type(&RuntimeType::Primitive(ty.clone())) {
Some(KclValue::HomArray {
value: vec![value.clone()],
ty: ty.clone(),
})
} else {
None
}
}
_ => None,
}
}
fn coerce_to_tuple_type(&self, tys: &[PrimitiveType], exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => {
if value.len() < tys.len() {
return None;
}
let mut result = Vec::new();
for (i, t) in tys.iter().enumerate() {
result.push(value[i].coerce_to_primitive_type(t, exec_state)?);
}
Some(KclValue::MixedArray {
value: result,
meta: Vec::new(),
})
}
KclValue::KclNone { meta, .. } if tys.is_empty() => Some(KclValue::MixedArray {
value: Vec::new(),
meta: meta.clone(),
}),
value if tys.len() == 1 => {
if value.has_type(&RuntimeType::Primitive(tys[0].clone())) {
Some(KclValue::MixedArray {
value: vec![value.clone()],
meta: Vec::new(),
})
} else {
None
}
}
_ => None,
}
}
fn coerce_to_union_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Option<KclValue> {
for t in tys {
if let Some(v) = self.coerce(t, exec_state) {
return Some(v);
}
}
None
}
fn coerce_to_object_type(&self, tys: &[(String, RuntimeType)], _exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::Object { value, .. } => {
for (s, t) in tys {
// TODO coerce fields
if !value.get(s)?.has_type(t) {
return None;
}
}
// TODO remove non-required fields
Some(self.clone())
}
_ => None,
}
}
pub fn principal_type(&self) -> Option<RuntimeType> {
match self {
KclValue::Bool { .. } => Some(RuntimeType::Primitive(PrimitiveType::Boolean)),
@ -592,18 +785,17 @@ impl KclValue {
}
KclValue::Plane { .. } => Some(RuntimeType::Primitive(PrimitiveType::Plane)),
KclValue::Sketch { .. } => Some(RuntimeType::Primitive(PrimitiveType::Sketch)),
KclValue::Sketches { .. } => Some(RuntimeType::Array(PrimitiveType::Sketch)),
KclValue::Solid { .. } => Some(RuntimeType::Primitive(PrimitiveType::Solid)),
KclValue::Solids { .. } => Some(RuntimeType::Array(PrimitiveType::Solid)),
KclValue::ImportedGeometry(..) => Some(RuntimeType::Primitive(PrimitiveType::ImportedGeometry)),
KclValue::MixedArray { value, .. } => Some(RuntimeType::Tuple(
value
.iter()
.map(|v| v.principal_type().and_then(RuntimeType::primitive))
.collect::<Option<Vec<_>>>()?,
)),
KclValue::HomArray { ty, value, .. } => Some(RuntimeType::Array(ty.clone(), ArrayLen::Known(value.len()))),
KclValue::Face { .. } => None,
KclValue::Helix { .. }
| KclValue::ImportedGeometry(..)
| KclValue::Function { .. }
| KclValue::Module { .. }
| KclValue::TagIdentifier(_)
@ -712,12 +904,11 @@ impl KclValue {
KclValue::TagIdentifier(tag) => Some(format!("${}", tag.value)),
// TODO better Array and Object stringification
KclValue::MixedArray { .. } => Some("[...]".to_owned()),
KclValue::HomArray { .. } => Some("[...]".to_owned()),
KclValue::Object { .. } => Some("{ ... }".to_owned()),
KclValue::Module { .. }
| KclValue::Solid { .. }
| KclValue::Solids { .. }
| KclValue::Sketch { .. }
| KclValue::Sketches { .. }
| KclValue::Helix { .. }
| KclValue::ImportedGeometry(_)
| KclValue::Function { .. }
@ -732,7 +923,8 @@ impl KclValue {
#[derive(Debug, Clone, PartialEq)]
pub enum RuntimeType {
Primitive(PrimitiveType),
Array(PrimitiveType),
Array(PrimitiveType, ArrayLen),
Union(Vec<RuntimeType>),
Tuple(Vec<PrimitiveType>),
Object(Vec<(String, RuntimeType)>),
}
@ -747,7 +939,9 @@ impl RuntimeType {
Type::Primitive(pt) => {
PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(RuntimeType::Primitive)
}
Type::Array(pt) => PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(RuntimeType::Array),
Type::Array(pt) => {
PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(|t| RuntimeType::Array(t, ArrayLen::None))
}
Type::Object { properties } => properties
.into_iter()
.map(|p| {
@ -763,15 +957,37 @@ impl RuntimeType {
})
}
pub fn human_friendly_type(&self) -> String {
match self {
RuntimeType::Primitive(ty) => ty.to_string(),
RuntimeType::Array(ty, ArrayLen::None) => format!("an array of {}", ty.display_multiple()),
RuntimeType::Array(ty, ArrayLen::NonEmpty) => format!("one or more {}", ty.display_multiple()),
RuntimeType::Array(ty, ArrayLen::Known(n)) => format!("an array of {n} {}", ty.display_multiple()),
RuntimeType::Union(tys) => tys
.iter()
.map(Self::human_friendly_type)
.collect::<Vec<_>>()
.join(" or "),
RuntimeType::Tuple(tys) => format!(
"an array with values of types ({})",
tys.iter().map(PrimitiveType::to_string).collect::<Vec<_>>().join(", ")
),
RuntimeType::Object(_) => format!("an object with fields {}", self),
}
}
// Subtype with no coercion, including refining numeric types.
fn subtype(&self, sup: &RuntimeType) -> bool {
use RuntimeType::*;
match (self, sup) {
(Primitive(t1), Primitive(t2)) => t1 == t2,
// TODO arrays could be covariant
(Primitive(t1), Primitive(t2)) | (Array(t1), Array(t2)) => t1 == t2,
(Array(t1, l1), Array(t2, l2)) => t1 == t2 && l1.subtype(*l2),
(Tuple(t1), Tuple(t2)) => t1 == t2,
(Tuple(t1), Array(t2)) => t1.iter().all(|t| t == t2),
(Tuple(t1), Array(t2, l2)) => (l2.satisfied(t1.len())) && t1.iter().all(|t| t == t2),
(Union(ts1), Union(ts2)) => ts1.iter().all(|t| ts2.contains(t)),
(t1, Union(ts2)) => ts2.contains(t1),
// TODO record subtyping - subtype can be larger, fields can be covariant.
(Object(t1), Object(t2)) => t1 == t2,
_ => false,
@ -790,12 +1006,21 @@ impl fmt::Display for RuntimeType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RuntimeType::Primitive(t) => t.fmt(f),
RuntimeType::Array(t) => write!(f, "[{t}]"),
RuntimeType::Array(t, l) => match l {
ArrayLen::None => write!(f, "[{t}]"),
ArrayLen::NonEmpty => write!(f, "[{t}; 1+]"),
ArrayLen::Known(n) => write!(f, "[{t}; {n}]"),
},
RuntimeType::Tuple(ts) => write!(
f,
"[{}]",
ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(", ")
),
RuntimeType::Union(ts) => write!(
f,
"{}",
ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(" | ")
),
RuntimeType::Object(items) => write!(
f,
"{{ {} }}",
@ -809,6 +1034,34 @@ impl fmt::Display for RuntimeType {
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ArrayLen {
None,
NonEmpty,
Known(usize),
}
impl ArrayLen {
pub fn subtype(self, other: ArrayLen) -> bool {
match (self, other) {
(_, ArrayLen::None) => true,
(ArrayLen::NonEmpty, ArrayLen::NonEmpty) => true,
(ArrayLen::Known(size), ArrayLen::NonEmpty) if size > 0 => true,
(ArrayLen::Known(s1), ArrayLen::Known(s2)) if s1 == s2 => true,
_ => false,
}
}
/// True if the length constraint is satisfied by the supplied length.
fn satisfied(self, len: usize) -> bool {
match self {
ArrayLen::None => true,
ArrayLen::NonEmpty => len > 0,
ArrayLen::Known(s) => len == s,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum PrimitiveType {
Number(NumericType),
@ -817,6 +1070,7 @@ pub enum PrimitiveType {
Sketch,
Solid,
Plane,
ImportedGeometry,
}
impl PrimitiveType {
@ -848,6 +1102,19 @@ impl PrimitiveType {
_ => None,
})
}
fn display_multiple(&self) -> String {
match self {
PrimitiveType::Number(NumericType::Known(unit)) => format!("numbers({unit})"),
PrimitiveType::Number(_) => "numbers".to_owned(),
PrimitiveType::String => "strings".to_owned(),
PrimitiveType::Boolean => "bools".to_owned(),
PrimitiveType::Sketch => "Sketches".to_owned(),
PrimitiveType::Solid => "Solids".to_owned(),
PrimitiveType::Plane => "Planes".to_owned(),
PrimitiveType::ImportedGeometry => "imported geometries".to_owned(),
}
}
}
impl fmt::Display for PrimitiveType {
@ -860,6 +1127,7 @@ impl fmt::Display for PrimitiveType {
PrimitiveType::Sketch => write!(f, "Sketch"),
PrimitiveType::Solid => write!(f, "Solid"),
PrimitiveType::Plane => write!(f, "Plane"),
PrimitiveType::ImportedGeometry => write!(f, "imported geometry"),
}
}
}

View File

@ -1879,15 +1879,6 @@ let w = f() + f()
parse_execute(ast).await.unwrap();
}
#[test]
fn test_serialize_memory_item() {
let mem = KclValue::Solids {
value: Default::default(),
};
let json = serde_json::to_string(&mem).unwrap();
assert_eq!(json, r#"{"type":"Solids","value":[]}"#);
}
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_ids_stable_between_executions() {
let code = r#"sketch001 = startSketchOn(XZ)

View File

@ -1170,7 +1170,7 @@ impl LanguageServer for Backend {
Hover::Variable { name, ty: None, range } => Ok(with_cached_var(&name, |value| {
let mut text: String = format!("```\n{}", name);
if let Some(ty) = value.principal_type() {
text.push_str(&format!(": {}", ty));
text.push_str(&format!(": {}", ty.human_friendly_type()));
}
if let Some(v) = value.value_str() {
text.push_str(&format!(" = {}", v));

View File

@ -2937,7 +2937,7 @@ impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Type::Primitive(primitive_type) => primitive_type.fmt(f),
Type::Array(primitive_type) => write!(f, "{primitive_type}[]"),
Type::Array(primitive_type) => write!(f, "[{primitive_type}]"),
Type::Object { properties } => {
write!(f, "{{")?;
let mut first = true;
@ -3509,7 +3509,7 @@ const cylinder = startSketchOn('-XZ')
#[tokio::test(flavor = "multi_thread")]
async fn test_parse_type_args_array_on_functions() {
let some_program_string = r#"fn thing = (arg0: number[], arg1: string[], tag?: string) => {
let some_program_string = r#"fn thing = (arg0: [number], arg1: [string], tag?: string) => {
return arg0
}"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
@ -3540,7 +3540,7 @@ const cylinder = startSketchOn('-XZ')
#[tokio::test(flavor = "multi_thread")]
async fn test_parse_type_args_object_on_functions() {
let some_program_string = r#"fn thing = (arg0: number[], arg1: {thing: number, things: string[], more?: string}, tag?: string) => {
let some_program_string = r#"fn thing = (arg0: [number], arg1: {thing: number, things: [string], more?: string}, tag?: string) => {
return arg0
}"#;
let module_id = ModuleId::default();
@ -3594,7 +3594,7 @@ const cylinder = startSketchOn('-XZ')
56,
module_id,
),
type_: Some(Node::new(Type::Array(PrimitiveType::String), 58, 64, module_id)),
type_: Some(Node::new(Type::Array(PrimitiveType::String), 59, 65, module_id)),
default_value: None,
labeled: true,
digest: None
@ -3625,7 +3625,7 @@ const cylinder = startSketchOn('-XZ')
#[tokio::test(flavor = "multi_thread")]
async fn test_parse_return_type_on_functions() {
let some_program_string = r#"fn thing(): {thing: number, things: string[], more?: string} {
let some_program_string = r#"fn thing(): {thing: number, things: [string], more?: string} {
return 1
}"#;
let module_id = ModuleId::default();
@ -3675,7 +3675,7 @@ const cylinder = startSketchOn('-XZ')
34,
module_id,
),
type_: Some(Node::new(Type::Array(PrimitiveType::String), 36, 42, module_id)),
type_: Some(Node::new(Type::Array(PrimitiveType::String), 37, 43, module_id)),
default_value: None,
labeled: true,
digest: None

View File

@ -2651,7 +2651,7 @@ fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> {
))
}),
// Array types
(primitive_type, open_bracket, close_bracket).map(|(t, _, _)| Ok(t.map(Type::Array))),
(open_bracket, primitive_type, close_bracket).map(|(_, t, _)| Ok(t.map(Type::Array))),
// Primitive types
primitive_type.map(|t| Ok(t.map(Type::Primitive))),
))

View File

@ -12,7 +12,10 @@ use validator::Validate;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Solid, SolidSet},
execution::{
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Solid,
},
std::Args,
};
@ -38,8 +41,12 @@ struct AppearanceData {
}
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let color: String = args.get_kw_arg("color")?;
let metalness: Option<f64> = args.get_kw_arg_opt("metalness")?;
@ -66,7 +73,7 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
}));
}
let result = inner_appearance(solid_set, data.color, data.metalness, data.roughness, args).await?;
let result = inner_appearance(solids, data.color, data.metalness, data.roughness, args).await?;
Ok(result.into())
}
@ -276,21 +283,19 @@ pub async fn appearance(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "The solid(s) whose appearance is being set" },
solids = { docs = "The solid(s) whose appearance is being set" },
color = { docs = "Color of the new material, a hex string like '#ff0000'"},
metalness = { docs = "Metalness of the new material, a percentage like 95.7." },
roughness = { docs = "Roughness of the new material, a percentage like 95.7." },
}
}]
async fn inner_appearance(
solid_set: SolidSet,
solids: Vec<Solid>,
color: String,
metalness: Option<f64>,
roughness: Option<f64>,
args: Args,
) -> Result<SolidSet, KclError> {
let solids: Vec<Box<Solid>> = solid_set.into();
) -> Result<Vec<Solid>, KclError> {
for solid in &solids {
// Set the material properties.
let rgb = rgba_simple::RGB::<f32>::from_hex(&color).map_err(|err| {
@ -323,5 +328,5 @@ async fn inner_appearance(
// I can't think of a use case for it.
}
Ok(SolidSet::from(solids))
Ok(solids)
}

View File

@ -12,9 +12,9 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
kcl_value::{FunctionSource, NumericType},
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSet,
SketchSurface, Solid, SolidSet, TagIdentifier,
kcl_value::{ArrayLen, FunctionSource, NumericType, RuntimeType},
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, PrimitiveType, Sketch,
SketchSurface, Solid, TagIdentifier,
},
parsing::ast::types::TagNode,
source_range::SourceRange,
@ -233,9 +233,41 @@ impl Args {
T::from_kcl_val(&arg.value).ok_or_else(|| {
let expected_type_name = tynm::type_name::<T>();
let actual_type_name = arg.value.human_friendly_type();
let msg_base = format!("This function expected the input argument to be of type {expected_type_name} but it's actually of type {actual_type_name}");
let suggestion = match (expected_type_name.as_str(), actual_type_name) {
("SolidSet", "Sketch") => Some(
let message = format!("This function expected the input argument to be of type {expected_type_name} but it's actually of type {actual_type_name}");
KclError::Semantic(KclErrorDetails {
source_ranges: arg.source_ranges(),
message,
})
})
}
/// Get the unlabeled keyword argument. If not set, returns Err. If it
/// can't be converted to the given type, returns Err.
pub(crate) fn get_unlabeled_kw_arg_typed<T>(
&self,
label: &str,
ty: &RuntimeType,
exec_state: &mut ExecState,
) -> Result<T, KclError>
where
T: for<'a> FromKclValue<'a>,
{
let arg = self
.unlabeled_kw_arg_unconverted()
.ok_or(KclError::Semantic(KclErrorDetails {
source_ranges: vec![self.source_range],
message: format!("This function requires a value for the special unlabeled first parameter, '{label}'"),
}))?;
let arg = arg.value.coerce(ty, exec_state).ok_or_else(|| {
let actual_type_name = arg.value.human_friendly_type();
let msg_base = format!(
"This function expected the input argument to be {} but it's actually of type {actual_type_name}",
ty.human_friendly_type(),
);
let suggestion = match (ty, actual_type_name) {
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch")
| (RuntimeType::Array(PrimitiveType::Solid, _), "Sketch") => Some(
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
),
_ => None,
@ -248,7 +280,10 @@ impl Args {
source_ranges: arg.source_ranges(),
message,
})
})
})?;
// TODO unnecessary cloning
Ok(T::from_kcl_val(&arg).unwrap())
}
// Add a modeling command to the batch but don't fire it right away.
@ -338,10 +373,10 @@ impl Args {
/// Flush just the fillets and chamfers for this specific SolidSet.
#[allow(clippy::vec_box)]
pub(crate) async fn flush_batch_for_solid_set(
pub(crate) async fn flush_batch_for_solids(
&self,
exec_state: &mut ExecState,
solids: Vec<Box<Solid>>,
solids: Vec<Solid>,
) -> Result<(), KclError> {
// Make sure we don't traverse sketches more than once.
let mut traversed_sketches = Vec::new();
@ -510,12 +545,48 @@ impl Args {
Ok((a.n, b.n, ty))
}
pub(crate) fn get_sketches(&self) -> Result<(SketchSet, Sketch), KclError> {
FromArgs::from_args(self, 0)
pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> {
let sarg = self.args[0]
.value
.coerce(&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::None), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected an array of sketches, found {}",
self.args[0].value.human_friendly_type()
),
source_ranges: vec![self.source_range],
}))?;
let sketches = match sarg {
KclValue::HomArray { value, .. } => value.iter().map(|v| v.as_sketch().unwrap().clone()).collect(),
_ => unreachable!(),
};
let sarg = self.args[1]
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!("Expected a sketch, found {}", self.args[1].value.human_friendly_type()),
source_ranges: vec![self.source_range],
}))?;
let sketch = match sarg {
KclValue::Sketch { value } => *value,
_ => unreachable!(),
};
Ok((sketches, sketch))
}
pub(crate) fn get_sketch(&self) -> Result<Sketch, KclError> {
FromArgs::from_args(self, 0)
pub(crate) fn get_sketch(&self, exec_state: &mut ExecState) -> Result<Sketch, KclError> {
let sarg = self.args[0]
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!("Expected a sketch, found {}", self.args[0].value.human_friendly_type()),
source_ranges: vec![self.source_range],
}))?;
match sarg {
KclValue::Sketch { value } => Ok(*value),
_ => unreachable!(),
}
}
pub(crate) fn get_data<'a, T>(&'a self) -> Result<T, KclError>
@ -536,18 +607,55 @@ impl Args {
FromArgs::from_args(self, 0)
}
pub(crate) fn get_data_and_sketch_set<'a, T>(&'a self) -> Result<(T, SketchSet), KclError>
pub(crate) fn get_data_and_sketches<'a, T>(
&'a self,
exec_state: &mut ExecState,
) -> Result<(T, Vec<Sketch>), KclError>
where
T: serde::de::DeserializeOwned + FromArgs<'a>,
{
FromArgs::from_args(self, 0)
let data: T = FromArgs::from_args(self, 0)?;
let sarg = self.args[1]
.value
.coerce(&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::None), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected an array of sketches for second argument, found {}",
self.args[1].value.human_friendly_type()
),
source_ranges: vec![self.source_range],
}))?;
let sketches = match sarg {
KclValue::HomArray { value, .. } => value.iter().map(|v| v.as_sketch().unwrap().clone()).collect(),
_ => unreachable!(),
};
Ok((data, sketches))
}
pub(crate) fn get_data_and_sketch_and_tag<'a, T>(&'a self) -> Result<(T, Sketch, Option<TagNode>), KclError>
pub(crate) fn get_data_and_sketch_and_tag<'a, T>(
&'a self,
exec_state: &mut ExecState,
) -> Result<(T, Sketch, Option<TagNode>), KclError>
where
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
{
FromArgs::from_args(self, 0)
let data: T = FromArgs::from_args(self, 0)?;
let sarg = self.args[1]
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected a sketch for second argument, found {}",
self.args[1].value.human_friendly_type()
),
source_ranges: vec![self.source_range],
}))?;
let sketch = match sarg {
KclValue::Sketch { value } => *value,
_ => unreachable!(),
};
let tag: Option<TagNode> = FromArgs::from_args(self, 2)?;
Ok((data, sketch, tag))
}
pub(crate) fn get_data_and_sketch_surface<'a, T>(&'a self) -> Result<(T, SketchSurface, Option<TagNode>), KclError>
@ -557,11 +665,26 @@ impl Args {
FromArgs::from_args(self, 0)
}
pub(crate) fn get_data_and_solid<'a, T>(&'a self) -> Result<(T, Box<Solid>), KclError>
pub(crate) fn get_data_and_solid<'a, T>(&'a self, exec_state: &mut ExecState) -> Result<(T, Box<Solid>), KclError>
where
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
{
FromArgs::from_args(self, 0)
let data: T = FromArgs::from_args(self, 0)?;
let sarg = self.args[1]
.value
.coerce(&RuntimeType::Primitive(PrimitiveType::Solid), exec_state)
.ok_or(KclError::Type(KclErrorDetails {
message: format!(
"Expected a solid for second argument, found {}",
self.args[1].value.human_friendly_type()
),
source_ranges: vec![self.source_range],
}))?;
let solid = match sarg {
KclValue::Solid { value } => value,
_ => unreachable!(),
};
Ok((data, solid))
}
pub(crate) fn get_tag_to_number_sketch(&self) -> Result<(TagIdentifier, f64, Sketch), KclError> {
@ -1304,7 +1427,6 @@ impl_from_kcl_for_vec!(crate::execution::EdgeCut);
impl_from_kcl_for_vec!(crate::execution::Metadata);
impl_from_kcl_for_vec!(super::fillet::EdgeReference);
impl_from_kcl_for_vec!(ExtrudeSurface);
impl_from_kcl_for_vec!(Sketch);
impl<'a> FromKclValue<'a> for SourceRange {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
@ -1340,8 +1462,10 @@ impl<'a> FromKclValue<'a> for crate::execution::Solid {
impl<'a> FromKclValue<'a> for crate::execution::SolidOrImportedGeometry {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
match arg {
KclValue::Solid { value } => Some(Self::Solid(value.clone())),
KclValue::Solids { value } => Some(Self::SolidSet(value.clone())),
KclValue::Solid { value } => Some(Self::SolidSet(vec![(**value).clone()])),
KclValue::HomArray { value, .. } => Some(Self::SolidSet(
value.iter().map(|v| v.as_solid().unwrap().clone()).collect(),
)),
KclValue::ImportedGeometry(value) => Some(Self::ImportedGeometry(Box::new(value.clone()))),
_ => None,
}
@ -1354,11 +1478,13 @@ impl<'a> FromKclValue<'a> for super::sketch::SketchData {
let case1 = crate::execution::Plane::from_kcl_val;
let case2 = super::sketch::PlaneData::from_kcl_val;
let case3 = crate::execution::Solid::from_kcl_val;
let case4 = <Vec<Solid>>::from_kcl_val;
case1(arg)
.map(Box::new)
.map(Self::Plane)
.or_else(|| case2(arg).map(Self::PlaneOrientation))
.or_else(|| case3(arg).map(Box::new).map(Self::Solid))
.or_else(|| case4(arg).map(|v| Box::new(v[0].clone())).map(Self::Solid))
}
}
@ -1531,6 +1657,7 @@ impl<'a> FromKclValue<'a> for TyF64 {
}
}
}
impl<'a> FromKclValue<'a> for Sketch {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::Sketch { value } = arg else {
@ -1548,13 +1675,16 @@ impl<'a> FromKclValue<'a> for Helix {
Some(value.as_ref().to_owned())
}
}
impl<'a> FromKclValue<'a> for SweepPath {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let case1 = Sketch::from_kcl_val;
let case2 = Helix::from_kcl_val;
let case2 = <Vec<Sketch>>::from_kcl_val;
let case3 = Helix::from_kcl_val;
case1(arg)
.map(Self::Sketch)
.or_else(|| case2(arg).map(|arg0: Helix| Self::Helix(Box::new(arg0))))
.or_else(|| case2(arg).map(|arg0: Vec<Sketch>| Self::Sketch(arg0[0].clone())))
.or_else(|| case3(arg).map(|arg0: Helix| Self::Helix(Box::new(arg0))))
}
}
impl<'a> FromKclValue<'a> for String {
@ -1582,20 +1712,6 @@ impl<'a> FromKclValue<'a> for bool {
}
}
impl<'a> FromKclValue<'a> for SketchSet {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
match arg {
KclValue::Sketch { value: sketch } => Some(SketchSet::from(sketch.to_owned())),
KclValue::Sketches { value } => Some(SketchSet::from(value.to_owned())),
KclValue::MixedArray { .. } => {
let v: Option<Vec<Sketch>> = FromKclValue::from_kcl_val(arg);
Some(SketchSet::Sketches(v?.iter().cloned().map(Box::new).collect()))
}
_ => None,
}
}
}
impl<'a> FromKclValue<'a> for Box<Solid> {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::Solid { value } = arg else {
@ -1605,15 +1721,27 @@ impl<'a> FromKclValue<'a> for Box<Solid> {
}
}
impl<'a> FromKclValue<'a> for &'a FunctionSource {
impl<'a> FromKclValue<'a> for Vec<Solid> {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
arg.get_function()
let KclValue::HomArray { value, .. } = arg else {
return None;
};
value.iter().map(Solid::from_kcl_val).collect()
}
}
impl<'a> FromKclValue<'a> for SolidSet {
impl<'a> FromKclValue<'a> for Vec<Sketch> {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
arg.get_solid_set().ok()
let KclValue::HomArray { value, .. } = arg else {
return None;
};
value.iter().map(Sketch::from_kcl_val).collect()
}
}
impl<'a> FromKclValue<'a> for &'a FunctionSource {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
arg.get_function()
}
}

View File

@ -7,7 +7,10 @@ use kittycad_modeling_cmds as kcmc;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid},
execution::{
kcl_value::RuntimeType, ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, PrimitiveType,
Solid,
},
parsing::ast::types::TagNode,
std::{fillet::EdgeReference, Args},
};
@ -16,7 +19,7 @@ pub(crate) const DEFAULT_TOLERANCE: f64 = 0.0000001;
/// Create chamfers on tagged paths.
pub async fn chamfer(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid = args.get_unlabeled_kw_arg("solid")?;
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::Primitive(PrimitiveType::Solid), exec_state)?;
let length = args.get_kw_arg("length")?;
let tags = args.kw_arg_array_and_source::<EdgeReference>("tags")?;
let tag = args.get_kw_arg_opt("tag")?;

View File

@ -19,18 +19,22 @@ use uuid::Uuid;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, Path, Sketch, SketchSet, SketchSurface, Solid,
SolidSet,
kcl_value::{ArrayLen, RuntimeType},
ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, Path, PrimitiveType, Sketch, SketchSurface, Solid,
},
std::Args,
};
/// Extrudes by a given amount.
pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_set = args.get_unlabeled_kw_arg("sketch_set")?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let length = args.get_kw_arg("length")?;
let result = inner_extrude(sketch_set, length, exec_state, args).await?;
let result = inner_extrude(sketches, length, exec_state, args).await?;
Ok(result.into())
}
@ -90,18 +94,17 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "Which sketch or set of sketches should be extruded"},
sketches = { docs = "Which sketch or sketches should be extruded"},
length = { docs = "How far to extrude the given sketches"},
}
}]
async fn inner_extrude(
sketch_set: SketchSet,
sketches: Vec<Sketch>,
length: f64,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidSet, KclError> {
) -> Result<Vec<Solid>, KclError> {
// Extrude the element(s).
let sketches: Vec<Sketch> = sketch_set.into();
let mut solids = Vec::new();
for sketch in &sketches {
let id = exec_state.next_uuid();
@ -121,7 +124,7 @@ async fn inner_extrude(
solids.push(do_post_extrude(sketch.clone(), id.into(), length, exec_state, args.clone()).await?);
}
Ok(solids.into())
Ok(solids)
}
pub(crate) async fn do_post_extrude(
@ -130,7 +133,7 @@ pub(crate) async fn do_post_extrude(
length: f64,
exec_state: &mut ExecState,
args: Args,
) -> Result<Box<Solid>, KclError> {
) -> Result<Solid, KclError> {
// Bring the object to the front of the scene.
// See: https://github.com/KittyCAD/modeling-app/issues/806
args.batch_modeling_cmd(
@ -269,7 +272,7 @@ pub(crate) async fn do_post_extrude(
})
.collect();
Ok(Box::new(Solid {
Ok(Solid {
// Ok so you would think that the id would be the id of the solid,
// that we passed in to the function, but it's actually the id of the
// sketch.
@ -283,7 +286,7 @@ pub(crate) async fn do_post_extrude(
start_cap_id,
end_cap_id,
edge_cuts: vec![],
}))
})
}
#[derive(Default)]

View File

@ -14,7 +14,10 @@ use uuid::Uuid;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier},
execution::{
kcl_value::RuntimeType, EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, PrimitiveType,
Solid, TagIdentifier,
},
parsing::ast::types::TagNode,
settings::types::UnitLength,
std::Args,
@ -64,8 +67,7 @@ pub(super) fn validate_unique<T: Eq + std::hash::Hash>(tags: &[(T, SourceRange)]
/// Create fillets on tagged paths.
pub async fn fillet(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
// Get all args:
let solid = args.get_unlabeled_kw_arg("solid")?;
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::Primitive(PrimitiveType::Solid), exec_state)?;
let radius = args.get_kw_arg("radius")?;
let tolerance = args.get_kw_arg_opt("tolerance")?;
let tags = args.kw_arg_array_and_source::<EdgeReference>("tags")?;

View File

@ -196,7 +196,7 @@ pub struct HelixRevolutionsData {
/// Create a helix on a cylinder.
pub async fn helix_revolutions(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, solid): (HelixRevolutionsData, Box<Solid>) = args.get_data_and_solid()?;
let (data, solid): (HelixRevolutionsData, Box<Solid>) = args.get_data_and_solid(exec_state)?;
let value = inner_helix_revolutions(data, solid, exec_state, args).await?;
Ok(KclValue::Solid { value })

View File

@ -9,7 +9,10 @@ use kittycad_modeling_cmds as kcmc;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Sketch, Solid},
execution::{
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Sketch, Solid,
},
std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
};
@ -17,7 +20,11 @@ const DEFAULT_V_DEGREE: u32 = 2;
/// Create a 3D surface or solid by interpolating between two or more sketches.
pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg("sketches")?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let v_degree: NonZeroU32 = args
.get_kw_arg_opt("vDegree")?
.unwrap_or(NonZeroU32::new(DEFAULT_V_DEGREE).unwrap());
@ -159,5 +166,7 @@ async fn inner_loft(
let mut sketch = sketches[0].clone();
// Override its id with the loft id so we can get its faces later
sketch.id = id;
do_post_extrude(sketch, id.into(), 0.0, exec_state, args).await
Ok(Box::new(
do_post_extrude(sketch, id.into(), 0.0, exec_state, args).await?,
))
}

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, KclValue, Sketch, SketchSet},
execution::{ExecState, KclValue, Sketch},
std::{axis_or_reference::Axis2dOrEdgeReference, Args},
};
@ -26,7 +26,7 @@ pub struct Mirror2dData {
///
/// Only works on unclosed sketches for now.
pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch_set): (Mirror2dData, SketchSet) = args.get_data_and_sketch_set()?;
let (data, sketch_set): (Mirror2dData, Vec<Sketch>) = args.get_data_and_sketches(exec_state)?;
let sketches = inner_mirror_2d(data, sketch_set, exec_state, args).await?;
Ok(sketches.into())
@ -103,14 +103,11 @@ pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValu
}]
async fn inner_mirror_2d(
data: Mirror2dData,
sketch_set: SketchSet,
sketches: Vec<Sketch>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
let starting_sketches = match sketch_set {
SketchSet::Sketch(sketch) => vec![sketch],
SketchSet::Sketches(sketches) => sketches,
};
) -> Result<Vec<Sketch>, KclError> {
let starting_sketches = sketches;
if args.ctx.no_engine_commands().await {
return Ok(starting_sketches);

View File

@ -20,9 +20,8 @@ use super::args::Arg;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
kcl_value::{FunctionSource, NumericType},
ExecState, Geometries, Geometry, KclObjectFields, KclValue, Point2d, Point3d, Sketch, SketchSet, Solid,
SolidSet,
kcl_value::{ArrayLen, FunctionSource, NumericType, RuntimeType},
ExecState, Geometries, Geometry, KclObjectFields, KclValue, Point2d, Point3d, PrimitiveType, Sketch, Solid,
},
std::Args,
ExecutorContext, SourceRange,
@ -48,25 +47,32 @@ pub struct LinearPattern3dData {
/// Repeat some 3D solid, changing each repetition slightly.
pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set = args.get_unlabeled_kw_arg("solidSet")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?;
let transform: &FunctionSource = args.get_kw_arg("transform")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let solids = inner_pattern_transform(solid_set, instances, transform, use_original, exec_state, &args).await?;
Ok(KclValue::Solids { value: solids })
let solids = inner_pattern_transform(solids, instances, transform, use_original, exec_state, &args).await?;
Ok(solids.into())
}
/// Repeat some 2D sketch, changing each repetition slightly.
pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_set = args.get_unlabeled_kw_arg("sketchSet")?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?;
let transform: &FunctionSource = args.get_kw_arg("transform")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let sketches =
inner_pattern_transform_2d(sketch_set, instances, transform, use_original, exec_state, &args).await?;
Ok(KclValue::Sketches { value: sketches })
let sketches = inner_pattern_transform_2d(sketches, instances, transform, use_original, exec_state, &args).await?;
Ok(sketches.into())
}
/// Repeat a 3-dimensional solid, changing it each time.
@ -258,20 +264,20 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "The solid(s) to duplicate" },
solids = { docs = "The solid(s) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
transform = { docs = "How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples." },
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
}
}]
async fn inner_pattern_transform<'a>(
solid_set: SolidSet,
solids: Vec<Solid>,
instances: u32,
transform: &'a FunctionSource,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
) -> Result<Vec<Box<Solid>>, KclError> {
) -> Result<Vec<Solid>, KclError> {
// Build the vec of transforms, one for each repetition.
let mut transform_vec = Vec::with_capacity(usize::try_from(instances).unwrap());
if instances < 1 {
@ -281,12 +287,12 @@ async fn inner_pattern_transform<'a>(
}));
}
for i in 1..instances {
let t = make_transform::<Box<Solid>>(i, transform, args.source_range, exec_state, &args.ctx).await?;
let t = make_transform::<Solid>(i, transform, args.source_range, exec_state, &args.ctx).await?;
transform_vec.push(t);
}
execute_pattern_transform(
transform_vec,
solid_set,
solids,
use_original.unwrap_or_default(),
exec_state,
args,
@ -311,20 +317,20 @@ async fn inner_pattern_transform<'a>(
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "The sketch(es) to duplicate" },
sketches = { docs = "The sketch(es) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
transform = { docs = "How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples." },
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
}
}]
async fn inner_pattern_transform_2d<'a>(
sketch_set: SketchSet,
sketches: Vec<Sketch>,
instances: u32,
transform: &'a FunctionSource,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
) -> Result<Vec<Sketch>, KclError> {
// Build the vec of transforms, one for each repetition.
let mut transform_vec = Vec::with_capacity(usize::try_from(instances).unwrap());
if instances < 1 {
@ -334,12 +340,12 @@ async fn inner_pattern_transform_2d<'a>(
}));
}
for i in 1..instances {
let t = make_transform::<Box<Sketch>>(i, transform, args.source_range, exec_state, &args.ctx).await?;
let t = make_transform::<Sketch>(i, transform, args.source_range, exec_state, &args.ctx).await?;
transform_vec.push(t);
}
execute_pattern_transform(
transform_vec,
sketch_set,
sketches,
use_original.unwrap_or_default(),
exec_state,
args,
@ -611,8 +617,8 @@ trait GeometryTrait: Clone {
async fn flush_batch(args: &Args, exec_state: &mut ExecState, set: Self::Set) -> Result<(), KclError>;
}
impl GeometryTrait for Box<Sketch> {
type Set = SketchSet;
impl GeometryTrait for Sketch {
type Set = Vec<Sketch>;
fn set_id(&mut self, id: Uuid) {
self.id = id;
}
@ -632,8 +638,8 @@ impl GeometryTrait for Box<Sketch> {
}
}
impl GeometryTrait for Box<Solid> {
type Set = SolidSet;
impl GeometryTrait for Solid {
type Set = Vec<Solid>;
fn set_id(&mut self, id: Uuid) {
self.id = id;
}
@ -651,7 +657,7 @@ impl GeometryTrait for Box<Solid> {
}
async fn flush_batch(args: &Args, exec_state: &mut ExecState, solid_set: Self::Set) -> Result<(), KclError> {
args.flush_batch_for_solid_set(exec_state, solid_set.into()).await
args.flush_batch_for_solids(exec_state, solid_set).await
}
}
@ -690,7 +696,11 @@ mod tests {
/// A linear pattern on a 2D sketch.
pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_set: SketchSet = args.get_unlabeled_kw_arg("sketchSet")?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?;
let distance: f64 = args.get_kw_arg("distance")?;
let axis: [f64; 2] = args.get_kw_arg("axis")?;
@ -705,8 +715,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
}));
}
let sketches =
inner_pattern_linear_2d(sketch_set, instances, distance, axis, use_original, exec_state, args).await?;
let sketches = inner_pattern_linear_2d(sketches, instances, distance, axis, use_original, exec_state, args).await?;
Ok(sketches.into())
}
@ -729,7 +738,7 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "The sketch(es) to duplicate" },
sketches = { docs = "The sketch(es) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
distance = { docs = "Distance between each repetition. Also known as 'spacing'."},
axis = { docs = "The axis of the pattern. A 2D vector." },
@ -737,14 +746,14 @@ pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result
}
}]
async fn inner_pattern_linear_2d(
sketch_set: SketchSet,
sketches: Vec<Sketch>,
instances: u32,
distance: f64,
axis: [f64; 2],
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
) -> Result<Vec<Sketch>, KclError> {
let [x, y] = axis;
let axis_len = f64::sqrt(x * x + y * y);
let normalized_axis = kcmc::shared::Point2d::from([x / axis_len, y / axis_len]);
@ -760,7 +769,7 @@ async fn inner_pattern_linear_2d(
.collect();
execute_pattern_transform(
transforms,
sketch_set,
sketches,
use_original.unwrap_or_default(),
exec_state,
&args,
@ -770,7 +779,11 @@ async fn inner_pattern_linear_2d(
/// A linear pattern on a 3D model.
pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?;
let distance: f64 = args.get_kw_arg("distance")?;
let axis: [f64; 3] = args.get_kw_arg("axis")?;
@ -785,7 +798,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
}));
}
let solids = inner_pattern_linear_3d(solid_set, instances, distance, axis, use_original, exec_state, args).await?;
let solids = inner_pattern_linear_3d(solids, instances, distance, axis, use_original, exec_state, args).await?;
Ok(solids.into())
}
@ -866,7 +879,7 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "The solid(s) to duplicate" },
solids = { docs = "The solid(s) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
distance = { docs = "Distance between each repetition. Also known as 'spacing'."},
axis = { docs = "The axis of the pattern. A 2D vector." },
@ -874,14 +887,14 @@ pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result
}
}]
async fn inner_pattern_linear_3d(
solid_set: SolidSet,
solids: Vec<Solid>,
instances: u32,
distance: f64,
axis: [f64; 3],
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Solid>>, KclError> {
) -> Result<Vec<Solid>, KclError> {
let [x, y, z] = axis;
let axis_len = f64::sqrt(x * x + y * y + z * z);
let normalized_axis = kcmc::shared::Point3d::from([x / axis_len, y / axis_len, z / axis_len]);
@ -895,14 +908,7 @@ async fn inner_pattern_linear_3d(
}]
})
.collect();
execute_pattern_transform(
transforms,
solid_set,
use_original.unwrap_or_default(),
exec_state,
&args,
)
.await
execute_pattern_transform(transforms, solids, use_original.unwrap_or_default(), exec_state, &args).await
}
/// Data for a circular pattern on a 2D sketch.
@ -1022,7 +1028,11 @@ impl CircularPattern {
/// A circular pattern on a 2D sketch.
pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_set: SketchSet = args.get_unlabeled_kw_arg("sketchSet")?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?;
let center: [f64; 2] = args.get_kw_arg("center")?;
let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?;
@ -1030,7 +1040,7 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let sketches = inner_pattern_circular_2d(
sketch_set,
sketches,
instances,
center,
arc_degrees,
@ -1079,7 +1089,7 @@ pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Resu
}]
#[allow(clippy::too_many_arguments)]
async fn inner_pattern_circular_2d(
sketch_set: SketchSet,
sketch_set: Vec<Sketch>,
instances: u32,
center: [f64; 2],
arc_degrees: f64,
@ -1087,8 +1097,8 @@ async fn inner_pattern_circular_2d(
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
let starting_sketches: Vec<Box<Sketch>> = sketch_set.into();
) -> Result<Vec<Sketch>, KclError> {
let starting_sketches = sketch_set;
if args.ctx.context_type == crate::execution::ContextType::Mock {
return Ok(starting_sketches);
@ -1126,7 +1136,11 @@ async fn inner_pattern_circular_2d(
/// A circular pattern on a 3D model.
pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set: SolidSet = args.get_unlabeled_kw_arg("solidSet")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
// The number of total instances. Must be greater than or equal to 1.
// This includes the original entity. For example, if instances is 2,
// there will be two copies -- the original, and one new copy.
@ -1145,7 +1159,7 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let solids = inner_pattern_circular_3d(
solid_set,
solids,
instances,
axis,
center,
@ -1183,7 +1197,7 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "Which solid(s) to pattern" },
solids = { docs = "Which solid(s) to pattern" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect."},
axis = { docs = "The axis around which to make the pattern. This is a 3D vector"},
center = { docs = "The center about which to make the pattern. This is a 3D vector."},
@ -1194,7 +1208,7 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
}]
#[allow(clippy::too_many_arguments)]
async fn inner_pattern_circular_3d(
solid_set: SolidSet,
solids: Vec<Solid>,
instances: u32,
axis: [f64; 3],
center: [f64; 3],
@ -1203,14 +1217,13 @@ async fn inner_pattern_circular_3d(
use_original: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Box<Solid>>, KclError> {
) -> Result<Vec<Solid>, KclError> {
// Flush the batch for our fillets/chamfers if there are any.
// If we do not flush these, then you won't be able to pattern something with fillets.
// Flush just the fillets/chamfers that apply to these solids.
args.flush_batch_for_solid_set(exec_state, solid_set.clone().into())
.await?;
args.flush_batch_for_solids(exec_state, solids.clone()).await?;
let starting_solids: Vec<Box<Solid>> = solid_set.into();
let starting_solids = solids;
if args.ctx.context_type == crate::execution::ContextType::Mock {
return Ok(starting_solids);

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Sketch, SketchSet, SolidSet},
execution::{ExecState, KclValue, Sketch, Solid},
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args},
};
@ -30,9 +30,9 @@ pub struct RevolveData {
/// Revolve a sketch or set of sketches around an axis.
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch_set): (RevolveData, SketchSet) = args.get_data_and_sketch_set()?;
let (data, sketches): (RevolveData, _) = args.get_data_and_sketches(exec_state)?;
let value = inner_revolve(data, sketch_set, exec_state, args).await?;
let value = inner_revolve(data, sketches, exec_state, args).await?;
Ok(value.into())
}
@ -206,10 +206,10 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}]
async fn inner_revolve(
data: RevolveData,
sketch_set: SketchSet,
sketches: Vec<Sketch>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidSet, KclError> {
) -> Result<Vec<Solid>, KclError> {
if let Some(angle) = data.angle {
// Return an error if the angle is zero.
// We don't use validate() here because we want to return a specific error message that is
@ -224,7 +224,6 @@ async fn inner_revolve(
let angle = Angle::from_degrees(data.angle.unwrap_or(360.0));
let sketches: Vec<Sketch> = sketch_set.into();
let mut solids = Vec::new();
for sketch in &sketches {
let id = exec_state.next_uuid();
@ -263,5 +262,5 @@ async fn inner_revolve(
solids.push(do_post_extrude(sketch.clone(), id.into(), 0.0, exec_state, args.clone()).await?);
}
Ok(solids.into())
Ok(solids)
}

View File

@ -6,7 +6,7 @@ use kittycad_modeling_cmds::shared::Angle;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Point2d, Sketch, TagIdentifier},
execution::{kcl_value::RuntimeType, ExecState, KclValue, Point2d, PrimitiveType, Sketch, TagIdentifier},
std::{utils::between, Args},
};
@ -282,8 +282,9 @@ fn inner_segment_start_y(tag: &TagIdentifier, exec_state: &mut ExecState, args:
Ok(path.get_from()[1])
}
/// Returns the last segment of x.
pub async fn last_segment_x(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg("sketch")?;
pub async fn last_segment_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let result = inner_last_segment_x(sketch, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -327,8 +328,9 @@ fn inner_last_segment_x(sketch: Sketch, args: Args) -> Result<f64, KclError> {
}
/// Returns the last segment of y.
pub async fn last_segment_y(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg("sketch")?;
pub async fn last_segment_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let result = inner_last_segment_y(sketch, args.clone())?;
Ok(args.make_user_val_from_f64(result))

View File

@ -7,17 +7,24 @@ use kittycad_modeling_cmds as kcmc;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, Solid, SolidSet},
execution::{
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Solid,
},
std::{sketch::FaceTag, Args},
};
/// Create a shell.
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set = args.get_unlabeled_kw_arg("solidSet")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let thickness = args.get_kw_arg("thickness")?;
let faces = args.get_kw_arg("faces")?;
let result = inner_shell(solid_set, thickness, faces, exec_state, args).await?;
let result = inner_shell(solids, thickness, faces, exec_state, args).await?;
Ok(result.into())
}
@ -173,18 +180,18 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "Which solid (or solids) to shell out"},
solids = { docs = "Which solid (or solids) to shell out"},
thickness = {docs = "The thickness of the shell"},
faces = {docs = "The faces you want removed"},
}
}]
async fn inner_shell(
solid_set: SolidSet,
solids: Vec<Solid>,
thickness: f64,
faces: Vec<FaceTag>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidSet, KclError> {
) -> Result<Vec<Solid>, KclError> {
if faces.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "You must shell at least one face".to_string(),
@ -192,7 +199,6 @@ async fn inner_shell(
}));
}
let solids: Vec<Box<Solid>> = solid_set.clone().into();
if solids.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "You must shell at least one solid".to_string(),
@ -204,7 +210,7 @@ async fn inner_shell(
for solid in &solids {
// Flush the batch for our fillets/chamfers if there are any.
// If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_solid_set(exec_state, solid.clone().into()).await?;
args.flush_batch_for_solids(exec_state, vec![solid.clone()]).await?;
for tag in &faces {
let extrude_plane_id = tag.get_face_id(solid, exec_state, &args, false).await?;
@ -241,12 +247,12 @@ async fn inner_shell(
)
.await?;
Ok(solid_set)
Ok(solids)
}
/// Make the inside of a 3D object hollow.
pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (thickness, solid): (f64, Box<Solid>) = args.get_data_and_solid()?;
let (thickness, solid): (f64, Box<Solid>) = args.get_data_and_solid(exec_state)?;
let value = inner_hollow(thickness, solid, exec_state, args).await?;
Ok(KclValue::Solid { value })
@ -314,7 +320,7 @@ async fn inner_hollow(
) -> Result<Box<Solid>, KclError> {
// Flush the batch for our fillets/chamfers if there are any.
// If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_solid_set(exec_state, solid.clone().into()).await?;
args.flush_batch_for_solids(exec_state, vec![(*solid).clone()]).await?;
args.batch_modeling_cmd(
exec_state.next_uuid(),

View File

@ -11,11 +11,13 @@ use parse_display::{Display, FromStr};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::execution::kcl_value::RuntimeType;
use crate::execution::PrimitiveType;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d,
Sketch, SketchSet, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier,
Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier,
},
parsing::ast::types::TagNode,
std::{
@ -96,7 +98,8 @@ pub const NEW_TAG_KW: &str = "tag";
/// Draw a line to a point.
pub async fn line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
// let (to, sketch, tag): ([f64; 2], Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let end = args.get_kw_arg_opt("end")?;
let end_absolute = args.get_kw_arg_opt("endAbsolute")?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
@ -263,7 +266,8 @@ async fn straight_line(
/// Draw a line on the x-axis.
pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let length = args.get_kw_arg_opt("length")?;
let end_absolute = args.get_kw_arg_opt("endAbsolute")?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
@ -331,7 +335,8 @@ async fn inner_x_line(
/// Draw a line on the y-axis.
pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let length = args.get_kw_arg_opt("length")?;
let end_absolute = args.get_kw_arg_opt("endAbsolute")?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
@ -410,7 +415,8 @@ pub enum AngledLineData {
/// Draw an angled line.
pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (AngledLineData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (AngledLineData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_angled_line(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -498,7 +504,8 @@ async fn inner_angled_line(
/// Draw an angled line of a given x length.
pub async fn angled_line_of_x_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (AngledLineData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (AngledLineData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_angled_line_of_x_length(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -568,7 +575,8 @@ pub struct AngledLineToData {
/// Draw an angled line to a given x coordinate.
pub async fn angled_line_to_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (AngledLineToData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (AngledLineToData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_angled_line_to_x(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -632,7 +640,8 @@ async fn inner_angled_line_to_x(
/// Draw an angled line of a given y length.
pub async fn angled_line_of_y_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (AngledLineData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (AngledLineData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_angled_line_of_y_length(data, sketch, tag, exec_state, args).await?;
@ -694,7 +703,8 @@ async fn inner_angled_line_of_y_length(
/// Draw an angled line to a given y coordinate.
pub async fn angled_line_to_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (AngledLineToData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (AngledLineToData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_angled_line_to_y(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -773,7 +783,7 @@ pub struct AngledLineThatIntersectsData {
/// Draw an angled line that intersects with a given line.
pub async fn angled_line_that_intersects(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (AngledLineThatIntersectsData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag()?;
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_angled_line_that_intersects(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
value: Box::new(new_sketch),
@ -1202,7 +1212,7 @@ pub(crate) async fn inner_start_profile_at(
SketchSurface::Face(face) => {
// Flush the batch for our fillets/chamfers if there are any.
// If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_solid_set(exec_state, face.solid.clone().into())
args.flush_batch_for_solids(exec_state, vec![(*face.solid).clone()])
.await?;
}
SketchSurface::Plane(plane) if !plane.is_standard() => {
@ -1301,8 +1311,8 @@ pub(crate) async fn inner_start_profile_at(
}
/// Returns the X component of the sketch profile start point.
pub async fn profile_start_x(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_sketch()?;
pub async fn profile_start_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_sketch(exec_state)?;
let ty = sketch.units.into();
let x = inner_profile_start_x(sketch)?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
@ -1326,8 +1336,8 @@ pub(crate) fn inner_profile_start_x(sketch: Sketch) -> Result<f64, KclError> {
}
/// Returns the Y component of the sketch profile start point.
pub async fn profile_start_y(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_sketch()?;
pub async fn profile_start_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_sketch(exec_state)?;
let ty = sketch.units.into();
let x = inner_profile_start_y(sketch)?;
Ok(args.make_user_val_from_f64_with_type(TyF64::new(x, ty)))
@ -1350,8 +1360,8 @@ pub(crate) fn inner_profile_start_y(sketch: Sketch) -> Result<f64, KclError> {
}
/// Returns the sketch profile start point.
pub async fn profile_start(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_sketch()?;
pub async fn profile_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch: Sketch = args.get_sketch(exec_state)?;
let ty = sketch.units.into();
let point = inner_profile_start(sketch)?;
Ok(KclValue::from_point2d(point, ty, args.into()))
@ -1378,7 +1388,8 @@ pub(crate) fn inner_profile_start(sketch: Sketch) -> Result<[f64; 2], KclError>
/// Close the current sketch.
pub async fn close(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let sketch =
args.get_unlabeled_kw_arg_typed("sketch", &RuntimeType::Primitive(PrimitiveType::Sketch), exec_state)?;
let tag = args.get_kw_arg_opt(NEW_TAG_KW)?;
let new_sketch = inner_close(sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -1495,7 +1506,7 @@ pub struct ArcToData {
/// Draw an arc.
pub async fn arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (ArcData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (ArcData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_arc(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -1608,7 +1619,7 @@ pub(crate) async fn inner_arc(
/// Draw a three point arc.
pub async fn arc_to(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (ArcToData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (ArcToData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_arc_to(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -1744,7 +1755,8 @@ pub enum TangentialArcData {
/// Draw a tangential arc.
pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (TangentialArcData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (TangentialArcData, Sketch, Option<TagNode>) =
args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_tangential_arc(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -1871,7 +1883,7 @@ fn tan_arc_to(sketch: &Sketch, to: &[f64; 2]) -> ModelingCmd {
/// Draw a tangential arc to a specific point.
pub async fn tangential_arc_to(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (to, sketch, tag): ([f64; 2], Sketch, Option<TagNode>) = super::args::FromArgs::from_args(&args, 0)?;
let (to, sketch, tag): ([f64; 2], Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_tangential_arc_to(to, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -1881,7 +1893,7 @@ pub async fn tangential_arc_to(exec_state: &mut ExecState, args: Args) -> Result
/// Draw a tangential arc to point some distance away..
pub async fn tangential_arc_to_relative(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (delta, sketch, tag): ([f64; 2], Sketch, Option<TagNode>) = super::args::FromArgs::from_args(&args, 0)?;
let (delta, sketch, tag): ([f64; 2], Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_tangential_arc_to_relative(delta, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -2055,7 +2067,7 @@ pub struct BezierData {
/// Draw a bezier curve.
pub async fn bezier_curve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (data, sketch, tag): (BezierData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag()?;
let (data, sketch, tag): (BezierData, Sketch, Option<TagNode>) = args.get_data_and_sketch_and_tag(exec_state)?;
let new_sketch = inner_bezier_curve(data, sketch, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -2138,7 +2150,7 @@ async fn inner_bezier_curve(
/// Use a sketch to cut a hole in another sketch.
pub async fn hole(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hole_sketch, sketch): (SketchSet, Sketch) = args.get_sketches()?;
let (hole_sketch, sketch): (Vec<Sketch>, Sketch) = args.get_sketches(exec_state)?;
let new_sketch = inner_hole(hole_sketch, sketch, exec_state, args).await?;
Ok(KclValue::Sketch {
@ -2182,13 +2194,12 @@ pub async fn hole(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
feature_tree_operation = true,
}]
async fn inner_hole(
hole_sketch: SketchSet,
hole_sketch: Vec<Sketch>,
sketch: Sketch,
exec_state: &mut ExecState,
args: Args,
) -> Result<Sketch, KclError> {
let hole_sketches: Vec<Sketch> = hole_sketch.into();
for hole_sketch in hole_sketches {
for hole_sketch in hole_sketch {
args.batch_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::Solid2dAddHole {

View File

@ -9,7 +9,10 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{ExecState, Helix, KclValue, Sketch, SketchSet, SolidSet},
execution::{
kcl_value::{ArrayLen, RuntimeType},
ExecState, Helix, KclValue, PrimitiveType, Sketch, Solid,
},
std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
};
@ -24,12 +27,16 @@ pub enum SweepPath {
/// Extrude a sketch along a path.
pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_set = args.get_unlabeled_kw_arg("sketch_set")?;
let sketches = args.get_unlabeled_kw_arg_typed(
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let path: SweepPath = args.get_kw_arg("path")?;
let sectional = args.get_kw_arg_opt("sectional")?;
let tolerance = args.get_kw_arg_opt("tolerance")?;
let value = inner_sweep(sketch_set, path, sectional, tolerance, exec_state, args).await?;
let value = inner_sweep(sketches, path, sectional, tolerance, exec_state, args).await?;
Ok(value.into())
}
@ -134,26 +141,25 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "The sketch or set of sketches that should be swept in space" },
sketches = { docs = "The sketch or set of sketches that should be swept in space" },
path = { docs = "The path to sweep the sketch along" },
sectional = { docs = "If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components." },
tolerance = { docs = "Tolerance for this operation" },
}
}]
async fn inner_sweep(
sketch_set: SketchSet,
sketches: Vec<Sketch>,
path: SweepPath,
sectional: Option<bool>,
tolerance: Option<f64>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidSet, KclError> {
) -> Result<Vec<Solid>, KclError> {
let trajectory = match path {
SweepPath::Sketch(sketch) => sketch.id.into(),
SweepPath::Helix(helix) => helix.value.into(),
};
let sketches: Vec<Sketch> = sketch_set.into();
let mut solids = Vec::new();
for sketch in &sketches {
let id = exec_state.next_uuid();
@ -171,5 +177,5 @@ async fn inner_sweep(
solids.push(do_post_extrude(sketch.clone(), id.into(), 0.0, exec_state, args.clone()).await?);
}
Ok(solids.into())
Ok(solids)
}

View File

@ -13,18 +13,28 @@ use kittycad_modeling_cmds as kcmc;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, KclValue, SolidOrImportedGeometry},
execution::{
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, SolidOrImportedGeometry,
},
std::Args,
};
/// Scale a solid.
pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set = args.get_unlabeled_kw_arg("solid_set")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Union(vec![
RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
RuntimeType::Primitive(PrimitiveType::ImportedGeometry),
]),
exec_state,
)?;
let scale = args.get_kw_arg("scale")?;
let global = args.get_kw_arg_opt("global")?;
let solid = inner_scale(solid_set, scale, global, exec_state, args).await?;
Ok(solid.into())
let solids = inner_scale(solids, scale, global, exec_state, args).await?;
Ok(solids.into())
}
/// Scale a solid.
@ -124,19 +134,19 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
keywords = true,
unlabeled_first = true,
args = {
solid_set = {docs = "The solid or set of solids to scale."},
solids = {docs = "The solid or set of solids to scale."},
scale = {docs = "The scale factor for the x, y, and z axes."},
global = {docs = "If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move."}
}
}]
async fn inner_scale(
solid_set: SolidOrImportedGeometry,
solids: SolidOrImportedGeometry,
scale: [f64; 3],
global: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidOrImportedGeometry, KclError> {
for solid_id in solid_set.ids() {
for solid_id in solids.ids() {
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
@ -162,17 +172,24 @@ async fn inner_scale(
.await?;
}
Ok(solid_set)
Ok(solids)
}
/// Move a solid.
pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set = args.get_unlabeled_kw_arg("solid_set")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solids",
&RuntimeType::Union(vec![
RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
RuntimeType::Primitive(PrimitiveType::ImportedGeometry),
]),
exec_state,
)?;
let translate = args.get_kw_arg("translate")?;
let global = args.get_kw_arg_opt("global")?;
let solid = inner_translate(solid_set, translate, global, exec_state, args).await?;
Ok(solid.into())
let solids = inner_translate(solids, translate, global, exec_state, args).await?;
Ok(solids.into())
}
/// Move a solid.
@ -264,19 +281,19 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
keywords = true,
unlabeled_first = true,
args = {
solid_set = {docs = "The solid or set of solids to move."},
solids = {docs = "The solid or set of solids to move."},
translate = {docs = "The amount to move the solid in all three axes."},
global = {docs = "If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move."}
}
}]
async fn inner_translate(
solid_set: SolidOrImportedGeometry,
solids: SolidOrImportedGeometry,
translate: [f64; 3],
global: Option<bool>,
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidOrImportedGeometry, KclError> {
for solid_id in solid_set.ids() {
for solid_id in solids.ids() {
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
@ -302,12 +319,19 @@ async fn inner_translate(
.await?;
}
Ok(solid_set)
Ok(solids)
}
/// Rotate a solid.
pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solid_set = args.get_unlabeled_kw_arg("solid_set")?;
let solids = args.get_unlabeled_kw_arg_typed(
"solid",
&RuntimeType::Union(vec![
RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
RuntimeType::Primitive(PrimitiveType::ImportedGeometry),
]),
exec_state,
)?;
let roll = args.get_kw_arg_opt("roll")?;
let pitch = args.get_kw_arg_opt("pitch")?;
let yaw = args.get_kw_arg_opt("yaw")?;
@ -415,8 +439,8 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}
}
let solid = inner_rotate(solid_set, roll, pitch, yaw, axis, angle, global, exec_state, args).await?;
Ok(solid.into())
let solids = inner_rotate(solids, roll, pitch, yaw, axis, angle, global, exec_state, args).await?;
Ok(solids.into())
}
/// Rotate a solid.
@ -571,7 +595,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
keywords = true,
unlabeled_first = true,
args = {
solid_set = {docs = "The solid or set of solids to rotate."},
solids = {docs = "The solid or set of solids to rotate."},
roll = {docs = "The roll angle in degrees. Must be used with `pitch` and `yaw`. Must be between -360 and 360.", include_in_snippet = true},
pitch = {docs = "The pitch angle in degrees. Must be used with `roll` and `yaw`. Must be between -360 and 360.", include_in_snippet = true},
yaw = {docs = "The yaw angle in degrees. Must be used with `roll` and `pitch`. Must be between -360 and 360.", include_in_snippet = true},
@ -582,7 +606,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}]
#[allow(clippy::too_many_arguments)]
async fn inner_rotate(
solid_set: SolidOrImportedGeometry,
solids: SolidOrImportedGeometry,
roll: Option<f64>,
pitch: Option<f64>,
yaw: Option<f64>,
@ -592,7 +616,7 @@ async fn inner_rotate(
exec_state: &mut ExecState,
args: Args,
) -> Result<SolidOrImportedGeometry, KclError> {
for solid_id in solid_set.ids() {
for solid_id in solids.ids() {
let id = exec_state.next_uuid();
if let (Some(roll), Some(pitch), Some(yaw)) = (roll, pitch, yaw) {
@ -645,7 +669,7 @@ async fn inner_rotate(
}
}
Ok(solid_set)
Ok(solids)
}
#[cfg(test)]

View File

@ -821,7 +821,7 @@ impl Type {
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
match self {
Type::Primitive(t) => t.to_string(),
Type::Array(t) => format!("{t}[]"),
Type::Array(t) => format!("[{t}]"),
Type::Object { properties } => {
let mut result = "{".to_owned();
for p in properties {
@ -1268,7 +1268,7 @@ thing(1)
#[test]
fn test_recast_typed_fn() {
let some_program_string = r#"fn thing(x: string, y: bool[]): number {
let some_program_string = r#"fn thing(x: string, y: [bool]): number {
return x + 1
}
"#;

View File

@ -350,28 +350,49 @@ description: Operations executed circular_pattern3d_a_pattern.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -138,7 +138,7 @@ description: Operations executed crazy_multi_profile.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -304,7 +304,7 @@ description: Operations executed crazy_multi_profile.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -44,7 +44,7 @@ description: Operations executed import_function_not_sketch.kcl
3
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

File diff suppressed because one or more lines are too long

View File

@ -138,19 +138,31 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -229,19 +241,31 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -185,7 +185,7 @@ description: Operations executed ball-bearing.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -445,7 +445,7 @@ description: Operations executed ball-bearing.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -693,7 +693,7 @@ description: Operations executed ball-bearing.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

File diff suppressed because it is too large Load Diff

View File

@ -1325,16 +1325,25 @@ description: Operations executed bench.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1474,13 +1483,19 @@ description: Operations executed bench.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -377,19 +377,31 @@ description: Operations executed bracket.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -463,13 +475,19 @@ description: Operations executed bracket.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

File diff suppressed because it is too large Load Diff

View File

@ -218,22 +218,37 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -466,22 +481,37 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -554,55 +584,103 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -675,22 +753,37 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -763,22 +856,37 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1062,22 +1170,37 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1150,22 +1273,37 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1217,7 +1355,7 @@ description: Operations executed car-wheel-assembly.kcl
3
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -1281,7 +1419,7 @@ description: Operations executed car-wheel-assembly.kcl
3
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -2223,7 +2361,7 @@ description: Operations executed car-wheel-assembly.kcl
3
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -2473,7 +2611,7 @@ description: Operations executed car-wheel-assembly.kcl
6
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -2730,7 +2868,7 @@ description: Operations executed car-wheel-assembly.kcl
5
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -2794,7 +2932,7 @@ description: Operations executed car-wheel-assembly.kcl
7
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -7,6 +7,11 @@ description: Variables in memory after executing car-wheel-assembly.kcl
"type": "Module",
"value": 5
},
"c1": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "c1"
},
"carRotor": {
"type": "Module",
"value": 4

View File

@ -1,5 +1,5 @@
---
source: kcl/src/simulation_tests.rs
source: kcl-lib/src/simulation_tests.rs
description: Operations executed dodecahedron.kcl
---
[
@ -915,22 +915,37 @@ description: Operations executed dodecahedron.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},

File diff suppressed because it is too large Load Diff

View File

@ -53,19 +53,31 @@ description: Operations executed flange.kcl
"labeledArgs": {
"holeSketch": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -284,13 +284,86 @@ description: Variables in memory after executing flange.kcl
}
},
"circles": {
"type": "Sketches",
"type": "HomArray",
"value": [
{
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"value": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
@ -298,90 +371,93 @@ description: Variables in memory after executing flange.kcl
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
},
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
{
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"value": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
@ -389,90 +465,93 @@ description: Variables in memory after executing flange.kcl
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
},
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
{
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"value": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
@ -480,90 +559,93 @@ description: Variables in memory after executing flange.kcl
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
},
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
{
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"value": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
@ -571,83 +653,13 @@ description: Variables in memory after executing flange.kcl
957,
0
]
},
"ccw": true,
"center": [
1.75,
0.0
],
"from": [
2.0625,
0.0
],
"radius": 0.3125,
"tag": null,
"to": [
2.0625,
0.0
],
"type": "Circle",
"units": {
"type": "Inches"
}
}
],
"on": {
"type": "plane",
"id": "[uuid]",
},
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
},
"start": {
"from": [
2.0625,
0.0
],
"to": [
2.0625,
0.0
],
"units": {
"type": "Inches"
},
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
851,
957,
0
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Inches"
}
}
]

View File

@ -57,7 +57,7 @@ description: Operations executed french-press.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -683,16 +683,25 @@ description: Operations executed french-press.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -744,7 +753,7 @@ description: Operations executed french-press.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -808,7 +817,7 @@ description: Operations executed french-press.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -1046,31 +1055,55 @@ description: Operations executed french-press.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1149,19 +1182,31 @@ description: Operations executed french-press.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1340,7 +1385,7 @@ description: Operations executed french-press.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -473,7 +473,7 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -764,19 +764,31 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -890,31 +902,55 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1028,19 +1064,31 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1154,31 +1202,55 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1338,19 +1410,31 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"labeledArgs": {
"holeSketch": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1997,13 +2081,19 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -2232,13 +2322,19 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -473,7 +473,7 @@ description: Operations executed gridfinity-baseplate.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -764,19 +764,31 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -890,31 +902,55 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1028,19 +1064,31 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1154,31 +1202,55 @@ description: Operations executed gridfinity-baseplate.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -473,7 +473,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -868,19 +868,31 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -988,19 +1000,31 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1108,31 +1132,55 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1240,19 +1288,31 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1360,31 +1420,55 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1601,13 +1685,19 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -3012,7 +3102,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -3346,7 +3436,7 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -473,7 +473,7 @@ description: Operations executed gridfinity-bins.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -868,19 +868,31 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -988,19 +1000,31 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1108,31 +1132,55 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1240,19 +1288,31 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1360,31 +1420,55 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1601,13 +1685,19 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -58,12 +58,10 @@ description: Operations executed i-beam.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"value": [
{
"artifactId": "[uuid]"
}
]
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": [
652,

View File

@ -212,157 +212,307 @@ description: Operations executed lego.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -441,115 +591,223 @@ description: Operations executed lego.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

File diff suppressed because it is too large Load Diff

View File

@ -506,19 +506,31 @@ description: Operations executed multi-axis-robot.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -597,19 +609,31 @@ description: Operations executed multi-axis-robot.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -1490,19 +1514,31 @@ description: Operations executed multi-axis-robot.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -2593,31 +2629,55 @@ description: Operations executed multi-axis-robot.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -2772,19 +2832,31 @@ description: Operations executed multi-axis-robot.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -3550,31 +3622,55 @@ description: Operations executed multi-axis-robot.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -67,7 +67,7 @@ description: Operations executed pipe-flange-assembly.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {
@ -117,28 +117,49 @@ description: Operations executed pipe-flange-assembly.kcl
"labeledArgs": {
"holeSketch": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},
@ -280,28 +301,49 @@ description: Operations executed pipe-flange-assembly.kcl
"labeledArgs": {
"holeSketch": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -95,7 +95,7 @@ description: Operations executed pipe-with-bend.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -44,7 +44,7 @@ description: Operations executed pipe.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -125,7 +125,7 @@ description: Operations executed poopy-shoe.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

File diff suppressed because it is too large Load Diff

View File

@ -288,28 +288,49 @@ description: Operations executed linear_pattern3d_a_pattern.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Solids",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Solid",
"value": {
"artifactId": "[uuid]"
}
}
]
},

View File

@ -125,7 +125,7 @@ description: Operations executed poop_chute.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -81,7 +81,7 @@ description: Operations executed revolve_about_edge.kcl
0
]
},
"sketchSet": {
"sketches": {
"value": {
"type": "Sketch",
"value": {

View File

@ -139,97 +139,187 @@ description: Operations executed ssi_pattern.kcl
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketches",
"type": "Array",
"value": [
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
{
"artifactId": "[uuid]"
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
}
]
},

File diff suppressed because it is too large Load Diff