allow for sketching on the face of a chamfer in kcl (#2760)

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* lots of cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* lots more cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more cleaniup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix typos

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add to known issues

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2024-06-23 23:04:32 -07:00
committed by GitHub
parent 394653247a
commit 5260bd6820
59 changed files with 990 additions and 278 deletions

View File

@ -23,5 +23,7 @@ once fixed in engine will just start working here with no language changes.
- **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple - **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple
chamfer cases work currently. chamfer cases work currently.
Sketching on the chamfered face does not currently work.
- **Shell**: Shell is only working for `end` faces, not for `side` or `start` - **Shell**: Shell is only working for `end` faces, not for `side` or `start`
faces. We are tracking the engine side bug on this. faces. We are tracking the engine side bug on this.

View File

@ -90,6 +90,7 @@ const extrusion = extrude(5, sketch001)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -91,6 +91,7 @@ const extrusion = extrude(5, sketch001)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -97,6 +97,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -371,6 +372,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -96,6 +96,7 @@ const extrusion = extrude(10, sketch001)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -370,6 +371,7 @@ const extrusion = extrude(10, sketch001)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -98,6 +98,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -372,6 +373,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -102,6 +102,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -376,6 +377,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -95,6 +95,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -369,6 +370,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -95,6 +95,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -369,6 +370,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -106,6 +106,7 @@ const exampleSketch = startSketchOn('XZ')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -380,6 +381,7 @@ const exampleSketch = startSketchOn('XZ')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -101,6 +101,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -375,6 +376,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -9,7 +9,7 @@ Create chamfers on tagged paths.
```js ```js
chamfer(data: ChamferData, extrude_group: ExtrudeGroup) -> ExtrudeGroup chamfer(data: ChamferData, extrude_group: ExtrudeGroup, tag?: String) -> ExtrudeGroup
``` ```
### Examples ### Examples
@ -73,6 +73,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -135,6 +136,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -295,6 +297,7 @@ string],
}], }],
} }
``` ```
* `tag`: `String` (OPTIONAL)
### Returns ### Returns
@ -318,6 +321,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -380,6 +384,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -95,6 +95,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -287,6 +288,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -481,6 +483,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -96,6 +96,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -370,6 +371,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -121,6 +121,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -361,6 +362,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -423,6 +425,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -73,6 +73,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -135,6 +136,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -318,6 +320,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -380,6 +383,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -60,6 +60,7 @@ const revolution = startSketchOn(box, "revolveAxis")
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -122,6 +123,7 @@ const revolution = startSketchOn(box, "revolveAxis")
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -58,6 +58,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -120,6 +121,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -56,6 +56,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -118,6 +119,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -58,6 +58,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -120,6 +121,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -63,6 +63,7 @@ const part001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -125,6 +126,7 @@ const part001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -308,6 +310,7 @@ const part001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -370,6 +373,7 @@ const part001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -107,6 +107,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -381,6 +382,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -654,6 +656,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -87,6 +87,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -87,6 +87,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -100,6 +100,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -374,6 +375,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -87,6 +87,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -361,6 +362,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -105,6 +105,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -67,6 +67,7 @@ const example = extrude(-5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -129,6 +130,7 @@ const example = extrude(-5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -98,6 +98,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -65,6 +65,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -127,6 +128,7 @@ const example = extrude(1, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -88,6 +88,7 @@ const sketch001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -83,6 +83,7 @@ const sketch001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -82,6 +82,7 @@ const sketch001 = startSketchOn('XY')
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -216,6 +216,7 @@ string,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -452,6 +453,7 @@ string,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -514,6 +516,7 @@ string,
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -90,6 +90,7 @@ const example = extrude(4, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -88,6 +88,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -89,6 +89,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -90,6 +90,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -61,6 +61,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -123,6 +124,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -306,6 +308,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -368,6 +371,7 @@ string],
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -109,6 +109,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -365,6 +366,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -113,6 +113,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -9,7 +9,7 @@ Start a sketch on a specific plane or face.
```js ```js
startSketchOn(data: SketchData, tag?: SketchOnFaceTag) -> SketchSurface startSketchOn(data: SketchData, tag?: FaceTag) -> SketchSurface
``` ```
### Examples ### Examples
@ -178,6 +178,7 @@ const a1 = startSketchOn({
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -349,7 +350,7 @@ const a1 = startSketchOn({
}], }],
} }
``` ```
* `tag`: `SketchOnFaceTag` - A tag for sketch on face. (OPTIONAL) * `tag`: `FaceTag` - A tag for a face. (OPTIONAL)
```js ```js
"start" | "end" | "start" | "end" |
string string
@ -410,6 +411,7 @@ string
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -370,6 +371,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -87,6 +87,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -361,6 +362,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -90,6 +90,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -364,6 +365,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -90,6 +90,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -364,6 +365,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -88,6 +88,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -362,6 +363,7 @@ const example = extrude(10, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -86,6 +86,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.
@ -360,6 +361,7 @@ const example = extrude(5, exampleSketch)
// The id of the engine command that called this chamfer. // The id of the engine command that called this chamfer.
id: uuid, id: uuid,
length: number, length: number,
tag: string,
type: "chamfer", type: "chamfer",
}], }],
// The height of the extrude group. // The height of the extrude group.

View File

