* Replace tag type with tagIdent and tagDecl Signed-off-by: Nick Cameron <nrc@ncameron.org> * Replace tagIdent with TaggedEdge and TaggedFace Signed-off-by: Nick Cameron <nrc@ncameron.org> --------- Signed-off-by: Nick Cameron <nrc@ncameron.org>
1144 lines
36 KiB
Plaintext
1144 lines
36 KiB
Plaintext
/// This module contains functions for modifying solids, e.g., by adding a fillet or chamfer, or
|
|
/// removing part of a solid.
|
|
|
|
@no_std
|
|
@settings(defaultLengthUnit = mm, kclVersion = 1.0)
|
|
|
|
import Face from "std::types"
|
|
|
|
/// Blend a transitional edge along a tagged path, smoothing the sharp edge.
|
|
///
|
|
/// Fillet is similar in function and use to a chamfer, except
|
|
/// a chamfer will cut a sharp transition along an edge while fillet
|
|
/// will smoothly blend the transition.
|
|
///
|
|
/// ```
|
|
/// width = 20
|
|
/// length = 10
|
|
/// thickness = 1
|
|
/// filletRadius = 2
|
|
///
|
|
/// mountingPlateSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-width/2, -length/2])
|
|
/// |> line(endAbsolute = [width/2, -length/2], tag = $edge1)
|
|
/// |> line(endAbsolute = [width/2, length/2], tag = $edge2)
|
|
/// |> line(endAbsolute = [-width/2, length/2], tag = $edge3)
|
|
/// |> close(tag = $edge4)
|
|
///
|
|
/// mountingPlate = extrude(mountingPlateSketch, length = thickness)
|
|
/// |> fillet(
|
|
/// radius = filletRadius,
|
|
/// tags = [
|
|
/// getNextAdjacentEdge(edge1),
|
|
/// getNextAdjacentEdge(edge2),
|
|
/// getNextAdjacentEdge(edge3),
|
|
/// getNextAdjacentEdge(edge4)
|
|
/// ],
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// width = 20
|
|
/// length = 10
|
|
/// thickness = 1
|
|
/// filletRadius = 1
|
|
///
|
|
/// mountingPlateSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-width/2, -length/2])
|
|
/// |> line(endAbsolute = [width/2, -length/2], tag = $edge1)
|
|
/// |> line(endAbsolute = [width/2, length/2], tag = $edge2)
|
|
/// |> line(endAbsolute = [-width/2, length/2], tag = $edge3)
|
|
/// |> close(tag = $edge4)
|
|
///
|
|
/// mountingPlate = extrude(mountingPlateSketch, length = thickness)
|
|
/// |> fillet(
|
|
/// radius = filletRadius,
|
|
/// tolerance = 0.000001,
|
|
/// tags = [
|
|
/// getNextAdjacentEdge(edge1),
|
|
/// getNextAdjacentEdge(edge2),
|
|
/// getNextAdjacentEdge(edge3),
|
|
/// getNextAdjacentEdge(edge4)
|
|
/// ],
|
|
/// )
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn fillet(
|
|
/// The solid whose edges should be filletted
|
|
@solid: Solid,
|
|
/// The radius of the fillet
|
|
radius: number(Length),
|
|
/// The paths you want to fillet
|
|
tags: [Edge; 1+],
|
|
/// The tolerance for this fillet
|
|
tolerance?: number(Length),
|
|
/// Create a new tag which refers to this fillet
|
|
tag?: TagDecl,
|
|
): Solid {}
|
|
|
|
/// Cut a straight transitional edge along a tagged path.
|
|
///
|
|
/// Chamfer is similar in function and use to a fillet, except
|
|
/// a fillet will blend the transition along an edge, rather than cut
|
|
/// a sharp, straight transitional edge.
|
|
///
|
|
/// ```
|
|
/// // Chamfer a mounting plate.
|
|
/// width = 20
|
|
/// length = 10
|
|
/// thickness = 1
|
|
/// chamferLength = 2
|
|
///
|
|
/// mountingPlateSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-width/2, -length/2])
|
|
/// |> line(endAbsolute = [width/2, -length/2], tag = $edge1)
|
|
/// |> line(endAbsolute = [width/2, length/2], tag = $edge2)
|
|
/// |> line(endAbsolute = [-width/2, length/2], tag = $edge3)
|
|
/// |> close(tag = $edge4)
|
|
///
|
|
/// mountingPlate = extrude(mountingPlateSketch, length = thickness)
|
|
/// |> chamfer(
|
|
/// length = chamferLength,
|
|
/// tags = [
|
|
/// getNextAdjacentEdge(edge1),
|
|
/// getNextAdjacentEdge(edge2),
|
|
/// getNextAdjacentEdge(edge3),
|
|
/// getNextAdjacentEdge(edge4)
|
|
/// ],
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Sketch on the face of a chamfer.
|
|
/// fn cube(pos, scale) {
|
|
/// sg = startSketchOn(XY)
|
|
/// |> startProfile(at = pos)
|
|
/// |> line(end = [0, scale])
|
|
/// |> line(end = [scale, 0])
|
|
/// |> line(end = [0, -scale])
|
|
///
|
|
/// return sg
|
|
/// }
|
|
///
|
|
/// part001 = cube(pos = [0,0], scale = 20)
|
|
/// |> close(tag = $line1)
|
|
/// |> extrude(length = 20)
|
|
/// // We tag the chamfer to reference it later.
|
|
/// |> chamfer(
|
|
/// length = 10,
|
|
/// tags = [getOppositeEdge(line1)],
|
|
/// tag = $chamfer1,
|
|
/// )
|
|
///
|
|
/// sketch001 = startSketchOn(part001, face = chamfer1)
|
|
/// |> startProfile(at = [10, 10])
|
|
/// |> line(end = [2, 0])
|
|
/// |> line(end = [0, 2])
|
|
/// |> line(end = [-2, 0])
|
|
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn chamfer(
|
|
/// The solid whose edges should be chamfered
|
|
@solid: Solid,
|
|
/// The length of the chamfer
|
|
length: number(Length),
|
|
/// The paths you want to chamfer
|
|
tags: [Edge; 1+],
|
|
/// Create a new tag which refers to this chamfer
|
|
tag?: TagDecl,
|
|
): Solid {}
|
|
|
|
/// Remove volume from a 3-dimensional shape such that a wall of the
|
|
/// provided thickness remains, taking volume starting at the provided
|
|
/// face, leaving it open in that direction.
|
|
///
|
|
/// ```
|
|
/// // Remove the end face for the extrusion.
|
|
/// firstSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0])
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
///
|
|
/// // Remove the end face for the extrusion.
|
|
/// shell(
|
|
/// firstSketch,
|
|
/// faces = [END],
|
|
/// thickness = 0.25,
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Remove the start face for the extrusion.
|
|
/// firstSketch = startSketchOn(-XZ)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0])
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
///
|
|
/// // Remove the start face for the extrusion.
|
|
/// shell(
|
|
/// firstSketch,
|
|
/// faces = [START],
|
|
/// thickness = 0.25,
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Remove a tagged face and the end face for the extrusion.
|
|
/// firstSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0], tag = $myTag)
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
///
|
|
/// // Remove a tagged face for the extrusion.
|
|
/// shell(
|
|
/// firstSketch,
|
|
/// faces = [myTag],
|
|
/// thickness = 0.25,
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Remove multiple faces at once.
|
|
/// firstSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0], tag = $myTag)
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
///
|
|
/// // Remove a tagged face and the end face for the extrusion.
|
|
/// shell(
|
|
/// firstSketch,
|
|
/// faces = [myTag, END],
|
|
/// thickness = 0.25,
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Shell a sketch on face.
|
|
/// size = 100
|
|
/// case = startSketchOn(-XZ)
|
|
/// |> startProfile(at = [-size, -size])
|
|
/// |> line(end = [2 * size, 0])
|
|
/// |> line(end = [0, 2 * size])
|
|
/// |> tangentialArc(endAbsolute = [-size, size])
|
|
/// |> close()
|
|
/// |> extrude(length = 65)
|
|
///
|
|
/// thing1 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [-size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// thing2 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// // We put "case" in the shell function to shell the entire object.
|
|
/// shell(case, faces = [START], thickness = 5)
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Shell a sketch on face object on the end face.
|
|
/// size = 100
|
|
/// case = startSketchOn(XY)
|
|
/// |> startProfile(at = [-size, -size])
|
|
/// |> line(end = [2 * size, 0])
|
|
/// |> line(end = [0, 2 * size])
|
|
/// |> tangentialArc(endAbsolute = [-size, size])
|
|
/// |> close()
|
|
/// |> extrude(length = 65)
|
|
///
|
|
/// thing1 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [-size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// thing2 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// // We put "thing1" in the shell function to shell the end face of the object.
|
|
/// shell(thing1, faces = [END], thickness = 5)
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Shell sketched on face objects on the end face, include all sketches to shell
|
|
/// // the entire object.
|
|
///
|
|
/// size = 100
|
|
/// case = startSketchOn(XY)
|
|
/// |> startProfile(at = [-size, -size])
|
|
/// |> line(end = [2 * size, 0])
|
|
/// |> line(end = [0, 2 * size])
|
|
/// |> tangentialArc(endAbsolute = [-size, size])
|
|
/// |> close()
|
|
/// |> extrude(length = 65)
|
|
///
|
|
/// thing1 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [-size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// thing2 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [size / 2, -size / 2], radius = 25)
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// // We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
|
/// shell([thing1, thing2], faces = [END], thickness = 5)
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn shell(
|
|
/// Which solid (or solids) to shell out
|
|
@solids: [Solid; 1+],
|
|
/// The thickness of the shell
|
|
thickness: number(Length),
|
|
/// The faces you want removed
|
|
faces: [TaggedFace; 1+],
|
|
): [Solid] {}
|
|
|
|
|
|
/// Make the inside of a 3D object hollow.
|
|
///
|
|
/// Remove volume from a 3-dimensional shape such that a wall of the
|
|
/// provided thickness remains around the exterior of the shape.
|
|
///
|
|
/// ```
|
|
/// // Hollow a basic sketch.
|
|
/// firstSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0])
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
/// |> hollow (thickness = 0.25)
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Hollow a basic sketch.
|
|
/// firstSketch = startSketchOn(-XZ)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0])
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
/// |> hollow (thickness = 0.5)
|
|
/// ```
|
|
///
|
|
/// ```
|
|
/// // Hollow a sketch on face object.
|
|
/// size = 100
|
|
/// case = startSketchOn(-XZ)
|
|
/// |> startProfile(at = [-size, -size])
|
|
/// |> line(end = [2 * size, 0])
|
|
/// |> line(end = [0, 2 * size])
|
|
/// |> tangentialArc(endAbsolute = [-size, size])
|
|
/// |> close()
|
|
/// |> extrude(length = 65)
|
|
///
|
|
/// thing1 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [-size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// thing2 = startSketchOn(case, face = END)
|
|
/// |> circle( center = [size / 2, -size / 2], radius = 25 )
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// hollow(case, thickness = 0.5)
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn hollow(
|
|
/// Which solid to hollow out
|
|
@solid: Solid,
|
|
/// The thickness of the remaining shell
|
|
thickness: number(Length),
|
|
): Solid {}
|
|
|
|
/// Repeat a 3-dimensional solid, changing it each time.
|
|
///
|
|
/// Replicates the 3D solid, applying a transformation function to each replica.
|
|
/// Transformation function could alter rotation, scale, visibility, position, etc.
|
|
///
|
|
/// The `patternTransform` call itself takes a number for how many total instances of
|
|
/// the shape should be. For example, if you use a circle with `patternTransform(instances = 4, transform = f)`
|
|
/// then there will be 4 circles: the original, and 3 created by replicating the original and
|
|
/// calling the transform function on each.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// The transform function returns a transform object. All properties of the object are optional,
|
|
/// they each default to "no change". So the overall transform object defaults to "no change" too.
|
|
/// Its properties are:
|
|
///
|
|
/// - `translate` (3D point)
|
|
///
|
|
/// Translates the replica, moving its position in space.
|
|
///
|
|
/// - `replicate` (bool)
|
|
///
|
|
/// If false, this ID will not actually copy the object. It'll be skipped.
|
|
///
|
|
/// - `scale` (3D point)
|
|
///
|
|
/// Stretches the object, multiplying its width in the given dimension by the point's component in
|
|
/// that direction.
|
|
///
|
|
/// - `rotation` (object, with the following properties)
|
|
///
|
|
/// - `rotation.axis` (a 3D point, defaults to the Z axis)
|
|
///
|
|
/// - `rotation.angle`
|
|
///
|
|
/// - `rotation.origin` (either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local")
|
|
///
|
|
/// ```kcl
|
|
/// // Each instance will be shifted along the X axis.
|
|
/// fn transform(@id) {
|
|
/// return { translate = [4 * id, 0, 0] }
|
|
/// }
|
|
///
|
|
/// // Sketch 4 cylinders.
|
|
/// sketch001 = startSketchOn(XZ)
|
|
/// |> circle(center = [0, 0], radius = 2)
|
|
/// |> extrude(length = 5)
|
|
/// |> patternTransform(instances = 4, transform = transform)
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Each instance will be shifted along the X axis,
|
|
/// // with a gap between the original (at x = 0) and the first replica
|
|
/// // (at x = 8). This is because `id` starts at 1.
|
|
/// fn transform(@id) {
|
|
/// return { translate = [4 * (1+id), 0, 0] }
|
|
/// }
|
|
///
|
|
/// sketch001 = startSketchOn(XZ)
|
|
/// |> circle(center = [0, 0], radius = 2)
|
|
/// |> extrude(length = 5)
|
|
/// |> patternTransform(instances = 4, transform = transform)
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// fn cube(length, center) {
|
|
/// l = length/2
|
|
/// x = center[0]
|
|
/// y = center[1]
|
|
/// p0 = [-l + x, -l + y]
|
|
/// p1 = [-l + x, l + y]
|
|
/// p2 = [ l + x, l + y]
|
|
/// p3 = [ l + x, -l + y]
|
|
///
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = p0)
|
|
/// |> line(endAbsolute = p1)
|
|
/// |> line(endAbsolute = p2)
|
|
/// |> line(endAbsolute = p3)
|
|
/// |> line(endAbsolute = p0)
|
|
/// |> close()
|
|
/// |> extrude(length = length)
|
|
/// }
|
|
///
|
|
/// width = 20
|
|
/// fn transform(@i) {
|
|
/// return {
|
|
/// // Move down each time.
|
|
/// translate = [0, 0, -i * width],
|
|
/// // Make the cube longer, wider and flatter each time.
|
|
/// scale = [pow(1.1, exp = i), pow(1.1, exp = i), pow(0.9, exp = i)],
|
|
/// // Turn by 15 degrees each time.
|
|
/// rotation = {
|
|
/// angle = 15deg * i,
|
|
/// origin = "local",
|
|
/// }
|
|
/// }
|
|
/// }
|
|
///
|
|
/// myCubes =
|
|
/// cube(length = width, center = [100,0])
|
|
/// |> patternTransform(instances = 25, transform = transform)
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// fn cube(length, center) {
|
|
/// l = length/2
|
|
/// x = center[0]
|
|
/// y = center[1]
|
|
/// p0 = [-l + x, -l + y]
|
|
/// p1 = [-l + x, l + y]
|
|
/// p2 = [ l + x, l + y]
|
|
/// p3 = [ l + x, -l + y]
|
|
///
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = p0)
|
|
/// |> line(endAbsolute = p1)
|
|
/// |> line(endAbsolute = p2)
|
|
/// |> line(endAbsolute = p3)
|
|
/// |> line(endAbsolute = p0)
|
|
/// |> close()
|
|
/// |> extrude(length = length)
|
|
/// }
|
|
///
|
|
/// width = 20
|
|
/// fn transform(@i) {
|
|
/// return {
|
|
/// translate = [0, 0, -i * width],
|
|
/// rotation = {
|
|
/// angle = 90deg * i,
|
|
/// // Rotate around the overall scene's origin.
|
|
/// origin = "global",
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// myCubes =
|
|
/// cube(length = width, center = [100,100])
|
|
/// |> patternTransform(instances = 4, transform = transform)
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Parameters
|
|
/// r = 50 // base radius
|
|
/// h = 10 // layer height
|
|
/// t = 0.005 // taper factor [0-1)
|
|
/// // Defines how to modify each layer of the vase.
|
|
/// // Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
|
/// fn transform(@replicaId) {
|
|
/// scale = r * abs(1 - (t * replicaId)) * (5 + cos((replicaId / 8): number(rad)))
|
|
/// return {
|
|
/// translate = [0, 0, replicaId * 10],
|
|
/// scale = [scale, scale, 0],
|
|
/// }
|
|
/// }
|
|
/// // Each layer is just a pretty thin cylinder.
|
|
/// fn layer() {
|
|
/// return startSketchOn(XY) // or some other plane idk
|
|
/// |> circle(center = [0, 0], radius = 1, tag = $tag1)
|
|
/// |> extrude(length = h)
|
|
/// }
|
|
/// // The vase is 100 layers tall.
|
|
/// // The 100 layers are replica of each other, with a slight transformation applied to each.
|
|
/// vase = layer() |> patternTransform(instances = 100, transform = transform)
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// fn transform(@i) {
|
|
/// // Transform functions can return multiple transforms. They'll be applied in order.
|
|
/// return [
|
|
/// { translate = [30 * i, 0, 0] },
|
|
/// { rotation = { angle = 45deg * i } },
|
|
/// ]
|
|
/// }
|
|
/// startSketchOn(XY)
|
|
/// |> startProfile(at = [0, 0])
|
|
/// |> polygon(
|
|
/// radius = 10,
|
|
/// numSides = 4,
|
|
/// center = [0, 0],
|
|
/// inscribed = false,
|
|
/// )
|
|
/// |> extrude(length = 4)
|
|
/// |> patternTransform(instances = 3, transform = transform)
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn patternTransform(
|
|
/// The solid(s) to duplicate.
|
|
@solids: [Solid; 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?: bool = false,
|
|
): [Solid; 1+] {}
|
|
|
|
/// Repeat a 3-dimensional solid along a linear path, with a dynamic amount
|
|
/// of distance between each repetition, some specified number of times.
|
|
///
|
|
/// ```kcl
|
|
/// /// Pattern using a named axis.
|
|
///
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> startProfile(at = [0, 0])
|
|
/// |> line(end = [0, 2])
|
|
/// |> line(end = [3, 1])
|
|
/// |> line(end = [0, -4])
|
|
/// |> close()
|
|
///
|
|
/// example = extrude(exampleSketch, length = 1)
|
|
/// |> patternLinear3d(
|
|
/// axis = X,
|
|
/// instances = 7,
|
|
/// distance = 6
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// /// Pattern using a raw axis.
|
|
///
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> startProfile(at = [0, 0])
|
|
/// |> line(end = [0, 2])
|
|
/// |> line(end = [3, 1])
|
|
/// |> line(end = [0, -4])
|
|
/// |> close()
|
|
///
|
|
/// example = extrude(exampleSketch, length = 1)
|
|
/// |> patternLinear3d(
|
|
/// axis = [1, 0, 1],
|
|
/// instances = 7,
|
|
/// distance = 6
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Pattern a whole sketch on face.
|
|
/// size = 100
|
|
/// case = startSketchOn(XY)
|
|
/// |> startProfile(at = [-size, -size])
|
|
/// |> line(end = [2 * size, 0])
|
|
/// |> line(end = [0, 2 * size])
|
|
/// |> tangentialArc(endAbsolute = [-size, size])
|
|
/// |> close(%)
|
|
/// |> extrude(length = 65)
|
|
///
|
|
/// thing1 = startSketchOn(case, face = END)
|
|
/// |> circle(center = [-size / 2, -size / 2], radius = 25)
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// thing2 = startSketchOn(case, face = END)
|
|
/// |> circle(center = [size / 2, -size / 2], radius = 25)
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// // We pass in the "case" here since we want to pattern the whole sketch.
|
|
/// // And the case was the base of the sketch.
|
|
/// patternLinear3d(case,
|
|
/// axis= [1, 0, 0],
|
|
/// distance= 250,
|
|
/// instances=2,
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Pattern an object on a face.
|
|
/// size = 100
|
|
/// case = startSketchOn(XY)
|
|
/// |> startProfile(at = [-size, -size])
|
|
/// |> line(end = [2 * size, 0])
|
|
/// |> line(end = [0, 2 * size])
|
|
/// |> tangentialArc(endAbsolute = [-size, size])
|
|
/// |> close(%)
|
|
/// |> extrude(length = 65)
|
|
///
|
|
/// thing1 = startSketchOn(case, face = END)
|
|
/// |> circle(center =[-size / 2, -size / 2], radius = 25)
|
|
/// |> extrude(length = 50)
|
|
///
|
|
/// // We pass in `thing1` here with `useOriginal` since we want to pattern just this object on the face.
|
|
/// patternLinear3d(thing1,
|
|
/// axis = [1, 0, 0],
|
|
/// distance = size,
|
|
/// instances =2,
|
|
/// useOriginal = true
|
|
/// )
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn patternLinear3d(
|
|
/// The solid(s) to duplicate.
|
|
@solids: [Solid; 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 3D vector.
|
|
@(snippetArray = ["1", "0", "0"])
|
|
axis: Axis3d | Point3d,
|
|
/// 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,
|
|
): [Solid; 1+] {}
|
|
|
|
/// Repeat a 3-dimensional solid 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
|
|
/// /// Pattern using a named axis.
|
|
///
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> circle(center = [0, 0], radius = 1)
|
|
///
|
|
/// example = extrude(exampleSketch, length = -5)
|
|
/// |> patternCircular3d(
|
|
/// axis = X,
|
|
/// center = [10, -20, 0],
|
|
/// instances = 11,
|
|
/// arcDegrees = 360,
|
|
/// rotateDuplicates = true
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// /// Pattern using a raw axis.
|
|
///
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> circle(center = [0, 0], radius = 1)
|
|
///
|
|
/// example = extrude(exampleSketch, length = -5)
|
|
/// |> patternCircular3d(
|
|
/// axis = [1, -1, 0],
|
|
/// center = [10, -20, 0],
|
|
/// instances = 11,
|
|
/// arcDegrees = 360,
|
|
/// rotateDuplicates = true
|
|
/// )
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn patternCircular3d(
|
|
/// The solid(s) to pattern.
|
|
@solids: [Solid; 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 axis of the pattern. A 3D vector.
|
|
@(snippetArray = ["1", "0", "0"])
|
|
axis: Axis3d | Point3d,
|
|
/// The center about which to make the pattern. This is a 3D vector.
|
|
@(snippetArray = ["0", "0", "0"])
|
|
center: Point3d,
|
|
/// "The arc angle to place the repetitions. Must be greater than 0.
|
|
arcDegrees?: number(deg) = 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,
|
|
): [Solid; 1+] {}
|
|
|
|
/// Union two or more solids into a single solid.
|
|
///
|
|
/// ```kcl
|
|
/// // Union two cubes using the stdlib functions.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// unionedPart = union([part001, part002])
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Union two cubes using operators.
|
|
/// // NOTE: This will not work when using codemods through the UI.
|
|
/// // Codemods will generate the stdlib function call instead.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// // This is the equivalent of: union([part001, part002])
|
|
/// unionedPart = part001 + part002
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Union two cubes using the more programmer-friendly operator.
|
|
/// // NOTE: This will not work when using codemods through the UI.
|
|
/// // Codemods will generate the stdlib function call instead.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// // This is the equivalent of: union([part001, part002])
|
|
/// // Programmers will understand `|` as a union operation, but mechanical engineers
|
|
/// // will understand `+`, we made both work.
|
|
/// unionedPart = part001 | part002
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn union(
|
|
/// The solids to union.
|
|
@solids: [Solid; 2+],
|
|
/// The tolerance to use for the union operation.
|
|
tolerance?: number(Length),
|
|
): [Solid; 1+] {}
|
|
|
|
/// Intersect returns the shared volume between multiple solids, preserving only
|
|
/// overlapping regions.
|
|
///
|
|
/// Intersect computes the geometric intersection of multiple solid bodies,
|
|
/// returning a new solid representing the volume that is common to all input
|
|
/// solids. This operation is useful for determining shared material regions,
|
|
/// verifying fit, and analyzing overlapping geometries in assemblies.
|
|
///
|
|
/// ```kcl
|
|
/// // Intersect two cubes using the stdlib functions.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// intersectedPart = intersect([part001, part002])
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Intersect two cubes using operators.
|
|
/// // NOTE: This will not work when using codemods through the UI.
|
|
/// // Codemods will generate the stdlib function call instead.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// // This is the equivalent of: intersect([part001, part002])
|
|
/// intersectedPart = part001 & part002
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn intersect(
|
|
/// The solids to intersect.
|
|
@solids: [Solid; 2+],
|
|
/// The tolerance to use for the intersection operation.
|
|
tolerance?: number(Length),
|
|
): [Solid; 1+] {}
|
|
|
|
/// Subtract removes tool solids from base solids, leaving the remaining material.
|
|
///
|
|
/// Performs a bool subtraction operation, removing the volume of one or more
|
|
/// tool solids from one or more base solids. The result is a new solid
|
|
/// representing the material that remains after all tool solids have been cut
|
|
/// away. This function is essential for machining simulations, cavity creation,
|
|
/// and complex multi-body part modeling.
|
|
///
|
|
/// ```kcl
|
|
/// // Subtract a cylinder from a cube using the stdlib functions.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// subtractedPart = subtract([part001], tools=[part002])
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Subtract a cylinder from a cube using operators.
|
|
/// // NOTE: This will not work when using codemods through the UI.
|
|
/// // Codemods will generate the stdlib function call instead.
|
|
///
|
|
/// fn cube(center, size) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] - size])
|
|
/// |> line(endAbsolute = [center[0] + size, center[1] + size])
|
|
/// |> line(endAbsolute = [center[0] - size, center[1] + size])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// part001 = cube(center = [0, 0], size = 10)
|
|
/// part002 = cube(center = [7, 3], size = 5)
|
|
/// |> translate(z = 1)
|
|
///
|
|
/// // This is the equivalent of: subtract([part001], tools=[part002])
|
|
/// subtractedPart = part001 - part002
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn subtract(
|
|
/// The solids to use as the base to subtract from.
|
|
@solids: [Solid; 1+],
|
|
/// The solids to subtract.
|
|
tools: [Solid],
|
|
/// The tolerance to use for the subtraction operation.
|
|
tolerance?: number(Length),
|
|
): [Solid; 1+] {}
|
|
|
|
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
|
|
///
|
|
/// This will work on any solid, including extruded solids, revolved solids, and shelled solids.
|
|
///
|
|
/// ```kcl
|
|
/// // Add color to an extruded solid.
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> startProfile(at = [0, 0])
|
|
/// |> line(endAbsolute = [10, 0])
|
|
/// |> line(endAbsolute = [0, 10])
|
|
/// |> line(endAbsolute = [-10, 0])
|
|
/// |> close()
|
|
///
|
|
/// example = extrude(exampleSketch, length = 5)
|
|
/// // There are other options besides 'color', but they're optional.
|
|
/// |> appearance(color='#ff0000')
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Add color to a revolved solid.
|
|
/// sketch001 = startSketchOn(XY)
|
|
/// |> circle( center = [15, 0], radius = 5 )
|
|
/// |> revolve( angle = 360deg, axis = Y)
|
|
/// |> appearance(
|
|
/// color = '#ff0000',
|
|
/// metalness = 90,
|
|
/// roughness = 90
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Add color to different solids.
|
|
/// fn cube(center) {
|
|
/// return startSketchOn(XY)
|
|
/// |> startProfile(at = [center[0] - 10, center[1] - 10])
|
|
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
|
|
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
|
|
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
|
|
/// |> close()
|
|
/// |> extrude(length = 10)
|
|
/// }
|
|
///
|
|
/// example0 = cube(center = [0, 0])
|
|
/// example1 = cube(center = [20, 0])
|
|
/// example2 = cube(center = [40, 0])
|
|
///
|
|
/// appearance([example0, example1], color='#ff0000', metalness=50, roughness=50)
|
|
/// appearance(example2, color='#00ff00', metalness=50, roughness=50)
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // You can set the appearance before or after you shell it will yield the same result.
|
|
/// // This example shows setting the appearance _after_ the shell.
|
|
/// firstSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0])
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
///
|
|
/// shell(
|
|
/// firstSketch,
|
|
/// faces = [END],
|
|
/// thickness = 0.25,
|
|
/// )
|
|
/// |> appearance(
|
|
/// color = '#ff0000',
|
|
/// metalness = 90,
|
|
/// roughness = 90
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // You can set the appearance before or after you shell it will yield the same result.
|
|
/// // This example shows setting the appearance _before_ the shell.
|
|
/// firstSketch = startSketchOn(XY)
|
|
/// |> startProfile(at = [-12, 12])
|
|
/// |> line(end = [24, 0])
|
|
/// |> line(end = [0, -24])
|
|
/// |> line(end = [-24, 0])
|
|
/// |> close()
|
|
/// |> extrude(length = 6)
|
|
/// |> appearance(
|
|
/// color = '#ff0000',
|
|
/// metalness = 90,
|
|
/// roughness = 90
|
|
/// )
|
|
///
|
|
/// shell(
|
|
/// firstSketch,
|
|
/// faces = [END],
|
|
/// thickness = 0.25,
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
|
|
/// // This example shows _before_ the pattern.
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> startProfile(at = [0, 0])
|
|
/// |> line(end = [0, 2])
|
|
/// |> line(end = [3, 1])
|
|
/// |> line(end = [0, -4])
|
|
/// |> close()
|
|
///
|
|
/// example = extrude(exampleSketch, length = 1)
|
|
/// |> appearance(
|
|
/// color = '#ff0000',
|
|
/// metalness = 90,
|
|
/// roughness = 90
|
|
/// )
|
|
/// |> patternLinear3d(
|
|
/// axis = [1, 0, 1],
|
|
/// instances = 7,
|
|
/// distance = 6
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Setting the appearance of a 3D pattern can be done _before_ or _after_ the pattern.
|
|
/// // This example shows _after_ the pattern.
|
|
/// exampleSketch = startSketchOn(XZ)
|
|
/// |> startProfile(at = [0, 0])
|
|
/// |> line(end = [0, 2])
|
|
/// |> line(end = [3, 1])
|
|
/// |> line(end = [0, -4])
|
|
/// |> close()
|
|
///
|
|
/// example = extrude(exampleSketch, length = 1)
|
|
/// |> patternLinear3d(
|
|
/// axis = [1, 0, 1],
|
|
/// instances = 7,
|
|
/// distance = 6
|
|
/// )
|
|
/// |> appearance(
|
|
/// color = '#ff0000',
|
|
/// metalness = 90,
|
|
/// roughness = 90
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Color the result of a 2D pattern that was extruded.
|
|
/// 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)
|
|
/// |> appearance(
|
|
/// color = '#ff0000',
|
|
/// metalness = 90,
|
|
/// roughness = 90
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Color the result of 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])
|
|
///
|
|
/// 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)
|
|
/// |> appearance(
|
|
/// color = "#ff0000",
|
|
/// metalness = 50,
|
|
/// roughness = 50
|
|
/// )
|
|
/// ```
|
|
///
|
|
/// ```kcl
|
|
/// // Change the appearance of an imported model.
|
|
///
|
|
/// import "tests/inputs/cube.sldprt" as cube
|
|
///
|
|
/// cube
|
|
/// |> appearance(
|
|
/// color = "#ff0000",
|
|
/// metalness = 50,
|
|
/// roughness = 50
|
|
/// )
|
|
/// ```
|
|
@(impl = std_rust)
|
|
export fn appearance(
|
|
/// The The solid(s) whose appearance is being set.
|
|
@solids: [Solid; 1+] | ImportedGeometry,
|
|
/// Color of the new material, a hex string like '#ff0000'.
|
|
color: string,
|
|
/// Metalness of the new material, a percentage like 95.7.
|
|
metalness?: number(Count),
|
|
/// Roughness of the new material, a percentage like 95.7.
|
|
roughness?: number(Count),
|
|
): [Solid; 1+] | ImportedGeometry {}
|