From 0d1852bbc3b097d21c7bbb9882b945d3c01ff2de Mon Sep 17 00:00:00 2001 From: Jess Frazelle Date: Thu, 7 Mar 2024 15:35:26 -0800 Subject: [PATCH] add optional tag to circle (#1669) --- docs/kcl/std.json | 1199 ++++------------- docs/kcl/std.md | 201 +-- src/wasm-lib/kcl/src/ast/types.rs | 27 +- src/wasm-lib/kcl/src/std/shapes.rs | 15 +- src/wasm-lib/kcl/src/std/sketch.rs | 111 +- src/wasm-lib/tests/executor/main.rs | 26 + .../outputs/sketch_on_face_circle_tagged.png | Bin 0 -> 116535 bytes 7 files changed, 367 insertions(+), 1212 deletions(-) create mode 100644 src/wasm-lib/tests/executor/outputs/sketch_on_face_circle_tagged.png diff --git a/docs/kcl/std.json b/docs/kcl/std.json index 4de6b2ae9..9349825c2 100644 --- a/docs/kcl/std.json +++ b/docs/kcl/std.json @@ -13914,38 +13914,7 @@ "description": "Data to draw an arc.", "anyOf": [ { - "description": "Angles and radius with a tag.", - "type": "object", - "required": [ - "angle_end", - "angle_start", - "radius", - "tag" - ], - "properties": { - "angle_end": { - "description": "The end angle.", - "type": "number", - "format": "double" - }, - "angle_start": { - "description": "The start angle.", - "type": "number", - "format": "double" - }, - "radius": { - "description": "The radius.", - "type": "number", - "format": "double" - }, - "tag": { - "description": "The tag.", - "type": "string" - } - } - }, - { - "description": "Angles and radius.", + "description": "Angles and radius with an optional tag.", "type": "object", "required": [ "angle_end", @@ -13967,16 +13936,21 @@ "description": "The radius.", "type": "number", "format": "double" + }, + "tag": { + "description": "The tag.", + "default": null, + "type": "string", + "nullable": true } } }, { - "description": "Center, to and radius with a tag.", + "description": "Center, to and radius with an optional tag.", "type": "object", "required": [ "center", "radius", - "tag", "to" ], "properties": { @@ -13997,43 +13971,9 @@ }, "tag": { "description": "The tag.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - { - "description": "Center, to and radius.", - "type": "object", - "required": [ - "center", - "radius", - "to" - ], - "properties": { - "center": { - "description": "The center.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "radius": { - "description": "The radius.", - "type": "number", - "format": "double" + "default": null, + "type": "string", + "nullable": true }, "to": { "description": "The to point.", @@ -16044,95 +15984,49 @@ "type": "BezierData", "schema": { "description": "Data to draw a bezier curve.", - "anyOf": [ - { - "description": "Points with a tag.", - "type": "object", - "required": [ - "control1", - "control2", - "tag", - "to" - ], - "properties": { - "control1": { - "description": "The first control point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "control2": { - "description": "The second control point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - } - } + "type": "object", + "required": [ + "control1", + "control2", + "to" + ], + "properties": { + "control1": { + "description": "The first control point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - { - "description": "Points.", - "type": "object", - "required": [ - "control1", - "control2", - "to" - ], - "properties": { - "control1": { - "description": "The first control point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "control2": { - "description": "The second control point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - } - } + "control2": { + "description": "The second control point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "tag": { + "description": "The tag.", + "type": "string", + "nullable": true + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 } - ] + } }, "required": true }, @@ -18123,178 +18017,16 @@ "name": "surface", "type": "SketchSurface", "schema": { - "description": "Data for start sketch on. You can start a sketch on a plane or an extrude group.", - "anyOf": [ + "description": "A sketch group type.", + "oneOf": [ { - "description": "Data for a plane.", - "oneOf": [ - { - "description": "The XY plane.", - "type": "string", - "enum": [ - "XY" - ] - }, - { - "description": "The opposite side of the XY plane.", - "type": "string", - "enum": [ - "-XY" - ] - }, - { - "description": "The XZ plane.", - "type": "string", - "enum": [ - "XZ" - ] - }, - { - "description": "The opposite side of the XZ plane.", - "type": "string", - "enum": [ - "-XZ" - ] - }, - { - "description": "The YZ plane.", - "type": "string", - "enum": [ - "YZ" - ] - }, - { - "description": "The opposite side of the YZ plane.", - "type": "string", - "enum": [ - "-YZ" - ] - }, - { - "description": "A defined plane.", - "type": "object", - "required": [ - "plane" - ], - "properties": { - "plane": { - "type": "object", - "required": [ - "origin", - "x_axis", - "y_axis", - "z_axis" - ], - "properties": { - "origin": { - "description": "Origin of the plane.", - "type": "object", - "required": [ - "x", - "y", - "z" - ], - "properties": { - "x": { - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - }, - "z": { - "type": "number", - "format": "double" - } - } - }, - "x_axis": { - "description": "What should the plane’s X axis be?", - "type": "object", - "required": [ - "x", - "y", - "z" - ], - "properties": { - "x": { - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - }, - "z": { - "type": "number", - "format": "double" - } - } - }, - "y_axis": { - "description": "What should the plane’s Y axis be?", - "type": "object", - "required": [ - "x", - "y", - "z" - ], - "properties": { - "x": { - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - }, - "z": { - "type": "number", - "format": "double" - } - } - }, - "z_axis": { - "description": "The z-axis (normal).", - "type": "object", - "required": [ - "x", - "y", - "z" - ], - "properties": { - "x": { - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - }, - "z": { - "type": "number", - "format": "double" - } - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - { - "description": "An extrude group is a collection of extrude surfaces.", + "description": "A plane.", "type": "object", "required": [ "__meta", - "height", "id", - "position", - "rotation", - "sketchGroupValues", + "origin", + "type", "value", "xAxis", "yAxis", @@ -18302,7 +18034,6 @@ ], "properties": { "__meta": { - "description": "Metadata.", "type": "array", "items": { "description": "Metadata.", @@ -18325,648 +18056,62 @@ } } }, - "endCapId": { - "description": "The id of the extrusion end cap", - "type": "string", - "format": "uuid", - "nullable": true - }, - "height": { - "description": "The height of the extrude group.", - "type": "number", - "format": "double" - }, "id": { - "description": "The id of the extrude group.", + "description": "The id of the plane.", "type": "string", "format": "uuid" }, - "position": { - "description": "The position of the extrude group.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 3, - "minItems": 3 - }, - "rotation": { - "description": "The rotation of the extrude group.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 4, - "minItems": 4 - }, - "sketchGroupValues": { - "description": "The sketch group paths.", - "type": "array", - "items": { - "description": "A path.", - "oneOf": [ - { - "description": "A path that goes to a point.", - "type": "object", - "required": [ - "__geoMeta", - "from", - "name", - "to", - "type" - ], - "properties": { - "__geoMeta": { - "description": "Metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "name": { - "description": "The name of the path.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "ToPoint" - ] - } - } - }, - { - "description": "A arc that is tangential to the last path segment that goes to a point", - "type": "object", - "required": [ - "__geoMeta", - "ccw", - "center", - "from", - "name", - "to", - "type" - ], - "properties": { - "__geoMeta": { - "description": "Metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - "ccw": { - "description": "arc's direction", - "type": "boolean" - }, - "center": { - "description": "the arc's center", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "name": { - "description": "The name of the path.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "TangentialArcTo" - ] - } - } - }, - { - "description": "A arc that is tangential to the last path segment", - "type": "object", - "required": [ - "__geoMeta", - "from", - "name", - "to", - "type" - ], - "properties": { - "__geoMeta": { - "description": "Metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "name": { - "description": "The name of the path.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "TangentialArc" - ] - } - } - }, - { - "description": "A path that is horizontal.", - "type": "object", - "required": [ - "__geoMeta", - "from", - "name", - "to", - "type", - "x" - ], - "properties": { - "__geoMeta": { - "description": "Metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "name": { - "description": "The name of the path.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "Horizontal" - ] - }, - "x": { - "description": "The x coordinate.", - "type": "number", - "format": "double" - } - } - }, - { - "description": "An angled line to.", - "type": "object", - "required": [ - "__geoMeta", - "from", - "name", - "to", - "type" - ], - "properties": { - "__geoMeta": { - "description": "Metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "name": { - "description": "The name of the path.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "AngledLineTo" - ] - }, - "x": { - "description": "The x coordinate.", - "type": "number", - "format": "double", - "nullable": true - }, - "y": { - "description": "The y coordinate.", - "type": "number", - "format": "double", - "nullable": true - } - } - }, - { - "description": "A base path.", - "type": "object", - "required": [ - "__geoMeta", - "from", - "name", - "to", - "type" - ], - "properties": { - "__geoMeta": { - "description": "Metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - } - } - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "name": { - "description": "The name of the path.", - "type": "string" - }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "Base" - ] - } - } - } - ] + "origin": { + "description": "Origin of the plane.", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } } }, - "startCapId": { - "description": "The id of the extrusion start cap", + "type": { "type": "string", - "format": "uuid", - "nullable": true + "enum": [ + "plane" + ] }, "value": { - "description": "The extrude surfaces.", - "type": "array", - "items": { - "description": "An extrude surface.", - "oneOf": [ - { - "description": "An extrude plane.", - "type": "object", - "required": [ - "faceId", - "id", - "name", - "position", - "rotation", - "sourceRange", - "type" - ], - "properties": { - "faceId": { - "description": "The face id for the extrude plane.", - "type": "string", - "format": "uuid" - }, - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "name": { - "description": "The name.", - "type": "string" - }, - "position": { - "description": "The position.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 3, - "minItems": 3 - }, - "rotation": { - "description": "The rotation.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 4, - "minItems": 4 - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "extrudePlane" - ] - } - } - }, - { - "description": "An extruded arc.", - "type": "object", - "required": [ - "faceId", - "id", - "name", - "position", - "rotation", - "sourceRange", - "type" - ], - "properties": { - "faceId": { - "description": "The face id for the extrude plane.", - "type": "string", - "format": "uuid" - }, - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" - }, - "name": { - "description": "The name.", - "type": "string" - }, - "position": { - "description": "The position.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 3, - "minItems": 3 - }, - "rotation": { - "description": "The rotation.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 4, - "minItems": 4 - }, - "sourceRange": { - "description": "The source range.", - "type": "array", - "items": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "maxItems": 2, - "minItems": 2 - }, - "type": { - "type": "string", - "enum": [ - "extrudeArc" - ] - } - } - } - ] - } + "description": "Type for a plane.", + "oneOf": [ + { + "type": "string", + "enum": [ + "XY", + "XZ", + "YZ" + ] + }, + { + "description": "A custom plane.", + "type": "string", + "enum": [ + "Custom" + ] + } + ] }, "xAxis": { - "description": "The x-axis of the extrude group base plane in the 3D space", + "description": "What should the plane’s X axis be?", "type": "object", "required": [ "x", @@ -18989,7 +18134,7 @@ } }, "yAxis": { - "description": "The y-axis of the extrude group base plane in the 3D space", + "description": "What should the plane’s Y axis be?", "type": "object", "required": [ "x", @@ -19012,7 +18157,135 @@ } }, "zAxis": { - "description": "The z-axis of the extrude group base plane in the 3D space", + "description": "The z-axis (normal).", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "__meta", + "id", + "sketchGroupId", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "__meta": { + "type": "array", + "items": { + "description": "Metadata.", + "type": "object", + "required": [ + "sourceRange" + ], + "properties": { + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + } + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "sketchGroupId": { + "description": "The original sketch group id of the object we are sketching on.", + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string", + "enum": [ + "face" + ] + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face’s X axis be?", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "yAxis": { + "description": "What should the face’s Y axis be?", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "zAxis": { + "description": "The z-axis (normal).", "type": "object", "required": [ "x", @@ -19039,6 +18312,14 @@ ] }, "required": true + }, + { + "name": "tag", + "type": "String", + "schema": { + "type": "string" + }, + "required": false } ], "returnValue": { diff --git a/docs/kcl/std.md b/docs/kcl/std.md index abfbbf0a7..2e40789f0 100644 --- a/docs/kcl/std.md +++ b/docs/kcl/std.md @@ -2654,14 +2654,6 @@ arc(data: ArcData, sketch_group: SketchGroup) -> SketchGroup // The tag. tag: string, } | -{ - // The end angle. - angle_end: number, - // The start angle. - angle_start: number, - // The radius. - radius: number, -} | { // The center. center: [number, number], @@ -2671,14 +2663,6 @@ arc(data: ArcData, sketch_group: SketchGroup) -> SketchGroup tag: string, // The to point. to: [number, number], -} | -{ - // The center. - center: [number, number], - // The radius. - radius: number, - // The to point. - to: [number, number], } ``` * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) @@ -3078,14 +3062,6 @@ bezierCurve(data: BezierData, sketch_group: SketchGroup) -> SketchGroup tag: string, // The to point. to: [number, number], -} | -{ - // The first control point. - control1: [number, number], - // The second control point. - control2: [number, number], - // The to point. - to: [number, number], } ``` * `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED) @@ -3449,171 +3425,67 @@ Sketch a circle on the given plane ``` -circle(center: [number, number], radius: number, surface: SketchSurface) -> SketchGroup +circle(center: [number, number], radius: number, surface: SketchSurface, tag?: String) -> SketchGroup ``` #### Arguments * `center`: `[number, number]` (REQUIRED) * `radius`: `number` (REQUIRED) -* `surface`: `SketchSurface` - Data for start sketch on. You can start a sketch on a plane or an extrude group. (REQUIRED) +* `surface`: `SketchSurface` - A sketch group type. (REQUIRED) ``` -"XY" | -"-XY" | -"XZ" | -"-XZ" | -"YZ" | -"-YZ" | { - plane: { + // The id of the plane. + id: uuid, // Origin of the plane. origin: { x: number, y: number, z: number, }, + type: "plane", + // Type for a plane. + value: "XY" | "XZ" | "YZ" | "Custom", // What should the plane’s X axis be? - x_axis: { - x: number, - y: number, - z: number, -}, - // What should the plane’s Y axis be? - y_axis: { - x: number, - y: number, - z: number, -}, - // The z-axis (normal). - z_axis: { - x: number, - y: number, - z: number, -}, -}, -} | -{ - // The id of the extrusion end cap - endCapId: uuid, - // The height of the extrude group. - height: number, - // The id of the extrude group. - id: uuid, - // The position of the extrude group. - position: [number, number, number], - // The rotation of the extrude group. - rotation: [number, number, number, number], - // The sketch group paths. - sketchGroupValues: [{ - // The from point. - from: [number, number], - // The name of the path. - name: string, - // The to point. - to: [number, number], - type: "ToPoint", -} | -{ - // arc's direction - ccw: string, - // the arc's center - center: [number, number], - // The from point. - from: [number, number], - // The name of the path. - name: string, - // The to point. - to: [number, number], - type: "TangentialArcTo", -} | -{ - // The from point. - from: [number, number], - // The name of the path. - name: string, - // The to point. - to: [number, number], - type: "TangentialArc", -} | -{ - // The from point. - from: [number, number], - // The name of the path. - name: string, - // The to point. - to: [number, number], - type: "Horizontal", - // The x coordinate. - x: number, -} | -{ - // The from point. - from: [number, number], - // The name of the path. - name: string, - // The to point. - to: [number, number], - type: "AngledLineTo", - // The x coordinate. - x: number, - // The y coordinate. - y: number, -} | -{ - // The from point. - from: [number, number], - // The name of the path. - name: string, - // The to point. - to: [number, number], - type: "Base", -}], - // The id of the extrusion start cap - startCapId: uuid, - // The extrude surfaces. - value: [{ - // The face id for the extrude plane. - faceId: uuid, - // The id of the geometry. - id: uuid, - // The name. - name: string, - // The position. - position: [number, number, number], - // The rotation. - rotation: [number, number, number, number], - // The source range. - sourceRange: [number, number], - type: "extrudePlane", -} | -{ - // The face id for the extrude plane. - faceId: uuid, - // The id of the geometry. - id: uuid, - // The name. - name: string, - // The position. - position: [number, number, number], - // The rotation. - rotation: [number, number, number, number], - // The source range. - sourceRange: [number, number], - type: "extrudeArc", -}], - // The x-axis of the extrude group base plane in the 3D space xAxis: { x: number, y: number, z: number, }, - // The y-axis of the extrude group base plane in the 3D space + // What should the plane’s Y axis be? yAxis: { x: number, y: number, z: number, }, - // The z-axis of the extrude group base plane in the 3D space + // The z-axis (normal). + zAxis: { + x: number, + y: number, + z: number, +}, +} | +{ + // The id of the face. + id: uuid, + // The original sketch group id of the object we are sketching on. + sketchGroupId: uuid, + type: "face", + // The tag of the face. + value: string, + // What should the face’s X axis be? + xAxis: { + x: number, + y: number, + z: number, +}, + // What should the face’s Y axis be? + yAxis: { + x: number, + y: number, + z: number, +}, + // The z-axis (normal). zAxis: { x: number, y: number, @@ -3621,6 +3493,7 @@ circle(center: [number, number], radius: number, surface: SketchSurface) -> Sket }, } ``` +* `tag`: `String` (OPTIONAL) #### Returns diff --git a/src/wasm-lib/kcl/src/ast/types.rs b/src/wasm-lib/kcl/src/ast/types.rs index 3543b3b46..2cdb129ca 100644 --- a/src/wasm-lib/kcl/src/ast/types.rs +++ b/src/wasm-lib/kcl/src/ast/types.rs @@ -1084,11 +1084,17 @@ impl CallExpression { } FunctionKind::Std(func) => { let function_expression = func.function(); - if fn_args.len() != function_expression.params.len() { + let parts = function_expression.clone().into_parts().map_err(|e| { + KclError::Semantic(KclErrorDetails { + message: format!("Error getting parts of function: {}", e), + source_ranges: vec![self.into()], + }) + })?; + if fn_args.len() < parts.params_required.len() || fn_args.len() > function_expression.params.len() { return Err(KclError::Semantic(KclErrorDetails { message: format!( "this function expected {} arguments, got {}", - function_expression.params.len(), + parts.params_required.len(), fn_args.len(), ), source_ranges: vec![self.into()], @@ -1097,13 +1103,28 @@ impl CallExpression { // Add the arguments to the memory. let mut fn_memory = memory.clone(); - for (index, param) in function_expression.params.iter().enumerate() { + for (index, param) in parts.params_required.iter().enumerate() { fn_memory.add( ¶m.identifier.name, fn_args.get(index).unwrap().clone(), param.identifier.clone().into(), )?; } + // Add the optional arguments to the memory. + for (index, param) in parts.params_optional.iter().enumerate() { + if let Some(arg) = fn_args.get(index + parts.params_required.len()) { + fn_memory.add(¶m.identifier.name, arg.clone(), param.identifier.clone().into())?; + } else { + fn_memory.add( + ¶m.identifier.name, + MemoryItem::UserVal(UserVal { + value: serde_json::value::Value::Null, + meta: Default::default(), + }), + param.identifier.clone().into(), + )?; + } + } // Call the stdlib function let p = func.function().clone().body; diff --git a/src/wasm-lib/kcl/src/std/shapes.rs b/src/wasm-lib/kcl/src/std/shapes.rs index a8d582dff..6bd376853 100644 --- a/src/wasm-lib/kcl/src/std/shapes.rs +++ b/src/wasm-lib/kcl/src/std/shapes.rs @@ -8,12 +8,13 @@ use crate::{ }; pub const CIRCLE_FN: &str = r#" -(center, radius, surface) => { +(center, radius, surface, tag?) => { const sg = startProfileAt([center[0] + radius, center[1]], surface) |> arc({ angle_end: 360, angle_start: 0, - radius: radius + radius: radius, + tag: tag }, %) |> close(%) return sg @@ -89,10 +90,18 @@ impl StdLibFn for Circle { args.push(crate::docs::StdLibFnArg { name: parameter.identifier.name.to_owned(), type_: "SketchSurface".to_string(), - schema: ::json_schema(&mut generator), + schema: ::json_schema(&mut generator), required: true, }); } + "tag" => { + args.push(crate::docs::StdLibFnArg { + name: parameter.identifier.name.to_owned(), + type_: "String".to_string(), + schema: ::json_schema(&mut generator), + required: false, + }); + } _ => panic!("Unknown parameter: {:?}", parameter.identifier.name), } } diff --git a/src/wasm-lib/kcl/src/std/sketch.rs b/src/wasm-lib/kcl/src/std/sketch.rs index 5914fb976..43ab03402 100644 --- a/src/wasm-lib/kcl/src/std/sketch.rs +++ b/src/wasm-lib/kcl/src/std/sketch.rs @@ -1130,18 +1130,7 @@ async fn inner_close( #[ts(export)] #[serde(rename_all = "camelCase", untagged)] pub enum ArcData { - /// Angles and radius with a tag. - AnglesAndRadiusWithTag { - /// The start angle. - angle_start: f64, - /// The end angle. - angle_end: f64, - /// The radius. - radius: f64, - /// The tag. - tag: String, - }, - /// Angles and radius. + /// Angles and radius with an optional tag. AnglesAndRadius { /// The start angle. angle_start: f64, @@ -1149,19 +1138,11 @@ pub enum ArcData { angle_end: f64, /// The radius. radius: f64, - }, - /// Center, to and radius with a tag. - CenterToRadiusWithTag { - /// The center. - center: [f64; 2], - /// The to point. - to: [f64; 2], - /// The radius. - radius: f64, /// The tag. - tag: String, + #[serde(default)] + tag: Option, }, - /// Center, to and radius. + /// Center, to and radius with an optional tag. CenterToRadius { /// The center. center: [f64; 2], @@ -1169,6 +1150,9 @@ pub enum ArcData { to: [f64; 2], /// The radius. radius: f64, + /// The tag. + #[serde(default)] + tag: Option, }, } @@ -1188,7 +1172,7 @@ async fn inner_arc(data: ArcData, sketch_group: Box, args: Args) -> let from: Point2d = sketch_group.get_coords_from_paths()?; let (center, angle_start, angle_end, radius, end) = match &data { - ArcData::AnglesAndRadiusWithTag { + ArcData::AnglesAndRadius { angle_start, angle_end, radius, @@ -1199,21 +1183,7 @@ async fn inner_arc(data: ArcData, sketch_group: Box, args: Args) -> let (center, end) = arc_center_and_end(from, a_start, a_end, *radius); (center, a_start, a_end, *radius, end) } - ArcData::AnglesAndRadius { - angle_start, - angle_end, - radius, - } => { - let a_start = Angle::from_degrees(*angle_start); - let a_end = Angle::from_degrees(*angle_end); - let (center, end) = arc_center_and_end(from, a_start, a_end, *radius); - (center, a_start, a_end, *radius, end) - } - ArcData::CenterToRadiusWithTag { center, to, radius, .. } => { - let (angle_start, angle_end) = arc_angles(from, center.into(), to.into(), *radius, args.source_range)?; - (center.into(), angle_start, angle_end, *radius, to.into()) - } - ArcData::CenterToRadius { center, to, radius } => { + ArcData::CenterToRadius { center, to, radius, .. } => { let (angle_start, angle_end) = arc_angles(from, center.into(), to.into(), *radius, args.source_range)?; (center.into(), angle_start, angle_end, *radius, to.into()) } @@ -1241,10 +1211,8 @@ async fn inner_arc(data: ArcData, sketch_group: Box, args: Args) -> from: from.into(), to: end.into(), name: match data { - ArcData::AnglesAndRadiusWithTag { tag, .. } => tag.to_string(), - ArcData::AnglesAndRadius { .. } => "".to_string(), - ArcData::CenterToRadiusWithTag { tag, .. } => tag.to_string(), - ArcData::CenterToRadius { .. } => "".to_string(), + ArcData::AnglesAndRadius { tag, .. } => tag.unwrap_or_default().to_string(), + ArcData::CenterToRadius { tag, .. } => tag.unwrap_or_default().to_string(), }, geo_meta: GeoMeta { id, @@ -1456,28 +1424,16 @@ async fn inner_tangential_arc_to( /// Data to draw a bezier curve. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[ts(export)] -#[serde(rename_all = "camelCase", untagged)] -pub enum BezierData { - /// Points with a tag. - PointsWithTag { - /// The to point. - to: [f64; 2], - /// The first control point. - control1: [f64; 2], - /// The second control point. - control2: [f64; 2], - /// The tag. - tag: String, - }, - /// Points. - Points { - /// The to point. - to: [f64; 2], - /// The first control point. - control1: [f64; 2], - /// The second control point. - control2: [f64; 2], - }, +#[serde(rename_all = "camelCase")] +pub struct BezierData { + /// The to point. + to: [f64; 2], + /// The first control point. + control1: [f64; 2], + /// The second control point. + control2: [f64; 2], + /// The tag. + tag: Option, } /// Draw a bezier curve. @@ -1499,16 +1455,9 @@ async fn inner_bezier_curve( ) -> Result, KclError> { let from = sketch_group.get_coords_from_paths()?; - let (to, control1, control2) = match &data { - BezierData::PointsWithTag { - to, control1, control2, .. - } => (to, control1, control2), - BezierData::Points { to, control1, control2 } => (to, control1, control2), - }; - let relative = true; - let delta = to; - let to = [from.x + to[0], from.y + to[1]]; + let delta = data.to; + let to = [from.x + data.to[0], from.y + data.to[1]]; let id = uuid::Uuid::new_v4(); @@ -1518,13 +1467,13 @@ async fn inner_bezier_curve( path: sketch_group.id, segment: kittycad::types::PathSegment::Bezier { control1: Point3D { - x: control1[0], - y: control1[1], + x: data.control1[0], + y: data.control1[1], z: 0.0, }, control2: Point3D { - x: control2[0], - y: control2[1], + x: data.control2[0], + y: data.control2[1], z: 0.0, }, end: Point3D { @@ -1542,11 +1491,7 @@ async fn inner_bezier_curve( base: BasePath { from: from.into(), to, - name: if let BezierData::PointsWithTag { tag, .. } = data { - tag.to_string() - } else { - "".to_string() - }, + name: data.tag.unwrap_or_default().to_string(), geo_meta: GeoMeta { id, metadata: args.source_range.into(), diff --git a/src/wasm-lib/tests/executor/main.rs b/src/wasm-lib/tests/executor/main.rs index 71cf727bf..c9824788e 100644 --- a/src/wasm-lib/tests/executor/main.rs +++ b/src/wasm-lib/tests/executor/main.rs @@ -1290,3 +1290,29 @@ const part002 = startSketchOn(part001, "end") .unwrap(); twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_circle.png", &result, 1.0); } + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_sketch_on_face_circle_tagged() { + 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(%) + |> extrude(20, %) + +const part002 = startSketchOn(part001, "end") + |> circle([0, 0], 5, %, "myCircle") + |> extrude(5, %) +"#; + + let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm) + .await + .unwrap(); + twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_circle_tagged.png", &result, 1.0); +} diff --git a/src/wasm-lib/tests/executor/outputs/sketch_on_face_circle_tagged.png b/src/wasm-lib/tests/executor/outputs/sketch_on_face_circle_tagged.png new file mode 100644 index 0000000000000000000000000000000000000000..b27fc6c67160cfc09b743d6664d64c73d3fa6cac GIT binary patch literal 116535 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 literal 0 HcmV?d00001