@ -172,7 +172,7 @@ impl MemoryItem {
MemoryItem::UserVal(value) => { MemoryItem::UserVal(value) => {
let sg: Vec<Box<SketchGroup>> = serde_json::from_value(value.value.clone()) let sg: Vec<Box<SketchGroup>> = serde_json::from_value(value.value.clone())
.map_err(|e| anyhow::anyhow!("Failed to deserialize array of sketch groups from JSON: {}", e))?; .map_err(|e| anyhow::anyhow!("Failed to deserialize array of sketch groups from JSON: {}", e))?;
Ok(SketchGroupSet::SketchGroups(sg.clone())) Ok(sg.into())
} }
_ => anyhow::bail!("Not a sketch group or sketch groups: {:?}", self), _ => anyhow::bail!("Not a sketch group or sketch groups: {:?}", self),
} }
@ -185,13 +185,51 @@ impl MemoryItem {
MemoryItem::UserVal(value) => { MemoryItem::UserVal(value) => {
let eg: Vec<Box<ExtrudeGroup>> = serde_json::from_value(value.value.clone()) let eg: Vec<Box<ExtrudeGroup>> = serde_json::from_value(value.value.clone())
.map_err(|e| anyhow::anyhow!("Failed to deserialize array of extrude groups from JSON: {}", e))?; .map_err(|e| anyhow::anyhow!("Failed to deserialize array of extrude groups from JSON: {}", e))?;
Ok(ExtrudeGroupSet::ExtrudeGroups(eg.clone())) Ok(eg.into())
} }
_ => anyhow::bail!("Not a extrude group or extrude groups: {:?}", self), _ => anyhow::bail!("Not a extrude group or extrude groups: {:?}", self),
} }
} }
} }
impl From<SketchGroupSet> for MemoryItem {
fn from(sg: SketchGroupSet) -> Self {
match sg {
SketchGroupSet::SketchGroup(sg) => MemoryItem::SketchGroup(sg),
SketchGroupSet::SketchGroups(sgs) => MemoryItem::SketchGroups { value: sgs },
}
}
}
impl From<Vec<Box<SketchGroup>>> for MemoryItem {
fn from(sg: Vec<Box<SketchGroup>>) -> Self {
if sg.len() == 1 {
MemoryItem::SketchGroup(sg[0].clone())
} else {
MemoryItem::SketchGroups { value: sg }
}
}
}
impl From<ExtrudeGroupSet> for MemoryItem {
fn from(eg: ExtrudeGroupSet) -> Self {
match eg {
ExtrudeGroupSet::ExtrudeGroup(eg) => MemoryItem::ExtrudeGroup(eg),
ExtrudeGroupSet::ExtrudeGroups(egs) => MemoryItem::ExtrudeGroups { value: egs },
}
}
}
impl From<Vec<Box<ExtrudeGroup>>> for MemoryItem {
fn from(eg: Vec<Box<ExtrudeGroup>>) -> Self {
if eg.len() == 1 {
MemoryItem::ExtrudeGroup(eg[0].clone())
} else {
MemoryItem::ExtrudeGroups { value: eg }
}
}
}
/// A geometry. /// A geometry.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)] #[ts(export)]
@ -228,6 +266,59 @@ pub enum SketchGroupSet {
SketchGroups(Vec<Box<SketchGroup>>), SketchGroups(Vec<Box<SketchGroup>>),
} }
impl From<SketchGroup> for SketchGroupSet {
fn from(sg: SketchGroup) -> Self {
SketchGroupSet::SketchGroup(Box::new(sg))
}
}
impl From<Box<SketchGroup>> for SketchGroupSet {
fn from(sg: Box<SketchGroup>) -> Self {
SketchGroupSet::SketchGroup(sg)
}
}
impl From<Vec<SketchGroup>> for SketchGroupSet {
fn from(sg: Vec<SketchGroup>) -> Self {
if sg.len() == 1 {
SketchGroupSet::SketchGroup(Box::new(sg[0].clone()))
} else {
SketchGroupSet::SketchGroups(sg.into_iter().map(Box::new).collect())
}
}
}
impl From<Vec<Box<SketchGroup>>> for SketchGroupSet {
fn from(sg: Vec<Box<SketchGroup>>) -> Self {
if sg.len() == 1 {
SketchGroupSet::SketchGroup(sg[0].clone())
} else {
SketchGroupSet::SketchGroups(sg)
}
}
}
impl From<SketchGroupSet> for Vec<Box<SketchGroup>> {
fn from(sg: SketchGroupSet) -> Self {
match sg {
SketchGroupSet::SketchGroup(sg) => vec![sg],
SketchGroupSet::SketchGroups(sgs) => sgs,
}
}
}
impl From<&SketchGroup> for Vec<Box<SketchGroup>> {
fn from(sg: &SketchGroup) -> Self {
vec![Box::new(sg.clone())]
}
}
impl From<Box<SketchGroup>> for Vec<Box<SketchGroup>> {
fn from(sg: Box<SketchGroup>) -> Self {
vec![sg]
}
}
/// A extrude group or a group of extrude groups. /// A extrude group or a group of extrude groups.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)] #[ts(export)]
@ -237,6 +328,59 @@ pub enum ExtrudeGroupSet {
ExtrudeGroups(Vec<Box<ExtrudeGroup>>), ExtrudeGroups(Vec<Box<ExtrudeGroup>>),
} }
impl From<ExtrudeGroup> for ExtrudeGroupSet {
fn from(eg: ExtrudeGroup) -> Self {
ExtrudeGroupSet::ExtrudeGroup(Box::new(eg))
}
}
impl From<Box<ExtrudeGroup>> for ExtrudeGroupSet {
fn from(eg: Box<ExtrudeGroup>) -> Self {
ExtrudeGroupSet::ExtrudeGroup(eg)
}
}
impl From<Vec<ExtrudeGroup>> for ExtrudeGroupSet {
fn from(eg: Vec<ExtrudeGroup>) -> Self {
if eg.len() == 1 {
ExtrudeGroupSet::ExtrudeGroup(Box::new(eg[0].clone()))
} else {
ExtrudeGroupSet::ExtrudeGroups(eg.into_iter().map(Box::new).collect())
}
}
}
impl From<Vec<Box<ExtrudeGroup>>> for ExtrudeGroupSet {
fn from(eg: Vec<Box<ExtrudeGroup>>) -> Self {
if eg.len() == 1 {
ExtrudeGroupSet::ExtrudeGroup(eg[0].clone())
} else {
ExtrudeGroupSet::ExtrudeGroups(eg)
}
}
}
impl From<ExtrudeGroupSet> for Vec<Box<ExtrudeGroup>> {
fn from(eg: ExtrudeGroupSet) -> Self {
match eg {
ExtrudeGroupSet::ExtrudeGroup(eg) => vec![eg],
ExtrudeGroupSet::ExtrudeGroups(egs) => egs,
}
}
}
impl From<&ExtrudeGroup> for Vec<Box<ExtrudeGroup>> {
fn from(eg: &ExtrudeGroup) -> Self {
vec![Box::new(eg.clone())]
}
}
impl From<Box<ExtrudeGroup>> for Vec<Box<ExtrudeGroup>> {
fn from(eg: Box<ExtrudeGroup>) -> Self {
vec![eg]
}
}
/// Data for an imported geometry. /// Data for an imported geometry.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)] #[ts(export)]
@ -631,6 +775,7 @@ pub enum FilletOrChamfer {
length: f64, length: f64,
/// The engine id of the edge to chamfer. /// The engine id of the edge to chamfer.
edge_id: uuid::Uuid, edge_id: uuid::Uuid,
tag: Option<String>,
}, },
} }
@ -648,6 +793,13 @@ impl FilletOrChamfer {
FilletOrChamfer::Chamfer { edge_id, .. } => *edge_id, FilletOrChamfer::Chamfer { edge_id, .. } => *edge_id,
} }
} }
pub fn tag(&self) -> Option<&str> {
match self {
FilletOrChamfer::Fillet { .. } => None,
FilletOrChamfer::Chamfer { tag, .. } => tag.as_deref(),
}
}
} }
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]

