Bump modeling api & pull thru csg endpoints (#6245)
* csg-upts Signed-off-by: Jess Frazelle <github@jessfraz.com> * base Signed-off-by: Jess Frazelle <github@jessfraz.com> * do the id shit Signed-off-by: Jess Frazelle <github@jessfraz.com> * tried to run Signed-off-by: Jess Frazelle <github@jessfraz.com> * csg-upts Signed-off-by: Jess Frazelle <github@jessfraz.com> * use bens samples Signed-off-by: Jess Frazelle <github@jessfraz.com> * use bens samples Signed-off-by: Jess Frazelle <github@jessfraz.com> * gen std Signed-off-by: Jess Frazelle <github@jessfraz.com> * gen std Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix; Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
							
								
								
									
										4
									
								
								rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						@ -2033,9 +2033,9 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "kittycad-modeling-cmds"
 | 
			
		||||
version = "0.2.110"
 | 
			
		||||
version = "0.2.112"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "bdfd16800a12a2eaefff53958bd871875c246e669274269f7caefc25d19641ad"
 | 
			
		||||
checksum = "08f06b4eb4e98ded7cda21586347baeb8055c4898f609f55f7c544cfed2b229c"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "anyhow",
 | 
			
		||||
 "chrono",
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ dashmap = { version = "6.1.0" }
 | 
			
		||||
http = "1"
 | 
			
		||||
indexmap = "2.7.0"
 | 
			
		||||
kittycad = { version = "0.3.36", default-features = false, features = ["js", "requests"] }
 | 
			
		||||
kittycad-modeling-cmds = { version = "0.2.110", features = ["ts-rs", "websocket"] }
 | 
			
		||||
kittycad-modeling-cmds = { version = "0.2.112", features = ["ts-rs", "websocket"] }
 | 
			
		||||
lazy_static = "1.5.0"
 | 
			
		||||
miette = "7.5.0"
 | 
			
		||||
pyo3 = { version = "0.24.0" }
 | 
			
		||||
 | 
			
		||||
@ -939,25 +939,40 @@ impl Node<BinaryExpression> {
 | 
			
		||||
        if self.operator == BinaryOperator::Add || self.operator == BinaryOperator::Or {
 | 
			
		||||
            if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
                let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
 | 
			
		||||
                let result =
 | 
			
		||||
                    crate::std::csg::inner_union(vec![*left.clone(), *right.clone()], exec_state, args).await?;
 | 
			
		||||
                let result = crate::std::csg::inner_union(
 | 
			
		||||
                    vec![*left.clone(), *right.clone()],
 | 
			
		||||
                    Default::default(),
 | 
			
		||||
                    exec_state,
 | 
			
		||||
                    args,
 | 
			
		||||
                )
 | 
			
		||||
                .await?;
 | 
			
		||||
                return Ok(result.into());
 | 
			
		||||
            }
 | 
			
		||||
        } else if self.operator == BinaryOperator::Sub {
 | 
			
		||||
            // Check if we have solids.
 | 
			
		||||
            if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
                let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
 | 
			
		||||
                let result =
 | 
			
		||||
                    crate::std::csg::inner_subtract(vec![*left.clone()], vec![*right.clone()], exec_state, args)
 | 
			
		||||
                        .await?;
 | 
			
		||||
                let result = crate::std::csg::inner_subtract(
 | 
			
		||||
                    vec![*left.clone()],
 | 
			
		||||
                    vec![*right.clone()],
 | 
			
		||||
                    Default::default(),
 | 
			
		||||
                    exec_state,
 | 
			
		||||
                    args,
 | 
			
		||||
                )
 | 
			
		||||
                .await?;
 | 
			
		||||
                return Ok(result.into());
 | 
			
		||||
            }
 | 
			
		||||
        } else if self.operator == BinaryOperator::And {
 | 
			
		||||
            // Check if we have solids.
 | 
			
		||||
            if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
                let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
 | 
			
		||||
                let result =
 | 
			
		||||
                    crate::std::csg::inner_intersect(vec![*left.clone(), *right.clone()], exec_state, args).await?;
 | 
			
		||||
                let result = crate::std::csg::inner_intersect(
 | 
			
		||||
                    vec![*left.clone(), *right.clone()],
 | 
			
		||||
                    Default::default(),
 | 
			
		||||
                    exec_state,
 | 
			
		||||
                    args,
 | 
			
		||||
                )
 | 
			
		||||
                .await?;
 | 
			
		||||
                return Ok(result.into());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,13 @@
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
    ok_response::OkModelingCmdResponse,
 | 
			
		||||
    output::{BooleanIntersection, BooleanSubtract, BooleanUnion},
 | 
			
		||||
    websocket::OkWebSocketResponseData,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
@ -9,10 +16,13 @@ use crate::{
 | 
			
		||||
    std::Args,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::DEFAULT_TOLERANCE;
 | 
			
		||||
 | 
			
		||||
/// Union two or more solids into a single solid.
 | 
			
		||||
pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
    let solids: Vec<Solid> =
 | 
			
		||||
        args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::Union(vec![RuntimeType::solids()]), exec_state)?;
 | 
			
		||||
    let tolerance = args.get_kw_arg_opt("tolerance")?;
 | 
			
		||||
 | 
			
		||||
    if solids.len() < 2 {
 | 
			
		||||
        return Err(KclError::UndefinedValue(KclErrorDetails {
 | 
			
		||||
@ -21,7 +31,7 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let solids = inner_union(solids, exec_state, args).await?;
 | 
			
		||||
    let solids = inner_union(solids, tolerance, exec_state, args).await?;
 | 
			
		||||
    Ok(solids.into())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,18 +40,19 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
/// ```no_run
 | 
			
		||||
/// // Union two cubes using the stdlib functions.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = cube([20, 10])
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// unionedPart = union([part001, part002])
 | 
			
		||||
/// ```
 | 
			
		||||
@ -51,18 +62,19 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
/// // NOTE: This will not work when using codemods through the UI.
 | 
			
		||||
/// // Codemods will generate the stdlib function call instead.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = cube([20, 10])
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// // This is the equivalent of: union([part001, part002])
 | 
			
		||||
/// unionedPart = part001 + part002
 | 
			
		||||
@ -73,18 +85,19 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
/// // NOTE: This will not work when using codemods through the UI.
 | 
			
		||||
/// // Codemods will generate the stdlib function call instead.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = cube([20, 10])
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// // This is the equivalent of: union([part001, part002])
 | 
			
		||||
/// // Programmers will understand `|` as a union operation, but mechanical engineers
 | 
			
		||||
@ -96,31 +109,64 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
    feature_tree_operation = true,
 | 
			
		||||
    keywords = true,
 | 
			
		||||
    unlabeled_first = true,
 | 
			
		||||
    deprecated = true,
 | 
			
		||||
    args = {
 | 
			
		||||
        solids = {docs = "The solids to union."},
 | 
			
		||||
        tolerance = {docs = "The tolerance to use for the union operation."},
 | 
			
		||||
    }
 | 
			
		||||
}]
 | 
			
		||||
pub(crate) async fn inner_union(
 | 
			
		||||
    solids: Vec<Solid>,
 | 
			
		||||
    tolerance: Option<f64>,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
) -> Result<Vec<Solid>, KclError> {
 | 
			
		||||
    let solid_out_id = exec_state.next_uuid();
 | 
			
		||||
 | 
			
		||||
    let mut solid = solids[0].clone();
 | 
			
		||||
    solid.id = solid_out_id;
 | 
			
		||||
    let mut new_solids = vec![solid.clone()];
 | 
			
		||||
 | 
			
		||||
    if args.ctx.no_engine_commands().await {
 | 
			
		||||
        return Ok(new_solids);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Flush the fillets for the solids.
 | 
			
		||||
    args.flush_batch_for_solids(exec_state, &solids).await?;
 | 
			
		||||
 | 
			
		||||
    // TODO: call the engine union operation.
 | 
			
		||||
    // TODO: figure out all the shit after for the faces etc.
 | 
			
		||||
    let result = args
 | 
			
		||||
        .send_modeling_cmd(
 | 
			
		||||
            solid_out_id,
 | 
			
		||||
            ModelingCmd::from(mcmd::BooleanUnion {
 | 
			
		||||
                solid_ids: solids.iter().map(|s| s.id).collect(),
 | 
			
		||||
                tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
    // For now just return the first solid.
 | 
			
		||||
    // Til we have a proper implementation.
 | 
			
		||||
    Ok(vec![solids[0].clone()])
 | 
			
		||||
    let OkWebSocketResponseData::Modeling {
 | 
			
		||||
        modeling_response: OkModelingCmdResponse::BooleanUnion(BooleanUnion { extra_solid_ids }),
 | 
			
		||||
    } = result
 | 
			
		||||
    else {
 | 
			
		||||
        return Err(KclError::Internal(KclErrorDetails {
 | 
			
		||||
            message: "Failed to get the result of the union operation.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // If we have more solids, set those as well.
 | 
			
		||||
    if !extra_solid_ids.is_empty() {
 | 
			
		||||
        solid.id = extra_solid_ids[0];
 | 
			
		||||
        new_solids.push(solid.clone());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(new_solids)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Intersect returns the shared volume between multiple solids, preserving only
 | 
			
		||||
/// overlapping regions.
 | 
			
		||||
pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
    let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
 | 
			
		||||
    let tolerance = args.get_kw_arg_opt("tolerance")?;
 | 
			
		||||
 | 
			
		||||
    if solids.len() < 2 {
 | 
			
		||||
        return Err(KclError::UndefinedValue(KclErrorDetails {
 | 
			
		||||
@ -129,7 +175,7 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let solids = inner_intersect(solids, exec_state, args).await?;
 | 
			
		||||
    let solids = inner_intersect(solids, tolerance, exec_state, args).await?;
 | 
			
		||||
    Ok(solids.into())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -144,18 +190,19 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
/// ```no_run
 | 
			
		||||
/// // Intersect two cubes using the stdlib functions.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = cube([8, 8])
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// intersectedPart = intersect([part001, part002])
 | 
			
		||||
/// ```
 | 
			
		||||
@ -165,18 +212,19 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
/// // NOTE: This will not work when using codemods through the UI.
 | 
			
		||||
/// // Codemods will generate the stdlib function call instead.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = cube([8, 8])
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// // This is the equivalent of: intersect([part001, part002])
 | 
			
		||||
/// intersectedPart = part001 & part002
 | 
			
		||||
@ -186,25 +234,57 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
    feature_tree_operation = true,
 | 
			
		||||
    keywords = true,
 | 
			
		||||
    unlabeled_first = true,
 | 
			
		||||
    deprecated = true,
 | 
			
		||||
    args = {
 | 
			
		||||
        solids = {docs = "The solids to intersect."},
 | 
			
		||||
        tolerance = {docs = "The tolerance to use for the intersection operation."},
 | 
			
		||||
    }
 | 
			
		||||
}]
 | 
			
		||||
pub(crate) async fn inner_intersect(
 | 
			
		||||
    solids: Vec<Solid>,
 | 
			
		||||
    tolerance: Option<f64>,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
) -> Result<Vec<Solid>, KclError> {
 | 
			
		||||
    let solid_out_id = exec_state.next_uuid();
 | 
			
		||||
 | 
			
		||||
    let mut solid = solids[0].clone();
 | 
			
		||||
    solid.id = solid_out_id;
 | 
			
		||||
    let mut new_solids = vec![solid.clone()];
 | 
			
		||||
 | 
			
		||||
    if args.ctx.no_engine_commands().await {
 | 
			
		||||
        return Ok(new_solids);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Flush the fillets for the solids.
 | 
			
		||||
    args.flush_batch_for_solids(exec_state, &solids).await?;
 | 
			
		||||
 | 
			
		||||
    // TODO: call the engine union operation.
 | 
			
		||||
    // TODO: figure out all the shit after for the faces etc.
 | 
			
		||||
    let result = args
 | 
			
		||||
        .send_modeling_cmd(
 | 
			
		||||
            solid_out_id,
 | 
			
		||||
            ModelingCmd::from(mcmd::BooleanIntersection {
 | 
			
		||||
                solid_ids: solids.iter().map(|s| s.id).collect(),
 | 
			
		||||
                tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
    // For now just return the first solid.
 | 
			
		||||
    // Til we have a proper implementation.
 | 
			
		||||
    Ok(vec![solids[0].clone()])
 | 
			
		||||
    let OkWebSocketResponseData::Modeling {
 | 
			
		||||
        modeling_response: OkModelingCmdResponse::BooleanIntersection(BooleanIntersection { extra_solid_ids }),
 | 
			
		||||
    } = result
 | 
			
		||||
    else {
 | 
			
		||||
        return Err(KclError::Internal(KclErrorDetails {
 | 
			
		||||
            message: "Failed to get the result of the intersection operation.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // If we have more solids, set those as well.
 | 
			
		||||
    if !extra_solid_ids.is_empty() {
 | 
			
		||||
        solid.id = extra_solid_ids[0];
 | 
			
		||||
        new_solids.push(solid.clone());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(new_solids)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Subtract removes tool solids from base solids, leaving the remaining material.
 | 
			
		||||
@ -212,7 +292,23 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
 | 
			
		||||
    let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
 | 
			
		||||
    let tools: Vec<Solid> = args.get_kw_arg_typed("tools", &RuntimeType::solids(), exec_state)?;
 | 
			
		||||
 | 
			
		||||
    let solids = inner_subtract(solids, tools, exec_state, args).await?;
 | 
			
		||||
    if solids.len() > 1 {
 | 
			
		||||
        return Err(KclError::UndefinedValue(KclErrorDetails {
 | 
			
		||||
            message: "Only one solid is allowed for a subtract operation, currently.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if tools.len() > 1 {
 | 
			
		||||
        return Err(KclError::UndefinedValue(KclErrorDetails {
 | 
			
		||||
            message: "Only one tool is allowed for a subtract operation, currently.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let tolerance = args.get_kw_arg_opt("tolerance")?;
 | 
			
		||||
 | 
			
		||||
    let solids = inner_subtract(solids, tools, tolerance, exec_state, args).await?;
 | 
			
		||||
    Ok(solids.into())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -227,20 +323,19 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
 | 
			
		||||
/// ```no_run
 | 
			
		||||
/// // Subtract a cylinder from a cube using the stdlib functions.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = startSketchOn('XY')
 | 
			
		||||
///     |> circle(center = [0, 0], radius = 2)
 | 
			
		||||
///     |> extrude(length = 10)
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// subtractedPart = subtract([part001], tools=[part002])
 | 
			
		||||
/// ```
 | 
			
		||||
@ -250,20 +345,19 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
 | 
			
		||||
/// // NOTE: This will not work when using codemods through the UI.
 | 
			
		||||
/// // Codemods will generate the stdlib function call instead.
 | 
			
		||||
///
 | 
			
		||||
/// fn cube(center) {
 | 
			
		||||
/// fn cube(center, size) {
 | 
			
		||||
///     return startSketchOn('XY')
 | 
			
		||||
///         |> startProfileAt([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])
 | 
			
		||||
///         |> startProfileAt([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([0, 0])
 | 
			
		||||
/// part002 = startSketchOn('XY')
 | 
			
		||||
///     |> circle(center = [0, 0], radius = 2)
 | 
			
		||||
///     |> extrude(length = 10)
 | 
			
		||||
/// part001 = cube([0, 0], 10)
 | 
			
		||||
/// part002 = cube([7, 3], 5)
 | 
			
		||||
///     |> translate(z = 1)
 | 
			
		||||
///
 | 
			
		||||
/// // This is the equivalent of: subtract([part001], tools=[part002])
 | 
			
		||||
/// subtractedPart = part001 - part002
 | 
			
		||||
@ -273,26 +367,59 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
 | 
			
		||||
    feature_tree_operation = true,
 | 
			
		||||
    keywords = true,
 | 
			
		||||
    unlabeled_first = true,
 | 
			
		||||
    deprecated = 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."},
 | 
			
		||||
    }
 | 
			
		||||
}]
 | 
			
		||||
pub(crate) async fn inner_subtract(
 | 
			
		||||
    solids: Vec<Solid>,
 | 
			
		||||
    tools: Vec<Solid>,
 | 
			
		||||
    tolerance: Option<f64>,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
) -> Result<Vec<Solid>, KclError> {
 | 
			
		||||
    let solid_out_id = exec_state.next_uuid();
 | 
			
		||||
 | 
			
		||||
    let mut solid = solids[0].clone();
 | 
			
		||||
    solid.id = solid_out_id;
 | 
			
		||||
    let mut new_solids = vec![solid.clone()];
 | 
			
		||||
 | 
			
		||||
    if args.ctx.no_engine_commands().await {
 | 
			
		||||
        return Ok(new_solids);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Flush the fillets for the solids and the tools.
 | 
			
		||||
    let combined_solids = solids.iter().chain(tools.iter()).cloned().collect::<Vec<Solid>>();
 | 
			
		||||
    args.flush_batch_for_solids(exec_state, &combined_solids).await?;
 | 
			
		||||
 | 
			
		||||
    // TODO: call the engine union operation.
 | 
			
		||||
    // TODO: figure out all the shit after for the faces etc.
 | 
			
		||||
    let result = args
 | 
			
		||||
        .send_modeling_cmd(
 | 
			
		||||
            solid_out_id,
 | 
			
		||||
            ModelingCmd::from(mcmd::BooleanSubtract {
 | 
			
		||||
                target_ids: solids.iter().map(|s| s.id).collect(),
 | 
			
		||||
                tool_ids: tools.iter().map(|s| s.id).collect(),
 | 
			
		||||
                tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)),
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
    // For now just return the first solid.
 | 
			
		||||
    // Til we have a proper implementation.
 | 
			
		||||
    Ok(vec![solids[0].clone()])
 | 
			
		||||
    let OkWebSocketResponseData::Modeling {
 | 
			
		||||
        modeling_response: OkModelingCmdResponse::BooleanSubtract(BooleanSubtract { extra_solid_ids }),
 | 
			
		||||
    } = result
 | 
			
		||||
    else {
 | 
			
		||||
        return Err(KclError::Internal(KclErrorDetails {
 | 
			
		||||
            message: "Failed to get the result of the subtract operation.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // If we have more solids, set those as well.
 | 
			
		||||
    if !extra_solid_ids.is_empty() {
 | 
			
		||||
        solid.id = extra_solid_ids[0];
 | 
			
		||||
        new_solids.push(solid.clone());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(new_solids)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -178,7 +178,7 @@ description: Artifact commands intersect_cubes.kcl
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "extrude",
 | 
			
		||||
      "target": "[uuid]",
 | 
			
		||||
      "distance": 10.0,
 | 
			
		||||
      "distance": 20.0,
 | 
			
		||||
      "faces": null,
 | 
			
		||||
      "opposite": "None"
 | 
			
		||||
    }
 | 
			
		||||
@ -342,7 +342,7 @@ description: Artifact commands intersect_cubes.kcl
 | 
			
		||||
      "type": "move_path_pen",
 | 
			
		||||
      "path": "[uuid]",
 | 
			
		||||
      "to": {
 | 
			
		||||
        "x": -2.0,
 | 
			
		||||
        "x": 2.0,
 | 
			
		||||
        "y": -2.0,
 | 
			
		||||
        "z": 0.0
 | 
			
		||||
      }
 | 
			
		||||
@ -364,7 +364,7 @@ description: Artifact commands intersect_cubes.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "line",
 | 
			
		||||
        "end": {
 | 
			
		||||
          "x": 18.0,
 | 
			
		||||
          "x": 12.0,
 | 
			
		||||
          "y": -2.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
@ -381,8 +381,8 @@ description: Artifact commands intersect_cubes.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "line",
 | 
			
		||||
        "end": {
 | 
			
		||||
          "x": 18.0,
 | 
			
		||||
          "y": 18.0,
 | 
			
		||||
          "x": 12.0,
 | 
			
		||||
          "y": 8.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "relative": false
 | 
			
		||||
@ -398,8 +398,8 @@ description: Artifact commands intersect_cubes.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "line",
 | 
			
		||||
        "end": {
 | 
			
		||||
          "x": -2.0,
 | 
			
		||||
          "y": 18.0,
 | 
			
		||||
          "x": 2.0,
 | 
			
		||||
          "y": 8.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "relative": false
 | 
			
		||||
@ -544,5 +544,41 @@ description: Artifact commands intersect_cubes.kcl
 | 
			
		||||
      "edge_id": "[uuid]",
 | 
			
		||||
      "face_id": "[uuid]"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "cmdId": "[uuid]",
 | 
			
		||||
    "range": [],
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "set_object_transform",
 | 
			
		||||
      "object_id": "[uuid]",
 | 
			
		||||
      "transforms": [
 | 
			
		||||
        {
 | 
			
		||||
          "translate": {
 | 
			
		||||
            "property": {
 | 
			
		||||
              "x": 0.0,
 | 
			
		||||
              "y": 0.0,
 | 
			
		||||
              "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "set": false,
 | 
			
		||||
            "is_local": true
 | 
			
		||||
          },
 | 
			
		||||
          "rotate_rpy": null,
 | 
			
		||||
          "rotate_angle_axis": null,
 | 
			
		||||
          "scale": null
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "cmdId": "[uuid]",
 | 
			
		||||
    "range": [],
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "boolean_intersection",
 | 
			
		||||
      "solid_ids": [
 | 
			
		||||
        "[uuid]",
 | 
			
		||||
        "[uuid]"
 | 
			
		||||
      ],
 | 
			
		||||
      "tolerance": 0.0000001
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,23 @@
 | 
			
		||||
```mermaid
 | 
			
		||||
flowchart LR
 | 
			
		||||
  subgraph path2 [Path]
 | 
			
		||||
    2["Path<br>[52, 103, 0]"]
 | 
			
		||||
    3["Segment<br>[111, 163, 0]"]
 | 
			
		||||
    4["Segment<br>[171, 223, 0]"]
 | 
			
		||||
    5["Segment<br>[231, 283, 0]"]
 | 
			
		||||
    6["Segment<br>[291, 298, 0]"]
 | 
			
		||||
    2["Path<br>[58, 113, 0]"]
 | 
			
		||||
    3["Segment<br>[121, 177, 0]"]
 | 
			
		||||
    4["Segment<br>[185, 241, 0]"]
 | 
			
		||||
    5["Segment<br>[249, 305, 0]"]
 | 
			
		||||
    6["Segment<br>[313, 320, 0]"]
 | 
			
		||||
    7[Solid2d]
 | 
			
		||||
  end
 | 
			
		||||
  subgraph path24 [Path]
 | 
			
		||||
    24["Path<br>[52, 103, 0]"]
 | 
			
		||||
    25["Segment<br>[111, 163, 0]"]
 | 
			
		||||
    26["Segment<br>[171, 223, 0]"]
 | 
			
		||||
    27["Segment<br>[231, 283, 0]"]
 | 
			
		||||
    28["Segment<br>[291, 298, 0]"]
 | 
			
		||||
    24["Path<br>[58, 113, 0]"]
 | 
			
		||||
    25["Segment<br>[121, 177, 0]"]
 | 
			
		||||
    26["Segment<br>[185, 241, 0]"]
 | 
			
		||||
    27["Segment<br>[249, 305, 0]"]
 | 
			
		||||
    28["Segment<br>[313, 320, 0]"]
 | 
			
		||||
    29[Solid2d]
 | 
			
		||||
  end
 | 
			
		||||
  1["Plane<br>[27, 44, 0]"]
 | 
			
		||||
  8["Sweep Extrusion<br>[306, 326, 0]"]
 | 
			
		||||
  1["Plane<br>[33, 50, 0]"]
 | 
			
		||||
  8["Sweep Extrusion<br>[328, 354, 0]"]
 | 
			
		||||
  9[Wall]
 | 
			
		||||
  10[Wall]
 | 
			
		||||
  11[Wall]
 | 
			
		||||
@ -32,8 +32,8 @@ flowchart LR
 | 
			
		||||
  20["SweepEdge Adjacent"]
 | 
			
		||||
  21["SweepEdge Opposite"]
 | 
			
		||||
  22["SweepEdge Adjacent"]
 | 
			
		||||
  23["Plane<br>[27, 44, 0]"]
 | 
			
		||||
  30["Sweep Extrusion<br>[306, 326, 0]"]
 | 
			
		||||
  23["Plane<br>[33, 50, 0]"]
 | 
			
		||||
  30["Sweep Extrusion<br>[328, 354, 0]"]
 | 
			
		||||
  31[Wall]
 | 
			
		||||
  32[Wall]
 | 
			
		||||
  33[Wall]
 | 
			
		||||
 | 
			
		||||
@ -101,16 +101,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                },
 | 
			
		||||
                                "operator": "-",
 | 
			
		||||
                                "right": {
 | 
			
		||||
                                  "abs_path": false,
 | 
			
		||||
                                  "commentStart": 0,
 | 
			
		||||
                                  "end": 0,
 | 
			
		||||
                                  "raw": "10",
 | 
			
		||||
                                  "name": {
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "name": "size",
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Identifier"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "path": [],
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "value": {
 | 
			
		||||
                                    "value": 10.0,
 | 
			
		||||
                                    "suffix": "None"
 | 
			
		||||
                                  }
 | 
			
		||||
                                  "type": "Name",
 | 
			
		||||
                                  "type": "Name"
 | 
			
		||||
                                },
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "BinaryExpression",
 | 
			
		||||
@ -149,16 +153,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                },
 | 
			
		||||
                                "operator": "-",
 | 
			
		||||
                                "right": {
 | 
			
		||||
                                  "abs_path": false,
 | 
			
		||||
                                  "commentStart": 0,
 | 
			
		||||
                                  "end": 0,
 | 
			
		||||
                                  "raw": "10",
 | 
			
		||||
                                  "name": {
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "name": "size",
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Identifier"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "path": [],
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "value": {
 | 
			
		||||
                                    "value": 10.0,
 | 
			
		||||
                                    "suffix": "None"
 | 
			
		||||
                                  }
 | 
			
		||||
                                  "type": "Name",
 | 
			
		||||
                                  "type": "Name"
 | 
			
		||||
                                },
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "BinaryExpression",
 | 
			
		||||
@ -246,16 +254,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -294,16 +306,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "-",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -386,16 +402,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -434,16 +454,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -526,16 +550,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "-",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -574,16 +602,20 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -656,14 +688,38 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                            "arg": {
 | 
			
		||||
                              "commentStart": 0,
 | 
			
		||||
                              "end": 0,
 | 
			
		||||
                              "raw": "10",
 | 
			
		||||
                              "left": {
 | 
			
		||||
                                "commentStart": 0,
 | 
			
		||||
                                "end": 0,
 | 
			
		||||
                                "raw": "2",
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "Literal",
 | 
			
		||||
                                "type": "Literal",
 | 
			
		||||
                                "value": {
 | 
			
		||||
                                  "value": 2.0,
 | 
			
		||||
                                  "suffix": "None"
 | 
			
		||||
                                }
 | 
			
		||||
                              },
 | 
			
		||||
                              "operator": "*",
 | 
			
		||||
                              "right": {
 | 
			
		||||
                                "abs_path": false,
 | 
			
		||||
                                "commentStart": 0,
 | 
			
		||||
                                "end": 0,
 | 
			
		||||
                                "name": {
 | 
			
		||||
                                  "commentStart": 0,
 | 
			
		||||
                                  "end": 0,
 | 
			
		||||
                                  "name": "size",
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "Identifier"
 | 
			
		||||
                                },
 | 
			
		||||
                                "path": [],
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "Name",
 | 
			
		||||
                                "type": "Name"
 | 
			
		||||
                              },
 | 
			
		||||
                              "start": 0,
 | 
			
		||||
                              "type": "Literal",
 | 
			
		||||
                              "type": "Literal",
 | 
			
		||||
                              "value": {
 | 
			
		||||
                                "value": 10.0,
 | 
			
		||||
                                "suffix": "None"
 | 
			
		||||
                              }
 | 
			
		||||
                              "type": "BinaryExpression",
 | 
			
		||||
                              "type": "BinaryExpression"
 | 
			
		||||
                            }
 | 
			
		||||
                          }
 | 
			
		||||
                        ],
 | 
			
		||||
@ -719,6 +775,16 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "type": "Parameter",
 | 
			
		||||
                "identifier": {
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "name": "size",
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "start": 0,
 | 
			
		||||
@ -780,6 +846,18 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "ArrayExpression",
 | 
			
		||||
                "type": "ArrayExpression"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "raw": "10",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Literal",
 | 
			
		||||
                "type": "Literal",
 | 
			
		||||
                "value": {
 | 
			
		||||
                  "value": 10.0,
 | 
			
		||||
                  "suffix": "None"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "callee": {
 | 
			
		||||
@ -825,61 +903,129 @@ description: Result of parsing intersect_cubes.kcl
 | 
			
		||||
            "type": "Identifier"
 | 
			
		||||
          },
 | 
			
		||||
          "init": {
 | 
			
		||||
            "arguments": [
 | 
			
		||||
            "body": [
 | 
			
		||||
              {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "elements": [
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "elements": [
 | 
			
		||||
                      {
 | 
			
		||||
                        "commentStart": 0,
 | 
			
		||||
                        "end": 0,
 | 
			
		||||
                        "raw": "7",
 | 
			
		||||
                        "start": 0,
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "value": {
 | 
			
		||||
                          "value": 7.0,
 | 
			
		||||
                          "suffix": "None"
 | 
			
		||||
                        }
 | 
			
		||||
                      },
 | 
			
		||||
                      {
 | 
			
		||||
                        "commentStart": 0,
 | 
			
		||||
                        "end": 0,
 | 
			
		||||
                        "raw": "3",
 | 
			
		||||
                        "start": 0,
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "value": {
 | 
			
		||||
                          "value": 3.0,
 | 
			
		||||
                          "suffix": "None"
 | 
			
		||||
                        }
 | 
			
		||||
                      }
 | 
			
		||||
                    ],
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "raw": "8",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "value": 8.0,
 | 
			
		||||
                      "suffix": "None"
 | 
			
		||||
                    }
 | 
			
		||||
                    "type": "ArrayExpression",
 | 
			
		||||
                    "type": "ArrayExpression"
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "raw": "8",
 | 
			
		||||
                    "raw": "5",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "value": 8.0,
 | 
			
		||||
                      "value": 5.0,
 | 
			
		||||
                      "suffix": "None"
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "ArrayExpression",
 | 
			
		||||
                "type": "ArrayExpression"
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "callee": {
 | 
			
		||||
              "abs_path": false,
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "name": {
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "name": "cube",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "name": "cube",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Identifier"
 | 
			
		||||
                "type": "CallExpression",
 | 
			
		||||
                "type": "CallExpression"
 | 
			
		||||
              },
 | 
			
		||||
              "path": [],
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "Name"
 | 
			
		||||
            },
 | 
			
		||||
              {
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "name": "z",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "raw": "1",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 1.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "name": "translate",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "unlabeled": null
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "CallExpression",
 | 
			
		||||
            "type": "CallExpression"
 | 
			
		||||
            "type": "PipeExpression",
 | 
			
		||||
            "type": "PipeExpression"
 | 
			
		||||
          },
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "VariableDeclarator"
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,15 @@
 | 
			
		||||
fn cube(center) {
 | 
			
		||||
fn cube(center, size) {
 | 
			
		||||
  return startSketchOn(XY)
 | 
			
		||||
    |> startProfileAt([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])
 | 
			
		||||
    |> startProfileAt([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)
 | 
			
		||||
    |> extrude(length = 2 * size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
part001 = cube([0, 0])
 | 
			
		||||
part002 = cube([8, 8])
 | 
			
		||||
part001 = cube([0, 0], 10)
 | 
			
		||||
part002 = cube([7, 3], 5)
 | 
			
		||||
     |> translate(z = 1)
 | 
			
		||||
 | 
			
		||||
fullPart = intersect([part001, part002])
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ description: Operations executed intersect_cubes.kcl
 | 
			
		||||
      "name": "cube",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        7,
 | 
			
		||||
        328,
 | 
			
		||||
        356,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
@ -38,7 +38,7 @@ description: Operations executed intersect_cubes.kcl
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 10.0,
 | 
			
		||||
          "value": 20.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
@ -75,7 +75,7 @@ description: Operations executed intersect_cubes.kcl
 | 
			
		||||
      "name": "cube",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        7,
 | 
			
		||||
        328,
 | 
			
		||||
        356,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
 | 
			
		||||
@ -7,182 +7,365 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
    "type": "Function"
 | 
			
		||||
  },
 | 
			
		||||
  "fullPart": {
 | 
			
		||||
    "type": "Solid",
 | 
			
		||||
    "value": {
 | 
			
		||||
      "type": "Solid",
 | 
			
		||||
      "id": "[uuid]",
 | 
			
		||||
      "artifactId": "[uuid]",
 | 
			
		||||
      "value": [
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "sketch": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "id": "[uuid]",
 | 
			
		||||
        "paths": [
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        "on": {
 | 
			
		||||
          "type": "plane",
 | 
			
		||||
    "type": "HomArray",
 | 
			
		||||
    "value": [
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "value": "XY",
 | 
			
		||||
          "origin": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "xAxis": {
 | 
			
		||||
            "x": 1.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "yAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 1.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "zAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 1.0
 | 
			
		||||
          },
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            -10.0,
 | 
			
		||||
            -10.0
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            -10.0,
 | 
			
		||||
            -10.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          },
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "__geoMeta": {
 | 
			
		||||
          "sketch": {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "sourceRange": []
 | 
			
		||||
            "paths": [
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "on": {
 | 
			
		||||
              "type": "plane",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "artifactId": "[uuid]",
 | 
			
		||||
              "value": "XY",
 | 
			
		||||
              "origin": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "xAxis": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "yAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "zAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
              },
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "start": {
 | 
			
		||||
              "from": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "to": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              },
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "__geoMeta": {
 | 
			
		||||
                "id": "[uuid]",
 | 
			
		||||
                "sourceRange": []
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "artifactId": "[uuid]",
 | 
			
		||||
            "originalId": "[uuid]",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "height": 20.0,
 | 
			
		||||
          "startCapId": "[uuid]",
 | 
			
		||||
          "endCapId": "[uuid]",
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "artifactId": "[uuid]",
 | 
			
		||||
        "originalId": "[uuid]",
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 10.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
        "type": "Mm"
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "sketch": {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "paths": [
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "on": {
 | 
			
		||||
              "type": "plane",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "artifactId": "[uuid]",
 | 
			
		||||
              "value": "XY",
 | 
			
		||||
              "origin": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "xAxis": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "yAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "zAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
              },
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "start": {
 | 
			
		||||
              "from": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "to": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              },
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "__geoMeta": {
 | 
			
		||||
                "id": "[uuid]",
 | 
			
		||||
                "sourceRange": []
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "artifactId": "[uuid]",
 | 
			
		||||
            "originalId": "[uuid]",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "height": 20.0,
 | 
			
		||||
          "startCapId": "[uuid]",
 | 
			
		||||
          "endCapId": "[uuid]",
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "part001": {
 | 
			
		||||
    "type": "Solid",
 | 
			
		||||
@ -354,7 +537,7 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 10.0,
 | 
			
		||||
      "height": 20.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
@ -408,12 +591,12 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -2.0,
 | 
			
		||||
              2.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              18.0,
 | 
			
		||||
              12.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
@ -427,13 +610,13 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              18.0,
 | 
			
		||||
              12.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              18.0,
 | 
			
		||||
              18.0
 | 
			
		||||
              12.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -446,13 +629,13 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              18.0,
 | 
			
		||||
              18.0
 | 
			
		||||
              12.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -2.0,
 | 
			
		||||
              18.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -465,12 +648,12 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -2.0,
 | 
			
		||||
              18.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -2.0,
 | 
			
		||||
              2.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
@ -510,11 +693,11 @@ description: Variables in memory after executing intersect_cubes.kcl
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            -2.0,
 | 
			
		||||
            2.0,
 | 
			
		||||
            -2.0
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            -2.0,
 | 
			
		||||
            2.0,
 | 
			
		||||
            -2.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 61 KiB  | 
@ -2,17 +2,18 @@
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Result of unparsing intersect_cubes.kcl
 | 
			
		||||
---
 | 
			
		||||
fn cube(center) {
 | 
			
		||||
fn cube(center, size) {
 | 
			
		||||
  return startSketchOn(XY)
 | 
			
		||||
    |> startProfileAt([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])
 | 
			
		||||
    |> startProfileAt([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)
 | 
			
		||||
    |> extrude(length = 2 * size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
part001 = cube([0, 0])
 | 
			
		||||
part002 = cube([8, 8])
 | 
			
		||||
part001 = cube([0, 0], 10)
 | 
			
		||||
part002 = cube([7, 3], 5)
 | 
			
		||||
  |> translate(z = 1)
 | 
			
		||||
 | 
			
		||||
fullPart = intersect([part001, part002])
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 58 KiB  | 
| 
		 Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 58 KiB  | 
| 
		 Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 59 KiB  | 
| 
		 Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 59 KiB  | 
| 
		 Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB  | 
| 
		 Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB  | 
| 
		 Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB  | 
@ -342,8 +342,8 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
 | 
			
		||||
      "type": "move_path_pen",
 | 
			
		||||
      "path": "[uuid]",
 | 
			
		||||
      "to": {
 | 
			
		||||
        "x": 2.0,
 | 
			
		||||
        "y": 0.0,
 | 
			
		||||
        "x": 4.0,
 | 
			
		||||
        "y": 2.0,
 | 
			
		||||
        "z": 0.0
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -364,8 +364,8 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "arc",
 | 
			
		||||
        "center": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 0.0
 | 
			
		||||
          "x": 2.0,
 | 
			
		||||
          "y": 2.0
 | 
			
		||||
        },
 | 
			
		||||
        "radius": 2.0,
 | 
			
		||||
        "start": {
 | 
			
		||||
@ -410,7 +410,7 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "extrude",
 | 
			
		||||
      "target": "[uuid]",
 | 
			
		||||
      "distance": 10.0,
 | 
			
		||||
      "distance": 5.0,
 | 
			
		||||
      "faces": null,
 | 
			
		||||
      "opposite": "None"
 | 
			
		||||
    }
 | 
			
		||||
@ -458,5 +458,19 @@ description: Artifact commands subtract_cylinder_from_cube.kcl
 | 
			
		||||
      "edge_id": "[uuid]",
 | 
			
		||||
      "face_id": "[uuid]"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "cmdId": "[uuid]",
 | 
			
		||||
    "range": [],
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "boolean_subtract",
 | 
			
		||||
      "target_ids": [
 | 
			
		||||
        "[uuid]"
 | 
			
		||||
      ],
 | 
			
		||||
      "tool_ids": [
 | 
			
		||||
        "[uuid]"
 | 
			
		||||
      ],
 | 
			
		||||
      "tolerance": 0.0000001
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ flowchart LR
 | 
			
		||||
  21["SweepEdge Opposite"]
 | 
			
		||||
  22["SweepEdge Adjacent"]
 | 
			
		||||
  23["Plane<br>[363, 382, 0]"]
 | 
			
		||||
  27["Sweep Extrusion<br>[429, 449, 0]"]
 | 
			
		||||
  27["Sweep Extrusion<br>[429, 448, 0]"]
 | 
			
		||||
  28[Wall]
 | 
			
		||||
  29["Cap Start"]
 | 
			
		||||
  30["Cap End"]
 | 
			
		||||
 | 
			
		||||
@ -876,24 +876,24 @@ description: Result of parsing subtract_cylinder_from_cube.kcl
 | 
			
		||||
                        {
 | 
			
		||||
                          "commentStart": 0,
 | 
			
		||||
                          "end": 0,
 | 
			
		||||
                          "raw": "0",
 | 
			
		||||
                          "raw": "2",
 | 
			
		||||
                          "start": 0,
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "value": {
 | 
			
		||||
                            "value": 0.0,
 | 
			
		||||
                            "value": 2.0,
 | 
			
		||||
                            "suffix": "None"
 | 
			
		||||
                          }
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                          "commentStart": 0,
 | 
			
		||||
                          "end": 0,
 | 
			
		||||
                          "raw": "0",
 | 
			
		||||
                          "raw": "2",
 | 
			
		||||
                          "start": 0,
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "value": {
 | 
			
		||||
                            "value": 0.0,
 | 
			
		||||
                            "value": 2.0,
 | 
			
		||||
                            "suffix": "None"
 | 
			
		||||
                          }
 | 
			
		||||
                        }
 | 
			
		||||
@ -963,12 +963,12 @@ description: Result of parsing subtract_cylinder_from_cube.kcl
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "raw": "10",
 | 
			
		||||
                      "raw": "5",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 10.0,
 | 
			
		||||
                        "value": 5.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ fn cube(center) {
 | 
			
		||||
 | 
			
		||||
part001 = cube([0, 0])
 | 
			
		||||
part002 = startSketchOn('XY')
 | 
			
		||||
  |> circle(center = [0, 0], radius = 2)
 | 
			
		||||
  |> extrude(length = 10)
 | 
			
		||||
  |> circle(center = [2, 2], radius = 2)
 | 
			
		||||
  |> extrude(length = 5)
 | 
			
		||||
 | 
			
		||||
fullPart = subtract([part001], tools=[part002])
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ description: Operations executed subtract_cylinder_from_cube.kcl
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 10.0,
 | 
			
		||||
          "value": 5.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
 | 
			
		||||
@ -7,182 +7,365 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
 | 
			
		||||
    "type": "Function"
 | 
			
		||||
  },
 | 
			
		||||
  "fullPart": {
 | 
			
		||||
    "type": "Solid",
 | 
			
		||||
    "value": {
 | 
			
		||||
      "type": "Solid",
 | 
			
		||||
      "id": "[uuid]",
 | 
			
		||||
      "artifactId": "[uuid]",
 | 
			
		||||
      "value": [
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "sketch": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "id": "[uuid]",
 | 
			
		||||
        "paths": [
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        "on": {
 | 
			
		||||
          "type": "plane",
 | 
			
		||||
    "type": "HomArray",
 | 
			
		||||
    "value": [
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "value": "XY",
 | 
			
		||||
          "origin": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "xAxis": {
 | 
			
		||||
            "x": 1.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "yAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 1.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "zAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 1.0
 | 
			
		||||
          },
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            -10.0,
 | 
			
		||||
            -10.0
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            -10.0,
 | 
			
		||||
            -10.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          },
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "__geoMeta": {
 | 
			
		||||
          "sketch": {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "sourceRange": []
 | 
			
		||||
            "paths": [
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "on": {
 | 
			
		||||
              "type": "plane",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "artifactId": "[uuid]",
 | 
			
		||||
              "value": "XY",
 | 
			
		||||
              "origin": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "xAxis": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "yAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "zAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
              },
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "start": {
 | 
			
		||||
              "from": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "to": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              },
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "__geoMeta": {
 | 
			
		||||
                "id": "[uuid]",
 | 
			
		||||
                "sourceRange": []
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "artifactId": "[uuid]",
 | 
			
		||||
            "originalId": "[uuid]",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "height": 10.0,
 | 
			
		||||
          "startCapId": "[uuid]",
 | 
			
		||||
          "endCapId": "[uuid]",
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "artifactId": "[uuid]",
 | 
			
		||||
        "originalId": "[uuid]",
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 10.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
        "type": "Mm"
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "sketch": {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "paths": [
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "on": {
 | 
			
		||||
              "type": "plane",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "artifactId": "[uuid]",
 | 
			
		||||
              "value": "XY",
 | 
			
		||||
              "origin": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "xAxis": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "yAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "zAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
              },
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "start": {
 | 
			
		||||
              "from": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "to": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              },
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "__geoMeta": {
 | 
			
		||||
                "id": "[uuid]",
 | 
			
		||||
                "sourceRange": []
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "artifactId": "[uuid]",
 | 
			
		||||
            "originalId": "[uuid]",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "height": 10.0,
 | 
			
		||||
          "startCapId": "[uuid]",
 | 
			
		||||
          "endCapId": "[uuid]",
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "part001": {
 | 
			
		||||
    "type": "Solid",
 | 
			
		||||
@ -388,18 +571,18 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
 | 
			
		||||
            },
 | 
			
		||||
            "ccw": true,
 | 
			
		||||
            "center": [
 | 
			
		||||
              0.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "from": [
 | 
			
		||||
              2.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              4.0,
 | 
			
		||||
              2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "radius": 2.0,
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              2.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              4.0,
 | 
			
		||||
              2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "Circle",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -438,12 +621,12 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            2.0,
 | 
			
		||||
            0.0
 | 
			
		||||
            4.0,
 | 
			
		||||
            2.0
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            2.0,
 | 
			
		||||
            0.0
 | 
			
		||||
            4.0,
 | 
			
		||||
            2.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
@ -460,7 +643,7 @@ description: Variables in memory after executing subtract_cylinder_from_cube.kcl
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 10.0,
 | 
			
		||||
      "height": 5.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB  | 
@ -14,7 +14,7 @@ fn cube(center) {
 | 
			
		||||
 | 
			
		||||
part001 = cube([0, 0])
 | 
			
		||||
part002 = startSketchOn(XY)
 | 
			
		||||
  |> circle(center = [0, 0], radius = 2)
 | 
			
		||||
  |> extrude(length = 10)
 | 
			
		||||
  |> circle(center = [2, 2], radius = 2)
 | 
			
		||||
  |> extrude(length = 5)
 | 
			
		||||
 | 
			
		||||
fullPart = subtract([part001], tools = [part002])
 | 
			
		||||
 | 
			
		||||
@ -178,7 +178,7 @@ description: Artifact commands union_cubes.kcl
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "extrude",
 | 
			
		||||
      "target": "[uuid]",
 | 
			
		||||
      "distance": 10.0,
 | 
			
		||||
      "distance": 20.0,
 | 
			
		||||
      "faces": null,
 | 
			
		||||
      "opposite": "None"
 | 
			
		||||
    }
 | 
			
		||||
@ -342,8 +342,8 @@ description: Artifact commands union_cubes.kcl
 | 
			
		||||
      "type": "move_path_pen",
 | 
			
		||||
      "path": "[uuid]",
 | 
			
		||||
      "to": {
 | 
			
		||||
        "x": 10.0,
 | 
			
		||||
        "y": 0.0,
 | 
			
		||||
        "x": 2.0,
 | 
			
		||||
        "y": -2.0,
 | 
			
		||||
        "z": 0.0
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -364,8 +364,8 @@ description: Artifact commands union_cubes.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "line",
 | 
			
		||||
        "end": {
 | 
			
		||||
          "x": 30.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "x": 12.0,
 | 
			
		||||
          "y": -2.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "relative": false
 | 
			
		||||
@ -381,8 +381,8 @@ description: Artifact commands union_cubes.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "line",
 | 
			
		||||
        "end": {
 | 
			
		||||
          "x": 30.0,
 | 
			
		||||
          "y": 20.0,
 | 
			
		||||
          "x": 12.0,
 | 
			
		||||
          "y": 8.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "relative": false
 | 
			
		||||
@ -398,8 +398,8 @@ description: Artifact commands union_cubes.kcl
 | 
			
		||||
      "segment": {
 | 
			
		||||
        "type": "line",
 | 
			
		||||
        "end": {
 | 
			
		||||
          "x": 10.0,
 | 
			
		||||
          "y": 20.0,
 | 
			
		||||
          "x": 2.0,
 | 
			
		||||
          "y": 8.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "relative": false
 | 
			
		||||
@ -544,5 +544,41 @@ description: Artifact commands union_cubes.kcl
 | 
			
		||||
      "edge_id": "[uuid]",
 | 
			
		||||
      "face_id": "[uuid]"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "cmdId": "[uuid]",
 | 
			
		||||
    "range": [],
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "set_object_transform",
 | 
			
		||||
      "object_id": "[uuid]",
 | 
			
		||||
      "transforms": [
 | 
			
		||||
        {
 | 
			
		||||
          "translate": {
 | 
			
		||||
            "property": {
 | 
			
		||||
              "x": 0.0,
 | 
			
		||||
              "y": 0.0,
 | 
			
		||||
              "z": 1.0
 | 
			
		||||
            },
 | 
			
		||||
            "set": false,
 | 
			
		||||
            "is_local": true
 | 
			
		||||
          },
 | 
			
		||||
          "rotate_rpy": null,
 | 
			
		||||
          "rotate_angle_axis": null,
 | 
			
		||||
          "scale": null
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "cmdId": "[uuid]",
 | 
			
		||||
    "range": [],
 | 
			
		||||
    "command": {
 | 
			
		||||
      "type": "boolean_union",
 | 
			
		||||
      "solid_ids": [
 | 
			
		||||
        "[uuid]",
 | 
			
		||||
        "[uuid]"
 | 
			
		||||
      ],
 | 
			
		||||
      "tolerance": 0.0000001
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,23 @@
 | 
			
		||||
```mermaid
 | 
			
		||||
flowchart LR
 | 
			
		||||
  subgraph path2 [Path]
 | 
			
		||||
    2["Path<br>[52, 103, 0]"]
 | 
			
		||||
    3["Segment<br>[111, 163, 0]"]
 | 
			
		||||
    4["Segment<br>[171, 223, 0]"]
 | 
			
		||||
    5["Segment<br>[231, 283, 0]"]
 | 
			
		||||
    6["Segment<br>[291, 298, 0]"]
 | 
			
		||||
    2["Path<br>[58, 113, 0]"]
 | 
			
		||||
    3["Segment<br>[121, 177, 0]"]
 | 
			
		||||
    4["Segment<br>[185, 241, 0]"]
 | 
			
		||||
    5["Segment<br>[249, 305, 0]"]
 | 
			
		||||
    6["Segment<br>[313, 320, 0]"]
 | 
			
		||||
    7[Solid2d]
 | 
			
		||||
  end
 | 
			
		||||
  subgraph path24 [Path]
 | 
			
		||||
    24["Path<br>[52, 103, 0]"]
 | 
			
		||||
    25["Segment<br>[111, 163, 0]"]
 | 
			
		||||
    26["Segment<br>[171, 223, 0]"]
 | 
			
		||||
    27["Segment<br>[231, 283, 0]"]
 | 
			
		||||
    28["Segment<br>[291, 298, 0]"]
 | 
			
		||||
    24["Path<br>[58, 113, 0]"]
 | 
			
		||||
    25["Segment<br>[121, 177, 0]"]
 | 
			
		||||
    26["Segment<br>[185, 241, 0]"]
 | 
			
		||||
    27["Segment<br>[249, 305, 0]"]
 | 
			
		||||
    28["Segment<br>[313, 320, 0]"]
 | 
			
		||||
    29[Solid2d]
 | 
			
		||||
  end
 | 
			
		||||
  1["Plane<br>[27, 44, 0]"]
 | 
			
		||||
  8["Sweep Extrusion<br>[306, 326, 0]"]
 | 
			
		||||
  1["Plane<br>[33, 50, 0]"]
 | 
			
		||||
  8["Sweep Extrusion<br>[328, 354, 0]"]
 | 
			
		||||
  9[Wall]
 | 
			
		||||
  10[Wall]
 | 
			
		||||
  11[Wall]
 | 
			
		||||
@ -32,8 +32,8 @@ flowchart LR
 | 
			
		||||
  20["SweepEdge Adjacent"]
 | 
			
		||||
  21["SweepEdge Opposite"]
 | 
			
		||||
  22["SweepEdge Adjacent"]
 | 
			
		||||
  23["Plane<br>[27, 44, 0]"]
 | 
			
		||||
  30["Sweep Extrusion<br>[306, 326, 0]"]
 | 
			
		||||
  23["Plane<br>[33, 50, 0]"]
 | 
			
		||||
  30["Sweep Extrusion<br>[328, 354, 0]"]
 | 
			
		||||
  31[Wall]
 | 
			
		||||
  32[Wall]
 | 
			
		||||
  33[Wall]
 | 
			
		||||
 | 
			
		||||
@ -101,16 +101,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                },
 | 
			
		||||
                                "operator": "-",
 | 
			
		||||
                                "right": {
 | 
			
		||||
                                  "abs_path": false,
 | 
			
		||||
                                  "commentStart": 0,
 | 
			
		||||
                                  "end": 0,
 | 
			
		||||
                                  "raw": "10",
 | 
			
		||||
                                  "name": {
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "name": "size",
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Identifier"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "path": [],
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "value": {
 | 
			
		||||
                                    "value": 10.0,
 | 
			
		||||
                                    "suffix": "None"
 | 
			
		||||
                                  }
 | 
			
		||||
                                  "type": "Name",
 | 
			
		||||
                                  "type": "Name"
 | 
			
		||||
                                },
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "BinaryExpression",
 | 
			
		||||
@ -149,16 +153,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                },
 | 
			
		||||
                                "operator": "-",
 | 
			
		||||
                                "right": {
 | 
			
		||||
                                  "abs_path": false,
 | 
			
		||||
                                  "commentStart": 0,
 | 
			
		||||
                                  "end": 0,
 | 
			
		||||
                                  "raw": "10",
 | 
			
		||||
                                  "name": {
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "name": "size",
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Identifier"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "path": [],
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "type": "Literal",
 | 
			
		||||
                                  "value": {
 | 
			
		||||
                                    "value": 10.0,
 | 
			
		||||
                                    "suffix": "None"
 | 
			
		||||
                                  }
 | 
			
		||||
                                  "type": "Name",
 | 
			
		||||
                                  "type": "Name"
 | 
			
		||||
                                },
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "BinaryExpression",
 | 
			
		||||
@ -246,16 +254,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -294,16 +306,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "-",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -386,16 +402,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -434,16 +454,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -526,16 +550,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "-",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -574,16 +602,20 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "operator": "+",
 | 
			
		||||
                                  "right": {
 | 
			
		||||
                                    "abs_path": false,
 | 
			
		||||
                                    "commentStart": 0,
 | 
			
		||||
                                    "end": 0,
 | 
			
		||||
                                    "raw": "10",
 | 
			
		||||
                                    "name": {
 | 
			
		||||
                                      "commentStart": 0,
 | 
			
		||||
                                      "end": 0,
 | 
			
		||||
                                      "name": "size",
 | 
			
		||||
                                      "start": 0,
 | 
			
		||||
                                      "type": "Identifier"
 | 
			
		||||
                                    },
 | 
			
		||||
                                    "path": [],
 | 
			
		||||
                                    "start": 0,
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "type": "Literal",
 | 
			
		||||
                                    "value": {
 | 
			
		||||
                                      "value": 10.0,
 | 
			
		||||
                                      "suffix": "None"
 | 
			
		||||
                                    }
 | 
			
		||||
                                    "type": "Name",
 | 
			
		||||
                                    "type": "Name"
 | 
			
		||||
                                  },
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "BinaryExpression",
 | 
			
		||||
@ -656,14 +688,38 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                            "arg": {
 | 
			
		||||
                              "commentStart": 0,
 | 
			
		||||
                              "end": 0,
 | 
			
		||||
                              "raw": "10",
 | 
			
		||||
                              "left": {
 | 
			
		||||
                                "commentStart": 0,
 | 
			
		||||
                                "end": 0,
 | 
			
		||||
                                "raw": "2",
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "Literal",
 | 
			
		||||
                                "type": "Literal",
 | 
			
		||||
                                "value": {
 | 
			
		||||
                                  "value": 2.0,
 | 
			
		||||
                                  "suffix": "None"
 | 
			
		||||
                                }
 | 
			
		||||
                              },
 | 
			
		||||
                              "operator": "*",
 | 
			
		||||
                              "right": {
 | 
			
		||||
                                "abs_path": false,
 | 
			
		||||
                                "commentStart": 0,
 | 
			
		||||
                                "end": 0,
 | 
			
		||||
                                "name": {
 | 
			
		||||
                                  "commentStart": 0,
 | 
			
		||||
                                  "end": 0,
 | 
			
		||||
                                  "name": "size",
 | 
			
		||||
                                  "start": 0,
 | 
			
		||||
                                  "type": "Identifier"
 | 
			
		||||
                                },
 | 
			
		||||
                                "path": [],
 | 
			
		||||
                                "start": 0,
 | 
			
		||||
                                "type": "Name",
 | 
			
		||||
                                "type": "Name"
 | 
			
		||||
                              },
 | 
			
		||||
                              "start": 0,
 | 
			
		||||
                              "type": "Literal",
 | 
			
		||||
                              "type": "Literal",
 | 
			
		||||
                              "value": {
 | 
			
		||||
                                "value": 10.0,
 | 
			
		||||
                                "suffix": "None"
 | 
			
		||||
                              }
 | 
			
		||||
                              "type": "BinaryExpression",
 | 
			
		||||
                              "type": "BinaryExpression"
 | 
			
		||||
                            }
 | 
			
		||||
                          }
 | 
			
		||||
                        ],
 | 
			
		||||
@ -719,6 +775,16 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "type": "Parameter",
 | 
			
		||||
                "identifier": {
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "name": "size",
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "start": 0,
 | 
			
		||||
@ -780,6 +846,18 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "ArrayExpression",
 | 
			
		||||
                "type": "ArrayExpression"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "raw": "10",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Literal",
 | 
			
		||||
                "type": "Literal",
 | 
			
		||||
                "value": {
 | 
			
		||||
                  "value": 10.0,
 | 
			
		||||
                  "suffix": "None"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "callee": {
 | 
			
		||||
@ -825,61 +903,129 @@ description: Result of parsing union_cubes.kcl
 | 
			
		||||
            "type": "Identifier"
 | 
			
		||||
          },
 | 
			
		||||
          "init": {
 | 
			
		||||
            "arguments": [
 | 
			
		||||
            "body": [
 | 
			
		||||
              {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "elements": [
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "elements": [
 | 
			
		||||
                      {
 | 
			
		||||
                        "commentStart": 0,
 | 
			
		||||
                        "end": 0,
 | 
			
		||||
                        "raw": "7",
 | 
			
		||||
                        "start": 0,
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "value": {
 | 
			
		||||
                          "value": 7.0,
 | 
			
		||||
                          "suffix": "None"
 | 
			
		||||
                        }
 | 
			
		||||
                      },
 | 
			
		||||
                      {
 | 
			
		||||
                        "commentStart": 0,
 | 
			
		||||
                        "end": 0,
 | 
			
		||||
                        "raw": "3",
 | 
			
		||||
                        "start": 0,
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "value": {
 | 
			
		||||
                          "value": 3.0,
 | 
			
		||||
                          "suffix": "None"
 | 
			
		||||
                        }
 | 
			
		||||
                      }
 | 
			
		||||
                    ],
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "raw": "20",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "value": 20.0,
 | 
			
		||||
                      "suffix": "None"
 | 
			
		||||
                    }
 | 
			
		||||
                    "type": "ArrayExpression",
 | 
			
		||||
                    "type": "ArrayExpression"
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "raw": "10",
 | 
			
		||||
                    "raw": "5",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "value": 10.0,
 | 
			
		||||
                      "value": 5.0,
 | 
			
		||||
                      "suffix": "None"
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "ArrayExpression",
 | 
			
		||||
                "type": "ArrayExpression"
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "callee": {
 | 
			
		||||
              "abs_path": false,
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "name": {
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "name": "cube",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "name": "cube",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Identifier"
 | 
			
		||||
                "type": "CallExpression",
 | 
			
		||||
                "type": "CallExpression"
 | 
			
		||||
              },
 | 
			
		||||
              "path": [],
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "Name"
 | 
			
		||||
            },
 | 
			
		||||
              {
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "name": "z",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "raw": "1",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 1.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "name": "translate",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "unlabeled": null
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "CallExpression",
 | 
			
		||||
            "type": "CallExpression"
 | 
			
		||||
            "type": "PipeExpression",
 | 
			
		||||
            "type": "PipeExpression"
 | 
			
		||||
          },
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "VariableDeclarator"
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,15 @@
 | 
			
		||||
fn cube(center) {
 | 
			
		||||
fn cube(center, size) {
 | 
			
		||||
  return startSketchOn(XY)
 | 
			
		||||
    |> startProfileAt([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])
 | 
			
		||||
    |> startProfileAt([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)
 | 
			
		||||
    |> extrude(length = 2 * size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
part001 = cube([0, 0])
 | 
			
		||||
part002 = cube([20, 10])
 | 
			
		||||
part001 = cube([0, 0], 10)
 | 
			
		||||
part002 = cube([7, 3], 5)
 | 
			
		||||
     |> translate(z = 1)
 | 
			
		||||
 | 
			
		||||
fullPart = union([part001, part002])
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ description: Operations executed union_cubes.kcl
 | 
			
		||||
      "name": "cube",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        7,
 | 
			
		||||
        328,
 | 
			
		||||
        356,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
@ -38,7 +38,7 @@ description: Operations executed union_cubes.kcl
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 10.0,
 | 
			
		||||
          "value": 20.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
@ -75,7 +75,7 @@ description: Operations executed union_cubes.kcl
 | 
			
		||||
      "name": "cube",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        7,
 | 
			
		||||
        328,
 | 
			
		||||
        356,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
 | 
			
		||||
@ -7,182 +7,365 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
    "type": "Function"
 | 
			
		||||
  },
 | 
			
		||||
  "fullPart": {
 | 
			
		||||
    "type": "Solid",
 | 
			
		||||
    "value": {
 | 
			
		||||
      "type": "Solid",
 | 
			
		||||
      "id": "[uuid]",
 | 
			
		||||
      "artifactId": "[uuid]",
 | 
			
		||||
      "value": [
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "faceId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "sourceRange": [],
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "type": "extrudePlane"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "sketch": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "id": "[uuid]",
 | 
			
		||||
        "paths": [
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -10.0,
 | 
			
		||||
              -10.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        "on": {
 | 
			
		||||
          "type": "plane",
 | 
			
		||||
    "type": "HomArray",
 | 
			
		||||
    "value": [
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "value": "XY",
 | 
			
		||||
          "origin": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "xAxis": {
 | 
			
		||||
            "x": 1.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "yAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 1.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "zAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 1.0
 | 
			
		||||
          },
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            -10.0,
 | 
			
		||||
            -10.0
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            -10.0,
 | 
			
		||||
            -10.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          },
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "__geoMeta": {
 | 
			
		||||
          "sketch": {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "sourceRange": []
 | 
			
		||||
            "paths": [
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "on": {
 | 
			
		||||
              "type": "plane",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "artifactId": "[uuid]",
 | 
			
		||||
              "value": "XY",
 | 
			
		||||
              "origin": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "xAxis": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "yAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "zAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
              },
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "start": {
 | 
			
		||||
              "from": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "to": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              },
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "__geoMeta": {
 | 
			
		||||
                "id": "[uuid]",
 | 
			
		||||
                "sourceRange": []
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "artifactId": "[uuid]",
 | 
			
		||||
            "originalId": "[uuid]",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "height": 20.0,
 | 
			
		||||
          "startCapId": "[uuid]",
 | 
			
		||||
          "endCapId": "[uuid]",
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "artifactId": "[uuid]",
 | 
			
		||||
        "originalId": "[uuid]",
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 10.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
        "type": "Mm"
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "faceId": "[uuid]",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": [],
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "type": "extrudePlane"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "sketch": {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "paths": [
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "__geoMeta": {
 | 
			
		||||
                  "id": "[uuid]",
 | 
			
		||||
                  "sourceRange": []
 | 
			
		||||
                },
 | 
			
		||||
                "from": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "tag": null,
 | 
			
		||||
                "to": [
 | 
			
		||||
                  -10.0,
 | 
			
		||||
                  -10.0
 | 
			
		||||
                ],
 | 
			
		||||
                "type": "ToPoint",
 | 
			
		||||
                "units": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "on": {
 | 
			
		||||
              "type": "plane",
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "artifactId": "[uuid]",
 | 
			
		||||
              "value": "XY",
 | 
			
		||||
              "origin": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "xAxis": {
 | 
			
		||||
                "x": 1.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "yAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 1.0,
 | 
			
		||||
                "z": 0.0
 | 
			
		||||
              },
 | 
			
		||||
              "zAxis": {
 | 
			
		||||
                "x": 0.0,
 | 
			
		||||
                "y": 0.0,
 | 
			
		||||
                "z": 1.0
 | 
			
		||||
              },
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "start": {
 | 
			
		||||
              "from": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "to": [
 | 
			
		||||
                -10.0,
 | 
			
		||||
                -10.0
 | 
			
		||||
              ],
 | 
			
		||||
              "units": {
 | 
			
		||||
                "type": "Mm"
 | 
			
		||||
              },
 | 
			
		||||
              "tag": null,
 | 
			
		||||
              "__geoMeta": {
 | 
			
		||||
                "id": "[uuid]",
 | 
			
		||||
                "sourceRange": []
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            "artifactId": "[uuid]",
 | 
			
		||||
            "originalId": "[uuid]",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "height": 20.0,
 | 
			
		||||
          "startCapId": "[uuid]",
 | 
			
		||||
          "endCapId": "[uuid]",
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "part001": {
 | 
			
		||||
    "type": "Solid",
 | 
			
		||||
@ -354,7 +537,7 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 10.0,
 | 
			
		||||
      "height": 20.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
@ -408,13 +591,13 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              30.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              12.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -427,13 +610,13 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              30.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              12.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              30.0,
 | 
			
		||||
              20.0
 | 
			
		||||
              12.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -446,13 +629,13 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              30.0,
 | 
			
		||||
              20.0
 | 
			
		||||
              12.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              20.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -465,13 +648,13 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              20.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              8.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              10.0,
 | 
			
		||||
              0.0
 | 
			
		||||
              2.0,
 | 
			
		||||
              -2.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
@ -510,12 +693,12 @@ description: Variables in memory after executing union_cubes.kcl
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            10.0,
 | 
			
		||||
            0.0
 | 
			
		||||
            2.0,
 | 
			
		||||
            -2.0
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            10.0,
 | 
			
		||||
            0.0
 | 
			
		||||
            2.0,
 | 
			
		||||
            -2.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Mm"
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 71 KiB  | 
@ -2,17 +2,18 @@
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Result of unparsing union_cubes.kcl
 | 
			
		||||
---
 | 
			
		||||
fn cube(center) {
 | 
			
		||||
fn cube(center, size) {
 | 
			
		||||
  return startSketchOn(XY)
 | 
			
		||||
    |> startProfileAt([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])
 | 
			
		||||
    |> startProfileAt([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)
 | 
			
		||||
    |> extrude(length = 2 * size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
part001 = cube([0, 0])
 | 
			
		||||
part002 = cube([20, 10])
 | 
			
		||||
part001 = cube([0, 0], 10)
 | 
			
		||||
part002 = cube([7, 3], 5)
 | 
			
		||||
  |> translate(z = 1)
 | 
			
		||||
 | 
			
		||||
fullPart = union([part001, part002])
 | 
			
		||||
 | 
			
		||||