Move solids functions to KCL (#7214)

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-05-28 08:37:54 +12:00
committed by GitHub
parent 77730196ae
commit 067e193780
78 changed files with 1969 additions and 40759 deletions

View File

@ -562,5 +562,361 @@ export fn patternTransform(
/// 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,
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+] {}