View File

@ -876,7 +876,7 @@ async fn test_kcl_lsp_on_hover() {
hover.contents, hover.contents,
tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent { tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent {
kind: tower_lsp::lsp_types::MarkupKind::Markdown, kind: tower_lsp::lsp_types::MarkupKind::Markdown,
value: "```startSketchOn(data: SketchData, tag?: SketchOnFaceTag) -> SketchSurface```\nStart a sketch on a specific plane or face.".to_string() value: "```startSketchOn(data: SketchData, tag?: FaceTag) -> SketchSurface```\nStart a sketch on a specific plane or face.".to_string()
}) })
); );
} else { } else {

View File

@ -38,9 +38,10 @@ pub enum EdgeReference {
/// Create chamfers on tagged paths. /// Create chamfers on tagged paths.
pub async fn chamfer(args: Args) -> Result<MemoryItem, KclError> { pub async fn chamfer(args: Args) -> Result<MemoryItem, KclError> {
let (data, extrude_group): (ChamferData, Box<ExtrudeGroup>) = args.get_data_and_extrude_group()?; let (data, extrude_group, tag): (ChamferData, Box<ExtrudeGroup>, Option<String>) =
args.get_data_and_extrude_group_and_tag()?;
let extrude_group = inner_chamfer(data, extrude_group, args).await?; let extrude_group = inner_chamfer(data, extrude_group, tag, args).await?;
Ok(MemoryItem::ExtrudeGroup(extrude_group)) Ok(MemoryItem::ExtrudeGroup(extrude_group))
} }
@ -76,6 +77,7 @@ pub async fn chamfer(args: Args) -> Result<MemoryItem, KclError> {
async fn inner_chamfer( async fn inner_chamfer(
data: ChamferData, data: ChamferData,
extrude_group: Box<ExtrudeGroup>, extrude_group: Box<ExtrudeGroup>,
tag: Option<String>,
args: Args, args: Args,
) -> Result<Box<ExtrudeGroup>, KclError> { ) -> Result<Box<ExtrudeGroup>, KclError> {
// Check if tags contains any duplicate values. // Check if tags contains any duplicate values.
@ -89,19 +91,28 @@ async fn inner_chamfer(
})); }));
} }
// If you try and tag multiple edges with a tagged chamfer, we want to return an
// error to the user that they can only tag one edge at a time.
if tag.is_some() && data.tags.len() > 1 {
return Err(KclError::Type(KclErrorDetails {
message: "You can only tag one edge at a time with a tagged chamfer. Either delete the tag for the chamfer fn if you don't need it OR separate into individual chamfer functions for each tag.".to_string(),
source_ranges: vec![args.source_range],
}));
}
let mut fillet_or_chamfers = Vec::new(); let mut fillet_or_chamfers = Vec::new();
for tag in data.tags { for edge_tag in data.tags {
let edge_id = match tag { let edge_id = match edge_tag {
EdgeReference::Uuid(uuid) => uuid, EdgeReference::Uuid(uuid) => uuid,
EdgeReference::Tag(tag) => { EdgeReference::Tag(edge_tag) => {
extrude_group extrude_group
.sketch_group .sketch_group
.value .value
.iter() .iter()
.find(|p| p.get_name() == tag) .find(|p| p.get_name() == edge_tag)
.ok_or_else(|| { .ok_or_else(|| {
KclError::Type(KclErrorDetails { KclError::Type(KclErrorDetails {
message: format!("No edge found with tag: `{}`", tag), message: format!("No edge found with tag: `{}`", edge_tag),
source_ranges: vec![args.source_range], source_ranges: vec![args.source_range],
}) })
})? })?
@ -128,6 +139,7 @@ async fn inner_chamfer(
id, id,
edge_id, edge_id,
length: data.length, length: data.length,
tag: tag.clone(),
}); });
} }

View File

@ -20,10 +20,7 @@ pub async fn extrude(args: Args) -> Result<MemoryItem, KclError> {
let result = inner_extrude(length, sketch_group_set, args).await?; let result = inner_extrude(length, sketch_group_set, args).await?;
match result { Ok(result.into())
ExtrudeGroupSet::ExtrudeGroup(extrude_group) => Ok(MemoryItem::ExtrudeGroup(extrude_group)),
ExtrudeGroupSet::ExtrudeGroups(extrude_groups) => Ok(MemoryItem::ExtrudeGroups { value: extrude_groups }),
}
} }
/// Extrudes by a given amount. /// Extrudes by a given amount.
@ -77,12 +74,9 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
let id = uuid::Uuid::new_v4(); let id = uuid::Uuid::new_v4();
// Extrude the element(s). // Extrude the element(s).
let sketch_groups = match sketch_group_set { let sketch_groups: Vec<Box<SketchGroup>> = sketch_group_set.into();
SketchGroupSet::SketchGroup(sketch_group) => vec![sketch_group],
SketchGroupSet::SketchGroups(sketch_groups) => sketch_groups,
};
let mut extrude_groups = Vec::new(); let mut extrude_groups = Vec::new();
for sketch_group in sketch_groups.iter() { for sketch_group in &sketch_groups {
args.send_modeling_cmd( args.send_modeling_cmd(
id, id,
kittycad::types::ModelingCmd::Extrude { kittycad::types::ModelingCmd::Extrude {
@ -95,11 +89,7 @@ async fn inner_extrude(length: f64, sketch_group_set: SketchGroupSet, args: Args
extrude_groups.push(do_post_extrude(sketch_group.clone(), length, id, args.clone()).await?); extrude_groups.push(do_post_extrude(sketch_group.clone(), length, id, args.clone()).await?);
} }
if extrude_groups.len() == 1 { Ok(extrude_groups.into())
Ok(ExtrudeGroupSet::ExtrudeGroup(extrude_groups.pop().unwrap()))
} else {
Ok(ExtrudeGroupSet::ExtrudeGroups(extrude_groups))
}
} }
pub(crate) async fn do_post_extrude( pub(crate) async fn do_post_extrude(

View File

@ -9,7 +9,7 @@ use uuid::Uuid;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
executor::{ExtrudeGroup, ExtrudeSurface, FilletOrChamfer, MemoryItem, UserVal}, executor::{ExtrudeGroup, FilletOrChamfer, MemoryItem, UserVal},
std::Args, std::Args,
}; };
@ -201,7 +201,7 @@ async fn inner_get_opposite_edge(tag: String, extrude_group: Box<ExtrudeGroup>,
})? })?
.get_base(); .get_base();
let face_id = get_adjacent_face_to_tag(&extrude_group, &tag, &args)?; let face_id = args.get_adjacent_face_to_tag(&extrude_group, &tag, false).await?;
let resp = args let resp = args
.send_modeling_cmd( .send_modeling_cmd(
@ -293,7 +293,7 @@ async fn inner_get_next_adjacent_edge(
})? })?
.get_base(); .get_base();
let face_id = get_adjacent_face_to_tag(&extrude_group, &tag, &args)?; let face_id = args.get_adjacent_face_to_tag(&extrude_group, &tag, false).await?;
let resp = args let resp = args
.send_modeling_cmd( .send_modeling_cmd(
@ -390,7 +390,7 @@ async fn inner_get_previous_adjacent_edge(
})? })?
.get_base(); .get_base();
let face_id = get_adjacent_face_to_tag(&extrude_group, &tag, &args)?; let face_id = args.get_adjacent_face_to_tag(&extrude_group, &tag, false).await?;
let resp = args let resp = args
.send_modeling_cmd( .send_modeling_cmd(
@ -419,20 +419,3 @@ async fn inner_get_previous_adjacent_edge(
}) })
}) })
} }
fn get_adjacent_face_to_tag(extrude_group: &ExtrudeGroup, tag: &str, args: &Args) -> Result<uuid::Uuid, KclError> {
extrude_group
.value
.iter()
.find_map(|extrude_surface| match extrude_surface {
ExtrudeSurface::ExtrudePlane(extrude_plane) if extrude_plane.name == tag => Some(Ok(extrude_plane.face_id)),
ExtrudeSurface::ExtrudeArc(extrude_arc) if extrude_arc.name == tag => Some(Ok(extrude_arc.face_id)),
ExtrudeSurface::ExtrudePlane(_) | ExtrudeSurface::ExtrudeArc(_) => None,
})
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a face with the tag `{}`", tag),
source_ranges: vec![args.source_range],
})
})?
}

