/// Sketching is the foundational activity for most KCL programs. A sketch is a two-dimensional /// drawing made from paths or shapes. A sketch is always drawn on a surface (either an abstract /// plane of a face of a solid). A sketch can be made into a solid by extruding it (or revolving, etc.). /// /// This module contains functions for creating and manipulating sketches, and making them into solids. @no_std @settings(defaultLengthUnit = mm, kclVersion = 1.0) /// Start a new 2-dimensional sketch on a specific plane or face. /// /// ### Sketch on Face Behavior /// /// There are some important behaviors to understand when sketching on a face: /// /// The resulting sketch will _include_ the face and thus Solid /// that was sketched on. So say you were to export the resulting Sketch / Solid /// from a sketch on a face, you would get both the artifact of the sketch /// on the face and the parent face / Solid itself. /// /// This is important to understand because if you were to then sketch on the /// resulting Solid, it would again include the face and parent Solid that was /// sketched on. This could go on indefinitely. /// /// The point is if you want to export the result of a sketch on a face, you /// only need to export the final Solid that was created from the sketch on the /// face, since it will include all the parent faces and Solids. /// /// /// ```kcl /// exampleSketch = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// /// exampleSketch002 = startSketchOn(example, face = END) /// |> startProfile(at = [1, 1]) /// |> line(end = [8, 0]) /// |> line(end = [0, 8]) /// |> line(end = [-8, 0]) /// |> close() /// /// example002 = extrude(exampleSketch002, length = 5) /// /// exampleSketch003 = startSketchOn(example002, face = END) /// |> startProfile(at = [2, 2]) /// |> line(end = [6, 0]) /// |> line(end = [0, 6]) /// |> line(end = [-6, 0]) /// |> close() /// /// example003 = extrude(exampleSketch003, length = 5) /// ``` /// /// ```kcl /// // Sketch on the end of an extruded face by tagging the end face. /// /// exampleSketch = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5, tagEnd = $end01) /// /// exampleSketch002 = startSketchOn(example, face = end01) /// |> startProfile(at = [1, 1]) /// |> line(end = [8, 0]) /// |> line(end = [0, 8]) /// |> line(end = [-8, 0]) /// |> close() /// /// example002 = extrude(exampleSketch002, length = 5, tagEnd = $end02) /// /// exampleSketch003 = startSketchOn(example002, face = end02) /// |> startProfile(at = [2, 2]) /// |> line(end = [6, 0]) /// |> line(end = [0, 6]) /// |> line(end = [-6, 0]) /// |> close() /// /// example003 = extrude(exampleSketch003, length = 5) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10], tag = $sketchingFace) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// /// exampleSketch002 = startSketchOn(example, face = sketchingFace) /// |> startProfile(at = [1, 1]) /// |> line(end = [8, 0]) /// |> line(end = [0, 8]) /// |> line(end = [-8, 0]) /// |> close(tag = $sketchingFace002) /// /// example002 = extrude(exampleSketch002, length = 10) /// /// exampleSketch003 = startSketchOn(example002, face = sketchingFace002) /// |> startProfile(at = [-8, 12]) /// |> line(end = [0, 6]) /// |> line(end = [6, 0]) /// |> line(end = [0, -6]) /// |> close() /// /// example003 = extrude(exampleSketch003, length = 5) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XY) /// |> startProfile(at = [4, 12]) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// /// example = revolve(exampleSketch, axis = Y, angle = 180deg) /// /// exampleSketch002 = startSketchOn(example, face = END) /// |> startProfile(at = [4.5, -5]) /// |> line(end = [0, 5]) /// |> line(end = [5, 0]) /// |> line(end = [0, -5]) /// |> close() /// /// example002 = extrude(exampleSketch002, length = 5) /// ``` /// /// ```kcl /// // Sketch on the end of a revolved face by tagging the end face. /// /// exampleSketch = startSketchOn(XY) /// |> startProfile(at = [4, 12]) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// /// example = revolve(exampleSketch, axis = Y, angle = 180deg, tagEnd = $end01) /// /// exampleSketch002 = startSketchOn(example, face = end01) /// |> startProfile(at = [4.5, -5]) /// |> line(end = [0, 5]) /// |> line(end = [5, 0]) /// |> line(end = [0, -5]) /// |> close() /// /// example002 = extrude(exampleSketch002, length = 5) /// ``` /// /// ```kcl /// a1 = startSketchOn({ /// origin = { x = 0, y = 0, z = 0 }, /// xAxis = { x = 1, y = 0, z = 0 }, /// yAxis = { x = 0, y = 1, z = 0 }, /// zAxis = { x = 0, y = 0, z = 1 } /// }) /// |> startProfile(at = [0, 0]) /// |> line(end = [100.0, 0]) /// |> yLine(length = -100.0) /// |> xLine(length = -100.0) /// |> yLine(length = 100.0) /// |> close() /// |> extrude(length = 3.14) /// ``` @(impl = std_rust) export fn startSketchOn( /// Profile whose start is being used. @planeOrSolid: Solid | Plane, /// Identify a face of a solid if a solid is specified as the input argument (`planeOrSolid`). face?: TaggedFace, ): Plane | Face {} /// Start a new profile at a given point. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(-XZ) /// |> startProfile(at = [10, 10]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(-XZ) /// |> startProfile(at = [-10, 23]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn startProfile( /// What to start the profile on. @startProfileOn: Plane | Face, /// Where to start the profile. An absolute point. @(snippetArray = ["0", "0"]) at: Point2d, /// Tag this first starting point. tag?: TagDecl, ): Sketch {} /// Sketch a rectangle. /// /// ``` /// exampleSketch = startSketchOn(-XZ) /// |> rectangle(center = [0, 0], width = 10, height = 5) // |> extrude(length = 2) /// ``` /// /// ``` /// exampleSketch = startSketchOn(-XZ) /// |> rectangle(corner = [0, 0], width = 10, height = 5) // |> extrude(length = 2) /// ``` @(impl = std_rust) export fn rectangle( /// Sketch to extend, or plane or surface to sketch on. @sketchOrSurface: Sketch | Plane | Face, /// Rectangle's width along X axis. width: number(Length), /// Rectangle's height along Y axis. height: number(Length), /// The center of the rectangle. /// Incompatible with `corner`. @(snippetArray = ["0", "0"]) center?: Point2d, /// The corner of the rectangle. /// Incompatible with `center`. /// This will be the corner which is most negative on /// both X and Y axes. @(snippetArray = ["0", "0"]) corner?: Point2d, ): Sketch {} /// Construct a 2-dimensional circle, of the specified radius, centered at /// the provided (x, y) origin point. /// /// ``` /// exampleSketch = startSketchOn(-XZ) /// |> circle(center = [0, 0], radius = 10) /// /// example = extrude(exampleSketch, length = 5) /// ``` /// /// ``` /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [-15, 0]) /// |> line(end = [30, 0]) /// |> line(end = [0, 30]) /// |> line(end = [-30, 0]) /// |> close() /// |> subtract2d(tool = circle(center = [0, 15], diameter = 10)) /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn circle( /// Sketch to extend, or plane or surface to sketch on. @sketchOrSurface: Sketch | Plane | Face, /// The center of the circle. @(snippetArray = ["0", "0"]) center: Point2d, /// The radius of the circle. Incompatible with `diameter`. radius?: number(Length), /// The diameter of the circle. Incompatible with `radius`. @(includeInSnippet = true) diameter?: number(Length), /// Create a new tag which refers to this circle. tag?: TagDecl, ): Sketch {} /// Extend a 2-dimensional sketch through a third dimension in order to /// create new 3-dimensional volume, or if extruded into an existing volume, /// cut into an existing solid. /// /// You can provide more than one sketch to extrude, and they will all be /// extruded in the same direction. /// /// ```kcl /// example = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> arc( /// angleStart = 120deg, /// angleEnd = 0, /// radius = 5, /// ) /// |> line(end = [5, 0]) /// |> line(end = [0, 10]) /// |> bezierCurve( /// control1 = [-10, 0], /// control2 = [2, 10], /// end = [-5, 10], /// ) /// |> line(end = [-5, -2]) /// |> close() /// |> extrude(length = 10) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [-10, 0]) /// |> arc( /// angleStart = 120deg, /// angleEnd = -60deg, /// radius = 5, /// ) /// |> line(end = [10, 0]) /// |> line(end = [5, 0]) /// |> bezierCurve( /// control1 = [-3, 0], /// control2 = [2, 10], /// end = [-5, 10], /// ) /// |> line(end = [-4, 10]) /// |> line(end = [-5, -2]) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [-10, 0]) /// |> arc( /// angleStart = 120deg, /// angleEnd = -60deg, /// radius = 5, /// ) /// |> line(end = [10, 0]) /// |> line(end = [5, 0]) /// |> bezierCurve( /// control1 = [-3, 0], /// control2 = [2, 10], /// end = [-5, 10], /// ) /// |> line(end = [-4, 10]) /// |> line(end = [-5, -2]) /// |> close() /// /// example = extrude(exampleSketch, length = 20, symmetric = true) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [-10, 0]) /// |> arc( /// angleStart = 120deg, /// angleEnd = -60deg, /// radius = 5, /// ) /// |> line(end = [10, 0]) /// |> line(end = [5, 0]) /// |> bezierCurve( /// control1 = [-3, 0], /// control2 = [2, 10], /// end = [-5, 10], /// ) /// |> line(end = [-4, 10]) /// |> line(end = [-5, -2]) /// |> close() /// /// example = extrude(exampleSketch, length = 10, bidirectionalLength = 50) /// ``` /// ```kcl /// example = startSketchOn(XZ) /// |> polygon(radius = 10, numSides = 3, center = [0, 0]) /// |> extrude(length = 10, twistAngle = 120deg) /// ``` @(impl = std_rust) export fn extrude( /// Which sketch or sketches should be extruded. @sketches: [Sketch; 1+], /// How far to extrude the given sketches. length: number(Length), /// If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch. symmetric?: bool, /// If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. bidirectionalLength?: number(Length), /// A named tag for the face at the start of the extrusion, i.e. the original sketch. tagStart?: TagDecl, /// A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch. tagEnd?: TagDecl, /// If given, the sketch will be twisted around this angle while being extruded. twistAngle?: number(Angle), /// The size of each intermediate angle as the sketch twists around. /// Must be between 4 and 90 degrees. /// Only used if `twistAngle` is given, defaults to 15 degrees. twistAngleStep?: number(Angle), /// The center around which the sketch will be twisted. Relative to the sketch's center. /// Only used if `twistAngle` is given, defaults to [0, 0] i.e. sketch's center. @(snippetArray = ["0", "0"]) twistCenter?: Point2d, ): [Solid; 1+] {} /// Rotate a sketch around some provided axis, creating a solid from its extent. /// /// This, like extrude, is able to create a 3-dimensional solid from a /// 2-dimensional sketch. However, unlike extrude, this creates a solid /// by using the extent of the sketch as its revolved around an axis rather /// than using the extent of the sketch linearly translated through a third /// dimension. /// /// Revolve occurs around a local sketch axis rather than a global axis. /// /// You can provide more than one sketch to revolve, and they will all be /// revolved around the same axis. /// /// ```kcl /// part001 = startSketchOn(XY) /// |> startProfile(at = [4, 12]) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// |> revolve(axis = Y) // default angle is 360deg /// ``` /// /// ```kcl /// // A donut shape. /// sketch001 = startSketchOn(XY) /// |> circle( center = [15, 0], radius = 5 ) /// |> revolve( /// angle = 360deg, /// axis = Y, /// ) /// ``` /// /// ```kcl /// part001 = startSketchOn(XY) /// |> startProfile(at = [4, 12]) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// |> revolve(axis = Y, angle = 180deg) /// ``` /// /// ```kcl /// part001 = startSketchOn(XY) /// |> startProfile(at = [4, 12]) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// |> revolve(axis = Y, angle = 180deg) /// /// part002 = startSketchOn(part001, face = END) /// |> startProfile(at = [4.5, -5]) /// |> line(end = [0, 5]) /// |> line(end = [5, 0]) /// |> line(end = [0, -5]) /// |> close() /// |> extrude(length = 5) /// ``` /// /// ```kcl /// box = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20]) /// |> line(end = [20, 0]) /// |> line(end = [0, -20]) /// |> close() /// |> extrude(length = 20) /// /// sketch001 = startSketchOn(box, face = END) /// |> circle( center = [10,10], radius = 4 ) /// |> revolve( /// angle = -90deg, /// axis = Y /// ) /// ``` /// /// ```kcl /// box = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20]) /// |> line(end = [20, 0]) /// |> line(end = [0, -20], tag = $revolveAxis) /// |> close() /// |> extrude(length = 20) /// /// sketch001 = startSketchOn(box, face = END) /// |> circle( center = [10,10], radius = 4 ) /// |> revolve( /// angle = 90deg, /// axis = getOppositeEdge(revolveAxis) /// ) /// ``` /// /// ```kcl /// box = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20]) /// |> line(end = [20, 0]) /// |> line(end = [0, -20], tag = $revolveAxis) /// |> close() /// |> extrude(length = 20) /// /// sketch001 = startSketchOn(box, face = END) /// |> circle( center = [10,10], radius = 4 ) /// |> revolve( /// angle = 90deg, /// axis = getOppositeEdge(revolveAxis), /// tolerance = 0.0001 /// ) /// ``` /// /// ```kcl /// sketch001 = startSketchOn(XY) /// |> startProfile(at = [10, 0]) /// |> line(end = [5, -5]) /// |> line(end = [5, 5]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// part001 = revolve( /// sketch001, /// axis = { /// direction = [0.0, 1.0], /// origin = [0.0, 0.0] /// } /// ) /// ``` /// /// ```kcl /// // Revolve two sketches around the same axis. /// /// sketch001 = startSketchOn(XY) /// profile001 = startProfile(sketch001, at = [4, 8]) /// |> xLine(length = 3) /// |> yLine(length = -3) /// |> xLine(length = -3) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// profile002 = startProfile(sketch001, at = [-5, 8]) /// |> xLine(length = 3) /// |> yLine(length = -3) /// |> xLine(length = -3) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// revolve( /// [profile001, profile002], /// axis = X, /// ) /// ``` /// /// ```kcl /// // Revolve around a path that has not been extruded. /// /// profile001 = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// |> line(end = [0, -20]) /// |> close(%) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90deg, axis = revolveAxis) /// ``` /// /// ```kcl /// // Revolve around a path that has not been extruded or closed. /// /// profile001 = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90deg, axis = revolveAxis) /// ``` /// /// ```kcl /// // Symmetrically revolve around a path. /// /// profile001 = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90deg, axis = revolveAxis, symmetric = true) /// ``` /// /// ```kcl /// // Bidirectional revolve around a path. /// /// profile001 = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90deg, axis = revolveAxis, bidirectionalAngle = 50) /// ``` @(impl = std_rust) export fn revolve( /// The sketch or set of sketches that should be revolved @sketches: [Sketch; 1+], /// Axis of revolution. axis: Axis2d | Edge, /// Angle to revolve (in degrees). Default is 360. angle?: number(Angle), /// Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. tolerance?: number(Length), /// If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch. symmetric?: bool, /// If specified, will also revolve in the opposite direction to 'angle' to the specified angle. If 'symmetric' is true, this value is ignored. bidirectionalAngle?: number(Angle), /// A named tag for the face at the start of the revolve, i.e. the original sketch. tagStart?: TagDecl, /// A named tag for the face at the end of the revolve. tagEnd?: TagDecl, ): [Solid; 1+] {} /// Just like `patternTransform`, but works on 2D sketches not 3D solids. /// /// ```kcl /// // Each instance will be shifted along the X axis. /// fn transform(@id) { /// return { translate = [4 * id, 0] } /// } /// /// // Sketch 4 circles. /// sketch001 = startSketchOn(XZ) /// |> circle(center = [0, 0], radius = 2) /// |> patternTransform2d(instances = 4, transform = transform) /// ``` @(impl = std_rust) export fn patternTransform2d( /// The sketch(es) to duplicate. @sketches: [Sketch; 1+], /// The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. instances: number(Count), /// How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. transform: fn(number(Count)): {}, /// If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. useOriginal?: boolean = false, ): [Sketch; 1+] {} /// Get the opposite edge to the edge given. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> angledLine( /// angle = 60deg, /// length = 10, /// ) /// |> angledLine( /// angle = 120deg, /// length = 10, /// ) /// |> line(end = [-10, 0]) /// |> angledLine( /// angle = 240deg, /// length = 10, /// tag = $referenceEdge, /// ) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// |> fillet( /// radius = 3, /// tags = [getOppositeEdge(referenceEdge)], /// ) /// ``` @(impl = std_rust) export fn getOppositeEdge( /// The tag of the edge you want to find the opposite edge of. @edge: TaggedEdge, ): Edge {} /// Get the next adjacent edge to the edge given. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> angledLine( /// angle = 60deg, /// length = 10, /// ) /// |> angledLine( /// angle = 120deg, /// length = 10, /// ) /// |> line(end = [-10, 0]) /// |> angledLine( /// angle = 240deg, /// length = 10, /// tag = $referenceEdge, /// ) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// |> fillet( /// radius = 3, /// tags = [getNextAdjacentEdge(referenceEdge)], /// ) /// ``` @(impl = std_rust) export fn getNextAdjacentEdge( /// The tag of the edge you want to find the next adjacent edge of. @edge: TaggedEdge, ): Edge {} /// Get the previous adjacent edge to the edge given. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> angledLine( /// angle = 60deg, /// length = 10, /// ) /// |> angledLine( /// angle = 120deg, /// length = 10, /// ) /// |> line(end = [-10, 0]) /// |> angledLine( /// angle = 240deg, /// length = 10, /// tag = $referenceEdge, /// ) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// |> fillet( /// radius = 3, /// tags = [getPreviousAdjacentEdge(referenceEdge)], /// ) /// ``` @(impl = std_rust) export fn getPreviousAdjacentEdge( /// The tag of the edge you want to find the previous adjacent edge of. @edge: TaggedEdge, ): Edge {} /// Get the shared edge between two faces. /// /// ```kcl /// // Get an edge shared between two faces, created after a chamfer. /// /// scale = 20 /// part001 = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, scale]) /// |> line(end = [scale, 0]) /// |> line(end = [0, -scale]) /// |> close(tag = $line0) /// |> extrude(length = 20, tagEnd = $end0) /// // We tag the chamfer to reference it later. /// |> chamfer(length = 10, tags = [getOppositeEdge(line0)], tag = $chamfer0) /// /// // Get the shared edge between the chamfer and the extrusion. /// commonEdge = getCommonEdge(faces = [chamfer0, end0]) /// /// // Chamfer the shared edge. /// // TODO: uncomment this when ssi for fillets lands /// // chamfer(part001, length = 5, tags = [commonEdge]) /// ``` @(impl = std_rust) export fn getCommonEdge( /// The tags of the faces you want to find the common edge between. faces: [TaggedFace; 2], ): Edge {} /// Construct a circle derived from 3 points. /// /// ```kcl /// exampleSketch = startSketchOn(XY) /// |> circleThreePoint(p1 = [10,10], p2 = [20,8], p3 = [15,5]) /// |> extrude(length = 5) /// ``` @(impl = std_rust) export fn circleThreePoint( /// Plane or surface to sketch on. @sketchOrSurface: Sketch | Plane | Face, /// 1st point to derive the circle. p1: Point2d, /// 2nd point to derive the circle. p2: Point2d, /// 3rd point to derive the circle. p3: Point2d, /// Identifier for the circle to reference elsewhere. tag?: TagDecl, ): Sketch {} /// Create a regular polygon with the specified number of sides that is either inscribed or circumscribed around a circle of the specified radius. /// /// ```kcl /// // Create a regular hexagon inscribed in a circle of radius 10 /// hex = startSketchOn(XY) /// |> polygon( /// radius = 10, /// numSides = 6, /// center = [0, 0], /// inscribed = true, /// ) /// /// example = extrude(hex, length = 5) /// ``` /// /// ```kcl /// // Create a square circumscribed around a circle of radius 5 /// square = startSketchOn(XY) /// |> polygon( /// radius = 5.0, /// numSides = 4, /// center = [10, 10], /// inscribed = false, /// ) /// example = extrude(square, length = 5) /// ``` @(impl = std_rust) export fn polygon( /// Plane or surface to sketch on. @sketchOrSurface: Sketch | Plane | Face, /// The radius of the polygon. radius: number(Length), /// The number of sides in the polygon. numSides: number(Count), /// The center point of the polygon. @(snippetArray = ["0", "0"]) center: Point2d, /// Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius. inscribed?: bool = true, ): Sketch {} /// Extrude a sketch along a path. /// /// This, like extrude, is able to create a 3-dimensional solid from a /// 2-dimensional sketch. However, unlike extrude, this creates a solid /// by using the extent of the sketch as its path. This is useful for /// creating more complex shapes that can't be created with a simple /// extrusion. /// /// You can provide more than one sketch to sweep, and they will all be /// swept along the same path. /// /// ```kcl /// // Create a pipe using a sweep. /// /// // Create a path for the sweep. /// sweepPath = startSketchOn(XZ) /// |> startProfile(at = [0.05, 0.05]) /// |> line(end = [0, 7]) /// |> tangentialArc(angle = 90deg, radius = 5) /// |> line(end = [-3, 0]) /// |> tangentialArc(angle = -90deg, radius = 5) /// |> line(end = [0, 7]) /// /// // Create a hole for the pipe. /// pipeHole = startSketchOn(XY) /// |> circle( /// center = [0, 0], /// radius = 1.5, /// ) /// /// sweepSketch = startSketchOn(XY) /// |> circle( /// center = [0, 0], /// radius = 2, /// ) /// |> subtract2d(tool = pipeHole) /// |> sweep(path = sweepPath) /// ``` /// /// ```kcl /// // Create a spring by sweeping around a helix path. /// /// // Create a helix around the Z axis. /// helixPath = helix( /// angleStart = 0, /// ccw = true, /// revolutions = 4, /// length = 10, /// radius = 5, /// axis = Z, /// ) /// /// /// // Create a spring by sweeping around the helix path. /// springSketch = startSketchOn(XZ) /// |> circle( center = [5, 0], radius = 1) /// |> sweep(path = helixPath) /// ``` /// /// ```kcl /// // Sweep two sketches along the same path. /// /// sketch001 = startSketchOn(XY) /// rectangleSketch = startProfile(sketch001, at = [-200, 23.86]) /// |> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001) /// |> angledLine( /// angle = segAng(rectangleSegmentA001) - 90deg, /// length = 50.61, /// ) /// |> angledLine( /// angle = segAng(rectangleSegmentA001), /// length = -segLen(rectangleSegmentA001), /// ) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) /// /// sketch002 = startSketchOn(YZ) /// sweepPath = startProfile(sketch002, at = [0, 0]) /// |> yLine(length = 231.81) /// |> tangentialArc(radius = 80, angle = -90deg) /// |> xLine(length = 384.93) /// /// sweep([rectangleSketch, circleSketch], path = sweepPath) /// ``` /// /// ```kcl /// // Sectionally sweep one sketch along the path /// /// sketch001 = startSketchOn(XY) /// circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63) /// /// sketch002 = startSketchOn(YZ) /// sweepPath = startProfile(sketch002, at = [0, 0]) /// |> yLine(length = 231.81) /// |> tangentialArc(radius = 80, angle = -90deg) /// |> xLine(length = 384.93) /// /// sweep(circleSketch, path = sweepPath, sectional = true) /// ``` @(impl = std_rust) export fn sweep( /// The sketch or set of sketches that should be swept in space. @sketches: [Sketch; 1+], /// The path to sweep the sketch along. path: Sketch | Helix, /// If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. sectional?: bool, /// Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. tolerance?: number(Length), /// What is the sweep relative to? Can be either 'sketchPlane' or 'trajectoryCurve'. relativeTo?: string = 'trajectoryCurve', /// A named tag for the face at the start of the sweep, i.e. the original sketch. tagStart?: TagDecl, /// A named tag for the face at the end of the sweep. tagEnd?: TagDecl, ): [Solid; 1+] {} /// Create a 3D surface or solid by interpolating between two or more sketches. /// /// The sketches need to be closed and on different planes that are parallel. /// /// ```kcl /// // Loft a square and a triangle. /// squareSketch = startSketchOn(XY) /// |> startProfile(at = [-100, 200]) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// triangleSketch = startSketchOn(offsetPlane(XY, offset = 75)) /// |> startProfile(at = [0, 125]) /// |> line(end = [-15, -30]) /// |> line(end = [30, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// loft([triangleSketch, squareSketch]) /// ``` /// /// ```kcl /// // Loft a square, a circle, and another circle. /// squareSketch = startSketchOn(XY) /// |> startProfile(at = [-100, 200]) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch0 = startSketchOn(offsetPlane(XY, offset = 75)) /// |> circle( center = [0, 100], radius = 50 ) /// /// circleSketch1 = startSketchOn(offsetPlane(XY, offset = 150)) /// |> circle( center = [0, 100], radius = 20 ) /// /// loft([squareSketch, circleSketch0, circleSketch1]) /// ``` /// /// ```kcl /// // Loft a square, a circle, and another circle with options. /// squareSketch = startSketchOn(XY) /// |> startProfile(at = [-100, 200]) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch0 = startSketchOn(offsetPlane(XY, offset = 75)) /// |> circle( center = [0, 100], radius = 50 ) /// /// circleSketch1 = startSketchOn(offsetPlane(XY, offset = 150)) /// |> circle( center = [0, 100], radius = 20 ) /// /// loft([squareSketch, circleSketch0, circleSketch1], /// baseCurveIndex = 0, /// bezApproximateRational = false, /// tolerance = 0.000001, /// vDegree = 2, /// ) /// ``` @(impl = std_rust) export fn loft( /// Which sketches to loft. Must include at least 2 sketches. @sketches: [Sketch; 2+], /// Degree of the interpolation. Must be greater than zero. For example, use 2 for quadratic, or 3 for cubic interpolation in the V direction. vDegree?: number(Count) = 2, /// Attempt to approximate rational curves (such as arcs) using a bezier. This will remove banding around interpolations between arcs and non-arcs. It may produce errors in other scenarios. Over time, this field won't be necessary. bezApproximateRational?: bool = false, /// This can be set to override the automatically determined topological base curve, which is usually the first section encountered. baseCurveIndex?: number(Count), /// Defines the smallest distance below which two entities are considered coincident, intersecting, coplanar, or similar. For most use cases, it should not be changed from its default value of 10^-7 millimeters. tolerance?: number(Length), /// A named tag for the face at the start of the loft, i.e. the original sketch. tagStart?: TagDecl, /// A named tag for the face at the end of the loft. tagEnd?: TagDecl, ): Solid {} /// Repeat a 2-dimensional sketch along some dimension, with a dynamic amount /// of distance between each repetition, some specified number of times. /// /// ```kcl /// /// Pattern using a named axis. /// /// exampleSketch = startSketchOn(XZ) /// |> circle(center = [0, 0], radius = 1) /// |> patternLinear2d( /// axis = X, /// instances = 7, /// distance = 4 /// ) /// /// example = extrude(exampleSketch, length = 1) /// ``` /// /// ```kcl /// /// Pattern using a raw axis. /// /// exampleSketch = startSketchOn(XZ) /// |> circle(center = [0, 0], radius = 1) /// |> patternLinear2d( /// axis = [1, 0], /// instances = 7, /// distance = 4 /// ) /// /// example = extrude(exampleSketch, length = 1) /// ``` @(impl = std_rust) export fn patternLinear2d( /// The sketch(es) to duplicate. @sketches: [Sketch; 1+], /// The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. instances: number(Count), /// Distance between each repetition. Also known as 'spacing'. distance: number(Length), /// The axis of the pattern. A 2D vector. @(snippetArray = ["1", "0"]) axis: Axis2d | Point2d, /// If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. useOriginal?: bool = false, ): [Sketch; 1+] {} /// Repeat a 2-dimensional sketch some number of times along a partial or /// complete circle some specified number of times. Each object may /// additionally be rotated along the circle, ensuring orientation of the /// solid with respect to the center of the circle is maintained. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [.5, 25]) /// |> line(end = [0, 5]) /// |> line(end = [-1, 0]) /// |> line(end = [0, -5]) /// |> close() /// |> patternCircular2d( /// center = [0, 0], /// instances = 13, /// arcDegrees = 360, /// rotateDuplicates = true /// ) /// /// example = extrude(exampleSketch, length = 1) /// ``` @(impl = std_rust) export fn patternCircular2d( /// The sketch(es) to duplicate. @sketches: [Sketch; 1+], /// The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. instances: number(Count), /// The center about which to make the pattern. This is a 2D vector. @(snippetArray = ["0", "0"]) center: Point2d, /// The arc angle (in degrees) to place the repetitions. Must be greater than 0. arcDegrees?: number(Angle) = 360deg, /// Whether or not to rotate the duplicates as they are copied. rotateDuplicates?: bool = true, /// If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. useOriginal?: bool = false, ): [Sketch; 1+] {} /// Compute the ending point of the provided line segment. /// /// ```kcl /// w = 15 /// cube = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [w, 0], tag = $line1) /// |> line(end = [0, w], tag = $line2) /// |> line(end = [-w, 0], tag = $line3) /// |> line(end = [0, -w], tag = $line4) /// |> close() /// |> extrude(length = 5) /// /// fn cylinder(radius, tag) { /// return startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> circle(radius = radius, center = segEnd(tag) ) /// |> extrude(length = radius) /// } /// /// cylinder(radius = 1, tag = line1) /// cylinder(radius = 2, tag = line2) /// cylinder(radius = 3, tag = line3) /// cylinder(radius = 4, tag = line4) /// ``` @(impl = std_rust) export fn segEnd( /// The line segment being queried by its tag. @tag: TaggedEdge, ): Point2d {} /// Compute the ending point of the provided line segment along the 'x' axis. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [20, 0], tag = $thing) /// |> line(end = [0, 5]) /// |> line(end = [segEndX(thing), 0]) /// |> line(end = [-20, 10]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn segEndX( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Length) {} /// Compute the ending point of the provided line segment along the 'y' axis. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [20, 0]) /// |> line(end = [0, 3], tag = $thing) /// |> line(end = [-10, 0]) /// |> line(end = [0, segEndY(thing)]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn segEndY( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Length) {} /// Compute the starting point of the provided line segment. /// /// ```kcl /// w = 15 /// cube = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [w, 0], tag = $line1) /// |> line(end = [0, w], tag = $line2) /// |> line(end = [-w, 0], tag = $line3) /// |> line(end = [0, -w], tag = $line4) /// |> close() /// |> extrude(length = 5) /// /// fn cylinder(radius, tag) { /// return startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> circle( radius = radius, center = segStart(tag) ) /// |> extrude(length = radius) /// } /// /// cylinder(radius = 1, tag = line1) /// cylinder(radius = 2, tag = line2) /// cylinder(radius = 3, tag = line3) /// cylinder(radius = 4, tag = line4) /// ``` @(impl = std_rust) export fn segStart( /// The line segment being queried by its tag. @tag: TaggedEdge, ): Point2d {} /// Compute the starting point of the provided line segment along the 'x' axis. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [20, 0], tag = $thing) /// |> line(end = [0, 5]) /// |> line(end = [20 - segStartX(thing), 0]) /// |> line(end = [-20, 10]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn segStartX( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Length) {} /// Compute the starting point of the provided line segment along the 'y' axis. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [20, 0]) /// |> line(end = [0, 3], tag = $thing) /// |> line(end = [-10, 0]) /// |> line(end = [0, 20-segStartY(thing)]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn segStartY( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Length) {} /// Extract the 'x' axis value of the last line segment in the provided 2-d sketch. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [5, 0]) /// |> line(end = [20, 5]) /// |> line(end = [lastSegX(%), 0]) /// |> line(end = [-15, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn lastSegX( /// The sketch whose line segment is being queried. @sketch: Sketch, ): number(Length) {} /// Extract the 'y' axis value of the last line segment in the provided 2-d sketch. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [5, 0]) /// |> line(end = [20, 5]) /// |> line(end = [0, lastSegY(%)]) /// |> line(end = [-15, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn lastSegY( /// The sketch whose line segment is being queried. @sketch: Sketch, ): number(Length) {} /// Compute the length of the provided line segment. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> angledLine( /// angle = 60, /// length = 10, /// tag = $thing, /// ) /// |> tangentialArc(angle = -120deg, radius = 5) /// |> angledLine( /// angle = -60deg, /// length = segLen(thing), /// ) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` @(impl = std_rust) export fn segLen( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Length) {} /// Compute the angle (in degrees) of the provided line segment. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> line(end = [5, 10], tag = $seg01) /// |> line(end = [-10, 0]) /// |> angledLine(angle = segAng(seg01), length = 10) /// |> line(end = [-10, 0]) /// |> angledLine(angle = segAng(seg01), length = -15) /// |> close() /// /// example = extrude(exampleSketch, length = 4) /// ``` @(impl = std_rust) export fn segAng( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Angle) {} /// Returns the angle coming out of the end of the segment in degrees. /// /// ```kcl /// // Horizontal pill. /// pillSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [20, 0]) /// |> tangentialArc(end = [0, 10], tag = $arc1) /// |> angledLine( /// angle = tangentToEnd(arc1), /// length = 20, /// ) /// |> tangentialArc(end = [0, -10]) /// |> close() /// /// pillExtrude = extrude(pillSketch, length = 10) /// ``` /// /// ```kcl /// // Vertical pill. Use absolute coordinate for arc. /// pillSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 20]) /// |> tangentialArc(endAbsolute = [10, 20], tag = $arc1) /// |> angledLine( /// angle = tangentToEnd(arc1), /// length = 20, /// ) /// |> tangentialArc(end = [-10, 0]) /// |> close() /// /// pillExtrude = extrude(pillSketch, length = 10) /// ``` /// /// ```kcl /// rectangleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0], tag = $seg1) /// |> angledLine( /// angle = tangentToEnd(seg1), /// length = 10, /// ) /// |> line(end = [0, 10]) /// |> line(end = [-20, 0]) /// |> close() /// /// rectangleExtrude = extrude(rectangleSketch, length = 10) /// ``` /// /// ```kcl /// bottom = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> arc( /// endAbsolute = [10, 10], /// interiorAbsolute = [5, 1], /// tag = $arc1, /// ) /// |> angledLine(angle = tangentToEnd(arc1), length = 20) /// |> close() /// ``` /// /// ```kcl /// circSketch = startSketchOn(XY) /// |> circle(center = [0, 0], radius= 3, tag = $circ) /// /// triangleSketch = startSketchOn(XY) /// |> startProfile(at = [-5, 0]) /// |> angledLine(angle = tangentToEnd(circ), length = 10) /// |> line(end = [-15, 0]) /// |> close() /// ``` @(impl = std_rust) export fn tangentToEnd( /// The line segment being queried by its tag. @tag: TaggedEdge, ): number(Angle) {} /// Extract the provided 2-dimensional sketch's profile's origin value. /// /// ```kcl /// sketch001 = startSketchOn(XY) /// |> startProfile(at = [5, 2]) /// |> angledLine(angle = 120, length = 50 , tag = $seg01) /// |> angledLine(angle = segAng(seg01) + 120deg, length = 50 ) /// |> line(end = profileStart(%)) /// |> close() /// |> extrude(length = 20) /// ``` @(impl = std_rust) export fn profileStart( /// Profile whose start is being used. @profile: Sketch, ): Point2d {} /// Extract the provided 2-dimensional sketch's profile's origin's 'x' value. /// /// ```kcl /// sketch001 = startSketchOn(XY) /// |> startProfile(at = [5, 2]) /// |> angledLine(angle = -26.6, length = 50) /// |> angledLine(angle = 90deg, length = 50) /// |> angledLine(angle = 30deg, endAbsoluteX = profileStartX(%)) /// ``` @(impl = std_rust) export fn profileStartX( /// Profile whose start is being used. @profile: Sketch, ): number(Length) {} /// Extract the provided 2-dimensional sketch's profile's origin's 'y' value. /// /// ```kcl /// sketch001 = startSketchOn(XY) /// |> startProfile(at = [5, 2]) /// |> angledLine(angle = -60deg, length = 14 ) /// |> angledLine(angle = 30deg, endAbsoluteY = profileStartY(%)) /// ``` @(impl = std_rust) export fn profileStartY( /// Profile whose start is being used. @profile: Sketch, ): number(Length) {} /// Extend the current sketch with a new involute circular curve. /// /// ```kcl /// a = 10 /// b = 14 /// startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> involuteCircular(startRadius = a, endRadius = b, angle = 60deg) /// |> involuteCircular(startRadius = a, endRadius = b, angle = 60deg, reverse = true) /// ``` @(impl = std_rust) export fn involuteCircular( /// Which sketch should this path be added to? @sketch: Sketch, /// The angle to rotate the involute by. A value of zero will produce a curve with a tangent along the x-axis at the start point of the curve. angle: number(Angle), /// The involute is described between two circles, startRadius is the radius of the inner circle. /// Either `startRadius` or `startDiameter` must be given (but not both). startRadius?: number(Length), /// The involute is described between two circles, endRadius is the radius of the outer circle. /// Either `endRadius` or `endDiameter` must be given (but not both). endRadius?: number(Length), /// The involute is described between two circles, startDiameter describes the inner circle. /// Either `startRadius` or `startDiameter` must be given (but not both). startDiameter?: number(Length), /// The involute is described between two circles, endDiameter describes the outer circle. /// Either `endRadius` or `endDiameter` must be given (but not both). endDiameter?: number(Length), /// If reverse is true, the segment will start from the end of the involute, otherwise it will start from that start. reverse?: bool = false, /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Extend the current sketch with a new straight line. /// /// ```kcl /// triangle = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// // The END argument means it ends at exactly [10, 0]. /// // This is an absolute measurement, it is NOT relative to /// // the start of the sketch. /// |> line(endAbsolute = [10, 0]) /// |> line(endAbsolute = [0, 10]) /// |> line(endAbsolute = [-10, 0], tag = $thirdLineOfTriangle) /// |> close() /// |> extrude(length = 5) /// /// box = startSketchOn(XZ) /// |> startProfile(at = [10, 10]) /// // The 'to' argument means move the pen this much. /// // So, [10, 0] is a relative distance away from the current point. /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> line(end = [-10, 0], tag = $thirdLineOfBox) /// |> close() /// |> extrude(length = 5) /// ``` @(impl = std_rust) export fn line( /// Which sketch should this path be added to? @sketch: Sketch, /// Which absolute point should this line go to? Incompatible with `end`. endAbsolute?: Point2d, /// How far away (along the X and Y axes) should this line go? Incompatible with `endAbsolute`. @(includeInSnippet = true) end?: Point2d, /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Draw a line relative to the current origin to a specified distance away /// from the current position along the 'x' axis. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> xLine(length = 15) /// |> angledLine( /// angle = 80deg, /// length = 15, /// ) /// |> line(end = [8, -10]) /// |> xLine(length = 10) /// |> angledLine( /// angle = 120deg, /// length = 30, /// ) /// |> xLine(length = -15) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn xLine( /// Which sketch should this path be added to? @sketch: Sketch, /// How far away along the X axis should this line go? Incompatible with `endAbsolute`. @(includeInSnippet = true) length?: number(Length), /// Which absolute X value should this line go to? Incompatible with `length`. endAbsolute?: number(Length), /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Draw a line relative to the current origin to a specified distance away /// from the current position along the 'y' axis. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> yLine(length = 15) /// |> angledLine( /// angle = 30deg, /// length = 15, /// ) /// |> line(end = [8, -10]) /// |> yLine(length = -5) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn yLine( /// Which sketch should this path be added to? @sketch: Sketch, /// How far away along the Y axis should this line go? Incompatible with `endAbsolute`. @(includeInSnippet = true) length?: number(Length), /// Which absolute Y value should this line go to? Incompatible with `length`. endAbsolute?: number(Length), /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Draw a line segment relative to the current origin using the polar /// measure of some angle and distance. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> yLine(endAbsolute = 15) /// |> angledLine( /// angle = 30deg, /// length = 15, /// ) /// |> line(end = [8, -10]) /// |> yLine(endAbsolute = 0) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn angledLine( /// Which sketch should this path be added to? @sketch: Sketch, /// Which angle should the line be drawn at? angle: number(Angle), /// Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. length?: number(Length), /// Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. lengthX?: number(Length), /// Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. lengthY?: number(Length), /// Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. endAbsoluteX?: number(Length), /// Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. endAbsoluteY?: number(Length), /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Draw an angled line from the current origin, constructing a line segment /// such that the newly created line intersects the desired target line /// segment. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(endAbsolute = [5, 10]) /// |> line(endAbsolute = [-10, 10], tag = $lineToIntersect) /// |> line(endAbsolute = [0, 20]) /// |> angledLineThatIntersects( /// angle = 80deg, /// intersectTag = lineToIntersect, /// offset = 10, /// ) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn angledLineThatIntersects( /// Which sketch should this path be added to? @sketch: Sketch, /// Which angle should the line be drawn at? angle: number(Angle), /// The tag of the line to intersect with. intersectTag: TaggedEdge, /// The offset from the intersecting line. offset?: number(Length) = 0mm, /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Construct a line segment from the current origin back to the profile's /// origin, ensuring the resulting 2-dimensional sketch is not open-ended. /// /// If you want to perform some 3-dimensional operation on a sketch, like /// extrude or sweep, you must `close` it first. `close` must be called even /// if the end point of the last segment is coincident with the sketch /// starting point. /// /// ```kcl /// startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 10]) /// |> line(end = [10, 0]) /// |> close() /// |> extrude(length = 10) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(-XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn close( /// The sketch you want to close. @sketch: Sketch, /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Draw a curved line segment along an imaginary circle. /// /// The arc is constructed such that the current position of the sketch is /// placed along an imaginary circle of the specified radius, at angleStart /// degrees. The resulting arc is the segment of the imaginary circle from /// that origin point to angleEnd, radius away from the center of the imaginary /// circle. /// /// Unless this makes a lot of sense and feels like what you're looking /// for to construct your shape, you're likely looking for tangentialArc. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [10, 0]) /// |> arc( /// angleStart = 0, /// angleEnd = 280deg, /// radius = 16 /// ) /// |> close() /// example = extrude(exampleSketch, length = 10) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> arc( /// endAbsolute = [10,0], /// interiorAbsolute = [5,5] /// ) /// |> close() /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn arc( /// Which sketch should this path be added to? @sketch: Sketch, /// Where along the circle should this arc start? @(includeInSnippet = true) angleStart?: number(Angle), /// Where along the circle should this arc end? @(includeInSnippet = true) angleEnd?: number(Angle), /// How large should the circle be? Incompatible with `diameter`. radius?: number(Length), /// How large should the circle be? Incompatible with `radius`. @(includeInSnippet = true) diameter?: number(Length), /// Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd`. interiorAbsolute?: Point2d, /// Where should this arc end? Requires `interiorAbsolute`. Incompatible with `angleStart` or `angleEnd`. endAbsolute?: Point2d, /// Create a new tag which refers to this arc. tag?: TagDecl, ): Sketch {} /// Starting at the current sketch's origin, draw a curved line segment along /// some part of an imaginary circle until it reaches the desired (x, y) /// coordinates. /// /// When using radius and angle, draw a curved line segment along part of an /// imaginary circle. The arc is constructed such that the last line segment is /// placed tangent to the imaginary circle of the specified radius. The /// resulting arc is the segment of the imaginary circle from that tangent point /// for 'angle' degrees along the imaginary circle. /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> angledLine( /// angle = 45deg, /// length = 10, /// ) /// |> tangentialArc(end = [0, -10]) /// |> line(end = [-10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> angledLine( /// angle = 60deg, /// length = 10, /// ) /// |> tangentialArc(endAbsolute = [15, 15]) /// |> line(end = [10, -15]) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` /// /// ```kcl /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> angledLine( /// angle = 60deg, /// length = 10, /// ) /// |> tangentialArc(radius = 10, angle = -120deg) /// |> angledLine( /// angle = -60deg, /// length = 10, /// ) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` @(impl = std_rust) export fn tangentialArc( /// Which sketch should this path be added to? @sketch: Sketch, /// Which absolute point should this arc go to? Incompatible with `end`, `radius`, and `offset`. endAbsolute?: Point2d, /// How far away (along the X and Y axes) should this arc go? Incompatible with `endAbsolute`, `radius`, and `offset`. @(includeInSnippet = true) end?: Point2d, /// Radius of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `diameter`. radius?: number(Length), /// Diameter of the imaginary circle. `angle` must be given. Incompatible with `end` and `endAbsolute` and `radius`. diameter?: number(Length), /// Offset of the arc. `radius` must be given. Incompatible with `end` and `endAbsolute`. angle?: number(Angle), /// Create a new tag which refers to this arc. tag?: TagDecl, ): Sketch {} /// Draw a smooth, continuous, curved line segment from the current origin to /// the desired (x, y), using a number of control points to shape the curve's /// shape. /// /// ```kcl /// // Example using relative control points. /// exampleSketch = startSketchOn(XZ) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 10]) /// |> bezierCurve( /// control1 = [5, 0], /// control2 = [5, 10], /// end = [10, 10], /// ) /// |> line(endAbsolute = [10, 0]) /// |> close() /// /// example = extrude(exampleSketch, length = 10) /// ``` /// /// ```kcl /// // Example using absolute control points. /// startSketchOn(XY) /// |> startProfile(at = [300, 300]) /// |> bezierCurve(control1Absolute = [600, 300], control2Absolute = [-300, -100], endAbsolute = [600, 600]) /// |> close() /// |> extrude(length = 10) /// ``` @(impl = std_rust) export fn bezierCurve( /// Which sketch should this path be added to? @sketch: Sketch, /// First control point for the cubic. control1?: Point2d, /// Second control point for the cubic. control2?: Point2d, /// How far away (along the X and Y axes) should this line go? end?: Point2d, /// First control point for the cubic. Absolute point. control1Absolute?: Point2d, /// Second control point for the cubic. Absolute point. control2Absolute?: Point2d, /// Coordinate on the plane at which this line should end. endAbsolute?: Point2d, /// Create a new tag which refers to this line. tag?: TagDecl, ): Sketch {} /// Use a 2-dimensional sketch to cut a hole in another 2-dimensional sketch. /// /// ```kcl /// exampleSketch = startSketchOn(XY) /// |> startProfile(at = [0, 0]) /// |> line(end = [0, 5]) /// |> line(end = [5, 0]) /// |> line(end = [0, -5]) /// |> close() /// |> subtract2d(tool =circle( center = [1, 1], radius = .25 )) /// |> subtract2d(tool =circle( center = [1, 4], radius = .25 )) /// /// example = extrude(exampleSketch, length = 1) /// ``` /// /// ```kcl /// fn squareHoleSketch() { /// squareSketch = startSketchOn(-XZ) /// |> startProfile(at = [-1, -1]) /// |> line(end = [2, 0]) /// |> line(end = [0, 2]) /// |> line(end = [-2, 0]) /// |> close() /// return squareSketch /// } /// /// exampleSketch = startSketchOn(-XZ) /// |> circle( center = [0, 0], radius = 3 ) /// |> subtract2d(tool = squareHoleSketch()) /// example = extrude(exampleSketch, length = 1) /// ``` @(impl = std_rust) export fn subtract2d( /// Which sketch should this path be added to? @sketch: Sketch, /// The shape(s) which should be cut out of the sketch. tool: [Sketch; 1+], ): Sketch {} /// Find the plane a face lies on. /// Returns an error if the face doesn't lie on any plane (for example, the curved face of a cylinder) ///```kcl /// triangle = startSketchOn(XY) /// |> polygon(radius = 3, numSides = 3, center = [0, 0]) /// |> extrude(length = 2) /// /// // Find the plane of the triangle's top face. /// topPlane = planeOf(triangle, face = END) /// /// // Create a new plane, 10 units above the triangle's top face. /// startSketchOn(offsetPlane(topPlane, offset = 10)) /// ``` @(impl = std_rust) export fn planeOf( /// The solid whose face is being queried. @solid: Solid, /// Find the plane which this face lies on. face: TaggedFace, ): Plane {}