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

@ -1,7 +1,6 @@
//! Constructive Solid Geometry (CSG) operations.
use anyhow::Result;
use kcl_derive_docs::stdlib;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
use kittycad_modeling_cmds::{
self as kcmc,
@ -34,85 +33,6 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
Ok(solids.into())
}
/// Union two or more solids into a single solid.
///
/// ```no_run
/// // 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])
/// ```
///
/// ```no_run
/// // 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
/// ```
///
/// ```no_run
/// // 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
/// ```
#[stdlib {
name = "union",
feature_tree_operation = true,
unlabeled_first = true,
args = {
solids = {docs = "The solids to union."},
tolerance = {docs = "The tolerance to use for the union operation."},
},
tags = ["solid"]
}]
pub(crate) async fn inner_union(
solids: Vec<Solid>,
tolerance: Option<TyF64>,
@ -178,66 +98,6 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
Ok(solids.into())
}
/// 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.
///
/// ```no_run
/// // 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])
/// ```
///
/// ```no_run
/// // 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
/// ```
#[stdlib {
name = "intersect",
feature_tree_operation = true,
unlabeled_first = true,
args = {
solids = {docs = "The solids to intersect."},
tolerance = {docs = "The tolerance to use for the intersection operation."},
},
tags = ["solid"]
}]
pub(crate) async fn inner_intersect(
solids: Vec<Solid>,
tolerance: Option<TyF64>,
@ -297,67 +157,6 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
Ok(solids.into())
}
/// Subtract removes tool solids from base solids, leaving the remaining material.
///
/// Performs a boolean 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.
///
/// ```no_run
/// // 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])
/// ```
///
/// ```no_run
/// // 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
/// ```
#[stdlib {
name = "subtract",
feature_tree_operation = true,
unlabeled_first = true,
args = {
solids = {docs = "The solids to use as the base to subtract from."},
tools = {docs = "The solids to subtract."},
tolerance = {docs = "The tolerance to use for the subtraction operation."},
},
tags = ["solid"]
}]
pub(crate) async fn inner_subtract(
solids: Vec<Solid>,
tools: Vec<Solid>,