View File

@ -31,10 +31,10 @@ use crate::{
docs::StdLibFn, docs::StdLibFn,
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
executor::{ executor::{
ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, MemoryItem, Metadata, ProgramMemory, SketchGroup, ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, ExtrudeSurface, MemoryItem, Metadata, ProgramMemory,
SketchGroupSet, SketchSurface, SourceRange, SketchGroup, SketchGroupSet, SketchSurface, SourceRange,
}, },
std::{kcl_stdlib::KclStdLibFn, sketch::SketchOnFaceTag}, std::{kcl_stdlib::KclStdLibFn, sketch::FaceTag},
}; };
pub type StdFn = fn(Args) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<MemoryItem, KclError>> + Send>>; pub type StdFn = fn(Args) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<MemoryItem, KclError>> + Send>>;
@ -252,12 +252,10 @@ impl Args {
} }
/// Flush just the fillets and chamfers for this specific ExtrudeGroupSet. /// Flush just the fillets and chamfers for this specific ExtrudeGroupSet.
pub async fn flush_batch_for_extrude_group_set(&self, extrude_group_set: &ExtrudeGroupSet) -> Result<(), KclError> { pub async fn flush_batch_for_extrude_group_set(
let extrude_groups = match extrude_group_set { &self,
ExtrudeGroupSet::ExtrudeGroup(eg) => vec![eg.clone()], extrude_groups: Vec<Box<ExtrudeGroup>>,
ExtrudeGroupSet::ExtrudeGroups(egs) => egs.clone(), ) -> Result<(), KclError> {
};
// Make sure we don't traverse sketch_groups more than once. // Make sure we don't traverse sketch_groups more than once.
let mut traversed_sketch_groups = Vec::new(); let mut traversed_sketch_groups = Vec::new();
@ -641,9 +639,7 @@ impl Args {
} }
} }
fn get_data_and_optional_tag<T: serde::de::DeserializeOwned>( fn get_data_and_optional_tag<T: serde::de::DeserializeOwned>(&self) -> Result<(T, Option<FaceTag>), KclError> {
&self,
) -> Result<(T, Option<SketchOnFaceTag>), KclError> {
let first_value = self let first_value = self
.args .args
.first() .first()
@ -663,9 +659,9 @@ impl Args {
})?; })?;
if let Some(second_value) = self.args.get(1) { if let Some(second_value) = self.args.get(1) {
let tag: SketchOnFaceTag = serde_json::from_value(second_value.get_json_value()?).map_err(|e| { let tag: FaceTag = serde_json::from_value(second_value.get_json_value()?).map_err(|e| {
KclError::Type(KclErrorDetails { KclError::Type(KclErrorDetails {
message: format!("Failed to deserialize SketchOnFaceTag from JSON: {}", e), message: format!("Failed to deserialize FaceTag from JSON: {}", e),
source_ranges: vec![self.source_range], source_ranges: vec![self.source_range],
}) })
})?; })?;
@ -933,6 +929,57 @@ impl Args {
Ok((data, extrude_group)) Ok((data, extrude_group))
} }
fn get_data_and_extrude_group_and_tag<T: serde::de::DeserializeOwned>(
&self,
) -> Result<(T, Box<ExtrudeGroup>, Option<String>), KclError> {
let first_value = self
.args
.first()
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a struct as the first argument, found `{:?}`", self.args),
source_ranges: vec![self.source_range],
})
})?
.get_json_value()?;
let data: T = serde_json::from_value(first_value).map_err(|e| {
KclError::Type(KclErrorDetails {
message: format!("Failed to deserialize struct from JSON: {}", e),
source_ranges: vec![self.source_range],
})
})?;
let second_value = self.args.get(1).ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!(
"Expected an ExtrudeGroup as the second argument, found `{:?}`",
self.args
),
source_ranges: vec![self.source_range],
})
})?;
let extrude_group = if let MemoryItem::ExtrudeGroup(eg) = second_value {
eg.clone()
} else {
return Err(KclError::Type(KclErrorDetails {
message: format!(
"Expected an ExtrudeGroup as the second argument, found `{:?}`",
self.args
),
source_ranges: vec![self.source_range],
}));
};
let tag = if let Some(tag) = self.args.get(2) {
tag.get_json_opt()?
} else {
None
};
Ok((data, extrude_group, tag))
}
fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, Box<SketchGroup>), KclError> { fn get_segment_name_to_number_sketch_group(&self) -> Result<(String, f64, Box<SketchGroup>), KclError> {
// Iterate over our args, the first argument should be a UserVal with a string value. // Iterate over our args, the first argument should be a UserVal with a string value.
// The second argument should be a number. // The second argument should be a number.
@ -1024,6 +1071,59 @@ impl Args {
Ok((number, sketch_set)) Ok((number, sketch_set))
} }
pub async fn get_adjacent_face_to_tag(
&self,
extrude_group: &ExtrudeGroup,
tag: &str,
must_be_planar: bool,
) -> Result<uuid::Uuid, KclError> {
if tag.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "Expected a non-empty tag for the face".to_string(),
source_ranges: vec![self.source_range],
}));
}
if let Some(face_from_surface) = extrude_group
.value
.iter()
.find_map(|extrude_surface| match extrude_surface {
ExtrudeSurface::ExtrudePlane(extrude_plane) if extrude_plane.name == tag => {
Some(Ok(extrude_plane.face_id))
}
// The must be planar check must be called before the arc check.
ExtrudeSurface::ExtrudeArc(_) if must_be_planar => Some(Err(KclError::Type(KclErrorDetails {
message: format!("Tag `{}` is a non-planar surface", tag),
source_ranges: vec![self.source_range],
}))),
ExtrudeSurface::ExtrudeArc(extrude_arc) if extrude_arc.name == tag => Some(Ok(extrude_arc.face_id)),
ExtrudeSurface::ExtrudePlane(_) | ExtrudeSurface::ExtrudeArc(_) => None,
})
{
return face_from_surface;
}
// A face could also be the result of a chamfer or fillet.
if let Some(face_from_chamfer_fillet) = extrude_group.fillet_or_chamfers.iter().find_map(|fc| {
if fc.tag() == Some(tag) {
Some(Ok(fc.id()))
} else {
None
}
}) {
// We want to make sure we execute the fillet before this operation.
self.flush_batch_for_extrude_group_set(extrude_group.into()).await?;
return face_from_chamfer_fillet;
}
// If we still haven't found the face, return an error.
Err(KclError::Type(KclErrorDetails {
message: format!("Expected a face with the tag `{}`", tag),
source_ranges: vec![self.source_range],
}))
}
} }
/// Returns the length of the given leg. /// Returns the length of the given leg.

