@no_std @settings(defaultLengthUnit = mm) // Note that everything in the prelude is treated as exported. export import * from "std::types" export import * from "std::math" export import * from "std::sketch" export import "std::turns" export XY = { origin = { x = 0, y = 0, z = 0 }, xAxis = { x = 1, y = 0, z = 0 }, yAxis = { x = 0, y = 1, z = 0 }, }: Plane export XZ = { origin = { x = 0, y = 0, z = 0 }, xAxis = { x = 1, y = 0, z = 0 }, yAxis = { x = 0, y = 0, z = 1 }, }: Plane export YZ = { origin = { x = 0, y = 0, z = 0 }, xAxis = { x = 0, y = 1, z = 0 }, yAxis = { x = 0, y = 0, z = 1 }, }: Plane export X = { origin = [0, 0, 0], direction = [1, 0, 0], }: Axis3d export Y = { origin = [0, 0, 0], direction = [0, 1, 0], }: Axis3d export Z = { origin = [0, 0, 0], direction = [0, 0, 1], }: Axis3d /// Identifies the starting face of an extrusion. I.e., the face which is extruded. export START = 'start' /// Identifies the ending face of an extrusion. I.e., the new face created by an extrusion. export END = 'end' /// Create a helix. /// /// ``` /// // Create a helix around the Z axis. /// helixPath = helix( /// angleStart = 0, /// ccw = true, /// revolutions = 5, /// length = 10, /// radius = 5, /// axis = Z, /// ) /// /// // Create a spring by sweeping around the helix path. /// springSketch = startSketchOn(YZ) /// |> circle( center = [0, 0], radius = 0.5) /// |> sweep(path = helixPath) /// ``` /// /// ``` /// // Create a helix around an edge. /// helper001 = startSketchOn(XZ) /// |> startProfileAt([0, 0], %) /// |> line(end = [0, 10], tag = $edge001) /// /// helixPath = helix( /// angleStart = 0, /// ccw = true, /// revolutions = 5, /// length = 10, /// radius = 5, /// axis = edge001, /// ) /// /// // Create a spring by sweeping around the helix path. /// springSketch = startSketchOn(XY) /// |> circle( center = [0, 0], radius = 0.5 ) /// |> sweep(path = helixPath) /// ``` /// /// ``` /// // Create a helix around a custom axis. /// helixPath = helix( /// angleStart = 0, /// ccw = true, /// revolutions = 5, /// length = 10, /// radius = 5, /// axis = { /// direction = [0, 0, 1.0], /// origin = [0, 0.25, 0] /// } /// ) /// /// // Create a spring by sweeping around the helix path. /// springSketch = startSketchOn(XY) /// |> circle( center = [0, 0], radius = 1 ) /// |> sweep(path = helixPath) /// ``` /// /// ``` /// // Create a helix on a cylinder. /// /// part001 = startSketchOn(XY) /// |> circle( center= [5, 5], radius= 10 ) /// |> extrude(length = 10) /// /// helix( /// angleStart = 0, /// ccw = true, /// revolutions = 16, /// cylinder = part001, /// ) /// ``` @(impl = std_rust) export fn helix( /// Number of revolutions. revolutions: number(_), /// Start angle. angleStart: number(Angle), /// Is the helix rotation counter clockwise? The default is `false`. ccw?: bool, /// Radius of the helix. @(include_in_snippet = true) radius?: number(Length), /// Axis to use for the helix. @(include_in_snippet = true) axis?: Axis3d | Edge, /// Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. @(include_in_snippet = true) length?: number(Length), /// Cylinder to create the helix on. cylinder?: Solid, ): Helix {} /// 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. /// /// ``` /// part001 = startSketchOn(XY) /// |> startProfileAt([4, 12], %) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// |> revolve(axis = Y) // default angle is 360 /// ``` /// /// ``` /// // A donut shape. /// sketch001 = startSketchOn(XY) /// |> circle( center = [15, 0], radius = 5 ) /// |> revolve( /// angle = 360, /// axis = Y, /// ) /// ``` /// /// ``` /// part001 = startSketchOn(XY) /// |> startProfileAt([4, 12], %) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// |> revolve(axis = Y, angle = 180) /// ``` /// /// ``` /// part001 = startSketchOn(XY) /// |> startProfileAt([4, 12], %) /// |> line(end = [2, 0]) /// |> line(end = [0, -6]) /// |> line(end = [4, -6]) /// |> line(end = [0, -6]) /// |> line(end = [-3.75, -4.5]) /// |> line(end = [0, -5.5]) /// |> line(end = [-2, 0]) /// |> close() /// |> revolve(axis = Y, angle = 180) /// /// part002 = startSketchOn(part001, face = END) /// |> startProfileAt([4.5, -5], %) /// |> line(end = [0, 5]) /// |> line(end = [5, 0]) /// |> line(end = [0, -5]) /// |> close() /// |> extrude(length = 5) /// ``` /// /// ``` /// box = startSketchOn(XY) /// |> startProfileAt([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 = -90, /// axis = Y /// ) /// ``` /// /// ``` /// box = startSketchOn(XY) /// |> startProfileAt([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 = 90, /// axis = getOppositeEdge(revolveAxis) /// ) /// ``` /// /// ``` /// box = startSketchOn(XY) /// |> startProfileAt([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 = 90, /// axis = getOppositeEdge(revolveAxis), /// tolerance = 0.0001 /// ) /// ``` /// /// ``` /// sketch001 = startSketchOn(XY) /// |> startProfileAt([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] /// } /// ) /// ``` /// /// ``` /// // Revolve two sketches around the same axis. /// /// sketch001 = startSketchOn(XY) /// profile001 = startProfileAt([4, 8], sketch001) /// |> xLine(length = 3) /// |> yLine(length = -3) /// |> xLine(length = -3) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// profile002 = startProfileAt([-5, 8], sketch001) /// |> xLine(length = 3) /// |> yLine(length = -3) /// |> xLine(length = -3) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// revolve( /// [profile001, profile002], /// axis = X, /// ) /// ``` /// /// ``` /// // Revolve around a path that has not been extruded. /// /// profile001 = startSketchOn(XY) /// |> startProfileAt([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 = 90, axis = revolveAxis) /// ``` /// /// ``` /// // Revolve around a path that has not been extruded or closed. /// /// profile001 = startSketchOn(XY) /// |> startProfileAt([0, 0], %) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90, axis = revolveAxis) /// ``` /// /// ``` /// // Symmetrically revolve around a path. /// /// profile001 = startSketchOn(XY) /// |> startProfileAt([0, 0], %) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90, axis = revolveAxis, symmetric = true) /// ``` /// /// ``` /// // Bidirectional revolve around a path. /// /// profile001 = startSketchOn(XY) /// |> startProfileAt([0, 0], %) /// |> line(end = [0, 20], tag = $revolveAxis) /// |> line(end = [20, 0]) /// /// sketch001 = startSketchOn(XY) /// |> circle(center = [-10, 10], radius = 4) /// |> revolve(angle = 90, 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), /// Tolerance for the revolve operation. 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?: tag, /// A named tag for the face at the end of the revolve. tagEnd?: tag, ): Solid {} /// Convert a number to millimeters from its current units. export fn toMillimeters(@num: number(mm)): number(mm) { return num } /// Convert a number to centimeters from its current units. export fn toCentimeters(@num: number(cm)): number(cm) { return num } /// Convert a number to meters from its current units. export fn toMeters(@num: number(m)): number(m) { return num } /// Convert a number to inches from its current units. export fn toInches(@num: number(in)): number(in) { return num } /// Convert a number to feet from its current units. export fn toFeet(@num: number(ft)): number(ft) { return num } /// Converts a number to yards from its current units. export fn toYards(@num: number(yd)): number(yd) { return num } /// Converts a number to radians from its current units. /// /// ``` /// exampleSketch = startSketchOn(XZ) /// |> startProfileAt([0, 0], %) /// |> angledLine( /// angle = 50, /// length = 70 * cos(toRadians(45)), /// ) /// |> yLine(endAbsolute = 0) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` export fn toRadians(@num: number(rad)): number(rad) { return num } /// Converts a number to degrees from its current units. /// /// ``` /// exampleSketch = startSketchOn(XZ) /// |> startProfileAt([0, 0], %) /// |> angledLine( /// angle = 50, /// length = 70 * cos(toDegrees((PI/4): number(rad))), /// ) /// |> yLine(endAbsolute = 0) /// |> close() /// /// example = extrude(exampleSketch, length = 5) /// ``` export fn toDegrees(@num: number(deg)): number(deg) { return num } /// Offset a plane by a distance along its normal. /// /// For example, if you offset the `XZ` plane by 10, the new plane will be parallel to the `XZ` /// plane and 10 units away from it. /// /// ``` /// // Loft a square and a circle on the `XY` plane using offset. /// squareSketch = startSketchOn(XY) /// |> startProfileAt([-100, 200], %) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch = startSketchOn(offsetPlane(XY, offset = 150)) /// |> circle( center = [0, 100], radius = 50 ) /// /// loft([squareSketch, circleSketch]) /// ``` /// /// ``` /// // Loft a square and a circle on the `XZ` plane using offset. /// squareSketch = startSketchOn(XZ) /// |> startProfileAt([-100, 200], %) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch = startSketchOn(offsetPlane(XZ, offset = 150)) /// |> circle( center = [0, 100], radius = 50 ) /// /// loft([squareSketch, circleSketch]) /// ``` /// /// ``` /// // Loft a square and a circle on the `YZ` plane using offset. /// squareSketch = startSketchOn(YZ) /// |> startProfileAt([-100, 200], %) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch = startSketchOn(offsetPlane(YZ, offset = 150)) /// |> circle( center = [0, 100], radius = 50 ) /// /// loft([squareSketch, circleSketch]) /// ``` /// /// ``` /// // Loft a square and a circle on the `-XZ` plane using offset. /// squareSketch = startSketchOn(-XZ) /// |> startProfileAt([-100, 200], %) /// |> line(end = [200, 0]) /// |> line(end = [0, -200]) /// |> line(end = [-200, 0]) /// |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) /// |> close() /// /// circleSketch = startSketchOn(offsetPlane(-XZ, offset = 150)) /// |> circle(center = [0, 100], radius = 50) /// /// loft([squareSketch, circleSketch]) /// ``` /// /// ``` /// // A circle on the XY plane /// startSketchOn(XY) /// |> startProfileAt([0, 0], %) /// |> circle( radius = 10, center = [0, 0] ) /// /// // Triangle on the plane 4 units above /// startSketchOn(offsetPlane(XY, offset = 4)) /// |> startProfileAt([0, 0], %) /// |> line(end = [10, 0]) /// |> line(end = [0, 10]) /// |> close() /// ``` @(impl = std_rust) export fn offsetPlane( /// The plane (e.g. `XY`) which this new plane is created from. @plane: Plane, /// Distance from the standard plane this new plane will be created at. offset: number(Length), ): Plane {}