View File

@ -84,7 +84,7 @@ pub async fn pattern_linear_2d(args: Args) -> Result<MemoryItem, KclError> {
} }
let sketch_groups = inner_pattern_linear_2d(data, sketch_group_set, args).await?; let sketch_groups = inner_pattern_linear_2d(data, sketch_group_set, args).await?;
Ok(MemoryItem::SketchGroups { value: sketch_groups }) Ok(sketch_groups.into())
} }
/// A linear pattern on a 2D sketch. /// A linear pattern on a 2D sketch.
@ -108,10 +108,7 @@ async fn inner_pattern_linear_2d(
sketch_group_set: SketchGroupSet, sketch_group_set: SketchGroupSet,
args: Args, args: Args,
) -> Result<Vec<Box<SketchGroup>>, KclError> { ) -> Result<Vec<Box<SketchGroup>>, KclError> {
let starting_sketch_groups = match sketch_group_set { let starting_sketch_groups: Vec<Box<SketchGroup>> = sketch_group_set.into();
SketchGroupSet::SketchGroup(sketch_group) => vec![sketch_group],
SketchGroupSet::SketchGroups(sketch_groups) => sketch_groups,
};
if args.ctx.is_mock { if args.ctx.is_mock {
return Ok(starting_sketch_groups); return Ok(starting_sketch_groups);
@ -153,7 +150,7 @@ pub async fn pattern_linear_3d(args: Args) -> Result<MemoryItem, KclError> {
} }
let extrude_groups = inner_pattern_linear_3d(data, extrude_group_set, args).await?; let extrude_groups = inner_pattern_linear_3d(data, extrude_group_set, args).await?;
Ok(MemoryItem::ExtrudeGroups { value: extrude_groups }) Ok(extrude_groups.into())
} }
/// A linear pattern on a 3D model. /// A linear pattern on a 3D model.
@ -184,12 +181,10 @@ async fn inner_pattern_linear_3d(
// Flush the batch for our fillets/chamfers if there are any. // 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. // 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 extrude groups. // Flush just the fillets/chamfers that apply to these extrude groups.
args.flush_batch_for_extrude_group_set(&extrude_group_set).await?; args.flush_batch_for_extrude_group_set(extrude_group_set.clone().into())
.await?;
let starting_extrude_groups = match extrude_group_set { let starting_extrude_groups: Vec<Box<ExtrudeGroup>> = extrude_group_set.into();
ExtrudeGroupSet::ExtrudeGroup(extrude_group) => vec![extrude_group],
ExtrudeGroupSet::ExtrudeGroups(extrude_groups) => extrude_groups,
};
if args.ctx.is_mock { if args.ctx.is_mock {
return Ok(starting_extrude_groups); return Ok(starting_extrude_groups);
@ -353,7 +348,7 @@ pub async fn pattern_circular_2d(args: Args) -> Result<MemoryItem, KclError> {
let (data, sketch_group_set): (CircularPattern2dData, SketchGroupSet) = args.get_data_and_sketch_group_set()?; let (data, sketch_group_set): (CircularPattern2dData, SketchGroupSet) = args.get_data_and_sketch_group_set()?;
let sketch_groups = inner_pattern_circular_2d(data, sketch_group_set, args).await?; let sketch_groups = inner_pattern_circular_2d(data, sketch_group_set, args).await?;
Ok(MemoryItem::SketchGroups { value: sketch_groups }) Ok(sketch_groups.into())
} }
/// A circular pattern on a 2D sketch. /// A circular pattern on a 2D sketch.
@ -382,10 +377,7 @@ async fn inner_pattern_circular_2d(
sketch_group_set: SketchGroupSet, sketch_group_set: SketchGroupSet,
args: Args, args: Args,
) -> Result<Vec<Box<SketchGroup>>, KclError> { ) -> Result<Vec<Box<SketchGroup>>, KclError> {
let starting_sketch_groups = match sketch_group_set { let starting_sketch_groups: Vec<Box<SketchGroup>> = sketch_group_set.into();
SketchGroupSet::SketchGroup(sketch_group) => vec![sketch_group],
SketchGroupSet::SketchGroups(sketch_groups) => sketch_groups,
};
if args.ctx.is_mock { if args.ctx.is_mock {
return Ok(starting_sketch_groups); return Ok(starting_sketch_groups);
@ -418,7 +410,7 @@ pub async fn pattern_circular_3d(args: Args) -> Result<MemoryItem, KclError> {
let (data, extrude_group_set): (CircularPattern3dData, ExtrudeGroupSet) = args.get_data_and_extrude_group_set()?; let (data, extrude_group_set): (CircularPattern3dData, ExtrudeGroupSet) = args.get_data_and_extrude_group_set()?;
let extrude_groups = inner_pattern_circular_3d(data, extrude_group_set, args).await?; let extrude_groups = inner_pattern_circular_3d(data, extrude_group_set, args).await?;
Ok(MemoryItem::ExtrudeGroups { value: extrude_groups }) Ok(extrude_groups.into())
} }
/// A circular pattern on a 3D model. /// A circular pattern on a 3D model.
@ -447,12 +439,10 @@ async fn inner_pattern_circular_3d(
// Flush the batch for our fillets/chamfers if there are any. // 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. // 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 extrude groups. // Flush just the fillets/chamfers that apply to these extrude groups.
args.flush_batch_for_extrude_group_set(&extrude_group_set).await?; args.flush_batch_for_extrude_group_set(extrude_group_set.clone().into())
.await?;
let starting_extrude_groups = match extrude_group_set { let starting_extrude_groups: Vec<Box<ExtrudeGroup>> = extrude_group_set.into();
ExtrudeGroupSet::ExtrudeGroup(extrude_group) => vec![extrude_group],
ExtrudeGroupSet::ExtrudeGroups(extrude_groups) => extrude_groups,
};
if args.ctx.is_mock { if args.ctx.is_mock {
return Ok(starting_extrude_groups); return Ok(starting_extrude_groups);

View File

@ -3,27 +3,15 @@
use anyhow::Result; use anyhow::Result;
use derive_docs::stdlib; use derive_docs::stdlib;
use kittycad::types::ModelingCmd; use kittycad::types::ModelingCmd;
use parse_display::{Display, FromStr};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
executor::{ExtrudeGroup, ExtrudeSurface, MemoryItem}, executor::{ExtrudeGroup, MemoryItem},
std::{sketch::StartOrEnd, Args}, std::{sketch::FaceTag, Args},
}; };
/// A tag for a face.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, FromStr, Display)]
#[ts(export)]
#[serde(rename_all = "snake_case", untagged)]
#[display("{0}")]
pub enum FaceTag {
StartOrEnd(StartOrEnd),
/// A string tag for the face you want to sketch on.
String(String),
}
/// Data for shells. /// Data for shells.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)] #[ts(export)]
@ -77,44 +65,7 @@ async fn inner_shell(
let mut face_ids = Vec::new(); let mut face_ids = Vec::new();
for tag in data.faces { for tag in data.faces {
let extrude_plane_id = match tag { let extrude_plane_id = tag.get_face_id(&extrude_group, &args, false).await?;
FaceTag::String(ref s) => {
if s.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "Expected a non-empty tag for the face".to_string(),
source_ranges: vec![args.source_range],
}));
}
extrude_group
.value
.iter()
.find_map(|extrude_surface| match extrude_surface {
ExtrudeSurface::ExtrudePlane(extrude_plane) if extrude_plane.name == *s => {
Some(extrude_plane.face_id)
}
ExtrudeSurface::ExtrudeArc(extrude_arc) if extrude_arc.name == *s => Some(extrude_arc.face_id),
ExtrudeSurface::ExtrudePlane(_) | ExtrudeSurface::ExtrudeArc(_) => None,
})
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a face with the tag `{}`", tag),
source_ranges: vec![args.source_range],
})
})?
}
FaceTag::StartOrEnd(StartOrEnd::Start) => extrude_group.start_cap_id.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: "Expected a start face".to_string(),
source_ranges: vec![args.source_range],
})
})?,
FaceTag::StartOrEnd(StartOrEnd::End) => extrude_group.end_cap_id.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: "Expected an end face".to_string(),
source_ranges: vec![args.source_range],
})
})?,
};
face_ids.push(extrude_plane_id); face_ids.push(extrude_plane_id);
} }

View File

@ -10,18 +10,72 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
executor::{ executor::{
BasePath, ExtrudeGroup, ExtrudeSurface, Face, GeoMeta, MemoryItem, Path, Plane, PlaneType, Point2d, Point3d, BasePath, ExtrudeGroup, Face, GeoMeta, MemoryItem, Path, Plane, PlaneType, Point2d, Point3d, SketchGroup,
SketchGroup, SketchGroupSet, SketchSurface, SourceRange, UserVal, SketchGroupSet, SketchSurface, SourceRange, UserVal,
}, },
std::{ std::{
utils::{ utils::{
arc_angles, arc_center_and_end, get_tangent_point_from_previous_arc, get_tangential_arc_to_info, arc_angles, arc_center_and_end, get_tangent_point_from_previous_arc, get_tangential_arc_to_info,
get_x_component, get_y_component, intersection_with_parallel_line, TangentialArcInfoInput, get_x_component, get_y_component, intersection_with_parallel_line, TangentialArcInfoInput,
}, },
Args, ExtrudeGroupSet, Args,
}, },
}; };
/// A tag for a face.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, FromStr, Display)]
#[ts(export)]
#[serde(rename_all = "snake_case", untagged)]
#[display("{0}")]
pub enum FaceTag {
StartOrEnd(StartOrEnd),
/// A string tag for the face you want to sketch on.
String(String),
}
impl FaceTag {
/// Get the face id from the tag.
pub async fn get_face_id(
&self,
extrude_group: &ExtrudeGroup,
args: &Args,
must_be_planar: bool,
) -> Result<uuid::Uuid, KclError> {
match self {
FaceTag::String(ref s) => args.get_adjacent_face_to_tag(extrude_group, s, must_be_planar).await,
FaceTag::StartOrEnd(StartOrEnd::Start) => extrude_group.start_cap_id.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: "Expected a start face".to_string(),
source_ranges: vec![args.source_range],
})
}),
FaceTag::StartOrEnd(StartOrEnd::End) => extrude_group.end_cap_id.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: "Expected an end face".to_string(),
source_ranges: vec![args.source_range],
})
}),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, FromStr, Display)]
#[ts(export)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
pub enum StartOrEnd {
/// The start face as in before you extruded. This could also be known as the bottom
/// face. But we do not call it bottom because it would be the top face if you
/// extruded it in the opposite direction or flipped the camera.
#[serde(rename = "start", alias = "START")]
Start,
/// The end face after you extruded. This could also be known as the top
/// face. But we do not call it top because it would be the bottom face if you
/// extruded it in the opposite direction or flipped the camera.
#[serde(rename = "end", alias = "END")]
End,
}
/// Draw a line to a point. /// Draw a line to a point.
pub async fn line_to(args: Args) -> Result<MemoryItem, KclError> { pub async fn line_to(args: Args) -> Result<MemoryItem, KclError> {
let (to, sketch_group, tag): ([f64; 2], Box<SketchGroup>, Option<String>) = let (to, sketch_group, tag): ([f64; 2], Box<SketchGroup>, Option<String>) =
@ -857,7 +911,7 @@ impl From<PlaneData> for Plane {
/// Start a sketch on a specific plane or face. /// Start a sketch on a specific plane or face.
pub async fn start_sketch_on(args: Args) -> Result<MemoryItem, KclError> { pub async fn start_sketch_on(args: Args) -> Result<MemoryItem, KclError> {
let (data, tag): (SketchData, Option<SketchOnFaceTag>) = args.get_data_and_optional_tag()?; let (data, tag): (SketchData, Option<FaceTag>) = args.get_data_and_optional_tag()?;
match inner_start_sketch_on(data, tag, args).await? { match inner_start_sketch_on(data, tag, args).await? {
SketchSurface::Plane(plane) => Ok(MemoryItem::Plane(plane)), SketchSurface::Plane(plane) => Ok(MemoryItem::Plane(plane)),
@ -969,11 +1023,7 @@ pub async fn start_sketch_on(args: Args) -> Result<MemoryItem, KclError> {
#[stdlib { #[stdlib {
name = "startSketchOn", name = "startSketchOn",
}] }]
async fn inner_start_sketch_on( async fn inner_start_sketch_on(data: SketchData, tag: Option<FaceTag>, args: Args) -> Result<SketchSurface, KclError> {
data: SketchData,
tag: Option<SketchOnFaceTag>,
args: Args,
) -> Result<SketchSurface, KclError> {
match data { match data {
SketchData::Plane(plane_data) => { SketchData::Plane(plane_data) => {
let plane = start_sketch_on_plane(plane_data, args).await?; let plane = start_sketch_on_plane(plane_data, args).await?;
@ -992,82 +1042,12 @@ async fn inner_start_sketch_on(
} }
} }
/// A tag for sketch on face.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, FromStr, Display)]
#[ts(export)]
#[serde(rename_all = "snake_case", untagged)]
#[display("{0}")]
pub enum SketchOnFaceTag {
StartOrEnd(StartOrEnd),
/// A string tag for the face you want to sketch on.
String(String),
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, FromStr, Display)]
#[ts(export)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
pub enum StartOrEnd {
/// The start face as in before you extruded. This could also be known as the bottom
/// face. But we do not call it bottom because it would be the top face if you
/// extruded it in the opposite direction or flipped the camera.
#[serde(rename = "start", alias = "START")]
Start,
/// The end face after you extruded. This could also be known as the top
/// face. But we do not call it top because it would be the bottom face if you
/// extruded it in the opposite direction or flipped the camera.
#[serde(rename = "end", alias = "END")]
End,
}
async fn start_sketch_on_face( async fn start_sketch_on_face(
extrude_group: Box<ExtrudeGroup>, extrude_group: Box<ExtrudeGroup>,
tag: SketchOnFaceTag, tag: FaceTag,
args: Args, args: Args,
) -> Result<Box<Face>, KclError> { ) -> Result<Box<Face>, KclError> {
let extrude_plane_id = match tag { let extrude_plane_id = tag.get_face_id(&extrude_group, &args, true).await?;
SketchOnFaceTag::String(ref s) => {
if s.is_empty() {
return Err(KclError::Type(KclErrorDetails {
message: "Expected a non-empty tag for the face to sketch on".to_string(),
source_ranges: vec![args.source_range],
}));
}
extrude_group
.value
.iter()
.find_map(|extrude_surface| match extrude_surface {
ExtrudeSurface::ExtrudePlane(extrude_plane) if extrude_plane.name == *s => {
Some(Ok(extrude_plane.face_id))
}
ExtrudeSurface::ExtrudeArc(extrude_arc) if extrude_arc.name == *s => {
Some(Err(KclError::Type(KclErrorDetails {
message: format!("Cannot sketch on a non-planar surface: `{}`", tag),
source_ranges: vec![args.source_range],
})))
}
ExtrudeSurface::ExtrudePlane(_) | ExtrudeSurface::ExtrudeArc(_) => None,
})
.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: format!("Expected a face with the tag `{}`", tag),
source_ranges: vec![args.source_range],
})
})??
}
SketchOnFaceTag::StartOrEnd(StartOrEnd::Start) => extrude_group.start_cap_id.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: "Expected a start face to sketch on".to_string(),
source_ranges: vec![args.source_range],
})
})?,
SketchOnFaceTag::StartOrEnd(StartOrEnd::End) => extrude_group.end_cap_id.ok_or_else(|| {
KclError::Type(KclErrorDetails {
message: "Expected an end face to sketch on".to_string(),
source_ranges: vec![args.source_range],
})
})?,
};
Ok(Box::new(Face { Ok(Box::new(Face {
id: extrude_plane_id, id: extrude_plane_id,
@ -1176,7 +1156,7 @@ pub(crate) async fn inner_start_profile_at(
if let SketchSurface::Face(face) = &sketch_surface { if let SketchSurface::Face(face) = &sketch_surface {
// Flush the batch for our fillets/chamfers if there are any. // 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. // If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_extrude_group_set(&ExtrudeGroupSet::ExtrudeGroup(face.extrude_group.clone())) args.flush_batch_for_extrude_group_set(face.extrude_group.clone().into())
.await?; .await?;
} }
@ -1851,55 +1831,29 @@ async fn inner_hole(
sketch_group: Box<SketchGroup>, sketch_group: Box<SketchGroup>,
args: Args, args: Args,
) -> Result<Box<SketchGroup>, KclError> { ) -> Result<Box<SketchGroup>, KclError> {
//TODO: batch these (once we have batch) let hole_sketch_groups: Vec<Box<SketchGroup>> = hole_sketch_group.into();
for hole_sketch_group in hole_sketch_groups {
args.batch_modeling_cmd(
uuid::Uuid::new_v4(),
ModelingCmd::Solid2DAddHole {
object_id: sketch_group.id,
hole_id: hole_sketch_group.id,
},
)
.await?;
match hole_sketch_group { // suggestion (mike)
SketchGroupSet::SketchGroup(hole_sketch_group) => { // we also hide the source hole since its essentially "consumed" by this operation
args.batch_modeling_cmd( args.batch_modeling_cmd(
uuid::Uuid::new_v4(), uuid::Uuid::new_v4(),
ModelingCmd::Solid2DAddHole { ModelingCmd::ObjectVisible {
object_id: sketch_group.id, object_id: hole_sketch_group.id,
hole_id: hole_sketch_group.id, hidden: true,
}, },
) )
.await?; .await?;
// suggestion (mike)
// we also hide the source hole since its essentially "consumed" by this operation
args.batch_modeling_cmd(
uuid::Uuid::new_v4(),
ModelingCmd::ObjectVisible {
object_id: hole_sketch_group.id,
hidden: true,
},
)
.await?;
}
SketchGroupSet::SketchGroups(hole_sketch_groups) => {
for hole_sketch_group in hole_sketch_groups {
args.batch_modeling_cmd(
uuid::Uuid::new_v4(),
ModelingCmd::Solid2DAddHole {
object_id: sketch_group.id,
hole_id: hole_sketch_group.id,
},
)
.await?;
// suggestion (mike)
// we also hide the source hole since its essentially "consumed" by this operation
args.batch_modeling_cmd(
uuid::Uuid::new_v4(),
ModelingCmd::ObjectVisible {
object_id: hole_sketch_group.id,
hidden: true,
},
)
.await?;
}
}
} }
// TODO: should we modify the sketch group to include the hole data, probably?
Ok(sketch_group) Ok(sketch_group)
} }
@ -1936,35 +1890,35 @@ mod tests {
assert_eq!(str_json, "\"start\""); assert_eq!(str_json, "\"start\"");
str_json = "\"end\"".to_string(); str_json = "\"end\"".to_string();
let data: crate::std::sketch::SketchOnFaceTag = serde_json::from_str(&str_json).unwrap(); let data: crate::std::sketch::FaceTag = serde_json::from_str(&str_json).unwrap();
assert_eq!( assert_eq!(
data, data,
crate::std::sketch::SketchOnFaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::End) crate::std::sketch::FaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::End)
); );
str_json = "\"thing\"".to_string(); str_json = "\"thing\"".to_string();
let data: crate::std::sketch::SketchOnFaceTag = serde_json::from_str(&str_json).unwrap(); let data: crate::std::sketch::FaceTag = serde_json::from_str(&str_json).unwrap();
assert_eq!(data, crate::std::sketch::SketchOnFaceTag::String("thing".to_string())); assert_eq!(data, crate::std::sketch::FaceTag::String("thing".to_string()));
str_json = "\"END\"".to_string(); str_json = "\"END\"".to_string();
let data: crate::std::sketch::SketchOnFaceTag = serde_json::from_str(&str_json).unwrap(); let data: crate::std::sketch::FaceTag = serde_json::from_str(&str_json).unwrap();
assert_eq!( assert_eq!(
data, data,
crate::std::sketch::SketchOnFaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::End) crate::std::sketch::FaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::End)
); );
str_json = "\"start\"".to_string(); str_json = "\"start\"".to_string();
let data: crate::std::sketch::SketchOnFaceTag = serde_json::from_str(&str_json).unwrap(); let data: crate::std::sketch::FaceTag = serde_json::from_str(&str_json).unwrap();
assert_eq!( assert_eq!(
data, data,
crate::std::sketch::SketchOnFaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::Start) crate::std::sketch::FaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::Start)
); );
str_json = "\"START\"".to_string(); str_json = "\"START\"".to_string();
let data: crate::std::sketch::SketchOnFaceTag = serde_json::from_str(&str_json).unwrap(); let data: crate::std::sketch::FaceTag = serde_json::from_str(&str_json).unwrap();
assert_eq!( assert_eq!(
data, data,
crate::std::sketch::SketchOnFaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::Start) crate::std::sketch::FaceTag::StartOrEnd(crate::std::sketch::StartOrEnd::Start)
); );
} }
} }

View File

@ -1218,7 +1218,7 @@ const part002 = startSketchOn(part001, "here")
assert!(result.is_err()); assert!(result.is_err());
assert_eq!( assert_eq!(
result.err().unwrap().to_string(), result.err().unwrap().to_string(),
r#"type: KclErrorDetails { source_ranges: [SourceRange([281, 311])], message: "Cannot sketch on a non-planar surface: `here`" }"# r#"type: KclErrorDetails { source_ranges: [SourceRange([281, 311])], message: "Tag `here` is a non-planar surface" }"#
); );
} }
@ -1897,7 +1897,7 @@ const secondSketch = startSketchOn(part001, '')
assert!(result.is_err()); assert!(result.is_err());
assert_eq!( assert_eq!(
result.err().unwrap().to_string(), result.err().unwrap().to_string(),
r#"type: KclErrorDetails { source_ranges: [SourceRange([272, 298])], message: "Expected a non-empty tag for the face to sketch on" }"# r#"type: KclErrorDetails { source_ranges: [SourceRange([272, 298])], message: "Expected a non-empty tag for the face" }"#
); );
} }
@ -2366,3 +2366,67 @@ const pattn2 = patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], repet
1.0, 1.0,
); );
} }
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_tag_chamfer_with_more_than_one_edge_should_fail() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const part001 = cube([0,0], 20)
|> close(%, 'line1')
|> extrude(20, %)
|> chamfer({
length: 10,
tags: ['line1', getOppositeEdge('line1',%)]
}, %, 'chamfer1')
"#;
let result = execute_and_snapshot(code, UnitLength::Mm).await;
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"type: KclErrorDetails { source_ranges: [SourceRange([272, 365])], message: "You can only tag one edge at a time with a tagged chamfer. Either delete the tag for the chamfer fn if you don't need it OR separate into individual chamfer functions for each tag." }"#
);
}
#[tokio::test(flavor = "multi_thread")]
#[ignore] // Ignore until this is fixed in the engine: https://github.com/KittyCAD/engine/issues/2260
async fn serial_test_sketch_on_face_of_chamfer() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const part001 = cube([0,0], 20)
|> close(%, 'line1')
|> extrude(20, %)
|> chamfer({
length: 10,
tags: [getOppositeEdge('line1',%)]
}, %, 'chamfer1')
const sketch001 = startSketchOn(part001, 'chamfer1')
|> startProfileAt([4.28, 3.83], %)
|> line([2.17, -0.03], %)
|> line([-0.07, -1.8], %)
|> line([-2.07, 0.05], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
|> extrude(10, %)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_of_chamfer.png", &result, 1.0);
}